diff --git a/app/code/Magento/Authorizenet/Model/Source/Cctype.php b/app/code/Magento/Authorizenet/Model/Source/Cctype.php
index c6a83e19bd32733781228f873bd964558bd894be..a6e173474ae869f2ed40520ed2ccf8197f752e4d 100644
--- a/app/code/Magento/Authorizenet/Model/Source/Cctype.php
+++ b/app/code/Magento/Authorizenet/Model/Source/Cctype.php
@@ -17,6 +17,6 @@ class Cctype extends PaymentCctype
      */
     public function getAllowedTypes()
     {
-        return ['VI', 'MC', 'AE', 'DI'];
+        return ['VI', 'MC', 'AE', 'DI', 'JCB', 'DN'];
     }
 }
diff --git a/app/code/Magento/Authorizenet/etc/config.xml b/app/code/Magento/Authorizenet/etc/config.xml
index 70b413b5c1a3936c4efe3542f992b1dfead63999..5c48b88e0829965dd6f9a7d2d66f7373a7bb6990 100644
--- a/app/code/Magento/Authorizenet/etc/config.xml
+++ b/app/code/Magento/Authorizenet/etc/config.xml
@@ -10,7 +10,7 @@
         <payment>
             <authorizenet_directpost>
                 <active>0</active>
-                <cctypes>AE,VI,MC,DI</cctypes>
+                <cctypes>AE,VI,MC,DI,JCB,DN</cctypes>
                 <debug>0</debug>
                 <email_customer>0</email_customer>
                 <login backend_model="Magento\Config\Model\Config\Backend\Encrypted" />
diff --git a/app/code/Magento/Authorizenet/view/adminhtml/templates/directpost/info.phtml b/app/code/Magento/Authorizenet/view/adminhtml/templates/directpost/info.phtml
index bf674f8d5f3b480f0892b7273a04e82e2fb804ed..cb7200cad183c26c1d5c5ec8d4baae1477d57feb 100644
--- a/app/code/Magento/Authorizenet/view/adminhtml/templates/directpost/info.phtml
+++ b/app/code/Magento/Authorizenet/view/adminhtml/templates/directpost/info.phtml
@@ -35,8 +35,12 @@ $ccExpYear = $block->getInfoData('cc_exp_year');
         </label>
         <div class="admin__field-control">
             <select id="<?php /* @noEscape */ echo $code; ?>_cc_type" name="payment[cc_type]"
-                    class="required-entry validate-cc-type-select admin__control-select">
-                <option value=""></option>
+                    class="admin__control-select"
+                    data-validate="{
+                        'required':true,
+                        'validate-cc-type-select':'#<?php /* @noEscape */ echo $code; ?>_cc_number'
+                        }">
+                <option value=""><?php echo $block->escapeHtml(__('Please Select')); ?></option>
                 <?php foreach ($block->getCcAvailableTypes() as $typeCode => $typeName): ?>
                     <option value="<?php echo $block->escapeHtml($typeCode); ?>"
                             <?php if ($typeCode == $ccType): ?>selected="selected"<?php endif; ?>>
@@ -46,19 +50,25 @@ $ccExpYear = $block->getInfoData('cc_exp_year');
             </select>
         </div>
     </div>
+
     <div class="admin__field _required">
         <label for="<?php /* @noEscape */ echo $code; ?>_cc_number" class="admin__field-label">
             <span><?php echo $block->escapeHtml(__('Credit Card Number')); ?></span>
         </label>
-
         <div class="admin__field-control">
             <input type="text" id="<?php /* @noEscape */ echo $code; ?>_cc_number"
                    name="payment[cc_number]"
-                   class="input-text required-entry validate-cc-number admin__control-text"
+                   data-validate="{
+                       'required-number':true,
+                       'validate-cc-number':'#<?php /* @noEscape */ echo $code; ?>_cc_type',
+                       'validate-cc-type':'#<?php /* @noEscape */ echo $code; ?>_cc_type'
+                   }"
+                   class="admin__control-text"
                    value="<?php /* @noEscape */ echo $block->getInfoData('cc_number'); ?>"/>
         </div>
     </div>
-    <div class="admin__field _required">
+
+    <div class="admin__field _required field-date" id="<?php /* @noEscape */ echo $code; ?>_cc_type_exp_div">
         <label for="<?php /* @noEscape */ echo $code; ?>_expiration" class="admin__field-label">
             <span><?php echo $block->escapeHtml(__('Expiration Date')); ?></span>
         </label>
@@ -66,7 +76,11 @@ $ccExpYear = $block->getInfoData('cc_exp_year');
         <div class="admin__field-control">
             <select id="<?php /* @noEscape */ echo $code; ?>_expiration"
                     name="payment[cc_exp_month]"
-                    class="validate-cc-exp required-entry admin__control-select admin__control-select-month">
+                    class="admin__control-select admin__control-select-month"
+                    data-validate="{
+                        'required':true,
+                        'validate-cc-exp':'#<?php /* @noEscape */ echo $code; ?>_expiration_yr'
+                        }">
                 <?php foreach ($block->getCcMonths() as $k => $v): ?>
                     <option value="<?php echo $block->escapeHtml($k); ?>"
                             <?php if ($k == $ccExpMonth): ?>selected="selected"<?php endif; ?>>
@@ -76,7 +90,9 @@ $ccExpYear = $block->getInfoData('cc_exp_year');
             </select>
             <select id="<?php /* @noEscape */ echo $code; ?>_expiration_yr"
                     name="payment[cc_exp_year]"
-                    class="required-entry admin__control-select admin__control-select-year">
+                    class="admin__control-select admin__control-select-year"
+                    data-container="<?php /* @noEscape */ echo $code; ?>-cc-year"
+                    data-validate="{required:true}">
                 <?php foreach ($block->getCcYears() as $k => $v): ?>
                     <option value="<?php /* @noEscape */ echo $k ? $block->escapeHtml($k) : ''; ?>"
                             <?php if ($k == $ccExpYear): ?>selected="selected"<?php endif; ?>>
@@ -86,17 +102,27 @@ $ccExpYear = $block->getInfoData('cc_exp_year');
             </select>
         </div>
     </div>
+
     <?php if ($block->hasVerification()): ?>
-    <div class="admin__field _required">
-        <label for="<?php /* @noEscape */ echo $code; ?>_cc_cid">
+    <div class="admin__field _required field-cvv">
+        <label class="admin__field-label"
+               for="<?php /* @noEscape */ echo $code; ?>_cc_cid"
+               id="<?php /* @noEscape */ echo $code; ?>_cc_type_cvv_div">
             <span><?php echo $block->escapeHtml(__('Card Verification Number')); ?></span>
         </label>
 
         <div class="admin__field-control">
             <input type="text"
-                   class="required-entry input-text validate-cc-cvn admin__control-text"
+                   data-container="<?php /* @noEscape */ echo $code; ?>-cc-cvv"
+                   title="<?php echo $block->escapeHtml(__('Card Verification Number')); ?>"
+                   class="admin__control-text cvv"
                    id="<?php /* @noEscape */ echo $code; ?>_cc_cid" name="payment[cc_cid]"
-                   value="<?php /* @noEscape */ echo $block->getInfoData('cc_cid') ?>"/>
+                   value="<?php /* @noEscape */ echo $block->getInfoData('cc_cid') ?>"
+                   data-validate="{
+                       'required-number':true,
+                       'validate-cc-cvn':'#<?php /* @noEscape */ echo $code; ?>_cc_type'
+                   }"
+                   autocomplete="off"/>
         </div>
     </div>
     <?php endif; ?>
@@ -105,7 +131,7 @@ $ccExpYear = $block->getInfoData('cc_exp_year');
     require([
         'prototype',
         'Magento_Sales/order/create/scripts',
-        "Magento_Sales/order/create/form",
+        'Magento_Sales/order/create/form',
         'Magento_Authorizenet/js/direct-post'
     ], function(){
 
diff --git a/app/code/Magento/Backend/Block/Widget/Form/Container.php b/app/code/Magento/Backend/Block/Widget/Form/Container.php
index 52c5525db17eb3f6b22e16e156f3010d10d08234..282b3e69532a7aa8b39701a7792df891cc11c66f 100644
--- a/app/code/Magento/Backend/Block/Widget/Form/Container.php
+++ b/app/code/Magento/Backend/Block/Widget/Form/Container.php
@@ -37,6 +37,16 @@ class Container extends \Magento\Backend\Block\Widget\Container
      * @var string
      */
     protected $_blockGroup = 'Magento_Backend';
+    
+    /**
+     *  @var string
+     */
+    const PARAM_BLOCK_GROUP = 'block_group';
+
+    /**
+     *  @var string
+     */
+    const PARAM_MODE = 'mode';
 
     /**
      * @var string
@@ -49,6 +59,12 @@ class Container extends \Magento\Backend\Block\Widget\Container
     protected function _construct()
     {
         parent::_construct();
+        if ($this->hasData(self::PARAM_BLOCK_GROUP)) {
+            $this->_blockGroup = $this->_getData(self::PARAM_BLOCK_GROUP);
+        }
+        if ($this->hasData(self::PARAM_MODE)) {
+            $this->_mode = $this->_getData(self::PARAM_MODE);
+        }
 
         $this->addButton(
             'back',
diff --git a/app/code/Magento/Braintree/Helper/Country.php b/app/code/Magento/Braintree/Helper/Country.php
index 3a3116b0d9ac0e94a3526e98c06a3e3847732ca7..e8660b8523b30ae6b1d308cf9503883099a2b8bf 100644
--- a/app/code/Magento/Braintree/Helper/Country.php
+++ b/app/code/Magento/Braintree/Helper/Country.php
@@ -6,6 +6,7 @@
 namespace Magento\Braintree\Helper;
 
 use Magento\Directory\Model\ResourceModel\Country\CollectionFactory;
+use Magento\Braintree\Model\Adminhtml\System\Config\Country as CountryConfig;
 
 /**
  * Class Country
@@ -13,12 +14,12 @@ use Magento\Directory\Model\ResourceModel\Country\CollectionFactory;
 class Country
 {
     /**
-     * @var \Magento\Directory\Model\ResourceModel\Country\CollectionFactory
+     * @var CollectionFactory
      */
     private $collectionFactory;
 
     /**
-     * @var \Magento\Braintree\Model\Adminhtml\System\Config\Country
+     * @var CountryConfig
      */
     private $countryConfig;
 
@@ -28,13 +29,11 @@ class Country
     private $countries;
 
     /**
-     * @param \Magento\Directory\Model\ResourceModel\Country\CollectionFactory $factory
-     * @param \Magento\Braintree\Model\Adminhtml\System\Config\Country $countryConfig
+     * @param CollectionFactory $factory
+     * @param CountryConfig $countryConfig
      */
-    public function __construct(
-        \Magento\Directory\Model\ResourceModel\Country\CollectionFactory $factory,
-        \Magento\Braintree\Model\Adminhtml\System\Config\Country $countryConfig
-    ) {
+    public function __construct(CollectionFactory $factory, CountryConfig $countryConfig)
+    {
         $this->collectionFactory = $factory;
         $this->countryConfig = $countryConfig;
     }
diff --git a/app/code/Magento/Braintree/etc/di.xml b/app/code/Magento/Braintree/etc/di.xml
index 849a3039fc361f84eb068fe681ae2e8deae598a0..d051ef78cfcd22424fa359e47be3efc0ee8dcc2b 100644
--- a/app/code/Magento/Braintree/etc/di.xml
+++ b/app/code/Magento/Braintree/etc/di.xml
@@ -22,6 +22,7 @@
             <argument name="code" xsi:type="const">Magento\Braintree\Model\Ui\PayPal\ConfigProvider::PAYPAL_CODE</argument>
             <argument name="infoBlockType" xsi:type="string">BraintreePayPalInfo</argument>
             <argument name="valueHandlerPool" xsi:type="object">BraintreePayPalValueHandlerPool</argument>
+            <argument name="validatorPool" xsi:type="object">BraintreePayPalValidatorPool</argument>
             <argument name="commandPool" xsi:type="object">BraintreePayPalCommandPool</argument>
         </arguments>
     </virtualType>
@@ -474,7 +475,7 @@
         </arguments>
     </virtualType>
 
-    <!-- Value validators infrastructure -->
+    <!-- Braintree validators infrastructure -->
     <virtualType name="BraintreeCountryValidator" type="Magento\Payment\Gateway\Validator\CountryValidator">
         <arguments>
             <argument name="config" xsi:type="object">Magento\Braintree\Gateway\Config\Config</argument>
@@ -487,6 +488,22 @@
             </argument>
         </arguments>
     </virtualType>
+    <!-- Braintree validators infrastructure -->
+
+    <!-- Braintree PayPal validators -->
+    <virtualType name="BraintreePayPalCountryValidator" type="Magento\Payment\Gateway\Validator\CountryValidator">
+        <arguments>
+            <argument name="config" xsi:type="object">Magento\Braintree\Gateway\Config\PayPal\Config</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="BraintreePayPalValidatorPool" type="Magento\Payment\Gateway\Validator\ValidatorPool">
+        <arguments>
+            <argument name="validators" xsi:type="array">
+                <item name="country" xsi:type="string">BraintreePayPalCountryValidator</item>
+            </argument>
+        </arguments>
+    </virtualType>
+    <!-- END Braintree PayPal validators -->
 
     <type name="Magento\Braintree\Block\Info">
         <arguments>
diff --git a/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/paypal.js b/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/paypal.js
index 0145264e3cd3a638094ad24035cd8f860322c415..184260c39e954d1c5a1fd6d45b34f09fcab9daa7 100644
--- a/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/paypal.js
+++ b/app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/paypal.js
@@ -12,8 +12,19 @@ define([
     'Magento_Checkout/js/model/quote',
     'Magento_Checkout/js/model/full-screen-loader',
     'Magento_Checkout/js/model/payment/additional-validators',
-    'Magento_Vault/js/view/payment/vault-enabler'
-], function ($, _, Component, Braintree, quote, fullScreenLoader, additionalValidators, VaultEnabler) {
+    'Magento_Vault/js/view/payment/vault-enabler',
+    'Magento_Checkout/js/action/create-billing-address'
+], function (
+    $,
+    _,
+    Component,
+    Braintree,
+    quote,
+    fullScreenLoader,
+    additionalValidators,
+    VaultEnabler,
+    createBillingAddress
+) {
     'use strict';
 
     return Component.extend({
@@ -172,14 +183,16 @@ define([
             var billingAddress = {
                 street: [address.streetAddress],
                 city: address.locality,
-                regionCode: address.region,
                 postcode: address.postalCode,
                 countryId: address.countryCodeAlpha2,
+                email: customer.email,
                 firstname: customer.firstName,
                 lastname: customer.lastName,
                 telephone: customer.phone
             };
 
+            billingAddress['region_code'] = address.region;
+            billingAddress = createBillingAddress(billingAddress);
             quote.billingAddress(billingAddress);
         },
 
diff --git a/app/code/Magento/Braintree/view/frontend/web/template/payment/form.html b/app/code/Magento/Braintree/view/frontend/web/template/payment/form.html
index 50c252862d6aad855503b9896854e6b364d24568..5aead9e82385152b49d3ddfff357c7e97beec105 100644
--- a/app/code/Magento/Braintree/view/frontend/web/template/payment/form.html
+++ b/app/code/Magento/Braintree/view/frontend/web/template/payment/form.html
@@ -109,8 +109,8 @@
                     <input type="checkbox"
                            name="vault[is_enabled]"
                            class="checkbox"
-                           data-bind="attr: {'id': getCode() + '_vault_enabler'}, checked: vaultEnabler.isActivePaymentTokenEnabler"/>
-                    <label class="label" data-bind="attr: {'for': getCode() + '_vault_enabler'}">
+                           data-bind="attr: {'id': getCode() + '_enable_vault'}, checked: vaultEnabler.isActivePaymentTokenEnabler"/>
+                    <label class="label" data-bind="attr: {'for': getCode() + '_enable_vault'}">
                         <span><!-- ko i18n: 'Save for later use.'--><!-- /ko --></span>
                     </label>
                     <div class="field-tooltip toggle">
diff --git a/app/code/Magento/Braintree/view/frontend/web/template/payment/paypal.html b/app/code/Magento/Braintree/view/frontend/web/template/payment/paypal.html
index c3450492e5d7f4945840a9727de752ed2885e398..465c5acea798d9c79884cc4f2983c41f0651f694 100644
--- a/app/code/Magento/Braintree/view/frontend/web/template/payment/paypal.html
+++ b/app/code/Magento/Braintree/view/frontend/web/template/payment/paypal.html
@@ -32,8 +32,8 @@
             <input type="checkbox"
                    name="vault[is_enabled]"
                    class="checkbox"
-                   data-bind="attr: {'id': getCode() + '_vault_enabler'}, checked: vaultEnabler.isActivePaymentTokenEnabler"/>
-            <label class="label" data-bind="attr: {'for': getCode() + '_vault_enabler'}">
+                   data-bind="attr: {'id': getCode() + '_enable_vault'}, checked: vaultEnabler.isActivePaymentTokenEnabler"/>
+            <label class="label" data-bind="attr: {'for': getCode() + '_enable_vault'}">
                 <span><!-- ko i18n: 'Save for later use.'--><!-- /ko --></span>
             </label>
             <div class="field-tooltip toggle">
diff --git a/app/code/Magento/BundleImportExport/Model/Export/RowCustomizer.php b/app/code/Magento/BundleImportExport/Model/Export/RowCustomizer.php
index 25ffc80c6630b0e40a6dd6c9b4f1b7426e336cab..59efe1ff2fc74675939b8716fdc107a74114fdef 100644
--- a/app/code/Magento/BundleImportExport/Model/Export/RowCustomizer.php
+++ b/app/code/Magento/BundleImportExport/Model/Export/RowCustomizer.php
@@ -331,10 +331,7 @@ class RowCustomizer implements RowCustomizerInterface
     protected function cleanNotBundleAdditionalAttributes($dataRow)
     {
         if (!empty($dataRow['additional_attributes'])) {
-            $additionalAttributes = explode(
-                ImportModel::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR,
-                $dataRow['additional_attributes']
-            );
+            $additionalAttributes = $this->parseAdditionalAttributes($dataRow['additional_attributes']);
             $dataRow['additional_attributes'] = $this->getNotBundleAttributes($additionalAttributes);
         }
 
@@ -349,17 +346,38 @@ class RowCustomizer implements RowCustomizerInterface
      */
     protected function getNotBundleAttributes($additionalAttributes)
     {
-        $cleanedAdditionalAttributes = '';
-        foreach ($additionalAttributes as $attribute) {
-            list($attributeCode, $attributeValue) = explode(ImportProductModel::PAIR_NAME_VALUE_SEPARATOR, $attribute);
-            if (!in_array('bundle_' . $attributeCode, $this->getBundleColumns())) {
-                $cleanedAdditionalAttributes .= $attributeCode
-                    . ImportProductModel::PAIR_NAME_VALUE_SEPARATOR
-                    . $attributeValue
-                    . ImportModel::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR;
+        $filteredAttributes = [];
+        foreach ($additionalAttributes as $code => $value) {
+            if (!in_array('bundle_' . $code, $this->getBundleColumns())) {
+                $filteredAttributes[] = $code . ImportProductModel::PAIR_NAME_VALUE_SEPARATOR . $value;
             }
         }
+        return implode(ImportModel::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR, $filteredAttributes);
+    }
 
-        return rtrim($cleanedAdditionalAttributes, ImportModel::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR);
+    /**
+     * Retrieves additional attributes as array code=>value.
+     *
+     * @param string $additionalAttributes
+     * @return array
+     */
+    private function parseAdditionalAttributes($additionalAttributes)
+    {
+        $attributeNameValuePairs = explode(ImportModel::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR, $additionalAttributes);
+        $preparedAttributes = [];
+        $code = '';
+        foreach ($attributeNameValuePairs as $attributeData) {
+            //process case when attribute has ImportModel::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR inside its value
+            if (strpos($attributeData, ImportProductModel::PAIR_NAME_VALUE_SEPARATOR) === false) {
+                if (!$code) {
+                    continue;
+                }
+                $preparedAttributes[$code] .= ImportModel::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR . $attributeData;
+                continue;
+            }
+            list($code, $value) = explode(ImportProductModel::PAIR_NAME_VALUE_SEPARATOR, $attributeData, 2);
+            $preparedAttributes[$code] = $value;
+        }
+        return $preparedAttributes;
     }
 }
diff --git a/app/code/Magento/BundleImportExport/Test/Unit/Model/Export/Product/RowCustomizerTest.php b/app/code/Magento/BundleImportExport/Test/Unit/Model/Export/Product/RowCustomizerTest.php
index e7c313c56034b07a4aa98cdb0e9ba5ccb59e144c..d13d0fe9d8f0041321119f58e164c4e38f7247cd 100644
--- a/app/code/Magento/BundleImportExport/Test/Unit/Model/Export/Product/RowCustomizerTest.php
+++ b/app/code/Magento/BundleImportExport/Test/Unit/Model/Export/Product/RowCustomizerTest.php
@@ -178,7 +178,8 @@ class RowCustomizerTest extends \PHPUnit_Framework_TestCase
     public function testAddData()
     {
         $preparedData = $this->rowCustomizerMock->prepareData($this->productResourceCollection, [1]);
-        $attributes = 'attribute=1,sku_type=1,price_type=1,price_view=1,weight_type=1,values=values,shipment_type=1';
+        $attributes = 'attribute=1,sku_type=1,attribute2="Text",price_type=1,price_view=1,weight_type=1,'
+            . 'values=values,shipment_type=1,attribute3=One,Two,Three';
         $dataRow = [
             'sku' => 'sku1',
             'additional_attributes' => $attributes
@@ -186,7 +187,7 @@ class RowCustomizerTest extends \PHPUnit_Framework_TestCase
         $preparedRow = $preparedData->addData($dataRow, 1);
         $expected = [
             'sku' => 'sku1',
-            'additional_attributes' => 'attribute=1',
+            'additional_attributes' => 'attribute=1,attribute2="Text",attribute3=One,Two,Three',
             'bundle_price_type' => 'fixed',
             'bundle_shipment_type' => 'separately',
             'bundle_sku_type' => 'fixed',
diff --git a/app/code/Magento/CacheInvalidate/Observer/InvalidateVarnishObserver.php b/app/code/Magento/CacheInvalidate/Observer/InvalidateVarnishObserver.php
index 44a9317e0b2469c81e58894c5a34fe59624ee7cb..0d4156ea78215b5811a16f24419e95cb43c2de40 100644
--- a/app/code/Magento/CacheInvalidate/Observer/InvalidateVarnishObserver.php
+++ b/app/code/Magento/CacheInvalidate/Observer/InvalidateVarnishObserver.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\CacheInvalidate\Observer;
 
+use Magento\Framework\App\ObjectManager;
 use Magento\Framework\Event\ObserverInterface;
 
 class InvalidateVarnishObserver implements ObserverInterface
@@ -21,6 +22,13 @@ class InvalidateVarnishObserver implements ObserverInterface
      */
     protected $purgeCache;
 
+    /**
+     * Invalidation tags resolver
+     *
+     * @var \Magento\Framework\App\Cache\Tag\Resolver
+     */
+    private $tagResolver;
+
     /**
      * @param \Magento\PageCache\Model\Config $config
      * @param \Magento\CacheInvalidate\Model\PurgeCache $purgeCache
@@ -42,18 +50,35 @@ class InvalidateVarnishObserver implements ObserverInterface
      */
     public function execute(\Magento\Framework\Event\Observer $observer)
     {
+        $object = $observer->getEvent()->getObject();
+        if (!is_object($object)) {
+            return;
+        }
         if ($this->config->getType() == \Magento\PageCache\Model\Config::VARNISH && $this->config->isEnabled()) {
-            $object = $observer->getEvent()->getObject();
-            if ($object instanceof \Magento\Framework\DataObject\IdentityInterface) {
-                $tags = [];
-                $pattern = "((^|,)%s(,|$))";
-                foreach ($object->getIdentities() as $tag) {
-                    $tags[] = sprintf($pattern, $tag);
-                }
-                if (!empty($tags)) {
-                    $this->purgeCache->sendPurgeRequest(implode('|', array_unique($tags)));
-                }
+            $bareTags = $this->getTagResolver()->getTags($object);
+
+            $tags = [];
+            $pattern = "((^|,)%s(,|$))";
+            foreach ($bareTags as $tag) {
+                $tags[] = sprintf($pattern, $tag);
+            }
+            if (!empty($tags)) {
+                $this->purgeCache->sendPurgeRequest(implode('|', array_unique($tags)));
             }
+
+        }
+    }
+
+    /**
+     * @deprecated
+     * @return \Magento\Framework\App\Cache\Tag\Resolver
+     */
+    private function getTagResolver()
+    {
+        if ($this->tagResolver === null) {
+            $this->tagResolver = \Magento\Framework\App\ObjectManager::getInstance()
+                ->get(\Magento\Framework\App\Cache\Tag\Resolver::class);
         }
+        return $this->tagResolver;
     }
 }
diff --git a/app/code/Magento/CacheInvalidate/Test/Unit/Observer/InvalidateVarnishObserverTest.php b/app/code/Magento/CacheInvalidate/Test/Unit/Observer/InvalidateVarnishObserverTest.php
index 0d5ace7afab7f38d8c209e6758d20f9b5970630b..e9aefc8cee2b54d967e68846850649c7c47c677a 100644
--- a/app/code/Magento/CacheInvalidate/Test/Unit/Observer/InvalidateVarnishObserverTest.php
+++ b/app/code/Magento/CacheInvalidate/Test/Unit/Observer/InvalidateVarnishObserverTest.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\CacheInvalidate\Test\Unit\Observer;
 
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
 class InvalidateVarnishObserverTest extends \PHPUnit_Framework_TestCase
 {
     /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\CacheInvalidate\Observer\InvalidateVarnishObserver */
@@ -22,11 +24,16 @@ class InvalidateVarnishObserverTest extends \PHPUnit_Framework_TestCase
     /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\DataObject\ */
     protected $observerObject;
 
+    /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\App\Cache\Tag\Resolver */
+    private $tagResolver;
+
     /**
      * Set up all mocks and data for test
      */
     protected function setUp()
     {
+        $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+
         $this->configMock = $this->getMock(
             \Magento\PageCache\Model\Config::class,
             ['getType', 'isEnabled'],
@@ -39,6 +46,10 @@ class InvalidateVarnishObserverTest extends \PHPUnit_Framework_TestCase
             $this->configMock,
             $this->purgeCache
         );
+
+        $this->tagResolver = $this->getMock(\Magento\Framework\App\Cache\Tag\Resolver::class, [], [], '', false);
+        $helper->setBackwardCompatibleProperty($this->model, 'tagResolver', $this->tagResolver);
+
         $this->observerMock = $this->getMock(
             \Magento\Framework\Event\Observer::class,
             ['getEvent'],
@@ -65,10 +76,12 @@ class InvalidateVarnishObserverTest extends \PHPUnit_Framework_TestCase
         )->will(
             $this->returnValue(\Magento\PageCache\Model\Config::VARNISH)
         );
+
         $eventMock = $this->getMock(\Magento\Framework\Event::class, ['getObject'], [], '', false);
         $eventMock->expects($this->once())->method('getObject')->will($this->returnValue($this->observerObject));
         $this->observerMock->expects($this->once())->method('getEvent')->will($this->returnValue($eventMock));
-        $this->observerObject->expects($this->once())->method('getIdentities')->will($this->returnValue($tags));
+        $this->tagResolver->expects($this->once())->method('getTags')->with($this->observerObject)
+            ->will($this->returnValue($tags));
         $this->purgeCache->expects($this->once())->method('sendPurgeRequest')->with($pattern);
 
         $this->model->execute($this->observerMock);
diff --git a/app/code/Magento/Catalog/Console/Command/ProductAttributesCleanUp.php b/app/code/Magento/Catalog/Console/Command/ProductAttributesCleanUp.php
index 25364844e3a710a860b6260969e375eaf8c7da29..a0667abbf4680309db499a646abaadfc40fa82e5 100644
--- a/app/code/Magento/Catalog/Console/Command/ProductAttributesCleanUp.php
+++ b/app/code/Magento/Catalog/Console/Command/ProductAttributesCleanUp.php
@@ -101,11 +101,14 @@ class ProductAttributesCleanUp extends \Symfony\Component\Console\Command\Comman
             $output->writeln("");
             $output->writeln("<info>Unused product attributes successfully cleaned up:</info>");
             $output->writeln("<comment>  " . implode("\n  ", $attributeTables) . "</comment>");
+            return \Magento\Framework\Console\Cli::RETURN_SUCCESS;
         } catch (\Exception $exception) {
             $this->attributeResource->rollBack();
 
             $output->writeln("");
             $output->writeln("<error>{$exception->getMessage()}</error>");
+            // we must have an exit code higher than zero to indicate something was wrong
+            return \Magento\Framework\Console\Cli::RETURN_FAILURE;
         }
     }
 
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category.php
index 8f8f21e207bf577e3b94a6de936a0edd183af82c..071ba902f4fe0b7cc0c720377738fce052e4f64e 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Category.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category.php
@@ -31,7 +31,7 @@ abstract class Category extends \Magento\Backend\App\Action
      */
     protected function _initCategory($getRootInstead = false)
     {
-        $categoryId = (int)$this->getRequest()->getParam('id', false);
+        $categoryId = $this->resolveCategoryId();
         $storeId = (int)$this->getRequest()->getParam('store');
         $category = $this->_objectManager->create(\Magento\Catalog\Model\Category::class);
         $category->setStoreId($storeId);
@@ -62,6 +62,18 @@ abstract class Category extends \Magento\Backend\App\Action
         return $category;
     }
 
+    /**
+     * Resolve Category Id (from get or from post)
+     *
+     * @return int
+     */
+    private function resolveCategoryId()
+    {
+        $categoryId = (int)$this->getRequest()->getParam('id', false);
+
+        return $categoryId ?: (int)$this->getRequest()->getParam('entity_id', false);
+    }
+
     /**
      * Build response for ajax request
      *
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Edit.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Edit.php
index b2722ec01978582041aae63ee230841b6fc32111..847499901ccdba77f6b1cb2206830a5dc4a99a94 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Edit.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Edit.php
@@ -99,9 +99,10 @@ class Edit extends \Magento\Catalog\Controller\Adminhtml\Category
             return $this->ajaxRequestResponse($category, $resultPage);
         }
 
+        $resultPageTitle = $categoryId ? $category->getName() . ' (ID: ' . $categoryId . ')' : __('Categories');
         $resultPage->setActiveMenu('Magento_Catalog::catalog_categories');
         $resultPage->getConfig()->getTitle()->prepend(__('Categories'));
-        $resultPage->getConfig()->getTitle()->prepend($categoryId ? $category->getName() : __('Categories'));
+        $resultPage->getConfig()->getTitle()->prepend($resultPageTitle);
         $resultPage->addBreadcrumb(__('Manage Catalog Categories'), __('Manage Categories'));
 
         $block = $resultPage->getLayout()->getBlock('catalog.wysiwyg.js');
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Move.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Move.php
index ead95c544814a5fde74bcebc01b4bd11375a9efb..07f84ae0a393e53ebb0c84b41f71c98dfc11b010 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Move.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Move.php
@@ -80,7 +80,7 @@ class Move extends \Magento\Catalog\Controller\Adminhtml\Category
         }
 
         if (!$error) {
-            $this->messageManager->addSuccess(__('You moved the category'));
+            $this->messageManager->addSuccess(__('You moved the category.'));
         }
 
         $block->setMessages($this->messageManager->getMessages(true));
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 d402c81becf1ce21e636b6d36082a47ddcc2f155..d59492c4065e72706f8c1a168e4a33b1c2c9e825 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php
@@ -199,6 +199,9 @@ class Helper
             $customOptions = [];
             foreach ($options as $customOptionData) {
                 if (empty($customOptionData['is_delete'])) {
+                    if (empty($customOptionData['option_id'])) {
+                        $customOptionData['option_id'] = null;
+                    }
                     if (isset($customOptionData['values'])) {
                         $customOptionData['values'] = array_filter($customOptionData['values'], function ($valueData) {
                             return empty($valueData['is_delete']);
@@ -206,7 +209,6 @@ class Helper
                     }
                     $customOption = $this->getCustomOptionFactory()->create(['data' => $customOptionData]);
                     $customOption->setProductSku($product->getSku());
-                    $customOption->setOptionId(null);
                     $customOptions[] = $customOption;
                 }
             }
@@ -255,7 +257,7 @@ class Helper
 
         foreach ($linkTypes as $linkType => $readonly) {
             if (isset($links[$linkType]) && !$readonly) {
-                foreach ((array) $links[$linkType] as $linkData) {
+                foreach ((array)$links[$linkType] as $linkData) {
                     if (empty($linkData['id'])) {
                         continue;
                     }
@@ -321,9 +323,11 @@ class Helper
 
             if (isset($option['values']) && isset($overwriteOptions[$optionId]['values'])) {
                 foreach ($option['values'] as $valueIndex => $value) {
-                    $valueId = $value['option_type_id'];
-                    $value = $this->overwriteValue($valueId, $value, $overwriteOptions[$optionId]['values']);
-                    $option['values'][$valueIndex] = $value;
+                    if (isset($value['option_type_id'])) {
+                        $valueId = $value['option_type_id'];
+                        $value = $this->overwriteValue($valueId, $value, $overwriteOptions[$optionId]['values']);
+                        $option['values'][$valueIndex] = $value;
+                    }
                 }
             }
 
@@ -347,6 +351,9 @@ class Helper
             foreach ($overwriteOptions[$optionId] as $fieldName => $overwrite) {
                 if ($overwrite && isset($option[$fieldName]) && isset($option['default_' . $fieldName])) {
                     $option[$fieldName] = $option['default_' . $fieldName];
+                    if ('title' == $fieldName) {
+                        $option['is_delete_store_title'] = 1;
+                    }
                 }
             }
         }
diff --git a/app/code/Magento/Catalog/Helper/Product/Compare.php b/app/code/Magento/Catalog/Helper/Product/Compare.php
index 64b3411591455f40ef288daaa29d41c7e02bc2d1..69f4a613a5b9555e2c46038c2a6cc620b291ef60 100644
--- a/app/code/Magento/Catalog/Helper/Product/Compare.php
+++ b/app/code/Magento/Catalog/Helper/Product/Compare.php
@@ -228,10 +228,11 @@ class Compare extends \Magento\Framework\Url\Helper\Data
      */
     public function getPostDataRemove($product)
     {
-        $listCleanUrl = $this->getEncodedUrl($this->_getUrl('catalog/product_compare'));
         $data = [
-            \Magento\Framework\App\ActionInterface::PARAM_NAME_URL_ENCODED => $listCleanUrl,
-            'product' => $product->getId()
+            \Magento\Framework\App\ActionInterface::PARAM_NAME_URL_ENCODED => '',
+            'product' => $product->getId(),
+            'confirmation' => true,
+            'confirmationMessage' => __('Are you sure you want to remove this item from your Compare Products list?')
         ];
         return $this->postHelper->getPostData($this->getRemoveUrl(), $data);
     }
@@ -253,9 +254,10 @@ class Compare extends \Magento\Framework\Url\Helper\Data
      */
     public function getPostDataClearList()
     {
-        $refererUrl = $this->_getRequest()->getServer('HTTP_REFERER');
         $params = [
-            \Magento\Framework\App\ActionInterface::PARAM_NAME_URL_ENCODED => $this->urlEncoder->encode($refererUrl)
+            \Magento\Framework\App\ActionInterface::PARAM_NAME_URL_ENCODED => '',
+            'confirmation' => true,
+            'confirmationMessage' => __('Are you sure you want to remove all items from your Compare Products list?'),
         ];
         return $this->postHelper->getPostData($this->getClearListUrl(), $params);
     }
diff --git a/app/code/Magento/Catalog/Model/Category.php b/app/code/Magento/Catalog/Model/Category.php
index b1f9dbf8c327a46176208cec90f8130065d8400a..9e855e05c7ce388dd52c11829882d5b46f634d02 100644
--- a/app/code/Magento/Catalog/Model/Category.php
+++ b/app/code/Magento/Catalog/Model/Category.php
@@ -65,7 +65,7 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements
      */
     const TREE_ROOT_ID = 1;
 
-    const CACHE_TAG = 'catalog_category';
+    const CACHE_TAG = 'cat_c';
 
     /**#@+
      * Constants
diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Product/Action/Full.php b/app/code/Magento/Catalog/Model/Indexer/Category/Product/Action/Full.php
index ba093c0129855981551c574652a1fcf0dc5879c3..3c33c44cb0dc4c0f0b307f6f55aefad623d48a30 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Category/Product/Action/Full.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Category/Product/Action/Full.php
@@ -7,6 +7,13 @@ namespace Magento\Catalog\Model\Indexer\Category\Product\Action;
 
 class Full extends \Magento\Catalog\Model\Indexer\Category\Product\AbstractAction
 {
+    /**
+     * Whether to use main or temporary index table
+     *
+     * @var bool
+     */
+    protected $useTempTable = false;
+
     /**
      * Refresh entities index
      *
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/FlatTableBuilder.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/FlatTableBuilder.php
index 0036b3b2ab54a5a2f4ff104dbe7b8a3da4526d28..4375092591d194962b108e2ba0351b1a03fa7e5c 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/FlatTableBuilder.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/FlatTableBuilder.php
@@ -221,7 +221,11 @@ class FlatTableBuilder
 
         unset($tables[$entityTableName]);
 
-        $allColumns = array_merge(['entity_id', 'type_id', 'attribute_set_id'], $columnsList);
+        $allColumns = array_values(
+            array_unique(
+                array_merge(['entity_id', $linkField, 'type_id', 'attribute_set_id'], $columnsList)
+            )
+        );
 
         /* @var $status \Magento\Eav\Model\Entity\Attribute */
         $status = $this->_productIndexerHelper->getAttribute('status');
@@ -263,7 +267,7 @@ class FlatTableBuilder
 
             $select->joinLeft(
                 $temporaryTableName,
-                "e.entity_id = " . $temporaryTableName . ".entity_id",
+                sprintf('e.%1$s = %2$s.%1$s', $linkField, $temporaryTableName),
                 $columnsNames
             );
             $allColumns = array_merge($allColumns, $columnsNames);
@@ -277,7 +281,7 @@ class FlatTableBuilder
             if (!empty($columnValueNames)) {
                 $select->joinLeft(
                     $temporaryValueTableName,
-                    "e.${linkField} = " . $temporaryValueTableName . ".entity_id",
+                    sprintf('e.%1$s = %2$s.%1$s', $linkField, $temporaryTableName),
                     $columnValueNames
                 );
                 $allColumns = array_merge($allColumns, $columnValueNames);
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Table/Builder.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Table/Builder.php
new file mode 100644
index 0000000000000000000000000000000000000000..192f411c93b4ea48c1b753d88f586a25aca41838
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Table/Builder.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Catalog\Model\Indexer\Product\Flat\Table;
+
+/**
+ * Class Builder
+ */
+class Builder implements BuilderInterface
+{
+    /**
+     * @var \Magento\Framework\DB\Ddl\Table
+     */
+    private $tableInstance;
+
+    /**
+     * Builder constructor.
+     *
+     * @param \Magento\Framework\DB\Adapter\AdapterInterface $connection
+     * @param string $tableName
+     */
+    public function __construct(\Magento\Framework\DB\Adapter\AdapterInterface $connection, $tableName)
+    {
+        $this->tableInstance = $connection->newTable($tableName);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function addColumn($name, $type, $size = null, $options = [], $comment = null)
+    {
+        $this->tableInstance->addColumn($name, $type, $size, $options, $comment);
+        return $this;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getTable()
+    {
+        return $this->tableInstance;
+    }
+}
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Table/BuilderInterface.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Table/BuilderInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..b24db9ee74334b743988b4a964004c41a5c610c7
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Table/BuilderInterface.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Catalog\Model\Indexer\Product\Flat\Table;
+
+/**
+ * Interface BuilderInterface
+ */
+interface BuilderInterface
+{
+    /**
+     * Adds column to table.
+     *
+     * $options contains additional options for columns. Supported values are:
+     * - 'unsigned', for number types only. Default: FALSE.
+     * - 'precision', for numeric and decimal only. Default: taken from $size, if not set there then 0.
+     * - 'scale', for numeric and decimal only. Default: taken from $size, if not set there then 10.
+     * - 'default'. Default: not set.
+     * - 'nullable'. Default: TRUE.
+     * - 'primary', add column to primary index. Default: do not add.
+     * - 'primary_position', only for column in primary index. Default: count of primary columns + 1.
+     * - 'identity' or 'auto_increment'. Default: FALSE.
+     *
+     * @param string $name the column name
+     * @param string $type the column data type
+     * @param string|int|array $size the column length
+     * @param array $options array of additional options
+     * @param string $comment column description
+     * @return $this
+     * @throws \Zend_Db_Exception
+     */
+    public function addColumn($name, $type, $size = null, $options = [], $comment = null);
+
+    /**
+     * @return \Magento\Framework\DB\Ddl\Table
+     */
+    public function getTable();
+}
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/TableBuilder.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/TableBuilder.php
index fdc405b27d3fd8b8b41c69395397c38235c8412e..d00a720a91ddefdad1036c52a0c12d6c5f10d7b3 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/TableBuilder.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/TableBuilder.php
@@ -5,7 +5,7 @@
  */
 namespace Magento\Catalog\Model\Indexer\Product\Flat;
 
-use Magento\Framework\App\ResourceConnection;
+use Magento\Catalog\Model\Indexer\Product\Flat\Table\BuilderInterfaceFactory;
 
 /**
  * Class TableBuilder
@@ -32,6 +32,11 @@ class TableBuilder
      */
     protected $resource;
 
+    /**
+     * @var BuilderInterfaceFactory
+     */
+    private $tableBuilderFactory;
+
     /**
      * Check whether builder was executed
      *
@@ -123,17 +128,27 @@ class TableBuilder
         $valueTables = [];
         if (!empty($columns)) {
             $valueTableName = $tableName . $valueFieldSuffix;
-            $temporaryTable = $this->_connection->newTable($tableName);
-            $valueTemporaryTable = $this->_connection->newTable($valueTableName);
+            $temporaryTableBuilder = $this->getTableBuilderFactory()->create(
+                [
+                    'connection' => $this->_connection,
+                    'tableName' => $tableName
+                ]
+            );
+            $valueTemporaryTableBuilder = $this->getTableBuilderFactory()->create(
+                [
+                    'connection' => $this->_connection,
+                    'tableName' => $valueTableName
+                ]
+            );
             $flatColumns = $this->_productIndexerHelper->getFlatColumns();
 
-            $temporaryTable->addColumn('entity_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER);
+            $temporaryTableBuilder->addColumn('entity_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER);
 
-            $temporaryTable->addColumn('type_id', \Magento\Framework\DB\Ddl\Table::TYPE_TEXT);
+            $temporaryTableBuilder->addColumn('type_id', \Magento\Framework\DB\Ddl\Table::TYPE_TEXT);
 
-            $temporaryTable->addColumn('attribute_set_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER);
+            $temporaryTableBuilder->addColumn('attribute_set_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER);
 
-            $valueTemporaryTable->addColumn('entity_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER);
+            $valueTemporaryTableBuilder->addColumn('entity_id', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER);
 
             /** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */
             foreach ($columns as $columnName => $attribute) {
@@ -145,7 +160,7 @@ class TableBuilder
                     $column = $column[$attributeCode];
                 }
 
-                $temporaryTable->addColumn(
+                $temporaryTableBuilder->addColumn(
                     $columnName,
                     $column['type'],
                     isset($column['length']) ? $column['length'] : null
@@ -154,7 +169,7 @@ class TableBuilder
                 $columnValueName = $attributeCode . $valueFieldSuffix;
                 if (isset($flatColumns[$columnValueName])) {
                     $columnValue = $flatColumns[$columnValueName];
-                    $valueTemporaryTable->addColumn(
+                    $valueTemporaryTableBuilder->addColumn(
                         $columnValueName,
                         $columnValue['type'],
                         isset($columnValue['length']) ? $columnValue['length'] : null
@@ -162,11 +177,11 @@ class TableBuilder
                 }
             }
             $this->_connection->dropTemporaryTable($tableName);
-            $this->_connection->createTemporaryTable($temporaryTable);
+            $this->_connection->createTemporaryTable($temporaryTableBuilder->getTable());
 
-            if (count($valueTemporaryTable->getColumns()) > 1) {
+            if (count($valueTemporaryTableBuilder->getTable()->getColumns()) > 1) {
                 $this->_connection->dropTemporaryTable($valueTableName);
-                $this->_connection->createTemporaryTable($valueTemporaryTable);
+                $this->_connection->createTemporaryTable($valueTemporaryTableBuilder->getTable());
                 $valueTables[$valueTableName] = $valueTableName;
             }
         }
@@ -197,7 +212,8 @@ class TableBuilder
         if (!empty($columns)) {
             $select = $this->_connection->select();
             $temporaryEntityTable = $this->_getTemporaryTableName($tableName);
-            $idsColumns = ['entity_id', 'type_id', 'attribute_set_id'];
+            $metadata = $this->getMetadataPool()->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class);
+            $idsColumns = array_unique([$metadata->getLinkField(), 'entity_id', 'type_id', 'attribute_set_id']);
 
             $columns = array_merge($idsColumns, array_keys($columns));
 
@@ -261,7 +277,7 @@ class TableBuilder
                 );
                 $temporaryTableName = $this->_getTemporaryTableName($tableName);
                 $temporaryValueTableName = $temporaryTableName . $valueFieldSuffix;
-                $keyColumn = ['entity_id'];
+                $keyColumn = array_unique([$metadata->getLinkField(), 'entity_id']);
                 $columns = array_merge($keyColumn, array_keys($columnsList));
                 $valueColumns = $keyColumn;
                 $flatColumns = $this->_productIndexerHelper->getFlatColumns();
@@ -333,6 +349,19 @@ class TableBuilder
         }
     }
 
+    /**
+     * @return BuilderInterfaceFactory
+     */
+    private function getTableBuilderFactory()
+    {
+        if (null === $this->tableBuilderFactory) {
+            $this->tableBuilderFactory = \Magento\Framework\App\ObjectManager::getInstance()
+                ->get(BuilderInterfaceFactory::class);
+        }
+
+        return $this->tableBuilderFactory;
+    }
+
     /**
      * @return \Magento\Framework\EntityManager\MetadataPool
      */
diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php
index 603e566f14fa10c5ef39ce3ac1da20f200b791a3..9e9f18e0113717ad6853ea5d4512661a897e926c 100644
--- a/app/code/Magento/Catalog/Model/Product.php
+++ b/app/code/Magento/Catalog/Model/Product.php
@@ -58,12 +58,12 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
     /**
      * Product cache tag
      */
-    const CACHE_TAG = 'catalog_product';
+    const CACHE_TAG = 'cat_p';
 
     /**
      * Category product relation cache tag
      */
-    const CACHE_PRODUCT_CATEGORY_TAG = 'catalog_category_product';
+    const CACHE_PRODUCT_CATEGORY_TAG = 'cat_c_p';
 
     /**
      * Product Store Id
@@ -1909,10 +1909,12 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
      */
     public function getOptionById($optionId)
     {
-        /** @var \Magento\Catalog\Model\Product\Option $option */
-        foreach ($this->getOptions() as $option) {
-            if ($option->getId() == $optionId) {
-                return $option;
+        if (is_array($this->getOptions())) {
+            /** @var \Magento\Catalog\Model\Product\Option $option */
+            foreach ($this->getOptions() as $option) {
+                if ($option->getId() == $optionId) {
+                    return $option;
+                }
             }
         }
 
@@ -2272,7 +2274,7 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
                 $identities[] = self::CACHE_PRODUCT_CATEGORY_TAG . '_' . $categoryId;
             }
         }
-        
+
         if (($this->getOrigData('status') != $this->getData('status')) || $this->isStockStatusChanged()) {
             foreach ($this->getCategoryIds() as $categoryId) {
                 $identities[] = self::CACHE_PRODUCT_CATEGORY_TAG . '_' . $categoryId;
@@ -2287,7 +2289,7 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
 
     /**
      * Check whether stock status changed
-     * 
+     *
      * @return bool
      */
     private function isStockStatusChanged()
@@ -2305,7 +2307,7 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
             && ($stockItem->getIsInStock() != $stockData['is_in_stock'])
         );
     }
-    
+
     /**
      * Reload PriceInfo object
      *
diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php b/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php
index a41a89a4ac9f77f2000842b95e5b4c9865015114..7e7234d1ebbf83d99fdbae1889504beaddf9a4db 100644
--- a/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php
+++ b/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php
@@ -8,6 +8,7 @@ namespace Magento\Catalog\Model\Product\Attribute;
 
 use Magento\Framework\Exception\InputException;
 use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Eav\Api\Data\AttributeInterface;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -117,12 +118,17 @@ class Repository implements \Magento\Catalog\Api\ProductAttributeRepositoryInter
                 throw NoSuchEntityException::singleField('attribute_code', $existingModel->getAttributeCode());
             }
 
+            // Attribute code must not be changed after attribute creation
+            $attribute->setAttributeCode($existingModel->getAttributeCode());
             $attribute->setAttributeId($existingModel->getAttributeId());
             $attribute->setIsUserDefined($existingModel->getIsUserDefined());
             $attribute->setFrontendInput($existingModel->getFrontendInput());
 
             if (is_array($attribute->getFrontendLabels())) {
-                $frontendLabel[0] = $existingModel->getDefaultFrontendLabel();
+                $defaultFrontendLabel = $attribute->getDefaultFrontendLabel();
+                $frontendLabel[0] = !empty($defaultFrontendLabel)
+                    ? $defaultFrontendLabel
+                    : $existingModel->getDefaultFrontendLabel();
                 foreach ($attribute->getFrontendLabels() as $item) {
                     $frontendLabel[$item->getStoreId()] = $item->getLabel();
                 }
@@ -176,8 +182,11 @@ class Repository implements \Magento\Catalog\Api\ProductAttributeRepositoryInter
             $attribute->setIsUserDefined(1);
         }
         $this->attributeResource->save($attribute);
-        foreach ($attribute->getOptions() as $option) {
-            $this->getOptionManagement()->add($attribute->getAttributeCode(), $option);
+
+        if (!empty($attribute->getData(AttributeInterface::OPTIONS))) {
+            foreach ($attribute->getOptions() as $option) {
+                $this->getOptionManagement()->add($attribute->getAttributeCode(), $option);
+            }
         }
         return $this->get($attribute->getAttributeCode());
     }
diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php b/app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php
index ada156f571b0e60c8ff1a0ada71b308f9b62b38f..f17760237034041764539e533d5f1440b8dad3e4 100644
--- a/app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php
+++ b/app/code/Magento/Catalog/Model/Product/Gallery/CreateHandler.php
@@ -160,12 +160,13 @@ class CreateHandler implements ExtensionInterface
             if (in_array($attrData, array_keys($existImages))) {
                 $product->setData($mediaAttrCode . '_label', $existImages[$attrData]['label']);
             }
-
-            $product->addAttributeUpdate(
-                $mediaAttrCode,
-                $product->getData($mediaAttrCode),
-                $product->getStoreId()
-            );
+            if (!empty($product->getData($mediaAttrCode))) {
+                $product->addAttributeUpdate(
+                    $mediaAttrCode,
+                    $product->getData($mediaAttrCode),
+                    $product->getStoreId()
+                );
+            }
         }
 
         $product->setData($attrCode, $value);
diff --git a/app/code/Magento/Catalog/Model/Product/Option/Repository.php b/app/code/Magento/Catalog/Model/Product/Option/Repository.php
index d48bed8e3ccd08718e02c57d764e89c147ebf161..946bebd93c94029907b0ac7ed13dc6c1610b376c 100644
--- a/app/code/Magento/Catalog/Model/Product/Option/Repository.php
+++ b/app/code/Magento/Catalog/Model/Product/Option/Repository.php
@@ -137,10 +137,33 @@ class Repository implements \Magento\Catalog\Api\ProductCustomOptionRepositoryIn
         if (!$productSku) {
             throw new CouldNotSaveException(__('ProductSku should be specified'));
         }
+        /** @var \Magento\Catalog\Model\Product $product */
         $product = $this->productRepository->get($productSku);
         $metadata = $this->getMetadataPool()->getMetadata(ProductInterface::class);
         $option->setData('product_id', $product->getData($metadata->getLinkField()));
-        $option->setOptionId(null);
+        $option->setData('store_id', $product->getStoreId());
+
+        if ($option->getOptionId()) {
+            $options = $product->getOptions();
+            if (!$options) {
+                $options = $this->getProductOptions($product);
+            }
+
+            $persistedOption = array_filter($options, function ($iOption) use ($option) {
+                return $option->getOptionId() == $iOption->getOptionId();
+            });
+            $persistedOption = reset($persistedOption);
+
+            if (!$persistedOption) {
+                throw new NoSuchEntityException();
+            }
+            $originalValues = $persistedOption->getValues();
+            $newValues = $option->getData('values');
+            if ($newValues) {
+                $newValues = $this->markRemovedValues($newValues, $originalValues);
+                $option->setData('values', $newValues);
+            }
+        }
         $option->save();
         return $option;
     }
diff --git a/app/code/Magento/Catalog/Model/Product/Option/SaveHandler.php b/app/code/Magento/Catalog/Model/Product/Option/SaveHandler.php
index 7c32232b6591aeb9a99a9b63f0b40300cd11dfe4..1c8c5b018ddf3b19642242431205756795fce45f 100644
--- a/app/code/Magento/Catalog/Model/Product/Option/SaveHandler.php
+++ b/app/code/Magento/Catalog/Model/Product/Option/SaveHandler.php
@@ -20,7 +20,6 @@ class SaveHandler implements ExtensionInterface
 
     /**
      * @param OptionRepository $optionRepository
-     * @param MetadataPool $metadataPool
      */
     public function __construct(
         OptionRepository $optionRepository
@@ -36,15 +35,28 @@ class SaveHandler implements ExtensionInterface
      */
     public function execute($entity, $arguments = [])
     {
+        $options = $entity->getOptions();
+        $optionIds = [];
+
+        if ($options) {
+            $optionIds = array_map(function ($option) {
+                /** @var \Magento\Catalog\Model\Product\Option $option */
+                return $option->getOptionId();
+            }, $options);
+        }
+
         /** @var \Magento\Catalog\Api\Data\ProductInterface $entity */
         foreach ($this->optionRepository->getProductOptions($entity) as $option) {
-            $this->optionRepository->delete($option);
+            if (!in_array($option->getOptionId(), $optionIds)) {
+                $this->optionRepository->delete($option);
+            }
         }
-        if ($entity->getOptions()) {
-            foreach ($entity->getOptions() as $option) {
+        if ($options) {
+            foreach ($options as $option) {
                 $this->optionRepository->save($option);
             }
         }
+
         return $entity;
     }
 }
diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File.php
index d974174ef7088e4a14a9e031e7e266d827ceb13d..70c20a4e314903ce9defb0e40f50c912a83d7307 100644
--- a/app/code/Magento/Catalog/Model/Product/Option/Type/File.php
+++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\Catalog\Model\Product\Option\Type;
 
+use Magento\Framework\App\Filesystem\DirectoryList;
 use Magento\Framework\Filesystem;
 use Magento\Framework\Exception\LocalizedException;
 use Magento\Catalog\Model\Product\Exception as ProductException;
@@ -69,17 +70,23 @@ class File extends \Magento\Catalog\Model\Product\Option\Type\DefaultType
      */
     protected $validatorFile;
 
+    /**
+     * @var Filesystem
+     */
+    private $filesystem;
+
     /**
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Quote\Model\Quote\Item\OptionFactory $itemOptionFactory
-     * @param \Magento\Catalog\Model\Product\Option\UrlBuilder $urlBuilder
-     * @param \Magento\Framework\Escaper $escaper
      * @param \Magento\MediaStorage\Helper\File\Storage\Database $coreFileStorageDatabase
      * @param File\ValidatorInfo $validatorInfo
      * @param File\ValidatorFile $validatorFile
+     * @param \Magento\Catalog\Model\Product\Option\UrlBuilder $urlBuilder
+     * @param \Magento\Framework\Escaper $escaper
      * @param array $data
-     * @throws \Magento\Framework\Exception\FileSystemException
+     * @param Filesystem $filesystem
+     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function __construct(
         \Magento\Checkout\Model\Session $checkoutSession,
@@ -90,12 +97,15 @@ class File extends \Magento\Catalog\Model\Product\Option\Type\DefaultType
         \Magento\Catalog\Model\Product\Option\Type\File\ValidatorFile $validatorFile,
         \Magento\Catalog\Model\Product\Option\UrlBuilder $urlBuilder,
         \Magento\Framework\Escaper $escaper,
-        array $data = []
+        array $data = [],
+        Filesystem $filesystem = null
     ) {
         $this->_itemOptionFactory = $itemOptionFactory;
         $this->_urlBuilder = $urlBuilder;
         $this->_escaper = $escaper;
         $this->_coreFileStorageDatabase = $coreFileStorageDatabase;
+        $this->filesystem = $filesystem ?: \Magento\Framework\App\ObjectManager::getInstance()->get(Filesystem::class);
+        $this->_rootDirectory = $this->filesystem->getDirectoryRead(DirectoryList::MEDIA);
         $this->validatorInfo = $validatorInfo;
         $this->validatorFile = $validatorFile;
         parent::__construct($checkoutSession, $scopeConfig, $data);
diff --git a/app/code/Magento/Catalog/Model/Product/Option/Validator/Select.php b/app/code/Magento/Catalog/Model/Product/Option/Validator/Select.php
index ba7103a5eada1acac077ae3ce432e0187e1fbe22..d1a317be7c7e0c2d09cd0b5bbddf6ab3844c96d6 100644
--- a/app/code/Magento/Catalog/Model/Product/Option/Validator/Select.php
+++ b/app/code/Magento/Catalog/Model/Product/Option/Validator/Select.php
@@ -51,6 +51,9 @@ class Select extends DefaultValidator
             $storeId = $option->getProduct()->getStoreId();
         }
         foreach ($values as $value) {
+            if (isset($value['is_delete']) && (bool)$value['is_delete']) {
+                continue;
+            }
             $type = isset($value['price_type']) ? $value['price_type'] : null;
             $price = isset($value['price']) ? $value['price'] : null;
             $title = isset($value['title']) ? $value['title'] : null;
diff --git a/app/code/Magento/Catalog/Model/Product/Option/Value.php b/app/code/Magento/Catalog/Model/Product/Option/Value.php
index 55a14e26333547543a14e22b7dcbc0342442596d..55c7c74e9a8e62bf14233f8c8b9b90309adfee66 100644
--- a/app/code/Magento/Catalog/Model/Product/Option/Value.php
+++ b/app/code/Magento/Catalog/Model/Product/Option/Value.php
@@ -200,7 +200,7 @@ class Value extends AbstractModel implements \Magento\Catalog\Api\Data\ProductCu
                 'store_id',
                 $this->getOption()->getStoreId()
             );
-            $this->unsetData('option_type_id');
+
             if ($this->getData('is_delete') == '1') {
                 if ($this->getId()) {
                     $this->deleteValues($this->getId());
diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php
index 9ceaa8bc9d0498ea6db05e4574991fc2c466c6e3..4385c8add37aef25dc52a888d2ff839b49e734db 100644
--- a/app/code/Magento/Catalog/Model/ProductRepository.php
+++ b/app/code/Magento/Catalog/Model/ProductRepository.php
@@ -313,15 +313,22 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
      */
     private function assignProductToWebsites(\Magento\Catalog\Model\Product $product)
     {
+        $websiteIds = $product->getWebsiteIds();
+
         if (!$this->storeManager->hasSingleStore()) {
-            if ($this->storeManager->getStore()->getCode() == \Magento\Store\Model\Store::ADMIN_CODE) {
-                $websiteIds = array_keys($this->storeManager->getWebsites());
-            } else {
-                $websiteIds = [$this->storeManager->getStore()->getWebsiteId()];
-            }
+            $websiteIds = array_unique(
+                array_merge(
+                    $websiteIds,
+                    [$this->storeManager->getStore()->getWebsiteId()]
+                )
+            );
+        }
 
-            $product->setWebsiteIds(array_unique(array_merge($product->getWebsiteIds(), $websiteIds)));
+        if ($this->storeManager->getStore(true)->getCode() == \Magento\Store\Model\Store::ADMIN_CODE) {
+            $websiteIds = array_keys($this->storeManager->getWebsites());
         }
+
+        $product->setWebsiteIds($websiteIds);
     }
 
     /**
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Category.php b/app/code/Magento/Catalog/Model/ResourceModel/Category.php
index 3b3468656935db5d52773af72691ff789e9dd6a5..407c2027923de4c683272773d519cf1adc7b1917 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Category.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Category.php
@@ -33,6 +33,11 @@ class Category extends AbstractResource
      */
     protected $_categoryProductTable;
 
+    /**
+     * @var array[]
+     */
+    private $entitiesWhereAttributesIs;
+
     /**
      * Id of 'is_active' category attribute
      *
@@ -573,22 +578,29 @@ class Category extends AbstractResource
      */
     public function findWhereAttributeIs($entityIdsFilter, $attribute, $expectedValue)
     {
-        $linkField = $this->getLinkField();
-        $bind = ['attribute_id' => $attribute->getId(), 'value' => $expectedValue];
-        $selectEntities = $this->getConnection()->select()->from(
-            ['ce' => $this->getTable('catalog_category_entity')],
-            ['entity_id']
-        )->joinLeft(
-            ['ci' => $attribute->getBackend()->getTable()],
-            "ci.{$linkField} = ce.{$linkField} AND attribute_id = :attribute_id",
-            ['value']
-        )->where(
-            'ci.value = :value'
-        )->where(
-            'ce.entity_id IN (?)',
-            $entityIdsFilter
-        );
-        return $this->getConnection()->fetchCol($selectEntities, $bind);
+        $entityIdsFilterHash = md5(serialize($entityIdsFilter));
+
+        if (!isset($this->entitiesWhereAttributesIs[$entityIdsFilterHash][$attribute->getId()][$expectedValue])) {
+            $linkField = $this->getLinkField();
+            $bind = ['attribute_id' => $attribute->getId(), 'value' => $expectedValue];
+            $selectEntities = $this->getConnection()->select()->from(
+                ['ce' => $this->getTable('catalog_category_entity')],
+                ['entity_id']
+            )->joinLeft(
+                ['ci' => $attribute->getBackend()->getTable()],
+                "ci.{$linkField} = ce.{$linkField} AND attribute_id = :attribute_id",
+                ['value']
+            )->where(
+                'ci.value = :value'
+            )->where(
+                'ce.entity_id IN (?)',
+                $entityIdsFilter
+            );
+            $this->entitiesWhereAttributesIs[$entityIdsFilterHash][$attribute->getId()][$expectedValue] =
+                $this->getConnection()->fetchCol($selectEntities, $bind);
+        }
+
+        return $this->entitiesWhereAttributesIs[$entityIdsFilterHash][$attribute->getId()][$expectedValue];
     }
 
     /**
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/MaxHeapTableSizeProcessor.php b/app/code/Magento/Catalog/Model/ResourceModel/MaxHeapTableSizeProcessor.php
index 92946c7f2d9e11f415ff948f6899f44904d19c37..2e599c2af3d8799d6588b3a10b9e344563c1c077 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/MaxHeapTableSizeProcessor.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/MaxHeapTableSizeProcessor.php
@@ -7,6 +7,9 @@ namespace Magento\Catalog\Model\ResourceModel;
 
 use Magento\Framework\App\ResourceConnection;
 
+/**
+ * @deprecated
+ */
 class MaxHeapTableSizeProcessor
 {
     /**
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Option.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Option.php
index 7b23e5979c8b841d9468f4c93596d4138c24d692..8dcdf441d7b85f014a5b6aa0398aa21592b81932 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Option.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Option.php
@@ -247,14 +247,21 @@ class Option extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
         $titleTableName = $this->getTable('catalog_product_option_title');
         foreach ([\Magento\Store\Model\Store::DEFAULT_STORE_ID, $object->getStoreId()] as $storeId) {
             $existInCurrentStore = $this->getColFromOptionTable($titleTableName, (int)$object->getId(), (int)$storeId);
-            $existInDefaultStore = $this->getColFromOptionTable(
-                $titleTableName,
-                (int)$object->getId(),
-                \Magento\Store\Model\Store::DEFAULT_STORE_ID
-            );
+            $existInDefaultStore = (int)$storeId == \Magento\Store\Model\Store::DEFAULT_STORE_ID ?
+                $existInCurrentStore :
+                $this->getColFromOptionTable(
+                    $titleTableName,
+                    (int)$object->getId(),
+                    \Magento\Store\Model\Store::DEFAULT_STORE_ID
+                );
+
             if ($object->getTitle()) {
+                $isDeleteStoreTitle = (bool)$object->getData('is_delete_store_title');
                 if ($existInCurrentStore) {
-                    if ($object->getStoreId() == $storeId) {
+                    if ($isDeleteStoreTitle && (int)$storeId != \Magento\Store\Model\Store::DEFAULT_STORE_ID) {
+                        $connection->delete($titleTableName, ['option_title_id = ?' => $existInCurrentStore]);
+
+                    } elseif ($object->getStoreId() == $storeId) {
                         $data = $this->_prepareDataForTable(
                             new \Magento\Framework\DataObject(['title' => $object->getTitle()]),
                             $titleTableName
@@ -270,8 +277,13 @@ class Option extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
                     }
                 } else {
                     // we should insert record into not default store only of if it does not exist in default store
-                    if (($storeId == \Magento\Store\Model\Store::DEFAULT_STORE_ID && !$existInDefaultStore)
-                        || ($storeId != \Magento\Store\Model\Store::DEFAULT_STORE_ID && !$existInCurrentStore)
+                    if (
+                        ($storeId == \Magento\Store\Model\Store::DEFAULT_STORE_ID && !$existInDefaultStore) ||
+                        (
+                            $storeId != \Magento\Store\Model\Store::DEFAULT_STORE_ID &&
+                            !$existInCurrentStore &&
+                            !$isDeleteStoreTitle
+                        )
                     ) {
                         $data = $this->_prepareDataForTable(
                             new \Magento\Framework\DataObject(
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php
index 39a67f9722e185894640178329d008de10cb574e..4f3d65800d9457194f4b26817353cc1e281c0dd7 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Option/Value.php
@@ -33,6 +33,11 @@ class Value extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
      */
     protected $_config;
 
+    /**
+     * @var \Magento\Framework\Locale\FormatInterface
+     */
+    private $localeFormat;
+
     /**
      * Class constructor
      *
@@ -91,8 +96,9 @@ class Value extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
     protected function _saveValuePrices(\Magento\Framework\Model\AbstractModel $object)
     {
         $priceTable = $this->getTable('catalog_product_option_type_price');
+        $formattedPrice = $this->getLocaleFormatter()->getNumber($object->getPrice());
 
-        $price = (double)sprintf('%F', $object->getPrice());
+        $price = (double)sprintf('%F', $formattedPrice);
         $priceType = $object->getPriceType();
 
         if ($object->getPrice() && $priceType) {
@@ -231,6 +237,11 @@ class Value extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
             );
             $optionTypeId = $this->getConnection()->fetchOne($select);
             $existInCurrentStore = $this->getOptionIdFromOptionTable($titleTable, (int)$object->getId(), (int)$storeId);
+
+            if ($storeId != \Magento\Store\Model\Store::DEFAULT_STORE_ID && $object->getData('is_delete_store_title')) {
+                $object->unsetData('title');
+            }
+
             if ($object->getTitle()) {
                 if ($existInCurrentStore) {
                     if ($storeId == $object->getStoreId()) {
@@ -410,4 +421,19 @@ class Value extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
 
         return $object;
     }
+
+    /**
+     * Get FormatInterface to convert price from string to number format
+     *
+     * @return \Magento\Framework\Locale\FormatInterface
+     * @deprecated
+     */
+    private function getLocaleFormatter()
+    {
+        if ($this->localeFormat === null) {
+            $this->localeFormat = \Magento\Framework\App\ObjectManager::getInstance()
+                ->get(\Magento\Framework\Locale\FormatInterface::class);
+        }
+        return $this->localeFormat;
+    }
 }
diff --git a/app/code/Magento/Catalog/Plugin/Model/Indexer/Category/Product/MaxHeapTableSizeProcessorOnFullReindex.php b/app/code/Magento/Catalog/Plugin/Model/Indexer/Category/Product/MaxHeapTableSizeProcessorOnFullReindex.php
index a4cd503c6b08b610a29ea5d3417d1aab81589a9d..f14156c7f09e7c5a6ceb15192a7f31fd1d44581a 100644
--- a/app/code/Magento/Catalog/Plugin/Model/Indexer/Category/Product/MaxHeapTableSizeProcessorOnFullReindex.php
+++ b/app/code/Magento/Catalog/Plugin/Model/Indexer/Category/Product/MaxHeapTableSizeProcessorOnFullReindex.php
@@ -10,6 +10,9 @@ use Magento\Catalog\Model\Indexer\Category\Product\Action\Full;
 use Magento\Catalog\Model\ResourceModel\MaxHeapTableSizeProcessor;
 use Psr\Log\LoggerInterface;
 
+/**
+ * @deprecated
+ */
 class MaxHeapTableSizeProcessorOnFullReindex
 {
     /**
diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Options/AjaxTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Options/AjaxTest.php
index 78c50d5925ad7c61c206bd6844cdc058bb7e2c6a..42f588eb47c98891e81dde579572ff79a95b7c79 100644
--- a/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Options/AjaxTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Block/Adminhtml/Product/Options/AjaxTest.php
@@ -53,7 +53,7 @@ class AjaxTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->setMethods(['dispatch'])
             ->getMock();
-        $eventManager->expects($this->once())->method('dispatch')->will($this->returnValue(true));
+        $eventManager->expects($this->exactly(2))->method('dispatch')->will($this->returnValue(true));
 
         $scopeConfig = $this->getMockBuilder(\Magento\Framework\App\Config::class)
             ->setMethods(['getValue'])
diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Product/ListProductTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Product/ListProductTest.php
index 38ef297e684267c17c128298147343c979c43f85..f420f140b35820e3cbcebf986ed305217523aab2 100644
--- a/app/code/Magento/Catalog/Test/Unit/Block/Product/ListProductTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Block/Product/ListProductTest.php
@@ -114,8 +114,8 @@ class ListProductTest extends \PHPUnit_Framework_TestCase
 
     public function testGetIdentities()
     {
-        $productTag = 'catalog_product_1';
-        $categoryTag = 'catalog_category_product_1';
+        $productTag = 'cat_p_1';
+        $categoryTag = 'cat_c_p_1';
 
         $this->productMock->expects($this->once())
             ->method('getIdentities')
diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Product/ViewTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Product/ViewTest.php
index d030cf456b6b13e9e8dfa240df6252d4016decd4..f0287e05a4b7b3b94f837e9adec3e4a43667e34c 100644
--- a/app/code/Magento/Catalog/Test/Unit/Block/Product/ViewTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Block/Product/ViewTest.php
@@ -32,7 +32,7 @@ class ViewTest extends \PHPUnit_Framework_TestCase
         $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
         $this->productTypeConfig = $this->getMock(\Magento\Catalog\Model\ProductTypes\ConfigInterface::class);
         $this->registryMock = $this->getMock(\Magento\Framework\Registry::class, [], [], '', false);
-        $this->view = $helper->getObject(
+        $this->view = $helper->getObject(
             \Magento\Catalog\Block\Product\View::class,
             ['productTypeConfig' => $this->productTypeConfig, 'registry' => $this->registryMock]
         );
@@ -65,7 +65,7 @@ class ViewTest extends \PHPUnit_Framework_TestCase
 
     public function testGetIdentities()
     {
-        $productTags = ['catalog_product_1'];
+        $productTags = ['cat_p_1'];
         $product = $this->getMock(\Magento\Catalog\Model\Product::class, [], [], '', false);
         $category = $this->getMock(\Magento\Catalog\Model\Category::class, [], [], '', false);
 
@@ -84,6 +84,6 @@ class ViewTest extends \PHPUnit_Framework_TestCase
                 ]
             )
         );
-        $this->assertEquals(['catalog_product_1', 'catalog_category_1'], $this->view->getIdentities());
+        $this->assertEquals(['cat_p_1', 'cat_c_1'], $this->view->getIdentities());
     }
 }
diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Product/Widget/NewWidgetTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Product/Widget/NewWidgetTest.php
index cfd009787158a2ca6be43b9273efafb05493611a..a42f3354f98e8c65fa2feb704145dfeb7cbf123f 100644
--- a/app/code/Magento/Catalog/Test/Unit/Block/Product/Widget/NewWidgetTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Block/Product/Widget/NewWidgetTest.php
@@ -186,7 +186,7 @@ class NewWidgetTest extends \PHPUnit_Framework_TestCase
 
     protected function generalGetProductCollection()
     {
-        $this->eventManager->expects($this->once())->method('dispatch')
+        $this->eventManager->expects($this->exactly(2))->method('dispatch')
             ->will($this->returnValue(true));
         $this->scopeConfig->expects($this->once())->method('getValue')->withAnyParameters()
             ->willReturn(false);
diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php
index 389599f510f08961211d7cc212b757db9620547a..a4218e92b3486db76afc61254553b914610d99c3 100644
--- a/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/HelperTest.php
@@ -6,10 +6,11 @@
 namespace Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\Initialization;
 
 use Magento\Catalog\Api\Data\ProductLinkInterfaceFactory;
-use Magento\Catalog\Api\ProductRepositoryInterface\Proxy as ProductRepository;
 use Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper;
 use Magento\Catalog\Controller\Adminhtml\Product\Initialization\StockDataFilter;
 use Magento\Catalog\Model\Product;
+use Magento\Catalog\Model\Product\Option;
+use Magento\Catalog\Model\ProductRepository;
 use Magento\Framework\App\RequestInterface;
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
 use Magento\Store\Api\Data\StoreInterface;
@@ -17,7 +18,6 @@ use Magento\Store\Api\Data\WebsiteInterface;
 use Magento\Store\Model\StoreManagerInterface;
 use Magento\Framework\Stdlib\DateTime\Filter\Date as DateFilter;
 use Magento\Catalog\Api\Data\ProductCustomOptionInterfaceFactory;
-use Magento\Catalog\Api\Data\ProductCustomOptionInterface;
 use Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks;
 
 /**
@@ -95,7 +95,7 @@ class HelperTest extends \PHPUnit_Framework_TestCase
     protected $customOptionFactoryMock;
 
     /**
-     * @var ProductCustomOptionInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var Option|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $customOptionMock;
 
@@ -136,8 +136,6 @@ class HelperTest extends \PHPUnit_Framework_TestCase
             ->getMock();
         $this->productMock = $this->getMockBuilder(Product::class)
             ->setMethods([
-                'setData',
-                'addData',
                 'getId',
                 'setWebsiteIds',
                 'isLockedAttribute',
@@ -145,7 +143,6 @@ class HelperTest extends \PHPUnit_Framework_TestCase
                 'getAttributes',
                 'unlockAttribute',
                 'getOptionsReadOnly',
-                'setOptions',
                 'setCanSaveCustomOptions',
                 '__sleep',
                 '__wakeup',
@@ -159,9 +156,10 @@ class HelperTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->setMethods(['create'])
             ->getMock();
-        $this->customOptionMock = $this->getMockBuilder(ProductCustomOptionInterface::class)
+        $this->customOptionMock = $this->getMockBuilder(Option::class)
             ->disableOriginalConstructor()
-            ->getMockForAbstractClass();
+            ->setMethods(null)
+            ->getMock();
         $this->productLinksMock = $this->getMockBuilder(ProductLinks::class)
             ->disableOriginalConstructor()
             ->getMock();
@@ -196,14 +194,10 @@ class HelperTest extends \PHPUnit_Framework_TestCase
      */
     public function testInitialize()
     {
-        $this->customOptionMock->expects($this->once())
-            ->method('setProductSku');
-        $this->customOptionMock->expects($this->once())
-            ->method('setOptionId');
-
         $optionsData = [
-            'option1' => ['is_delete' => true, 'name' => 'name1', 'price' => 'price1'],
-            'option2' => ['is_delete' => false, 'name' => 'name1', 'price' => 'price1'],
+            'option1' => ['is_delete' => true, 'name' => 'name1', 'price' => 'price1', 'option_id' => ''],
+            'option2' => ['is_delete' => false, 'name' => 'name1', 'price' => 'price1', 'option_id' => '13'],
+            'option3' => ['is_delete' => false, 'name' => 'name1', 'price' => 'price1', 'option_id' => '14']
         ];
         $productData = [
             'stock_data' => ['stock_data'],
@@ -277,29 +271,38 @@ class HelperTest extends \PHPUnit_Framework_TestCase
             ->method('getAttributes')
             ->willReturn($attributesArray);
 
-        $productData['category_ids'] = [];
-        $productData['website_ids'] = [];
-        unset($productData['options']);
-
-        $this->productMock->expects($this->once())
-            ->method('addData')
-            ->with($productData);
-        $this->productMock->expects($this->once())
+        $this->productMock->expects($this->any())
             ->method('getSku')
             ->willReturn('sku');
         $this->productMock->expects($this->any())
             ->method('getOptionsReadOnly')
             ->willReturn(false);
 
+        $firstExpectedCustomOption = clone $this->customOptionMock;
+        $firstExpectedCustomOption->setData($optionsData['option2']);
+        $secondExpectedCustomOption = clone $this->customOptionMock;
+        $secondExpectedCustomOption->setData($optionsData['option3']);
         $this->customOptionFactoryMock->expects($this->any())
             ->method('create')
-            ->with(['data' => $optionsData['option2']])
-            ->willReturn($this->customOptionMock);
-        $this->productMock->expects($this->once())
-            ->method('setOptions')
-            ->with([$this->customOptionMock]);
+            ->willReturnMap([
+                [
+                    ['data' => $optionsData['option2']],
+                    $firstExpectedCustomOption
+                ], [
+                    ['data' => $optionsData['option3']],
+                    $secondExpectedCustomOption
+                ]
+            ]);
 
         $this->assertEquals($this->productMock, $this->helper->initialize($this->productMock));
+
+        $productOptions = $this->productMock->getOptions();
+        $this->assertTrue(2 == count($productOptions));
+        list($option2, $option3) = $productOptions;
+        $this->assertTrue($option2->getOptionId() == $optionsData['option2']['option_id']);
+        $this->assertTrue('sku' == $option2->getData('product_sku'));
+        $this->assertTrue($option3->getOptionId() == $optionsData['option3']['option_id']);
+        $this->assertTrue('sku' == $option2->getData('product_sku'));
     }
 
     /**
@@ -362,9 +365,9 @@ class HelperTest extends \PHPUnit_Framework_TestCase
                     [
                         'option_id' => '5',
                         'key1' => 'val1',
-                        'key2' => 'val2',
+                        'title' => 'val2',
                         'default_key1' => 'val3',
-                        'default_key2' => 'val4',
+                        'default_title' => 'val4',
                         'values' => [
                             [
                                 'option_type_id' => '2',
@@ -379,7 +382,7 @@ class HelperTest extends \PHPUnit_Framework_TestCase
                 [
                     5 => [
                         'key1' => '0',
-                        'key2' => '1',
+                        'title' => '1',
                         'values' => [2 => ['key1' => 1]]
                     ]
                 ],
@@ -387,9 +390,10 @@ class HelperTest extends \PHPUnit_Framework_TestCase
                     [
                         'option_id' => '5',
                         'key1' => 'val1',
-                        'key2' => 'val4',
+                        'title' => 'val4',
                         'default_key1' => 'val3',
-                        'default_key2' => 'val4',
+                        'default_title' => 'val4',
+                        'is_delete_store_title' => 1,
                         'values' => [
                             [
                                 'option_type_id' => '2',
@@ -413,8 +417,9 @@ class HelperTest extends \PHPUnit_Framework_TestCase
                             [
                                 'option_type_id' => '2',
                                 'key1' => 'val1',
-                                'key2' => 'val2',
-                                'default_key1' => 'val11'
+                                'title' => 'val2',
+                                'default_key1' => 'val11',
+                                'default_title' => 'val22'
                             ]
                         ]
                     ]
@@ -423,7 +428,7 @@ class HelperTest extends \PHPUnit_Framework_TestCase
                     7 => [
                         'key1' => '1',
                         'key2' => '1',
-                        'values' => [2 => ['key1' => 1, 'key2' => 1]]
+                        'values' => [2 => ['key1' => 0, 'title' => 1]]
                     ]
                 ],
                 [
@@ -435,9 +440,11 @@ class HelperTest extends \PHPUnit_Framework_TestCase
                         'values' => [
                             [
                                 'option_type_id' => '2',
-                                'key1' => 'val11',
-                                'key2' => 'val2',
-                                'default_key1' => 'val11'
+                                'key1' => 'val1',
+                                'title' => 'val22',
+                                'default_key1' => 'val11',
+                                'default_title' => 'val22',
+                                'is_delete_store_title' => 1
                             ]
                         ]
                     ]
diff --git a/app/code/Magento/Catalog/Test/Unit/Controller/Category/MoveTest.php b/app/code/Magento/Catalog/Test/Unit/Controller/Category/MoveTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7196074ab03e2707814a1a01001ca4e381fd4913
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Unit/Controller/Category/MoveTest.php
@@ -0,0 +1,320 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Catalog\Test\Unit\Controller\Category;
+
+use Magento\Catalog\Controller\Adminhtml\Category\Move;
+use Magento\Framework\Message\ManagerInterface;
+use Magento\Framework\ObjectManagerInterface;
+use Magento\Framework\Registry;
+
+/**
+ * Class MoveTest
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class MoveTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\Controller\Result\JsonFactory | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $resultJsonFactoryMock;
+
+    /**
+     * @var \Magento\Framework\View\LayoutFactory | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $layoutFactoryMock;
+
+    /**
+     * @var \Psr\Log\LoggerInterface | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $loggerMock;
+
+    /**
+     * @var \Magento\Backend\App\Action\Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $context;
+
+    /**
+     * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $request;
+
+    /**
+     * @var \Magento\Catalog\Controller\Adminhtml\Category\Move
+     */
+    private $moveController;
+
+    /**
+     * @var ObjectManagerInterface | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $objectManager;
+
+    /**
+     * @var ManagerInterface | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $messageManager;
+
+    public function setUp()
+    {
+        $this->resultJsonFactoryMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\JsonFactory::class)
+            ->setMethods(['create'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->layoutFactoryMock = $this->getMockBuilder(\Magento\Framework\View\LayoutFactory::class)
+            ->setMethods(['create'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->context = $this->getMock(\Magento\Backend\App\Action\Context::class, [], [], '', false);
+        $this->loggerMock = $this->getMock(\Psr\Log\LoggerInterface::class);
+        $this->fillContext();
+
+        $this->moveController = new Move(
+            $this->context,
+            $this->resultJsonFactoryMock,
+            $this->layoutFactoryMock,
+            $this->loggerMock
+        );
+        $this->initObjectManager();
+    }
+
+    private function fillContext()
+    {
+        $this->request = $this
+            ->getMockBuilder(\Magento\Framework\App\RequestInterface::class)
+            ->setMethods(['getPost'])
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $this->context->expects($this->once())->method('getRequest')->will($this->returnValue($this->request));
+        $this->messageManager = $this->getMock(ManagerInterface::class);
+        $this->context->expects($this->once())->method('getMessageManager')->willReturn($this->messageManager);
+    }
+
+    private function initObjectManager()
+    {
+        $this->objectManager = $this->getMock(ObjectManagerInterface::class);
+        $moveController = new \ReflectionClass($this->moveController);
+        $objectManagerProp = $moveController->getProperty('_objectManager');
+        $objectManagerProp->setAccessible(true);
+        $objectManagerProp->setValue($this->moveController, $this->objectManager);
+    }
+
+    public function testExecuteWithGenericException()
+    {
+        $messagesCollection = $this->getMockBuilder(\Magento\Framework\Message\Collection::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $messageBlock = $this->getMockBuilder(\Magento\Framework\View\Element\Messages::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $layoutMock = $this->getMock(\Magento\Framework\View\LayoutInterface::class);
+        $this->layoutFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($layoutMock);
+        $layoutMock->expects($this->once())
+            ->method('getMessagesBlock')
+            ->willReturn($messageBlock);
+        $wysiwigConfig = $this->getMockBuilder(\Magento\Cms\Model\Wysiwyg\Config::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $registry = $this->getMockBuilder(Registry::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $categoryMock = $this->getMockBuilder(\Magento\Catalog\Model\Category::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->request->expects($this->exactly(2))
+            ->method('getPost')
+            ->withConsecutive(['pid', false], ['aid', false])
+            ->willReturnMap([['pid', false, 2], ['aid', false, 1]]);
+        $this->objectManager->expects($this->once())
+            ->method('create')
+            ->with(\Magento\Catalog\Model\Category::class)
+            ->willReturn($categoryMock);
+        $this->objectManager->expects($this->any())
+            ->method('get')
+            ->withConsecutive([Registry::class], [Registry::class], [\Magento\Cms\Model\Wysiwyg\Config::class])
+            ->willReturnMap([[Registry::class, $registry], [\Magento\Cms\Model\Wysiwyg\Config::class, $wysiwigConfig]]);
+        $categoryMock->expects($this->once())
+            ->method('move')
+            ->willThrowException(new \Exception(
+                __('Some exception')
+            ));
+        $this->messageManager->expects($this->once())
+            ->method('addError')
+            ->with(__('There was a category move error.'));
+        $this->messageManager->expects($this->once())
+            ->method('getMessages')
+            ->with(true)
+            ->willReturn($messagesCollection);
+        $messageBlock->expects($this->once())
+            ->method('setMessages')
+            ->with($messagesCollection);
+        $resultJsonMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Json::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $messageBlock->expects($this->once())
+            ->method('getGroupedHtml')
+            ->willReturn('<body></body>');
+        $resultJsonMock->expects($this->once())
+            ->method('setData')
+            ->with(
+                [
+                    'messages' => '<body></body>',
+                    'error' => true
+                ]
+            )
+            ->willReturn(true);
+        $this->resultJsonFactoryMock
+            ->expects($this->once())
+            ->method('create')
+            ->willReturn($resultJsonMock);
+        $this->assertTrue($this->moveController->execute());
+    }
+
+    public function testExecuteWithLocaliedException()
+    {
+        $exceptionMessage = 'Sorry, but we can\'t find the new category you selected.';
+        $messagesCollection = $this->getMockBuilder(\Magento\Framework\Message\Collection::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $messageBlock = $this->getMockBuilder(\Magento\Framework\View\Element\Messages::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $layoutMock = $this->getMock(\Magento\Framework\View\LayoutInterface::class);
+        $this->layoutFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($layoutMock);
+        $layoutMock->expects($this->once())
+            ->method('getMessagesBlock')
+            ->willReturn($messageBlock);
+        $wysiwigConfig = $this->getMockBuilder(\Magento\Cms\Model\Wysiwyg\Config::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $registry = $this->getMockBuilder(Registry::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $categoryMock = $this->getMockBuilder(\Magento\Catalog\Model\Category::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->request->expects($this->exactly(2))
+            ->method('getPost')
+            ->withConsecutive(['pid', false], ['aid', false])
+            ->willReturnMap([['pid', false, 2], ['aid', false, 1]]);
+        $this->objectManager->expects($this->once())
+            ->method('create')
+            ->with(\Magento\Catalog\Model\Category::class)
+            ->willReturn($categoryMock);
+        $this->objectManager->expects($this->any())
+            ->method('get')
+            ->withConsecutive([Registry::class], [Registry::class], [\Magento\Cms\Model\Wysiwyg\Config::class])
+            ->willReturnMap([[Registry::class, $registry], [\Magento\Cms\Model\Wysiwyg\Config::class, $wysiwigConfig]]);
+        $this->messageManager->expects($this->once())
+            ->method('addError')
+            ->with($exceptionMessage);
+        $this->messageManager->expects($this->once())
+            ->method('getMessages')
+            ->with(true)
+            ->willReturn($messagesCollection);
+        $messageBlock->expects($this->once())
+            ->method('setMessages')
+            ->with($messagesCollection);
+        $resultJsonMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Json::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $messageBlock->expects($this->once())
+            ->method('getGroupedHtml')
+            ->willReturn('<body></body>');
+        $resultJsonMock->expects($this->once())
+            ->method('setData')
+            ->with(
+                [
+                    'messages' => '<body></body>',
+                    'error' => true
+                ]
+            )
+            ->willReturn(true);
+        $categoryMock->expects($this->once())
+            ->method('move')
+            ->willThrowException(new \Magento\Framework\Exception\LocalizedException(
+                __($exceptionMessage)
+            ));
+        $this->resultJsonFactoryMock
+            ->expects($this->once())
+            ->method('create')
+            ->willReturn($resultJsonMock);
+        $this->assertTrue($this->moveController->execute());
+    }
+
+    public function testSuccessfullCategorySave()
+    {
+        $messagesCollection = $this->getMockBuilder(\Magento\Framework\Message\Collection::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $messageBlock = $this->getMockBuilder(\Magento\Framework\View\Element\Messages::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $layoutMock = $this->getMock(\Magento\Framework\View\LayoutInterface::class);
+        $this->layoutFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($layoutMock);
+        $layoutMock->expects($this->once())
+            ->method('getMessagesBlock')
+            ->willReturn($messageBlock);
+        $wysiwigConfig = $this->getMockBuilder(\Magento\Cms\Model\Wysiwyg\Config::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $registry = $this->getMockBuilder(Registry::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $categoryMock = $this->getMockBuilder(\Magento\Catalog\Model\Category::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->request->expects($this->exactly(2))
+            ->method('getPost')
+            ->withConsecutive(['pid', false], ['aid', false])
+            ->willReturnMap([['pid', false, 2], ['aid', false, 1]]);
+        $this->objectManager->expects($this->once())
+            ->method('create')
+            ->with(\Magento\Catalog\Model\Category::class)
+            ->willReturn($categoryMock);
+        $this->objectManager->expects($this->any())
+            ->method('get')
+            ->withConsecutive([Registry::class], [Registry::class], [\Magento\Cms\Model\Wysiwyg\Config::class])
+            ->willReturnMap([[Registry::class, $registry], [\Magento\Cms\Model\Wysiwyg\Config::class, $wysiwigConfig]]);
+        $this->messageManager->expects($this->once())
+            ->method('getMessages')
+            ->with(true)
+            ->willReturn($messagesCollection);
+        $messageBlock->expects($this->once())
+            ->method('setMessages')
+            ->with($messagesCollection);
+        $resultJsonMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\Json::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $messageBlock->expects($this->once())
+            ->method('getGroupedHtml')
+            ->willReturn('<body></body>');
+        $resultJsonMock->expects($this->once())
+            ->method('setData')
+            ->with(
+                [
+                    'messages' => '<body></body>',
+                    'error' => false
+                ]
+            )
+            ->willReturn(true);
+        $this->messageManager->expects($this->once())
+            ->method('addSuccess')
+            ->with(__('You moved the category.'));
+        $categoryMock->expects($this->once())
+            ->method('move')
+            ->with(2, 1);
+        $this->resultJsonFactoryMock
+            ->expects($this->once())
+            ->method('create')
+            ->willReturn($resultJsonMock);
+        $this->assertTrue($this->moveController->execute());
+    }
+}
diff --git a/app/code/Magento/Catalog/Test/Unit/Helper/Product/CompareTest.php b/app/code/Magento/Catalog/Test/Unit/Helper/Product/CompareTest.php
index 29786ecdce9696488fecc87b1840a35baa6ed1a8..51388c3725ba9dc430137514ba3c3fc103237d1f 100644
--- a/app/code/Magento/Catalog/Test/Unit/Helper/Product/CompareTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Helper/Product/CompareTest.php
@@ -113,18 +113,15 @@ class CompareTest extends \PHPUnit_Framework_TestCase
         //Data
         $productId = 1;
         $removeUrl = 'catalog/product_compare/remove';
-        $compareListUrl = 'catalog/product_compare';
         $postParams = [
-            Action::PARAM_NAME_URL_ENCODED => strtr(base64_encode($compareListUrl), '+/=', '-_,'),
-            'product' => $productId
+            Action::PARAM_NAME_URL_ENCODED => '',
+            'product' => $productId,
+            'confirmation' => true,
+            'confirmationMessage' => __('Are you sure you want to remove this item from your Compare Products list?'),
         ];
 
         //Verification
-        $this->urlBuilder->expects($this->at(0))
-            ->method('getUrl')
-            ->with($compareListUrl)
-            ->will($this->returnValue($compareListUrl));
-        $this->urlBuilder->expects($this->at(1))
+        $this->urlBuilder->expects($this->once())
             ->method('getUrl')
             ->with($removeUrl)
             ->will($this->returnValue($removeUrl));
@@ -159,18 +156,14 @@ class CompareTest extends \PHPUnit_Framework_TestCase
     public function testGetPostDataClearList()
     {
         //Data
-        $refererUrl = 'home/';
         $clearUrl = 'catalog/product_compare/clear';
         $postParams = [
-            Action::PARAM_NAME_URL_ENCODED => strtr(base64_encode($refererUrl), '+/=', '-_,')
+            Action::PARAM_NAME_URL_ENCODED => '',
+            'confirmation' => true,
+            'confirmationMessage' => __('Are you sure you want to remove all items from your Compare Products list?'),
         ];
 
         //Verification
-        $this->request->expects($this->once())
-            ->method('getServer')
-            ->with('HTTP_REFERER')
-            ->will($this->returnValue($refererUrl));
-
         $this->urlBuilder->expects($this->once())
             ->method('getUrl')
             ->with($clearUrl)
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/FlatTableBuilderTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/FlatTableBuilderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c57dd950dc3e01c038631b52d2eb76657f1c25b1
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/FlatTableBuilderTest.php
@@ -0,0 +1,204 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Catalog\Test\Unit\Model\Indexer\Product\Flat;
+
+use Magento\Catalog\Api\Data\ProductInterface;
+
+/**
+ * Class FlatTableBuilderTest
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class FlatTableBuilderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Helper\Product\Flat\Indexer|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $flatIndexerMock;
+
+    /**
+     * @var \Magento\Framework\App\ResourceConnection|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $resourceMock;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $scopeConfigMock;
+
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $storeManagerMock;
+
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Flat\TableDataInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $tableDataMock;
+
+    /**
+     * @var \Magento\Framework\DB\Adapter\AdapterInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $connectionMock;
+
+    /**
+     * @var \Magento\Framework\EntityManager\MetadataPool|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $metadataPoolMock;
+
+    /**
+     * @var \Magento\Framework\EntityManager\EntityMetadataInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $metadataMock;
+
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Flat\FlatTableBuilder
+     */
+    private $flatTableBuilder;
+
+    protected function setUp()
+    {
+        $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->flatIndexerMock = $this->getMockBuilder(\Magento\Catalog\Helper\Product\Flat\Indexer::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resourceMock = $this->getMockBuilder(\Magento\Framework\App\ResourceConnection::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->scopeConfigMock = $this->getMockBuilder(\Magento\Framework\App\Config\ScopeConfigInterface::class)
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $this->storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class)
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $this->tableDataMock = $this->getMockBuilder(
+            \Magento\Catalog\Model\Indexer\Product\Flat\TableDataInterface::class
+        )->disableOriginalConstructor()->getMockForAbstractClass();
+        $this->connectionMock = $this->getMockBuilder(\Magento\Framework\DB\Adapter\AdapterInterface::class)
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $this->metadataPoolMock = $this->getMockBuilder(\Magento\Framework\EntityManager\MetadataPool::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->metadataMock = $this->getMockBuilder(
+            \Magento\Framework\EntityManager\EntityMetadataInterface::class
+        )->disableOriginalConstructor()->getMockForAbstractClass();
+        $this->metadataMock->expects($this->any())->method('getLinkField')->willReturn('entity_id');
+
+        $this->flatTableBuilder = $objectManagerHelper->getObject(
+            \Magento\Catalog\Model\Indexer\Product\Flat\FlatTableBuilder::class,
+            [
+                'productIndexerHelper' => $this->flatIndexerMock,
+                'resource' => $this->resourceMock,
+                'config' => $this->scopeConfigMock,
+                'storeManager' => $this->storeManagerMock,
+                'tableData' => $this->tableDataMock,
+                '_connection' => $this->connectionMock
+            ]
+        );
+        $objectManagerHelper->setBackwardCompatibleProperty(
+            $this->flatTableBuilder,
+            'metadataPool',
+            $this->metadataPoolMock
+        );
+    }
+
+    public function testBuild()
+    {
+        list($storeId, $changedIds, $valueFieldSuffix, $tableDropSuffix, $fillTmpTables) = [1, [], '', '', true];
+        $tableName = 'catalog_product_entity';
+        $attributeTable = 'catalog_product_entity_int';
+        $temporaryTableName = 'catalog_product_entity_int_tmp_indexer';
+        $temporaryValueTableName = 'catalog_product_entity_int_tmp_indexer';
+        $linkField = 'entity_id';
+        $statusId = 22;
+        $this->flatIndexerMock->expects($this->once())->method('getAttributes')->willReturn([]);
+        $this->flatIndexerMock->expects($this->exactly(3))->method('getFlatColumns')
+            ->willReturnOnConsecutiveCalls(
+                [],
+                [$linkField => []],
+                [$linkField => []]
+            );
+        $this->flatIndexerMock->expects($this->once())->method('getFlatIndexes')->willReturn([]);
+        $statusAttributeMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->flatIndexerMock->expects($this->once())->method('getTablesStructure')
+            ->willReturn(
+                [
+                    'catalog_product_entity' => [
+                        $linkField => $statusAttributeMock
+                    ],
+                    'catalog_product_entity_int' => [
+                        $linkField => $statusAttributeMock
+                    ]
+                ]
+            );
+        $this->flatIndexerMock->expects($this->atLeastOnce())->method('getTable')
+            ->withConsecutive(
+                [$tableName],
+                ['catalog_product_website']
+            )
+            ->willReturn(
+                $tableName,
+                'catalog_product_website'
+            );
+        $this->flatIndexerMock->expects($this->once())->method('getAttribute')
+            ->with('status')
+            ->willReturn($statusAttributeMock);
+        $backendMock = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $backendMock->expects($this->atLeastOnce())->method('getTable')->willReturn($attributeTable);
+        $statusAttributeMock->expects($this->atLeastOnce())->method('getBackend')->willReturn(
+            $backendMock
+        );
+        $statusAttributeMock->expects($this->atLeastOnce())->method('getId')->willReturn($statusId);
+        $tableMock = $this->getMockBuilder(\Magento\Framework\DB\Ddl\Table::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->connectionMock->expects($this->any())->method('newTable')->willReturn($tableMock);
+        $selectMock = $this->getMockBuilder(\Magento\Framework\DB\Select::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->connectionMock->expects($this->atLeastOnce())->method('select')->willReturn($selectMock);
+        $selectMock->expects($this->once())->method('from')->with(
+            ['et' => 'catalog_product_entity_tmp_indexer'],
+            [$linkField, 'type_id', 'attribute_set_id']
+        )->willReturnSelf();
+        $selectMock->expects($this->atLeastOnce())->method('joinInner')->willReturnSelf();
+        $selectMock->expects($this->exactly(3))->method('joinLeft')
+            ->withConsecutive(
+                [
+                    ['dstatus' => $attributeTable],
+                    sprintf(
+                        'e.%s = dstatus.%s AND dstatus.store_id = %s AND dstatus.attribute_id = %s',
+                        $linkField,
+                        $linkField,
+                        $storeId,
+                        $statusId
+                    ),
+                    []
+                ],
+                [
+                    $temporaryTableName,
+                    "e.{$linkField} = ${temporaryTableName}.{$linkField}",
+                    [$linkField]
+                ],
+                [
+                    $temporaryValueTableName,
+                    "e.${linkField} = " . $temporaryValueTableName . ".${linkField}",
+                    [$linkField]
+                ]
+            )->willReturnSelf();
+        $this->metadataPoolMock->expects($this->atLeastOnce())->method('getMetadata')->with(ProductInterface::class)
+            ->willReturn($this->metadataMock);
+        $storeMock = $this->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class)
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $this->storeManagerMock->expects($this->once())->method('getStore')->with($storeId)->willReturn($storeMock);
+        $this->flatTableBuilder->build($storeId, $changedIds, $valueFieldSuffix, $tableDropSuffix, $fillTmpTables);
+    }
+}
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/Table/BuilderTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/Table/BuilderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0a80250fbdf03153b52b4e509b90bee9bf7dde9c
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/Flat/Table/BuilderTest.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Catalog\Test\Unit\Model\Indexer\Product\Flat\Table;
+
+/**
+ * Class BuilderTest
+ */
+class BuilderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\DB\Adapter\AdapterInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $connectionMock;
+
+    public function testAddColumn()
+    {
+        $this->connectionMock = $this->getMockBuilder(\Magento\Framework\DB\Adapter\AdapterInterface::class)
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $table = $this->getMockBuilder(\Magento\Framework\DB\Ddl\Table::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $table->expects($this->once())->method('addColumn')
+            ->with('test', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER)
+            ->willReturnSelf();
+        $tableName = 'test_table';
+        $this->connectionMock->expects($this->once())
+            ->method('newTable')
+            ->with($tableName)
+            ->willReturn($table);
+        $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        /**
+         * @var $builder \Magento\Catalog\Model\Indexer\Product\Flat\Table\Builder
+         */
+        $builder = $objectManagerHelper->getObject(
+            \Magento\Catalog\Model\Indexer\Product\Flat\Table\Builder::class,
+            [
+                'connection' => $this->connectionMock,
+                'tableName' => $tableName
+            ]
+        );
+        $this->assertEquals($builder, $builder->addColumn('test', \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER));
+    }
+}
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/RepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/RepositoryTest.php
index 1b2648fb3254c1209de624d4c9f3c24540cf515c..87159b4e2d6d3e19378d36bc21e891131b3d097a 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/RepositoryTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/RepositoryTest.php
@@ -9,7 +9,10 @@
 
 namespace Magento\Catalog\Test\Unit\Model\Product\Attribute;
 
-use \Magento\Catalog\Model\Product\Attribute\Repository;
+use Magento\Catalog\Model\Product\Attribute\Repository;
+use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
+use Magento\Catalog\Api\Data\ProductAttributeInterface;
+use Magento\Eav\Api\Data\AttributeFrontendLabelInterface;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -261,4 +264,67 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
 
         $this->model->save($attributeMock);
     }
+
+    public function testSaveDoesNotSaveAttributeOptionsIfOptionsAreAbsentInPayload()
+    {
+        $attributeId = 1;
+        $attributeCode = 'existing_attribute_code';
+        $attributeMock = $this->getMock(Attribute::class, [], [], '', false);
+        $attributeMock->expects($this->any())->method('getAttributeCode')->willReturn($attributeCode);
+        $attributeMock->expects($this->any())->method('getAttributeId')->willReturn($attributeId);
+
+        $existingModelMock = $this->getMock(Attribute::class, [], [], '', false);
+        $existingModelMock->expects($this->any())->method('getAttributeCode')->willReturn($attributeCode);
+        $existingModelMock->expects($this->any())->method('getAttributeId')->willReturn($attributeId);
+
+        $this->eavAttributeRepositoryMock->expects($this->any())
+            ->method('get')
+            ->with(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode)
+            ->willReturn($existingModelMock);
+
+        // Attribute code must not be changed after attribute creation
+        $attributeMock->expects($this->once())->method('setAttributeCode')->with($attributeCode);
+        $this->attributeResourceMock->expects($this->once())->method('save')->with($attributeMock);
+        $this->optionManagementMock->expects($this->never())->method('add');
+
+        $this->model->save($attributeMock);
+    }
+
+    public function testSaveSavesDefaultFrontendLabelIfItIsPresentInPayload()
+    {
+        $labelMock = $this->getMock(AttributeFrontendLabelInterface::class);
+        $labelMock->expects($this->any())->method('getStoreId')->willReturn(1);
+        $labelMock->expects($this->any())->method('getLabel')->willReturn('Store Scope Label');
+
+        $attributeId = 1;
+        $attributeCode = 'existing_attribute_code';
+        $attributeMock = $this->getMock(Attribute::class, [], [], '', false);
+        $attributeMock->expects($this->any())->method('getAttributeCode')->willReturn($attributeCode);
+        $attributeMock->expects($this->any())->method('getAttributeId')->willReturn($attributeId);
+        $attributeMock->expects($this->any())->method('getDefaultFrontendLabel')->willReturn('Default Label');
+        $attributeMock->expects($this->any())->method('getFrontendLabels')->willReturn([$labelMock]);
+        $attributeMock->expects($this->any())->method('getOptions')->willReturn([]);
+
+
+        $existingModelMock = $this->getMock(Attribute::class, [], [], '', false);
+        $existingModelMock->expects($this->any())->method('getAttributeId')->willReturn($attributeId);
+        $existingModelMock->expects($this->any())->method('getAttributeCode')->willReturn($attributeCode);
+
+        $this->eavAttributeRepositoryMock->expects($this->any())
+            ->method('get')
+            ->with(ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeCode)
+            ->willReturn($existingModelMock);
+
+        $attributeMock->expects($this->once())
+            ->method('setDefaultFrontendLabel')
+            ->with(
+                [
+                    0 => 'Default Label',
+                    1 => 'Store Scope Label'
+                ]
+            );
+        $this->attributeResourceMock->expects($this->once())->method('save')->with($attributeMock);
+
+        $this->model->save($attributeMock);
+    }
 }
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/RepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/RepositoryTest.php
index c461e7a616d81c3e9a72a3031d979b9f44817de1..894596342722d392fd79b51a330341c0b14660f5 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/RepositoryTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/RepositoryTest.php
@@ -8,6 +8,8 @@
 namespace Magento\Catalog\Test\Unit\Model\Product\Option;
 
 use \Magento\Catalog\Model\Product\Option\Repository;
+use Magento\Catalog\Api\Data\ProductCustomOptionInterface;
+use \Magento\Catalog\Model\ResourceModel\Product\Option\CollectionFactory;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -30,10 +32,15 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
     protected $optionResourceMock;
 
     /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
+     * @var ProductCustomOptionInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $optionMock;
 
+    /**
+     * @var CollectionFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $optionCollectionFactory;
+
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
@@ -71,13 +78,10 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $optionCollectionFactory = $this->getMock(
-            \Magento\Catalog\Model\ResourceModel\Product\Option\CollectionFactory::class,
-            ['create'],
-            [],
-            '',
-            false
-        );
+        $this->optionCollectionFactory = $this->getMockBuilder(CollectionFactory::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
         $metadataPool = $this->getMockBuilder(\Magento\Framework\EntityManager\MetadataPool::class)
             ->disableOriginalConstructor()
             ->getMock();
@@ -96,7 +100,7 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
             $this->optionRepository,
             [
                 'optionFactory' => $optionFactory,
-                'optionCollectionFactory' => $optionCollectionFactory,
+                'collectionFactory' => $this->optionCollectionFactory,
                 'metadataPool' => $metadataPool
             ]
         );
@@ -240,4 +244,75 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
             }
         }
     }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\CouldNotSaveException
+     * @expectedExceptionMessage ProductSku should be specified
+     */
+    public function testSaveCouldNotSaveException()
+    {
+        $this->optionMock->expects($this->once())->method('getProductSku')->willReturn(null);
+        $this->optionRepository->save($this->optionMock);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     */
+    public function testSaveNoSuchEntityException()
+    {
+        $productSku = 'simple_product';
+        $optionId = 1;
+        $productOptionId = 2;
+        $this->optionMock->expects($this->once())->method('getProductSku')->willReturn($productSku);
+        $this->productRepositoryMock
+            ->expects($this->once())
+            ->method('get')
+            ->with($productSku)
+            ->willReturn($this->productMock);
+        $productOption = clone $this->optionMock;
+        $this->optionMock->expects($this->any())->method('getOptionId')->willReturn($optionId);
+        $productOption->expects($this->any())->method('getOptionId')->willReturn($productOptionId);
+        $this->productMock->expects($this->once())->method('getOptions')->willReturn([$productOption]);
+        $this->optionRepository->save($this->optionMock);
+    }
+
+    public function testSave()
+    {
+        $productSku = 'simple_product';
+        $optionId = 1;
+        $originalValue1 = $this->getMockBuilder(\Magento\Catalog\Model\Product\Option::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $originalValue2 = clone $originalValue1;
+        $originalValue3 = clone $originalValue1;
+
+        $originalValue1->expects($this->at(0))->method('getData')->with('option_type_id')->willReturn(10);
+        $originalValue1->expects($this->once())->method('setData')->with('is_delete', 1);
+        $originalValue2->expects($this->once())->method('getData')->with('option_type_id')->willReturn(4);
+        $originalValue3->expects($this->once())->method('getData')->with('option_type_id')->willReturn(5);
+
+        $this->optionMock->expects($this->once())->method('getProductSku')->willReturn($productSku);
+        $this->productRepositoryMock
+            ->expects($this->once())
+            ->method('get')
+            ->with($productSku)
+            ->willReturn($this->productMock);
+        $this->optionMock->expects($this->any())->method('getOptionId')->willReturn($optionId);
+        $this->productMock->expects($this->once())->method('getOptions')->willReturn([]);
+        $this->optionMock->expects($this->once())->method('getData')->with('values')->willReturn([
+            ['option_type_id' => 4],
+            ['option_type_id' => 5]
+        ]);
+        $optionCollection = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Product\Option\Collection::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $optionCollection->expects($this->once())->method('getProductOptions')->willReturn([$this->optionMock]);
+        $this->optionCollectionFactory->expects($this->once())->method('create')->willReturn($optionCollection);
+        $this->optionMock->expects($this->once())->method('getValues')->willReturn([
+            $originalValue1,
+            $originalValue2,
+            $originalValue3
+        ]);
+        $this->assertEquals($this->optionMock, $this->optionRepository->save($this->optionMock));
+    }
 }
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/SaveHandlerTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/SaveHandlerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..222abadd9fe4b9ff2e6c82a9bd7efc24bf5166de
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/SaveHandlerTest.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Catalog\Test\Unit\Model\Product\Option;
+
+use Magento\Catalog\Model\Product;
+use Magento\Catalog\Model\Product\Option;
+use \Magento\Catalog\Model\Product\Option\Repository;
+use \Magento\Catalog\Model\Product\Option\SaveHandler;
+
+class SaveHandlerTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var SaveHandler|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $model;
+
+    /**
+     * @var Product|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $entity;
+
+    /**
+     * @var Option|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $optionMock;
+
+    /**
+     * @var Repository|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $optionRepository;
+
+    public function setUp()
+    {
+        $this->entity = $this->getMockBuilder(Product::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->optionMock = $this->getMockBuilder(Option::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->optionRepository = $this->getMockBuilder(Repository::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->model = new SaveHandler($this->optionRepository);
+    }
+
+    public function testExecute()
+    {
+        $this->optionMock->expects($this->any())->method('getOptionId')->willReturn(5);
+        $this->entity->expects($this->once())->method('getOptions')->willReturn([$this->optionMock]);
+
+        $secondOptionMock = $this->getMockBuilder(Option::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $secondOptionMock->expects($this->once())->method('getOptionId')->willReturn(6);
+
+        $this->optionRepository
+            ->expects($this->once())
+            ->method('getProductOptions')
+            ->with($this->entity)
+            ->willReturn([$this->optionMock, $secondOptionMock]);
+
+        $this->optionRepository->expects($this->once())->method('delete');
+        $this->optionRepository->expects($this->once())->method('save')->with($this->optionMock);
+
+        $this->assertEquals($this->entity, $this->model->execute($this->entity));
+    }
+}
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/Type/FileTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/Type/FileTest.php
index 9b41651863fdb21112d422dd7bda8ee6a97aa09b..6682b295476325f2df099faa183d5edb451cadb5 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/Type/FileTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Option/Type/FileTest.php
@@ -5,6 +5,12 @@
  */
 namespace Magento\Catalog\Test\Unit\Model\Product\Option\Type;
 
+use Magento\Catalog\Model\Product\Configuration\Item\Option\OptionInterface;
+use Magento\Framework\App\Filesystem\DirectoryList;
+use Magento\Framework\Filesystem;
+use Magento\Framework\Filesystem\Directory\ReadInterface;
+use Magento\Framework\Filesystem\DriverPool;
+
 class FileTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -13,7 +19,7 @@ class FileTest extends \PHPUnit_Framework_TestCase
     protected $objectManager;
 
     /**
-     * @var \Magento\Framework\Filesystem\Directory\ReadInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var ReadInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $rootDirectory;
 
@@ -22,14 +28,26 @@ class FileTest extends \PHPUnit_Framework_TestCase
      */
     protected $coreFileStorageDatabase;
 
+    /**
+     * @var Filesystem|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $filesystemMock;
+
     protected function setUp()
     {
         $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
 
-        $this->rootDirectory = $this->getMockBuilder(\Magento\Framework\Filesystem\Directory\ReadInterface::class)
+        $this->filesystemMock = $this->getMockBuilder(Filesystem::class)
             ->disableOriginalConstructor()
-            ->setMethods(['isFile', 'isReadable', 'getAbsolutePath'])
-            ->getMockForAbstractClass();
+            ->getMock();
+
+        $this->rootDirectory = $this->getMockBuilder(ReadInterface::class)
+            ->getMock();
+
+        $this->filesystemMock->expects($this->once())
+            ->method('getDirectoryRead')
+            ->with(DirectoryList::MEDIA, DriverPool::FILE)
+            ->willReturn($this->rootDirectory);
 
         $this->coreFileStorageDatabase = $this->getMock(
             \Magento\MediaStorage\Helper\File\Storage\Database::class,
@@ -48,26 +66,27 @@ class FileTest extends \PHPUnit_Framework_TestCase
         return $this->objectManager->getObject(
             \Magento\Catalog\Model\Product\Option\Type\File::class,
             [
-                'saleableItem' => $this->rootDirectory,
-                'priceCurrency' => $this->coreFileStorageDatabase
+                'filesystem' => $this->filesystemMock,
+                'coreFileStorageDatabase' => $this->coreFileStorageDatabase
             ]
         );
     }
 
     public function testCopyQuoteToOrder()
     {
-        $optionMock = $this->getMockBuilder(
-            \Magento\Catalog\Model\Product\Configuration\Item\Option\OptionInterface::class
-        )->disableOriginalConstructor()->setMethods(['getValue'])->getMockForAbstractClass();
+        $optionMock = $this->getMockBuilder(OptionInterface::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getValue'])
+            ->getMockForAbstractClass();
 
         $quotePath = '/quote/path/path/uploaded.file';
         $orderPath = '/order/path/path/uploaded.file';
 
         $optionMock->expects($this->any())
             ->method('getValue')
-            ->will($this->returnValue(['quote_path' => $quotePath, 'order_path' => $orderPath]));
+            ->will($this->returnValue(serialize(['quote_path' => $quotePath, 'order_path' => $orderPath])));
 
-        $this->rootDirectory->expects($this->any())
+        $this->rootDirectory->expects($this->once())
             ->method('isFile')
             ->with($this->equalTo($quotePath))
             ->will($this->returnValue(true));
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php
index 5042ac1b745cf07a7134687c2598694b773ff804..e91bb469eb112d4de70cba92bff5b93ca069ca58 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php
@@ -14,6 +14,7 @@ use Magento\Framework\Api\Data\ImageContentInterface;
 use Magento\Framework\DB\Adapter\ConnectionException;
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
 use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface;
+use Magento\Store\Api\Data\StoreInterface;
 
 /**
  * Class ProductRepositoryTest
@@ -284,7 +285,6 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
         $storeMock->expects($this->any())->method('getWebsiteId')->willReturn('1');
         $storeMock->expects($this->any())->method('getCode')->willReturn(\Magento\Store\Model\Store::ADMIN_CODE);
         $this->storeManagerMock->expects($this->any())->method('getStore')->willReturn($storeMock);
-        $this->storeManagerMock->expects($this->any())->method('getWebsites')->willReturn([1 => 'default']);
 
         $this->mediaGalleryProcessor = $this->getMock(
             \Magento\Catalog\Model\Product\Gallery\Processor::class,
@@ -495,6 +495,7 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
 
     public function testSaveExisting()
     {
+        $this->storeManagerMock->expects($this->any())->method('getWebsites')->willReturn([1 => 'default']);
         $this->resourceModelMock->expects($this->any())->method('getIdBySku')->will($this->returnValue(100));
         $this->productFactoryMock->expects($this->any())
             ->method('create')
@@ -514,6 +515,7 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
 
     public function testSaveNew()
     {
+        $this->storeManagerMock->expects($this->any())->method('getWebsites')->willReturn([1 => 'default']);
         $this->resourceModelMock->expects($this->at(0))->method('getIdBySku')->will($this->returnValue(null));
         $this->resourceModelMock->expects($this->at(3))->method('getIdBySku')->will($this->returnValue(100));
         $this->productFactoryMock->expects($this->any())
@@ -538,6 +540,7 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
      */
     public function testSaveUnableToSaveException()
     {
+        $this->storeManagerMock->expects($this->any())->method('getWebsites')->willReturn([1 => 'default']);
         $this->resourceModelMock->expects($this->exactly(1))->method('getIdBySku')->will($this->returnValue(null));
         $this->productFactoryMock->expects($this->exactly(2))
             ->method('create')
@@ -562,6 +565,7 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
      */
     public function testSaveException()
     {
+        $this->storeManagerMock->expects($this->any())->method('getWebsites')->willReturn([1 => 'default']);
         $this->resourceModelMock->expects($this->exactly(1))->method('getIdBySku')->will($this->returnValue(null));
         $this->productFactoryMock->expects($this->exactly(2))
             ->method('create')
@@ -587,6 +591,7 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
      */
     public function testSaveInvalidProductException()
     {
+        $this->storeManagerMock->expects($this->any())->method('getWebsites')->willReturn([1 => 'default']);
         $this->resourceModelMock->expects($this->exactly(1))->method('getIdBySku')->will($this->returnValue(null));
         $this->productFactoryMock->expects($this->exactly(2))
             ->method('create')
@@ -610,6 +615,7 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
      */
     public function testSaveThrowsTemporaryStateExceptionIfDatabaseConnectionErrorOccurred()
     {
+        $this->storeManagerMock->expects($this->any())->method('getWebsites')->willReturn([1 => 'default']);
         $this->productFactoryMock->expects($this->any())
             ->method('create')
             ->will($this->returnValue($this->productMock));
@@ -796,6 +802,7 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
      */
     public function testSaveExistingWithOptions(array $newOptions, array $existingOptions, array $expectedData)
     {
+        $this->storeManagerMock->expects($this->any())->method('getWebsites')->willReturn([1 => 'default']);
         $this->resourceModelMock->expects($this->any())->method('getIdBySku')->will($this->returnValue(100));
         $this->productFactoryMock->expects($this->any())
             ->method('create')
@@ -964,6 +971,7 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
      */
     public function testSaveWithLinks(array $newLinks, array $existingLinks, array $expectedData)
     {
+        $this->storeManagerMock->expects($this->any())->method('getWebsites')->willReturn([1 => 'default']);
         $this->resourceModelMock->expects($this->any())->method('getIdBySku')->will($this->returnValue(100));
         $this->productFactoryMock->expects($this->any())
             ->method('create')
@@ -1143,6 +1151,7 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
 
     public function testSaveExistingWithNewMediaGalleryEntries()
     {
+        $this->storeManagerMock->expects($this->any())->method('getWebsites')->willReturn([1 => 'default']);
         $newEntriesData = [
             [
                 "label" => "label_text",
@@ -1222,8 +1231,48 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
         $this->model->save($this->productMock);
     }
 
+    public function websitesProvider()
+    {
+        return [
+            [[1,2,3]]
+        ];
+    }
+
+    public function testSaveWithDifferentWebsites()
+    {
+        $storeMock = $this->getMock(StoreInterface::class);
+        $this->resourceModelMock->expects($this->at(0))->method('getIdBySku')->will($this->returnValue(null));
+        $this->resourceModelMock->expects($this->at(3))->method('getIdBySku')->will($this->returnValue(100));
+        $this->productFactoryMock->expects($this->any())
+            ->method('create')
+            ->will($this->returnValue($this->productMock));
+        $this->initializationHelperMock->expects($this->never())->method('initialize');
+        $this->resourceModelMock->expects($this->once())->method('validate')->with($this->productMock)
+            ->willReturn(true);
+        $this->resourceModelMock->expects($this->once())->method('save')->with($this->productMock)->willReturn(true);
+        $this->extensibleDataObjectConverterMock
+            ->expects($this->once())
+            ->method('toNestedArray')
+            ->will($this->returnValue($this->productData));
+        $this->storeManagerMock->expects($this->any())
+            ->method('getStore')
+            ->willReturn($storeMock);
+        $this->storeManagerMock->expects($this->once())
+            ->method('getWebsites')
+            ->willReturn([
+                1 => ['first'],
+                2 => ['second'],
+                3 => ['third']
+            ]);
+        $this->productMock->expects($this->once())->method('getWebsiteIds')->willReturn([1,2,3]);
+        $this->productMock->expects($this->once())->method('setWebsiteIds')->willReturn([2,3]);
+
+        $this->assertEquals($this->productMock, $this->model->save($this->productMock));
+    }
+
     public function testSaveExistingWithMediaGalleryEntries()
     {
+        $this->storeManagerMock->expects($this->any())->method('getWebsites')->willReturn([1 => 'default']);
         //update one entry, delete one entry
         $newEntries = [
             [
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php
index d4950d9df6de7b71d3f86e0e81ad4aa01d71fd6a..f8e162dff45f390156e63c779ce2c2818d723aa5 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductTest.php
@@ -708,13 +708,13 @@ class ProductTest extends \PHPUnit_Framework_TestCase
 
         return [
             'no changes' => [
-                ['catalog_product_1'],
+                ['cat_p_1'],
                 ['id' => 1, 'name' => 'value', 'category_ids' => [1]],
                 ['id' => 1, 'name' => 'value', 'category_ids' => [1]],
             ],
             'new product' => $this->getNewProductProviderData(),
             'status and category change' => [
-                [0 => 'catalog_product_1', 1 => 'catalog_category_product_1', 2 => 'catalog_category_product_2'],
+                [0 => 'cat_p_1', 1 => 'cat_c_p_1', 2 => 'cat_c_p_2'],
                 ['id' => 1, 'name' => 'value', 'category_ids' => [1], 'status' => 2],
                 [
                     'id' => 1,
@@ -726,18 +726,18 @@ class ProductTest extends \PHPUnit_Framework_TestCase
                 ],
             ],
             'status change only' => [
-                [0 => 'catalog_product_1', 1 => 'catalog_category_product_7'],
+                [0 => 'cat_p_1', 1 => 'cat_c_p_7'],
                 ['id' => 1, 'name' => 'value', 'category_ids' => [7], 'status' => 1],
                 ['id' => 1, 'name' => 'value', 'category_ids' => [7], 'status' => 2],
             ],
             'status changed, category unassigned' => $this->getStatusAndCategoryChangesData(),
             'no status changes' => [
-                [0 => 'catalog_product_1'],
+                [0 => 'cat_p_1'],
                 ['id' => 1, 'name' => 'value', 'category_ids' => [1], 'status' => 1],
                 ['id' => 1, 'name' => 'value', 'category_ids' => [1], 'status' => 1],
             ],
             'no stock status changes' => [
-                [0 => 'catalog_product_1'],
+                [0 => 'cat_p_1'],
                 ['id' => 1, 'name' => 'value', 'category_ids' => [1], 'status' => 1],
                 [
                     'id' => 1,
@@ -749,7 +749,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
                 ],
             ],
             'no stock status data 1' => [
-                [0 => 'catalog_product_1'],
+                [0 => 'cat_p_1'],
                 ['id' => 1, 'name' => 'value', 'category_ids' => [1], 'status' => 1],
                 [
                     'id' => 1,
@@ -760,7 +760,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
                 ],
             ],
             'no stock status data 2' => [
-                [0 => 'catalog_product_1'],
+                [0 => 'cat_p_1'],
                 ['id' => 1, 'name' => 'value', 'category_ids' => [1], 'status' => 1],
                 [
                     'id' => 1,
@@ -780,7 +780,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
     private function getStatusAndCategoryChangesData()
     {
         return [
-            [0 => 'catalog_product_1', 1 => 'catalog_category_product_5'],
+            [0 => 'cat_p_1', 1 => 'cat_c_p_5'],
             ['id' => 1, 'name' => 'value', 'category_ids' => [5], 'status' => 2],
             [
                 'id' => 1,
@@ -799,7 +799,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
     private function getNewProductProviderData()
     {
         return [
-            ['catalog_product_1', 'catalog_category_product_1'],
+            ['cat_p_1', 'cat_c_p_1'],
             null,
             [
                 'id' => 1,
@@ -818,7 +818,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
     private function getStatusStockProviderData($extensionAttributesMock)
     {
         return [
-            [0 => 'catalog_product_1', 1 => 'catalog_category_product_1'],
+            [0 => 'cat_p_1', 1 => 'cat_c_p_1'],
             ['id' => 1, 'name' => 'value', 'category_ids' => [1], 'status' => 1],
             [
                 'id' => 1,
@@ -831,20 +831,6 @@ class ProductTest extends \PHPUnit_Framework_TestCase
         ];
     }
 
-    public function testStatusAfterLoad()
-    {
-        $this->resource->expects($this->once())->method('load')->with($this->model, 1, null);
-        $this->eventManagerMock->expects($this->exactly(4))->method('dispatch');
-        $this->model->load(1);
-        $this->assertEquals(
-            Status::STATUS_ENABLED,
-            $this->model->getData(\Magento\Catalog\Model\Product::STATUS)
-        );
-        $this->assertFalse($this->model->hasDataChanges());
-        $this->model->setStatus(Status::STATUS_DISABLED);
-        $this->assertTrue($this->model->hasDataChanges());
-    }
-
     /**
      * Test retrieving price Info
      */
@@ -1467,4 +1453,27 @@ class ProductTest extends \PHPUnit_Framework_TestCase
         $this->model->setTypeId('typeId');
         $this->model->getTypeInstance();
     }
+
+    public function testGetOptionById()
+    {
+        $optionId = 100;
+        $optionMock = $this->getMock(\Magento\Catalog\Model\Product\Option::class, [], [], '', false);
+        $this->model->setOptions([$optionMock]);
+        $optionMock->expects($this->once())->method('getId')->willReturn($optionId);
+        $this->assertEquals($optionMock, $this->model->getOptionById($optionId));
+    }
+
+    public function testGetOptionByIdWithWrongOptionId()
+    {
+        $optionId = 100;
+        $optionMock = $this->getMock(\Magento\Catalog\Model\Product\Option::class, [], [], '', false);
+        $this->model->setOptions([$optionMock]);
+        $optionMock->expects($this->once())->method('getId')->willReturn(200);
+        $this->assertNull($this->model->getOptionById($optionId));
+    }
+
+    public function testGetOptionByIdForProductWithoutOptions()
+    {
+        $this->assertNull($this->model->getOptionById(100));
+    }
 }
diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CategoriesTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CategoriesTest.php
index f913779fc526e9b8e45e592a4e1a8834d0ff7f03..2070a64884b1172f5e00e6e950981d10c5ddadb3 100644
--- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CategoriesTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CategoriesTest.php
@@ -8,6 +8,7 @@ namespace Magento\Catalog\Test\Unit\Ui\DataProvider\Product\Form\Modifier;
 use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Categories;
 use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory as CategoryCollectionFactory;
 use Magento\Catalog\Model\ResourceModel\Category\Collection as CategoryCollection;
+use Magento\Framework\App\CacheInterface;
 use Magento\Framework\DB\Helper as DbHelper;
 use Magento\Framework\UrlInterface;
 use Magento\Store\Model\Store;
@@ -112,4 +113,38 @@ class CategoriesTest extends AbstractModifierTest
 
         $this->assertArrayHasKey($groupCode, $this->getModel()->modifyMeta($meta));
     }
+
+    public function testModifyMetaWithCaching()
+    {
+        $this->arrayManagerMock->expects($this->exactly(2))
+            ->method('findPath')
+            ->willReturn(true);
+        $cacheManager = $this->getMockBuilder(CacheInterface::class)
+            ->getMockForAbstractClass();
+        $cacheManager->expects($this->once())
+            ->method('load')
+            ->with(Categories::CATEGORY_TREE_ID . '_');
+        $cacheManager->expects($this->once())
+            ->method('save');
+        
+        $modifier = $this->createModel();
+        $cacheContextProperty = new \ReflectionProperty(
+            Categories::class,
+            'cacheManager'
+        );
+        $cacheContextProperty->setAccessible(true);
+        $cacheContextProperty->setValue($modifier, $cacheManager);
+
+        $groupCode = 'test_group_code';
+        $meta = [
+            $groupCode => [
+                'children' => [
+                    'category_ids' => [
+                        'sortOrder' => 10,
+                    ],
+                ],
+            ],
+        ];
+        $modifier->modifyMeta($meta);
+    }
 }
diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CustomOptionsTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CustomOptionsTest.php
index c2b3de0c24cb0736b778efb75d9e722d0fcb47b8..75a2b7c27b4d263d6603438ae9d7c8ab13578e91 100644
--- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CustomOptionsTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/CustomOptionsTest.php
@@ -87,35 +87,47 @@ class CustomOptionsTest extends AbstractModifierTest
 
         $originalData = [
             $productId => [
-                \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\CustomOptions::DATA_SOURCE_DEFAULT => [
+                CustomOptions::DATA_SOURCE_DEFAULT => [
                     'title' => 'original'
                 ]
             ]
         ];
 
         $options = [
-            $this->getProductOptionMock(['title' => 'option1']),
+            $this->getProductOptionMock(['title' => 'option1', 'store_title' => 'Option Store Title']),
             $this->getProductOptionMock(
-                ['title' => 'option2'],
+                ['title' => 'option2', 'store_title' => null],
                 [
-                    $this->getProductOptionMock(['title' => 'value1']),
-                    $this->getProductOptionMock(['title' => 'value2'])
+                    $this->getProductOptionMock(['title' => 'value1', 'store_title' => 'Option Value Store Title']),
+                    $this->getProductOptionMock(['title' => 'value2', 'store_title' => null])
                 ]
             )
         ];
 
         $resultData = [
             $productId => [
-                \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\CustomOptions::DATA_SOURCE_DEFAULT => [
-                    'title' => 'original',
-                    \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\CustomOptions::FIELD_ENABLE => 1,
-                    \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\CustomOptions::GRID_OPTIONS_NAME => [
-                        ['title' => 'option1'],
+                CustomOptions::DATA_SOURCE_DEFAULT => [
+                    CustomOptions::FIELD_TITLE_NAME => 'original',
+                    CustomOptions::FIELD_ENABLE => 1,
+                    CustomOptions::GRID_OPTIONS_NAME => [
                         [
-                            'title' => 'option2',
+                            CustomOptions::FIELD_TITLE_NAME => 'option1',
+                            CustomOptions::FIELD_STORE_TITLE_NAME => 'Option Store Title',
+                            CustomOptions::FIELD_IS_USE_DEFAULT => false
+                        ], [
+                            CustomOptions::FIELD_TITLE_NAME => 'option2',
+                            CustomOptions::FIELD_STORE_TITLE_NAME => null,
+                            CustomOptions::FIELD_IS_USE_DEFAULT => true,
                             CustomOptions::GRID_TYPE_SELECT_NAME => [
-                                ['title' => 'value1'],
-                                ['title' => 'value2']
+                                [
+                                    CustomOptions::FIELD_TITLE_NAME => 'value1',
+                                    CustomOptions::FIELD_STORE_TITLE_NAME => 'Option Value Store Title',
+                                    CustomOptions::FIELD_IS_USE_DEFAULT => false
+                                ], [
+                                    CustomOptions::FIELD_TITLE_NAME => 'value2',
+                                    CustomOptions::FIELD_STORE_TITLE_NAME => null,
+                                    CustomOptions::FIELD_IS_USE_DEFAULT => true
+                                ]
                             ]
                         ]
                     ]
@@ -154,13 +166,13 @@ class CustomOptionsTest extends AbstractModifierTest
      */
     protected function getProductOptionMock(array $data, array $values = [])
     {
+        /** @var ProductOption|\PHPUnit_Framework_MockObject_MockObject $productOptionMock */
         $productOptionMock = $this->getMockBuilder(ProductOption::class)
             ->disableOriginalConstructor()
+            ->setMethods(['getValues'])
             ->getMock();
 
-        $productOptionMock->expects($this->any())
-            ->method('getData')
-            ->willReturn($data);
+        $productOptionMock->setData($data);
         $productOptionMock->expects($this->any())
             ->method('getValues')
             ->willReturn($values);
diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php
index 33c8cea3262a4d589a1d5b37b66ece85e614a2c3..53360de08b434b4a0314fe341760c55fef476ef4 100644
--- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php
+++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php
@@ -493,7 +493,6 @@ class AdvancedPricing extends AbstractModifier
                                 'data' => [
                                     'config' => [
                                         'componentType' => Field::NAME,
-                                        'component' => 'Magento_Catalog/js/form/element/price-input',
                                         'formElement' => Input::NAME,
                                         'dataType' => Price::NAME,
                                         'label' => __('Price'),
diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php
index b0e663532e8690ab75c8a0580155d3629009f86e..0e46b5899851f477abaae8a0591c4e95e872ef3e 100644
--- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php
+++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Categories.php
@@ -7,6 +7,8 @@ namespace Magento\Catalog\Ui\DataProvider\Product\Form\Modifier;
 
 use Magento\Catalog\Model\Locator\LocatorInterface;
 use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory as CategoryCollectionFactory;
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\App\CacheInterface;
 use Magento\Framework\DB\Helper as DbHelper;
 use Magento\Catalog\Model\Category as CategoryModel;
 use Magento\Framework\UrlInterface;
@@ -14,9 +16,16 @@ use Magento\Framework\Stdlib\ArrayManager;
 
 /**
  * Data provider for categories field of product page
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class Categories extends AbstractModifier
 {
+    /**#@+
+     * Category tree cache id
+     */
+    const CATEGORY_TREE_ID = 'CATALOG_PRODUCT_CATEGORY_TREE';
+    /**#@-*/
+
     /**
      * @var CategoryCollectionFactory
      */
@@ -29,6 +38,7 @@ class Categories extends AbstractModifier
 
     /**
      * @var array
+     * @deprecated
      */
     protected $categoriesTrees = [];
 
@@ -47,6 +57,11 @@ class Categories extends AbstractModifier
      */
     protected $arrayManager;
 
+    /**
+     * @var CacheInterface
+     */
+    private $cacheManager;
+
     /**
      * @param LocatorInterface $locator
      * @param CategoryCollectionFactory $categoryCollectionFactory
@@ -68,6 +83,21 @@ class Categories extends AbstractModifier
         $this->arrayManager = $arrayManager;
     }
 
+    /**
+     * Retrieve cache interface
+     *
+     * @return CacheInterface
+     * @deprecated
+     */
+    private function getCacheManager()
+    {
+        if (!$this->cacheManager) {
+            $this->cacheManager = ObjectManager::getInstance()
+                ->get(CacheInterface::class);
+        }
+        return $this->cacheManager;
+    }
+
     /**
      * {@inheritdoc}
      */
@@ -254,8 +284,9 @@ class Categories extends AbstractModifier
      */
     protected function getCategoriesTree($filter = null)
     {
-        if (isset($this->categoriesTrees[$filter])) {
-            return $this->categoriesTrees[$filter];
+        $categoryTree = $this->getCacheManager()->load(self::CATEGORY_TREE_ID . '_' . $filter);
+        if ($categoryTree) {
+            return unserialize($categoryTree);
         }
 
         $storeId = $this->locator->getStore()->getId();
@@ -307,9 +338,16 @@ class Categories extends AbstractModifier
             $categoryById[$category->getId()]['label'] = $category->getName();
             $categoryById[$category->getParentId()]['optgroup'][] = &$categoryById[$category->getId()];
         }
+        
+        $this->getCacheManager()->save(
+            serialize($categoryById[CategoryModel::TREE_ROOT_ID]['optgroup']),
+            self::CATEGORY_TREE_ID . '_' . $filter,
+            [
+                \Magento\Catalog\Model\Category::CACHE_TAG,
+                \Magento\Framework\App\Cache\Type\Block::CACHE_TAG
+            ]
+        );
 
-        $this->categoriesTrees[$filter] = $categoryById[CategoryModel::TREE_ROOT_ID]['optgroup'];
-
-        return $this->categoriesTrees[$filter];
+        return $categoryById[CategoryModel::TREE_ROOT_ID]['optgroup'];
     }
 }
diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php
index 5e6c88a1ba93d43f3ab05236769761aa17fcfb12..780cdbbb00e0a3ac06208e6c70a01708376f071d 100755
--- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php
+++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php
@@ -68,6 +68,7 @@ class CustomOptions extends AbstractModifier
     const FIELD_ENABLE = 'affect_product_custom_options';
     const FIELD_OPTION_ID = 'option_id';
     const FIELD_TITLE_NAME = 'title';
+    const FIELD_STORE_TITLE_NAME = 'store_title';
     const FIELD_TYPE_NAME = 'type';
     const FIELD_IS_REQUIRE_NAME = 'is_require';
     const FIELD_SORT_ORDER_NAME = 'sort_order';
@@ -79,6 +80,7 @@ class CustomOptions extends AbstractModifier
     const FIELD_IMAGE_SIZE_X_NAME = 'image_size_x';
     const FIELD_IMAGE_SIZE_Y_NAME = 'image_size_y';
     const FIELD_IS_DELETE = 'is_delete';
+    const FIELD_IS_USE_DEFAULT = 'is_use_default';
     /**#@-*/
 
     /**#@+
@@ -112,7 +114,7 @@ class CustomOptions extends AbstractModifier
      * @var UrlInterface
      */
     protected $urlBuilder;
-    
+
     /**
      * @var ArrayManager
      */
@@ -162,9 +164,14 @@ class CustomOptions extends AbstractModifier
 
         /** @var \Magento\Catalog\Model\Product\Option $option */
         foreach ($productOptions as $index => $option) {
-            $options[$index] = $this->formatPriceByPath(static::FIELD_PRICE_NAME, $option->getData());
+            $optionData = $option->getData();
+            $optionData[static::FIELD_IS_USE_DEFAULT] = !$option->getData(static::FIELD_STORE_TITLE_NAME);
+            $options[$index] = $this->formatPriceByPath(static::FIELD_PRICE_NAME, $optionData);
             $values = $option->getValues() ?: [];
 
+            foreach ($values as $value) {
+                $value->setData(static::FIELD_IS_USE_DEFAULT, !$value->getData(static::FIELD_STORE_TITLE_NAME));
+            }
             /** @var \Magento\Catalog\Model\Product\Option $value */
             foreach ($values as $value) {
                 $options[$index][static::GRID_TYPE_SELECT_NAME][] = $this->formatPriceByPath(
@@ -529,7 +536,8 @@ class CustomOptions extends AbstractModifier
                                     'component' => 'Magento_Catalog/component/static-type-input',
                                     'valueUpdate' => 'input',
                                     'imports' => [
-                                        'optionId' => '${ $.provider }:${ $.parentScope }.option_id'
+                                        'optionId' => '${ $.provider }:${ $.parentScope }.option_id',
+                                        'isUseDefault' => '${ $.provider }:${ $.parentScope }.is_use_default'
                                     ]
                                 ],
                             ],
@@ -604,6 +612,7 @@ class CustomOptions extends AbstractModifier
                         'imports' => [
                             'optionId' => '${ $.provider }:${ $.parentScope }.option_id',
                             'optionTypeId' => '${ $.provider }:${ $.parentScope }.option_type_id',
+                            'isUseDefault' => '${ $.provider }:${ $.parentScope }.is_use_default'
                         ],
                         'service' => [
                             'template' => 'Magento_Catalog/form/element/helper/custom-option-type-service',
@@ -1109,7 +1118,7 @@ class CustomOptions extends AbstractModifier
         }
         return $this->localeCurrency;
     }
-    
+
     /**
      * Format price according to the locale of the currency
      *
diff --git a/app/code/Magento/Catalog/etc/adminhtml/di.xml b/app/code/Magento/Catalog/etc/adminhtml/di.xml
index 9993d4657533a33b5df653c59d3f19cdf0aa3dc9..584a2e51514db53a0250615a55d67455ca1a0f57 100644
--- a/app/code/Magento/Catalog/etc/adminhtml/di.xml
+++ b/app/code/Magento/Catalog/etc/adminhtml/di.xml
@@ -73,7 +73,6 @@
     </type>
     <type name="Magento\Catalog\Model\Indexer\Category\Product\Action\Full">
         <plugin name="invalidate_pagecache_after_full_reindex" type="Magento\Catalog\Plugin\Model\Indexer\Category\Product\Execute" />
-        <plugin name="max_heap_tablse_size_processor_on_full_reindex" type="Magento\Catalog\Plugin\Model\Indexer\Category\Product\MaxHeapTableSizeProcessorOnFullReindex"/>
     </type>
     <type name="Magento\Catalog\Model\ResourceModel\Attribute">
         <plugin name="invalidate_pagecache_after_attribute_save" type="Magento\Catalog\Plugin\Model\ResourceModel\Attribute\Save" />
diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml
index 49ad7d67d705899077d4beb13f4a26383982dcf5..d191f0332f5f28d28f22e981f8ebc74f0c0c8b98 100644
--- a/app/code/Magento/Catalog/etc/di.xml
+++ b/app/code/Magento/Catalog/etc/di.xml
@@ -47,6 +47,7 @@
     <preference for="Magento\Catalog\Api\CategoryListInterface" type="Magento\Catalog\Model\CategoryList" />
     <preference for="Magento\Catalog\Api\Data\CategorySearchResultsInterface" type="Magento\Framework\Api\SearchResults" />
     <preference for="Magento\Catalog\Model\Config\Source\ProductPriceOptionsInterface" type="Magento\Catalog\Model\Config\Source\Product\Options\Price"/>
+    <preference for="Magento\Catalog\Model\Indexer\Product\Flat\Table\BuilderInterface" type="Magento\Catalog\Model\Indexer\Product\Flat\Table\Builder"/>
     <type name="Magento\Customer\Model\ResourceModel\Visitor">
         <plugin name="catalogLog" type="Magento\Catalog\Model\Plugin\Log" />
     </type>
@@ -833,4 +834,7 @@
             <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor</argument>
         </arguments>
     </type>
+    <type name="Magento\Quote\Model\Quote\Item\ToOrderItem">
+        <plugin name="copy_quote_files_to_order" type="Magento\Catalog\Model\Plugin\QuoteItemProductOption"/>
+    </type>
 </config>
diff --git a/app/code/Magento/Catalog/etc/frontend/di.xml b/app/code/Magento/Catalog/etc/frontend/di.xml
index 9b99bd4a781402d662fa6e9c7a17d925c28e6460..ac8c3693e8f3056611a9152e7f259a7e547c4311 100644
--- a/app/code/Magento/Catalog/etc/frontend/di.xml
+++ b/app/code/Magento/Catalog/etc/frontend/di.xml
@@ -18,9 +18,6 @@
             <argument name="fetchStrategy" xsi:type="object">Magento\Catalog\Model\ResourceModel\Category\Collection\FetchStrategy</argument>
         </arguments>
     </type>
-    <type name="Magento\Quote\Model\Quote\Item\ToOrderItem">
-        <plugin name="copy_quote_files_to_order" type="Magento\Catalog\Model\Plugin\QuoteItemProductOption"/>
-    </type>
     <type name="Magento\Catalog\Model\Indexer\AbstractFlatState">
         <arguments>
             <argument name="isAvailable" xsi:type="boolean">true</argument>
diff --git a/app/code/Magento/Catalog/i18n/en_US.csv b/app/code/Magento/Catalog/i18n/en_US.csv
index 2ad2194b36466b0112afc78880ff91249a7ca6af..94b32f979383dc323dbb112b01e8ac5f200f4590 100644
--- a/app/code/Magento/Catalog/i18n/en_US.csv
+++ b/app/code/Magento/Catalog/i18n/en_US.csv
@@ -183,7 +183,7 @@ Categories,Categories
 "Category is not available for requested store.","Category is not available for requested store."
 "There was a category move error.","There was a category move error."
 "There was a category move error. %1","There was a category move error. %1"
-"You moved the category","You moved the category"
+"You moved the category.","You moved the category."
 "Attribute ""%1"" is required.","Attribute ""%1"" is required."
 "You saved the category.","You saved the category."
 "Something went wrong while saving the category.","Something went wrong while saving the category."
diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/set/main.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/set/main.phtml
index 4379fa062a121a96750eee3856ea768c680310ae..5b8034e87fef73f4c241ab9cd8b7d058d2e713aa 100644
--- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/set/main.phtml
+++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/set/main.phtml
@@ -208,6 +208,8 @@
                         },
 
                         submit : function() {
+                            var i, child, newNode;
+
                             if( TreePanels.root.firstChild == TreePanels.root.lastChild ) {
                                 return;
                             }
@@ -221,6 +223,7 @@
 
                             if( editSet.currentNode && editSet.currentNode.attributes.cls == 'folder' ) {
                                 TreePanels.root.removeChild(editSet.currentNode);
+
                                 for( i in editSet.currentNode.childNodes ) {
                                     if( editSet.currentNode.childNodes[i].id ) {
                                         child = editSet.currentNode.childNodes[i];
@@ -231,12 +234,20 @@
                                         }
                                     }
                                 }
+
                                 editSet.req.removeGroups[editSet.currentNode.id] = editSet.currentNode.id;
                                 editSet.currentNode = false;
                             }
                         },
 
                         SystemNodesExists : function(currentNode) {
+                            if (!currentNode) {
+                                alert({
+                                    content: '<?php echo $block->escapeJs(__('Please select a node.')) ?>'
+                                });
+                                return;
+                            }
+
                             for (i in currentNode.childNodes) {
                                 if (currentNode.childNodes[i].id) {
                                     child = editSet.currentNode.childNodes[i];
@@ -253,31 +264,40 @@
 
                         addGroup : function() {
                             prompt({
+                                title: "<?php /* @escapeNotVerified */ echo __('Add New Group') ?>",
                                 content: "<?php /* @escapeNotVerified */ echo __('Please enter a new group name.') ?>",
                                 value: "",
+                                validation: true,
+                                validationRules: ['required-entry'],
+                                attributesForm: {
+                                    novalidate: 'novalidate',
+                                    action: ''
+                                },
+                                attributesField: {
+                                    name: 'name',
+                                    'data-validate': '{required:true}',
+                                    maxlength: '255'
+                                },
                                 actions: {
                                     confirm: function (group_name) {
                                         group_name = group_name.strip();
-                                        if( group_name == '' ) {
-                                            self.addGroup();
-                                        } else if( group_name != false && group_name != null && group_name != '' ) {
-
-                                            if (!editSet.validateGroupName(group_name, 0)) {
-                                                return;
-                                            }
-
-                                            var newNode = new Ext.tree.TreeNode({
-                                                text : group_name.escapeHTML(),
-                                                cls : 'folder',
-                                                allowDrop : true,
-                                                allowDrag : true
-                                            });
-                                            TreePanels.root.appendChild(newNode);
-                                            newNode.addListener('beforemove', editSet.groupBeforeMove);
-                                            newNode.addListener('beforeinsert', editSet.groupBeforeInsert);
-                                            newNode.addListener('beforeappend', editSet.groupBeforeInsert);
-                                            newNode.addListener('click', editSet.register);
+
+                                        if (!editSet.validateGroupName(group_name, 0)) {
+                                            return;
                                         }
+
+                                        var newNode = new Ext.tree.TreeNode({
+                                            text : group_name.escapeHTML(),
+                                            cls : 'folder',
+                                            allowDrop : true,
+                                            allowDrag : true
+                                        });
+
+                                        TreePanels.root.appendChild(newNode);
+                                        newNode.addListener('beforemove', editSet.groupBeforeMove);
+                                        newNode.addListener('beforeinsert', editSet.groupBeforeInsert);
+                                        newNode.addListener('beforeappend', editSet.groupBeforeInsert);
+                                        newNode.addListener('click', editSet.register);
                                     }
                                 }
                             });
@@ -302,7 +322,7 @@
                             }
                             for (var i=0; i < TreePanels.root.childNodes.length; i++) {
                                 if (TreePanels.root.childNodes[i].text.toLowerCase() == name.toLowerCase() && TreePanels.root.childNodes[i].id != exceptNodeId) {
-                                    errorText = '<?php /* @escapeNotVerified */ echo __('An attribute group named "/name/" already exists".') ?>';
+                                    errorText = '<?php /* @escapeNotVerified */ echo __('An attribute group named "/name/" already exists.') ?>';
                                     alert({
                                         content: errorText.replace("/name/",name)
                                     });
@@ -313,8 +333,13 @@
                         },
 
                         save : function() {
+                            var block;
+
                             if ($('messages')) {
                                 $('messages').update();
+                            } else {
+                                block = jQuery('<div/>').attr('id', 'messages');
+                                jQuery('.page-main-actions').after(block);
                             }
                             TreePanels.rebuildTrees();
                             if(!jQuery('#set-prop-form').valid()) {
diff --git a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product-attributes.js b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product-attributes.js
index 937c83c14faa4b6bef8632fa59d177ec458250d7..c2f16d82959d0d0561e2f0ff0c2c5c417e131275 100644
--- a/app/code/Magento/Catalog/view/adminhtml/web/catalog/product-attributes.js
+++ b/app/code/Magento/Catalog/view/adminhtml/web/catalog/product-attributes.js
@@ -6,7 +6,8 @@ define([
     'jquery',
     'underscore',
     'uiRegistry',
-    'jquery/ui'
+    'jquery/ui',
+    'mage/translate'
 ], function ($, _, registry) {
     'use strict';
 
diff --git a/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js b/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js
index b330ccfd8c12531d4945fad1ea255bdee23a6404..a2e05dcc1c69c22a8572f5480dedf54c253b96a6 100644
--- a/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js
+++ b/app/code/Magento/Catalog/view/adminhtml/web/component/image-size-field.js
@@ -7,7 +7,8 @@ define([
     'jquery',
     'Magento_Ui/js/lib/validation/utils',
     'Magento_Ui/js/form/element/abstract',
-    'Magento_Ui/js/lib/validation/validator'
+    'Magento_Ui/js/lib/validation/validator',
+    'mage/translate'
 ], function ($, utils, Abstract, validator) {
     'use strict';
 
diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/components/import-handler.js b/app/code/Magento/Catalog/view/adminhtml/web/js/components/import-handler.js
index fd69874c318e21606361d503cc55ea900ad604cf..e67bde152475f62769d6eaff73548893f98ed7d0 100644
--- a/app/code/Magento/Catalog/view/adminhtml/web/js/components/import-handler.js
+++ b/app/code/Magento/Catalog/view/adminhtml/web/js/components/import-handler.js
@@ -4,8 +4,9 @@
  */
 
 define([
+    'underscore',
     'Magento_Ui/js/form/element/textarea'
-], function (Textarea) {
+], function (_, Textarea) {
     'use strict';
 
     return Textarea.extend({
@@ -123,24 +124,21 @@ define([
          * Update field value, if it's allowed
          */
         updateValue: function () {
-            var str = this.mask,
+            var str = this.mask || '',
                 nonEmptyValueFlag = false,
-                placeholder,
-                property,
                 tmpElement;
 
             if (!this.allowImport) {
                 return;
             }
 
-            for (property in this.values) {
-                if (this.values.hasOwnProperty(property)) {
-                    placeholder = '';
-                    placeholder = placeholder.concat('{{', property, '}}');
-                    str = str.replace(placeholder, this.values[property]);
-                    nonEmptyValueFlag = nonEmptyValueFlag || !!this.values[property];
-                }
+            if (str) {
+                _.each(this.values, function (propertyValue, propertyName) {
+                    str = str.replace('{{' + propertyName + '}}', propertyValue);
+                    nonEmptyValueFlag = nonEmptyValueFlag || !!propertyValue;
+                });
             }
+
             // strip tags
             tmpElement = document.createElement('div');
             tmpElement.innerHTML = str;
diff --git a/app/code/Magento/Catalog/view/adminhtml/web/js/form/element/price-input.js b/app/code/Magento/Catalog/view/adminhtml/web/js/form/element/price-input.js
deleted file mode 100644
index 0939619809a460b49cc7f254702797357c3b06f5..0000000000000000000000000000000000000000
--- a/app/code/Magento/Catalog/view/adminhtml/web/js/form/element/price-input.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-define([
-    'Magento_Ui/js/form/element/abstract'
-], function (Abstract) {
-    'use strict';
-
-    return Abstract.extend({
-        defaults: {
-            elementTmpl: 'Magento_Catalog/form/element/price-input'
-        }
-    });
-});
diff --git a/app/code/Magento/Catalog/view/adminhtml/web/template/form/element/helper/custom-option-type-service.html b/app/code/Magento/Catalog/view/adminhtml/web/template/form/element/helper/custom-option-type-service.html
index a3f7970e7420ad52ceb96ed23943f8166d1e2c4a..442d96b5ae4bac2c2954f377bba818448d1284b9 100644
--- a/app/code/Magento/Catalog/view/adminhtml/web/template/form/element/helper/custom-option-type-service.html
+++ b/app/code/Magento/Catalog/view/adminhtml/web/template/form/element/helper/custom-option-type-service.html
@@ -12,6 +12,6 @@
                 name: 'options_use_default[' + $data.optionId + '][values][' + $data.optionTypeId + '][' + $data.index + ']',
                 'data-form-part': $data.ns
            "
-           ko-checked="isUseDefault">
+           ko-checked="$data.isUseDefault">
     <label translate="'Use Default Value'" attr="for: $data.uid + '_default'" class="admin__field-label"></label>
 </div>
diff --git a/app/code/Magento/Catalog/view/adminhtml/web/template/form/element/price-input.html b/app/code/Magento/Catalog/view/adminhtml/web/template/form/element/price-input.html
deleted file mode 100644
index ce8ae751e6702ff11099db5a06c8dbb8d4b1cbb9..0000000000000000000000000000000000000000
--- a/app/code/Magento/Catalog/view/adminhtml/web/template/form/element/price-input.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<!--
-/**
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<input class="admin__control-text" type="text"
-       data-bind="
-        event: {
-            change: userChanges,
-            input: onInput
-        },
-        value: value,
-        hasFocus: focused,
-        valueUpdate: valueUpdate,
-        attr: {
-            name: inputName,
-            placeholder: placeholder,
-            'aria-describedby': noticeId,
-            id: uid,
-            disabled: disabled
-    }"/>
diff --git a/app/code/Magento/Catalog/view/frontend/requirejs-config.js b/app/code/Magento/Catalog/view/frontend/requirejs-config.js
index c0d05a322b7cd9e0a0603cdbef8505963ead80fa..6c7a8d3a969fff3090e0c24bbb431eebf83b9e6b 100644
--- a/app/code/Magento/Catalog/view/frontend/requirejs-config.js
+++ b/app/code/Magento/Catalog/view/frontend/requirejs-config.js
@@ -6,7 +6,6 @@
 var config = {
     map: {
         '*': {
-            compareItems:           'Magento_Catalog/js/compare',
             compareList:            'Magento_Catalog/js/list',
             relatedProducts:        'Magento_Catalog/js/related-products',
             upsellProducts:         'Magento_Catalog/js/upsell-products',
diff --git a/app/code/Magento/Catalog/view/frontend/web/js/compare.js b/app/code/Magento/Catalog/view/frontend/web/js/compare.js
deleted file mode 100644
index 66f8767bf2b8830c4229588d7c0a7ac5a8b6a422..0000000000000000000000000000000000000000
--- a/app/code/Magento/Catalog/view/frontend/web/js/compare.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*jshint browser:true jquery:true*/
-/*global confirm:true*/
-define([
-    "jquery",
-    "jquery/ui",
-    "mage/decorate"
-], function($){
-    "use strict";
-
-    $.widget('mage.compareItems', {
-        _create: function() {
-            this.element.decorate('list', true);
-            this._confirm(this.options.removeSelector, this.options.removeConfirmMessage);
-            this._confirm(this.options.clearAllSelector, this.options.clearAllConfirmMessage);
-        },
-
-        /**
-         * Set up a click event on the given selector to display a confirmation request message
-         * and ask for that confirmation.
-         * @param selector Selector for the confirmation on click event
-         * @param message Message to display asking for confirmation to perform action
-         * @private
-         */
-        _confirm: function(selector, message) {
-            $(selector).on('click', function() {
-                return confirm(message);
-            });
-        }
-    });
-
-    return $.mage.compareItems;
-});
\ No newline at end of file
diff --git a/app/code/Magento/Catalog/view/frontend/web/js/view/compare-products.js b/app/code/Magento/Catalog/view/frontend/web/js/view/compare-products.js
index d6e47f6df33a0d93588fb0de467b14fdee4c6d6c..9662b3fc7268b7366b9a448e90ca75690506b13a 100644
--- a/app/code/Magento/Catalog/view/frontend/web/js/view/compare-products.js
+++ b/app/code/Magento/Catalog/view/frontend/web/js/view/compare-products.js
@@ -2,37 +2,32 @@
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
 define([
     'uiComponent',
-    'Magento_Customer/js/customer-data'
-], function (Component, customerData) {
+    'Magento_Customer/js/customer-data',
+    'jquery',
+    'mage/mage',
+    'mage/decorate'
+], function (Component, customerData, $) {
     'use strict';
 
     var sidebarInitialized = false;
 
+    /**
+     * Initialize sidebar
+     */
     function initSidebar() {
         if (sidebarInitialized) {
-            return ;
+            return;
         }
+
         sidebarInitialized = true;
-        require([
-            'jquery',
-            'mage/mage'
-        ], function ($) {
-            $('[data-role=compare-products-sidebar]').mage('compareItems', {
-                "removeConfirmMessage": $.mage.__(
-                    "Are you sure you want to remove this item from your Compare Products list?"
-                ),
-                "removeSelector": "#compare-items a.action.delete",
-                "clearAllConfirmMessage": $.mage.__(
-                    "Are you sure you want to remove all items from your Compare Products list?"
-                ),
-                "clearAllSelector": "#compare-clear-all"
-            });
-        });
+        $('[data-role=compare-products-sidebar]').decorate('list', true);
     }
 
     return Component.extend({
+        /** @inheritdoc */
         initialize: function () {
             this._super();
             this.compareProducts = customerData.get('compare-products');
diff --git a/app/code/Magento/CatalogImportExport/Model/Export/Product.php b/app/code/Magento/CatalogImportExport/Model/Export/Product.php
index 02953743662ebbfe52124c2b760258361810cd6f..86b150062d3c057afe500a6d76aac3665690ba87 100644
--- a/app/code/Magento/CatalogImportExport/Model/Export/Product.php
+++ b/app/code/Magento/CatalogImportExport/Model/Export/Product.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\CatalogImportExport\Model\Export;
 
+use Magento\Framework\DB\Ddl\Table;
 use Magento\ImportExport\Model\Import;
 use \Magento\Store\Model\Store;
 use \Magento\CatalogImportExport\Model\Import\Product as ImportProduct;
@@ -127,6 +128,13 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity
      */
     protected $_attributeTypes = [];
 
+    /**
+     * Attributes defined by user
+     *
+     * @var array
+     */
+    private $userDefinedAttributes = [];
+
     /**
      * Product collection
      *
@@ -261,7 +269,11 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity
      */
     protected $dateAttrCodes = [
         'special_from_date',
-        'special_to_date'
+        'special_to_date',
+        'news_from_date',
+        'news_to_date',
+        'custom_design_from',
+        'custom_design_to'
     ];
 
     /**
@@ -817,7 +829,7 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity
         while (true) {
             ++$page;
             $entityCollection = $this->_getEntityCollection(true);
-            $entityCollection->setOrder('has_options', 'asc');
+            $entityCollection->setOrder('entity_id', 'asc');
             $entityCollection->setStoreId(Store::DEFAULT_STORE_ID);
             $this->_prepareEntityCollection($entityCollection);
             $this->paginateCollection($page, $this->getItemsPerPage());
@@ -910,20 +922,24 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity
                     }
                     $fieldName = isset($this->_fieldsMap[$code]) ? $this->_fieldsMap[$code] : $code;
 
-                    if (in_array($code, $this->dateAttrCodes)) {
-                        $attrValue = $this->_localeDate->formatDateTime(
-                            new \DateTime($attrValue),
-                            \IntlDateFormatter::SHORT,
-                            \IntlDateFormatter::NONE,
-                            null,
-                            date_default_timezone_get()
-                        );
-                    } else if ($this->_attributeTypes[$code] === 'datetime') {
-                        $attrValue = $this->_localeDate->formatDateTime(
-                            new \DateTime($attrValue),
-                            \IntlDateFormatter::SHORT,
-                            \IntlDateFormatter::SHORT
-                        );
+                    if ($this->_attributeTypes[$code] == 'datetime') {
+                        if (in_array($code, $this->dateAttrCodes)
+                            || in_array($code, $this->userDefinedAttributes)
+                        ) {
+                            $attrValue = $this->_localeDate->formatDateTime(
+                                new \DateTime($attrValue),
+                                \IntlDateFormatter::SHORT,
+                                \IntlDateFormatter::NONE,
+                                null,
+                                date_default_timezone_get()
+                            );
+                        } else {
+                            $attrValue = $this->_localeDate->formatDateTime(
+                                new \DateTime($attrValue),
+                                \IntlDateFormatter::SHORT,
+                                \IntlDateFormatter::SHORT
+                            );
+                        }
                     }
 
                     if ($storeId != Store::DEFAULT_STORE_ID
@@ -1380,6 +1396,9 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity
             $this->_attributeValues[$attribute->getAttributeCode()] = $this->getAttributeOptions($attribute);
             $this->_attributeTypes[$attribute->getAttributeCode()] =
                 \Magento\ImportExport\Model\Import::getAttributeType($attribute);
+            if ($attribute->getIsUserDefined()) {
+                $this->userDefinedAttributes[] = $attribute->getAttributeCode();
+            }
         }
         return $this;
     }
diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
index 75ec58ff908762ff82f3c93e6fa218abde6ba42a..16df0866135a7f07760134c7aff9a0b15bc6fb01 100644
--- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php
+++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
@@ -217,7 +217,11 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
      */
     protected $dateAttrCodes = [
         'special_from_date',
-        'special_to_date'
+        'special_to_date',
+        'news_from_date',
+        'news_to_date',
+        'custom_design_from',
+        'custom_design_to'
     ];
 
     /**
@@ -273,7 +277,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
         ValidatorInterface::ERROR_MEDIA_PATH_NOT_ACCESSIBLE => 'Imported resource (image) does not exist in the local media storage',
         ValidatorInterface::ERROR_MEDIA_URL_NOT_ACCESSIBLE => 'Imported resource (image) could not be downloaded from external resource due to timeout or access permissions',
         ValidatorInterface::ERROR_INVALID_WEIGHT => 'Product weight is invalid',
-        ValidatorInterface::ERROR_DUPLICATE_URL_KEY => 'Specified URL key already exists',
+        ValidatorInterface::ERROR_DUPLICATE_URL_KEY => 'Url key: \'%s\' was already generated for an item with the SKU: \'%s\'. You need to specify the unique URL key manually'
     ];
 
     /**
@@ -561,7 +565,10 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
     /** @var array */
     protected $productUrlSuffix = [];
 
-    /** @var array */
+    /**
+     * @var array
+     * @deprecated
+     */
     protected $productUrlKeys = [];
 
     /**
@@ -1508,6 +1515,10 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
                 }
                 $rowScope = $this->getRowScope($rowData);
 
+                if (empty($rowData[self::URL_KEY])) {
+                    $rowData[self::URL_KEY] = $this->getUrlKey($rowData);
+                }
+
                 $rowSku = $rowData[self::COL_SKU];
 
                 if (null === $rowSku) {
@@ -1692,7 +1703,10 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
 
                     if (
                         'datetime' == $attribute->getBackendType()
-                        && in_array($attribute->getAttributeCode(), $this->dateAttrCodes)
+                        && (
+                            in_array($attribute->getAttributeCode(), $this->dateAttrCodes)
+                            || $attribute->getIsUserDefined()
+                        )
                     ) {
                         $attrValue = $this->dateTime->formatDate($attrValue, false);
                     } else if ('datetime' == $attribute->getBackendType() && strtotime($attrValue)) {
@@ -2360,7 +2374,17 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
                     $this->urlKeys[$storeId][$urlPath] = $rowData[self::COL_SKU];
                     $this->rowNumbers[$storeId][$urlPath] = $rowNum;
                 } else {
-                    $this->addRowError(ValidatorInterface::ERROR_DUPLICATE_URL_KEY, $rowNum);
+                    $message = sprintf(
+                        $this->retrieveMessageTemplate(ValidatorInterface::ERROR_DUPLICATE_URL_KEY),
+                        $urlKey,
+                        $this->urlKeys[$storeId][$urlPath]
+                    );
+                    $this->addRowError(
+                        ValidatorInterface::ERROR_DUPLICATE_URL_KEY,
+                        $rowNum,
+                        $rowData[self::COL_NAME],
+                        $message
+                    );
                 }
             }
         }
@@ -2409,20 +2433,34 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
         if (empty($rowData['additional_attributes'])) {
             return $rowData;
         }
+        $rowData = array_merge($rowData, $this->parseAdditionalAttributes($rowData['additional_attributes']));
+        return $rowData;
+    }
 
-        $attributeNameValuePairs = explode($this->getMultipleValueSeparator(), $rowData['additional_attributes']);
-        foreach ($attributeNameValuePairs as $attributeNameValuePair) {
-            $separatorPosition = strpos($attributeNameValuePair, self::PAIR_NAME_VALUE_SEPARATOR);
-            if ($separatorPosition !== false) {
-                $key = substr($attributeNameValuePair, 0, $separatorPosition);
-                $value = substr(
-                    $attributeNameValuePair,
-                    $separatorPosition + strlen(self::PAIR_NAME_VALUE_SEPARATOR)
-                );
-                $rowData[$key] = $value === false ? '' : $value;
+    /**
+     * Retrieves additional attributes as array code=>value.
+     *
+     * @param string $additionalAttributes
+     * @return array
+     */
+    private function parseAdditionalAttributes($additionalAttributes)
+    {
+        $attributeNameValuePairs = explode($this->getMultipleValueSeparator(), $additionalAttributes);
+        $preparedAttributes = [];
+        $code = '';
+        foreach ($attributeNameValuePairs as $attributeData) {
+            //process case when attribute has ImportModel::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR inside its value
+            if (strpos($attributeData, self::PAIR_NAME_VALUE_SEPARATOR) === false) {
+                if (!$code) {
+                    continue;
+                }
+                $preparedAttributes[$code] .= $this->getMultipleValueSeparator() . $attributeData;
+                continue;
             }
+            list($code, $value) = explode(self::PAIR_NAME_VALUE_SEPARATOR, $attributeData, 2);
+            $preparedAttributes[$code] = $value;
         }
-        return $rowData;
+        return $preparedAttributes;
     }
 
     /**
@@ -2502,7 +2540,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
             $rowData = $this->_customFieldsMapping($rowData);
 
             $this->validateRow($rowData, $source->key());
-            
+
             $source->next();
         }
         $this->checkUrlKeyDuplicates();
@@ -2562,12 +2600,14 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
     protected function getUrlKey($rowData)
     {
         if (!empty($rowData[self::URL_KEY])) {
-            $this->productUrlKeys[$rowData[self::COL_SKU]] = $rowData[self::URL_KEY];
+            return $rowData[self::URL_KEY];
         }
-        $urlKey = !empty($this->productUrlKeys[$rowData[self::COL_SKU]])
-            ? $this->productUrlKeys[$rowData[self::COL_SKU]]
-            : $this->productUrl->formatUrlKey($rowData[self::COL_NAME]);
-        return $urlKey;
+
+        if (!empty($rowData[self::COL_NAME])) {
+            return $this->productUrl->formatUrlKey($rowData[self::COL_NAME]);
+        }
+
+        return '';
     }
 
     /**
diff --git a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Export/ProductTest.php b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Export/ProductTest.php
index c61cb03aefa41596bbac8d1da1c5b50e55e12754..5e68a7d80bb4ac31354bfa8de80892146f5e94ae 100644
--- a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Export/ProductTest.php
+++ b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Export/ProductTest.php
@@ -403,7 +403,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
         $this->product->expects($this->once())->method('_prepareEntityCollection')->with($this->abstractCollection);
         $this->product->expects($this->once())->method('getItemsPerPage')->willReturn($itemsPerPage);
         $this->product->expects($this->once())->method('paginateCollection')->with($page, $itemsPerPage);
-        $this->abstractCollection->expects($this->once())->method('setOrder')->with('has_options', 'asc');
+        $this->abstractCollection->expects($this->once())->method('setOrder')->with('entity_id', 'asc');
         $this->abstractCollection->expects($this->once())->method('setStoreId')->with(Store::DEFAULT_STORE_ID);
 
         $this->abstractCollection->expects($this->once())->method('count')->willReturn(0);
@@ -434,7 +434,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
         $this->product->expects($this->once())->method('_prepareEntityCollection')->with($this->abstractCollection);
         $this->product->expects($this->once())->method('getItemsPerPage')->willReturn($itemsPerPage);
         $this->product->expects($this->once())->method('paginateCollection')->with($page, $itemsPerPage);
-        $this->abstractCollection->expects($this->once())->method('setOrder')->with('has_options', 'asc');
+        $this->abstractCollection->expects($this->once())->method('setOrder')->with('entity_id', 'asc');
         $this->abstractCollection->expects($this->once())->method('setStoreId')->with(Store::DEFAULT_STORE_ID);
 
         $this->abstractCollection->expects($this->once())->method('count')->willReturn(1);
diff --git a/app/code/Magento/CatalogInventory/Block/Stockqty/AbstractStockqty.php b/app/code/Magento/CatalogInventory/Block/Stockqty/AbstractStockqty.php
index 9c080905165ae668a582c9f78303904e2a48458e..7f5d69754f4691b213c93c203dfc07f742b73f2c 100644
--- a/app/code/Magento/CatalogInventory/Block/Stockqty/AbstractStockqty.php
+++ b/app/code/Magento/CatalogInventory/Block/Stockqty/AbstractStockqty.php
@@ -15,6 +15,8 @@ abstract class AbstractStockqty extends \Magento\Framework\View\Element\Template
 {
     /**
      * Threshold qty config path
+     * @deprecated
+     * @see \Magento\CatalogInventory\Model\Configuration::XML_PATH_STOCK_THRESHOLD_QTY
      */
     const XML_PATH_STOCK_THRESHOLD_QTY = 'cataloginventory/options/stock_threshold_qty';
 
diff --git a/app/code/Magento/CatalogInventory/Model/Configuration.php b/app/code/Magento/CatalogInventory/Model/Configuration.php
index d1509eec3d4adce87cfd4b8ecf75f63485bbeff5..e660543e55605be39821e342feb5b9e2b9275410 100644
--- a/app/code/Magento/CatalogInventory/Model/Configuration.php
+++ b/app/code/Magento/CatalogInventory/Model/Configuration.php
@@ -96,6 +96,11 @@ class Configuration implements StockConfigurationInterface
      */
     const XML_PATH_DISPLAY_PRODUCT_STOCK_STATUS = 'cataloginventory/options/display_product_stock_status';
 
+    /**
+     * Threshold qty config path
+     */
+    const XML_PATH_STOCK_THRESHOLD_QTY = 'cataloginventory/options/stock_threshold_qty';
+
     /**
      * @var ConfigInterface
      */
@@ -385,6 +390,19 @@ class Configuration implements StockConfigurationInterface
         );
     }
 
+    /**
+     * @param null|string|bool|int|\Magento\Store\Model\Store $store
+     * @return string|null
+     */
+    public function getStockThresholdQty($store = null)
+    {
+        return $this->scopeConfig->getValue(
+            self::XML_PATH_STOCK_THRESHOLD_QTY,
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+            $store
+        );
+    }
+
     /**
      * Retrieve inventory item options (used in config)
      *
diff --git a/app/code/Magento/CatalogInventory/Model/Indexer/Stock/AbstractAction.php b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/AbstractAction.php
index cabbfb807070c65eeff88a3cc1576c8d7c40ae00..1aa9fb8ac6d60e200e595f6c1d8f816caf10f5b4 100644
--- a/app/code/Magento/CatalogInventory/Model/Indexer/Stock/AbstractAction.php
+++ b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/AbstractAction.php
@@ -8,8 +8,7 @@
 
 namespace Magento\CatalogInventory\Model\Indexer\Stock;
 
-use Magento\Catalog\Model\Category;
-use Magento\Catalog\Model\Product;
+use Magento\Framework\App\ObjectManager;
 use Magento\Framework\App\ResourceConnection;
 
 /**
@@ -66,6 +65,11 @@ abstract class AbstractAction
      */
     private $eventManager;
 
+    /**
+     * @var CacheCleaner
+     */
+    private $cacheCleaner;
+
     /**
      * @param ResourceConnection $resource
      * @param \Magento\CatalogInventory\Model\ResourceModel\Indexer\StockFactory $indexerFactory
@@ -219,14 +223,31 @@ abstract class AbstractAction
      * Refresh entities index
      *
      * @param array $productIds
-     * @return array Affected ids
+     * @return $this
      */
     protected function _reindexRows($productIds = [])
     {
-        $connection = $this->_getConnection();
         if (!is_array($productIds)) {
             $productIds = [$productIds];
         }
+
+        $this->getCacheCleaner()->clean($productIds, function () use ($productIds) {
+            $this->doReindex($productIds);
+        });
+
+        return $this;
+    }
+
+    /**
+     * Refresh entities index
+     *
+     * @param array $productIds
+     * @return void
+     */
+    private function doReindex($productIds = [])
+    {
+        $connection = $this->_getConnection();
+
         $parentIds = $this->getRelationsByChild($productIds);
         $processIds = $parentIds ? array_merge($parentIds, $productIds) : $productIds;
 
@@ -247,11 +268,17 @@ abstract class AbstractAction
                 $indexer->reindexEntity($byType[$indexer->getTypeId()]);
             }
         }
-        
-        $this->cacheContext->registerEntities(Product::CACHE_TAG, $productIds);
-        $this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->cacheContext]);
-        
-        return $this;
+    }
+
+    /**
+     * @return CacheCleaner
+     */
+    private function getCacheCleaner()
+    {
+        if (null === $this->cacheCleaner) {
+            $this->cacheCleaner = ObjectManager::getInstance()->get(CacheCleaner::class);
+        }
+        return $this->cacheCleaner;
     }
 
     /**
diff --git a/app/code/Magento/CatalogInventory/Model/Indexer/Stock/CacheCleaner.php b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/CacheCleaner.php
new file mode 100644
index 0000000000000000000000000000000000000000..59380822e616299d3934967d87d2efebbaf90f60
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/CacheCleaner.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ * @category    Magento
+ * @package     Magento_CatalogInventory
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogInventory\Model\Indexer\Stock;
+
+use Magento\CatalogInventory\Api\StockConfigurationInterface;
+use Magento\Framework\App\ResourceConnection;
+use Magento\Framework\DB\Adapter\AdapterInterface;
+use Magento\Framework\Event\ManagerInterface;
+use Magento\Framework\Indexer\CacheContext;
+use Magento\CatalogInventory\Model\Stock;
+use Magento\Catalog\Model\Product;
+
+/**
+ * Clean product cache only when stock status was updated
+ */
+class CacheCleaner
+{
+    /**
+     * @var ResourceConnection
+     */
+    private $resource;
+
+    /**
+     * @var StockConfigurationInterface
+     */
+    private $stockConfiguration;
+
+    /**
+     * @var CacheContext
+     */
+    private $cacheContext;
+
+    /**
+     * @var ManagerInterface
+     */
+    private $eventManager;
+
+    /**
+     * @var AdapterInterface
+     */
+    private $connection;
+
+    /**
+     * @param ResourceConnection $resource
+     * @param StockConfigurationInterface $stockConfiguration
+     * @param CacheContext $cacheContext
+     * @param ManagerInterface $eventManager
+     */
+    public function __construct(
+        ResourceConnection $resource,
+        StockConfigurationInterface $stockConfiguration,
+        CacheContext $cacheContext,
+        ManagerInterface $eventManager
+    ) {
+        $this->resource = $resource;
+        $this->stockConfiguration = $stockConfiguration;
+        $this->cacheContext = $cacheContext;
+        $this->eventManager = $eventManager;
+    }
+
+    /**
+     * @param array $productIds
+     * @param callable $reindex
+     * @return void
+     */
+    public function clean(array $productIds, callable $reindex)
+    {
+        $productStatusesBefore = $this->getProductStockStatuses($productIds);
+        $reindex();
+        $productStatusesAfter = $this->getProductStockStatuses($productIds);
+        $productIds = $this->getProductIds($productStatusesBefore, $productStatusesAfter);
+        if ($productIds) {
+            $this->cacheContext->registerEntities(Product::CACHE_TAG, $productIds);
+            $this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->cacheContext]);
+        }
+    }
+
+    /**
+     * @param array $productIds
+     * @return array
+     */
+    private function getProductStockStatuses(array $productIds)
+    {
+        $select = $this->getConnection()->select()
+            ->from(
+                $this->resource->getTableName('cataloginventory_stock_status'),
+                ['product_id', 'stock_status', 'qty']
+            )->where('product_id IN (?)', $productIds)
+            ->where('stock_id = ?', Stock::DEFAULT_STOCK_ID)
+            ->where('website_id = ?', $this->stockConfiguration->getDefaultScopeId());
+
+        $statuses = [];
+        foreach ($this->getConnection()->fetchAll($select) as $item) {
+            $statuses[$item['product_id']] = $item;
+        }
+        return $statuses;
+    }
+
+    /**
+     * @param array $productStatusesBefore
+     * @param array $productStatusesAfter
+     * @return array
+     */
+    private function getProductIds(array $productStatusesBefore, array $productStatusesAfter)
+    {
+        $productIds = [];
+        $stockThresholdQty = $this->stockConfiguration->getStockThresholdQty();
+        foreach ($productStatusesBefore as $productId => $statusBefore) {
+            $statusAfter = $productStatusesAfter[$productId];
+            if ($statusBefore['stock_status'] !== $statusAfter['stock_status']
+                || ($stockThresholdQty && $statusAfter['qty'] <= $stockThresholdQty)) {
+                $productIds[] = $productId;
+            }
+        }
+
+        return $productIds;
+    }
+
+    /**
+     * @return AdapterInterface
+     */
+    private function getConnection()
+    {
+        if (null === $this->connection) {
+            $this->connection = $this->resource->getConnection();
+        }
+
+        return $this->connection;
+    }
+}
diff --git a/app/code/Magento/CatalogInventory/Model/Stock/Status.php b/app/code/Magento/CatalogInventory/Model/Stock/Status.php
index 50e58e5b756f8fa14ebb608f5c59828ab64901f9..b375da3434e3f2a02d7dfa00265a7dbe2157fa02 100644
--- a/app/code/Magento/CatalogInventory/Model/Stock/Status.php
+++ b/app/code/Magento/CatalogInventory/Model/Stock/Status.php
@@ -100,7 +100,7 @@ class Status extends AbstractExtensibleModel implements StockStatusInterface
      */
     public function getStockId()
     {
-        return $this->getData(self::KEY_WEBSITE_ID);
+        return $this->getData(self::KEY_STOCK_ID);
     }
 
     /**
diff --git a/app/code/Magento/CatalogInventory/Setup/UpgradeData.php b/app/code/Magento/CatalogInventory/Setup/UpgradeData.php
new file mode 100644
index 0000000000000000000000000000000000000000..db3408c01b77f9fc620ee0862f2f71f2eec232c5
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Setup/UpgradeData.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogInventory\Setup;
+
+use Magento\CatalogInventory\Api\StockConfigurationInterface;
+use Magento\Framework\Indexer\AbstractProcessor;
+use Magento\Framework\Setup\UpgradeDataInterface;
+use Magento\Framework\Setup\ModuleContextInterface;
+use Magento\Framework\Setup\ModuleDataSetupInterface;
+use Magento\Store\Model\StoreManagerInterface;
+
+/**
+ * Upgrade Data script
+ * @codeCoverageIgnore
+ */
+class UpgradeData implements UpgradeDataInterface
+{
+    /**
+     * @var StockConfigurationInterface
+     */
+    private $configuration;
+
+    /**
+     * @var AbstractProcessor
+     */
+    private $indexerProcessor;
+
+    /**
+     * @var StoreManagerInterface
+     */
+    private $storeManager;
+
+    /**
+     * @param StockConfigurationInterface $configuration
+     * @param StoreManagerInterface $storeManager
+     * @param AbstractProcessor $indexerProcessor
+     */
+    public function __construct(
+        StockConfigurationInterface $configuration,
+        StoreManagerInterface $storeManager,
+        AbstractProcessor $indexerProcessor
+    ) {
+        $this->configuration = $configuration;
+        $this->storeManager = $storeManager;
+        $this->indexerProcessor = $indexerProcessor;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
+    {
+        $setup->startSetup();
+        if (version_compare($context->getVersion(), '2.0.2') < 0) {
+            $this->upgradeCatalogInventoryStockItem($setup);
+        }
+        $setup->endSetup();
+    }
+
+    /**
+     * @param ModuleDataSetupInterface $setup
+     * @return void
+     */
+    private function upgradeCatalogInventoryStockItem($setup)
+    {
+        $setup->getConnection()->update(
+            $setup->getTable('cataloginventory_stock_item'),
+            ['website_id' => $this->configuration->getDefaultScopeId()],
+            ['website_id = ?' => $this->storeManager->getWebsite()->getId()]
+        );
+        $this->indexerProcessor->getIndexer()->invalidate();
+    }
+}
diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Adminhtml/Stock/ItemTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Adminhtml/Stock/ItemTest.php
index aef8141e70f340862e7c8f610cdfbf6cd4d6cf8d..dfb8073e718a7f31dd316a88efc7bf9b373dcd60 100644
--- a/app/code/Magento/CatalogInventory/Test/Unit/Model/Adminhtml/Stock/ItemTest.php
+++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Adminhtml/Stock/ItemTest.php
@@ -62,6 +62,6 @@ class ItemTest extends \PHPUnit_Framework_TestCase
     public function testGetIdentities()
     {
         $this->_model->setProductId(1);
-        $this->assertEquals(['catalog_product_1'], $this->_model->getIdentities());
+        $this->assertEquals(['cat_p_1'], $this->_model->getIdentities());
     }
 }
diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Indexer/Stock/CacheCleanerTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Indexer/Stock/CacheCleanerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..690b20f4e97c568ef0bdcb82939eff3d1bef2fde
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Indexer/Stock/CacheCleanerTest.php
@@ -0,0 +1,169 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogInventory\Test\Unit\Model\Indexer\Stock;
+
+use Magento\CatalogInventory\Api\StockConfigurationInterface;
+use Magento\CatalogInventory\Model\Indexer\Stock\CacheCleaner;
+use Magento\Framework\App\ResourceConnection;
+use Magento\Framework\DB\Adapter\AdapterInterface;
+use Magento\Framework\DB\Select;
+use Magento\Framework\Event\ManagerInterface;
+use Magento\Framework\Indexer\CacheContext;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Catalog\Model\Product;
+
+class CacheCleanerTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var CacheCleaner
+     */
+    private $unit;
+
+    /**
+     * @var ResourceConnection|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $resourceMock;
+
+    /**
+     * @var AdapterInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $connectionMock;
+
+    /**
+     * @var ManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $eventManagerMock;
+
+    /**
+     * @var CacheContext|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $cacheContextMock;
+
+    /**
+     * @var StockConfigurationInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $stockConfigurationMock;
+
+    /**
+     * @var Select|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $selectMock;
+
+    protected function setUp()
+    {
+        $this->resourceMock = $this->getMockBuilder(ResourceConnection::class)->disableOriginalConstructor()->getMock();
+        $this->connectionMock = $this->getMockBuilder(AdapterInterface::class)->getMock();
+        $this->stockConfigurationMock = $this->getMockBuilder(StockConfigurationInterface::class)
+            ->setMethods(['getStockThresholdQty'])->getMockForAbstractClass();
+        $this->cacheContextMock = $this->getMockBuilder(CacheContext::class)->disableOriginalConstructor()->getMock();
+        $this->eventManagerMock = $this->getMockBuilder(ManagerInterface::class)->getMock();
+        $this->selectMock = $this->getMockBuilder(Select::class)->disableOriginalConstructor()->getMock();
+
+        $this->resourceMock->expects($this->any())
+            ->method('getConnection')
+            ->will($this->returnValue($this->connectionMock));
+
+        $this->unit = (new ObjectManager($this))->getObject(
+            CacheCleaner::class,
+            [
+                'resource' => $this->resourceMock,
+                'stockConfiguration' => $this->stockConfigurationMock,
+                'cacheContext' => $this->cacheContextMock,
+                'eventManager' => $this->eventManagerMock,
+            ]
+        );
+    }
+
+    /**
+     * @param bool $stockStatusBefore
+     * @param bool $stockStatusAfter
+     * @param int $qtyAfter
+     * @param bool|int $stockThresholdQty
+     * @dataProvider cleanDataProvider
+     */
+    public function testClean($stockStatusBefore, $stockStatusAfter, $qtyAfter, $stockThresholdQty)
+    {
+        $productId = 123;
+        $this->selectMock->expects($this->any())->method('from')->willReturnSelf();
+        $this->selectMock->expects($this->any())->method('where')->willReturnSelf();
+        $this->connectionMock->expects($this->exactly(2))->method('select')->willReturn($this->selectMock);
+        $this->connectionMock->expects($this->exactly(2))->method('fetchAll')->willReturnOnConsecutiveCalls(
+            [
+                ['product_id' => $productId, 'stock_status' => $stockStatusBefore],
+            ],
+            [
+                ['product_id' => $productId, 'stock_status' => $stockStatusAfter, 'qty' => $qtyAfter],
+            ]
+        );
+        $this->stockConfigurationMock->expects($this->once())->method('getStockThresholdQty')
+            ->willReturn($stockThresholdQty);
+        $this->cacheContextMock->expects($this->once())->method('registerEntities')
+            ->with(Product::CACHE_TAG, [$productId]);
+        $this->eventManagerMock->expects($this->once())->method('dispatch')
+            ->with('clean_cache_by_tags', ['object' => $this->cacheContextMock]);
+
+        $callback = function () {
+        };
+        $this->unit->clean([], $callback);
+    }
+
+    /**
+     * @return array
+     */
+    public function cleanDataProvider()
+    {
+        return [
+            [true, false, 1, false],
+            [false, true, 1, false],
+            [true, true, 1, 2],
+            [false, false, 1, 2],
+        ];
+    }
+
+    /**
+     * @param bool $stockStatusBefore
+     * @param bool $stockStatusAfter
+     * @param int $qtyAfter
+     * @param bool|int $stockThresholdQty
+     * @dataProvider notCleanCacheDataProvider
+     */
+    public function testNotCleanCache($stockStatusBefore, $stockStatusAfter, $qtyAfter, $stockThresholdQty)
+    {
+        $productId = 123;
+        $this->selectMock->expects($this->any())->method('from')->willReturnSelf();
+        $this->selectMock->expects($this->any())->method('where')->willReturnSelf();
+        $this->connectionMock->expects($this->exactly(2))->method('select')->willReturn($this->selectMock);
+        $this->connectionMock->expects($this->exactly(2))->method('fetchAll')->willReturnOnConsecutiveCalls(
+            [
+                ['product_id' => $productId, 'stock_status' => $stockStatusBefore],
+            ],
+            [
+                ['product_id' => $productId, 'stock_status' => $stockStatusAfter, 'qty' => $qtyAfter],
+            ]
+        );
+        $this->stockConfigurationMock->expects($this->once())->method('getStockThresholdQty')
+            ->willReturn($stockThresholdQty);
+        $this->cacheContextMock->expects($this->never())->method('registerEntities');
+        $this->eventManagerMock->expects($this->never())->method('dispatch');
+
+        $callback = function () {
+        };
+        $this->unit->clean([], $callback);
+    }
+
+    /**
+     * @return array
+     */
+    public function notCleanCacheDataProvider()
+    {
+        return [
+            [true, true, 1, false],
+            [false, false, 1, false],
+            [true, true, 3, 2],
+        ];
+    }
+}
diff --git a/app/code/Magento/CatalogInventory/etc/di.xml b/app/code/Magento/CatalogInventory/etc/di.xml
index eb97aa454f6e8c63583bfd9cd4b6fec32b6d67e1..71b42ef89f73ce981f25393179fbbd05f59a4d08 100644
--- a/app/code/Magento/CatalogInventory/etc/di.xml
+++ b/app/code/Magento/CatalogInventory/etc/di.xml
@@ -74,4 +74,9 @@
     <type name="Magento\Catalog\Api\ProductRepositoryInterface">
         <plugin name="catalogInventoryAroundSave" sortOrder="20" type="Magento\CatalogInventory\Model\Plugin\AroundProductRepositorySave"/>
     </type>
+    <type name="Magento\CatalogInventory\Setup\UpgradeData">
+        <arguments>
+            <argument name="indexerProcessor" xsi:type="object">Magento\CatalogInventory\Model\Indexer\Stock\Processor</argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/CatalogInventory/etc/module.xml b/app/code/Magento/CatalogInventory/etc/module.xml
index 2224da524fccc1029bd42e588b0696c65efd0408..711d18bead9c9ece376e74f3b13aced3419b7806 100644
--- a/app/code/Magento/CatalogInventory/etc/module.xml
+++ b/app/code/Magento/CatalogInventory/etc/module.xml
@@ -6,7 +6,7 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
-    <module name="Magento_CatalogInventory" setup_version="2.0.1">
+    <module name="Magento_CatalogInventory" setup_version="2.0.2">
         <sequence>
             <module name="Magento_Catalog"/>
         </sequence>
diff --git a/app/code/Magento/CatalogRule/view/adminhtml/ui_component/catalog_rule_form.xml b/app/code/Magento/CatalogRule/view/adminhtml/ui_component/catalog_rule_form.xml
index af60e0247169bb402d5b6d71be4576ad2ed24566..acfd1efa605c758750d1205662cbdb959e655d15 100644
--- a/app/code/Magento/CatalogRule/view/adminhtml/ui_component/catalog_rule_form.xml
+++ b/app/code/Magento/CatalogRule/view/adminhtml/ui_component/catalog_rule_form.xml
@@ -149,7 +149,7 @@
                     <item name="source" xsi:type="string">catalog_rule</item>
                     <item name="dataScope" xsi:type="string">customer_group_ids</item>
                 </item>
-                <item name="options" xsi:type="object">\Magento\Customer\Model\Customer\Source\GroupSourceInterface</item>
+                <item name="options" xsi:type="object">\Magento\CatalogRule\Model\Rule\CustomerGroupsOptionsProvider</item>
             </argument>
         </field>
         <field name="from_date">
diff --git a/app/code/Magento/CatalogSearch/Block/Advanced/Result.php b/app/code/Magento/CatalogSearch/Block/Advanced/Result.php
index 7b720c8c7c87a33bb55cd51e50deac5472e56ebf..4351b134e4a1100f2decc3b5e1d8f39a0bead78f 100644
--- a/app/code/Magento/CatalogSearch/Block/Advanced/Result.php
+++ b/app/code/Magento/CatalogSearch/Block/Advanced/Result.php
@@ -64,6 +64,7 @@ class Result extends Template
      */
     protected function _prepareLayout()
     {
+        $this->pageConfig->getTitle()->set($this->getPageTitle());
         $breadcrumbs = $this->getLayout()->getBlock('breadcrumbs');
         if ($breadcrumbs) {
             $breadcrumbs->addCrumb(
@@ -84,6 +85,16 @@ class Result extends Template
         return parent::_prepareLayout();
     }
 
+    /**
+     * Get page title
+     *
+     * @return \Magento\Framework\Phrase
+     */
+    private function getPageTitle()
+    {
+        return __('Advanced Search Results');
+    }
+
     /**
      * Set order options
      *
diff --git a/app/code/Magento/CatalogSearch/Model/Advanced.php b/app/code/Magento/CatalogSearch/Model/Advanced.php
index ef332a675e8a84f2aeb85a9c1b8443713ca57afa..f469820b3bb2db88821119e6435fe20adb4d1279 100644
--- a/app/code/Magento/CatalogSearch/Model/Advanced.php
+++ b/app/code/Magento/CatalogSearch/Model/Advanced.php
@@ -368,9 +368,11 @@ class Advanced extends \Magento\Framework\Model\AbstractModel
                 $value = $value['label'];
             }
         } elseif ($attribute->getFrontendInput() == 'boolean') {
-            $value = $value == 1
-                ? __('Yes')
-                : __('No');
+            if (is_numeric($value)) {
+                $value = $value == 1 ? __('Yes') : __('No');
+            } else {
+                $value = false;
+            }
         }
 
         return $value;
diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandlerFactory.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandlerFactory.php
index bb2df11c9083dfd122bfd4809283634b4cc8e090..58be7fcb1bcb9a97eed2eb9351dba181cf816080 100644
--- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandlerFactory.php
+++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandlerFactory.php
@@ -75,12 +75,14 @@ class IndexerHandlerFactory
         $indexer = $this->_objectManager->create($this->handlers[$currentHandler], $data);
 
         if (!$indexer instanceof IndexerInterface) {
-            throw new \InvalidArgumentException($indexer . ' doesn\'t implement \Magento\Framework\IndexerInterface');
+            throw new \InvalidArgumentException(
+                $currentHandler . ' indexer handler doesn\'t implement ' . IndexerInterface::class
+            );
         }
 
         if ($indexer && !$indexer->isAvailable()) {
             throw new \LogicException(
-                'Indexer handler is not available: ' . $indexer
+                'Indexer handler is not available: ' . $currentHandler
             );
         }
         return $indexer;
diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php
index 2ca347aae83c29ee3b10923245fe618d84d54a6c..1dc33743d76c187b2f20dec9149c3bd10dd2ddd3 100644
--- a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php
+++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator.php
@@ -8,7 +8,8 @@ namespace Magento\CatalogSearch\Model\Search;
 use Magento\Catalog\Api\Data\EavAttributeInterface;
 use Magento\Catalog\Model\Entity\Attribute;
 use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory;
-use Magento\Framework\Search\Request\BucketInterface;
+use Magento\CatalogSearch\Model\Search\RequestGenerator\GeneratorResolver;
+use Magento\Framework\App\ObjectManager;
 use Magento\Framework\Search\Request\FilterInterface;
 use Magento\Framework\Search\Request\QueryInterface;
 
@@ -25,12 +26,22 @@ class RequestGenerator
      */
     private $productAttributeCollectionFactory;
 
+    /**
+     * @var GeneratorResolver
+     */
+    private $generatorResolver;
+
     /**
      * @param CollectionFactory $productAttributeCollectionFactory
+     * @param GeneratorResolver $generatorResolver
      */
-    public function __construct(CollectionFactory $productAttributeCollectionFactory)
-    {
+    public function __construct(
+        CollectionFactory $productAttributeCollectionFactory,
+        GeneratorResolver $generatorResolver = null
+    ) {
         $this->productAttributeCollectionFactory = $productAttributeCollectionFactory;
+        $this->generatorResolver = $generatorResolver
+            ?: ObjectManager::getInstance()->get(GeneratorResolver::class);
     }
 
     /**
@@ -62,7 +73,7 @@ class RequestGenerator
         $request = [];
         foreach ($this->getSearchableAttributes() as $attribute) {
             if ($attribute->getData($attributeType)) {
-                if (!in_array($attribute->getAttributeCode(), ['price', 'category_ids'])) {
+                if (!in_array($attribute->getAttributeCode(), ['price', 'category_ids'], true)) {
                     $queryName = $attribute->getAttributeCode() . '_query';
 
                     $request['queries'][$container]['queryReference'][] = [
@@ -76,58 +87,33 @@ class RequestGenerator
                         'filterReference' => [['ref' => $filterName]],
                     ];
                     $bucketName = $attribute->getAttributeCode() . self::BUCKET_SUFFIX;
-                    if ($attribute->getBackendType() == 'decimal') {
-                        $request['filters'][$filterName] = [
-                            'type' => FilterInterface::TYPE_RANGE,
-                            'name' => $filterName,
-                            'field' => $attribute->getAttributeCode(),
-                            'from' => '$' . $attribute->getAttributeCode() . '.from$',
-                            'to' => '$' . $attribute->getAttributeCode() . '.to$',
-                        ];
-                        $request['aggregations'][$bucketName] = [
-                            'type' => BucketInterface::TYPE_DYNAMIC,
-                            'name' => $bucketName,
-                            'field' => $attribute->getAttributeCode(),
-                            'method' => 'manual',
-                            'metric' => [["type" => "count"]],
-                        ];
-                    } else {
-                        $request['filters'][$filterName] = [
-                            'type' => FilterInterface::TYPE_TERM,
-                            'name' => $filterName,
-                            'field' => $attribute->getAttributeCode(),
-                            'value' => '$' . $attribute->getAttributeCode() . '$',
-                        ];
-                        $request['aggregations'][$bucketName] = [
-                            'type' => BucketInterface::TYPE_TERM,
-                            'name' => $bucketName,
-                            'field' => $attribute->getAttributeCode(),
-                            'metric' => [["type" => "count"]],
-                        ];
-                    }
+                    $generator = $this->generatorResolver->getGeneratorForType($attribute->getBackendType());
+                    $request['filters'][$filterName] = $generator->getFilterData($attribute, $filterName);
+                    $request['aggregations'][$bucketName] = $generator->getAggregationData($attribute, $bucketName);
                 }
             }
             /** @var $attribute Attribute */
-            if (in_array($attribute->getAttributeCode(), ['price', 'sku'])
-                || !$attribute->getIsSearchable()
-            ) {
-                //same fields have special semantics
+            if (!$attribute->getIsSearchable() || in_array($attribute->getAttributeCode(), ['price', 'sku'], true)) {
+                // Some fields have their own specific handlers
                 continue;
             }
-            if ($useFulltext) {
+
+            // Match search by custom price attribute isn't supported
+            if ($useFulltext && $attribute->getFrontendInput() !== 'price') {
                 $request['queries']['search']['match'][] = [
                     'field' => $attribute->getAttributeCode(),
                     'boost' => $attribute->getSearchWeight() ?: 1,
                 ];
             }
         }
+
         return $request;
     }
 
     /**
      * Retrieve searchable attributes
      *
-     * @return \Magento\Catalog\Model\Entity\Attribute[]
+     * @return \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection
      */
     protected function getSearchableAttributes()
     {
@@ -231,6 +217,7 @@ class RequestGenerator
                     ];
             }
         }
+
         return $request;
     }
 }
diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php
new file mode 100644
index 0000000000000000000000000000000000000000..52cab1c6ff942b3a94418a808ac96ff6ff5f678a
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/Decimal.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Model\Search\RequestGenerator;
+
+
+use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
+use Magento\Framework\Search\Request\BucketInterface;
+use Magento\Framework\Search\Request\FilterInterface;
+
+class Decimal implements GeneratorInterface
+{
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getFilterData(Attribute $attribute, $filterName)
+    {
+        return [
+            'type' => FilterInterface::TYPE_RANGE,
+            'name' => $filterName,
+            'field' => $attribute->getAttributeCode(),
+            'from' => '$' . $attribute->getAttributeCode() . '.from$',
+            'to' => '$' . $attribute->getAttributeCode() . '.to$',
+        ];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getAggregationData(Attribute $attribute, $bucketName)
+    {
+        return [
+            'type' => BucketInterface::TYPE_DYNAMIC,
+            'name' => $bucketName,
+            'field' => $attribute->getAttributeCode(),
+            'method' => 'manual',
+            'metric' => [['type' => 'count']],
+        ];
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php
new file mode 100644
index 0000000000000000000000000000000000000000..96362ce484b1ee8981d45c0661b760d62b1b7303
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/General.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Model\Search\RequestGenerator;
+
+
+use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
+use Magento\Framework\Search\Request\BucketInterface;
+use Magento\Framework\Search\Request\FilterInterface;
+
+class General implements GeneratorInterface
+{
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getFilterData(Attribute $attribute, $filterName)
+    {
+        return [
+            'type' => FilterInterface::TYPE_TERM,
+            'name' => $filterName,
+            'field' => $attribute->getAttributeCode(),
+            'value' => '$' . $attribute->getAttributeCode() . '$',
+        ];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getAggregationData(Attribute $attribute, $bucketName)
+    {
+        return [
+            'type' => BucketInterface::TYPE_TERM,
+            'name' => $bucketName,
+            'field' => $attribute->getAttributeCode(),
+            'metric' => [['type' => 'count']],
+        ];
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..c43786db2b6968761e4586f40bba9e4a8628f30a
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorInterface.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Model\Search\RequestGenerator;
+
+
+use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
+
+interface GeneratorInterface
+{
+    /**
+     * Get filter data for specific attribute
+     * @param Attribute $attribute
+     * @param string $filterName
+     * @return array
+     */
+    public function getFilterData(Attribute $attribute, $filterName);
+
+    /**
+     * Get aggregation data for specific attribute
+     * @param Attribute $attribute
+     * @param string $bucketName
+     * @return array
+     */
+    public function getAggregationData(Attribute $attribute, $bucketName);
+}
diff --git a/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorResolver.php b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorResolver.php
new file mode 100644
index 0000000000000000000000000000000000000000..129a036ff2544fe4c84a70da98cbf0bb31ace4cb
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Model/Search/RequestGenerator/GeneratorResolver.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Model\Search\RequestGenerator;
+
+class GeneratorResolver
+{
+    /**
+     * @var GeneratorInterface[]
+     */
+    private $generators;
+
+    /**
+     * @var GeneratorInterface
+     */
+    private $defaultGenerator;
+
+    /**
+     * @param GeneratorInterface $defaultGenerator
+     * @param GeneratorInterface[] $generators
+     */
+    public function __construct(GeneratorInterface $defaultGenerator, array $generators)
+    {
+        $this->defaultGenerator = $defaultGenerator;
+        $this->generators = $generators;
+    }
+
+    /**
+     * @param string $type
+     * @return GeneratorInterface
+     * @throws \InvalidArgumentException
+     */
+    public function getGeneratorForType($type)
+    {
+        $generator = isset($this->generators[$type]) ? $this->generators[$type] : $this->defaultGenerator;
+        if (!($generator instanceof GeneratorInterface)) {
+            throw new \InvalidArgumentException(
+                'Generator must implement ' . GeneratorInterface::class
+            );
+        }
+        return $generator;
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/AdvancedTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/AdvancedTest.php
index e15b9b7818181180a22f55417e269d0dece2362e..afff7722fdec7b2eea34a590c85e048080489395 100644
--- a/app/code/Magento/CatalogSearch/Test/Unit/Model/AdvancedTest.php
+++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/AdvancedTest.php
@@ -170,7 +170,7 @@ class AdvancedTest extends \PHPUnit_Framework_TestCase
                             'static'
                         )
                     ],
-                    'values' => ['is_active' => false],
+                    'values' => ['is_active' => 0],
                     'currentCurrencyCode' => 'GBP',
                     'baseCurrencyCode' => 'USD'
                 ],
diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/IndexerHandlerFactoryTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/IndexerHandlerFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..417eb63d08ab4c8af4e9b8d48ff9843d4d7e3ad8
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/IndexerHandlerFactoryTest.php
@@ -0,0 +1,173 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogSearch\Test\Unit\Model\Indexer;
+
+use Magento\CatalogSearch\Model\Indexer\IndexerHandlerFactory;
+use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Framework\Indexer\SaveHandler\IndexerInterface;
+use Magento\Framework\ObjectManagerInterface;
+use Magento\Store\Model\ScopeInterface;
+
+class IndexerHandlerFactoryTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var IndexerHandlerFactory */
+    protected $model;
+
+    /** @var ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $objectManagerMock;
+
+    /** @var ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $scopeConfigMock;
+
+    protected function setUp()
+    {
+        $this->objectManagerMock = $this->getMockBuilder(ObjectManagerInterface::class)
+            ->getMockForAbstractClass();
+        $this->scopeConfigMock = $this->getMockBuilder(ScopeConfigInterface::class)
+            ->getMockForAbstractClass();
+    }
+
+    public function testCreate()
+    {
+        $configPath = 'config_path';
+        $currentHandler = 'current_handler';
+        $currentHandlerClass = 'current_handler_class';
+        $handlers = [
+            $currentHandler => $currentHandlerClass,
+        ];
+        $data = ['data'];
+
+        $this->scopeConfigMock->expects($this->once())
+            ->method('getValue')
+            ->with($configPath, ScopeInterface::SCOPE_STORE)
+            ->willReturn($currentHandler);
+
+        $indexerMock = $this->getMockBuilder(IndexerInterface::class)
+            ->getMockForAbstractClass();
+
+        $this->objectManagerMock->expects($this->once())
+            ->method('create')
+            ->with($currentHandlerClass, $data)
+            ->willReturn($indexerMock);
+
+        $indexerMock->expects($this->once())
+            ->method('isAvailable')
+            ->willReturn(true);
+
+        $this->model = new IndexerHandlerFactory(
+            $this->objectManagerMock,
+            $this->scopeConfigMock,
+            $configPath,
+            $handlers
+        );
+
+        $this->assertEquals($indexerMock, $this->model->create($data));
+    }
+
+    /**
+     * @expectedException \LogicException
+     * @expectedExceptionMessage There is no such indexer handler: current_handler
+     */
+    public function testCreateWithoutHandlers()
+    {
+        $configPath = 'config_path';
+        $currentHandler = 'current_handler';
+        $handlers = [];
+        $data = ['data'];
+
+        $this->scopeConfigMock->expects($this->once())
+            ->method('getValue')
+            ->with($configPath, ScopeInterface::SCOPE_STORE)
+            ->willReturn($currentHandler);
+
+        $this->model = new IndexerHandlerFactory(
+            $this->objectManagerMock,
+            $this->scopeConfigMock,
+            $configPath,
+            $handlers
+        );
+
+        $this->model->create($data);
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     * @expectedExceptionMessage current_handler indexer handler doesn't implement
+     */
+    public function testCreateWithWrongHandler()
+    {
+        $configPath = 'config_path';
+        $currentHandler = 'current_handler';
+        $currentHandlerClass = 'current_handler_class';
+        $handlers = [
+            $currentHandler => $currentHandlerClass,
+        ];
+        $data = ['data'];
+
+        $this->scopeConfigMock->expects($this->once())
+            ->method('getValue')
+            ->with($configPath, ScopeInterface::SCOPE_STORE)
+            ->willReturn($currentHandler);
+
+        $indexerMock = $this->getMockBuilder(\stdClass::class)
+            ->getMockForAbstractClass();
+
+        $this->objectManagerMock->expects($this->once())
+            ->method('create')
+            ->with($currentHandlerClass, $data)
+            ->willReturn($indexerMock);
+
+        $this->model = new IndexerHandlerFactory(
+            $this->objectManagerMock,
+            $this->scopeConfigMock,
+            $configPath,
+            $handlers
+        );
+
+        $this->model->create($data);
+    }
+
+    /**
+     * @expectedException \LogicException
+     * @expectedExceptionMessage Indexer handler is not available: current_handler
+     */
+    public function testCreateWithoutAvailableHandler()
+    {
+        $configPath = 'config_path';
+        $currentHandler = 'current_handler';
+        $currentHandlerClass = 'current_handler_class';
+        $handlers = [
+            $currentHandler => $currentHandlerClass,
+        ];
+        $data = ['data'];
+
+        $this->scopeConfigMock->expects($this->once())
+            ->method('getValue')
+            ->with($configPath, ScopeInterface::SCOPE_STORE)
+            ->willReturn($currentHandler);
+
+        $indexerMock = $this->getMockBuilder(IndexerInterface::class)
+            ->getMockForAbstractClass();
+
+        $this->objectManagerMock->expects($this->once())
+            ->method('create')
+            ->with($currentHandlerClass, $data)
+            ->willReturn($indexerMock);
+
+        $indexerMock->expects($this->once())
+            ->method('isAvailable')
+            ->willReturn(false);
+
+        $this->model = new IndexerHandlerFactory(
+            $this->objectManagerMock,
+            $this->scopeConfigMock,
+            $configPath,
+            $handlers
+        );
+
+        $this->model->create($data);
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/DecimalTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/DecimalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..67a991f51856516ce3e2678bf768729f1d0aa86f
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/DecimalTest.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Test\Unit\Model\Search\RequestGenerator;
+
+use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
+use Magento\CatalogSearch\Model\Search\RequestGenerator\Decimal;
+use Magento\Framework\Search\Request\BucketInterface;
+use Magento\Framework\Search\Request\FilterInterface;
+
+class DecimalTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var  Decimal */
+    private $decimal;
+
+    /** @var  Attribute|\PHPUnit_Framework_MockObject_MockObject */
+    private $attribute;
+
+    protected function setUp()
+    {
+        $this->attribute = $this->getMockBuilder(Attribute::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getAttributeCode'])
+            ->getMockForAbstractClass();
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->decimal = $objectManager->getObject(Decimal::class);
+    }
+
+    public function testGetFilterData()
+    {
+        $filterName = 'test_filter_name';
+        $attributeCode = 'test_attribute_code';
+        $expected = [
+            'type' => FilterInterface::TYPE_RANGE,
+            'name' => $filterName,
+            'field' => $attributeCode,
+            'from' => '$' . $attributeCode . '.from$',
+            'to' => '$' . $attributeCode . '.to$',
+        ];
+        $this->attribute->expects($this->atLeastOnce())
+            ->method('getAttributeCode')
+            ->willReturn($attributeCode);
+        $actual = $this->decimal->getFilterData($this->attribute, $filterName);
+        $this->assertEquals($expected, $actual);
+    }
+
+    public function testGetAggregationData()
+    {
+        $bucketName = 'test_bucket_name';
+        $attributeCode = 'test_attribute_code';
+        $expected = [
+            'type' => BucketInterface::TYPE_DYNAMIC,
+            'name' => $bucketName,
+            'field' => $attributeCode,
+            'method' => 'manual',
+            'metric' => [['type' => 'count']],
+        ];
+        $this->attribute->expects($this->atLeastOnce())
+            ->method('getAttributeCode')
+            ->willReturn($attributeCode);
+        $actual = $this->decimal->getAggregationData($this->attribute, $bucketName);
+        $this->assertEquals($expected, $actual);
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/GeneralTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/GeneralTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d40829e6e53de8883b8f0b4ec4abb2b6d980da68
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/GeneralTest.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Test\Unit\Model\Search\RequestGenerator;
+
+use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
+use Magento\CatalogSearch\Model\Search\RequestGenerator\General;
+use Magento\Framework\Search\Request\BucketInterface;
+use Magento\Framework\Search\Request\FilterInterface;
+
+class GeneralTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var  General */
+    private $general;
+
+    /** @var  Attribute|\PHPUnit_Framework_MockObject_MockObject */
+    private $attribute;
+
+    protected function setUp()
+    {
+        $this->attribute = $this->getMockBuilder(Attribute::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getAttributeCode'])
+            ->getMockForAbstractClass();
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->general = $objectManager->getObject(General::class);
+    }
+
+    public function testGetFilterData()
+    {
+        $filterName = 'test_general_filter_name';
+        $attributeCode = 'test_general_attribute_code';
+        $expected = [
+            'type' => FilterInterface::TYPE_TERM,
+            'name' => $filterName,
+            'field' => $attributeCode,
+            'value' => '$' . $attributeCode . '$',
+        ];
+        $this->attribute->expects($this->atLeastOnce())
+            ->method('getAttributeCode')
+            ->willReturn($attributeCode);
+        $actual = $this->general->getFilterData($this->attribute, $filterName);
+        $this->assertEquals($expected, $actual);
+    }
+
+    public function testGetAggregationData()
+    {
+        $bucketName = 'test_bucket_name';
+        $attributeCode = 'test_attribute_code';
+        $expected = [
+            'type' => BucketInterface::TYPE_TERM,
+            'name' => $bucketName,
+            'field' => $attributeCode,
+            'metric' => [['type' => 'count']],
+        ];
+        $this->attribute->expects($this->atLeastOnce())
+            ->method('getAttributeCode')
+            ->willReturn($attributeCode);
+        $actual = $this->general->getAggregationData($this->attribute, $bucketName);
+        $this->assertEquals($expected, $actual);
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/GeneratorResolverTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/GeneratorResolverTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0b8bf882b850e05d9a5eac0d4887d8756cf56331
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGenerator/GeneratorResolverTest.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Test\Unit\Model\Search\RequestGenerator;
+
+
+use Magento\CatalogSearch\Model\Search\RequestGenerator\GeneratorResolver;
+use Magento\CatalogSearch\Model\Search\RequestGenerator\GeneratorInterface;
+
+class GeneratorResolverTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var  GeneratorResolver */
+    private $resolver;
+
+    /** @var  GeneratorInterface|\PHPUnit_Framework_MockObject_MockObject */
+    private $defaultGenerator;
+
+    /** @var  GeneratorInterface|\PHPUnit_Framework_MockObject_MockObject */
+    private $datetimeGenerator;
+
+    /** @var  GeneratorInterface|\PHPUnit_Framework_MockObject_MockObject */
+    private $rangeGenerator;
+
+    protected function setUp()
+    {
+        $this->defaultGenerator = $this->getMockBuilder(GeneratorInterface::class)
+            ->setMethods([])
+            ->getMockForAbstractClass();
+
+        $this->datetimeGenerator = $this->getMockBuilder(GeneratorInterface::class)
+            ->setMethods([])
+            ->getMockForAbstractClass();
+
+        $this->rangeGenerator = $this->getMockBuilder(GeneratorInterface::class)
+            ->setMethods([])
+            ->getMockForAbstractClass();
+
+        $invalidTypeGenerator = $this->getMockBuilder(\stdClass::class)
+            ->setMethods([]);
+
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->resolver = $objectManager->getObject(
+            GeneratorResolver::class,
+            [
+                'defaultGenerator' => $this->defaultGenerator,
+                'generators' => [
+                    'datetime' => $this->datetimeGenerator,
+                    'range' => $this->datetimeGenerator,
+                    'invalid_type' => $invalidTypeGenerator,
+                ],
+            ]
+        );
+    }
+
+    public function testGetSpecificGenerator()
+    {
+        $this->assertEquals($this->rangeGenerator, $this->resolver->getGeneratorForType('range'));
+        $this->assertEquals($this->datetimeGenerator, $this->resolver->getGeneratorForType('datetime'));
+    }
+
+    public function testGetFallbackGenerator()
+    {
+        $this->assertEquals($this->defaultGenerator, $this->resolver->getGeneratorForType('unknown_type'));
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testGetInvalidGeneratorType()
+    {
+        $this->resolver->getGeneratorForType('invalid_type');
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGeneratorTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGeneratorTest.php
index f66bacfad306a0cd41cfc1a44206c3f0e60e6aa7..ca56dd83444b2b01d92b6c8e65023acdeeea277f 100644
--- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGeneratorTest.php
+++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/RequestGeneratorTest.php
@@ -6,6 +6,8 @@
 namespace Magento\CatalogSearch\Test\Unit\Model\Search;
 
 use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory;
+use Magento\CatalogSearch\Model\Search\RequestGenerator\GeneratorResolver;
+use Magento\CatalogSearch\Model\Search\RequestGenerator\GeneratorInterface;
 
 class RequestGeneratorTest extends \PHPUnit_Framework_TestCase
 {
@@ -25,11 +27,29 @@ class RequestGeneratorTest extends \PHPUnit_Framework_TestCase
                 ->setMethods(['create'])
                 ->disableOriginalConstructor()
                 ->getMock();
+        $generatorResolver = $this->getMockBuilder(GeneratorResolver::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getGeneratorForType'])
+            ->getMock();
+        $generator = $this->getMockBuilder(GeneratorInterface::class)
+            ->setMethods(['getFilterData', 'getAggregationData'])
+            ->getMockForAbstractClass();
+        $generator->expects($this->any())
+            ->method('getFilterData')
+            ->willReturn(['some filter data goes here']);
+        $generator->expects($this->any())
+            ->method('getAggregationData')
+            ->willReturn(['some aggregation data goes here']);
+        $generatorResolver->method('getGeneratorForType')
+            ->willReturn($generator);
 
         $this->objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
         $this->object = $this->objectManagerHelper->getObject(
             \Magento\CatalogSearch\Model\Search\RequestGenerator::class,
-            ['productAttributeCollectionFactory' => $this->productAttributeCollectionFactory]
+            [
+                'productAttributeCollectionFactory' => $this->productAttributeCollectionFactory,
+                'generatorResolver' => $generatorResolver
+            ]
         );
     }
 
@@ -87,6 +107,14 @@ class RequestGeneratorTest extends \PHPUnit_Framework_TestCase
                 ],
                 ['attr_int', 'int', 0, 1, 0]
             ],
+            [
+                [
+                    'quick_search_container' => ['queries' => 2, 'filters' => 1, 'aggregations' => 1],
+                    'advanced_search_container' => ['queries' => 0, 'filters' => 0, 'aggregations' => 0],
+                    'catalog_view_container' => ['queries' => 0, 'filters' => 0, 'aggregations' => 0],
+                ],
+                ['custom_price_attr', 'price', 0, 1, 0],
+            ],
         ];
     }
 
@@ -124,19 +152,23 @@ class RequestGeneratorTest extends \PHPUnit_Framework_TestCase
 
         $this->assertEquals(
             $countResult['quick_search_container']['queries'],
-            $this->countVal($result['quick_search_container']['queries'])
+            $this->countVal($result['quick_search_container']['queries']),
+            'Queries count for "quick_search_container" doesn\'t match'
         );
         $this->assertEquals(
             $countResult['advanced_search_container']['queries'],
-            $this->countVal($result['advanced_search_container']['queries'])
+            $this->countVal($result['advanced_search_container']['queries']),
+            'Queries count for "advanced_search_container" doesn\'t match'
         );
         $this->assertEquals(
             $countResult['advanced_search_container']['filters'],
-            $this->countVal($result['advanced_search_container']['filters'])
+            $this->countVal($result['advanced_search_container']['filters']),
+            'Filters count for "advanced_search_container" doesn\'t match'
         );
         $this->assertEquals(
             $countResult['catalog_view_container']['queries'],
-            $this->countVal($result['catalog_view_container']['queries'])
+            $this->countVal($result['catalog_view_container']['queries']),
+            'Queries count for "catalog_view_container" doesn\'t match'
         );
     }
 
@@ -144,11 +176,12 @@ class RequestGeneratorTest extends \PHPUnit_Framework_TestCase
      * Create attribute mock
      *
      * @param $attributeOptions
-     * @return \PHPUnit_Framework_MockObject_MockObject
+     * @return \Magento\Catalog\Model\Entity\Attribute|\PHPUnit_Framework_MockObject_MockObject
      */
     private function createAttributeMock($attributeOptions)
     {
-        $attribute = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Product\Attribute::class)
+        /** @var \Magento\Catalog\Model\Entity\Attribute|\PHPUnit_Framework_MockObject_MockObject $attribute */
+        $attribute = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class)
             ->disableOriginalConstructor()
             ->setMethods(
                 [
@@ -184,8 +217,8 @@ class RequestGeneratorTest extends \PHPUnit_Framework_TestCase
             ->method('getData')
             ->willReturnMap(
                 [
-                    ['is_filterable', $attributeOptions[2]],
-                    ['is_filterable_in_search', $attributeOptions[3]]
+                    ['is_filterable', null, $attributeOptions[2]],
+                    ['is_filterable_in_search', null, $attributeOptions[3]],
                 ]
             );
 
diff --git a/app/code/Magento/CatalogSearch/etc/di.xml b/app/code/Magento/CatalogSearch/etc/di.xml
index e715b5fea7cd05edc4f1fa50e894f685d9747bd2..f62b4e47767a25230c5c2ad8372f99acc6bda2eb 100644
--- a/app/code/Magento/CatalogSearch/etc/di.xml
+++ b/app/code/Magento/CatalogSearch/etc/di.xml
@@ -237,4 +237,12 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\CatalogSearch\Model\Search\RequestGenerator\GeneratorResolver">
+        <arguments>
+            <argument name="defaultGenerator" xsi:type="object">\Magento\CatalogSearch\Model\Search\RequestGenerator\General</argument>
+            <argument name="generators" xsi:type="array">
+                <item name="decimal" xsi:type="object">Magento\CatalogSearch\Model\Search\RequestGenerator\Decimal</item>
+            </argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/CategoryBasedProductRewriteGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/CategoryBasedProductRewriteGenerator.php
new file mode 100644
index 0000000000000000000000000000000000000000..58025ad03f0b46dec7cf5dc9f8bbd4d35aca836d
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/CategoryBasedProductRewriteGenerator.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogUrlRewrite\Model;
+
+use Magento\Catalog\Model\Category;
+use Magento\Catalog\Model\Product;
+use Magento\CatalogUrlRewrite\Model\Product\CanonicalUrlRewriteGenerator;
+use Magento\CatalogUrlRewrite\Model\Product\CategoriesUrlRewriteGenerator;
+use Magento\CatalogUrlRewrite\Model\Product\CurrentUrlRewritesRegenerator;
+use Magento\CatalogUrlRewrite\Model\Product\AnchorUrlRewriteGenerator;
+use Magento\CatalogUrlRewrite\Service\V1\StoreViewService;
+use Magento\Store\Model\Store;
+use Magento\Catalog\Model\Product\Visibility;
+
+/**
+ * Class ProductUrlRewriteGenerator
+ * @package Magento\CatalogUrlRewrite\Model
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class CategoryBasedProductRewriteGenerator
+{
+    /**
+     * @var ProductScopeRewriteGenerator
+     */
+    private $productScopeRewriteGenerator;
+
+    /**
+     * @param ProductScopeRewriteGenerator $productUrlRewriteGenerator
+     */
+    public function __construct(
+        ProductScopeRewriteGenerator $productScopeRewriteGenerator
+    ) {
+        $this->productScopeRewriteGenerator = $productScopeRewriteGenerator;
+    }
+
+    /**
+     * Generate product url rewrites based on category
+     *
+     * @param \Magento\Catalog\Model\Product $product
+     * @param \Magento\Catalog\Model\Category $category
+     * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+     */
+    public function generate(Product $product, Category $category)
+    {
+        if ($product->getVisibility() == Visibility::VISIBILITY_NOT_VISIBLE) {
+            return [];
+        }
+
+        $storeId = $product->getStoreId();
+
+        $urls = $this->productScopeRewriteGenerator->isGlobalScope($storeId)
+            ? $this->productScopeRewriteGenerator->generateForGlobalScope([$category], $product)
+            : $this->productScopeRewriteGenerator->generateForSpecificStoreView($storeId, [$category], $product);
+
+        $this->product = null;
+        return $urls;
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/ProductScopeRewriteGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/ProductScopeRewriteGenerator.php
new file mode 100644
index 0000000000000000000000000000000000000000..94464ec05d8249696e9a312636c62b4b03545d8c
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/ProductScopeRewriteGenerator.php
@@ -0,0 +1,171 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogUrlRewrite\Model;
+
+use Magento\Catalog\Model\Category;
+use Magento\Catalog\Model\Product;
+use Magento\CatalogUrlRewrite\Model\Product\CanonicalUrlRewriteGenerator;
+use Magento\CatalogUrlRewrite\Model\Product\CategoriesUrlRewriteGenerator;
+use Magento\CatalogUrlRewrite\Model\Product\CurrentUrlRewritesRegenerator;
+use Magento\CatalogUrlRewrite\Model\Product\AnchorUrlRewriteGenerator;
+use Magento\CatalogUrlRewrite\Service\V1\StoreViewService;
+use Magento\Store\Model\Store;
+use Magento\Store\Model\StoreManagerInterface;
+
+/**
+ * Class ProductScopeRewriteGenerator
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class ProductScopeRewriteGenerator
+{
+    /**
+     * @var StoreViewService
+     */
+    private $storeViewService;
+
+    /**
+     * @var StoreManagerInterface
+     */
+    private $storeManager;
+
+    /**
+     * @var ObjectRegistryFactory
+     */
+    private $objectRegistryFactory;
+
+    /**
+     * @var AnchorUrlRewriteGenerator
+     */
+    private $anchorUrlRewriteGenerator;
+
+    /**
+     * @var \Magento\CatalogUrlRewrite\Model\Product\CurrentUrlRewritesRegenerator
+     */
+    private $currentUrlRewritesRegenerator;
+
+    /**
+     * @var \Magento\CatalogUrlRewrite\Model\Product\CategoriesUrlRewriteGenerator
+     */
+    private $categoriesUrlRewriteGenerator;
+
+    /**
+     * @var \Magento\CatalogUrlRewrite\Model\Product\CanonicalUrlRewriteGenerator
+     */
+    private $canonicalUrlRewriteGenerator;
+
+    /**
+     * @param StoreViewService $storeViewService
+     * @param StoreManagerInterface $storeManager
+     * @param ObjectRegistryFactory $objectRegistryFactory
+     * @param CanonicalUrlRewriteGenerator $canonicalUrlRewriteGenerator
+     * @param CategoriesUrlRewriteGenerator $categoriesUrlRewriteGenerator
+     * @param CurrentUrlRewritesRegenerator $currentUrlRewritesRegenerator
+     * @param AnchorUrlRewriteGenerator $anchorUrlRewriteGenerator
+     */
+    public function __construct(
+        StoreViewService $storeViewService,
+        StoreManagerInterface $storeManager,
+        ObjectRegistryFactory $objectRegistryFactory,
+        CanonicalUrlRewriteGenerator $canonicalUrlRewriteGenerator,
+        CategoriesUrlRewriteGenerator $categoriesUrlRewriteGenerator,
+        CurrentUrlRewritesRegenerator $currentUrlRewritesRegenerator,
+        AnchorUrlRewriteGenerator $anchorUrlRewriteGenerator
+    ) {
+        $this->storeViewService = $storeViewService;
+        $this->storeManager = $storeManager;
+        $this->objectRegistryFactory = $objectRegistryFactory;
+        $this->canonicalUrlRewriteGenerator = $canonicalUrlRewriteGenerator;
+        $this->categoriesUrlRewriteGenerator = $categoriesUrlRewriteGenerator;
+        $this->currentUrlRewritesRegenerator = $currentUrlRewritesRegenerator;
+        $this->anchorUrlRewriteGenerator = $anchorUrlRewriteGenerator;
+    }
+
+    /**
+     * Check is global scope
+     *
+     * @param int|null $storeId
+     * @return bool
+     */
+    public function isGlobalScope($storeId)
+    {
+        return null === $storeId || $storeId == Store::DEFAULT_STORE_ID;
+    }
+
+    /**
+     * Generate url rewrites for global scope
+     *
+     * @param Product $product
+     * @param \Magento\Framework\Data\Collection $productCategories
+     * @return array
+     */
+    public function generateForGlobalScope($productCategories, Product $product)
+    {
+        $urls = [];
+        $productId = $product->getEntityId();
+
+        foreach ($product->getStoreIds() as $id) {
+            if (!$this->isGlobalScope($id)
+                && !$this->storeViewService->doesEntityHaveOverriddenUrlKeyForStore($id, $productId, Product::ENTITY)
+            ) {
+                $urls = array_merge($urls, $this->generateForSpecificStoreView($id, $productCategories, $product));
+            }
+        }
+
+        return $urls;
+    }
+
+    /**
+     * Generate list of urls for specific store view
+     *
+     * @param int $storeId
+     * @param \Magento\Framework\Data\Collection $productCategories
+     * @param \Magento\Catalog\Model\Product $product
+     * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+     */
+    public function generateForSpecificStoreView($storeId, $productCategories, Product $product)
+    {
+        $categories = [];
+        foreach ($productCategories as $category) {
+            if ($this->isCategoryProperForGenerating($category, $storeId)) {
+                $categories[] = $category;
+            }
+        }
+        $productCategories = $this->objectRegistryFactory->create(['entities' => $categories]);
+        /**
+         * @var $urls \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+         */
+        $urls = array_merge(
+            $this->canonicalUrlRewriteGenerator->generate($storeId, $product),
+            $this->categoriesUrlRewriteGenerator->generate($storeId, $product, $productCategories),
+            $this->currentUrlRewritesRegenerator->generate($storeId, $product, $productCategories),
+            $this->anchorUrlRewriteGenerator->generate($storeId, $product, $productCategories)
+        );
+
+        /* Reduce duplicates. Last wins */
+        $result = [];
+        foreach ($urls as $url) {
+            $result[$url->getTargetPath() . '-' . $url->getStoreId()] = $url;
+        }
+        $this->productCategories = null;
+        return $result;
+    }
+
+    /**
+     * Check possibility for url rewrite generation
+     *
+     * @param \Magento\Catalog\Model\Category $category
+     * @param int $storeId
+     * @return bool
+     */
+    public function isCategoryProperForGenerating(Category $category, $storeId)
+    {
+        if ($category->getParentId() != \Magento\Catalog\Model\Category::TREE_ROOT_ID) {
+            list(, $rootCategoryId) = $category->getParentIds();
+            return $rootCategoryId == $this->storeManager->getStore($storeId)->getRootCategoryId();
+        }
+        return false;
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteGenerator.php
index db39a201d9c05a1cef0f9b3768335ee0d8ec0fbd..f8f8991f95a04c19cc8a046064af1c550b948354 100644
--- a/app/code/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteGenerator.php
+++ b/app/code/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteGenerator.php
@@ -9,9 +9,8 @@ use Magento\Catalog\Model\Product;
 use Magento\CatalogUrlRewrite\Model\Product\CanonicalUrlRewriteGenerator;
 use Magento\CatalogUrlRewrite\Model\Product\CategoriesUrlRewriteGenerator;
 use Magento\CatalogUrlRewrite\Model\Product\CurrentUrlRewritesRegenerator;
-use Magento\CatalogUrlRewrite\Model\Product\AnchorUrlRewriteGenerator;
 use Magento\CatalogUrlRewrite\Service\V1\StoreViewService;
-use Magento\Store\Model\Store;
+use Magento\Framework\App\ObjectManager;
 use Magento\Catalog\Model\Product\Visibility;
 
 /**
@@ -26,32 +25,55 @@ class ProductUrlRewriteGenerator
      */
     const ENTITY_TYPE = 'product';
 
-    /** @var \Magento\CatalogUrlRewrite\Service\V1\StoreViewService */
+    /**
+     * @deprecated
+     * @var \Magento\CatalogUrlRewrite\Service\V1\StoreViewService
+     */
     protected $storeViewService;
 
     /** @var \Magento\Catalog\Model\Product */
     protected $product;
 
-    /** @var \Magento\CatalogUrlRewrite\Model\Product\CurrentUrlRewritesRegenerator */
+    /**
+     * @deprecated
+     * @var \Magento\CatalogUrlRewrite\Model\Product\CurrentUrlRewritesRegenerator
+     */
     protected $currentUrlRewritesRegenerator;
 
-    /** @var \Magento\CatalogUrlRewrite\Model\Product\CategoriesUrlRewriteGenerator */
+    /**
+     * @deprecated
+     * @var \Magento\CatalogUrlRewrite\Model\Product\CategoriesUrlRewriteGenerator
+     */
     protected $categoriesUrlRewriteGenerator;
 
-    /** @var \Magento\CatalogUrlRewrite\Model\Product\CanonicalUrlRewriteGenerator */
+    /**
+     * @deprecated
+     * @var \Magento\CatalogUrlRewrite\Model\Product\CanonicalUrlRewriteGenerator
+     */
     protected $canonicalUrlRewriteGenerator;
 
-    /** @var \Magento\CatalogUrlRewrite\Model\ObjectRegistryFactory */
+    /**
+     * @deprecated
+     * @var \Magento\CatalogUrlRewrite\Model\ObjectRegistryFactory
+     */
     protected $objectRegistryFactory;
 
-    /** @var \Magento\CatalogUrlRewrite\Model\ObjectRegistry */
+    /**
+     * @deprecated
+     * @var \Magento\CatalogUrlRewrite\Model\ObjectRegistry
+     */
     protected $productCategories;
 
-    /** @var \Magento\Store\Model\StoreManagerInterface */
+    /**
+     * @deprecated
+     * @var \Magento\Store\Model\StoreManagerInterface
+     */
     protected $storeManager;
 
-    /** @var AnchorUrlRewriteGenerator */
-    private $anchorUrlRewriteGenerator;
+    /**
+     * @var ProductScopeRewriteGenerator
+     */
+    private $productScopeRewriteGenerator;
 
     /**
      * @param \Magento\CatalogUrlRewrite\Model\Product\CanonicalUrlRewriteGenerator $canonicalUrlRewriteGenerator
@@ -78,17 +100,19 @@ class ProductUrlRewriteGenerator
     }
 
     /**
-     * @return AnchorUrlRewriteGenerator
+     * Retrieve Delegator for generation rewrites in different scopes
      *
      * @deprecated
+     * @return ProductScopeRewriteGenerator|mixed
      */
-    private function getAnchorUrlRewriteGenerator()
+    private function getProductScopeRewriteGenerator()
     {
-        if ($this->anchorUrlRewriteGenerator === null) {
-            $this->anchorUrlRewriteGenerator = \Magento\Framework\App\ObjectManager::getInstance()
-                ->get(\Magento\CatalogUrlRewrite\Model\Product\AnchorUrlRewriteGenerator::class);
+        if (!$this->productScopeRewriteGenerator) {
+            $this->productScopeRewriteGenerator = ObjectManager::getInstance()
+            ->get(ProductScopeRewriteGenerator::class);
         }
-        return $this->anchorUrlRewriteGenerator;
+
+        return $this->productScopeRewriteGenerator;
     }
 
     /**
@@ -121,80 +145,49 @@ class ProductUrlRewriteGenerator
     /**
      * Check is global scope
      *
+     * @deprecated
      * @param int|null $storeId
      * @return bool
      */
     protected function isGlobalScope($storeId)
     {
-        return null === $storeId || $storeId == Store::DEFAULT_STORE_ID;
+        return $this->getProductScopeRewriteGenerator()->isGlobalScope($storeId);
     }
 
     /**
      * Generate list of urls for global scope
      *
+     * @deprecated
      * @param \Magento\Framework\Data\Collection $productCategories
      * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
      */
     protected function generateForGlobalScope($productCategories)
     {
-        $urls = [];
-        $productId = $this->product->getEntityId();
-        foreach ($this->product->getStoreIds() as $id) {
-            if (!$this->isGlobalScope($id)
-                && !$this->storeViewService->doesEntityHaveOverriddenUrlKeyForStore($id, $productId, Product::ENTITY)
-            ) {
-                $urls = array_merge($urls, $this->generateForSpecificStoreView($id, $productCategories));
-            }
-        }
-        return $urls;
+        return $this->getProductScopeRewriteGenerator()->generateForGlobalScope($productCategories, $this->product);
     }
 
     /**
      * Generate list of urls for specific store view
      *
+     * @deprecated
      * @param int $storeId
      * @param \Magento\Framework\Data\Collection $productCategories
      * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
      */
     protected function generateForSpecificStoreView($storeId, $productCategories)
     {
-        $categories = [];
-        foreach ($productCategories as $category) {
-            if ($this->isCategoryProperForGenerating($category, $storeId)) {
-                $categories[] = $category;
-            }
-        }
-        $this->productCategories = $this->objectRegistryFactory->create(['entities' => $categories]);
-        /**
-         * @var $urls \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
-         */
-        $urls = array_merge(
-            $this->canonicalUrlRewriteGenerator->generate($storeId, $this->product),
-            $this->categoriesUrlRewriteGenerator->generate($storeId, $this->product, $this->productCategories),
-            $this->currentUrlRewritesRegenerator->generate($storeId, $this->product, $this->productCategories),
-            $this->getAnchorUrlRewriteGenerator()->generate($storeId, $this->product, $this->productCategories)
-        );
-
-        /* Reduce duplicates. Last wins */
-        $result = [];
-        foreach ($urls as $url) {
-            $result[$url->getTargetPath() . '-' . $url->getStoreId()] = $url;
-        }
-        $this->productCategories = null;
-        return $result;
+        return $this->getProductScopeRewriteGenerator()
+            ->generateForSpecificStoreView($storeId, $productCategories, $this->product);
     }
 
     /**
+     * @deprecated
      * @param \Magento\Catalog\Model\Category $category
      * @param int $storeId
      * @return bool
      */
     protected function isCategoryProperForGenerating($category, $storeId)
     {
-        if ($category->getParentId() != \Magento\Catalog\Model\Category::TREE_ROOT_ID) {
-            list(, $rootCategoryId) = $category->getParentIds();
-            return $rootCategoryId == $this->storeManager->getStore($storeId)->getRootCategoryId();
-        }
-        return false;
+        return $this->getProductScopeRewriteGenerator()->isCategoryProperForGenerating($category, $storeId);
     }
 }
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/UrlRewriteBunchReplacer.php b/app/code/Magento/CatalogUrlRewrite/Model/UrlRewriteBunchReplacer.php
new file mode 100644
index 0000000000000000000000000000000000000000..eb799dfe5991a7de92afd04f50003d982a100c73
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Model/UrlRewriteBunchReplacer.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogUrlRewrite\Model;
+
+use Magento\UrlRewrite\Model\UrlPersistInterface;
+
+class UrlRewriteBunchReplacer
+{
+    /**
+     * @var UrlPersistInterface
+     */
+    private $urlPersist;
+
+    /**
+     * @param UrlPersistInterface $urlPersist
+     */
+    public function __construct(UrlPersistInterface $urlPersist)
+    {
+        $this->urlPersist = $urlPersist;
+    }
+
+    /**
+     * Do Bunch Replace, with default bunch value = 10000
+     *
+     * @param array $urls
+     * @param int $bunchSize
+     * @return void
+     */
+    public function doBunchReplace(array $urls, $bunchSize = 10000)
+    {
+        foreach (array_chunk($urls, $bunchSize) as $urlsBunch) {
+            $this->urlPersist->replace($urlsBunch);
+        }
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteMovingObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteMovingObserver.php
index c891ab403f81b209a4f09978c9528c80f9ad7035..24126015e3b08a13ba236eca35a411c68ebc3ea6 100644
--- a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteMovingObserver.php
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteMovingObserver.php
@@ -8,7 +8,9 @@ namespace Magento\CatalogUrlRewrite\Observer;
 use Magento\Catalog\Model\Category;
 use Magento\CatalogUrlRewrite\Block\UrlKeyRenderer;
 use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
+use Magento\CatalogUrlRewrite\Model\UrlRewriteBunchReplacer;
 use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Framework\App\ObjectManager;
 use Magento\Store\Model\ScopeInterface;
 use Magento\UrlRewrite\Model\UrlPersistInterface;
 use Magento\Framework\Event\ObserverInterface;
@@ -27,6 +29,11 @@ class CategoryProcessUrlRewriteMovingObserver implements ObserverInterface
     /** @var UrlRewriteHandler */
     protected $urlRewriteHandler;
 
+    /**
+     * @var UrlRewriteBunchReplacer
+     */
+    private $urlRewriteBunchReplacer;
+
     /**
      * @param CategoryUrlRewriteGenerator $categoryUrlRewriteGenerator
      * @param UrlPersistInterface $urlPersist
@@ -45,6 +52,21 @@ class CategoryProcessUrlRewriteMovingObserver implements ObserverInterface
         $this->urlRewriteHandler = $urlRewriteHandler;
     }
 
+    /**
+     * Retrieve Url Rewrite Replacer based on bunches
+     *
+     * @deprecated
+     * @return UrlRewriteBunchReplacer
+     */
+    private function getUrlRewriteBunchReplacer()
+    {
+        if (!$this->urlRewriteBunchReplacer) {
+            $this->urlRewriteBunchReplacer = ObjectManager::getInstance()->get(UrlRewriteBunchReplacer::class);
+        }
+
+        return $this->urlRewriteBunchReplacer;
+    }
+
     /**
      * @param \Magento\Framework\Event\Observer $observer
      * @return void
@@ -65,7 +87,7 @@ class CategoryProcessUrlRewriteMovingObserver implements ObserverInterface
                 $this->urlRewriteHandler->generateProductUrlRewrites($category)
             );
             $this->urlRewriteHandler->deleteCategoryRewritesForChildren($category);
-            $this->urlPersist->replace($urlRewrites);
+            $this->getUrlRewriteBunchReplacer()->doBunchReplace($urlRewrites);
         }
     }
 }
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php
index 806cfb8edb7291b83eaa38aeafc7d88599247074..fe86bc363b49cf2d358ee07ff293bb09f0bedae1 100644
--- a/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/CategoryProcessUrlRewriteSavingObserver.php
@@ -7,6 +7,8 @@ namespace Magento\CatalogUrlRewrite\Observer;
 
 use Magento\Catalog\Model\Category;
 use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
+use Magento\CatalogUrlRewrite\Model\UrlRewriteBunchReplacer;
+use Magento\Framework\App\ObjectManager;
 use Magento\UrlRewrite\Model\UrlPersistInterface;
 use Magento\Framework\Event\ObserverInterface;
 
@@ -18,6 +20,11 @@ class CategoryProcessUrlRewriteSavingObserver implements ObserverInterface
     /** @var UrlPersistInterface */
     protected $urlPersist;
 
+    /**
+     * @var UrlRewriteBunchReplacer
+     */
+    private $urlRewriteBunchReplacer;
+
     /** @var UrlRewriteHandler */
     protected $urlRewriteHandler;
 
@@ -36,6 +43,21 @@ class CategoryProcessUrlRewriteSavingObserver implements ObserverInterface
         $this->urlRewriteHandler = $urlRewriteHandler;
     }
 
+    /**
+     * Retrieve Url Rewrite Replacer based on bunches
+     *
+     * @deprecated
+     * @return UrlRewriteBunchReplacer
+     */
+    private function getUrlRewriteBunchReplacer()
+    {
+        if (!$this->urlRewriteBunchReplacer) {
+            $this->urlRewriteBunchReplacer = ObjectManager::getInstance()->get(UrlRewriteBunchReplacer::class);
+        }
+
+        return $this->urlRewriteBunchReplacer;
+    }
+
     /**
      * Generate urls for UrlRewrite and save it in storage
      *
@@ -57,7 +79,8 @@ class CategoryProcessUrlRewriteSavingObserver implements ObserverInterface
                 $this->categoryUrlRewriteGenerator->generate($category),
                 $this->urlRewriteHandler->generateProductUrlRewrites($category)
             );
-            $this->urlPersist->replace($urlRewrites);
+
+            $this->getUrlRewriteBunchReplacer()->doBunchReplace($urlRewrites);
         }
     }
 }
diff --git a/app/code/Magento/CatalogUrlRewrite/Observer/UrlRewriteHandler.php b/app/code/Magento/CatalogUrlRewrite/Observer/UrlRewriteHandler.php
index b02ef76d951462d53d087449eb433dd905f7d928..ff914dc1adb2044534fe8468bebed8c868ba3cc8 100644
--- a/app/code/Magento/CatalogUrlRewrite/Observer/UrlRewriteHandler.php
+++ b/app/code/Magento/CatalogUrlRewrite/Observer/UrlRewriteHandler.php
@@ -6,8 +6,10 @@
 namespace Magento\CatalogUrlRewrite\Observer;
 
 use Magento\Catalog\Model\Category;
+use Magento\CatalogUrlRewrite\Model\CategoryBasedProductRewriteGenerator;
 use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
 use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
+use Magento\Framework\App\ObjectManager;
 use Magento\Framework\Event\Observer as EventObserver;
 use Magento\UrlRewrite\Model\UrlPersistInterface;
 use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
@@ -32,6 +34,11 @@ class UrlRewriteHandler
     /** @var \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory */
     protected $productCollectionFactory;
 
+    /**
+     * @var CategoryBasedProductRewriteGenerator
+     */
+    private $categoryBasedProductRewriteGenerator;
+
     /**
      * @param \Magento\CatalogUrlRewrite\Model\Category\ChildrenCategoriesProvider $childrenCategoriesProvider
      * @param CategoryUrlRewriteGenerator $categoryUrlRewriteGenerator
@@ -116,11 +123,30 @@ class UrlRewriteHandler
             $this->isSkippedProduct[] = $product->getId();
             $product->setStoreId($storeId);
             $product->setData('save_rewrites_history', $saveRewriteHistory);
-            $productUrls = array_merge($productUrls, $this->productUrlRewriteGenerator->generate($product));
+            $productUrls = array_merge(
+                $productUrls,
+                $this->getCategoryBasedProductRewriteGenerator()->generate($product, $category)
+            );
         }
         return $productUrls;
     }
 
+    /**
+     * Retrieve generator, which use single category for different products
+     *
+     * @deprecated
+     * @return CategoryBasedProductRewriteGenerator|mixed
+     */
+    private function getCategoryBasedProductRewriteGenerator()
+    {
+        if (!$this->categoryBasedProductRewriteGenerator) {
+            $this->categoryBasedProductRewriteGenerator = ObjectManager::getInstance()
+                ->get(CategoryBasedProductRewriteGenerator::class);
+        }
+
+        return $this->categoryBasedProductRewriteGenerator;
+    }
+
     /**
      * @param Category $category
      * @return void
diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/CategoryBasedProductRewriteGeneratorTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/CategoryBasedProductRewriteGeneratorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c62475f3cc7cf07ecaaf06831c30be5c29d532cd
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/CategoryBasedProductRewriteGeneratorTest.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogUrlRewrite\Test\Unit\Model;
+
+use Magento\Catalog\Model\Category;
+use Magento\Catalog\Model\Product;
+use Magento\CatalogUrlRewrite\Model\CategoryBasedProductRewriteGenerator;
+use Magento\CatalogUrlRewrite\Model\ProductScopeRewriteGenerator;
+
+/**
+ * Class CategoryBasedProductRewriteGeneratorTest
+ * @package Magento\CatalogUrlRewrite\Test\Unit\Model
+ */
+class CategoryBasedProductRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $productScopeRewriteGeneratorMock;
+
+    /**
+     * @var CategoryBasedProductRewriteGenerator
+     */
+    private $generator;
+
+    public function setUp()
+    {
+        $this->productScopeRewriteGeneratorMock = $this->getMockBuilder(ProductScopeRewriteGenerator::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->generator = new CategoryBasedProductRewriteGenerator(
+            $this->productScopeRewriteGeneratorMock
+        );
+    }
+
+    public function testGenerationWithGlobalScope()
+    {
+        $categoryMock = $this->getMockBuilder(Category::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $productMock = $this->getMockBuilder(Product::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $storeId = 1;
+        $urls = ['dummy-url.html'];
+
+        $productMock->expects($this->once())
+            ->method('getVisibility')
+            ->willReturn(2);
+        $productMock->expects($this->once())
+            ->method('getStoreId')
+            ->willReturn($storeId);
+        $this->productScopeRewriteGeneratorMock->expects($this->once())
+            ->method('isGlobalScope')
+            ->with($storeId)
+            ->willReturn(true);
+        $this->productScopeRewriteGeneratorMock->expects($this->once())
+            ->method('generateForGlobalScope')
+            ->with([$categoryMock], $productMock)
+            ->willReturn($urls);
+
+        $this->assertEquals($urls, $this->generator->generate($productMock, $categoryMock));
+    }
+
+    public function testGenerationWithSpecificStore()
+    {
+        $categoryMock = $this->getMockBuilder(Category::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $productMock = $this->getMockBuilder(Product::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $storeId = 1;
+        $urls = ['dummy-url.html'];
+
+        $productMock->expects($this->once())
+            ->method('getVisibility')
+            ->willReturn(2);
+        $productMock->expects($this->once())
+            ->method('getStoreId')
+            ->willReturn($storeId);
+        $this->productScopeRewriteGeneratorMock->expects($this->once())
+            ->method('isGlobalScope')
+            ->with($storeId)
+            ->willReturn(false);
+        $this->productScopeRewriteGeneratorMock->expects($this->once())
+            ->method('generateForSpecificStoreView')
+            ->with($storeId, [$categoryMock], $productMock)
+            ->willReturn($urls);
+
+        $this->assertEquals($urls, $this->generator->generate($productMock, $categoryMock));
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/ProductScopeRewriteGeneratorTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/ProductScopeRewriteGeneratorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..99bb858e31b8f02218599bc48f089eb3ef387a32
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/ProductScopeRewriteGeneratorTest.php
@@ -0,0 +1,182 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogUrlRewrite\Test\Unit\Model;
+
+use Magento\Catalog\Model\Category;
+use Magento\CatalogUrlRewrite\Model\ProductScopeRewriteGenerator;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Store\Model\StoreManagerInterface;
+
+/**
+ * Class ProductScopeRewriteGeneratorTest
+ * @package Magento\CatalogUrlRewrite\Test\Unit\Model
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class ProductScopeRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    private $canonicalUrlRewriteGenerator;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    private $currentUrlRewritesRegenerator;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    private $categoriesUrlRewriteGenerator;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    private $anchorUrlRewriteGenerator;
+
+    /** @var \Magento\CatalogUrlRewrite\Service\V1\StoreViewService|\PHPUnit_Framework_MockObject_MockObject */
+    private $storeViewService;
+
+    /** @var \Magento\CatalogUrlRewrite\Model\ObjectRegistryFactory|\PHPUnit_Framework_MockObject_MockObject */
+    private $objectRegistryFactory;
+
+    /** @var  StoreManagerInterface | \PHPUnit_Framework_MockObject_MockObject */
+    private $storeManager;
+
+    /** @var  ProductScopeRewriteGenerator */
+    private $productScopeGenerator;
+
+    public function setUp()
+    {
+        $this->currentUrlRewritesRegenerator = $this->getMockBuilder(
+            \Magento\CatalogUrlRewrite\Model\Product\CurrentUrlRewritesRegenerator::class
+        )->disableOriginalConstructor()->getMock();
+        $this->canonicalUrlRewriteGenerator = $this->getMockBuilder(
+            \Magento\CatalogUrlRewrite\Model\Product\CanonicalUrlRewriteGenerator::class
+        )->disableOriginalConstructor()->getMock();
+        $this->categoriesUrlRewriteGenerator = $this->getMockBuilder(
+            \Magento\CatalogUrlRewrite\Model\Product\CategoriesUrlRewriteGenerator::class
+        )->disableOriginalConstructor()->getMock();
+        $this->anchorUrlRewriteGenerator = $this->getMockBuilder(
+            \Magento\CatalogUrlRewrite\Model\Product\AnchorUrlRewriteGenerator::class
+        )->disableOriginalConstructor()->getMock();
+        $this->objectRegistryFactory = $this->getMockBuilder(
+            \Magento\CatalogUrlRewrite\Model\ObjectRegistryFactory::class
+        )->disableOriginalConstructor()->setMethods(['create'])->getMock();
+        $this->storeViewService = $this->getMockBuilder(\Magento\CatalogUrlRewrite\Service\V1\StoreViewService::class)
+            ->disableOriginalConstructor()->getMock();
+        $this->storeManager = $this->getMock(StoreManagerInterface::class);
+
+        $this->productScopeGenerator = (new ObjectManager($this))->getObject(
+            \Magento\CatalogUrlRewrite\Model\ProductScopeRewriteGenerator::class,
+            [
+                'canonicalUrlRewriteGenerator' => $this->canonicalUrlRewriteGenerator,
+                'categoriesUrlRewriteGenerator' => $this->categoriesUrlRewriteGenerator,
+                'currentUrlRewritesRegenerator' => $this->currentUrlRewritesRegenerator,
+                'anchorUrlRewriteGenerator' => $this->anchorUrlRewriteGenerator,
+                'objectRegistryFactory' => $this->objectRegistryFactory,
+                'storeViewService' => $this->storeViewService,
+                'storeManager' => $this->storeManager,
+            ]
+        );
+    }
+
+    public function testGenerationForGlobalScope()
+    {
+        $product = $this->getMock(\Magento\Catalog\Model\Product::class, [], [], '', false);
+        $product->expects($this->any())->method('getStoreId')->will($this->returnValue(null));
+        $product->expects($this->any())->method('getStoreIds')->will($this->returnValue([1]));
+        $this->storeViewService->expects($this->once())->method('doesEntityHaveOverriddenUrlKeyForStore')
+            ->will($this->returnValue(false));
+        $categoryMock = $this->getMockBuilder(Category::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $categoryMock->expects($this->once())
+            ->method('getParentId')
+            ->willReturn(1);
+        $this->initObjectRegistryFactory([]);
+        $canonical = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
+        $canonical->setTargetPath('category-1')
+            ->setStoreId(1);
+        $this->canonicalUrlRewriteGenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue([$canonical]));
+        $categories = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
+        $categories->setTargetPath('category-2')
+            ->setStoreId(2);
+        $this->categoriesUrlRewriteGenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue([$categories]));
+        $current = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
+        $current->setTargetPath('category-3')
+            ->setStoreId(3);
+        $this->currentUrlRewritesRegenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue([$current]));
+        $anchorCategories = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
+        $anchorCategories->setTargetPath('category-4')
+            ->setStoreId(4);
+        $this->anchorUrlRewriteGenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue([$anchorCategories]));
+
+        $this->assertEquals(
+            [
+                'category-1-1' => $canonical,
+                'category-2-2' => $categories,
+                'category-3-3' => $current,
+                'category-4-4' => $anchorCategories
+            ],
+            $this->productScopeGenerator->generateForGlobalScope([$categoryMock], $product)
+        );
+    }
+
+    public function testGenerationForSpecificStore()
+    {
+        $product = $this->getMock(\Magento\Catalog\Model\Product::class, [], [], '', false);
+        $product->expects($this->any())->method('getStoreId')->will($this->returnValue(1));
+        $product->expects($this->never())->method('getStoreIds');
+        $storeRootCategoryId = 'root-for-store-id';
+        $category = $this->getMock(\Magento\Catalog\Model\Category::class, [], [], '', false);
+        $category->expects($this->any())->method('getParentIds')
+            ->will($this->returnValue(['root-id', $storeRootCategoryId]));
+        $category->expects($this->any())->method('getParentId')->will($this->returnValue('parent_id'));
+        $category->expects($this->any())->method('getId')->will($this->returnValue('category_id'));
+        $store = $this->getMockBuilder(\Magento\Store\Model\Store::class)->disableOriginalConstructor()->getMock();
+        $store->expects($this->any())->method('getRootCategoryId')->will($this->returnValue($storeRootCategoryId));
+        $this->storeManager->expects($this->any())->method('getStore')->will($this->returnValue($store));
+        $this->initObjectRegistryFactory([$category]);
+        $canonical = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
+        $canonical->setTargetPath('category-1')
+            ->setStoreId(1);
+        $this->canonicalUrlRewriteGenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue([$canonical]));
+        $this->categoriesUrlRewriteGenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue([]));
+        $this->currentUrlRewritesRegenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue([]));
+        $this->anchorUrlRewriteGenerator->expects($this->any())->method('generate')
+            ->will($this->returnValue([]));
+
+        $this->assertEquals(
+            ['category-1-1' => $canonical],
+            $this->productScopeGenerator->generateForSpecificStoreView(1, [$category], $product)
+        );
+    }
+
+    /**
+     * Test method
+     */
+    public function testSkipGenerationForGlobalScope()
+    {
+        $product = $this->getMock(\Magento\Catalog\Model\Product::class, [], [], '', false);
+        $product->expects($this->any())->method('getStoreIds')->will($this->returnValue([1, 2]));
+        $this->storeViewService->expects($this->exactly(2))->method('doesEntityHaveOverriddenUrlKeyForStore')
+            ->will($this->returnValue(true));
+
+        $this->assertEquals([], $this->productScopeGenerator->generateForGlobalScope([], $product));
+    }
+
+    /**
+     * @param array $entities
+     */
+    protected function initObjectRegistryFactory($entities)
+    {
+        $objectRegistry = $this->getMockBuilder(\Magento\CatalogUrlRewrite\Model\ObjectRegistry::class)
+            ->disableOriginalConstructor()->getMock();
+        $this->objectRegistryFactory->expects($this->any())->method('create')
+            ->with(['entities' => $entities])
+            ->will($this->returnValue($objectRegistry));
+    }
+}
diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/ProductUrlRewriteGeneratorTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/ProductUrlRewriteGeneratorTest.php
index 4086fe256790b851edace762b6f23571677821b3..d88171b90bbeec463e370568d3d6671ffae019e5 100644
--- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/ProductUrlRewriteGeneratorTest.php
+++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/ProductUrlRewriteGeneratorTest.php
@@ -9,6 +9,8 @@
 namespace Magento\CatalogUrlRewrite\Test\Unit\Model;
 
 use Magento\Catalog\Model\Category;
+use Magento\Catalog\Model\Product;
+use Magento\CatalogUrlRewrite\Model\ProductScopeRewriteGenerator;
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
 
 /**
@@ -46,6 +48,9 @@ class ProductUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Catalog\Model\ResourceModel\Category\Collection|\PHPUnit_Framework_MockObject_MockObject */
     protected $categoriesCollection;
 
+    /** @var \PHPUnit_Framework_MockObject_MockObject  */
+    private $productScopeRewriteGenerator;
+
     /**
      * Test method
      */
@@ -59,8 +64,6 @@ class ProductUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue($this->categoriesCollection));
         $this->storeManager = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class)
             ->disableOriginalConstructor()->getMock();
-        $this->categoriesCollection->expects($this->exactly(2))->method('addAttributeToSelect')
-            ->will($this->returnSelf());
         $this->currentUrlRewritesRegenerator = $this->getMockBuilder(
             \Magento\CatalogUrlRewrite\Model\Product\CurrentUrlRewritesRegenerator::class
         )->disableOriginalConstructor()->getMock();
@@ -78,7 +81,9 @@ class ProductUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
         )->disableOriginalConstructor()->setMethods(['create'])->getMock();
         $this->storeViewService = $this->getMockBuilder(\Magento\CatalogUrlRewrite\Service\V1\StoreViewService::class)
             ->disableOriginalConstructor()->getMock();
-
+        $this->productScopeRewriteGenerator = $this->getMockBuilder(
+            ProductScopeRewriteGenerator::class
+        )->disableOriginalConstructor()->getMock();
         $this->productUrlRewriteGenerator = (new ObjectManager($this))->getObject(
             \Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator::class,
             [
@@ -92,172 +97,38 @@ class ProductUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
         );
 
         $reflection = new \ReflectionClass(get_class($this->productUrlRewriteGenerator));
-        $reflectionProperty = $reflection->getProperty('anchorUrlRewriteGenerator');
+        $reflectionProperty = $reflection->getProperty('productScopeRewriteGenerator');
         $reflectionProperty->setAccessible(true);
-        $reflectionProperty->setValue($this->productUrlRewriteGenerator, $this->anchorUrlRewriteGenerator);
-    }
-
-    /**
-     * Test method
-     */
-    public function testGenerationForGlobalScope()
-    {
-        $this->product->expects($this->any())->method('getStoreId')->will($this->returnValue(null));
-        $this->product->expects($this->any())->method('getStoreIds')->will($this->returnValue([1]));
-        $this->storeViewService->expects($this->once())->method('doesEntityHaveOverriddenUrlKeyForStore')
-            ->will($this->returnValue(false));
-        $this->categoriesCollection->expects($this->any())->method('getIterator')
-            ->willReturn(new \ArrayIterator([]));
-        $this->initObjectRegistryFactory([]);
-        $canonical = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
-        $canonical->setTargetPath('category-1')
-            ->setStoreId(1);
-        $this->canonicalUrlRewriteGenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue([$canonical]));
-        $categories = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
-        $categories->setTargetPath('category-2')
-            ->setStoreId(2);
-        $this->categoriesUrlRewriteGenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue([$categories]));
-        $current = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
-        $current->setTargetPath('category-3')
-            ->setStoreId(3);
-        $this->currentUrlRewritesRegenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue([$current]));
-        $anchorCategories = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
-        $anchorCategories->setTargetPath('category-4')
-            ->setStoreId(4);
-        $this->anchorUrlRewriteGenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue([$anchorCategories]));
-
-        $this->assertEquals(
-            [
-                'category-1-1' => $canonical,
-                'category-2-2' => $categories,
-                'category-3-3' => $current,
-                'category-4-4' => $anchorCategories
-            ],
-            $this->productUrlRewriteGenerator->generate($this->product)
-        );
+        $reflectionProperty->setValue($this->productUrlRewriteGenerator, $this->productScopeRewriteGenerator);
     }
 
-    /**
-     * Test method
-     */
-    public function testGenerationForSpecificStore()
-    {
-        $this->product->expects($this->any())->method('getStoreId')->will($this->returnValue(1));
-        $this->product->expects($this->never())->method('getStoreIds');
-        $storeRootCategoryId = 'root-for-store-id';
-        $category = $this->getMock(\Magento\Catalog\Model\Category::class, [], [], '', false);
-        $category->expects($this->any())->method('getParentIds')
-            ->will($this->returnValue(['root-id', $storeRootCategoryId]));
-        $category->expects($this->any())->method('getParentId')->will($this->returnValue('parent_id'));
-        $category->expects($this->any())->method('getId')->will($this->returnValue('category_id'));
-        $store = $this->getMockBuilder(\Magento\Store\Model\Store::class)->disableOriginalConstructor()->getMock();
-        $store->expects($this->any())->method('getRootCategoryId')->will($this->returnValue($storeRootCategoryId));
-        $this->storeManager->expects($this->any())->method('getStore')->will($this->returnValue($store));
-        $this->categoriesCollection->expects($this->any())->method('getIterator')
-            ->willReturn(new \ArrayIterator([$category]));
-        $this->initObjectRegistryFactory([$category]);
-        $canonical = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
-        $canonical->setTargetPath('category-1')
-            ->setStoreId(1);
-        $this->canonicalUrlRewriteGenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue([$canonical]));
-        $this->categoriesUrlRewriteGenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue([]));
-        $this->currentUrlRewritesRegenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue([]));
-        $this->anchorUrlRewriteGenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue([]));
-
-        $this->assertEquals(['category-1-1' => $canonical], $this->productUrlRewriteGenerator->generate($this->product));
-    }
-
-    /**
-     * Test method
-     */
-    public function testSkipRootCategoryForCategoriesGenerator()
+    public function testGenerate()
     {
-        $this->product->expects($this->any())->method('getStoreId')->will($this->returnValue(1));
-        $this->product->expects($this->never())->method('getStoreIds');
-        $store = $this->getMockBuilder(\Magento\Store\Model\Store::class)->disableOriginalConstructor()->getMock();
-        $store->expects($this->any())->method('getRootCategoryId')->will($this->returnValue('root-for-store-id'));
-        $this->storeManager->expects($this->any())->method('getStore')->will($this->returnValue($store));
-        $rootCategory = $this->getMock(\Magento\Catalog\Model\Category::class, [], [], '', false);
-        $rootCategory->expects($this->any())->method('getParentIds')->will($this->returnValue([1, 2]));
-        $rootCategory->expects($this->any())->method('getParentId')->will($this->returnValue(Category::TREE_ROOT_ID));
-        $this->categoriesCollection->expects($this->any())->method('getIterator')
-            ->willReturn(new \ArrayIterator([$rootCategory]));
-        $this->initObjectRegistryFactory([]);
-        $canonical = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
-        $canonical->setTargetPath('category-1')
-            ->setStoreId(1);
-        $this->canonicalUrlRewriteGenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue([$canonical]));
-        $this->categoriesUrlRewriteGenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue([]));
-        $this->currentUrlRewritesRegenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue([]));
-        $this->anchorUrlRewriteGenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue([]));
-
-        $this->assertEquals(['category-1-1' => $canonical], $this->productUrlRewriteGenerator->generate($this->product));
-    }
-
-    /**
-     * Test method
-     */
-    public function testSkipGenerationForNotStoreRootCategory()
-    {
-        $this->product->expects($this->any())->method('getStoreId')->will($this->returnValue(1));
-        $this->product->expects($this->never())->method('getStoreIds');
-        $category = $this->getMock(\Magento\Catalog\Model\Category::class, [], [], '', false);
-        $category->expects($this->any())->method('getParentIds')
-            ->will($this->returnValue(['root-id', 'root-for-store-id']));
-        $store = $this->getMockBuilder(\Magento\Store\Model\Store::class)->disableOriginalConstructor()->getMock();
-        $store->expects($this->any())->method('getRootCategoryId')->will($this->returnValue('not-root-id'));
-        $this->storeManager->expects($this->any())->method('getStore')->will($this->returnValue($store));
-        $this->categoriesCollection->expects($this->any())->method('getIterator')
-            ->willReturn(new \ArrayIterator([$category]));
-        $this->initObjectRegistryFactory([]);
-        $canonical = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
-        $canonical->setTargetPath('category-1')
-            ->setStoreId(1);
-        $this->canonicalUrlRewriteGenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue([$canonical]));
-        $this->categoriesUrlRewriteGenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue([]));
-        $this->currentUrlRewritesRegenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue([]));
-        $this->anchorUrlRewriteGenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue([]));
-
-        $this->assertEquals(['category-1-1' => $canonical], $this->productUrlRewriteGenerator->generate($this->product));
-    }
-
-    /**
-     * Test method
-     */
-    public function testSkipGenerationForGlobalScope()
-    {
-        $this->product->expects($this->any())->method('getStoreIds')->will($this->returnValue([1, 2]));
-        $this->storeViewService->expects($this->exactly(2))->method('doesEntityHaveOverriddenUrlKeyForStore')
-            ->will($this->returnValue(true));
-
-        $this->assertEquals([], $this->productUrlRewriteGenerator->generate($this->product));
-    }
-
-    /**
-     * @param array $entities
-     */
-    protected function initObjectRegistryFactory($entities)
-    {
-        $objectRegistry = $this->getMockBuilder(\Magento\CatalogUrlRewrite\Model\ObjectRegistry::class)
-            ->disableOriginalConstructor()->getMock();
-        $this->objectRegistryFactory->expects($this->any())->method('create')
-            ->with(['entities' => $entities])
-            ->will($this->returnValue($objectRegistry));
+        $productMock = $this->getMockBuilder(Product::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $storeId = 1;
+        $urls = ['dummy-url.html'];
+
+        $productMock->expects($this->once())
+            ->method('getVisibility')
+            ->willReturn(2);
+        $productMock->expects($this->once())
+            ->method('getStoreId')
+            ->willReturn($storeId);
+        $productCategoriesMock = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Category\Collection::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $productCategoriesMock->expects($this->exactly(2))
+            ->method('addAttributeToSelect')
+            ->withConsecutive(['url_key'], ['url_path'])
+            ->willReturnSelf();
+        $productMock->expects($this->once())
+            ->method('getCategoryCollection')
+            ->willReturn($productCategoriesMock);
+        $this->productScopeRewriteGenerator->expects($this->once())
+            ->method('generateForSpecificStoreView')
+            ->willReturn($urls);
+        $this->assertEquals($urls, $this->productUrlRewriteGenerator->generate($productMock));
     }
 }
diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/UrlRewriteBunchReplacerTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/UrlRewriteBunchReplacerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7a44cc5d6f9726098a3467e8d8629f6d9c04ea59
--- /dev/null
+++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/UrlRewriteBunchReplacerTest.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogUrlRewrite\Test\Unit\Model;
+
+use Magento\CatalogUrlRewrite\Model\UrlRewriteBunchReplacer;
+use Magento\UrlRewrite\Model\UrlPersistInterface;
+
+class UrlRewriteBunchReplacerTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var UrlPersistInterface | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $urlPersistMock;
+
+    /**
+     * @var UrlRewriteBunchReplacer
+     */
+    private $urlRewriteBunchReplacer;
+
+    public function setUp()
+    {
+        $this->urlPersistMock = $this->getMock(UrlPersistInterface::class);
+        $this->urlRewriteBunchReplacer = new UrlRewriteBunchReplacer(
+            $this->urlPersistMock
+        );
+    }
+
+    public function testDoBunchReplace()
+    {
+        $urls = [[1], [2]];
+        $this->urlPersistMock->expects($this->exactly(2))
+            ->method('replace')
+            ->withConsecutive([[[1]]], [[[2]]]);
+        $this->urlRewriteBunchReplacer->doBunchReplace($urls, 1);
+    }
+}
diff --git a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php
index a547fb862acac50b42b7ae971bb3d3690e56808e..0f665984b0e0471adc4dad16590bde36940ad03c 100644
--- a/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php
+++ b/app/code/Magento/CatalogWidget/Block/Product/ProductsList.php
@@ -4,12 +4,11 @@
  * See COPYING.txt for license details.
  */
 
-// @codingStandardsIgnoreFile
-
 namespace Magento\CatalogWidget\Block\Product;
 
 use Magento\Framework\DataObject\IdentityInterface;
 use Magento\Widget\Block\BlockInterface;
+use Magento\Framework\Pricing\PriceCurrencyInterface;
 
 /**
  * Catalog Products List widget block
@@ -81,6 +80,11 @@ class ProductsList extends \Magento\Catalog\Block\Product\AbstractProduct implem
      */
     protected $conditionsHelper;
 
+    /**
+     * @var PriceCurrencyInterface
+     */
+    private $priceCurrency;
+
     /**
      * @param \Magento\Catalog\Block\Product\Context $context
      * @param \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory
@@ -144,6 +148,7 @@ class ProductsList extends \Magento\Catalog\Block\Product\AbstractProduct implem
 
         return [
             'CATALOG_PRODUCTS_LIST_WIDGET',
+            $this->getPriceCurrency()->getCurrencySymbol(),
             $this->_storeManager->getStore()->getId(),
             $this->_design->getDesignTheme()->getId(),
             $this->httpContext->getValue(\Magento\Customer\Model\Context::CONTEXT_GROUP),
@@ -351,4 +356,19 @@ class ProductsList extends \Magento\Catalog\Block\Product\AbstractProduct implem
     {
         return $this->getData('title');
     }
+
+    /**
+     * @return PriceCurrencyInterface
+     *
+     * @deprecated
+     */
+    private function getPriceCurrency()
+    {
+        if ($this->priceCurrency === null) {
+            $this->priceCurrency = \Magento\Framework\App\ObjectManager::getInstance()
+                ->get(PriceCurrencyInterface::class);
+        }
+        return $this->priceCurrency;
+
+    }
 }
diff --git a/app/code/Magento/CatalogWidget/Test/Unit/Block/Product/ProductsListTest.php b/app/code/Magento/CatalogWidget/Test/Unit/Block/Product/ProductsListTest.php
index fd4ae990a754d58490a582a7bca0124e451dd214..c2410cea1d9bfe0cf13f5a8a2bc3d8cf1320a651 100644
--- a/app/code/Magento/CatalogWidget/Test/Unit/Block/Product/ProductsListTest.php
+++ b/app/code/Magento/CatalogWidget/Test/Unit/Block/Product/ProductsListTest.php
@@ -10,6 +10,7 @@ use \Magento\CatalogWidget\Block\Product\ProductsList;
 
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
 use Magento\Catalog\Model\Product\Visibility;
+use Magento\Framework\Pricing\PriceCurrencyInterface;
 
 /**
  * Class ProductsListTest
@@ -72,6 +73,11 @@ class ProductsListTest extends \PHPUnit_Framework_TestCase
      */
     protected $layout;
 
+    /**
+     * @var PriceCurrencyInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $priceCurrency;
+
     protected function setUp()
     {
         $this->collectionFactory =
@@ -105,11 +111,13 @@ class ProductsListTest extends \PHPUnit_Framework_TestCase
         );
         $this->request = $arguments['context']->getRequest();
         $this->layout = $arguments['context']->getLayout();
+        $this->priceCurrency = $this->getMock(PriceCurrencyInterface::class);
 
         $this->productsList = $objectManagerHelper->getObject(
             \Magento\CatalogWidget\Block\Product\ProductsList::class,
             $arguments
         );
+        $objectManagerHelper->setBackwardCompatibleProperty($this->productsList, 'priceCurrency', $this->priceCurrency);
     }
 
     public function testGetCacheKeyInfo()
@@ -130,9 +138,11 @@ class ProductsListTest extends \PHPUnit_Framework_TestCase
         $this->request->expects($this->once())->method('getParam')->with('page_number')->willReturn(1);
 
         $this->request->expects($this->once())->method('getParams')->willReturn('request_params');
+        $this->priceCurrency->expects($this->once())->method('getCurrencySymbol')->willReturn('$');
 
         $cacheKey = [
             'CATALOG_PRODUCTS_LIST_WIDGET',
+            '$',
             1,
             'blank',
             'context_group',
diff --git a/app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php b/app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php
index 646137310cb5125b8f892f0112d769704a474963..1b2c7444198915c866a55ca2cc9b8e6b29544e39 100644
--- a/app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php
+++ b/app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\Checkout\Block\Checkout;
 
+use Magento\Checkout\Helper\Data;
 use Magento\Framework\App\ObjectManager;
 
 class LayoutProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcessorInterface
@@ -29,6 +30,11 @@ class LayoutProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcesso
      */
     private $options;
 
+    /**
+     * @var Data
+     */
+    private $checkoutDataHelper;
+
     /**
      * @param \Magento\Customer\Model\AttributeMetadataDataProvider $attributeMetadataDataProvider
      * @param \Magento\Ui\Component\Form\AttributeMapper $attributeMapper
@@ -133,23 +139,12 @@ class LayoutProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcesso
         if (isset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
             ['payment']['children']
         )) {
-            if (!isset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
-                ['payment']['children']['payments-list']['children'])) {
-                $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
-                ['payment']['children']['payments-list']['children'] = [];
-            }
-
             $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
-            ['payment']['children']['payments-list']['children'] =
-                array_merge_recursive(
-                    $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
-                    ['payment']['children']['payments-list']['children'],
-                    $this->processPaymentConfiguration(
-                        $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
-                        ['payment']['children']['renders']['children'],
-                        $elements
-                    )
-                );
+            ['payment']['children'] = $this->processPaymentChildrenComponents(
+                $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
+                ['payment']['children'],
+                $elements
+            );
         }
 
         if (isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
@@ -168,6 +163,44 @@ class LayoutProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcesso
         return $jsLayout;
     }
 
+    /**
+     * Appends billing address form component to payment layout
+     * @param array $paymentLayout
+     * @param array $elements
+     * @return array
+     */
+    private function processPaymentChildrenComponents(array $paymentLayout, array $elements)
+    {
+        if (!isset($paymentLayout['payments-list']['children'])) {
+            $paymentLayout['payments-list']['children'] = [];
+        }
+
+        if (!isset($paymentLayout['afterMethods']['children'])) {
+            $paymentLayout['afterMethods']['children'] = [];
+        }
+
+        // The if billing address should be displayed on Payment method or page
+        if ($this->getCheckoutDataHelper()->isDisplayBillingOnPaymentMethodAvailable()) {
+            $paymentLayout['payments-list']['children'] =
+                array_merge_recursive(
+                    $paymentLayout['payments-list']['children'],
+                    $this->processPaymentConfiguration(
+                        $paymentLayout['renders']['children'],
+                        $elements
+                    )
+                );
+        } else {
+            $component['billing-address-form'] = $this->getBillingAddressComponent('shared', $elements);
+            $paymentLayout['afterMethods']['children'] =
+                array_merge_recursive(
+                    $component,
+                    $paymentLayout['afterMethods']['children']
+                );
+        }
+
+        return $paymentLayout;
+    }
+
     /**
      * Inject billing address component into every payment component
      *
@@ -183,75 +216,102 @@ class LayoutProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcesso
                 if (empty($paymentComponent['isBillingAddressRequired'])) {
                     continue;
                 }
-                $output[$paymentCode . '-form'] = [
-                    'component' => 'Magento_Checkout/js/view/billing-address',
-                    'displayArea' => 'billing-address-form-' . $paymentCode,
-                    'provider' => 'checkoutProvider',
-                    'deps' => 'checkoutProvider',
-                    'dataScopePrefix' => 'billingAddress' . $paymentCode,
-                    'sortOrder' => 1,
-                    'children' => [
-                        'form-fields' => [
-                            'component' => 'uiComponent',
-                            'displayArea' => 'additional-fieldsets',
-                            'children' => $this->merger->merge(
-                                $elements,
-                                'checkoutProvider',
-                                'billingAddress' . $paymentCode,
-                                [
-                                    'country_id' => [
-                                        'sortOrder' => 115,
-                                    ],
-                                    'region' => [
-                                        'visible' => false,
-                                    ],
-                                    'region_id' => [
-                                        'component' => 'Magento_Ui/js/form/element/region',
-                                        'config' => [
-                                            'template' => 'ui/form/field',
-                                            'elementTmpl' => 'ui/form/element/select',
-                                            'customEntry' => 'billingAddress' . $paymentCode . '.region',
-                                        ],
-                                        'validation' => [
-                                            'required-entry' => true,
-                                        ],
-                                        'filterBy' => [
-                                            'target' => '${ $.provider }:${ $.parentScope }.country_id',
-                                            'field' => 'country_id',
-                                        ],
-                                    ],
-                                    'postcode' => [
-                                        'component' => 'Magento_Ui/js/form/element/post-code',
-                                        'validation' => [
-                                            'required-entry' => true,
-                                        ],
-                                    ],
-                                    'company' => [
-                                        'validation' => [
-                                            'min_text_length' => 0,
-                                        ],
-                                    ],
-                                    'fax' => [
-                                        'validation' => [
-                                            'min_text_length' => 0,
-                                        ],
-                                    ],
-                                    'telephone' => [
-                                        'config' => [
-                                            'tooltip' => [
-                                                'description' => __('For delivery questions.'),
-                                            ],
-                                        ],
-                                    ],
-                                ]
-                            ),
-                        ],
-                    ],
-                ];
+                $output[$paymentCode . '-form'] = $this->getBillingAddressComponent($paymentCode, $elements);
             }
             unset($configuration[$paymentGroup]['methods']);
         }
 
         return $output;
     }
+
+    /**
+     * Gets billing address component details
+     *
+     * @param string $paymentCode
+     * @param array $elements
+     * @return array
+     */
+    private function getBillingAddressComponent($paymentCode, $elements)
+    {
+        return [
+            'component' => 'Magento_Checkout/js/view/billing-address',
+            'displayArea' => 'billing-address-form-' . $paymentCode,
+            'provider' => 'checkoutProvider',
+            'deps' => 'checkoutProvider',
+            'dataScopePrefix' => 'billingAddress' . $paymentCode,
+            'sortOrder' => 1,
+            'children' => [
+                'form-fields' => [
+                    'component' => 'uiComponent',
+                    'displayArea' => 'additional-fieldsets',
+                    'children' => $this->merger->merge(
+                        $elements,
+                        'checkoutProvider',
+                        'billingAddress' . $paymentCode,
+                        [
+                            'country_id' => [
+                                'sortOrder' => 115,
+                            ],
+                            'region' => [
+                                'visible' => false,
+                            ],
+                            'region_id' => [
+                                'component' => 'Magento_Ui/js/form/element/region',
+                                'config' => [
+                                    'template' => 'ui/form/field',
+                                    'elementTmpl' => 'ui/form/element/select',
+                                    'customEntry' => 'billingAddress' . $paymentCode . '.region',
+                                ],
+                                'validation' => [
+                                    'required-entry' => true,
+                                ],
+                                'filterBy' => [
+                                    'target' => '${ $.provider }:${ $.parentScope }.country_id',
+                                    'field' => 'country_id',
+                                ],
+                            ],
+                            'postcode' => [
+                                'component' => 'Magento_Ui/js/form/element/post-code',
+                                'validation' => [
+                                    'required-entry' => true,
+                                ],
+                            ],
+                            'company' => [
+                                'validation' => [
+                                    'min_text_length' => 0,
+                                ],
+                            ],
+                            'fax' => [
+                                'validation' => [
+                                    'min_text_length' => 0,
+                                ],
+                            ],
+                            'telephone' => [
+                                'config' => [
+                                    'tooltip' => [
+                                        'description' => __('For delivery questions.'),
+                                    ],
+                                ],
+                            ],
+                        ]
+                    ),
+                ],
+            ],
+        ];
+    }
+
+    /**
+     * Get checkout data helper instance
+     *
+     * @return Data
+     * @deprecated
+     */
+    private function getCheckoutDataHelper()
+    {
+        if (!$this->checkoutDataHelper) {
+            $this->checkoutDataHelper = ObjectManager::getInstance()->get(Data::class);
+        }
+
+        return $this->checkoutDataHelper;
+    }
 }
diff --git a/app/code/Magento/Checkout/Helper/Data.php b/app/code/Magento/Checkout/Helper/Data.php
index 2073ffe87d4d6525535895c4238d4469aaa77388..b54d3187949e41190a7cdccbe7e4aacd79683aee 100644
--- a/app/code/Magento/Checkout/Helper/Data.php
+++ b/app/code/Magento/Checkout/Helper/Data.php
@@ -8,6 +8,7 @@ namespace Magento\Checkout\Helper;
 use Magento\Framework\Pricing\PriceCurrencyInterface;
 use Magento\Quote\Model\Quote\Item\AbstractItem;
 use Magento\Store\Model\Store;
+use Magento\Store\Model\ScopeInterface;
 
 /**
  * Checkout default helper
@@ -400,4 +401,17 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
             \Magento\Store\Model\ScopeInterface::SCOPE_STORE
         );
     }
+
+    /**
+     * Checks if display billing address on payment method is available, otherwise
+     * billing address should be display on payment page
+     * @return bool
+     */
+    public function isDisplayBillingOnPaymentMethodAvailable()
+    {
+        return (bool) !$this->scopeConfig->getValue(
+            'checkout/options/display_billing_address_on',
+            ScopeInterface::SCOPE_STORE
+        );
+    }
 }
diff --git a/app/code/Magento/Checkout/Model/Adminhtml/BillingAddressDisplayOptions.php b/app/code/Magento/Checkout/Model/Adminhtml/BillingAddressDisplayOptions.php
new file mode 100644
index 0000000000000000000000000000000000000000..831d4b41ec9049b3dabc73dd6d72818ee2d915c4
--- /dev/null
+++ b/app/code/Magento/Checkout/Model/Adminhtml/BillingAddressDisplayOptions.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Model\Adminhtml;
+
+use Magento\Framework\Option\ArrayInterface;
+
+/**
+ * BillingAddressDisplayOptions gets list of configuration options for billing address displaying on
+ * the Payment step on checkout
+ */
+class BillingAddressDisplayOptions implements ArrayInterface
+{
+
+    /**
+     * Return array of options for billing address displaying on checkout payment step
+     *
+     * @return array:
+     * [
+     *  ['label' => 'Payment Method', 'value' => 0],
+     *  ['label' => 'Payment Page', 'value' => 1]
+     * ]
+     */
+    public function toOptionArray()
+    {
+        return [
+            [
+                'label' => __('Payment Method'),
+                'value' => 0
+            ],
+            [
+                'label' => __('Payment Page'),
+                'value' => 1
+            ]
+        ];
+    }
+}
diff --git a/app/code/Magento/Checkout/Model/DefaultConfigProvider.php b/app/code/Magento/Checkout/Model/DefaultConfigProvider.php
index 923e54aac937819ca59c2ae796c97d32d1bddfea..0544f3aae39120db5f06b6691175e0e9b07ffd69 100644
--- a/app/code/Magento/Checkout/Model/DefaultConfigProvider.php
+++ b/app/code/Magento/Checkout/Model/DefaultConfigProvider.php
@@ -296,6 +296,7 @@ class DefaultConfigProvider implements ConfigProviderInterface
         $output['originCountryCode'] = $this->getOriginCountryCode();
         $output['paymentMethods'] = $this->getPaymentMethods();
         $output['autocomplete'] = $this->isAutocompleteEnabled();
+        $output['displayBillingOnPaymentMethod'] = $this->checkoutHelper->isDisplayBillingOnPaymentMethodAvailable();
         return $output;
     }
 
diff --git a/app/code/Magento/Checkout/Test/Unit/Block/Checkout/LayoutProcessorTest.php b/app/code/Magento/Checkout/Test/Unit/Block/Checkout/LayoutProcessorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1351213f990b54a573a5d5d3a015e7b940a5f7ee
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Unit/Block/Checkout/LayoutProcessorTest.php
@@ -0,0 +1,276 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Test\Unit\Block\Checkout;
+
+use Magento\Checkout\Block\Checkout\AttributeMerger;
+use Magento\Checkout\Block\Checkout\LayoutProcessor;
+use Magento\Checkout\Helper\Data;
+use Magento\Customer\Model\AttributeMetadataDataProvider;
+use Magento\Customer\Model\Options;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Ui\Component\Form\AttributeMapper;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
+
+/**
+ * LayoutProcessorTest covers a list of variations for
+ * checkout layout processor
+ */
+class LayoutProcessorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var AttributeMetadataDataProvider|MockObject
+     */
+    private $attributeDataProvider;
+
+    /**
+     * @var AttributeMapper|MockObject
+     */
+    private $attributeMapper;
+
+    /**
+     * @var AttributeMerger|MockObject
+     */
+    private $attributeMerger;
+
+    /**
+     * @var Data|MockObject
+     */
+    private $dataHelper;
+
+    /**
+     * @var LayoutProcessor
+     */
+    private $layoutProcessor;
+
+    protected function setUp()
+    {
+        $objectManager = new ObjectManager($this);
+
+        $this->attributeDataProvider = $this->getMockBuilder(AttributeMetadataDataProvider::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['loadAttributesCollection'])
+            ->getMock();
+
+        $this->attributeMapper = $this->getMockBuilder(AttributeMapper::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['map'])
+            ->getMock();
+
+        $this->attributeMerger = $this->getMockBuilder(AttributeMerger::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['merge'])
+            ->getMock();
+
+        $this->dataHelper = $this->getMockBuilder(Data::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['isDisplayBillingOnPaymentMethodAvailable'])
+            ->getMock();
+
+        $options = $this->getMockBuilder(Options::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->layoutProcessor = new LayoutProcessor(
+            $this->attributeDataProvider,
+            $this->attributeMapper,
+            $this->attributeMerger
+        );
+
+        $objectManager->setBackwardCompatibleProperty($this->layoutProcessor, 'checkoutDataHelper', $this->dataHelper);
+        $objectManager->setBackwardCompatibleProperty($this->layoutProcessor, 'options', $options);
+    }
+
+    /**
+     * @covers \Magento\Checkout\Block\Checkout\LayoutProcessor::process
+     */
+    public function testProcess()
+    {
+        $jsLayout = $this->getLayoutData();
+
+        $this->attributeDataProvider->expects(static::once())
+            ->method('loadAttributesCollection')
+            ->willReturn([]);
+
+        $this->dataHelper->expects(static::once())
+            ->method('isDisplayBillingOnPaymentMethodAvailable')
+            ->willReturn(true);
+
+        $this->attributeMerger->expects(static::exactly(2))
+            ->method('merge')
+            ->willReturnMap([
+                ['payment1_1' => $this->getBillingComponent('payment1_1')],
+                ['payment2_1' => $this->getBillingComponent('payment2_1')],
+            ]);
+
+        $actual = $this->layoutProcessor->process($jsLayout);
+
+        static::assertArrayHasKey(
+            'payment1_1-form',
+            $actual['components']['checkout']['children']['steps']['children']['billing-step']['children']
+            ['payment']['children']['payments-list']['children']
+        );
+        static::assertArrayHasKey(
+            'payment2_1-form',
+            $actual['components']['checkout']['children']['steps']['children']['billing-step']['children']
+            ['payment']['children']['payments-list']['children']
+        );
+        static::assertArrayNotHasKey(
+            'payment2_2-form',
+            $actual['components']['checkout']['children']['steps']['children']['billing-step']['children']
+            ['payment']['children']['payments-list']['children']
+        );
+        static::assertArrayHasKey(
+            'afterMethods',
+            $actual['components']['checkout']['children']['steps']['children']['billing-step']
+            ['children']['payment']['children']
+        );
+        static::assertEmpty(
+            $actual['components']['checkout']['children']['steps']['children']['billing-step']
+            ['children']['payment']['children']['afterMethods']['children']
+        );
+    }
+
+    /**
+     * @covers \Magento\Checkout\Block\Checkout\LayoutProcessor::process
+     */
+    public function testProcessWithBillingAddressOnPaymentPage()
+    {
+        $jsLayout = $this->getLayoutData();
+
+        $this->attributeDataProvider->expects(static::once())
+            ->method('loadAttributesCollection')
+            ->willReturn([]);
+
+        $this->dataHelper->expects(static::once())
+            ->method('isDisplayBillingOnPaymentMethodAvailable')
+            ->willReturn(false);
+
+        $this->attributeMerger->expects(static::once())
+            ->method('merge')
+            ->willReturn($this->getBillingComponent('shared'));
+
+        $actual = $this->layoutProcessor->process($jsLayout);
+
+        static::assertEmpty(
+            $actual['components']['checkout']['children']['steps']['children']['billing-step']['children']
+            ['payment']['children']['payments-list']['children']
+        );
+
+        static::assertNotEmpty(
+            $actual['components']['checkout']['children']['steps']['children']['billing-step']['children']
+            ['payment']['children']['afterMethods']['children']
+        );
+        static::assertArrayHasKey(
+            'billing-address-form',
+            $actual['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']
+            ['children']['afterMethods']['children']
+        );
+    }
+
+    /**
+     * Get mock layout data for testing
+     * @return array
+     */
+    private function getLayoutData()
+    {
+        return [
+            'components' => [
+                'checkout' => [
+                    'children' => [
+                        'steps' => [
+                            'children' => [
+                                'billing-step' => [
+                                    'children' => [
+                                        'payment' => [
+                                            'children' => [
+                                                'renders' => [
+                                                    'children' => [
+                                                        'payment1' => [
+                                                            'methods' => [
+                                                                'payment1_1' => [
+                                                                    'isBillingAddressRequired' => true
+                                                                ]
+                                                            ]
+                                                        ],
+                                                        'payment2' => [
+                                                            'methods' => [
+                                                                'payment2_1' => [
+                                                                    'isBillingAddressRequired' => true
+                                                                ],
+                                                                'payment2_2' => [
+                                                                    'isBillingAddressRequired' => false
+                                                                ]
+                                                            ]
+                                                        ]
+                                                    ]
+                                                ]
+                                            ]
+                                        ]
+                                    ]
+                                ]
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ];
+    }
+
+    /**
+     * Get mock data for billing component
+     * @param string $paymentCode
+     * @return array
+     */
+    private function getBillingComponent($paymentCode)
+    {
+        return [
+            'country_id' => [
+                'sortOrder' => 115,
+            ],
+            'region' => [
+                'visible' => false,
+            ],
+            'region_id' => [
+                'component' => 'Magento_Ui/js/form/element/region',
+                'config' => [
+                    'template' => 'ui/form/field',
+                    'elementTmpl' => 'ui/form/element/select',
+                    'customEntry' => 'billingAddress' . $paymentCode . '.region',
+                ],
+                'validation' => [
+                    'required-entry' => true,
+                ],
+                'filterBy' => [
+                    'target' => '${ $.provider }:${ $.parentScope }.country_id',
+                    'field' => 'country_id',
+                ],
+            ],
+            'postcode' => [
+                'component' => 'Magento_Ui/js/form/element/post-code',
+                'validation' => [
+                    'required-entry' => true,
+                ],
+            ],
+            'company' => [
+                'validation' => [
+                    'min_text_length' => 0,
+                ],
+            ],
+            'fax' => [
+                'validation' => [
+                    'min_text_length' => 0,
+                ],
+            ],
+            'telephone' => [
+                'config' => [
+                    'tooltip' => [
+                        'description' => __('For delivery questions.'),
+                    ],
+                ],
+            ],
+        ];
+    }
+}
diff --git a/app/code/Magento/Checkout/Test/Unit/Model/ShippingInformationManagementTest.php b/app/code/Magento/Checkout/Test/Unit/Model/ShippingInformationManagementTest.php
index c6ef3aac3ba7e667be7edf52d64ddd8a5eddd0fb..04d347ec237a9435964a5f4fcce784708c4365a4 100644
--- a/app/code/Magento/Checkout/Test/Unit/Model/ShippingInformationManagementTest.php
+++ b/app/code/Magento/Checkout/Test/Unit/Model/ShippingInformationManagementTest.php
@@ -7,6 +7,7 @@ namespace Magento\Checkout\Test\Unit\Model;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ * @SuppressWarnings(PHPMD.TooManyFields)
  */
 class ShippingInformationManagementTest extends \PHPUnit_Framework_TestCase
 {
@@ -70,10 +71,38 @@ class ShippingInformationManagementTest extends \PHPUnit_Framework_TestCase
      */
     protected $model;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $shippingAssignmentFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $cartExtensionFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $shippingFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $cartExtensionMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $shippingAssignmentMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $shippingMock;
+
     protected function setUp()
     {
-        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
-
         $this->paymentMethodManagementMock = $this->getMock(\Magento\Quote\Api\PaymentMethodManagementInterface::class);
         $this->paymentDetailsFactoryMock = $this->getMock(
             \Magento\Checkout\Model\PaymentDetailsFactory::class,
@@ -96,21 +125,6 @@ class ShippingInformationManagementTest extends \PHPUnit_Framework_TestCase
         $this->scopeConfigMock = $this->getMock(\Magento\Framework\App\Config\ScopeConfigInterface::class);
         $this->totalsCollectorMock =
             $this->getMock(\Magento\Quote\Model\Quote\TotalsCollector::class, [], [], '', false);
-        $this->model = $objectManager->getObject(
-            \Magento\Checkout\Model\ShippingInformationManagement::class,
-            [
-                'paymentMethodManagement' => $this->paymentMethodManagementMock,
-                'paymentDetailsFactory' => $this->paymentDetailsFactoryMock,
-                'cartTotalsRepository' => $this->cartTotalsRepositoryMock,
-                'quoteRepository' => $this->quoteRepositoryMock,
-                'addressValidator' => $this->addressValidatorMock,
-                'logger' => $this->loggerMock,
-                'addressRepository' => $this->addressRepositoryMock,
-                'scopeConfig' => $this->scopeConfigMock,
-                'totalsCollector' => $this->totalsCollectorMock
-            ]
-        );
-
         $this->shippingAddressMock = $this->getMock(
             \Magento\Quote\Model\Quote\Address::class,
             [
@@ -144,39 +158,40 @@ class ShippingInformationManagementTest extends \PHPUnit_Framework_TestCase
                 'getStoreId',
                 'setShippingAddress',
                 'getShippingAddress',
-                'collectTotals'
+                'collectTotals',
+                'getExtensionAttributes',
+                'setExtensionAttributes',
+                'setBillingAddress'
             ],
             [],
             '',
             false
         );
-    }
-
-    /**
-     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
-     * @expectedExceptionMessage Cart contains virtual product(s) only. Shipping address is not applicable.
-     */
-    public function testSaveAddressInformationIfCartIsVirtual()
-    {
-        $this->markTestSkipped('MAGETWO-48531');
-        $cartId = 100;
-        $carrierCode = 'carrier_code';
-        $shippingMethod = 'shipping_method';
-        $addressInformationMock = $this->getMock(\Magento\Checkout\Api\Data\ShippingInformationInterface::class);
-
-        $addressInformationMock->expects($this->once())
-            ->method('getShippingAddress')
-            ->willReturn($this->shippingAddressMock);
-        $addressInformationMock->expects($this->once())->method('getShippingCarrierCode')->willReturn($carrierCode);
-        $addressInformationMock->expects($this->once())->method('getShippingMethodCode')->willReturn($shippingMethod);
 
-        $this->quoteMock->expects($this->once())->method('isVirtual')->willReturn(true);
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')
-            ->with($cartId)
-            ->willReturn($this->quoteMock);
-
-        $this->model->saveAddressInformation($cartId, $addressInformationMock);
+        $this->shippingAssignmentFactoryMock =
+            $this->getMock(\Magento\Quote\Model\ShippingAssignmentFactory::class, ['create'], [], '', false);
+        $this->cartExtensionFactoryMock =
+            $this->getMock(\Magento\Quote\Api\Data\CartExtensionInterfaceFactory::class, ['create'], [], '', false);
+        $this->shippingFactoryMock =
+            $this->getMock(\Magento\Quote\Model\ShippingFactory::class, ['create'], [], '', false);
+
+        $this->prepareObjectManager([
+            [\Magento\Quote\Model\ShippingAssignmentFactory::class, $this->shippingAssignmentFactoryMock],
+            [\Magento\Quote\Api\Data\CartExtensionFactory::class, $this->cartExtensionFactoryMock],
+            [\Magento\Quote\Model\ShippingFactory::class, $this->shippingFactoryMock],
+        ]);
+
+        $this->model = new \Magento\Checkout\Model\ShippingInformationManagement(
+            $this->paymentMethodManagementMock,
+            $this->paymentDetailsFactoryMock,
+            $this->cartTotalsRepositoryMock,
+            $this->quoteRepositoryMock,
+            $this->addressValidatorMock,
+            $this->loggerMock,
+            $this->addressRepositoryMock,
+            $this->scopeConfigMock,
+            $this->totalsCollectorMock
+        );
     }
 
     /**
@@ -185,19 +200,23 @@ class ShippingInformationManagementTest extends \PHPUnit_Framework_TestCase
      */
     public function testSaveAddressInformationIfCartIsEmpty()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $cartId = 100;
         $carrierCode = 'carrier_code';
         $shippingMethod = 'shipping_method';
         $addressInformationMock = $this->getMock(\Magento\Checkout\Api\Data\ShippingInformationInterface::class);
 
+        $billingAddress = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class);
         $addressInformationMock->expects($this->once())
             ->method('getShippingAddress')
             ->willReturn($this->shippingAddressMock);
+        $addressInformationMock->expects($this->once())->method('getBillingAddress')->willReturn($billingAddress);
         $addressInformationMock->expects($this->once())->method('getShippingCarrierCode')->willReturn($carrierCode);
         $addressInformationMock->expects($this->once())->method('getShippingMethodCode')->willReturn($shippingMethod);
 
-        $this->quoteMock->expects($this->once())->method('isVirtual')->willReturn(false);
+        $this->shippingAddressMock->expects($this->once())->method('getCountryId')->willReturn('USA');
+
+        $this->setShippingAssignmentsMocks($carrierCode . '_' . $shippingMethod);
+
         $this->quoteMock->expects($this->once())->method('getItemsCount')->willReturn(0);
         $this->quoteRepositoryMock->expects($this->once())
             ->method('getActive')
@@ -208,468 +227,209 @@ class ShippingInformationManagementTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * @expectedException \Magento\Framework\Exception\StateException
-     * @expectedExceptionMessage Shipping address is not set
+     * @param string $shippingMethod
      */
-    public function testSaveAddressInformationIfShippingAddressNotSet()
+    private function setShippingAssignmentsMocks($shippingMethod)
     {
-        $this->markTestSkipped('MAGETWO-48531');
-        $cartId = 100;
-        $carrierCode = 'carrier_code';
-        $shippingMethod = 'shipping_method';
-        $customerAddressId = 200;
-        $addressInformationMock = $this->getMock(\Magento\Checkout\Api\Data\ShippingInformationInterface::class);
+        $this->quoteMock->expects($this->once())->method('getExtensionAttributes')->willReturn(null);
 
-        $addressInformationMock->expects($this->once())
-            ->method('getShippingAddress')
-            ->willReturn($this->shippingAddressMock);
-        $addressInformationMock->expects($this->once())->method('getShippingCarrierCode')->willReturn($carrierCode);
-        $addressInformationMock->expects($this->once())->method('getShippingMethodCode')->willReturn($shippingMethod);
-
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')
-            ->with($cartId)
-            ->willReturn($this->quoteMock);
-
-        $this->quoteMock->expects($this->once())->method('isVirtual')->willReturn(false);
-        $this->quoteMock->expects($this->once())->method('getItemsCount')->willReturn(5);
+        $this->cartExtensionMock = $this->getMock(
+            \Magento\Quote\Api\Data\CartExtension::class,
+            ['getShippingAssignments', 'setShippingAssignments'],
+            [],
+            '',
+            false
+        );
+        $this->cartExtensionFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($this->cartExtensionMock);
+        $this->cartExtensionMock->expects($this->once())->method('getShippingAssignments')->willReturn(null);
 
-        $this->shippingAddressMock->expects($this->once())->method('getSaveInAddressBook')->willReturn(1);
-        $this->shippingAddressMock->expects($this->once())->method('getSameAsBilling')->willReturn(1);
-        $this->shippingAddressMock->expects($this->once())
-            ->method('getCustomerAddressId')
-            ->willReturn($customerAddressId);
+        $this->shippingAssignmentMock = $this->getMock(
+            \Magento\Quote\Model\ShippingAssignment::class,
+            [],
+            [],
+            '',
+            false
+        );
+        $this->shippingAssignmentFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($this->shippingAssignmentMock);
+        $this->shippingAssignmentMock->expects($this->once())->method('getShipping')->willReturn(null);
 
-        $this->addressValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->shippingAddressMock)
-            ->willReturn(true);
+        $this->shippingMock = $this->getMock(\Magento\Quote\Model\Shipping::class, [], [], '', false);
+        $this->shippingFactoryMock->expects($this->once())->method('create')->willReturn($this->shippingMock);
 
-        $this->quoteMock->expects($this->once())
-            ->method('setShippingAddress')
+        $this->shippingMock->expects($this->once())
+            ->method('setAddress')
             ->with($this->shippingAddressMock)
             ->willReturnSelf();
-        $this->quoteMock->expects($this->exactly(2))
-            ->method('getShippingAddress')
-            ->willReturn($this->shippingAddressMock);
-
-        $customerAddressMock = $this->getMock(\Magento\Customer\Api\Data\AddressInterface::class);
-        $this->addressRepositoryMock->expects($this->once())
-            ->method('getById')
-            ->with($customerAddressId)
-            ->willReturn($customerAddressMock);
+        $this->shippingMock->expects($this->once())->method('setMethod')->with($shippingMethod)->willReturnSelf();
 
-        $this->shippingAddressMock->expects($this->once())
-            ->method('importCustomerAddressData')
-            ->with($customerAddressMock)
-            ->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())->method('setSaveInAddressBook')->with(1)->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())->method('setSameAsBilling')->with(1)->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())
-            ->method('setCollectShippingRates')
-            ->with(true)
+        $this->shippingAssignmentMock->expects($this->once())
+            ->method('setShipping')
+            ->with($this->shippingMock)
             ->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())->method('getCountryId')->willReturn(false);
 
-        $this->model->saveAddressInformation($cartId, $addressInformationMock);
-    }
-
-    /**
-     * @expectedException \Magento\Framework\Exception\InputException
-     * @expectedExceptionMessage Unable to save address. Please check input data.
-     */
-    public function testSaveAddressInformationThrowExceptionWhileAddressSaving()
-    {
-        $this->markTestSkipped('MAGETWO-48531');
-        $cartId = 100;
-        $carrierCode = 'carrier_code';
-        $shippingMethod = 'shipping_method';
-        $customerAddressId = 200;
-        $exception = new \Exception();
-
-        $addressInformationMock = $this->getMock(\Magento\Checkout\Api\Data\ShippingInformationInterface::class);
-        $addressInformationMock->expects($this->once())
-            ->method('getShippingAddress')
-            ->willReturn($this->shippingAddressMock);
-        $addressInformationMock->expects($this->once())->method('getShippingCarrierCode')->willReturn($carrierCode);
-        $addressInformationMock->expects($this->once())->method('getShippingMethodCode')->willReturn($shippingMethod);
-
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')
-            ->with($cartId)
-            ->willReturn($this->quoteMock);
-
-        $this->quoteMock->expects($this->once())->method('isVirtual')->willReturn(false);
-        $this->quoteMock->expects($this->once())->method('getItemsCount')->willReturn(5);
-
-        $this->shippingAddressMock->expects($this->once())->method('getSaveInAddressBook')->willReturn(1);
-        $this->shippingAddressMock->expects($this->once())->method('getSameAsBilling')->willReturn(1);
-        $this->shippingAddressMock->expects($this->once())
-            ->method('getCustomerAddressId')
-            ->willReturn($customerAddressId);
-        $this->shippingAddressMock->expects($this->once())->method('setSaveInAddressBook')->with(1)->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())->method('setSameAsBilling')->with(1)->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())
-            ->method('setCollectShippingRates')
-            ->with(true)
+        $this->cartExtensionMock->expects($this->once())
+            ->method('setShippingAssignments')
+            ->with([$this->shippingAssignmentMock])
             ->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())->method('getCountryId')->willReturn(1);
-        $this->totalsCollectorMock
-            ->expects($this->once())
-            ->method('collectAddressTotals')
-            ->willThrowException($exception);
-        $this->addressValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->shippingAddressMock)
-            ->willReturn(true);
 
         $this->quoteMock->expects($this->once())
-            ->method('setShippingAddress')
-            ->with($this->shippingAddressMock)
-            ->willReturnSelf();
-        $this->quoteMock->expects($this->exactly(2))
-            ->method('getShippingAddress')
-            ->willReturn($this->shippingAddressMock);
-
-        $customerAddressMock = $this->getMock(\Magento\Customer\Api\Data\AddressInterface::class);
-        $this->addressRepositoryMock->expects($this->once())
-            ->method('getById')
-            ->with($customerAddressId)
-            ->willReturn($customerAddressMock);
-
-        $this->shippingAddressMock->expects($this->once())
-            ->method('importCustomerAddressData')
-            ->with($customerAddressMock)
+            ->method('setExtensionAttributes')
+            ->with($this->cartExtensionMock)
             ->willReturnSelf();
-
-        $this->loggerMock->expects($this->once())->method('critical')->with($exception);
-
-        $this->model->saveAddressInformation($cartId, $addressInformationMock);
     }
 
     /**
-     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
-     * @expectedExceptionMessage Carrier with such method not found: carrier_code, shipping_method
+     * @expectedException \Magento\Framework\Exception\StateException
+     * @expectedExceptionMessage Shipping address is not set
      */
-    public function testSaveAddressInformationIfCarrierCodeIsInvalid()
+    public function testSaveAddressInformationIfShippingAddressNotSet()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $cartId = 100;
         $carrierCode = 'carrier_code';
         $shippingMethod = 'shipping_method';
-        $customerAddressId = 200;
-
-        $this->quoteMock->expects($this->once())->method('isVirtual')->willReturn(false);
-        $this->quoteMock->expects($this->once())->method('getItemsCount')->willReturn(5);
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')
-            ->with($cartId)
-            ->willReturn($this->quoteMock);
-
         $addressInformationMock = $this->getMock(\Magento\Checkout\Api\Data\ShippingInformationInterface::class);
+
         $addressInformationMock->expects($this->once())
             ->method('getShippingAddress')
             ->willReturn($this->shippingAddressMock);
         $addressInformationMock->expects($this->once())->method('getShippingCarrierCode')->willReturn($carrierCode);
         $addressInformationMock->expects($this->once())->method('getShippingMethodCode')->willReturn($shippingMethod);
 
-        $this->shippingAddressMock->expects($this->once())->method('getSaveInAddressBook')->willReturn(1);
-        $this->shippingAddressMock->expects($this->once())->method('getSameAsBilling')->willReturn(1);
-        $this->shippingAddressMock->expects($this->once())
-            ->method('getCustomerAddressId')
-            ->willReturn($customerAddressId);
-
-        $this->addressValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->shippingAddressMock)
-            ->willReturn(true);
+        $billingAddress = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class);
+        $addressInformationMock->expects($this->once())->method('getBillingAddress')->willReturn($billingAddress);
 
-        $this->quoteMock->expects($this->once())
-            ->method('setShippingAddress')
-            ->with($this->shippingAddressMock)
-            ->willReturnSelf();
-        $this->quoteMock->expects($this->exactly(2))
-            ->method('getShippingAddress')
-            ->willReturn($this->shippingAddressMock);
-
-        $customerAddressMock = $this->getMock(\Magento\Customer\Api\Data\AddressInterface::class);
-        $this->addressRepositoryMock->expects($this->once())
-            ->method('getById')
-            ->with($customerAddressId)
-            ->willReturn($customerAddressMock);
-
-        $this->shippingAddressMock->expects($this->once())
-            ->method('importCustomerAddressData')
-            ->with($customerAddressMock)
-            ->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())->method('setSaveInAddressBook')->with(1)->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())->method('setSameAsBilling')->with(1)->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())
-            ->method('setCollectShippingRates')
-            ->with(true)
-            ->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())->method('getCountryId')->willReturn(1);
-        $this->totalsCollectorMock
-            ->expects($this->once())
-            ->method('collectAddressTotals')
-            ->with($this->quoteMock, $this->shippingAddressMock);
-        $this->shippingAddressMock->expects($this->once())->method('getShippingMethod')->willReturn($shippingMethod);
-        $this->shippingAddressMock->expects($this->once())
-            ->method('getShippingRateByCode')
-            ->with($shippingMethod)
-            ->willReturn(false);
+        $this->shippingAddressMock->expects($this->once())->method('getCountryId')->willReturn(null);
 
         $this->model->saveAddressInformation($cartId, $addressInformationMock);
     }
 
     /**
      * @expectedException \Magento\Framework\Exception\InputException
-     * @expectedExceptionMessage Wrong minimum amount.
+     * @expectedExceptionMessage Unable to save shipping information. Please check input data.
      */
-    public function testSaveAddressInformationIfMinimumAmountIsNotValid()
+    public function testSaveAddressInformationIfCanNotSaveQuote()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $cartId = 100;
         $carrierCode = 'carrier_code';
         $shippingMethod = 'shipping_method';
-        $customerAddressId = 200;
-        $storeId = 500;
-        $minAmountExceptionMessage = __('Wrong minimum amount.');
-
-        $this->quoteMock->expects($this->once())->method('isVirtual')->willReturn(false);
-        $this->quoteMock->expects($this->once())->method('getItemsCount')->willReturn(5);
-        $this->quoteMock->expects($this->once())->method('getIsMultiShipping')->willReturn(true);
-        $this->quoteMock->expects($this->once())->method('setIsMultiShipping')->with(false)->willReturnSelf();
-        $this->quoteMock->expects($this->once())->method('validateMinimumAmount')->with(true)->willReturn(false);
-        $this->quoteMock->expects($this->once())->method('getStoreId')->willReturn($storeId);
+        $addressInformationMock = $this->getMock(\Magento\Checkout\Api\Data\ShippingInformationInterface::class);
 
         $this->quoteRepositoryMock->expects($this->once())
             ->method('getActive')
             ->with($cartId)
             ->willReturn($this->quoteMock);
 
-        $addressInformationMock = $this->getMock(\Magento\Checkout\Api\Data\ShippingInformationInterface::class);
         $addressInformationMock->expects($this->once())
             ->method('getShippingAddress')
             ->willReturn($this->shippingAddressMock);
         $addressInformationMock->expects($this->once())->method('getShippingCarrierCode')->willReturn($carrierCode);
         $addressInformationMock->expects($this->once())->method('getShippingMethodCode')->willReturn($shippingMethod);
 
-        $this->shippingAddressMock->expects($this->once())->method('getSaveInAddressBook')->willReturn(1);
-        $this->shippingAddressMock->expects($this->once())->method('getSameAsBilling')->willReturn(1);
-        $this->shippingAddressMock->expects($this->once())
-            ->method('getCustomerAddressId')
-            ->willReturn($customerAddressId);
+        $billingAddress = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class);
+        $addressInformationMock->expects($this->once())->method('getBillingAddress')->willReturn($billingAddress);
 
-        $this->addressValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->shippingAddressMock)
-            ->willReturn(true);
-
-        $this->quoteMock->expects($this->once())
-            ->method('setShippingAddress')
-            ->with($this->shippingAddressMock)
-            ->willReturnSelf();
-        $this->quoteMock->expects($this->exactly(2))
-            ->method('getShippingAddress')
-            ->willReturn($this->shippingAddressMock);
+        $this->shippingAddressMock->expects($this->once())->method('getCountryId')->willReturn('USA');
 
-        $customerAddressMock = $this->getMock(\Magento\Customer\Api\Data\AddressInterface::class);
-        $this->addressRepositoryMock->expects($this->once())
-            ->method('getById')
-            ->with($customerAddressId)
-            ->willReturn($customerAddressMock);
+        $this->setShippingAssignmentsMocks($carrierCode . '_' . $shippingMethod);
 
-        $this->shippingAddressMock->expects($this->once())
-            ->method('importCustomerAddressData')
-            ->with($customerAddressMock)
-            ->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())->method('setSaveInAddressBook')->with(1)->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())->method('setSameAsBilling')->with(1)->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())
-            ->method('setCollectShippingRates')
-            ->with(true)
-            ->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())->method('getCountryId')->willReturn(1);
-        $this->totalsCollectorMock
-            ->expects($this->once())
-            ->method('collectAddressTotals')
-            ->with($this->quoteMock, $this->shippingAddressMock);
-        $this->shippingAddressMock->expects($this->once())->method('getShippingMethod')->willReturn($shippingMethod);
-        $this->shippingAddressMock->expects($this->once())
-            ->method('getShippingRateByCode')
-            ->with($shippingMethod)
-            ->willReturn($this->getMock(\Magento\Quote\Model\Quote\Address\Rate::class, [], [], '', false));
+        $this->quoteMock->expects($this->once())->method('getItemsCount')->willReturn(100);
+        $this->quoteMock->expects($this->once())->method('setIsMultiShipping')->with(false)->willReturnSelf();
+        $this->quoteMock->expects($this->once())->method('setBillingAddress')->with($billingAddress)->willReturnSelf();
 
-        $this->scopeConfigMock->expects($this->once())
-            ->method('getValue')
-            ->with('sales/minimum_order/error_message', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $storeId)
-            ->willReturn($minAmountExceptionMessage);
+        $this->quoteRepositoryMock->expects($this->once())
+            ->method('save')
+            ->with($this->quoteMock)
+            ->willThrowException(new \Exception());
 
         $this->model->saveAddressInformation($cartId, $addressInformationMock);
     }
 
     /**
-     * @expectedException \Magento\Framework\Exception\InputException
-     * @expectedExceptionMessage Unable to save shipping information. Please check input data.
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage Carrier with such method not found: carrier_code, shipping_method
      */
-    public function testSaveAddressInformationIfCanNotSaveQuote()
+    public function testSaveAddressInformationIfCarrierCodeIsInvalid()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $cartId = 100;
         $carrierCode = 'carrier_code';
         $shippingMethod = 'shipping_method';
-        $customerAddressId = 200;
-        $exception = new \Exception();
-
-        $this->quoteMock->expects($this->once())->method('isVirtual')->willReturn(false);
-        $this->quoteMock->expects($this->once())->method('getItemsCount')->willReturn(5);
-        $this->quoteMock->expects($this->once())->method('getIsMultiShipping')->willReturn(true);
-        $this->quoteMock->expects($this->once())->method('setIsMultiShipping')->with(false)->willReturnSelf();
-        $this->quoteMock->expects($this->once())->method('validateMinimumAmount')->with(true)->willReturn(true);
-        $this->quoteMock->expects($this->once())->method('collectTotals')->willReturnSelf();
+        $addressInformationMock = $this->getMock(\Magento\Checkout\Api\Data\ShippingInformationInterface::class);
 
         $this->quoteRepositoryMock->expects($this->once())
             ->method('getActive')
             ->with($cartId)
             ->willReturn($this->quoteMock);
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('save')
-            ->with($this->quoteMock)
-            ->willThrowException($exception);
-        $addressInformationMock = $this->getMock(\Magento\Checkout\Api\Data\ShippingInformationInterface::class);
         $addressInformationMock->expects($this->once())
             ->method('getShippingAddress')
             ->willReturn($this->shippingAddressMock);
         $addressInformationMock->expects($this->once())->method('getShippingCarrierCode')->willReturn($carrierCode);
         $addressInformationMock->expects($this->once())->method('getShippingMethodCode')->willReturn($shippingMethod);
 
-        $this->shippingAddressMock->expects($this->once())->method('getSaveInAddressBook')->willReturn(1);
-        $this->shippingAddressMock->expects($this->once())->method('getSameAsBilling')->willReturn(1);
-        $this->shippingAddressMock->expects($this->once())
-            ->method('getCustomerAddressId')
-            ->willReturn($customerAddressId);
+        $billingAddress = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class);
+        $addressInformationMock->expects($this->once())->method('getBillingAddress')->willReturn($billingAddress);
+        $this->shippingAddressMock->expects($this->once())->method('getCountryId')->willReturn('USA');
 
-        $this->addressValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->shippingAddressMock)
-            ->willReturn(true);
+        $this->setShippingAssignmentsMocks($carrierCode . '_' . $shippingMethod);
 
-        $this->quoteMock->expects($this->once())
-            ->method('setShippingAddress')
-            ->with($this->shippingAddressMock)
-            ->willReturnSelf();
-        $this->quoteMock->expects($this->exactly(2))
-            ->method('getShippingAddress')
-            ->willReturn($this->shippingAddressMock);
+        $this->quoteMock->expects($this->once())->method('getItemsCount')->willReturn(100);
+        $this->quoteMock->expects($this->once())->method('setIsMultiShipping')->with(false)->willReturnSelf();
+        $this->quoteMock->expects($this->once())->method('setBillingAddress')->with($billingAddress)->willReturnSelf();
+        $this->quoteMock->expects($this->once())->method('getShippingAddress')->willReturn($this->shippingAddressMock);
 
-        $customerAddressMock = $this->getMock(\Magento\Customer\Api\Data\AddressInterface::class);
-        $this->addressRepositoryMock->expects($this->once())
-            ->method('getById')
-            ->with($customerAddressId)
-            ->willReturn($customerAddressMock);
+        $this->quoteRepositoryMock->expects($this->once())
+            ->method('save')
+            ->with($this->quoteMock);
 
-        $this->shippingAddressMock->expects($this->once())
-            ->method('importCustomerAddressData')
-            ->with($customerAddressMock)
-            ->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())->method('setSaveInAddressBook')->with(1)->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())->method('setSameAsBilling')->with(1)->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())
-            ->method('setCollectShippingRates')
-            ->with(true)
-            ->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())->method('getCountryId')->willReturn(1);
-        $this->shippingAddressMock->expects($this->once())->method('save')->willReturnSelf();
-        $this->totalsCollectorMock
-            ->expects($this->once())
-            ->method('collectAddressTotals')
-            ->with($this->quoteMock, $this->shippingAddressMock);
         $this->shippingAddressMock->expects($this->once())->method('getShippingMethod')->willReturn($shippingMethod);
         $this->shippingAddressMock->expects($this->once())
             ->method('getShippingRateByCode')
             ->with($shippingMethod)
-            ->willReturn($this->getMock(\Magento\Quote\Model\Quote\Address\Rate::class, [], [], '', false));
-
-        $this->loggerMock->expects($this->once())->method('critical')->with($exception);
+            ->willReturn(false);
 
         $this->model->saveAddressInformation($cartId, $addressInformationMock);
     }
 
     public function testSaveAddressInformation()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $cartId = 100;
         $carrierCode = 'carrier_code';
         $shippingMethod = 'shipping_method';
-        $customerAddressId = 200;
-
-        $this->quoteMock->expects($this->once())->method('isVirtual')->willReturn(false);
-        $this->quoteMock->expects($this->once())->method('getItemsCount')->willReturn(5);
-        $this->quoteMock->expects($this->once())->method('getIsMultiShipping')->willReturn(true);
-        $this->quoteMock->expects($this->once())->method('setIsMultiShipping')->with(false)->willReturnSelf();
-        $this->quoteMock->expects($this->once())->method('validateMinimumAmount')->with(true)->willReturn(true);
-        $this->quoteMock->expects($this->once())->method('collectTotals')->willReturnSelf();
+        $addressInformationMock = $this->getMock(\Magento\Checkout\Api\Data\ShippingInformationInterface::class);
 
         $this->quoteRepositoryMock->expects($this->once())
             ->method('getActive')
             ->with($cartId)
             ->willReturn($this->quoteMock);
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('save')
-            ->with($this->quoteMock);
-
-        $addressInformationMock = $this->getMock(\Magento\Checkout\Api\Data\ShippingInformationInterface::class);
         $addressInformationMock->expects($this->once())
             ->method('getShippingAddress')
             ->willReturn($this->shippingAddressMock);
         $addressInformationMock->expects($this->once())->method('getShippingCarrierCode')->willReturn($carrierCode);
         $addressInformationMock->expects($this->once())->method('getShippingMethodCode')->willReturn($shippingMethod);
 
-        $this->shippingAddressMock->expects($this->once())->method('getSaveInAddressBook')->willReturn(1);
-        $this->shippingAddressMock->expects($this->once())->method('getSameAsBilling')->willReturn(1);
-        $this->shippingAddressMock->expects($this->once())
-            ->method('getCustomerAddressId')
-            ->willReturn($customerAddressId);
+        $billingAddress = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class);
+        $addressInformationMock->expects($this->once())->method('getBillingAddress')->willReturn($billingAddress);
+        $this->shippingAddressMock->expects($this->once())->method('getCountryId')->willReturn('USA');
 
-        $this->addressValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->shippingAddressMock)
-            ->willReturn(true);
+        $this->setShippingAssignmentsMocks($carrierCode . '_' . $shippingMethod);
 
-        $this->quoteMock->expects($this->once())
-            ->method('setShippingAddress')
-            ->with($this->shippingAddressMock)
-            ->willReturnSelf();
-        $this->quoteMock->expects($this->exactly(2))
-            ->method('getShippingAddress')
-            ->willReturn($this->shippingAddressMock);
-        $customerAddressMock = $this->getMock(\Magento\Customer\Api\Data\AddressInterface::class);
-        $this->addressRepositoryMock->expects($this->once())
-            ->method('getById')
-            ->with($customerAddressId)
-            ->willReturn($customerAddressMock);
+        $this->quoteMock->expects($this->once())->method('getItemsCount')->willReturn(100);
+        $this->quoteMock->expects($this->once())->method('setIsMultiShipping')->with(false)->willReturnSelf();
+        $this->quoteMock->expects($this->once())->method('setBillingAddress')->with($billingAddress)->willReturnSelf();
+        $this->quoteMock->expects($this->once())->method('getShippingAddress')->willReturn($this->shippingAddressMock);
+
+        $this->quoteRepositoryMock->expects($this->once())
+            ->method('save')
+            ->with($this->quoteMock);
 
-        $this->shippingAddressMock->expects($this->once())
-            ->method('importCustomerAddressData')
-            ->with($customerAddressMock)
-            ->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())->method('setSaveInAddressBook')->with(1)->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())->method('setSameAsBilling')->with(1)->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())
-            ->method('setCollectShippingRates')
-            ->with(true)
-            ->willReturnSelf();
-        $this->shippingAddressMock->expects($this->once())->method('getCountryId')->willReturn(1);
-        $this->totalsCollectorMock
-            ->expects($this->once())
-            ->method('collectAddressTotals')
-            ->with($this->quoteMock, $this->shippingAddressMock);
         $this->shippingAddressMock->expects($this->once())->method('getShippingMethod')->willReturn($shippingMethod);
         $this->shippingAddressMock->expects($this->once())
             ->method('getShippingRateByCode')
             ->with($shippingMethod)
-            ->willReturn($this->getMock(\Magento\Quote\Model\Quote\Address\Rate::class, [], [], '', false));
+            ->willReturn('rates');
 
         $paymentDetailsMock = $this->getMock(\Magento\Checkout\Api\Data\PaymentDetailsInterface::class);
         $this->paymentDetailsFactoryMock->expects($this->once())->method('create')->willReturn($paymentDetailsMock);
@@ -679,18 +439,38 @@ class ShippingInformationManagementTest extends \PHPUnit_Framework_TestCase
             ->method('getList')
             ->with($cartId)
             ->willReturn([$paymentMethodMock]);
-        $totalsMock = $this->getMock(\Magento\Quote\Api\Data\TotalsInterface::class);
-        $this->cartTotalsRepositoryMock->expects($this->once())->method('get')->with($cartId)->willReturn($totalsMock);
+
+        $cartTotalsMock = $this->getMock(\Magento\Quote\Api\Data\TotalsInterface::class);
+        $this->cartTotalsRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($cartId)
+            ->willReturn($cartTotalsMock);
 
         $paymentDetailsMock->expects($this->once())
             ->method('setPaymentMethods')
             ->with([$paymentMethodMock])
             ->willReturnSelf();
-        $paymentDetailsMock->expects($this->once())->method('setTotals')->with($totalsMock)->willReturnSelf();
+        $paymentDetailsMock->expects($this->once())->method('setTotals')->with()->willReturnSelf($cartTotalsMock);
 
         $this->assertEquals(
             $paymentDetailsMock,
             $this->model->saveAddressInformation($cartId, $addressInformationMock)
         );
     }
+
+    /**
+     * @param array $map
+     */
+    private function prepareObjectManager($map)
+    {
+        $objectManagerMock = $this->getMock(\Magento\Framework\ObjectManagerInterface::class);
+        $objectManagerMock->expects($this->any())->method('getInstance')->willReturnSelf();
+        $objectManagerMock->expects($this->any())
+            ->method('get')
+            ->will($this->returnValueMap($map));
+        $reflectionClass = new \ReflectionClass(\Magento\Framework\App\ObjectManager::class);
+        $reflectionProperty = $reflectionClass->getProperty('_instance');
+        $reflectionProperty->setAccessible(true);
+        $reflectionProperty->setValue($objectManagerMock);
+    }
 }
diff --git a/app/code/Magento/Checkout/etc/adminhtml/system.xml b/app/code/Magento/Checkout/etc/adminhtml/system.xml
index d4567a438253935c25cc00e88628d97c16dd7a42..b3b3d11b568a3c692d48b8e7b1b875ece4c11ac5 100644
--- a/app/code/Magento/Checkout/etc/adminhtml/system.xml
+++ b/app/code/Magento/Checkout/etc/adminhtml/system.xml
@@ -21,6 +21,10 @@
                     <label>Allow Guest Checkout</label>
                     <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
                 </field>
+                <field id="display_billing_address_on" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Display Billing Address On</label>
+                    <source_model>\Magento\Checkout\Model\Adminhtml\BillingAddressDisplayOptions</source_model>
+                </field>
             </group>
             <group id="cart" translate="label" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
                 <label>Shopping Cart</label>
diff --git a/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_configure.xml b/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_configure.xml
index 403e07c64d3ede27b5830a44ccdffbcaa5961273..c255f17cd36974518b8dc932e2a74e6726e6a266 100644
--- a/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_configure.xml
+++ b/app/code/Magento/Checkout/view/frontend/layout/checkout_cart_configure.xml
@@ -6,6 +6,9 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
+    <head>
+        <link src="Magento_Checkout::js/view/configure/product-customer-data.js"/>
+    </head>
     <update handle="catalog_product_view"/>
     <body>
         <referenceBlock name="head.components">
diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/item/configure/updatecart.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/item/configure/updatecart.phtml
index fe39e9c44ada8b421966103b8d1810d82c21bc7b..0f221a393f5eb181f31a778ce4d01da1b0cc109b 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/cart/item/configure/updatecart.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/cart/item/configure/updatecart.phtml
@@ -17,7 +17,7 @@
             <div class="field qty">
                 <label class="label" for="qty"><span><?php /* @escapeNotVerified */ echo __('Qty') ?></span></label>
                 <div class="control">
-                    <input type="number" name="qty" id="qty" maxlength="12" value="<?php /* @escapeNotVerified */ echo $block->getProductDefaultQty() * 1 ?>" title="<?php /* @escapeNotVerified */ echo __('Qty') ?>" class="input-text qty" data-validate="{'required-number':true,digits:true}"/>
+                    <input type="number" name="qty" id="qty" maxlength="12" value="" title="<?php /* @escapeNotVerified */ echo __('Qty') ?>" class="input-text qty" data-validate="{'required-number':true,digits:true}"/>
                 </div>
             </div>
             <?php endif; ?>
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/set-billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/action/set-billing-address.js
index 31d52e5dd1d766460b74458d160f2e0281dc4cd8..36518a4d615e146d9d8a8d1736a9235f0363e88c 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/action/set-billing-address.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/action/set-billing-address.js
@@ -10,7 +10,6 @@ define(
         'mage/storage',
         'Magento_Checkout/js/model/error-processor',
         'Magento_Customer/js/model/customer',
-        'Magento_Checkout/js/action/get-totals',
         'Magento_Checkout/js/model/full-screen-loader',
         'Magento_Checkout/js/action/get-payment-information'
     ],
@@ -20,7 +19,6 @@ define(
               storage,
               errorProcessor,
               customer,
-              getTotalsAction,
               fullScreenLoader,
               getPaymentInformationAction
     ) {
@@ -55,18 +53,12 @@ define(
                 serviceUrl, JSON.stringify(payload)
             ).done(
                 function () {
-                    var deferred = null;
+                    var deferred = $.Deferred();
 
-                    if (!quote.isVirtual()) {
-                        getTotalsAction([]);
+                    getPaymentInformationAction(deferred);
+                    $.when(deferred).done(function () {
                         fullScreenLoader.stopLoader();
-                    } else {
-                        deferred = $.Deferred();
-                        getPaymentInformationAction(deferred);
-                        $.when(deferred).done(function () {
-                            fullScreenLoader.stopLoader();
-                        });
-                    }
+                    });
                 }
             ).fail(
                 function (response) {
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/new-customer-address.js b/app/code/Magento/Checkout/view/frontend/web/js/model/new-customer-address.js
index 4e2fbdc5dfa50fe1e7f27ed1c0935ce97f3e5cc7..bee4480b0dfb1c9db669d53f5091bb1d3564237a 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/model/new-customer-address.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/new-customer-address.js
@@ -21,7 +21,7 @@ define([], function () {
 
         return {
             email: addressData.email,
-            countryId: (addressData.country_id) ? addressData.country_id : window.checkoutConfig.defaultCountryId,
+            countryId: addressData['country_id'] || addressData.countryId || window.checkoutConfig.defaultCountryId,
             regionId: regionId,
             regionCode: (addressData.region) ? addressData.region.region_code : null,
             region: (addressData.region) ? addressData.region.region : null,
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js
index 55678fc701d5b43ada6be2b74f456960d2917cb4..420d50b83478a91ab38b6a333a681f119b6db49e 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js
@@ -12,7 +12,8 @@ define(
         '../action/select-shipping-address',
         './postcode-validator',
         'mage/translate',
-        'uiRegistry'
+        'uiRegistry',
+        'Magento_Checkout/js/model/quote'
     ],
     function (
         $,
@@ -22,7 +23,8 @@ define(
         selectShippingAddress,
         postcodeValidator,
         $t,
-        uiRegistry
+        uiRegistry,
+        quote
     ) {
         'use strict';
 
@@ -41,7 +43,7 @@ define(
              * @param {Object} validator
              */
             registerValidator: function (carrier, validator) {
-                if (checkoutConfig.activeCarriers.indexOf(carrier) != -1) {
+                if (checkoutConfig.activeCarriers.indexOf(carrier) !== -1) {
                     validators.push(validator);
                 }
             },
@@ -174,6 +176,7 @@ define(
                     address;
 
                 if (this.validateAddressData(addressFlat)) {
+                    addressFlat = $.extend(true, {}, quote.shippingAddress(), addressFlat);
                     address = addressConverter.formAddressDataToQuoteAddress(addressFlat);
                     selectShippingAddress(address);
                 }
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js
index 433adfb7f824d23ffa113089ecebb7dc4340b979..ea88d2c1e7b10f27636293a38a3814e672b8010a 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js
@@ -224,7 +224,7 @@ define([
 
                         if (msg) {
                             alert({
-                                content: $.mage.__(msg)
+                                content: msg
                             });
                         }
                     }
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js
index b9cf58b51b1338d591e13de3f55c5f7370395434..0c2e7fb01c7015f030af9c2f30442def258fa834 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js
@@ -7,6 +7,7 @@
 define(
     [
         'ko',
+        'underscore',
         'Magento_Ui/js/form/form',
         'Magento_Customer/js/model/customer',
         'Magento_Customer/js/model/address-list',
@@ -22,6 +23,7 @@ define(
     ],
     function (
         ko,
+        _,
         Component,
         customer,
         addressList,
@@ -39,9 +41,13 @@ define(
 
         var lastSelectedBillingAddress = null,
             newAddressOption = {
+                /**
+                 * Get new address label
+                 * @returns {String}
+                 */
                 getAddressInline: function () {
-                return $t('New Address');
-            },
+                    return $t('New Address');
+                },
                 customerAddressId: null
             },
             countryData = customerData.get('directory-data'),
@@ -121,9 +127,8 @@ define(
             useShippingAddress: function () {
                 if (this.isAddressSameAsShipping()) {
                     selectBillingAddress(quote.shippingAddress());
-                    if (window.checkoutConfig.reloadOnBillingAddress) {
-                        setBillingAddressAction(globalMessageList);
-                    }
+
+                    this.updateAddresses();
                     this.isAddressDetailsVisible(true);
                 } else {
                     lastSelectedBillingAddress = quote.billingAddress();
@@ -142,15 +147,13 @@ define(
                 if (this.selectedAddress() && this.selectedAddress() != newAddressOption) {
                     selectBillingAddress(this.selectedAddress());
                     checkoutData.setSelectedBillingAddress(this.selectedAddress().getKey());
-                    if (window.checkoutConfig.reloadOnBillingAddress) {
-                        setBillingAddressAction(globalMessageList);
-                    }
                 } else {
                     this.source.set('params.invalid', false);
                     this.source.trigger(this.dataScopePrefix + '.data.validate');
+
                     if (this.source.get(this.dataScopePrefix + '.custom_attributes')) {
                         this.source.trigger(this.dataScopePrefix + '.custom_attributes.data.validate');
-                    };
+                    }
 
                     if (!this.source.get('params.invalid')) {
                         var addressData = this.source.get(this.dataScopePrefix),
@@ -159,19 +162,16 @@ define(
                         if (customer.isLoggedIn() && !this.customerHasAddresses) {
                             this.saveInAddressBook(1);
                         }
-                        addressData.save_in_address_book = this.saveInAddressBook() ? 1 : 0;
+                        addressData['save_in_address_book'] = this.saveInAddressBook() ? 1 : 0;
                         newBillingAddress = createBillingAddress(addressData);
 
                         // New address must be selected as a billing address
                         selectBillingAddress(newBillingAddress);
                         checkoutData.setSelectedBillingAddress(newBillingAddress.getKey());
                         checkoutData.setNewCustomerBillingAddress(addressData);
-
-                        if (window.checkoutConfig.reloadOnBillingAddress) {
-                            setBillingAddressAction(globalMessageList);
-                        }
                     }
                 }
+                this.updateAddresses();
             },
 
             /**
@@ -222,6 +222,26 @@ define(
              */
             getCountryName: function (countryId) {
                 return countryData()[countryId] != undefined ? countryData()[countryId].name : '';
+            },
+
+            /**
+             * Trigger action to update shipping and billing addresses
+             */
+            updateAddresses: function () {
+                if (window.checkoutConfig.reloadOnBillingAddress ||
+                    !window.checkoutConfig.displayBillingOnPaymentMethod
+                ) {
+                    setBillingAddressAction(globalMessageList);
+                }
+            },
+
+            /**
+             * Get code
+             * @param {Object} parent
+             * @returns {String}
+             */
+            getCode: function (parent) {
+                return _.isFunction(parent.getCode) ? parent.getCode() : 'shared';
             }
         });
     }
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/configure/product-customer-data.js b/app/code/Magento/Checkout/view/frontend/web/js/view/configure/product-customer-data.js
new file mode 100644
index 0000000000000000000000000000000000000000..a612b5e2dc6b7d38fa365911b81d67e5a3ca2aaa
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/configure/product-customer-data.js
@@ -0,0 +1,59 @@
+require([
+    'jquery',
+    'Magento_Customer/js/customer-data'
+], function ($, customerData) {
+    'use strict';
+
+    var selectors = {
+        qtySelector: '#product_addtocart_form [name="qty"]',
+        productIdSelector: '#product_addtocart_form [name="product"]'
+    },
+    cartData = customerData.get('cart'),
+    productId = $(selectors.productIdSelector).val(),
+    productQty,
+    productQtyInput,
+
+    /**
+    * Updates product's qty input value according to actual data
+    */
+    updateQty = function () {
+
+        if (productQty || productQty === 0) {
+            productQtyInput = productQtyInput || $(selectors.qtySelector);
+
+            if (productQtyInput && productQty.toString() !== productQtyInput.val()) {
+                productQtyInput.val(productQty);
+            }
+        }
+    },
+
+    /**
+    * Sets productQty according to cart data from customer-data
+    *
+    * @param {Object} data - cart data from customer-data
+    */
+    setProductQty = function (data) {
+        var product;
+
+        if (!(data && data.items && data.items.length && productId)) {
+            return;
+        }
+        product = data.items.find(function (item) {
+            return item['product_id'] === productId ||
+                item['item_id'] === productId;
+        });
+
+        if (!product) {
+            return;
+        }
+        productQty = product.qty;
+    };
+
+    cartData.subscribe(function (updateCartData) {
+        setProductQty(updateCartData);
+        updateQty();
+    });
+
+    setProductQty(cartData());
+    updateQty();
+});
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js
index 0e5e1dc35bf6390c349227cbd2ad19551c56e02c..7e0f5b877174767c566999d3cb4498169a8cb285 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js
@@ -8,7 +8,8 @@ define([
     'jquery',
     'ko',
     'underscore',
-    'sidebar'
+    'sidebar',
+    'mage/translate'
 ], function (Component, customerData, $, ko, _) {
     'use strict';
 
@@ -68,9 +69,7 @@ define([
                 'qty': ':input.cart-item-qty',
                 'button': ':button.update-cart-item'
             },
-            'confirmMessage': $.mage.__(
-                'Are you sure you would like to remove this item from the shopping cart?'
-            )
+            'confirmMessage': $.mage.__('Are you sure you would like to remove this item from the shopping cart?')
         });
     }
 
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/billing-address.html b/app/code/Magento/Checkout/view/frontend/web/template/billing-address.html
index 377208aa1b8ee050304d151e1f36a25ff2151069..23c02caa70b1a1d78037906a5b03f6d92ffc80b5 100644
--- a/app/code/Magento/Checkout/view/frontend/web/template/billing-address.html
+++ b/app/code/Magento/Checkout/view/frontend/web/template/billing-address.html
@@ -4,23 +4,29 @@
  * See COPYING.txt for license details.
  */
 -->
-<div class="billing-address-same-as-shipping-block field choice" data-bind="visible: canUseShippingAddress()">
-    <input type="checkbox" name="billing-address-same-as-shipping" data-bind="checked: isAddressSameAsShipping, click: useShippingAddress, attr: {id: 'billing-address-same-as-shipping-' + $parent.getCode()}"/>
-    <label data-bind="attr: {for: 'billing-address-same-as-shipping-' + $parent.getCode()}"><span data-bind="i18n: 'My billing and shipping address are the same'"></span></label>
-</div>
+<div class="checkout-billing-address">
 
-<!-- ko template: 'Magento_Checkout/billing-address/details' --><!-- /ko -->
-<fieldset class="fieldset" data-bind="visible: !isAddressDetailsVisible()">
-    <!-- ko template: 'Magento_Checkout/billing-address/list' --><!-- /ko -->
-    <!-- ko template: 'Magento_Checkout/billing-address/form' --><!-- /ko -->
-    <div class="actions-toolbar">
-        <div class="primary">
-            <button class="action action-update" type="button" data-bind="click: updateAddress">
-                <span data-bind="i18n: 'Update'"></span>
-            </button>
-            <button class="action action-cancel" type="button" data-bind="click: cancelAddressEdit">
-                <span data-bind="i18n: 'Cancel'"></span>
-            </button>
-        </div>
+    <div class="billing-address-same-as-shipping-block field choice" data-bind="visible: canUseShippingAddress()">
+        <input type="checkbox" name="billing-address-same-as-shipping"
+               data-bind="checked: isAddressSameAsShipping, click: useShippingAddress, attr: {id: 'billing-address-same-as-shipping-' + getCode($parent)}"/>
+        <label data-bind="attr: {for: 'billing-address-same-as-shipping-' + getCode($parent)}"><span
+                data-bind="i18n: 'My billing and shipping address are the same'"></span></label>
     </div>
-</fieldset>
+
+    <!-- ko template: 'Magento_Checkout/billing-address/details' --><!-- /ko -->
+    <fieldset class="fieldset" data-bind="visible: !isAddressDetailsVisible()">
+        <!-- ko template: 'Magento_Checkout/billing-address/list' --><!-- /ko -->
+        <!-- ko template: 'Magento_Checkout/billing-address/form' --><!-- /ko -->
+        <div class="actions-toolbar">
+            <div class="primary">
+                <button class="action action-update" type="button" data-bind="click: updateAddress">
+                    <span data-bind="i18n: 'Update'"></span>
+                </button>
+                <button class="action action-cancel" type="button" data-bind="click: cancelAddressEdit">
+                    <span data-bind="i18n: 'Cancel'"></span>
+                </button>
+            </div>
+        </div>
+    </fieldset>
+
+</div>
\ No newline at end of file
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php
index c2e26220aee46b9f3e964c3217ee3789ed0b6041..d317e55127a89b4a3cb1980f5640654dc9e6b120 100644
--- a/app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/InlineEdit.php
@@ -17,6 +17,11 @@ use Magento\Cms\Api\Data\PageInterface;
  */
 class InlineEdit extends \Magento\Backend\App\Action
 {
+    /**
+     * Authorization level of a basic admin session
+     */
+    const ADMIN_RESOURCE = 'Magento_Cms::save';
+
     /** @var PostDataProcessor */
     protected $dataProcessor;
 
diff --git a/app/code/Magento/Cms/Model/Block.php b/app/code/Magento/Cms/Model/Block.php
index d87f0f0d18884b6c31672fc5fdae32cd47e99c22..b25d433b0fee4f96618a31111940f9d410d9f006 100644
--- a/app/code/Magento/Cms/Model/Block.php
+++ b/app/code/Magento/Cms/Model/Block.php
@@ -23,7 +23,7 @@ class Block extends AbstractModel implements BlockInterface, IdentityInterface
     /**
      * CMS block cache tag
      */
-    const CACHE_TAG = 'cms_block';
+    const CACHE_TAG = 'cms_b';
 
     /**#@+
      * Block's statuses
@@ -36,7 +36,7 @@ class Block extends AbstractModel implements BlockInterface, IdentityInterface
     /**
      * @var string
      */
-    protected $_cacheTag = 'cms_block';
+    protected $_cacheTag = self::CACHE_TAG;
 
     /**
      * Prefix of model events names
diff --git a/app/code/Magento/Cms/Model/Page.php b/app/code/Magento/Cms/Model/Page.php
index 20c2e0547193160643feddf1ddded16208e74a57..f98b56d82db03660e8a81353332a089f6739d37d 100644
--- a/app/code/Magento/Cms/Model/Page.php
+++ b/app/code/Magento/Cms/Model/Page.php
@@ -39,12 +39,12 @@ class Page extends AbstractModel implements PageInterface, IdentityInterface
     /**
      * CMS page cache tag
      */
-    const CACHE_TAG = 'cms_page';
+    const CACHE_TAG = 'cms_p';
 
     /**
      * @var string
      */
-    protected $_cacheTag = 'cms_page';
+    protected $_cacheTag = self::CACHE_TAG;
 
     /**
      * Prefix of model events names
diff --git a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/DataProviderTest.php b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/DataProviderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..70fef18f3a77d422765ce9fe420229f1fb10dafa
--- /dev/null
+++ b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/DataProviderTest.php
@@ -0,0 +1,135 @@
+<?php
+/***
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Cms\Test\Unit\Ui\Component\Listing;
+
+
+use Magento\Cms\Ui\Component\DataProvider;
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Authorization;
+use Magento\Framework\View\Element\UiComponent\DataProvider\Reporting;
+use Magento\Framework\Api\Search\SearchCriteriaBuilder;
+use Magento\Framework\App\RequestInterface;
+use Magento\Framework\Api\FilterBuilder;
+use Magento\Framework\ObjectManagerInterface;
+
+class DataProviderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\Authorization|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $authorizationMock;
+
+    /**
+     * @var \Magento\Framework\View\Element\UiComponent\DataProvider\Reporting|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $reportingMock;
+
+    /**
+     * @var \Magento\Framework\Api\Search\SearchCriteriaBuilder|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $searchCriteriaBuilderMock;
+
+    /**
+     * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $requestInterfaceMock;
+
+    /**
+     * @var \Magento\Framework\Api\FilterBuilder|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $filterBuilderMock;
+
+    /**
+     * @var \Magento\Cms\Ui\Component\DataProvider
+     */
+    private $dataProvider;
+
+    /**
+     * @var string
+     */
+    private $name = 'cms_page_listing_data_source';
+
+    /**
+     * @var string
+     */
+    private $primaryFieldName = 'page';
+
+    /**
+     * @var string
+     */
+    private $requestFieldName = 'id';
+
+    public function setUp()
+    {
+        $this->authorizationMock = $this->getMockBuilder(Authorization::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->reportingMock = $this->getMockBuilder(Reporting::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->searchCriteriaBuilderMock = $this->getMockBuilder(SearchCriteriaBuilder::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->requestInterfaceMock = $this->getMockBuilder(RequestInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->filterBuilderMock = $this->getMockBuilder(FilterBuilder::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        /** @var ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject $objectManagerMock */
+        $objectManagerMock = $this->getMock(ObjectManagerInterface::class);
+        $objectManagerMock->expects($this->once())
+            ->method('get')
+            ->willReturn($this->authorizationMock);
+        ObjectManager::setInstance($objectManagerMock);
+
+        $this->dataProvider = new DataProvider(
+            $this->name,
+            $this->primaryFieldName,
+            $this->requestFieldName,
+            $this->reportingMock,
+            $this->searchCriteriaBuilderMock,
+            $this->requestInterfaceMock,
+            $this->filterBuilderMock
+        );
+    }
+
+    /**
+     * @covers \Magento\Cms\Ui\Component\DataProvider::prepareMetadata
+     */
+    public function testPrepareMetadata()
+    {
+        $this->authorizationMock->expects($this->once())
+            ->method('isAllowed')
+            ->with('Magento_Cms::save')
+            ->willReturn(false);
+
+        $metadata = [
+            'cms_page_columns' => [
+                'arguments' => [
+                    'data' => [
+                        'config' => [
+                            'editorConfig' => [
+                                'enabled' => false
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ];
+
+        $this->assertEquals(
+            $metadata,
+            $this->dataProvider->prepareMetadata()
+        );
+
+    }
+}
diff --git a/app/code/Magento/Cms/Ui/Component/DataProvider.php b/app/code/Magento/Cms/Ui/Component/DataProvider.php
index 53ba80e6ccb7367986b8540e4452282e2cee7475..85b00d341fad8980271408644e7088534b7f549d 100644
--- a/app/code/Magento/Cms/Ui/Component/DataProvider.php
+++ b/app/code/Magento/Cms/Ui/Component/DataProvider.php
@@ -7,11 +7,18 @@ namespace Magento\Cms\Ui\Component;
 
 use Magento\Framework\Api\FilterBuilder;
 use Magento\Framework\Api\Search\SearchCriteriaBuilder;
+use Magento\Framework\App\ObjectManager;
 use Magento\Framework\App\RequestInterface;
+use Magento\Framework\AuthorizationInterface;
 use Magento\Framework\View\Element\UiComponent\DataProvider\Reporting;
 
 class DataProvider extends \Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider
 {
+    /**
+     * @var AuthorizationInterface
+     */
+    private $authorization;
+
     /**
      * @param string $name
      * @param string $primaryFieldName
@@ -45,5 +52,47 @@ class DataProvider extends \Magento\Framework\View\Element\UiComponent\DataProvi
             $meta,
             $data
         );
+
+        $this->meta = array_replace_recursive($meta, $this->prepareMetadata());
+    }
+
+    /**
+     * @deprecated
+     * @return AuthorizationInterface|mixed
+     */
+    private function getAuthorizationInstance()
+    {
+        if ($this->authorization === null) {
+            $this->authorization = ObjectManager::getInstance()->get(AuthorizationInterface::class);
+        }
+        return $this->authorization;
+    }
+
+    /**
+     * Prepares Meta
+     *
+     * @return array
+     */
+    public function prepareMetadata()
+    {
+        $metadata = [];
+
+        if (!$this->getAuthorizationInstance()->isAllowed('Magento_Cms::save')) {
+            $metadata = [
+                'cms_page_columns' => [
+                    'arguments' => [
+                        'data' => [
+                            'config' => [
+                                'editorConfig' => [
+                                    'enabled' => false
+                                ]
+                            ]
+                        ]
+                    ]
+                ]
+            ];
+        }
+
+        return $metadata;
     }
 }
diff --git a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml
index 8d9aea7bb20c5b9e49241a75b15ae83f9142929a..6a29cb1497175d418723af26a041c6bb80a990f8 100644
--- a/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml
+++ b/app/code/Magento/Cms/view/adminhtml/templates/browser/content/uploader.phtml
@@ -29,7 +29,8 @@ require([
     'jquery',
     'mage/template',
     'jquery/file-uploader',
-    'domReady!'
+    'domReady!',
+    'mage/translate'
 ], function ($, mageTemplate) {
     $('#<?php echo $block->getHtmlId() ?> .fileupload').fileupload({
         dataType: 'json',
diff --git a/app/code/Magento/ConfigurableProduct/Model/LinkManagement.php b/app/code/Magento/ConfigurableProduct/Model/LinkManagement.php
index cd205746a9bcecfdda9326667d2611e4cd23b55a..0fdfbd3bfa172ee597414ed3ab4c46bbac2a9549 100644
--- a/app/code/Magento/ConfigurableProduct/Model/LinkManagement.php
+++ b/app/code/Magento/ConfigurableProduct/Model/LinkManagement.php
@@ -103,7 +103,7 @@ class LinkManagement implements \Magento\ConfigurableProduct\Api\LinkManagementI
         }
 
         $childrenIds[] = $child->getId();
-        $product->setAssociatedProductIds($childrenIds);
+        $product->getExtensionAttributes()->setConfigurableProductLinks($childrenIds);
         $product->save();
         return true;
     }
@@ -132,7 +132,7 @@ class LinkManagement implements \Magento\ConfigurableProduct\Api\LinkManagementI
         if (count($options) == count($ids)) {
             throw new NoSuchEntityException(__('Requested option doesn\'t exist'));
         }
-        $product->addData(['associated_product_ids' => $ids]);
+        $product->getExtensionAttributes()->setConfigurableProductLinks($ids);
         $product->save();
         return true;
     }
diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Cache/Tag/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Product/Cache/Tag/Configurable.php
new file mode 100644
index 0000000000000000000000000000000000000000..2059eee2b1f34d2008c1201c04fa3857ed35dcba
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Model/Product/Cache/Tag/Configurable.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\ConfigurableProduct\Model\Product\Cache\Tag;
+
+use Magento\Framework\App\Cache\Tag\StrategyInterface;
+
+/**
+ * Add parent invalidation tags
+ */
+class Configurable implements StrategyInterface
+{
+    /**
+     *  Configurable product type resource
+     *
+     * @var \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable
+     */
+    private $catalogProductTypeConfigurable;
+
+    /**
+     * @param \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable $catalogProductTypeConfigurable
+     */
+    public function __construct(
+        \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable $catalogProductTypeConfigurable
+    ) {
+        $this->catalogProductTypeConfigurable = $catalogProductTypeConfigurable;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getTags($object)
+    {
+        if (!is_object($object)) {
+            throw new \InvalidArgumentException('Provided argument is not an object');
+        }
+
+        if (!($object instanceof \Magento\Catalog\Model\Product)) {
+            throw new \InvalidArgumentException('Provided argument must be a product');
+        }
+
+        $result = $object->getIdentities();
+
+        foreach ($this->catalogProductTypeConfigurable->getParentIdsByChild($object->getId()) as $parentId) {
+            $result[] = \Magento\Catalog\Model\Product::CACHE_TAG . '_' . $parentId;
+        }
+        return $result;
+    }
+}
diff --git a/app/code/Magento/ConfigurableProduct/Plugin/Model/Product.php b/app/code/Magento/ConfigurableProduct/Plugin/Model/Product.php
deleted file mode 100644
index 41ab66aecfd4a3c53bc87fa65b896486284703c7..0000000000000000000000000000000000000000
--- a/app/code/Magento/ConfigurableProduct/Plugin/Model/Product.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-/**
- *
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\ConfigurableProduct\Plugin\Model;
-
-use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
-
-/**
- * Plugin for Product Identity
- */
-class Product
-{
-    /**
-     * Add identity of child product to identities
-     *
-     * @param \Magento\Catalog\Model\Product $product
-     * @param string[] $result
-     * @return string[]
-     */
-    public function afterGetIdentities(\Magento\Catalog\Model\Product $product, $result)
-    {
-        /** @var Configurable $productType */
-        $productType = $product->getTypeInstance();
-        if ($productType instanceof Configurable) {
-            foreach ($productType->getChildrenIds($product->getId())[0] as $productId) {
-                $result[] = \Magento\Catalog\Model\Product::CACHE_TAG . '_' . $productId;
-            }
-        }
-        return $result;
-    }
-}
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php
index 84d3ac72c187e99201410958cad6102ed4fce168..6b69888e6dd0924cf6e090bdb1eb0af2daddaab1 100644
--- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/LinkManagementTest.php
@@ -7,6 +7,7 @@
 namespace Magento\ConfigurableProduct\Test\Unit\Model;
 
 use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
+use Magento\ConfigurableProduct\Test\Unit\Model\Product\ProductExtensionAttributes;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -162,7 +163,15 @@ class LinkManagementTest extends \PHPUnit_Framework_TestCase
             ->will(
                 $this->returnValue([0 => [1, 2, 3]])
             );
-        $configurable->expects($this->once())->method('__call')->with('setAssociatedProductIds', [[1, 2, 3, 999]]);
+
+        $extensionAttributes = $this->getMockBuilder(ProductExtensionAttributes::class)
+            ->setMethods(['setConfigurableProductLinks'])
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+
+        $configurable->expects($this->once())->method('getExtensionAttributes')->willReturn($extensionAttributes);
+        $extensionAttributes->expects($this->once())->method('setConfigurableProductLinks')->willReturnSelf();
+
         $configurable->expects($this->once())->method('save');
 
         $this->assertTrue(true, $this->object->addChild($productSku, $childSku));
@@ -206,7 +215,7 @@ class LinkManagementTest extends \PHPUnit_Framework_TestCase
         $childSku = 'simple_10';
 
         $product = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
-            ->setMethods(['getTypeInstance', 'save', 'getTypeId', 'addData', '__wakeup'])
+            ->setMethods(['getTypeInstance', 'save', 'getTypeId', 'addData', '__wakeup', 'getExtensionAttributes'])
             ->disableOriginalConstructor()
             ->getMock();
 
@@ -234,7 +243,14 @@ class LinkManagementTest extends \PHPUnit_Framework_TestCase
         $productType->expects($this->once())->method('getUsedProducts')
             ->will($this->returnValue([$option]));
 
-        $product->expects($this->once())->method('addData')->with(['associated_product_ids' => []]);
+        $extensionAttributes = $this->getMockBuilder(ProductExtensionAttributes::class)
+            ->setMethods(['setConfigurableProductLinks'])
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+
+        $product->expects($this->once())->method('getExtensionAttributes')->willReturn($extensionAttributes);
+        $extensionAttributes->expects($this->once())->method('setConfigurableProductLinks')->willReturnSelf();
+
         $product->expects($this->once())->method('save');
         $this->assertTrue($this->object->removeChild($productSku, $childSku));
     }
diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Cache/Tag/ConfigurableTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Cache/Tag/ConfigurableTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..5251f470071bc628a50afdbfd141f4719621dc9f
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Cache/Tag/ConfigurableTest.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\ConfigurableProduct\Test\Unit\Model\Product\Cache\Tag;
+
+use \Magento\ConfigurableProduct\Model\Product\Cache\Tag\Configurable;
+
+class ConfigurableTest extends \PHPUnit_Framework_TestCase
+{
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|Configurable
+     */
+    private $typeResource;
+
+    /**
+     * @var Configurable
+     */
+    private $model;
+
+    protected function setUp()
+    {
+        $this->typeResource = $this->getMock(
+            \Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable::class,
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->model = new Configurable($this->typeResource);
+    }
+
+    public function testGetWithScalar()
+    {
+        $this->setExpectedException(\InvalidArgumentException::class, 'Provided argument is not an object');
+        $this->model->getTags('scalar');
+    }
+
+    public function testGetTagsWithObject()
+    {
+        $this->setExpectedException(\InvalidArgumentException::class, 'Provided argument must be a product');
+        $this->model->getTags(new \StdClass);
+    }
+
+    public function testGetTagsWithVariation()
+    {
+        $product = $this->getMock(\Magento\Catalog\Model\Product::class, [], [], '', false);
+
+        $identities = ['id1', 'id2'];
+
+        $product->expects($this->once())
+            ->method('getIdentities')
+            ->willReturn($identities);
+
+        $parentId = 4;
+        $this->typeResource->expects($this->once())
+            ->method('getParentIdsByChild')
+            ->willReturn([$parentId]);
+
+        $expected = array_merge($identities, [\Magento\Catalog\Model\Product::CACHE_TAG . '_' . $parentId]);
+
+        $this->assertEquals($expected, $this->model->getTags($product));
+    }
+}
diff --git a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php
index da7a0d7a3d9da28be96d39ff22b0bc115d77293c..ac1b8b981ea3d1bfeeed5e7ba499463e88053741 100644
--- a/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php
+++ b/app/code/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProducts.php
@@ -284,7 +284,7 @@ class AssociatedProducts
                         'sku' => $product->getSku(),
                         'name' => $product->getName(),
                         'qty' => $this->getProductStockQty($product),
-                        'price' => $currency->toCurrency(sprintf("%f", $price), ['display' => false]),
+                        'price' => $price,
                         'price_string' => $currency->toCurrency(sprintf("%f", $price)),
                         'price_currency' => $this->locator->getStore()->getBaseCurrency()->getCurrencySymbol(),
                         'configurable_attribute' => $this->getJsonConfigurableAttributes($variationOptions),
diff --git a/app/code/Magento/ConfigurableProduct/etc/di.xml b/app/code/Magento/ConfigurableProduct/etc/di.xml
index c3be4aaea189a63edb9091df2712d063eb8e09e1..89b271de838f992e9acd93ecdd27bc321f59d54e 100644
--- a/app/code/Magento/ConfigurableProduct/etc/di.xml
+++ b/app/code/Magento/ConfigurableProduct/etc/di.xml
@@ -61,9 +61,6 @@
     <type name="Magento\Catalog\Api\ProductRepositoryInterface">
         <plugin name="configurableProductSaveOptions" sortOrder="10" type="Magento\ConfigurableProduct\Model\Plugin\ProductRepositorySave"/>
     </type>
-    <type name="Magento\Catalog\Model\Product">
-        <plugin name="configurable_identity" type="Magento\ConfigurableProduct\Plugin\Model\Product" />
-    </type>
     <type name="Magento\Catalog\Model\Product\Type">
         <plugin name="configurable_output" type="Magento\ConfigurableProduct\Model\Product\Type\Plugin" />
     </type>
@@ -160,4 +157,11 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Framework\App\Cache\Tag\Strategy\Factory">
+        <arguments>
+            <argument name="customStrategies" xsi:type="array">
+                <item name="Magento\Catalog\Api\Data\ProductInterface" xsi:type="object">\Magento\ConfigurableProduct\Model\Product\Cache\Tag\Configurable</item>
+            </argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/product-grid.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/product-grid.js
index 4d1867669ade0957c15d26b355f5415b1e6050e7..7d574a32498d07a511e36b2928ae53ee752b167e 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/product-grid.js
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/product-grid.js
@@ -8,7 +8,8 @@ define([
     'jquery',
     'Magento_Ui/js/core/app',
     'underscore',
-    'notification'
+    'notification',
+    'mage/translate'
 ], function (Component, $, bootstrap, _) {
     'use strict';
 
@@ -221,9 +222,7 @@ define([
 
             if (data.items.length) {
                 this.productsModal.notification('add', {
-                    message: $.mage.__(
-                        'Choose a new product to delete and replace the current product configuration.'
-                    ),
+                    message: $.mage.__('Choose a new product to delete and replace the current product configuration.'),
                     messageContainer: this.gridSelector
                 });
             } else {
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/select_attributes.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/select_attributes.js
index 3653e91894c29e5b650fe357e7a1a73a9f50403b..994fbf25e3b0faf3995ca97f8a0e5ad0eab3326c 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/select_attributes.js
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/select_attributes.js
@@ -51,9 +51,13 @@ define([
             this.setNotificationMessage();
         },
         setNotificationMessage: function () {
+            /*eslint-disable max-len*/
+            var msg = $.mage.__('When you remove or add an attribute, we automatically update all configurations and you will need to recreate current configurations manually.');
+
+            /*eslint-enable max-len*/
+
             if (this.mode === 'edit') {
-                this.wizard.setNotificationMessage($.mage.__('When you remove or add an attribute, we automatically ' +
-                'update all configurations and you will need to recreate current configurations manually.'));
+                this.wizard.setNotificationMessage(msg);
             }
         },
         doSelectSavedAttributes: function () {
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php
index 45d31dc0e2764c4c41888a23ef0bb7f99836fed3..3c3fa73087e4a17a4c883b370c3a3fd44f7ad645 100644
--- a/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php
@@ -6,6 +6,7 @@
 namespace Magento\Customer\Controller\Adminhtml\Index;
 
 use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Framework\Exception\SecurityViolationException;
 
 class ResetPassword extends \Magento\Customer\Controller\Adminhtml\Index
 {
@@ -40,6 +41,8 @@ class ResetPassword extends \Magento\Customer\Controller\Adminhtml\Index
                 $messages = $exception->getMessage();
             }
             $this->_addSessionErrorMessages($messages);
+        } catch (SecurityViolationException $exception) {
+            $this->messageManager->addErrorMessage($exception->getMessage());
         } catch (\Exception $exception) {
             $this->messageManager->addException(
                 $exception,
diff --git a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/ResetPasswordTest.php b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/ResetPasswordTest.php
index b7295fb9ceb4f19dd29fa8fe148552ebb20648e6..44444935973d43e9424242a9931b93121f314bae 100644
--- a/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/ResetPasswordTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/ResetPasswordTest.php
@@ -143,7 +143,7 @@ class ResetPasswordTest extends \PHPUnit_Framework_TestCase
         $this->messageManager = $this->getMockBuilder(
             \Magento\Framework\Message\Manager::class
         )->disableOriginalConstructor()->setMethods(
-            ['addSuccess', 'addMessage', 'addException']
+            ['addSuccess', 'addMessage', 'addException', 'addErrorMessage']
         )->getMock();
 
         $this->resultRedirectFactoryMock = $this->getMockBuilder(
@@ -332,6 +332,56 @@ class ResetPasswordTest extends \PHPUnit_Framework_TestCase
         $this->_testedObject->execute();
     }
 
+    public function testResetPasswordActionSecurityException()
+    {
+        $securityText = 'Security violation.';
+        $exception = new \Magento\Framework\Exception\SecurityViolationException(__($securityText));
+        $customerId = 1;
+        $email = 'some@example.com';
+        $websiteId = 1;
+
+        $this->_request->expects(
+            $this->once()
+        )->method(
+            'getParam'
+        )->with(
+            $this->equalTo('customer_id'),
+            $this->equalTo(0)
+        )->will(
+            $this->returnValue($customerId)
+        );
+        $customer = $this->getMockForAbstractClass(
+            \Magento\Customer\Api\Data\CustomerInterface::class,
+            ['getId', 'getEmail', 'getWebsiteId']
+        );
+        $customer->expects($this->once())->method('getEmail')->will($this->returnValue($email));
+        $customer->expects($this->once())->method('getWebsiteId')->will($this->returnValue($websiteId));
+        $this->_customerRepositoryMock->expects(
+            $this->once()
+        )->method(
+            'getById'
+        )->with(
+            $customerId
+        )->will(
+            $this->returnValue($customer)
+        );
+        $this->_customerAccountManagementMock->expects(
+            $this->once()
+        )->method(
+            'initiatePasswordReset'
+        )->willThrowException($exception);
+
+        $this->messageManager->expects(
+            $this->once()
+        )->method(
+            'addErrorMessage'
+        )->with(
+            $this->equalTo($exception->getMessage())
+        );
+
+        $this->_testedObject->execute();
+    }
+
     public function testResetPasswordActionCoreExceptionWarn()
     {
         $warningText = 'Warning';
diff --git a/app/code/Magento/Customer/Test/Unit/Model/Address/AbstractAddressTest.php b/app/code/Magento/Customer/Test/Unit/Model/Address/AbstractAddressTest.php
index 4e0922721de5c2413619a06bf827651d0640b123..32112ccdeb1aec053955226a49eb1838f8c4276b 100644
--- a/app/code/Magento/Customer/Test/Unit/Model/Address/AbstractAddressTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Model/Address/AbstractAddressTest.php
@@ -245,15 +245,14 @@ class AbstractAddressTest extends \PHPUnit_Framework_TestCase
      */
     public function testSetDataWithMultidimensionalArray()
     {
-        $this->markTestSkipped('Need to revert changes from  MAGETWO-39106 and then modify this test.');
         $expected = [
             'key' => 'value',
-            'array' => 'value1',
+            'street' => 'value1',
         ];
 
         $key = [
             'key' => 'value',
-            'array' => [
+            'street' => [
                 'key1' => 'value1',
             ]
         ];
diff --git a/app/code/Magento/Customer/view/frontend/requirejs-config.js b/app/code/Magento/Customer/view/frontend/requirejs-config.js
index 53f12373bfd928a1fcea86ee50ba4038caf0cf6a..508737742cafe2e2cf9905571ae3655bba440ad5 100644
--- a/app/code/Magento/Customer/view/frontend/requirejs-config.js
+++ b/app/code/Magento/Customer/view/frontend/requirejs-config.js
@@ -10,7 +10,8 @@ var config = {
             address:            'Magento_Customer/address',
             changeEmailPassword: 'Magento_Customer/change-email-password',
             passwordStrengthIndicator: 'Magento_Customer/js/password-strength-indicator',
-            zxcvbn: 'Magento_Customer/js/zxcvbn'
+            zxcvbn: 'Magento_Customer/js/zxcvbn',
+            addressValidation: 'Magento_Customer/js/addressValidation'
         }
     }
 };
diff --git a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml
index 2de971bf6a9c05d1c07cb5745272fcad7a135e23..17d7c9852fc4b5e0efa4ba8342a9bcff0d97d805 100644
--- a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml
+++ b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml
@@ -203,7 +203,7 @@
 <script type="text/x-magento-init">
     {
         "#form-validate": {
-            "validation": {}
+            "addressValidation": {}
         },
         "#country": {
             "regionUpdater": {
diff --git a/app/code/Magento/Customer/view/frontend/web/js/addressValidation.js b/app/code/Magento/Customer/view/frontend/web/js/addressValidation.js
new file mode 100644
index 0000000000000000000000000000000000000000..c01463b4046aebc4277fcaf6d8765d1d7a785893
--- /dev/null
+++ b/app/code/Magento/Customer/view/frontend/web/js/addressValidation.js
@@ -0,0 +1,43 @@
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+define([
+    'jquery',
+    'jquery/ui',
+    'validation'
+], function ($) {
+    'use strict';
+
+    $.widget('mage.addressValidation', {
+        options: {
+            selectors: {
+                button: '[data-action=save-address]'
+            }
+        },
+
+        /**
+         * Validation creation
+         * @protected
+         */
+        _create: function () {
+            var button = $(this.options.selectors.button, this.element);
+
+            this.element.validation({
+
+                /**
+                 * Submit Handler
+                 * @param {Element} form - address form
+                 */
+                submitHandler: function (form) {
+
+                    button.attr('disabled', true);
+                    form.submit();
+                }
+            });
+        }
+    });
+
+    return $.mage.addressValidation;
+});
diff --git a/app/code/Magento/CustomerImportExport/Model/Import/Customer.php b/app/code/Magento/CustomerImportExport/Model/Import/Customer.php
index 4c0517c37bb4413395acced8929855e592c9fdb4..2035b663e07e974ca7c26aebd070d81a8110ae3d 100644
--- a/app/code/Magento/CustomerImportExport/Model/Import/Customer.php
+++ b/app/code/Magento/CustomerImportExport/Model/Import/Customer.php
@@ -370,10 +370,6 @@ class Customer extends AbstractCustomer
 
         // attribute values
         foreach (array_intersect_key($rowData, $this->_attributes) as $attributeCode => $value) {
-            if ($newCustomer && !strlen($value)) {
-                continue;
-            }
-
             $attributeParameters = $this->_attributes[$attributeCode];
             if ('select' == $attributeParameters['type']) {
                 $value = isset($attributeParameters['options'][strtolower($value)])
diff --git a/app/code/Magento/Deploy/Console/Command/SetModeCommand.php b/app/code/Magento/Deploy/Console/Command/SetModeCommand.php
index f8c5cde9b942aa62f7fe85ea0567b206137bf12f..51509bdc85d8287b2f9cfffa0f534816960e9370 100644
--- a/app/code/Magento/Deploy/Console/Command/SetModeCommand.php
+++ b/app/code/Magento/Deploy/Console/Command/SetModeCommand.php
@@ -104,6 +104,8 @@ class SetModeCommand extends Command
                     throw new LocalizedException(__('Cannot switch into given mode "%1"', $toMode));
             }
             $output->writeln('Enabled ' . $toMode . ' mode.');
+            
+            return \Magento\Framework\Console\Cli::RETURN_SUCCESS;
         } catch (\Exception $e) {
             $output->writeln('<error>' . $e->getMessage() . '</error>');
             if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
diff --git a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/links.phtml b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/links.phtml
index 2fe4a23944694653bad0491c24c36b6fc9424a1f..d4fe3ec72a0731833651254824d4ba71f44bb62b 100644
--- a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/links.phtml
+++ b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/links.phtml
@@ -104,7 +104,8 @@ require([
     'mage/template',
     'jquery/file-uploader',
     'mage/mage',
-    'prototype'
+    'prototype',
+    'mage/translate'
 ], function(jQuery, registry, mageTemplate){
     registry.get('downloadable', function (Downloadable) {
         var linkTemplate = '<tr>'+
diff --git a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/samples.phtml b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/samples.phtml
index 699bfce3acd1a2fc6c21437a1b1e37224772243e..510a3d3fcc8d78ce0848d579d0590db6764ba4b7 100644
--- a/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/samples.phtml
+++ b/app/code/Magento/Downloadable/view/adminhtml/templates/product/edit/downloadable/samples.phtml
@@ -63,7 +63,8 @@ require([
     'uiRegistry',
     'mage/template',
     'jquery/file-uploader',
-    'prototype'
+    'prototype',
+    'mage/translate'
 ], function (jQuery, registry, mageTemplate) {
     registry.get('downloadable', function (Downloadable) {
         var sampleTemplate = '<tr>'+
diff --git a/lib/internal/Magento/Framework/EntityManager/CustomAttributesMapper.php b/app/code/Magento/Eav/Model/CustomAttributesMapper.php
similarity index 96%
rename from lib/internal/Magento/Framework/EntityManager/CustomAttributesMapper.php
rename to app/code/Magento/Eav/Model/CustomAttributesMapper.php
index fe3a199da86a32bdb866894b53831fe4c5e8a246..51b9277714278bca92ef3fbf7ad31b112b0237e0 100644
--- a/lib/internal/Magento/Framework/EntityManager/CustomAttributesMapper.php
+++ b/app/code/Magento/Eav/Model/CustomAttributesMapper.php
@@ -3,12 +3,15 @@
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\Framework\EntityManager;
+namespace Magento\Eav\Model;
+
 
 use Magento\Framework\Api\AttributeInterface;
 use Magento\Framework\Api\CustomAttributesDataInterface;
 use Magento\Eav\Api\AttributeRepositoryInterface;
 use Magento\Framework\Api\SearchCriteriaBuilder;
+use Magento\Framework\EntityManager\MapperInterface;
+use Magento\Framework\EntityManager\MetadataPool;
 
 /**
  * Class CustomAttributesMapper
diff --git a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php
index c3e5a4b0c4d462b2f7e6576e7c8666e71b18be58..878ddf812028825267297aac958c22c14070f7b9 100644
--- a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php
+++ b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php
@@ -950,6 +950,7 @@ abstract class AbstractEntity extends AbstractResource implements EntityInterfac
         /**
          * Load object base row data
          */
+        $object->beforeLoad($entityId);
         $select = $this->_getLoadRowSelect($object, $entityId);
         $row = $this->getConnection()->fetchRow($select);
 
@@ -962,11 +963,10 @@ abstract class AbstractEntity extends AbstractResource implements EntityInterfac
         $this->loadAttributesMetadata($attributes);
 
         $this->_loadModelAttributes($object);
-
-        $object->setOrigData();
-
         $this->_afterLoad($object);
-
+        $object->afterLoad();
+        $object->setOrigData();
+        $object->setHasDataChanges(false);
         \Magento\Framework\Profiler::stop('EAV:load_entity');
         return $this;
     }
diff --git a/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php b/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php
index 19f332da4c5667cd64c0cc596121a84532e5e363..ab269e8f1f7757e06df4e7fe4f990bc06785f9b5 100644
--- a/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php
+++ b/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute.php
@@ -464,7 +464,8 @@ class Attribute extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
     {
         $connection = $this->getConnection();
         $table = $this->getTable('eav_attribute_option');
-        $intOptionId = (int)$optionId;
+        // ignore strings that start with a number
+        $intOptionId = is_numeric($optionId) ? (int)$optionId : 0;
 
         if (!empty($option['delete'][$optionId])) {
             if ($intOptionId) {
diff --git a/app/code/Magento/Eav/Model/ResourceModel/ReadHandler.php b/app/code/Magento/Eav/Model/ResourceModel/ReadHandler.php
index 6b32cc77188e8542ef31f8527c0f93a65dd14c64..723d05b92c5129f8d912acc133134bd38d789219 100644
--- a/app/code/Magento/Eav/Model/ResourceModel/ReadHandler.php
+++ b/app/code/Magento/Eav/Model/ResourceModel/ReadHandler.php
@@ -13,6 +13,7 @@ use Magento\Framework\Model\Entity\ScopeResolver;
 use Magento\Framework\Model\Entity\ScopeInterface;
 use Magento\Framework\EntityManager\Operation\AttributeInterface;
 use Magento\Eav\Model\Entity\AttributeCache;
+use Psr\Log\LoggerInterface;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -49,6 +50,11 @@ class ReadHandler implements AttributeInterface
      */
     protected $scopeResolver;
 
+    /**
+     * @var LoggerInterface
+     */
+    private $logger;
+
     /**
      * ReadHandler constructor.
      *
@@ -58,6 +64,7 @@ class ReadHandler implements AttributeInterface
      * @param AppResource $appResource
      * @param ScopeResolver $scopeResolver
      * @param AttributeCache $attributeCache
+     * @param LoggerInterface $logger
      */
     public function __construct(
         AttributeRepository $attributeRepository,
@@ -65,7 +72,8 @@ class ReadHandler implements AttributeInterface
         SearchCriteriaBuilder $searchCriteriaBuilder,
         AppResource $appResource,
         ScopeResolver $scopeResolver,
-        AttributeCache $attributeCache
+        AttributeCache $attributeCache,
+        LoggerInterface $logger
     ) {
         $this->attributeRepository = $attributeRepository;
         $this->metadataPool = $metadataPool;
@@ -73,6 +81,7 @@ class ReadHandler implements AttributeInterface
         $this->appResource = $appResource;
         $this->scopeResolver = $scopeResolver;
         $this->attributeCache = $attributeCache;
+        $this->logger = $logger;
     }
 
     /**
@@ -163,7 +172,14 @@ class ReadHandler implements AttributeInterface
                 \Magento\Framework\DB\Select::SQL_UNION_ALL
             );
             foreach ($connection->fetchAll($unionSelect) as $attributeValue) {
-                $entityData[$attributesMap[$attributeValue['attribute_id']]] = $attributeValue['value'];
+                if (isset($attributesMap[$attributeValue['attribute_id']])) {
+                    $entityData[$attributesMap[$attributeValue['attribute_id']]] = $attributeValue['value'];
+                } else {
+                    $this->logger->warning(
+                        "Attempt to load value of nonexistent EAV attribute '{$attributeValue['attribute_id']}' 
+                        for entity type '$entityType'."
+                    );
+                }
             }
         }
         return $entityData;
diff --git a/lib/internal/Magento/Framework/EntityManager/Test/Unit/CustomAttributesMapperTest.php b/app/code/Magento/Eav/Test/Unit/Model/CustomAttributesMapperTest.php
similarity index 88%
rename from lib/internal/Magento/Framework/EntityManager/Test/Unit/CustomAttributesMapperTest.php
rename to app/code/Magento/Eav/Test/Unit/Model/CustomAttributesMapperTest.php
index 56977af1dd6eb5c62872572ec22f2024f7479223..f7e98f751497a8dde96c404cfa61951e41f5b99b 100644
--- a/lib/internal/Magento/Framework/EntityManager/Test/Unit/CustomAttributesMapperTest.php
+++ b/app/code/Magento/Eav/Test/Unit/Model/CustomAttributesMapperTest.php
@@ -3,10 +3,11 @@
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\Framework\EntityManager\Test\Unit;
-
-use Magento\Framework\App\ResourceConnection;
+namespace Magento\Eav\Test\Unit\Model;
 
+/**
+ * Class CustomAttributesMapperTest
+ */
 class CustomAttributesMapperTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -55,7 +56,7 @@ class CustomAttributesMapperTest extends \PHPUnit_Framework_TestCase
             ->willReturn(true);
         $metadataPool->expects($this->any())
             ->method('getMetadata')
-            ->with($this->equalTo(\Magento\Customer\Api\Data\AddressInterface::class))
+            ->with($this->equalTo(\Magento\Framework\Api\CustomAttributesDataInterface::class))
             ->will($this->returnValue($metadata));
         $metadataPool->expects($this->once())
             ->method('hasConfiguration')
@@ -75,16 +76,16 @@ class CustomAttributesMapperTest extends \PHPUnit_Framework_TestCase
             ->method('create')
             ->will($this->returnValue($searchCriteria));
 
-        /** @var \Magento\Framework\EntityManager\CustomAttributesMapper $customAttributesMapper */
+        /** @var \Magento\Eav\Model\CustomAttributesMapper $customAttributesMapper */
         $customAttributesMapper = $this->objectManager
-            ->getObject(\Magento\Framework\EntityManager\CustomAttributesMapper::class, [
+            ->getObject(\Magento\Eav\Model\CustomAttributesMapper::class, [
                 'attributeRepository' => $attributeRepository,
                 'metadataPool' => $metadataPool,
                 'searchCriteriaBuilder' => $searchCriteriaBuilder
             ]);
 
         $actual = $customAttributesMapper->entityToDatabase(
-            \Magento\Customer\Api\Data\AddressInterface::class,
+            \Magento\Framework\Api\CustomAttributesDataInterface::class,
             [
                 \Magento\Framework\Api\CustomAttributesDataInterface::CUSTOM_ATTRIBUTES => [
                     'test' => [
@@ -151,7 +152,7 @@ class CustomAttributesMapperTest extends \PHPUnit_Framework_TestCase
             ->getMock();
         $metadataPool->expects($this->any())
             ->method('getMetadata')
-            ->with($this->equalTo(\Magento\Customer\Api\Data\AddressInterface::class))
+            ->with($this->equalTo(\Magento\Framework\Api\CustomAttributesDataInterface::class))
             ->will($this->returnValue($metadata));
 
         $searchCriteriaBuilder = $this->getMockBuilder(\Magento\Framework\Api\SearchCriteriaBuilder::class)
@@ -168,15 +169,15 @@ class CustomAttributesMapperTest extends \PHPUnit_Framework_TestCase
             ->method('create')
             ->will($this->returnValue($searchCriteria));
 
-        /** @var \Magento\Framework\EntityManager\CustomAttributesMapper $customAttributesMapper */
+        /** @var \Magento\Eav\Model\CustomAttributesMapper $customAttributesMapper */
         $customAttributesMapper = $this->objectManager
-            ->getObject(\Magento\Framework\EntityManager\CustomAttributesMapper::class, [
+            ->getObject(\Magento\Eav\Model\CustomAttributesMapper::class, [
                 'attributeRepository' => $attributeRepository,
                 'metadataPool' => $metadataPool,
                 'searchCriteriaBuilder' => $searchCriteriaBuilder
             ]);
         $actual = $customAttributesMapper->databaseToEntity(
-            \Magento\Customer\Api\Data\AddressInterface::class,
+            \Magento\Framework\Api\CustomAttributesDataInterface::class,
             [
                 'test' => 'test',
                 'test4' => 'test4',
@@ -200,10 +201,10 @@ class CustomAttributesMapperTest extends \PHPUnit_Framework_TestCase
     private function getAttributes()
     {
         /* Attribute with the code we want to copy */
-        $attribute = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class)
+        $attribute = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class)
             ->disableOriginalConstructor()
             ->setMethods(['isStatic', 'getAttributeCode'])
-            ->getMock();
+            ->getMockForAbstractClass();
         $attribute->expects($this->any())
             ->method('isStatic')
             ->will($this->returnValue(false));
@@ -212,10 +213,10 @@ class CustomAttributesMapperTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue('test'));
 
         /* Attribute with the code we don't want to copy */
-        $attribute1 = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class)
+        $attribute1 = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class)
             ->disableOriginalConstructor()
             ->setMethods(['isStatic', 'getAttributeCode'])
-            ->getMock();
+            ->getMockForAbstractClass();
         $attribute1->expects($this->any())
             ->method('isStatic')
             ->will($this->returnValue(false));
@@ -224,10 +225,10 @@ class CustomAttributesMapperTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue('test1'));
 
         /* Static attribute but with the code which exists in custom attributes */
-        $attribute2 = $this->getMockBuilder(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class)
+        $attribute2 = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class)
             ->disableOriginalConstructor()
             ->setMethods(['isStatic', 'getAttributeCode'])
-            ->getMock();
+            ->getMockForAbstractClass();
         $attribute2->expects($this->any())
             ->method('isStatic')
             ->will($this->returnValue(true));
diff --git a/app/code/Magento/Eav/etc/di.xml b/app/code/Magento/Eav/etc/di.xml
index 49d6753bc48da61320c1a209b82bdfd18bf834ce..0fcba9907cc4d46b76cf0b7e86c2e0e1bf61da5a 100644
--- a/app/code/Magento/Eav/etc/di.xml
+++ b/app/code/Magento/Eav/etc/di.xml
@@ -152,5 +152,13 @@
             <argument name="collectionProcessor" xsi:type="object">Magento\Eav\Model\Api\SearchCriteria\AttributeGroupCollectionProcessor</argument>
         </arguments>
     </type>
+    <type name="Magento\Framework\EntityManager\CompositeMapper">
+        <arguments>
+            <argument name="mappers" xsi:type="array">
+                <item name="mapper" xsi:type="object">Magento\Framework\EntityManager\Mapper</item>
+                <item name="customAttributesMapper" xsi:type="object">Magento\Eav\Model\CustomAttributesMapper</item>
+            </argument>
+        </arguments>
+    </type>
 </config>
 
diff --git a/app/code/Magento/Email/Model/AbstractTemplate.php b/app/code/Magento/Email/Model/AbstractTemplate.php
index 4ce6f0d90a6ccd129d03d16518522bef5fd097d3..e85ef27e13406df6273b2b89488c2d8c60ca7110 100644
--- a/app/code/Magento/Email/Model/AbstractTemplate.php
+++ b/app/code/Magento/Email/Model/AbstractTemplate.php
@@ -663,13 +663,13 @@ abstract class AbstractTemplate extends AbstractModel implements TemplateTypesIn
      * Save current design config and replace with design config from specified store
      * Event is not dispatched.
      *
-     * @param int|string $storeId
+     * @param null|bool|int|string $storeId
      * @param string $area
      * @return void
      */
     public function emulateDesign($storeId, $area = self::DEFAULT_DESIGN_AREA)
     {
-        if ($storeId) {
+        if ($storeId !== null && $storeId !== false) {
             // save current design settings
             $this->emulatedDesignConfig = clone $this->getDesignConfig();
             if (
diff --git a/app/code/Magento/Email/Model/Mail/TransportInterfacePlugin.php b/app/code/Magento/Email/Model/Mail/TransportInterfacePlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..02c1fee1b0745efbdee91e025f7b7c4d9b6f03b4
--- /dev/null
+++ b/app/code/Magento/Email/Model/Mail/TransportInterfacePlugin.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Email\Model\Mail;
+
+use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Framework\Exception\MailException;
+use Magento\Framework\Mail\TransportInterface;
+use Magento\Store\Model\ScopeInterface;
+
+class TransportInterfacePlugin
+{
+    /**
+     * Config path to mail sending setting that shows if email communications are disabled
+     */
+    const XML_PATH_SYSTEM_SMTP_DISABLE = 'system/smtp/disable';
+
+    /**
+     * @var ScopeConfigInterface
+     */
+    private $scopeConfig;
+
+    /**
+     * @param ScopeConfigInterface $scopeConfig
+     */
+    public function __construct(
+        ScopeConfigInterface $scopeConfig
+    ) {
+        $this->scopeConfig = $scopeConfig;
+    }
+
+    /**
+     * Omit email sending if disabled
+     *
+     * @param TransportInterface $subject
+     * @param \Closure $proceed
+     * @return void
+     * @throws MailException
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function aroundSendMessage(
+        TransportInterface $subject,
+        \Closure $proceed
+    ) {
+        if (!$this->scopeConfig->isSetFlag(self::XML_PATH_SYSTEM_SMTP_DISABLE, ScopeInterface::SCOPE_STORE)) {
+            $proceed();
+        }
+    }
+}
diff --git a/app/code/Magento/Email/Model/Template.php b/app/code/Magento/Email/Model/Template.php
index c281a08ab97b6bd153b77a0803b7d2c21792cc50..c42c4088793d7c429bf246bd3090731751e4ddff 100644
--- a/app/code/Magento/Email/Model/Template.php
+++ b/app/code/Magento/Email/Model/Template.php
@@ -5,26 +5,11 @@
  */
 namespace Magento\Email\Model;
 
-use Magento\Store\Model\ScopeInterface;
 use Magento\Store\Model\StoreManagerInterface;
 
 /**
  * Template model
  *
- * Example:
- *
- * // Loading of template
- * \Magento\Email\Model\TemplateFactory $templateFactory
- * $templateFactory->create()->load($this->_scopeConfig->getValue(
- *  'path_to_email_template_id_config',
- *  \Magento\Store\Model\ScopeInterface::SCOPE_STORE
- *  ));
- * $variables = array(
- *    'someObject' => $this->_coreResourceEmailTemplate
- *    'someString' => 'Some string value'
- * );
- * $emailTemplate->send('some@domain.com', 'Name Of User', $variables);
- *
  * @method \Magento\Email\Model\ResourceModel\Template _getResource()
  * @method \Magento\Email\Model\ResourceModel\Template getResource()
  * @method string getTemplateCode()
@@ -63,6 +48,8 @@ class Template extends AbstractTemplate implements \Magento\Framework\Mail\Templ
 
     /**
      * Config path to mail sending setting that shows if email communications are disabled
+     * @deprecated
+     * @see \Magento\Email\Model\Mail\TransportInterfacePlugin::XML_PATH_SYSTEM_SMTP_DISABLE
      */
     const XML_PATH_SYSTEM_SMTP_DISABLE = 'system/smtp/disable';
 
@@ -196,8 +183,7 @@ class Template extends AbstractTemplate implements \Magento\Framework\Mail\Templ
      */
     public function isValidForSend()
     {
-        return !$this->scopeConfig->isSetFlag(Template::XML_PATH_SYSTEM_SMTP_DISABLE, ScopeInterface::SCOPE_STORE)
-            && $this->getSenderName() && $this->getSenderEmail() && $this->getTemplateSubject();
+        return $this->getSenderName() && $this->getSenderEmail() && $this->getTemplateSubject();
     }
 
     /**
@@ -344,7 +330,8 @@ class Template extends AbstractTemplate implements \Magento\Framework\Mail\Templ
         if ($this->_getResource()->checkCodeUsage($this)) {
             throw new \Magento\Framework\Exception\MailException(__('Duplicate Of Template Name'));
         }
-        return parent::beforeSave();
+        parent::beforeSave();
+        return $this;
     }
 
     /**
diff --git a/app/code/Magento/Email/Test/Unit/Model/AbstractTemplateTest.php b/app/code/Magento/Email/Test/Unit/Model/AbstractTemplateTest.php
index 74ec2f98dd0e5779b9405c31c001eb08c1146d6d..761e293768cca50479424e5831f279e7826dcfaf 100644
--- a/app/code/Magento/Email/Test/Unit/Model/AbstractTemplateTest.php
+++ b/app/code/Magento/Email/Test/Unit/Model/AbstractTemplateTest.php
@@ -331,16 +331,24 @@ class AbstractTemplateTest extends \PHPUnit_Framework_TestCase
     {
         $model = $this->getModelMock();
         $originalConfig = ['area' => 'some_area', 'store' => 1];
-        $expectedConfig = ['area' => 'frontend', 'store' => 2];
         $model->setDesignConfig($originalConfig);
 
-        $model->emulateDesign(2);
-        // assert config data has been emulated
-        $this->assertEquals($expectedConfig, $model->getDesignConfig()->getData());
-
-        $model->revertDesign();
-        // assert config data has been reverted to the original state
-        $this->assertEquals($originalConfig, $model->getDesignConfig()->getData());
+        $expectedConfigs = [
+            ['in' => ['area' => 'frontend', 'store' => null], 'out' => $originalConfig],
+            ['in' => ['area' => 'frontend', 'store' => false], 'out' => $originalConfig],
+            ['in' => ['area' => 'frontend', 'store' => 0], 'out' => ['area' => 'frontend', 'store' => 0]],
+            ['in' => ['area' => 'frontend', 'store' => 1], 'out' => ['area' => 'frontend', 'store' => 1]],
+            ['in' => ['area' => 'frontend', 'store' => 2], 'out' => ['area' => 'frontend', 'store' => 2]],
+        ];
+        foreach ($expectedConfigs as $set) {
+            $model->emulateDesign($set['in']['store'], $set['in']['area']);
+            // assert config data has been emulated
+            $this->assertEquals($set['out'], $model->getDesignConfig()->getData());
+
+            $model->revertDesign();
+            // assert config data has been reverted to the original state
+            $this->assertEquals($originalConfig, $model->getDesignConfig()->getData());
+        }
     }
 
     public function testGetDesignConfig()
diff --git a/app/code/Magento/Email/Test/Unit/Model/TemplateTest.php b/app/code/Magento/Email/Test/Unit/Model/TemplateTest.php
index f2195a64220e25effc00550af98c93d21e5e0145..3ee95954c0a3af7d122d62631e77f94d54ad5dda 100644
--- a/app/code/Magento/Email/Test/Unit/Model/TemplateTest.php
+++ b/app/code/Magento/Email/Test/Unit/Model/TemplateTest.php
@@ -5,7 +5,6 @@
  */
 namespace Magento\Email\Test\Unit\Model;
 
-use Magento\Email\Model\Template\Filter;
 use Magento\Framework\App\Area;
 use Magento\Framework\App\Filesystem\DirectoryList;
 use Magento\Framework\App\TemplateTypesInterface;
@@ -426,18 +425,13 @@ class TemplateTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * @param $isSMTPDisabled bool
      * @param $senderName string
      * @param $senderEmail string
      * @param $templateSubject string
      * @dataProvider isValidForSendDataProvider
      */
-    public function testIsValidForSend($isSMTPDisabled, $senderName, $senderEmail, $templateSubject, $expectedValue)
+    public function testIsValidForSend($senderName, $senderEmail, $templateSubject, $expectedValue)
     {
-        $this->scopeConfig->expects($this->once())
-            ->method('isSetFlag')
-            ->with('system/smtp/disable', ScopeInterface::SCOPE_STORE)
-            ->will($this->returnValue($isSMTPDisabled));
         $model = $this->getModelMock(['getSenderName', 'getSenderEmail', 'getTemplateSubject']);
         $model->expects($this->any())
             ->method('getSenderName')
@@ -455,35 +449,24 @@ class TemplateTest extends \PHPUnit_Framework_TestCase
     {
         return [
             'should be valid' => [
-                'isSMTPDisabled' => false,
                 'senderName' => 'sender name',
                 'senderEmail' => 'email@example.com',
                 'templateSubject' => 'template subject',
                 'expectedValue' => true
             ],
-            'no smtp so not valid' => [
-                'isSMTPDisabled' => true,
-                'senderName' => 'sender name',
-                'senderEmail' => 'email@example.com',
-                'templateSubject' => 'template subject',
-                'expectedValue' => false
-            ],
             'no sender name so not valid' => [
-                'isSMTPDisabled' => false,
                 'senderName' => '',
                 'senderEmail' => 'email@example.com',
                 'templateSubject' => 'template subject',
                 'expectedValue' => false
             ],
             'no sender email so not valid' => [
-                'isSMTPDisabled' => false,
                 'senderName' => 'sender name',
                 'senderEmail' => '',
                 'templateSubject' => 'template subject',
                 'expectedValue' => false
             ],
             'no subject so not valid' => [
-                'isSMTPDisabled' => false,
                 'senderName' => 'sender name',
                 'senderEmail' => 'email@example.com',
                 'templateSubject' => '',
diff --git a/app/code/Magento/Email/etc/di.xml b/app/code/Magento/Email/etc/di.xml
index d1477d470abd1d35416e4ba40d246ecd90148c26..380e5e6248fb3f3b6a42108f91a2a4f49b08e263 100644
--- a/app/code/Magento/Email/etc/di.xml
+++ b/app/code/Magento/Email/etc/di.xml
@@ -59,5 +59,6 @@
     </type>
     <type name="Magento\Framework\Mail\TransportInterface">
         <plugin name="WindowsSmtpConfig" type="Magento\Email\Model\Plugin\WindowsSmtpConfig" />
+        <plugin name="disableSending" type="Magento\Email\Model\Mail\TransportInterfacePlugin" />
     </type>
 </config>
diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php
index b7ba3196de4566950d45bc0a335310d77b6c6202..157887ec62c526458377d5d0103a992fab60a63d 100644
--- a/app/code/Magento/ImportExport/Model/Import.php
+++ b/app/code/Magento/ImportExport/Model/Import.php
@@ -605,7 +605,10 @@ class Import extends \Magento\ImportExport\Model\AbstractModel
         foreach (array_keys($relatedIndexers) as $indexerId) {
             try {
                 $indexer = $this->indexerRegistry->get($indexerId);
-                $indexer->invalidate();
+
+                if (!$indexer->isScheduled()) {
+                    $indexer->invalidate();
+                }
             } catch (\InvalidArgumentException $e) {
             }
         }
diff --git a/app/code/Magento/ImportExport/Test/Unit/Model/ImportTest.php b/app/code/Magento/ImportExport/Test/Unit/Model/ImportTest.php
index f39acf7add05dc30cc91e56e2fbb7e1e7d6a6fd2..4c175b64924b951465ba9d512900e56570180ad4 100644
--- a/app/code/Magento/ImportExport/Test/Unit/Model/ImportTest.php
+++ b/app/code/Magento/ImportExport/Test/Unit/Model/ImportTest.php
@@ -5,6 +5,9 @@
  */
 namespace Magento\ImportExport\Test\Unit\Model;
 
+use Magento\Framework\Indexer\IndexerInterface;
+use Magento\ImportExport\Model\Import;
+
 /**
  * Class ImportTest
  * @package Magento\ImportExport\Test\Unit\Model
@@ -126,7 +129,7 @@ class ImportTest extends \Magento\ImportExport\Test\Unit\Model\Import\AbstractIm
             ->getMock();
         $this->_importConfig = $this->getMockBuilder(\Magento\ImportExport\Model\Import\Config::class)
             ->disableOriginalConstructor()
-            ->setMethods(['getEntityTypeCode', 'getBehavior', 'getEntities'])
+            ->setMethods(['getEntityTypeCode', 'getBehavior', 'getEntities', 'getRelatedIndexers'])
             ->getMockForAbstractClass();
         $this->_entityFactory = $this->getMockBuilder(\Magento\ImportExport\Model\Import\Entity\Factory::class)
             ->disableOriginalConstructor()
@@ -419,12 +422,90 @@ class ImportTest extends \Magento\ImportExport\Test\Unit\Model\Import\AbstractIm
         $this->markTestIncomplete('This test has not been implemented yet.');
     }
 
-    /**
-     * @todo to implement it.
-     */
     public function testInvalidateIndex()
     {
-        $this->markTestIncomplete('This test has not been implemented yet.');
+        $indexers = [
+            'indexer_1' => 'indexer_1',
+            'indexer_2' => 'indexer_2'
+        ];
+        $indexer1 = $this->getMockBuilder(IndexerInterface::class)
+            ->getMockForAbstractClass();
+        $indexer2 = clone $indexer1;
+        $logger = $this->getMockBuilder(\Psr\Log\LoggerInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $indexer1->expects($this->once())
+            ->method('isScheduled')
+            ->willReturn(true);
+        $indexer1->expects($this->never())
+            ->method('invalidate');
+        $indexer2->expects($this->once())
+            ->method('isScheduled')
+            ->willReturn(false);
+        $indexer2->expects($this->once())
+            ->method('invalidate');
+
+        $this->_importConfig->expects($this->atLeastOnce())
+            ->method('getRelatedIndexers')
+            ->willReturn($indexers);
+        $this->indexerRegistry->expects($this->any())
+            ->method('get')
+            ->willReturnMap([
+                ['indexer_1', $indexer1],
+                ['indexer_2', $indexer2],
+            ]);
+
+        $import = new Import(
+            $logger,
+            $this->_filesystem,
+            $this->_importExportData,
+            $this->_coreConfig,
+            $this->_importConfig,
+            $this->_entityFactory,
+            $this->_importData,
+            $this->_csvFactory,
+            $this->_httpFactory,
+            $this->_uploaderFactory,
+            $this->_behaviorFactory,
+            $this->indexerRegistry,
+            $this->historyModel,
+            $this->dateTime
+        );
+
+        $import->setEntity('test');
+        $import->invalidateIndex();
+    }
+
+    public function testInvalidateIndexWithoutIndexers()
+    {
+        $this->_importConfig->expects($this->once())
+            ->method('getRelatedIndexers')
+            ->willReturn([]);
+
+        $logger = $this->getMockBuilder(\Psr\Log\LoggerInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $import = new Import(
+            $logger,
+            $this->_filesystem,
+            $this->_importExportData,
+            $this->_coreConfig,
+            $this->_importConfig,
+            $this->_entityFactory,
+            $this->_importData,
+            $this->_csvFactory,
+            $this->_httpFactory,
+            $this->_uploaderFactory,
+            $this->_behaviorFactory,
+            $this->indexerRegistry,
+            $this->historyModel,
+            $this->dateTime
+        );
+
+        $import->setEntity('test');
+        $this->assertSame($import, $import->invalidateIndex());
     }
 
     /**
diff --git a/app/code/Magento/Newsletter/Model/Subscriber.php b/app/code/Magento/Newsletter/Model/Subscriber.php
index 6e614545b23d00dbcbee736beb7a2f687eb58d20..431d8ed4a5587fe97071b6a0a82fed5463edd212 100644
--- a/app/code/Magento/Newsletter/Model/Subscriber.php
+++ b/app/code/Magento/Newsletter/Model/Subscriber.php
@@ -542,11 +542,17 @@ class Subscriber extends \Magento\Framework\Model\AbstractModel
 
         $sendInformationEmail = false;
         $status = self::STATUS_SUBSCRIBED;
+        $isConfirmNeed = $this->_scopeConfig->getValue(
+            self::XML_PATH_CONFIRMATION_FLAG,
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+        ) == 1 ? true : false;
         if ($subscribe) {
             if (AccountManagementInterface::ACCOUNT_CONFIRMATION_REQUIRED
                 == $this->customerAccountManagement->getConfirmationStatus($customerId)
             ) {
                 $status = self::STATUS_UNCONFIRMED;
+            } else if ($isConfirmNeed) {
+                $status = self::STATUS_NOT_ACTIVE;
             }
         } else {
             $status = self::STATUS_UNSUBSCRIBED;
@@ -581,7 +587,9 @@ class Subscriber extends \Magento\Framework\Model\AbstractModel
         $sendSubscription = $sendInformationEmail;
         if ($sendSubscription === null xor $sendSubscription) {
             try {
-                if ($this->isStatusChanged() && $status == self::STATUS_UNSUBSCRIBED) {
+                if ($isConfirmNeed) {
+                    $this->sendConfirmationRequestEmail();
+                } else if ($this->isStatusChanged() && $status == self::STATUS_UNSUBSCRIBED) {
                     $this->sendUnsubscriptionEmail();
                 } elseif ($this->isStatusChanged() && $status == self::STATUS_SUBSCRIBED) {
                     $this->sendConfirmationSuccessEmail();
diff --git a/app/code/Magento/Newsletter/Model/Template.php b/app/code/Magento/Newsletter/Model/Template.php
index 7b454921b0ddc490a139aa35402d987b6cbdeda9..09ea825c612af13a08636a6d4d302ec65cad9a4f 100644
--- a/app/code/Magento/Newsletter/Model/Template.php
+++ b/app/code/Magento/Newsletter/Model/Template.php
@@ -174,7 +174,8 @@ class Template extends \Magento\Email\Model\AbstractTemplate
     public function beforeSave()
     {
         $this->validate();
-        return parent::beforeSave();
+        parent::beforeSave();
+        return $this;
     }
 
     /**
@@ -238,9 +239,6 @@ class Template extends \Magento\Email\Model\AbstractTemplate
      */
     public function isValidForSend()
     {
-        return !$this->scopeConfig->isSetFlag(
-            \Magento\Email\Model\Template::XML_PATH_SYSTEM_SMTP_DISABLE,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-        ) && $this->getTemplateSenderName() && $this->getTemplateSenderEmail() && $this->getTemplateSubject();
+        return $this->getTemplateSenderName() && $this->getTemplateSenderEmail() && $this->getTemplateSubject();
     }
 }
diff --git a/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php b/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php
index 789a8bdcd439755e421f845a1523b3a4189096e0..ea884a9e720c30cecf001ae08dbf3ea02c38e75d 100644
--- a/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php
+++ b/app/code/Magento/Newsletter/Test/Unit/Model/SubscriberTest.php
@@ -260,6 +260,37 @@ class SubscriberTest extends \PHPUnit_Framework_TestCase
         $this->subscriber->subscribeCustomerById($customerId);
     }
 
+    public function testSubscribeCustomerById1()
+    {
+        $customerId = 1;
+        $customerDataMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)
+            ->getMock();
+        $this->customerRepository->expects($this->atLeastOnce())
+            ->method('getById')
+            ->with($customerId)->willReturn($customerDataMock);
+        $this->resource->expects($this->atLeastOnce())
+            ->method('loadByCustomerData')
+            ->with($customerDataMock)
+            ->willReturn(
+                [
+                    'subscriber_id' => 1,
+                    'subscriber_status' => 3
+                ]
+            );
+        $customerDataMock->expects($this->atLeastOnce())->method('getId')->willReturn('id');
+        $this->resource->expects($this->atLeastOnce())->method('save')->willReturnSelf();
+        $customerDataMock->expects($this->once())->method('getStoreId')->willReturn('store_id');
+        $customerDataMock->expects($this->once())->method('getEmail')->willReturn('email');
+        $this->sendEmailCheck();
+        $this->customerAccountManagement->expects($this->once())
+            ->method('getConfirmationStatus')
+            ->willReturn(\Magento\Customer\Api\AccountManagementInterface::ACCOUNT_CONFIRMATION_NOT_REQUIRED);
+        $this->scopeConfig->expects($this->atLeastOnce())->method('getValue')->with()->willReturn(true);
+
+        $this->subscriber->subscribeCustomerById($customerId);
+        $this->assertEquals(\Magento\Newsletter\Model\Subscriber::STATUS_NOT_ACTIVE, $this->subscriber->getStatus());
+    }
+
     public function testUnsubscribe()
     {
         $this->resource->expects($this->once())->method('save')->willReturnSelf();
diff --git a/app/code/Magento/Newsletter/Test/Unit/Model/TemplateTest.php b/app/code/Magento/Newsletter/Test/Unit/Model/TemplateTest.php
index e51d5e0fdb3a75f6abcf79cd6289b398ec0e9391..c8599230652425348ce1b8eea8d0679defa9df16 100644
--- a/app/code/Magento/Newsletter/Test/Unit/Model/TemplateTest.php
+++ b/app/code/Magento/Newsletter/Test/Unit/Model/TemplateTest.php
@@ -379,4 +379,55 @@ class TemplateTest extends \PHPUnit_Framework_TestCase
             ],
         ];
     }
+
+    /**
+     * @param $senderName string
+     * @param $senderEmail string
+     * @param $templateSubject string
+     * @dataProvider isValidForSendDataProvider
+     */
+    public function testIsValidForSend($senderName, $senderEmail, $templateSubject, $expectedValue)
+    {
+        $model = $this->getModelMock(['getTemplateSenderName', 'getTemplateSenderEmail', 'getTemplateSubject']);
+        $model->expects($this->any())
+            ->method('getTemplateSenderName')
+            ->will($this->returnValue($senderName));
+        $model->expects($this->any())
+            ->method('getTemplateSenderEmail')
+            ->will($this->returnValue($senderEmail));
+        $model->expects($this->any())
+            ->method('getTemplateSubject')
+            ->will($this->returnValue($templateSubject));
+        $this->assertEquals($expectedValue, $model->isValidForSend());
+    }
+
+    public function isValidForSendDataProvider()
+    {
+        return [
+            'should be valid' => [
+                'senderName' => 'sender name',
+                'senderEmail' => 'email@example.com',
+                'templateSubject' => 'template subject',
+                'expectedValue' => true
+            ],
+            'no sender name so not valid' => [
+                'senderName' => '',
+                'senderEmail' => 'email@example.com',
+                'templateSubject' => 'template subject',
+                'expectedValue' => false
+            ],
+            'no sender email so not valid' => [
+                'senderName' => 'sender name',
+                'senderEmail' => '',
+                'templateSubject' => 'template subject',
+                'expectedValue' => false
+            ],
+            'no subject so not valid' => [
+                'senderName' => 'sender name',
+                'senderEmail' => 'email@example.com',
+                'templateSubject' => '',
+                'expectedValue' => false
+            ],
+        ];
+    }
 }
diff --git a/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php b/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php
index c4d9657a322dab4b48a1668f908021de223f050b..d176b5be6a4551d9d7162ebf5d9436f99aadcd37 100644
--- a/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php
+++ b/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php
@@ -151,25 +151,28 @@ class Tablerate extends \Magento\Shipping\Model\Carrier\AbstractCarrier implemen
         $request->setPackageQty($oldQty);
 
         if (!empty($rate) && $rate['price'] >= 0) {
-            /** @var \Magento\Quote\Model\Quote\Address\RateResult\Method $method */
-            $method = $this->_resultMethodFactory->create();
-
-            $method->setCarrier('tablerate');
-            $method->setCarrierTitle($this->getConfigData('title'));
-
-            $method->setMethod('bestway');
-            $method->setMethodTitle($this->getConfigData('name'));
-
             if ($request->getFreeShipping() === true || $request->getPackageQty() == $freeQty) {
                 $shippingPrice = 0;
             } else {
                 $shippingPrice = $this->getFinalPriceWithHandlingFee($rate['price']);
             }
-
-            $method->setPrice($shippingPrice);
-            $method->setCost($rate['cost']);
-
+            $method = $this->createShippingMethod($shippingPrice, $rate['cost']);
             $result->append($method);
+        } elseif (empty($rate) && $request->getFreeShipping() === true || $request->getPackageQty() == $freeQty) {
+
+            /**
+             * Promotion rule was applied for the whole cart.
+             *  In this case all other shipping methods could be omitted
+             * Table rate shipping method with 0$ price must be shown if grand total is more than minimal value.
+             * Free package weight has been already taken into account.
+             */
+            $request->setPackageValue($freePackageValue);
+            $request->setPackageQty($freeQty);
+            $rate = $this->getRate($request);
+            if (!empty($rate) && $rate['price'] >= 0) {
+                $method = $this->createShippingMethod(0, 0);
+                $result->append($method);
+            }
         } else {
             /** @var \Magento\Quote\Model\Quote\Address\RateResult\Error $error */
             $error = $this->_rateErrorFactory->create(
@@ -241,4 +244,27 @@ class Tablerate extends \Magento\Shipping\Model\Carrier\AbstractCarrier implemen
     {
         return ['bestway' => $this->getConfigData('name')];
     }
+
+    /**
+     * Get the method object based on the shipping price and cost
+     *
+     * @param float $shippingPrice
+     * @param float $cost
+     * @return \Magento\Quote\Model\Quote\Address\RateResult\Method
+     */
+    private function createShippingMethod($shippingPrice, $cost)
+    {
+        /** @var  \Magento\Quote\Model\Quote\Address\RateResult\Method $method */
+        $method = $this->_resultMethodFactory->create();
+
+        $method->setCarrier('tablerate');
+        $method->setCarrierTitle($this->getConfigData('title'));
+
+        $method->setMethod('bestway');
+        $method->setMethodTitle($this->getConfigData('name'));
+
+        $method->setPrice($shippingPrice);
+        $method->setCost($cost);
+        return $method;
+    }
 }
diff --git a/app/code/Magento/PageCache/Observer/FlushCacheByTags.php b/app/code/Magento/PageCache/Observer/FlushCacheByTags.php
index 7fa52cba4d76706337d1703c243f8af9ed36fae1..d229cda9b62203ca5643bcd134afd16957f9145e 100644
--- a/app/code/Magento/PageCache/Observer/FlushCacheByTags.php
+++ b/app/code/Magento/PageCache/Observer/FlushCacheByTags.php
@@ -30,6 +30,13 @@ class FlushCacheByTags implements ObserverInterface
      */
     private $fullPageCache;
 
+    /**
+     * Invalidation tags resolver
+     *
+     * @var \Magento\Framework\App\Cache\Tag\Resolver
+     */
+    private $tagResolver;
+
     /**
      * @param \Magento\PageCache\Model\Config $config
      * @param \Magento\Framework\App\PageCache\Cache $cache
@@ -51,11 +58,13 @@ class FlushCacheByTags implements ObserverInterface
     {
         if ($this->_config->getType() == \Magento\PageCache\Model\Config::BUILT_IN && $this->_config->isEnabled()) {
             $object = $observer->getEvent()->getObject();
-            if ($object instanceof \Magento\Framework\DataObject\IdentityInterface) {
-                $tags = $object->getIdentities();
-                if (!empty($tags)) {
-                    $this->getCache()->clean(\Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG, array_unique($tags));
-                }
+            if (!is_object($object)) {
+                return;
+            }
+            $tags = $this->getTagResolver()->getTags($object);
+
+            if (!empty($tags)) {
+                $this->getCache()->clean(\Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG, array_unique($tags));
             }
         }
     }
@@ -63,6 +72,7 @@ class FlushCacheByTags implements ObserverInterface
     /**
      * TODO: Workaround to support backwards compatibility, will rework to use Dependency Injection in MAGETWO-49547
      *
+     *
      * @return \Magento\PageCache\Model\Cache\Type
      */
     private function getCache()
@@ -72,4 +82,17 @@ class FlushCacheByTags implements ObserverInterface
         }
         return $this->fullPageCache;
     }
+
+    /**
+     * @deprecated
+     * @return \Magento\Framework\App\Cache\Tag\Resolver
+     */
+    private function getTagResolver()
+    {
+        if ($this->tagResolver === null) {
+            $this->tagResolver = \Magento\Framework\App\ObjectManager::getInstance()
+                ->get(\Magento\Framework\App\Cache\Tag\Resolver::class);
+        }
+        return $this->tagResolver;
+    }
 }
diff --git a/app/code/Magento/PageCache/Test/Unit/Observer/FlushCacheByTagsTest.php b/app/code/Magento/PageCache/Test/Unit/Observer/FlushCacheByTagsTest.php
index 2227228e007c722436fc0afefe1b6a2c1680d8fa..e6453c8d6683f282a3db5858f2c315cc7991d74c 100644
--- a/app/code/Magento/PageCache/Test/Unit/Observer/FlushCacheByTagsTest.php
+++ b/app/code/Magento/PageCache/Test/Unit/Observer/FlushCacheByTagsTest.php
@@ -23,11 +23,15 @@ class FlushCacheByTagsTest extends \PHPUnit_Framework_TestCase
     /** @var  \PHPUnit_Framework_MockObject_MockObject|\Magento\PageCache\Model\Cache\Type */
     private $fullPageCacheMock;
 
+    /** @var  \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\Cache\Tag\Resolver */
+    private $tagResolver;
+
     /**
      * Set up all mocks and data for test
      */
     protected function setUp()
     {
+        $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
         $this->_configMock = $this->getMock(
             \Magento\PageCache\Model\Config::class,
             ['getType', 'isEnabled'],
@@ -42,6 +46,11 @@ class FlushCacheByTagsTest extends \PHPUnit_Framework_TestCase
             $this->_configMock,
             $this->_cacheMock
         );
+
+        $this->tagResolver = $this->getMock(\Magento\Framework\App\Cache\Tag\Resolver::class, [], [], '', false);
+
+
+        $helper->setBackwardCompatibleProperty($this->_model, 'tagResolver', $this->tagResolver);
         $reflection = new \ReflectionClass(\Magento\PageCache\Observer\FlushCacheByTags::class);
         $reflectionProperty = $reflection->getProperty('fullPageCache');
         $reflectionProperty->setAccessible(true);
@@ -70,7 +79,7 @@ class FlushCacheByTagsTest extends \PHPUnit_Framework_TestCase
             $this->_configMock->expects($this->once())
                 ->method('getType')
                 ->willReturn(\Magento\PageCache\Model\Config::BUILT_IN);
-            $observedObject->expects($this->once())->method('getIdentities')->will($this->returnValue($tags));
+            $this->tagResolver->expects($this->once())->method('getTags')->will($this->returnValue($tags));
 
             $this->fullPageCacheMock->expects($this->once())
                 ->method('clean')
@@ -106,7 +115,7 @@ class FlushCacheByTagsTest extends \PHPUnit_Framework_TestCase
         )->will(
             $this->returnValue(\Magento\PageCache\Model\Config::BUILT_IN)
         );
-        $observedObject->expects($this->once())->method('getIdentities')->will($this->returnValue($tags));
+        $this->tagResolver->expects($this->once())->method('getTags')->will($this->returnValue($tags));
 
         $this->fullPageCacheMock->expects($this->never())->method('clean');
 
diff --git a/app/code/Magento/Payment/Model/Checks/CanUseForCountry/CountryProvider.php b/app/code/Magento/Payment/Model/Checks/CanUseForCountry/CountryProvider.php
index 8342b181d5e6f094bd294e99d1e60a21d3038424..cb7791cbc6d2da13e65000ba644a5b467fec9d16 100644
--- a/app/code/Magento/Payment/Model/Checks/CanUseForCountry/CountryProvider.php
+++ b/app/code/Magento/Payment/Model/Checks/CanUseForCountry/CountryProvider.php
@@ -31,8 +31,8 @@ class CountryProvider
      */
     public function getCountry(Quote $quote)
     {
-        $address = $quote->isVirtual() ? $quote->getBillingAddress() : $quote->getShippingAddress();
-        return $address
+        $address = $quote->getBillingAddress() ? : $quote->getShippingAddress();
+        return (!empty($address) && !empty($address->getCountry()))
             ? $address->getCountry()
             : $this->directoryHelper->getDefaultCountry();
     }
diff --git a/app/code/Magento/Payment/Test/Unit/Model/Checks/CanUseForCountry/CountryProviderTest.php b/app/code/Magento/Payment/Test/Unit/Model/Checks/CanUseForCountry/CountryProviderTest.php
index 5b14cc57a3035fd992656327e89e4376cabfc981..02cfd0387c3e5dfe412434ed10c8490da59e21a3 100644
--- a/app/code/Magento/Payment/Test/Unit/Model/Checks/CanUseForCountry/CountryProviderTest.php
+++ b/app/code/Magento/Payment/Test/Unit/Model/Checks/CanUseForCountry/CountryProviderTest.php
@@ -5,55 +5,123 @@
  */
 namespace Magento\Payment\Test\Unit\Model\Checks\CanUseForCountry;
 
+use Magento\Directory\Helper\Data;
+use Magento\Payment\Model\Checks\CanUseForCountry\CountryProvider;
+use Magento\Quote\Model\Quote;
+use Magento\Quote\Model\Quote\Address;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
+
+/**
+ * CountryProviderTest contains tests for CountryProvider class
+ */
 class CountryProviderTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\Payment\Model\Checks\CanUseForCountry\CountryProvider
+     * @var CountryProvider
      */
-    protected $model;
+    private $countryProvider;
 
     /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
+     * @var Data|MockObject
      */
-    protected $directoryMock;
+    private $directory;
+
+    /**
+     * @var Quote|MockObject
+     */
+    private $quote;
 
     protected function setUp()
     {
-        $this->directoryMock = $this->getMock(\Magento\Directory\Helper\Data::class, [], [], '', false, false);
-        $this->model = new \Magento\Payment\Model\Checks\CanUseForCountry\CountryProvider($this->directoryMock);
+        $this->directory = $this->getMockBuilder(Data::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getDefaultCountry'])
+            ->getMock();
+
+        $this->quote = $this->getMockBuilder(Quote::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getBillingAddress', 'getShippingAddress'])
+            ->getMock();
+
+        $this->countryProvider = new CountryProvider($this->directory);
     }
 
-    public function testGetCountryForNonVirtualQuote()
+    /**
+     * @covers \Magento\Payment\Model\Checks\CanUseForCountry\CountryProvider::getCountry
+     */
+    public function testGetCountry()
     {
-        $quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false, false);
-        $quoteMock->expects($this->once())->method('isVirtual')->willReturn(false);
-        $addressMock = $this->getMock(\Magento\Quote\Model\Quote\Address::class, [], [], '', false, false);
-        $addressMock->expects($this->once())->method('getCountry')->will($this->returnValue(1));
-        $quoteMock->expects($this->once())->method('getShippingAddress')->will($this->returnValue($addressMock));
-        $this->assertEquals(1, $this->model->getCountry($quoteMock));
+        $address = $this->getMockBuilder(Address::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getCountry'])
+            ->getMock();
+
+        $this->quote->expects(static::once())
+            ->method('getBillingAddress')
+            ->willReturn($address);
+
+        $this->quote->expects(static::never())
+            ->method('getShippingAddress');
+
+        $address->expects(static::exactly(2))
+            ->method('getCountry')
+            ->willReturn('UK');
+        $this->directory->expects(static::never())
+            ->method('getDefaultCountry');
+
+        static::assertEquals('UK', $this->countryProvider->getCountry($this->quote));
     }
 
-    public function testGetCountryForVirtualQuoteWhenBillingAddressNotExist()
+    /**
+     * @covers \Magento\Payment\Model\Checks\CanUseForCountry\CountryProvider::getCountry
+     */
+    public function testGetCountryForBillingAddressWithoutCountry()
     {
-        $quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false, false);
-        $quoteMock->expects($this->once())->method('isVirtual')->willReturn(true);
-        $addressMock = $this->getMock(\Magento\Quote\Model\Quote\Address::class, [], [], '', false, false);
-        $addressMock->expects($this->never())->method('getCountry');
-        $quoteMock->expects($this->never())->method('getShippingAddress');
-        $quoteMock->expects($this->once())->method('getBillingAddress')->willReturn(null);
-        $this->directoryMock->expects($this->once())->method('getDefaultCountry')->willReturn(10);
-        $this->assertEquals(10, $this->model->getCountry($quoteMock));
+        $address = $this->getMockBuilder(Address::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getCountry'])
+            ->getMock();
+
+        $this->quote->expects(static::never())
+            ->method('getShippingAddress');
+        $this->quote->expects(static::once())
+            ->method('getBillingAddress')
+            ->willReturn($address);
+
+        $address->expects(static::once())
+            ->method('getCountry')
+            ->willReturn(null);
+        $this->directory->expects(static::once())
+            ->method('getDefaultCountry')
+            ->willReturn('US');
+        static::assertEquals('US', $this->countryProvider->getCountry($this->quote));
     }
 
-    public function testGetCountryForVirtualQuoteWhenBillingAddressExist()
+    /**
+     * @covers \Magento\Payment\Model\Checks\CanUseForCountry\CountryProvider::getCountry
+     */
+    public function testGetCountryShippingAddress()
     {
-        $quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false, false);
-        $quoteMock->expects($this->once())->method('isVirtual')->willReturn(true);
-        $addressMock = $this->getMock(\Magento\Quote\Model\Quote\Address::class, [], [], '', false, false);
-        $addressMock->expects($this->once())->method('getCountry')->willReturn(10);
-        $quoteMock->expects($this->never())->method('getShippingAddress');
-        $quoteMock->expects($this->once())->method('getBillingAddress')->willReturn($addressMock);
-        $this->directoryMock->expects($this->never())->method('getDefaultCountry');
-        $this->assertEquals(10, $this->model->getCountry($quoteMock));
+        $address = $this->getMockBuilder(Address::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getCountry'])
+            ->getMock();
+
+        $this->quote->expects(static::once())
+            ->method('getBillingAddress')
+            ->willReturn(null);
+
+        $this->quote->expects(static::once())
+            ->method('getShippingAddress')
+            ->willReturn($address);
+
+        $address->expects(static::exactly(2))
+            ->method('getCountry')
+            ->willReturn('CA');
+
+        $this->directory->expects(static::never())
+            ->method('getDefaultCountry');
+
+        static::assertEquals('CA', $this->countryProvider->getCountry($this->quote));
     }
 }
diff --git a/app/code/Magento/Payment/view/adminhtml/web/transparent.js b/app/code/Magento/Payment/view/adminhtml/web/transparent.js
index 583945d39612e67ad99318dafca192a9355bd453..b94e9bd4b2673465e807fda1c54edf6af36f5980 100644
--- a/app/code/Magento/Payment/view/adminhtml/web/transparent.js
+++ b/app/code/Magento/Payment/view/adminhtml/web/transparent.js
@@ -6,12 +6,14 @@
 define([
     'jquery',
     'mage/template',
-    'Magento_Ui/js/modal/alert'
+    'Magento_Ui/js/modal/alert',
+    'Magento_Payment/js/model/credit-card-validation/validator'
 ], function ($, mageTemplate, alert) {
     'use strict';
 
     $.widget('mage.transparent', {
         options: {
+            editFormSelector: '#edit_form',
             hiddenFormTmpl:
                 '<form target="<%= data.target %>" action="<%= data.action %>"' +
                 'method="POST" hidden' +
@@ -33,37 +35,51 @@ define([
          * @private
          */
         _create: function () {
+            this.hiddenFormTmpl = mageTemplate(this.options.hiddenFormTmpl);
 
-            /**
-             * @param {Object} event
-             * @param {String} method
-             */
-            var prepare = function (event, method) {
-                if (method === this.options.gateway) {
-                    $('#edit_form')
-                        .off('submitOrder')
-                        .on('submitOrder.' +  this.options.gateway, this._orderSave.bind(this));
-                } else {
-                    $('#edit_form')
-                        .off('submitOrder.' + this.options.gateway);
-                }
-            },
-                $editForm = $('#edit_form');
+            $(this.options.editFormSelector).on('changePaymentMethod', this._setPlaceOrderHandler.bind(this));
+            $(this.options.editFormSelector).trigger('changePaymentMethod', [
+                $(this.options.editFormSelector).find(':radio[name="payment[method]"]:checked').val()
+            ]);
+        },
 
-            this.hiddenFormTmpl = mageTemplate(this.options.hiddenFormTmpl);
-            $editForm.on('changePaymentMethod', prepare.bind(this));
-
-            $editForm.trigger(
-                'changePaymentMethod',
-                [
-                    $editForm.find(':radio[name="payment[method]"]:checked').val()
-                ]
-            );
+        /**
+         * Handler for form submit.
+         *
+         * @param {Object} event
+         * @param {String} method
+         */
+        _setPlaceOrderHandler: function (event, method) {
+            if (method === this.options.gateway) {
+                $(this.options.editFormSelector)
+                    .off('submitOrder')
+                    .on('submitOrder.' +  this.options.gateway, this._placeOrderHandler.bind(this));
+            } else {
+                $(this.options.editFormSelector)
+                    .off('submitOrder.' + this.options.gateway);
+            }
+        },
+
+        /**
+         * Handler for form submit to call gateway for credit card validation.
+         *
+         * @return {Boolean}
+         * @private
+         */
+        _placeOrderHandler: function () {
+            if ($(this.options.editFormSelector).valid()) {
+                this._orderSave();
+            } else {
+                $('body').trigger('processStop');
+            }
+
+            return false;
         },
 
         /**
-         * handler for Place Order button to call gateway for credit card validation
-         * Save order and generate post data for gateway call
+         * Handler for Place Order button to call gateway for credit card validation.
+         * Save order and generate post data for gateway call.
+         *
          * @private
          */
         _orderSave: function () {
@@ -99,7 +115,8 @@ define([
         },
 
         /**
-         * Post data to gateway for credit card validation
+         * Post data to gateway for credit card validation.
+         *
          * @param {Object} response
          * @private
          */
@@ -136,7 +153,7 @@ define([
         },
 
         /**
-         * Add credit card fields to post data for gateway
+         * Add credit card fields to post data for gateway.
          *
          * @param {Object} response
          * @private
diff --git a/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/credit-card-data.js b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/credit-card-data.js
similarity index 100%
rename from app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/credit-card-data.js
rename to app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/credit-card-data.js
diff --git a/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/credit-card-number-validator.js b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/credit-card-number-validator.js
similarity index 100%
rename from app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/credit-card-number-validator.js
rename to app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/credit-card-number-validator.js
diff --git a/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/credit-card-number-validator/credit-card-type.js b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/credit-card-number-validator/credit-card-type.js
similarity index 100%
rename from app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/credit-card-number-validator/credit-card-type.js
rename to app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/credit-card-number-validator/credit-card-type.js
diff --git a/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/credit-card-number-validator/luhn10-validator.js b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/credit-card-number-validator/luhn10-validator.js
similarity index 100%
rename from app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/credit-card-number-validator/luhn10-validator.js
rename to app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/credit-card-number-validator/luhn10-validator.js
diff --git a/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/cvv-validator.js b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/cvv-validator.js
similarity index 100%
rename from app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/cvv-validator.js
rename to app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/cvv-validator.js
diff --git a/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator.js b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/expiration-date-validator.js
similarity index 100%
rename from app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator.js
rename to app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/expiration-date-validator.js
diff --git a/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator/expiration-month-validator.js b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/expiration-date-validator/expiration-month-validator.js
similarity index 100%
rename from app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator/expiration-month-validator.js
rename to app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/expiration-date-validator/expiration-month-validator.js
diff --git a/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator/expiration-year-validator.js b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/expiration-date-validator/expiration-year-validator.js
similarity index 100%
rename from app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator/expiration-year-validator.js
rename to app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/expiration-date-validator/expiration-year-validator.js
diff --git a/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator/parse-date.js b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/expiration-date-validator/parse-date.js
similarity index 100%
rename from app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator/parse-date.js
rename to app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/expiration-date-validator/parse-date.js
diff --git a/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/validator.js b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js
similarity index 88%
rename from app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/validator.js
rename to app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js
index e859a03491cba156bd8ef4ba32e9838f24375e47..4a733dd155a22c36f68c33c3d5b86c11d44ca224 100644
--- a/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/validator.js
+++ b/app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js
@@ -12,7 +12,8 @@
             'Magento_Payment/js/model/credit-card-validation/credit-card-number-validator',
             'Magento_Payment/js/model/credit-card-validation/expiration-date-validator/expiration-year-validator',
             'Magento_Payment/js/model/credit-card-validation/expiration-date-validator/expiration-month-validator',
-            'Magento_Payment/js/model/credit-card-validation/credit-card-data'
+            'Magento_Payment/js/model/credit-card-validation/credit-card-data',
+            'mage/translate'
         ], factory);
     } else {
         factory(jQuery);
@@ -40,7 +41,7 @@
                     return false;
                 }
             },
-            'Please enter a valid credit card type number.'
+            $.mage.__('Please enter a valid credit card type number.')
         ],
         'validate-card-number': [
             /**
@@ -51,7 +52,7 @@
                 function (number) {
                 return creditCardNumberValidator(number).isValid;
             },
-            'Please enter a valid credit card number.'
+            $.mage.__('Please enter a valid credit card number.')
         ],
         'validate-card-date': [
             /**
@@ -62,7 +63,7 @@
                 function (date) {
                 return monthValidator(date).isValid;
             },
-            'Incorrect credit card expiration month.'
+            $.mage.__('Incorrect credit card expiration month.')
         ],
         'validate-card-cvv': [
             /**
@@ -74,7 +75,7 @@
                 var maxLength = creditCardData.creditCard ? creditCardData.creditCard.code.size : 3;
                 return cvvValidator(cvv, maxLength).isValid;
             },
-            'Please enter a valid credit card verification number.'
+            $.mage.__('Please enter a valid credit card verification number.')
         ],
         'validate-card-year': [
             /**
@@ -85,7 +86,7 @@
                 function (date) {
                 return monthValidator(date).isValid;
             },
-            'Incorrect credit card expiration year.'
+            $.mage.__('Incorrect credit card expiration year.')
         ]
 
     }, function (i, rule) {
diff --git a/app/code/Magento/Paypal/Model/Config.php b/app/code/Magento/Paypal/Model/Config.php
index 0af8b18355ec32b045c4e609137cb0eed7944373..100b5525ecb8885b1f8d832041213cb9b1db2822 100644
--- a/app/code/Magento/Paypal/Model/Config.php
+++ b/app/code/Magento/Paypal/Model/Config.php
@@ -866,7 +866,7 @@ class Config extends AbstractConfig
      */
     public function getExpressCheckoutStartUrl($token)
     {
-        return sprintf('https://www.%spaypal.com/checkoutnow/2%s',
+        return sprintf('https://www.%spaypal.com/checkoutnow%s',
             $this->getValue('sandboxFlag') ? 'sandbox.' : '',
             '?token=' . urlencode($token));
     }
diff --git a/app/code/Magento/Paypal/Test/Unit/Block/Billing/AgreementsTest.php b/app/code/Magento/Paypal/Test/Unit/Block/Billing/AgreementsTest.php
index 444cd9fdc708aeeb9a8628d5cb449af17038926f..11527bbe8c441226a6e69ccbe6d1c57b94248f02 100644
--- a/app/code/Magento/Paypal/Test/Unit/Block/Billing/AgreementsTest.php
+++ b/app/code/Magento/Paypal/Test/Unit/Block/Billing/AgreementsTest.php
@@ -235,9 +235,14 @@ class AgreementsTest extends \PHPUnit_Framework_TestCase
     public function testToHtml()
     {
         $this->eventManager
-            ->expects($this->once())
+            ->expects($this->at(0))
             ->method('dispatch')
             ->with('view_block_abstract_to_html_before', ['block' => $this->block]);
+        $transport = new \Magento\Framework\DataObject(['html' => '']);
+        $this->eventManager
+            ->expects($this->at(1))
+            ->method('dispatch')
+            ->with('view_block_abstract_to_html_after', ['block' => $this->block, 'transport' => $transport]);
         $this->scopeConfig
             ->expects($this->once())
             ->method('getValue')
diff --git a/app/code/Magento/Paypal/view/adminhtml/templates/transparent/form.phtml b/app/code/Magento/Paypal/view/adminhtml/templates/transparent/form.phtml
index b1a50bcb1bf73db9232cf3457e26215bebe92eff..4c1a3d8e4a41007ade8e32ebf1371c1b55278c32 100644
--- a/app/code/Magento/Paypal/view/adminhtml/templates/transparent/form.phtml
+++ b/app/code/Magento/Paypal/view/adminhtml/templates/transparent/form.phtml
@@ -129,12 +129,12 @@ $ccExpMonth = $block->getInfoData('cc_exp_month');
     <?php endif; ?>
 
     <?php if($block->isVaultEnabled()): ?>
-        <div class="field-tooltip-content">
+        <div class="admin__field admin__field-option field-tooltip-content">
             <input type="checkbox"
                    id="<?php /* @noEscape */ echo $code; ?>_vault"
                    name="payment[is_active_payment_token_enabler]"
                    class="admin__control-checkbox"/>
-            <label class="label" for="<?php /* @noEscape */ echo $code; ?>_vault">
+            <label class="admin__field-label" for="<?php /* @noEscape */ echo $code; ?>_vault">
                 <span><?php echo $block->escapeHtml('Save for later use.'); ?></span>
             </label>
         </div>
diff --git a/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/in-context/checkout-express.js b/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/in-context/checkout-express.js
index 97dbf0e81b9da0003018ab6c6975aea3216501b4..8a29f0c3a6ea4f774ffc38c9eeb5e65dd34b9657 100644
--- a/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/in-context/checkout-express.js
+++ b/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/in-context/checkout-express.js
@@ -25,6 +25,9 @@ define(
     ) {
         'use strict';
 
+        // State of PayPal module initialization
+        var clientInit = false;
+
         return Component.extend({
 
             defaults: {
@@ -93,15 +96,26 @@ define(
              * @returns {Object}
              */
             initClient: function () {
+                var selector = '#' + this.getButtonId();
+
                 _.each(this.clientConfig, function (fn, name) {
                     if (typeof fn === 'function') {
                         this.clientConfig[name] = fn.bind(this);
                     }
                 }, this);
 
-                domObserver.get('#' + this.getButtonId(), function () {
-                    paypalExpressCheckout.checkout.setup(this.merchantId, this.clientConfig);
-                }.bind(this));
+                if (!clientInit) {
+                    domObserver.get(selector, function () {
+                        paypalExpressCheckout.checkout.setup(this.merchantId, this.clientConfig);
+                        clientInit = true;
+                        domObserver.off(selector);
+                    }.bind(this));
+                } else {
+                    domObserver.get(selector, function () {
+                        $(selector).on('click', this.clientConfig.click);
+                        domObserver.off(selector);
+                    }.bind(this));
+                }
 
                 return this;
             },
diff --git a/app/code/Magento/Paypal/view/frontend/web/order-review.js b/app/code/Magento/Paypal/view/frontend/web/order-review.js
index dc389493e46cc3069eeb94754d764b532cd1e01b..4ce2d5a1b8f2f33d4e057fc3af2638935b90f424 100644
--- a/app/code/Magento/Paypal/view/frontend/web/order-review.js
+++ b/app/code/Magento/Paypal/view/frontend/web/order-review.js
@@ -132,7 +132,7 @@ define([
                                 }
                             }
                             alert({
-                                content: $.mage.__(msg)
+                                content: msg
                             });
                             return false;
                         }
diff --git a/app/code/Magento/Paypal/view/frontend/web/template/payment/payflowpro-form.html b/app/code/Magento/Paypal/view/frontend/web/template/payment/payflowpro-form.html
index da1da321fe6213213222f8fdbc8605e85e87b98b..4d85a3abcca0cdfdba5be21e55f44cd158a14e21 100644
--- a/app/code/Magento/Paypal/view/frontend/web/template/payment/payflowpro-form.html
+++ b/app/code/Magento/Paypal/view/frontend/web/template/payment/payflowpro-form.html
@@ -51,8 +51,8 @@
                 <input type="checkbox"
                        name="vault[is_enabled]"
                        class="checkbox-inline"
-                       data-bind="attr: {'id': getCode() + '_vault_enabler'}, checked: vaultEnabler.isActivePaymentTokenEnabler"/>
-                <label class="label" data-bind="attr: {'for': getCode() + '_vault_enabler'}">
+                       data-bind="attr: {'id': getCode() + '_enable_vault'}, checked: vaultEnabler.isActivePaymentTokenEnabler"/>
+                <label class="label" data-bind="attr: {'for': getCode() + '_enable_vault'}">
                     <span><!-- ko i18n: 'Save credit card information for future use.'--><!-- /ko --></span>
                 </label>
             </div>
diff --git a/app/code/Magento/Persistent/Test/Unit/Block/Header/AdditionalTest.php b/app/code/Magento/Persistent/Test/Unit/Block/Header/AdditionalTest.php
index c5f93d1557c08b48f7027eae35aa1da4206f6f90..08ad98787852eba1d43667d3d1cc9dba6decc6d7 100644
--- a/app/code/Magento/Persistent/Test/Unit/Block/Header/AdditionalTest.php
+++ b/app/code/Magento/Persistent/Test/Unit/Block/Header/AdditionalTest.php
@@ -261,9 +261,12 @@ class AdditionalTest extends \PHPUnit_Framework_TestCase
         $this->additional->setData('cache_lifetime', 789);
         $this->additional->setData('cache_key', 'cache-key');
 
-        $this->eventManagerMock->expects($this->once())
+        $this->eventManagerMock->expects($this->at(0))
             ->method('dispatch')
             ->with('view_block_abstract_to_html_before', ['block' => $this->additional]);
+        $this->eventManagerMock->expects($this->at(1))
+            ->method('dispatch')
+            ->with('view_block_abstract_to_html_after');
         $this->scopeConfigMock->expects($this->once())
             ->method('getValue')
             ->with(
diff --git a/app/code/Magento/ProductVideo/view/adminhtml/web/js/get-video-information.js b/app/code/Magento/ProductVideo/view/adminhtml/web/js/get-video-information.js
index cd175bed111062a44620b3044889b2349c564a8a..5885c157927bc3c64eff9f770ce03cab5822a35b 100644
--- a/app/code/Magento/ProductVideo/view/adminhtml/web/js/get-video-information.js
+++ b/app/code/Magento/ProductVideo/view/adminhtml/web/js/get-video-information.js
@@ -6,7 +6,8 @@
 define([
     'jquery',
     'Magento_Ui/js/modal/alert',
-    'jquery/ui'
+    'jquery/ui',
+    'mage/translate'
 ], function ($, alert) {
         'use strict';
 
diff --git a/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js b/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js
index 0b149e37a0716ad2b912a605050e05dd8f657a06..43a0292270a3f10b9a4170c30b13c0f0ef12d547 100644
--- a/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js
+++ b/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js
@@ -432,7 +432,7 @@ define([
 
             for (t = 0; t < thumbs.length; t++) {
                 this._setThumbsIcon(thumbs.eq(t), t);
-                this._checkForVideo(e, fotorama, t);
+                this._checkForVideo(e, fotorama, t + 1);
             }
 
             this.fotoramaItem.on('fotorama:showend', $.proxy(function (evt, fotoramaData) {
diff --git a/app/code/Magento/Quote/Api/GuestBillingAddressManagementInterface.php b/app/code/Magento/Quote/Api/GuestBillingAddressManagementInterface.php
index 4b45f4f469e06b80e5c81ae58dc24ecd25b2c231..66bb7f45bc4b45c4f4b83f357fc786dda2431d34 100644
--- a/app/code/Magento/Quote/Api/GuestBillingAddressManagementInterface.php
+++ b/app/code/Magento/Quote/Api/GuestBillingAddressManagementInterface.php
@@ -16,11 +16,12 @@ interface GuestBillingAddressManagementInterface
      *
      * @param string $cartId The cart ID.
      * @param \Magento\Quote\Api\Data\AddressInterface $address Billing address data.
+     * @param bool $useForShipping
      * @return int Address ID.
      * @throws \Magento\Framework\Exception\NoSuchEntityException The specified cart does not exist.
      * @throws \Magento\Framework\Exception\InputException The specified cart ID or address data is not valid.
      */
-    public function assign($cartId, \Magento\Quote\Api\Data\AddressInterface $address);
+    public function assign($cartId, \Magento\Quote\Api\Data\AddressInterface $address, $useForShipping = false);
 
     /**
      * Return the billing address for a specified quote.
diff --git a/app/code/Magento/Quote/Model/BillingAddressManagement.php b/app/code/Magento/Quote/Model/BillingAddressManagement.php
index e74eac3f4dd590c87036c5d339e4dae10d5d42ee..bbbe775044d3d6dad32ced90ec8cd054899d179f 100644
--- a/app/code/Magento/Quote/Model/BillingAddressManagement.php
+++ b/app/code/Magento/Quote/Model/BillingAddressManagement.php
@@ -40,6 +40,11 @@ class BillingAddressManagement implements BillingAddressManagementInterface
      */
     protected $addressRepository;
 
+    /**
+     * @var \Magento\Quote\Model\ShippingAddressAssignment
+     */
+    private $shippingAddressAssignment;
+
     /**
      * Constructs a quote billing address service object.
      *
@@ -71,6 +76,7 @@ class BillingAddressManagement implements BillingAddressManagementInterface
         $quote->removeAddress($quote->getBillingAddress()->getId());
         $quote->setBillingAddress($address);
         try {
+            $this->getShippingAddressAssignment()->setAddress($quote, $address, $useForShipping);
             $quote->setDataChanges(true);
             $this->quoteRepository->save($quote);
         } catch (\Exception $e) {
@@ -88,4 +94,17 @@ class BillingAddressManagement implements BillingAddressManagementInterface
         $cart = $this->quoteRepository->getActive($cartId);
         return $cart->getBillingAddress();
     }
+
+    /**
+     * @return \Magento\Quote\Model\ShippingAddressAssignment
+     * @deprecated
+     */
+    private function getShippingAddressAssignment()
+    {
+        if (!$this->shippingAddressAssignment) {
+            $this->shippingAddressAssignment = ObjectManager::getInstance()
+                ->get(\Magento\Quote\Model\ShippingAddressAssignment::class);
+        }
+        return $this->shippingAddressAssignment;
+    }
 }
diff --git a/app/code/Magento/Quote/Model/GuestCart/GuestBillingAddressManagement.php b/app/code/Magento/Quote/Model/GuestCart/GuestBillingAddressManagement.php
index 0a14aaaa0be203b132704384321efb3acd7a278e..05a1e7f7aaa683669d0f368d6457b7463e3f4298 100644
--- a/app/code/Magento/Quote/Model/GuestCart/GuestBillingAddressManagement.php
+++ b/app/code/Magento/Quote/Model/GuestCart/GuestBillingAddressManagement.php
@@ -42,11 +42,11 @@ class GuestBillingAddressManagement implements GuestBillingAddressManagementInte
     /**
      * {@inheritDoc}
      */
-    public function assign($cartId, \Magento\Quote\Api\Data\AddressInterface $address)
+    public function assign($cartId, \Magento\Quote\Api\Data\AddressInterface $address, $useForShipping = false)
     {
         /** @var $quoteIdMask QuoteIdMask */
         $quoteIdMask = $this->quoteIdMaskFactory->create()->load($cartId, 'masked_id');
-        return $this->billingAddressManagement->assign($quoteIdMask->getQuoteId(), $address);
+        return $this->billingAddressManagement->assign($quoteIdMask->getQuoteId(), $address, $useForShipping);
     }
 
     /**
diff --git a/app/code/Magento/Quote/Model/Quote/Address/Total/Grand.php b/app/code/Magento/Quote/Model/Quote/Address/Total/Grand.php
index 84c66140ee4c416734f9fc8b75374cada1dd688e..58130fe5d22399bc7ffe039dda7a962949cbc76e 100644
--- a/app/code/Magento/Quote/Model/Quote/Address/Total/Grand.php
+++ b/app/code/Magento/Quote/Model/Quote/Address/Total/Grand.php
@@ -14,17 +14,20 @@ class Grand extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
      * @param \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment
      * @param \Magento\Quote\Model\Quote\Address\Total $total
      * @return $this
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function collect(
         \Magento\Quote\Model\Quote $quote,
         \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment,
         \Magento\Quote\Model\Quote\Address\Total $total
     ) {
+        $grandTotal = $total->getGrandTotal();
+        $baseGrandTotal = $total->getBaseGrandTotal();
         $totals = array_sum($total->getAllTotalAmounts());
         $baseTotals = array_sum($total->getAllBaseTotalAmounts());
 
-        $total->setGrandTotal($totals);
-        $total->setBaseGrandTotal($baseTotals);
+        $total->setGrandTotal($grandTotal + $totals);
+        $total->setBaseGrandTotal($baseGrandTotal + $baseTotals);
         return $this;
     }
 
@@ -34,6 +37,7 @@ class Grand extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
      * @param \Magento\Quote\Model\Quote $quote
      * @param \Magento\Quote\Model\Quote\Address\Total $total
      * @return $this
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function fetch(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Model\Quote\Address\Total $total)
     {
diff --git a/app/code/Magento/Quote/Model/Quote/Address/Total/Shipping.php b/app/code/Magento/Quote/Model/Quote/Address/Total/Shipping.php
index 88edeb5b99dd6c32e43994796eb48a6646ba5bc9..f1660c9f9d6427fb617c2de9d87ae2a8026be3aa 100644
--- a/app/code/Magento/Quote/Model/Quote/Address/Total/Shipping.php
+++ b/app/code/Magento/Quote/Model/Quote/Address/Total/Shipping.php
@@ -60,10 +60,9 @@ class Shipping extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
         $addressWeight = $address->getWeight();
         $freeMethodWeight = $address->getFreeMethodWeight();
 
-        $isAllFree = $this->freeShipping->isFreeShipping($quote, $shippingAssignment->getItems());
-        if ($isAllFree && !$address->getFreeShipping()) {
-            $address->setFreeShipping(true);
-        }
+        $address->setFreeShipping(
+            $this->freeShipping->isFreeShipping($quote, $shippingAssignment->getItems())
+        );
         $total->setTotalAmount($this->getCode(), 0);
         $total->setBaseTotalAmount($this->getCode(), 0);
 
diff --git a/app/code/Magento/Quote/Model/Quote/Payment.php b/app/code/Magento/Quote/Model/Quote/Payment.php
index 432f984fb143ff73ec2ceda4e56d1d0604b82fc1..612802ccd279d58e3aa0349a8fb1da1ea4213f60 100644
--- a/app/code/Magento/Quote/Model/Quote/Payment.php
+++ b/app/code/Magento/Quote/Model/Quote/Payment.php
@@ -60,6 +60,11 @@ class Payment extends \Magento\Payment\Model\Info implements PaymentInterface
      */
     protected $methodSpecificationFactory;
 
+    /**
+     * @var array
+     */
+    private $additionalChecks;
+
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
@@ -71,6 +76,7 @@ class Payment extends \Magento\Payment\Model\Info implements PaymentInterface
      * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
      * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
      * @param array $data
+     * @param array $additionalChecks
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function __construct(
@@ -83,9 +89,11 @@ class Payment extends \Magento\Payment\Model\Info implements PaymentInterface
         \Magento\Payment\Model\Checks\SpecificationFactory $methodSpecificationFactory,
         \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
         \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
-        array $data = []
+        array $data = [],
+        array $additionalChecks = []
     ) {
         $this->methodSpecificationFactory = $methodSpecificationFactory;
+        $this->additionalChecks = $additionalChecks;
         parent::__construct(
             $context,
             $registry,
@@ -162,7 +170,8 @@ class Payment extends \Magento\Payment\Model\Info implements PaymentInterface
          */
         $quote->collectTotals();
 
-        $methodSpecification = $this->methodSpecificationFactory->create($data->getChecks());
+        $checks = array_merge($data->getChecks(), $this->additionalChecks);
+        $methodSpecification = $this->methodSpecificationFactory->create($checks);
         if (!$method->isAvailable($quote) || !$methodSpecification->isApplicable($method, $quote)) {
             throw new \Magento\Framework\Exception\LocalizedException(
                 __('The requested Payment Method is not available.')
diff --git a/app/code/Magento/Quote/Model/ShippingAddressAssignment.php b/app/code/Magento/Quote/Model/ShippingAddressAssignment.php
new file mode 100644
index 0000000000000000000000000000000000000000..9a918f3f3fb4bdf80831c1098da67cfea2548fb6
--- /dev/null
+++ b/app/code/Magento/Quote/Model/ShippingAddressAssignment.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Quote\Model;
+
+class ShippingAddressAssignment
+{
+    /**
+     * @var \Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentProcessor
+     */
+    private $shippingAssignmentProcessor;
+
+    /**
+     * @var \Magento\Quote\Api\Data\CartExtensionFactory
+     */
+    private $cartExtensionFactory;
+
+    /**
+     * ShippingAddressAssignment constructor.
+     * @param \Magento\Quote\Api\Data\CartExtensionFactory $cartExtensionFactory
+     * @param Quote\ShippingAssignment\ShippingAssignmentProcessor $shippingAssignmentProcessor
+     */
+    public function __construct(
+        \Magento\Quote\Api\Data\CartExtensionFactory $cartExtensionFactory,
+        \Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentProcessor $shippingAssignmentProcessor
+    ) {
+        $this->shippingAssignmentProcessor = $shippingAssignmentProcessor;
+        $this->cartExtensionFactory = $cartExtensionFactory;
+    }
+
+    /**
+     * @param \Magento\Quote\Api\Data\CartInterface $quote
+     * @param \Magento\Quote\Api\Data\AddressInterface $address
+     * @param bool $useForShipping
+     * @return void
+     */
+    public function setAddress(
+        \Magento\Quote\Api\Data\CartInterface $quote,
+        \Magento\Quote\Api\Data\AddressInterface $address,
+        $useForShipping = false
+    ) {
+        if ($useForShipping) {
+            $quote->removeAddress($quote->getShippingAddress()->getId());
+            $address->setSameAsBilling(1);
+            $address->setCollectShippingRates(true);
+        } else {
+            $address = $quote->getShippingAddress()->setSameAsBilling(0);
+        }
+
+        $quote->setShippingAddress($address);
+        $cartExtension = $quote->getExtensionAttributes();
+        if ($cartExtension === null) {
+            $cartExtension = $this->cartExtensionFactory->create();
+        }
+        /** @var \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment */
+        $shippingAssignment = $this->shippingAssignmentProcessor->create($quote);
+        $cartExtension->setShippingAssignments([$shippingAssignment]);
+        $quote->setExtensionAttributes($cartExtension);
+    }
+}
diff --git a/app/code/Magento/Quote/Test/Unit/Model/BillingAddressManagementTest.php b/app/code/Magento/Quote/Test/Unit/Model/BillingAddressManagementTest.php
index 3219b137b47750593a65cd73c3f4f42b51dfc0fa..81eaeed19fe15c4676bf4936a81b82aae954d8b1 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/BillingAddressManagementTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/BillingAddressManagementTest.php
@@ -40,6 +40,11 @@ class BillingAddressManagementTest extends \PHPUnit_Framework_TestCase
      */
     protected $addressRepository;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $shippingAssignmentMock;
+
     /**
      * @return void
      */
@@ -59,6 +64,19 @@ class BillingAddressManagementTest extends \PHPUnit_Framework_TestCase
                 'addressRepository' => $this->addressRepository
             ]
         );
+
+        $this->shippingAssignmentMock = $this->getMock(
+            \Magento\Quote\Model\ShippingAddressAssignment::class,
+            ['setAddress'],
+            [],
+            '',
+            false
+        );
+        $this->objectManager->setBackwardCompatibleProperty(
+            $this->model,
+            'shippingAddressAssignment',
+            $this->shippingAssignmentMock
+        );
     }
 
     /**
@@ -76,95 +94,44 @@ class BillingAddressManagementTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($addressMock, $this->model->get('cartId'));
     }
 
-    /**
-     * @return void
-     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
-     * @expectedExceptionMessage error123
-     */
-    public function testSetAddressValidationFailed()
-    {
-        $this->markTestSkipped('MAGETWO-48531');
-        $address = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class);
-        $quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false);
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')
-            ->with('cartId')
-            ->will($this->returnValue($quoteMock));
-
-        $this->validatorMock->expects($this->once())
-            ->method('validate')
-            ->will($this->throwException(new \Magento\Framework\Exception\NoSuchEntityException(__('error123'))));
-
-        $this->model->assign('cartId', $address);
-    }
-
     /**
      * @return void
      */
     public function testSetAddress()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $cartId = 100;
         $useForShipping = true;
         $addressId = 1;
-        $customerAddressId = 10;
 
         $address = $this->getMock(
             \Magento\Quote\Model\Quote\Address::class,
-            ['setSaveInAddressBook', 'getCustomerAddressId', 'getSaveInAddressBook'],
+            ['getId'],
             [],
             '',
             false
         );
-        $quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false);
-
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')
-            ->with($cartId)
-            ->willReturn($quoteMock);
-        $this->validatorMock->expects($this->once())->method('validate')
-            ->with($address)
-            ->willReturn(true);
-
-        $address->expects($this->once())->method('getCustomerAddressId')->willReturn($customerAddressId);
-        $address->expects($this->once())->method('getSaveInAddressBook')->willReturn(1);
-
-        $customerAddressMock = $this->getMock(\Magento\Customer\Api\Data\AddressInterface::class, [], [], '', false);
-        $this->addressRepository->expects($this->once())
-            ->method('getById')
-            ->with($customerAddressId)
-            ->willReturn($customerAddressMock);
-
-        $quoteBillingAddress = $this->getMock(\Magento\Quote\Model\Quote\Address::class, [], [], '', false);
-        $quoteBillingAddress->expects($this->once())->method('getId')->will($this->returnValue($addressId));
-        $quoteMock->expects($this->exactly(2))->method('getBillingAddress')->willReturn($quoteBillingAddress);
-        $quoteBillingAddress->expects($this->once())
-            ->method('importCustomerAddressData')
-            ->with($customerAddressMock)
-            ->willReturnSelf();
-
-        $quoteShippingAddress = $this->getMock(
-            \Magento\Quote\Model\Quote\Address::class,
-            ['setSaveInAddressBook', 'setSameAsBilling', 'setCollectShippingRates', 'importCustomerAddressData'],
+        $quoteMock = $this->getMock(
+            \Magento\Quote\Model\Quote::class,
+            ['removeAddress', 'getBillingAddress', 'setBillingAddress', 'setDataChanges'],
             [],
             '',
             false
         );
-        $quoteMock->expects($this->once())->method('getShippingAddress')->willReturn($quoteShippingAddress);
-        $quoteShippingAddress->expects($this->once())
-            ->method('importCustomerAddressData')
-            ->with($customerAddressMock)
-            ->willReturnSelf();
-        $quoteShippingAddress->expects($this->once())->method('setSaveInAddressBook')->with(1)->willReturnSelf();
 
-        $quoteBillingAddress->expects($this->once())->method('setSaveInAddressBook')->with(1)->willReturnSelf();
-        $quoteMock->expects($this->once())->method('setBillingAddress')->with($quoteBillingAddress)->willReturnSelf();
+        $this->quoteRepositoryMock->expects($this->once())
+            ->method('getActive')
+            ->with($cartId)
+            ->willReturn($quoteMock);
 
-        $quoteShippingAddress->expects($this->once())->method('setSameAsBilling')->with(1)->willReturnSelf();
-        $quoteShippingAddress->expects($this->once())->method('setCollectShippingRates')->with(true)->willReturnSelf();
+        $address->expects($this->exactly(2))->method('getId')->willReturn($addressId);
+        $quoteMock->expects($this->exactly(2))->method('getBillingAddress')->willReturn($address);
+        $quoteMock->expects($this->once())->method('removeAddress')->with($addressId)->willReturnSelf();
+        $quoteMock->expects($this->once())->method('setBillingAddress')->with($address)->willReturnSelf();
+        $quoteMock->expects($this->once())->method('setDataChanges')->with(1)->willReturnSelf();
 
-        $quoteMock->expects($this->once())->method('setShippingAddress')->with($quoteShippingAddress);
-        $quoteMock->expects($this->once())->method('setDataChanges')->with(true);
+        $this->shippingAssignmentMock->expects($this->once())
+            ->method('setAddress')
+            ->with($quoteMock, $address, $useForShipping);
 
         $this->quoteRepositoryMock->expects($this->once())->method('save')->with($quoteMock);
         $this->assertEquals($addressId, $this->model->assign($cartId, $address, $useForShipping));
@@ -177,27 +144,45 @@ class BillingAddressManagementTest extends \PHPUnit_Framework_TestCase
      */
     public function testSetAddressWithInabilityToSaveQuote()
     {
-        $this->markTestSkipped('MAGETWO-48531');
-        $address = $this->getMock(\Magento\Quote\Model\Quote\Address::class, [], [], '', false, false);
+        $cartId = 100;
+        $addressId = 1;
+
+        $address = $this->getMock(
+            \Magento\Quote\Model\Quote\Address::class,
+            ['getId'],
+            [],
+            '',
+            false
+        );
+        $quoteMock = $this->getMock(
+            \Magento\Quote\Model\Quote::class,
+            ['removeAddress', 'getBillingAddress', 'setBillingAddress', 'setDataChanges'],
+            [],
+            '',
+            false
+        );
 
-        $quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false);
         $this->quoteRepositoryMock->expects($this->once())
             ->method('getActive')
-            ->with('cartId')
-            ->will($this->returnValue($quoteMock));
+            ->with($cartId)
+            ->willReturn($quoteMock);
+
+        $address->expects($this->once())->method('getId')->willReturn($addressId);
+        $quoteMock->expects($this->once())->method('getBillingAddress')->willReturn($address);
+        $quoteMock->expects($this->once())->method('removeAddress')->with($addressId)->willReturnSelf();
+        $quoteMock->expects($this->once())->method('setBillingAddress')->with($address)->willReturnSelf();
+        $quoteMock->expects($this->once())->method('setDataChanges')->with(1)->willReturnSelf();
 
-        $this->validatorMock->expects($this->once())->method('validate')
-            ->with($address)
-            ->will($this->returnValue(true));
+        $this->shippingAssignmentMock->expects($this->once())
+            ->method('setAddress')
+            ->with($quoteMock, $address, false);
 
-        $quoteMock->expects($this->once())->method('setBillingAddress')->with($address);
-        $quoteMock->expects($this->once())->method('setDataChanges')->with(true);
         $this->quoteRepositoryMock->expects($this->once())
             ->method('save')
             ->with($quoteMock)
             ->willThrowException(
                 new \Exception('Some DB Error')
             );
-        $this->model->assign('cartId', $address);
+        $this->model->assign($cartId, $address);
     }
 }
diff --git a/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/Total/GrandTest.php b/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/Total/GrandTest.php
index 8db55ff0be6dfc0a4f3d0f72557721d06abcc987..842106a4d134f0db0604c63567cfccf5fea52e2e 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/Total/GrandTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/Total/GrandTest.php
@@ -29,15 +29,24 @@ class GrandTest extends \PHPUnit_Framework_TestCase
 
         $totalMock = $this->getMock(
             \Magento\Quote\Model\Quote\Address\Total::class,
-            ['getAllTotalAmounts', 'getAllBaseTotalAmounts', 'setGrandTotal', 'setBaseGrandTotal'],
+            [
+                'getAllTotalAmounts',
+                'getAllBaseTotalAmounts',
+                'setGrandTotal',
+                'setBaseGrandTotal',
+                'getGrandTotal',
+                'getBaseGrandTotal'
+            ],
             [],
             '',
             false
         );
+        $totalMock->expects($this->once())->method('getGrandTotal')->willReturn(2);
+        $totalMock->expects($this->once())->method('getBaseGrandTotal')->willReturn(2);
         $totalMock->expects($this->once())->method('getAllTotalAmounts')->willReturn($totals);
         $totalMock->expects($this->once())->method('getAllBaseTotalAmounts')->willReturn($totalsBase);
-        $totalMock->expects($this->once())->method('setGrandTotal')->with($grandTotal);
-        $totalMock->expects($this->once())->method('setBaseGrandTotal')->with($grandTotalBase);
+        $totalMock->expects($this->once())->method('setGrandTotal')->with($grandTotal + 2);
+        $totalMock->expects($this->once())->method('setBaseGrandTotal')->with($grandTotalBase + 2);
 
         $this->model->collect(
             $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false),
diff --git a/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/RepositoryTest.php b/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/RepositoryTest.php
index 76c3766d1f2481ba4251540dfcb2c084d435a0b7..dae3d56aa04b093c76d33f671606e2acfedb57af 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/RepositoryTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/RepositoryTest.php
@@ -30,7 +30,7 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
-    protected $dataMock;
+    protected $itemMock;
 
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
@@ -58,6 +58,11 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
     /** @var \PHPUnit_Framework_MockObject_MockObject */
     protected $shippingAddressMock;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $optionsProcessorMock;
+
     /**
      * @return void
      */
@@ -67,7 +72,7 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
         $this->productRepositoryMock = $this->getMock(\Magento\Catalog\Api\ProductRepositoryInterface::class);
         $this->itemDataFactoryMock =
             $this->getMock(\Magento\Quote\Api\Data\CartItemInterfaceFactory::class, ['create'], [], '', false);
-        $this->dataMock = $this->getMock(\Magento\Quote\Model\Quote\Item::class, [], [], '', false);
+        $this->itemMock = $this->getMock(\Magento\Quote\Model\Quote\Item::class, [], [], '', false);
         $this->quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false);
         $this->productMock = $this->getMock(\Magento\Catalog\Model\Product::class, [], [], '', false);
         $methods = ['getId', 'getSku', 'getQty', 'setData', '__wakeUp', 'getProduct', 'addProduct'];
@@ -88,6 +93,20 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
             false
         );
 
+        $this->optionsProcessorMock = $this->getMock(
+            \Magento\Quote\Model\Quote\Item\CartItemOptionsProcessor::class,
+            [],
+            [],
+            '',
+            false
+        );
+        $this->prepareObjectManager([
+            [
+                \Magento\Quote\Model\Quote\Item\CartItemOptionsProcessor::class,
+                $this->optionsProcessorMock
+            ]
+        ]);
+
         $this->repository = new \Magento\Quote\Model\Quote\Item\Repository(
             $this->quoteRepositoryMock,
             $this->productRepositoryMock,
@@ -96,395 +115,40 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
         );
     }
 
-    /**
-     * @param null|string|bool|int|float $value
-     * @return void
-     * @expectedException \Magento\Framework\Exception\InputException
-     * @expectedExceptionMessage Invalid value of
-     * @dataProvider addItemWithInvalidQtyDataProvider
-     */
-    public function testSaveItemWithInvalidQty($value)
-    {
-        $this->markTestSkipped('MAGETWO-48531');
-        $this->dataMock->expects($this->once())->method('getQty')->will($this->returnValue($value));
-        $this->repository->save($this->dataMock);
-    }
-
-    /**
-     * @return array
-     */
-    public function addItemWithInvalidQtyDataProvider()
-    {
-        return [
-            ['string'],
-            [0],
-            [''],
-            [null],
-            [-12],
-            [false],
-            [-13.1],
-        ];
-    }
-
-    /**
-     * @return void
-     * @expectedException \Magento\Framework\Exception\LocalizedException
-     * @expectedExceptionMessage Please specify all the required information.
-     */
-    public function testSaveCouldNotAddProduct()
-    {
-        $this->markTestSkipped('MAGETWO-48531');
-        $cartId = 13;
-        $buyRequest = $this->getMock(\Magento\Framework\DataObject::class, [], [], '', false);
-        $buyRequest->expects($this->once())
-            ->method('setData')
-            ->with('qty', '12');
-        $this->dataMock->expects($this->exactly(2))->method('getQty')->will($this->returnValue(12));
-        $this->dataMock->expects($this->once())->method('getQuoteId')->willReturn($cartId);
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')->with($cartId)->will($this->returnValue($this->quoteMock));
-        $this->productRepositoryMock->expects($this->once())
-            ->method('get')
-            ->will($this->returnValue($this->productMock));
-        $this->dataMock->expects($this->once())->method('getSku');
-        $this->quoteMock
-            ->expects($this->once())
-            ->method('addProduct')
-            ->with($this->productMock, $buyRequest)
-            ->willReturn('Please specify all the required information.');
-        $this->quoteMock->expects($this->never())->method('getItemById');
-        $this->quoteRepositoryMock->expects($this->never())->method('save')->with($this->quoteMock);
-        $this->quoteMock
-            ->expects($this->never())
-            ->method('getAllItems');
-        $this->customOptionProcessor->expects($this->once())
-            ->method('convertToBuyRequest')
-            ->with($this->dataMock)
-            ->willReturn($buyRequest);
-        $this->repository->save($this->dataMock);
-    }
-
-    /**
-     * @return void
-     * @expectedException \Magento\Framework\Exception\CouldNotSaveException
-     * @expectedExceptionMessage Could not save quote
-     */
-    public function testSaveCouldNotSaveException()
-    {
-        $this->markTestSkipped('MAGETWO-48531');
-        $cartId = 13;
-        $buyRequest = $this->getMock(\Magento\Framework\DataObject::class, [], [], '', false);
-        $this->dataMock->expects($this->exactly(2))->method('getQty')->will($this->returnValue(12));
-        $this->dataMock->expects($this->once())->method('getQuoteId')->willReturn($cartId);
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')->with($cartId)->will($this->returnValue($this->quoteMock));
-        $this->productRepositoryMock->expects($this->once())
-            ->method('get')
-            ->will($this->returnValue($this->productMock));
-        $this->dataMock->expects($this->once())->method('getSku');
-        $this->quoteMock
-            ->expects($this->once())
-            ->method('addProduct')
-            ->with($this->productMock, $buyRequest)
-            ->willReturn($this->productMock);
-        $this->quoteMock->expects($this->never())->method('getItemById');
-        $this->quoteMock->expects($this->once())->method('collectTotals')->will($this->returnValue($this->quoteMock));
-        $this->quoteMock->expects($this->once())
-            ->method('getShippingAddress')
-            ->willReturn($this->shippingAddressMock);
-        $this->shippingAddressMock->expects($this->once())
-            ->method('setCollectShippingRates')
-            ->with(true);
-        $this->quoteRepositoryMock->expects($this->once())->method('save')->with($this->quoteMock);
-        $this->dataMock->expects($this->once())->method('getItemId')->will($this->returnValue(null));
-        $exceptionMessage = 'Could not save quote';
-        $exception = new \Magento\Framework\Exception\CouldNotSaveException(__($exceptionMessage));
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('save')
-            ->with($this->quoteMock)
-            ->willThrowException($exception);
-        $this->quoteMock
-            ->expects($this->never())
-            ->method('getAllItems');
-        $this->customOptionProcessor->expects($this->once())
-            ->method('convertToBuyRequest')
-            ->with($this->dataMock)
-            ->willReturn($buyRequest);
-        $buyRequest->expects($this->once())
-            ->method('setData')
-            ->with('qty', '12');
-        $this->repository->save($this->dataMock);
-    }
-
     /**
      * @return void
      */
     public function testSave()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $cartId = 13;
-        $buyRequest = $this->getMock(\Magento\Framework\DataObject::class, [], [], '', false);
-        $buyRequest->expects($this->once())
-            ->method('setData')
-            ->with('qty', '12');
-        $this->dataMock->expects($this->exactly(2))->method('getQty')->will($this->returnValue(12));
-        $this->dataMock->expects($this->once())->method('getQuoteId')->willReturn($cartId);
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')->with($cartId)->will($this->returnValue($this->quoteMock));
-        $this->productRepositoryMock->expects($this->once())
-            ->method('get')
-            ->will($this->returnValue($this->productMock));
-        $this->dataMock->expects($this->once())->method('getSku');
-        $this->quoteMock
-            ->expects($this->once())
-            ->method('addProduct')
-            ->with($this->productMock, $buyRequest)
-            ->willReturn($this->productMock);
-        $this->quoteMock->expects($this->never())->method('getItemById');
-        $this->quoteMock->expects($this->once())->method('collectTotals')->will($this->returnValue($this->quoteMock));
-        $this->quoteMock->expects($this->once())
-            ->method('getShippingAddress')
-            ->willReturn($this->shippingAddressMock);
-        $this->shippingAddressMock->expects($this->once())
-            ->method('setCollectShippingRates')
-            ->with(true);
-        $this->quoteRepositoryMock->expects($this->once())->method('save')->with($this->quoteMock);
-        $this->dataMock->expects($this->once())->method('getItemId')->will($this->returnValue(null));
-        $this->quoteMock
-            ->expects($this->once())
-            ->method('getAllItems')
-            ->willReturn([$this->quoteItemMock]);
-        $this->quoteItemMock->expects($this->any())->method('getId');
-        $this->customOptionProcessor->expects($this->once())
-            ->method('convertToBuyRequest')
-            ->with($this->dataMock)
-            ->willReturn($buyRequest);
-        $this->assertEquals($this->quoteItemMock, $this->repository->save($this->dataMock));
-    }
+        $itemId = 20;
 
-    public function testSaveWithCustomOption()
-    {
-        $this->markTestSkipped('MAGETWO-48531');
-        $cartId = 13;
-        $buyRequest = $this->getMock(\Magento\Framework\DataObject::class, [], [], '', false);
-        $this->dataMock->expects($this->exactly(2))->method('getQty')->will($this->returnValue(12));
-        $this->dataMock->expects($this->once())->method('getQuoteId')->willReturn($cartId);
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')->with($cartId)->will($this->returnValue($this->quoteMock));
-        $this->productRepositoryMock->expects($this->once())
-            ->method('get')
-            ->will($this->returnValue($this->productMock));
-        $this->dataMock->expects($this->once())->method('getSku');
-        $this->quoteMock->expects($this->once())
-            ->method('addProduct')
-            ->with($this->productMock, $buyRequest)
-            ->willReturn($this->productMock);
-        $this->quoteMock->expects($this->never())->method('getItemById');
-        $this->quoteMock->expects($this->once())->method('collectTotals')->will($this->returnValue($this->quoteMock));
-        $this->quoteMock->expects($this->once())
-            ->method('getShippingAddress')
-            ->willReturn($this->shippingAddressMock);
-        $this->shippingAddressMock->expects($this->once())
-            ->method('setCollectShippingRates')
-            ->with(true);
-        $this->quoteRepositoryMock->expects($this->once())->method('save')->with($this->quoteMock);
-        $this->dataMock->expects($this->once())->method('getItemId')->will($this->returnValue(null));
-        $this->quoteMock->expects($this->once())
-            ->method('getAllItems')
-            ->willReturn([$this->quoteItemMock]);
-        $this->quoteItemMock->expects($this->any())->method('getId');
-        $this->customOptionProcessor->expects($this->once())
-            ->method('convertToBuyRequest')
-            ->with($this->dataMock)
-            ->willReturn($buyRequest);
-        $this->assertEquals($this->quoteItemMock, $this->repository->save($this->dataMock));
-    }
+        $quoteMock = $this->getMock(
+            \Magento\Quote\Model\Quote::class,
+            ['getItems', 'setItems', 'collectTotals', 'getLastAddedItem'],
+            [],
+            '',
+            false
+        );
 
-    /**
-     * @return void
-     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
-     * @expectedExceptionMessage Cart 11 doesn't contain item  5
-     */
-    public function testUpdateItemWithInvalidQuoteItem()
-    {
-        $this->markTestSkipped('MAGETWO-48531');
-        $cartId = 11;
-        $itemId = 5;
-        $this->dataMock->expects($this->once())->method('getQty')->will($this->returnValue(12));
-        $this->dataMock->expects($this->once())->method('getQuoteId')->willReturn($cartId);
-        $this->dataMock->expects($this->once())->method('getItemId')->will($this->returnValue($itemId));
+        $this->itemMock->expects($this->once())->method('getQuoteId')->willReturn($cartId);
         $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')->with($cartId)->will($this->returnValue($this->quoteMock));
-        $this->quoteMock->expects($this->once())
-            ->method('getItemById')->with($itemId)->will($this->returnValue(false));
-        $this->quoteItemMock->expects($this->never())->method('setData');
-        $this->quoteItemMock->expects($this->never())->method('addProduct');
+            ->method('getActive')
+            ->with($cartId)
+            ->willReturn($quoteMock);
 
-        $this->repository->save($this->dataMock);
-    }
+        $quoteMock->expects($this->once())->method('getItems')->willReturn([]);
+        $quoteMock->expects($this->once())
+            ->method('setItems')
+            ->with([$this->itemMock])
+            ->willReturnSelf();
 
-    /**
-     * @return void
-     * @expectedException \Magento\Framework\Exception\CouldNotSaveException
-     * @expectedExceptionMessage Could not save quote
-     */
-    public function testUpdateItemWithCouldNotSaveException()
-    {
-        $this->markTestSkipped('MAGETWO-48531');
-        $cartId = 11;
-        $itemId = 5;
-        $buyRequest = $this->getMock(\Magento\Framework\DataObject::class, [], [], '', false);
-        $this->dataMock->expects($this->exactly(2))->method('getQty')->will($this->returnValue(12));
-        $this->dataMock->expects($this->once())->method('getItemId')->will($this->returnValue($itemId));
-        $this->dataMock->expects($this->once())->method('getQuoteId')->willReturn($cartId);
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')->with($cartId)->will($this->returnValue($this->quoteMock));
-        $this->quoteMock->expects($this->once())
-            ->method('getItemById')->with($itemId)->will($this->returnValue($this->quoteItemMock));
-        $this->quoteItemMock->expects($this->any())->method('getProduct')->willReturn($this->productMock);
-        $this->productMock->expects($this->once())->method('getTypeId')->willReturn('simple');
-        $this->quoteItemMock->expects($this->never())->method('setData');
-        $this->productRepositoryMock
-            ->expects($this->never())->method('get');
-        $this->quoteItemMock->expects($this->never())->method('addProduct');
-        $this->quoteMock->expects($this->once())->method('collectTotals')->will($this->returnValue($this->quoteMock));
-        $this->quoteMock
-            ->expects($this->never())
-            ->method('getAllItems');
-        $this->quoteItemMock->expects($this->never())->method('getId');
-        $exceptionMessage = 'Could not save quote';
-        $exception = new \Magento\Framework\Exception\CouldNotSaveException(__($exceptionMessage));
-        $this->quoteMock->expects($this->once())
-            ->method('getShippingAddress')
-            ->willReturn($this->shippingAddressMock);
-        $this->shippingAddressMock->expects($this->once())
-            ->method('setCollectShippingRates')
-            ->with(true);
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('save')
-            ->with($this->quoteMock)
-            ->willThrowException($exception);
-        $this->customOptionProcessor->expects($this->once())
-            ->method('convertToBuyRequest')
-            ->with($this->dataMock)
-            ->willReturn($buyRequest);
-        $buyRequest->expects($this->once())
-            ->method('setData')
-            ->with('qty', '12');
-        $this->repository->save($this->dataMock);
-    }
+        $this->quoteRepositoryMock->expects($this->once())->method('save')->with($quoteMock);
 
-    /**
-     * @return void
-     */
-    public function testUpdateItemQty()
-    {
-        $this->markTestSkipped('MAGETWO-48531');
-        $cartId = 11;
-        $itemId = 5;
-        $buyRequest = $this->getMock(\Magento\Framework\DataObject::class, [], [], '', false);
-        $this->dataMock->expects($this->exactly(2))->method('getQty')->will($this->returnValue(12));
-        $this->dataMock->expects($this->once())->method('getItemId')->will($this->returnValue($itemId));
-        $this->dataMock->expects($this->once())->method('getQuoteId')->willReturn($cartId);
-        $this->dataMock->expects($this->once())->method('getId')->willReturn($itemId);
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')->with($cartId)->will($this->returnValue($this->quoteMock));
-        $this->quoteMock->expects($this->once())
-            ->method('getItemById')->with($itemId)->will($this->returnValue($this->quoteItemMock));
-        $this->quoteItemMock->expects($this->once())->method('getProduct')->willReturn($this->productMock);
-        $this->productMock->expects($this->once())->method('getTypeId')->willReturn('simple');
-        $this->quoteItemMock->expects($this->never())->method('setData');
-        $this->productRepositoryMock
-            ->expects($this->never())->method('get');
-        $this->quoteItemMock->expects($this->never())->method('addProduct');
-        $this->quoteMock->expects($this->once())->method('collectTotals')->will($this->returnValue($this->quoteMock));
-        $this->quoteMock->expects($this->once())
-            ->method('getShippingAddress')
-            ->willReturn($this->shippingAddressMock);
-        $this->shippingAddressMock->expects($this->once())
-            ->method('setCollectShippingRates')
-            ->with(true);
-        $this->quoteRepositoryMock->expects($this->once())->method('save')->with($this->quoteMock);
-        $this->quoteMock
-            ->expects($this->once())
-            ->method('getAllItems')
-            ->willReturn([$this->quoteItemMock]);
-        $this->quoteItemMock->expects($this->any())->method('getId')->willReturn($itemId);
-        $this->customOptionProcessor->expects($this->once())
-            ->method('convertToBuyRequest')
-            ->with($this->dataMock)
-            ->willReturn($buyRequest);
-        $buyRequest->expects($this->once())
-            ->method('setData')
-            ->with('qty', '12');
-        $this->quoteMock->expects($this->once())
-            ->method('updateItem')
-            ->with($itemId, $buyRequest)
-            ->willReturn($this->dataMock);
-        $this->assertEquals($this->quoteItemMock, $this->repository->save($this->dataMock));
-    }
+        $quoteMock->expects($this->once())->method('collectTotals')->willReturnSelf();
+        $quoteMock->expects($this->once())->method('getLastAddedItem')->willReturn($itemId);
 
-    /**
-     * @return void
-     */
-    public function testUpdateItemOptions()
-    {
-        $this->markTestSkipped('MAGETWO-48531');
-        $cartId = 11;
-        $itemId = 5;
-        $buyRequest = $this->getMock(\Magento\Framework\DataObject::class, [], [], '', false);
-        $cartItemProcessorMock = $this->getMock(\Magento\Quote\Model\Quote\Item\CartItemProcessorInterface::class);
-        $this->repository = new \Magento\Quote\Model\Quote\Item\Repository(
-            $this->quoteRepositoryMock,
-            $this->productRepositoryMock,
-            $this->itemDataFactoryMock,
-            ['simple' => $cartItemProcessorMock, 'custom_options' => $this->customOptionProcessor]
-        );
-        $requestMock = $this->getMock(\Magento\Framework\DataObject::class, ['setQty', 'getData'], [], '', false);
-        $cartItemProcessorMock->expects($this->once())->method('convertToBuyRequest')->willReturn($requestMock);
-        $cartItemProcessorMock
-            ->expects($this->once())
-            ->method('processOptions')
-            ->willReturn($this->quoteItemMock);
-        $requestMock->expects($this->once())->method('setQty')->with(12)->willReturnSelf();
-        $requestMock->expects($this->once())
-            ->method('getData')
-            ->willReturn([]);
-        $this->quoteMock
-            ->expects($this->once())
-            ->method('updateItem')
-            ->with($itemId, $buyRequest)
-            ->willReturn($this->quoteItemMock);
-        $this->dataMock->expects($this->any())->method('getQty')->will($this->returnValue(12));
-        $this->dataMock->expects($this->once())->method('getItemId')->will($this->returnValue($itemId));
-        $this->dataMock->expects($this->once())->method('getQuoteId')->willReturn($cartId);
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')->with($cartId)->will($this->returnValue($this->quoteMock));
-        $this->quoteMock->expects($this->once())
-            ->method('getItemById')->with($itemId)->will($this->returnValue($this->quoteItemMock));
-        $this->quoteItemMock->expects($this->once())->method('getProduct')->willReturn($this->productMock);
-        $this->productMock->expects($this->once())->method('getTypeId')->willReturn('simple');
-        $this->productRepositoryMock
-            ->expects($this->never())->method('get');
-        $this->quoteMock->expects($this->once())->method('collectTotals')->will($this->returnValue($this->quoteMock));
-        $this->quoteMock->expects($this->once())
-            ->method('getShippingAddress')
-            ->willReturn($this->shippingAddressMock);
-        $this->shippingAddressMock->expects($this->once())
-            ->method('setCollectShippingRates')
-            ->with(true);
-        $this->quoteRepositoryMock->expects($this->once())->method('save')->with($this->quoteMock);
-        $this->quoteMock
-            ->expects($this->once())
-            ->method('getAllItems')
-            ->willReturn([$this->quoteItemMock]);
-        $this->quoteItemMock->expects($this->any())->method('getId')->willReturn($itemId);
-        $this->quoteItemMock->expects($this->any())->method('getQty')->willReturn(12);
-        $this->customOptionProcessor->expects($this->once())
-            ->method('convertToBuyRequest')
-            ->with($this->dataMock)
-            ->willReturn($buyRequest);
-        $this->assertEquals($this->quoteItemMock, $this->repository->save($this->dataMock));
+        $this->assertEquals($itemId, $this->repository->save($this->itemMock));
     }
 
     /**
@@ -512,16 +176,20 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
      */
     public function testDeleteWithCouldNotSaveException()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $cartId = 11;
         $itemId = 5;
         $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')->with($cartId)->will($this->returnValue($this->quoteMock));
+            ->method('getActive')
+            ->with($cartId)
+            ->willReturn($this->quoteMock);
         $this->quoteMock->expects($this->once())
-            ->method('getItemById')->with($itemId)->will($this->returnValue($this->quoteItemMock));
+            ->method('getItemById')
+            ->with($itemId)
+            ->willReturn($this->quoteItemMock);
         $this->quoteMock->expects($this->once())
-            ->method('removeItem')->with($itemId)->will($this->returnValue($this->quoteMock));
-        $this->quoteMock->expects($this->once())->method('collectTotals')->will($this->returnValue($this->quoteMock));
+            ->method('removeItem')
+            ->with($itemId)
+            ->willReturn($this->quoteMock);
         $exceptionMessage = 'Could not remove item from quote';
         $exception = new \Magento\Framework\Exception\CouldNotSaveException(__($exceptionMessage));
         $this->quoteRepositoryMock->expects($this->once())
@@ -537,13 +205,23 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
      */
     public function testGetList()
     {
-        $this->markTestSkipped('MAGETWO-48531');
+        $productType = 'type';
         $quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false);
         $this->quoteRepositoryMock->expects($this->once())->method('getActive')
             ->with(33)
             ->will($this->returnValue($quoteMock));
         $itemMock = $this->getMock(\Magento\Quote\Model\Quote\Item::class, [], [], '', false);
-        $quoteMock->expects($this->any())->method('getAllItems')->will($this->returnValue([$itemMock]));
+        $quoteMock->expects($this->once())->method('getAllVisibleItems')->will($this->returnValue([$itemMock]));
+        $itemMock->expects($this->once())->method('getProductType')->willReturn($productType);
+
+        $this->optionsProcessorMock->expects($this->once())
+            ->method('addProductOptions')
+            ->with($productType, $itemMock)
+            ->willReturn($itemMock);
+        $this->optionsProcessorMock->expects($this->once())
+            ->method('applyCustomOptions')
+            ->with($itemMock)
+            ->willReturn($itemMock);
 
         $this->assertEquals([$itemMock], $this->repository->getList(33));
     }
@@ -553,17 +231,35 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
      */
     public function testDeleteById()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $cartId = 11;
         $itemId = 5;
         $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')->with($cartId)->will($this->returnValue($this->quoteMock));
+            ->method('getActive')
+            ->with($cartId)
+            ->willReturn($this->quoteMock);
         $this->quoteMock->expects($this->once())
-            ->method('getItemById')->with($itemId)->will($this->returnValue($this->quoteItemMock));
+            ->method('getItemById')
+            ->with($itemId)
+            ->willReturn($this->quoteItemMock);
         $this->quoteMock->expects($this->once())->method('removeItem');
-        $this->quoteMock->expects($this->once())->method('collectTotals')->will($this->returnValue($this->quoteMock));
         $this->quoteRepositoryMock->expects($this->once())->method('save')->with($this->quoteMock);
 
         $this->assertTrue($this->repository->deleteById($cartId, $itemId));
     }
+
+    /**
+     * @param array $map
+     */
+    private function prepareObjectManager($map)
+    {
+        $objectManagerMock = $this->getMock(\Magento\Framework\ObjectManagerInterface::class);
+        $objectManagerMock->expects($this->any())->method('getInstance')->willReturnSelf();
+        $objectManagerMock->expects($this->any())
+            ->method('get')
+            ->will($this->returnValueMap($map));
+        $reflectionClass = new \ReflectionClass(\Magento\Framework\App\ObjectManager::class);
+        $reflectionProperty = $reflectionClass->getProperty('_instance');
+        $reflectionProperty->setAccessible(true);
+        $reflectionProperty->setValue($objectManagerMock);
+    }
 }
diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteAddressValidatorTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteAddressValidatorTest.php
index 2ba9aaa751e4d4d58107f2dedd151d93c5a1ea3a..9d75c219e697877f94e5932777a4536a08ded08e 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/QuoteAddressValidatorTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteAddressValidatorTest.php
@@ -96,10 +96,10 @@ class QuoteAddressValidatorTest extends \PHPUnit_Framework_TestCase
      */
     public function testValidateInvalidAddress()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $address = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class);
         $this->customerRepositoryMock->expects($this->never())->method('getById');
-        $address->expects($this->atLeastOnce())->method('getId')->willReturn(101);
+        $address->expects($this->atLeastOnce())->method('getCustomerAddressId')->willReturn(101);
+        $address->expects($this->once())->method('getId')->willReturn(101);
 
         $this->addressRepositoryMock->expects($this->once())->method('getById')
             ->willThrowException(new \Magento\Framework\Exception\NoSuchEntityException());
@@ -118,70 +118,23 @@ class QuoteAddressValidatorTest extends \PHPUnit_Framework_TestCase
         $this->assertTrue($this->model->validate($address));
     }
 
-    /**
-     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
-     * @expectedExceptionMessage Invalid address id 100
-     */
-    public function testValidateWithAddressOfOtherCustomer()
-    {
-        $this->markTestSkipped('MAGETWO-48531');
-        $addressCustomer = 100;
-        $addressId = 100;
-        $address = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class);
-        $customerMock = $this->getMock(\Magento\Customer\Api\Data\CustomerInterface::class);
-
-        $this->customerRepositoryMock->expects($this->once())->method('getById')->with($addressCustomer)
-            ->willReturn($customerMock);
-        $this->addressRepositoryMock->expects($this->once())->method('getById')->willReturn($this->quoteAddressMock);
-        $customerMock->expects($this->once())->method('getId')->willReturn(42);
-        $address->expects($this->atLeastOnce())->method('getId')->willReturn($addressId);
-        $address->expects($this->atLeastOnce())->method('getCustomerId')->willReturn($addressCustomer);
-
-        $this->quoteAddressMock->expects($this->once())->method('getCustomerId')->willReturn(42);
-        $this->model->validate($address);
-    }
-
-    /**
-     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
-     * @expectedExceptionMessage Invalid address id 42
-     */
-    public function testValidateWithInvalidCustomerAddressId()
-    {
-        $this->markTestSkipped('MAGETWO-48531');
-        $customerAddressId = 42;
-        $address = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class);
-        $customerAddress = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class);
-        $customerMock = $this->getMock(\Magento\Customer\Api\Data\CustomerInterface::class);
-
-        $address->expects($this->atLeastOnce())->method('getCustomerAddressId')->willReturn($customerAddressId);
-        $this->customerSessionMock->expects($this->once())->method('getCustomerDataObject')->willReturn($customerMock);
-        $customerMock->expects($this->once())->method('getAddresses')->willReturn([$customerAddress]);
-        $customerAddress->expects($this->once())->method('getId')->willReturn(43);
-
-        $this->model->validate($address);
-    }
-
     public function testValidateWithValidAddress()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $addressCustomer = 100;
-        $addressId = 100;
         $customerAddressId = 42;
 
         $address = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class);
-        $address->expects($this->atLeastOnce())->method('getId')->willReturn($addressId);
         $address->expects($this->atLeastOnce())->method('getCustomerId')->willReturn($addressCustomer);
         $address->expects($this->atLeastOnce())->method('getCustomerAddressId')->willReturn($customerAddressId);
         $customerMock = $this->getMock(\Magento\Customer\Api\Data\CustomerInterface::class);
         $customerAddress = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class);
 
-        $this->customerRepositoryMock->expects($this->once())->method('getById')->willReturn($customerMock);
+        $this->customerRepositoryMock->expects($this->exactly(2))->method('getById')->willReturn($customerMock);
         $customerMock->expects($this->once())->method('getId')->willReturn($addressCustomer);
 
         $this->addressRepositoryMock->expects($this->once())->method('getById')->willReturn($this->quoteAddressMock);
         $this->quoteAddressMock->expects($this->any())->method('getCustomerId')->willReturn($addressCustomer);
 
-        $this->customerSessionMock->expects($this->once())->method('getCustomerDataObject')->willReturn($customerMock);
         $customerMock->expects($this->once())->method('getAddresses')->willReturn([$customerAddress]);
         $customerAddress->expects($this->once())->method('getId')->willReturn(42);
 
diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php
index 3bd838d9d4b75f0c8d0fe1ab7188883283e61b72..891eb108b224deb9a35bd05e7e57ae903fea243d 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php
@@ -11,6 +11,7 @@ use Magento\Framework\Api\SortOrder;
 use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
 use Magento\Quote\Api\Data\CartInterface;
 use Magento\Quote\Model\QuoteRepository\LoadHandler;
+use Magento\Quote\Model\QuoteRepository\SaveHandler;
 use Magento\Quote\Model\ResourceModel\Quote\CollectionFactory;
 
 /**
@@ -63,6 +64,11 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase
      */
     private $loadHandlerMock;
 
+    /**
+     * @var LoadHandler|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $saveHandlerMock;
+
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
@@ -91,7 +97,9 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase
                 'setSharedStoreIds',
                 'save',
                 'delete',
-                'getCustomerId'
+                'getCustomerId',
+                'getStoreId',
+                'getData'
             ],
             [],
             '',
@@ -136,10 +144,16 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->loadHandlerMock = $this->getMock(LoadHandler::class, [], [], '', false);
+        $this->saveHandlerMock = $this->getMock(SaveHandler::class, [], [], '', false);
+
         $reflection = new \ReflectionClass(get_class($this->model));
         $reflectionProperty = $reflection->getProperty('loadHandler');
         $reflectionProperty->setAccessible(true);
         $reflectionProperty->setValue($this->model, $this->loadHandlerMock);
+
+        $reflectionProperty = $reflection->getProperty('saveHandler');
+        $reflectionProperty->setAccessible(true);
+        $reflectionProperty->setValue($this->model, $this->saveHandlerMock);
     }
 
     /**
@@ -235,7 +249,6 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase
 
     public function testGetWithSharedStoreIds()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $cartId = 16;
         $sharedStoreIds = [1, 2];
 
@@ -252,7 +265,11 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase
             ->willReturn($this->storeMock);
         $this->quoteMock->expects($this->once())->method('getId')->willReturn($cartId);
 
-        $this->assertEquals($this->quoteMock, $this->model->get($cartId, $sharedStoreIds));
+        $this->loadHandlerMock->expects($this->once())
+            ->method('load')
+            ->with($this->quoteMock)
+            ->willReturn($this->quoteMock);
+
         $this->assertEquals($this->quoteMock, $this->model->get($cartId, $sharedStoreIds));
     }
 
@@ -316,7 +333,6 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase
      */
     public function testGetActiveWithExceptionByIsActive()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $cartId = 15;
 
         $this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock);
@@ -330,12 +346,16 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase
         $this->quoteMock->expects($this->once())->method('getId')->willReturn($cartId);
         $this->quoteMock->expects($this->once())->method('getIsActive')->willReturn(0);
 
+        $this->loadHandlerMock->expects($this->once())
+            ->method('load')
+            ->with($this->quoteMock)
+            ->willReturn($this->quoteMock);
+
         $this->model->getActive($cartId);
     }
 
     public function testGetActive()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $cartId = 15;
 
         $this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock);
@@ -347,15 +367,18 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase
             ->with($cartId)
             ->willReturn($this->storeMock);
         $this->quoteMock->expects($this->once())->method('getId')->willReturn($cartId);
-        $this->quoteMock->expects($this->exactly(2))->method('getIsActive')->willReturn(1);
+        $this->quoteMock->expects($this->once())->method('getIsActive')->willReturn(1);
+
+        $this->loadHandlerMock->expects($this->once())
+            ->method('load')
+            ->with($this->quoteMock)
+            ->willReturn($this->quoteMock);
 
-        $this->assertEquals($this->quoteMock, $this->model->getActive($cartId));
         $this->assertEquals($this->quoteMock, $this->model->getActive($cartId));
     }
 
     public function testGetActiveWithSharedStoreIds()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $cartId = 16;
         $sharedStoreIds = [1, 2];
 
@@ -371,15 +394,18 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase
             ->with($cartId)
             ->willReturn($this->storeMock);
         $this->quoteMock->expects($this->once())->method('getId')->willReturn($cartId);
-        $this->quoteMock->expects($this->exactly(2))->method('getIsActive')->willReturn(1);
+        $this->quoteMock->expects($this->once())->method('getIsActive')->willReturn(1);
+
+        $this->loadHandlerMock->expects($this->once())
+            ->method('load')
+            ->with($this->quoteMock)
+            ->willReturn($this->quoteMock);
 
-        $this->assertEquals($this->quoteMock, $this->model->getActive($cartId, $sharedStoreIds));
         $this->assertEquals($this->quoteMock, $this->model->getActive($cartId, $sharedStoreIds));
     }
 
     public function testGetActiveForCustomer()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $cartId = 17;
         $customerId = 23;
 
@@ -394,19 +420,50 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase
         $this->quoteMock->expects($this->exactly(2))->method('getId')->willReturn($cartId);
         $this->quoteMock->expects($this->exactly(2))->method('getIsActive')->willReturn(1);
 
+        $this->loadHandlerMock->expects($this->once())
+            ->method('load')
+            ->with($this->quoteMock)
+            ->willReturn($this->quoteMock);
+
         $this->assertEquals($this->quoteMock, $this->model->getActiveForCustomer($customerId));
         $this->assertEquals($this->quoteMock, $this->model->getActiveForCustomer($customerId));
     }
 
     public function testSave()
     {
-        $this->markTestSkipped('MAGETWO-48531');
+        $cartId = 100;
+        $quoteMock = $this->getMock(
+            \Magento\Quote\Model\Quote::class,
+            ['getId', 'getCustomerId', 'getStoreId', 'hasData', 'setData'],
+            [],
+            '',
+            false
+        );
+        $quoteMock->expects($this->exactly(3))->method('getId')->willReturn($cartId);
+        $quoteMock->expects($this->once())->method('getCustomerId')->willReturn(2);
+        $quoteMock->expects($this->once())->method('getStoreId')->willReturn(5);
+
+        $this->quoteFactoryMock->expects($this->once())->method('create')->willReturn($this->quoteMock);
+        $this->storeManagerMock->expects($this->once())->method('getStore')->willReturn($this->storeMock);
+        $this->storeMock->expects($this->once())->method('getId')->willReturn(1);
+        $this->quoteMock->expects($this->once())->method('getId')->willReturn($cartId);
+        $this->quoteMock->expects($this->once())->method('setSharedStoreIds');
         $this->quoteMock->expects($this->once())
-            ->method('save');
-        $this->quoteMock->expects($this->exactly(1))->method('getId')->willReturn(1);
-        $this->quoteMock->expects($this->exactly(1))->method('getCustomerId')->willReturn(2);
+            ->method('load')
+            ->with($cartId)
+            ->willReturn($this->storeMock);
+        $this->loadHandlerMock->expects($this->once())
+            ->method('load')
+            ->with($this->quoteMock)
+            ->willReturn($this->quoteMock);
+
+        $this->quoteMock->expects($this->once())->method('getData')->willReturn(['key' => 'value']);
+
+        $quoteMock->expects($this->once())->method('hasData')->with('key')->willReturn(false);
+        $quoteMock->expects($this->once())->method('setData')->with('key', 'value')->willReturnSelf();
 
-        $this->model->save($this->quoteMock);
+        $this->saveHandlerMock->expects($this->once())->method('save')->with($quoteMock)->willReturn($quoteMock);
+        $this->model->save($quoteMock);
     }
 
     public function testDelete()
diff --git a/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressAssignmentTest.php b/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressAssignmentTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1acf50a4d4b4fca86c43df4c78c6114611024144
--- /dev/null
+++ b/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressAssignmentTest.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Quote\Test\Unit\Model;
+
+class ShippingAddressAssignmentTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Quote\Model\ShippingAddressAssignment
+     */
+    private $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $shippingAssignmentProcessorMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $cartExtensionFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $quoteMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $addressMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $extensionAttributeMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $shippingAssignmentMock;
+
+    public function setUp()
+    {
+        $this->cartExtensionFactoryMock = $this->getMock(
+            \Magento\Quote\Api\Data\CartExtensionFactory::class,
+            ['create'],
+            [],
+            '',
+            false
+        );
+        $this->shippingAssignmentProcessorMock = $this->getMock(
+            \Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentProcessor::class,
+            [],
+            [],
+            '',
+            false
+        );
+        $this->quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false);
+        $this->addressMock = $this->getMock(\Magento\Quote\Model\Quote\Address::class, [], [], '', false);
+        $this->extensionAttributeMock = $this->getMock(
+            \Magento\Quote\Api\Data\CartExtension::class,
+            ['setShippingAssignments'],
+            [],
+            '',
+            false
+        );
+
+        $this->shippingAssignmentMock = $this->getMock(\Magento\Quote\Api\Data\ShippingAssignmentInterface::class);
+        //shipping assignment processing
+        $this->quoteMock->expects($this->once())->method('getExtensionAttributes')->willReturn(null);
+        $this->cartExtensionFactoryMock
+            ->expects($this->once())
+            ->method('create')
+            ->willReturn($this->extensionAttributeMock);
+        $this->shippingAssignmentProcessorMock
+            ->expects($this->once())
+            ->method('create')
+            ->willReturn($this->shippingAssignmentMock);
+        $this->extensionAttributeMock
+            ->expects($this->once())
+            ->method('setShippingAssignments')
+            ->with([$this->shippingAssignmentMock])
+            ->willReturnSelf();
+        $this->quoteMock->expects($this->once())->method('setExtensionAttributes')->with($this->extensionAttributeMock);
+        $this->model = new \Magento\Quote\Model\ShippingAddressAssignment(
+            $this->cartExtensionFactoryMock,
+            $this->shippingAssignmentProcessorMock
+        );
+    }
+
+    public function testSetAddressUseForShippingTrue()
+    {
+        $addressId = 1;
+        $addressMock = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class);
+        $this->quoteMock->expects($this->once())->method('getShippingAddress')->willReturn($addressMock);
+        $addressMock->expects($this->once())->method('getId')->willReturn($addressId);
+        $this->addressMock->expects($this->once())->method('setSameAsBilling')->with(1);
+        $this->quoteMock->expects($this->once())->method('removeAddress')->with($addressId);
+        $this->quoteMock->expects($this->once())->method('setShippingAddress')->with($this->addressMock);
+        $this->model->setAddress($this->quoteMock, $this->addressMock, true);
+    }
+
+    public function testSetAddressUseForShippingFalse()
+    {
+        $addressMock = $this->getMock(\Magento\Quote\Api\Data\AddressInterface::class);
+        $this->quoteMock->expects($this->once())->method('getShippingAddress')->willReturn($addressMock);
+        $addressMock->expects($this->once())->method('setSameAsBilling')->with(0)->willReturnSelf();
+        $this->quoteMock->expects($this->once())->method('setShippingAddress')->with($addressMock);
+        $this->model->setAddress($this->quoteMock, $this->addressMock, false);
+    }
+}
diff --git a/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressManagementTest.php b/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressManagementTest.php
index 09125c032872513c9d5bfb10401c89c36549bf81..abae7bae110e6521fbf7b708270eb32cb6792c69 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressManagementTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressManagementTest.php
@@ -50,6 +50,16 @@ class ShippingAddressManagementTest extends \PHPUnit_Framework_TestCase
      */
     protected $totalsCollectorMock;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $addressRepository;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $amountErrorMessageMock;
+
     protected function setUp()
     {
         $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
@@ -66,7 +76,10 @@ class ShippingAddressManagementTest extends \PHPUnit_Framework_TestCase
                 'save',
                 'getId',
                 'getCustomerAddressId',
-                'getSaveInAddressBook'
+                'getSaveInAddressBook',
+                'getSameAsBilling',
+                'importCustomerAddressData',
+                'setSaveInAddressBook',
             ],
             [],
             '',
@@ -82,6 +95,22 @@ class ShippingAddressManagementTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
+        $this->addressRepository = $this->getMock(\Magento\Customer\Api\AddressRepositoryInterface::class);
+
+        $this->amountErrorMessageMock = $this->getMock(
+            \Magento\Quote\Model\Quote\Validator\MinimumOrderAmount\ValidationMessage::class,
+            ['getMessage'],
+            [],
+            '',
+            false
+        );
+        $this->prepareObjectManager([
+            [
+                \Magento\Quote\Model\Quote\Validator\MinimumOrderAmount\ValidationMessage::class,
+                $this->amountErrorMessageMock
+            ]
+        ]);
+
         $this->service = $this->objectManager->getObject(
             \Magento\Quote\Model\ShippingAddressManagement::class,
             [
@@ -89,7 +118,8 @@ class ShippingAddressManagementTest extends \PHPUnit_Framework_TestCase
                 'addressValidator' => $this->validatorMock,
                 'logger' => $this->getMock(\Psr\Log\LoggerInterface::class),
                 'scopeConfig' => $this->scopeConfigMock,
-                'totalsCollector' => $this->totalsCollectorMock
+                'totalsCollector' => $this->totalsCollectorMock,
+                'addressRepository' => $this->addressRepository
             ]
         );
     }
@@ -114,34 +144,58 @@ class ShippingAddressManagementTest extends \PHPUnit_Framework_TestCase
 
     public function testSetAddress()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $addressId = 1;
-        $quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false);
+        $customerAddressId = 150;
+
+        $quoteMock = $this->getMock(
+            \Magento\Quote\Model\Quote::class,
+            ['getIsMultiShipping', 'isVirtual', 'validateMinimumAmount', 'setShippingAddress', 'getShippingAddress'],
+            [],
+            '',
+            false
+        );
         $this->quoteRepositoryMock->expects($this->once())
             ->method('getActive')
             ->with('cart867')
-            ->will($this->returnValue($quoteMock));
+            ->willReturn($quoteMock);
         $quoteMock->expects($this->once())->method('isVirtual')->will($this->returnValue(false));
+        $quoteMock->expects($this->once())
+            ->method('setShippingAddress')
+            ->with($this->quoteAddressMock)
+            ->willReturnSelf();
+
+        $this->quoteAddressMock->expects($this->once())->method('getSaveInAddressBook')->willReturn(1);
+        $this->quoteAddressMock->expects($this->once())->method('getSameAsBilling')->willReturn(1);
+        $this->quoteAddressMock->expects($this->once())->method('getCustomerAddressId')->willReturn($customerAddressId);
+
+        $customerAddressMock = $this->getMock(\Magento\Customer\Api\Data\AddressInterface::class);
 
+        $this->addressRepository->expects($this->once())
+            ->method('getById')
+            ->with($customerAddressId)
+            ->willReturn($customerAddressMock);
 
         $this->validatorMock->expects($this->once())->method('validate')
             ->with($this->quoteAddressMock)
-            ->will($this->returnValue(true));
-        $this->totalsCollectorMock
-            ->expects($this->once())
-            ->method('collectAddressTotals')
-            ->with($quoteMock, $this->quoteAddressMock);
-        $this->quoteAddressMock->expects($this->once())->method('save')->willReturnSelf();
-        $this->quoteAddressMock->expects($this->once())->method('getId')->will($this->returnValue($addressId));
+            ->willReturn(true);
 
-        $quoteMock->expects($this->any())
-            ->method('setShippingAddress')
-            ->with($this->quoteAddressMock)
+        $quoteMock->expects($this->exactly(3))->method('getShippingAddress')->willReturn($this->quoteAddressMock);
+        $this->quoteAddressMock->expects($this->once())
+            ->method('importCustomerAddressData')
+            ->with($customerAddressMock)
             ->willReturnSelf();
-        $quoteMock->expects($this->any())
-            ->method('getShippingAddress')
-            ->will($this->returnValue($this->quoteAddressMock));
-        $quoteMock->expects($this->once())->method('validateMinimumAmount')->willReturn(true);
+
+        $this->quoteAddressMock->expects($this->once())->method('setSameAsBilling')->with(1)->willReturnSelf();
+        $this->quoteAddressMock->expects($this->once())->method('setSaveInAddressBook')->with(1)->willReturnSelf();
+        $this->quoteAddressMock->expects($this->once())
+            ->method('setCollectShippingRates')
+            ->with(true)
+            ->willReturnSelf();
+        $quoteMock->expects($this->once())->method('getIsMultiShipping')->willReturn(false);
+        $quoteMock->expects($this->once())->method('validateMinimumAmount')->with(false)->willReturn(true);
+
+        $this->quoteAddressMock->expects($this->once())->method('save')->willReturnSelf();
+        $this->quoteAddressMock->expects($this->once())->method('getId')->will($this->returnValue($addressId));
 
         $this->assertEquals($addressId, $this->service->assign('cart867', $this->quoteAddressMock));
     }
@@ -174,52 +228,122 @@ class ShippingAddressManagementTest extends \PHPUnit_Framework_TestCase
      */
     public function testSetAddressWithInabilityToSaveQuote()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $this->quoteAddressMock->expects($this->once())->method('save')->willThrowException(
             new \Exception('Unable to save address. Please check input data.')
         );
 
-        $quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false);
-        $this->totalsCollectorMock
-            ->expects($this->once())
-            ->method('collectAddressTotals')
-            ->with($quoteMock, $this->quoteAddressMock);
+        $customerAddressId = 150;
+
+        $quoteMock = $this->getMock(
+            \Magento\Quote\Model\Quote::class,
+            ['getIsMultiShipping', 'isVirtual', 'validateMinimumAmount', 'setShippingAddress', 'getShippingAddress'],
+            [],
+            '',
+            false
+        );
         $this->quoteRepositoryMock->expects($this->once())
             ->method('getActive')
             ->with('cart867')
-            ->will($this->returnValue($quoteMock));
+            ->willReturn($quoteMock);
         $quoteMock->expects($this->once())->method('isVirtual')->will($this->returnValue(false));
-        $quoteMock->expects($this->once())->method('getShippingAddress')->willReturn($this->quoteAddressMock);
+        $quoteMock->expects($this->once())
+            ->method('setShippingAddress')
+            ->with($this->quoteAddressMock)
+            ->willReturnSelf();
+
+        $customerAddressMock = $this->getMock(\Magento\Customer\Api\Data\AddressInterface::class);
+
+        $this->addressRepository->expects($this->once())
+            ->method('getById')
+            ->with($customerAddressId)
+            ->willReturn($customerAddressMock);
 
         $this->validatorMock->expects($this->once())->method('validate')
             ->with($this->quoteAddressMock)
-            ->will($this->returnValue(true));
+            ->willReturn(true);
+
+        $this->quoteAddressMock->expects($this->once())->method('getSaveInAddressBook')->willReturn(1);
+        $this->quoteAddressMock->expects($this->once())->method('getSameAsBilling')->willReturn(1);
+        $this->quoteAddressMock->expects($this->once())->method('getCustomerAddressId')->willReturn($customerAddressId);
+
+        $quoteMock->expects($this->exactly(2))->method('getShippingAddress')->willReturn($this->quoteAddressMock);
+        $this->quoteAddressMock->expects($this->once())
+            ->method('importCustomerAddressData')
+            ->with($customerAddressMock)
+            ->willReturnSelf();
+
+        $this->quoteAddressMock->expects($this->once())->method('setSameAsBilling')->with(1)->willReturnSelf();
+        $this->quoteAddressMock->expects($this->once())->method('setSaveInAddressBook')->with(1)->willReturnSelf();
+        $this->quoteAddressMock->expects($this->once())
+            ->method('setCollectShippingRates')
+            ->with(true)
+            ->willReturnSelf();
+        $quoteMock->expects($this->once())->method('getIsMultiShipping')->willReturn(false);
+        $quoteMock->expects($this->once())->method('validateMinimumAmount')->with(false)->willReturn(true);
+
         $this->service->assign('cart867', $this->quoteAddressMock);
     }
 
     /**
      * @expectedException \Magento\Framework\Exception\InputException
+     * @expectedExceptionMessage Incorrect amount
      */
     public function testSetAddressWithViolationOfMinimumAmount()
     {
-        $this->markTestSkipped('MAGETWO-48531');
-        $storeId = 12;
-        $this->quoteAddressMock->expects($this->once())->method('save');
+        $customerAddressId = 150;
 
-        $quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false);
-        $this->quoteRepositoryMock->expects($this->once())->method('getActive')->with('cart123')
-            ->will($this->returnValue($quoteMock));
+        $quoteMock = $this->getMock(
+            \Magento\Quote\Model\Quote::class,
+            ['getIsMultiShipping', 'isVirtual', 'validateMinimumAmount', 'setShippingAddress', 'getShippingAddress'],
+            [],
+            '',
+            false
+        );
+        $this->quoteRepositoryMock->expects($this->once())
+            ->method('getActive')
+            ->with('cart867')
+            ->willReturn($quoteMock);
         $quoteMock->expects($this->once())->method('isVirtual')->will($this->returnValue(false));
-        $quoteMock->expects($this->once())->method('getShippingAddress')->willReturn($this->quoteAddressMock);
-        $quoteMock->expects($this->any())->method('getStoreId')->will($this->returnValue($storeId));
-        $this->totalsCollectorMock
-            ->expects($this->once())
-            ->method('collectAddressTotals')
-            ->with($quoteMock, $this->quoteAddressMock);
-        $this->scopeConfigMock->expects($this->once())->method('getValue')
-            ->with('sales/minimum_order/error_message', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $storeId);
-
-        $this->service->assign('cart123', $this->quoteAddressMock);
+        $quoteMock->expects($this->once())
+            ->method('setShippingAddress')
+            ->with($this->quoteAddressMock)
+            ->willReturnSelf();
+
+        $customerAddressMock = $this->getMock(\Magento\Customer\Api\Data\AddressInterface::class);
+
+        $this->addressRepository->expects($this->once())
+            ->method('getById')
+            ->with($customerAddressId)
+            ->willReturn($customerAddressMock);
+
+        $this->validatorMock->expects($this->once())->method('validate')
+            ->with($this->quoteAddressMock)
+            ->willReturn(true);
+
+        $this->quoteAddressMock->expects($this->once())->method('getSaveInAddressBook')->willReturn(1);
+        $this->quoteAddressMock->expects($this->once())->method('getSameAsBilling')->willReturn(1);
+        $this->quoteAddressMock->expects($this->once())->method('getCustomerAddressId')->willReturn($customerAddressId);
+
+        $quoteMock->expects($this->exactly(2))->method('getShippingAddress')->willReturn($this->quoteAddressMock);
+        $this->quoteAddressMock->expects($this->once())
+            ->method('importCustomerAddressData')
+            ->with($customerAddressMock)
+            ->willReturnSelf();
+
+        $this->quoteAddressMock->expects($this->once())->method('setSameAsBilling')->with(1)->willReturnSelf();
+        $this->quoteAddressMock->expects($this->once())->method('setSaveInAddressBook')->with(1)->willReturnSelf();
+        $this->quoteAddressMock->expects($this->once())
+            ->method('setCollectShippingRates')
+            ->with(true)
+            ->willReturnSelf();
+
+        $this->amountErrorMessageMock->expects($this->once())
+            ->method('getMessage')
+            ->willReturn(__('Incorrect amount'));
+        $quoteMock->expects($this->once())->method('getIsMultiShipping')->willReturn(false);
+        $quoteMock->expects($this->once())->method('validateMinimumAmount')->with(false)->willReturn(false);
+
+        $this->service->assign('cart867', $this->quoteAddressMock);
     }
 
     public function testGetAddress()
@@ -251,4 +375,20 @@ class ShippingAddressManagementTest extends \PHPUnit_Framework_TestCase
 
         $this->service->get('cartId');
     }
+
+    /**
+     * @param $map
+     */
+    private function prepareObjectManager($map)
+    {
+        $objectManagerMock = $this->getMock(\Magento\Framework\ObjectManagerInterface::class);
+        $objectManagerMock->expects($this->any())->method('getInstance')->willReturnSelf();
+        $objectManagerMock->expects($this->any())
+            ->method('get')
+            ->will($this->returnValueMap($map));
+        $reflectionClass = new \ReflectionClass(\Magento\Framework\App\ObjectManager::class);
+        $reflectionProperty = $reflectionClass->getProperty('_instance');
+        $reflectionProperty->setAccessible(true);
+        $reflectionProperty->setValue($objectManagerMock);
+    }
 }
diff --git a/app/code/Magento/Quote/Test/Unit/Model/ShippingMethodManagementTest.php b/app/code/Magento/Quote/Test/Unit/Model/ShippingMethodManagementTest.php
index 5f31b7b1219ce7bebaa821e78212556392397193..bb0eab1d8aed263448502575d1bf630d9bf6129b 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/ShippingMethodManagementTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/ShippingMethodManagementTest.php
@@ -311,12 +311,13 @@ class ShippingMethodManagementTest extends \PHPUnit_Framework_TestCase
      */
     public function testSetMethodWithInputException()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $cartId = 12;
         $carrierCode = 34;
         $methodCode = 56;
-        $this->quoteRepository->expects($this->once())
-            ->method('getActive')->with($cartId)->will($this->returnValue($this->quote));
+        $this->quoteRepository->expects($this->exactly(2))
+            ->method('getActive')
+            ->with($cartId)
+            ->willReturn($this->quote);
         $this->quote->expects($this->once())->method('getItemsCount')->will($this->returnValue(0));
         $this->quote->expects($this->never())->method('isVirtual');
 
@@ -329,13 +330,14 @@ class ShippingMethodManagementTest extends \PHPUnit_Framework_TestCase
      */
     public function testSetMethodWithVirtualProduct()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $cartId = 12;
         $carrierCode = 34;
         $methodCode = 56;
 
-        $this->quoteRepository->expects($this->once())
-            ->method('getActive')->with($cartId)->will($this->returnValue($this->quote));
+        $this->quoteRepository->expects($this->exactly(2))
+            ->method('getActive')
+            ->with($cartId)
+            ->willReturn($this->quote);
         $this->quote->expects($this->once())->method('getItemsCount')->will($this->returnValue(1));
         $this->quote->expects($this->once())->method('isVirtual')->will($this->returnValue(true));
 
@@ -348,12 +350,13 @@ class ShippingMethodManagementTest extends \PHPUnit_Framework_TestCase
      */
     public function testSetMethodWithoutShippingAddress()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $cartId = 12;
         $carrierCode = 34;
         $methodCode = 56;
-        $this->quoteRepository->expects($this->once())
-            ->method('getActive')->with($cartId)->will($this->returnValue($this->quote));
+        $this->quoteRepository->expects($this->exactly(2))
+            ->method('getActive')
+            ->with($cartId)
+            ->willReturn($this->quote);
         $this->quote->expects($this->once())->method('getItemsCount')->will($this->returnValue(1));
         $this->quote->expects($this->once())->method('isVirtual')->will($this->returnValue(false));
         $this->quote->expects($this->once())
@@ -363,60 +366,34 @@ class ShippingMethodManagementTest extends \PHPUnit_Framework_TestCase
         $this->model->set($cartId, $carrierCode, $methodCode);
     }
 
-    /**
-     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
-     * @expectedExceptionMessage Carrier with such method not found: 34, 56
-     */
-    public function testSetMethodWithNotFoundMethod()
-    {
-        $this->markTestSkipped('MAGETWO-48531');
-        $cartId = 12;
-        $carrierCode = 34;
-        $methodCode = 56;
-        $countryId = 1;
-        $this->quoteRepository->expects($this->once())
-            ->method('getActive')->with($cartId)->will($this->returnValue($this->quote));
-        $this->quote->expects($this->once())->method('getItemsCount')->will($this->returnValue(1));
-        $this->quote->expects($this->once())->method('isVirtual')->will($this->returnValue(false));
-        $this->quote->expects($this->once())
-            ->method('getShippingAddress')->will($this->returnValue($this->shippingAddress));
-        $this->shippingAddress->expects($this->once())
-            ->method('getCountryId')->will($this->returnValue($countryId));
-        $this->shippingAddress->expects($this->once())
-            ->method('setShippingMethod')->with($carrierCode . '_' . $methodCode);
-        $this->shippingAddress->expects($this->once())
-            ->method('getShippingRateByCode')->will($this->returnValue(false));
-        $this->shippingAddress->expects($this->never())->method('save');
-
-        $this->model->set($cartId, $carrierCode, $methodCode);
-    }
-
     /**
      * @expectedException \Magento\Framework\Exception\CouldNotSaveException
      * @expectedExceptionMessage Cannot set shipping method. Custom Error
      */
     public function testSetMethodWithCouldNotSaveException()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $cartId = 12;
         $carrierCode = 34;
         $methodCode = 56;
         $countryId = 1;
 
-        $this->quoteRepository->expects($this->once())
-            ->method('getActive')->with($cartId)->will($this->returnValue($this->quote));
+        $this->quoteRepository->expects($this->exactly(2))
+            ->method('getActive')
+            ->with($cartId)
+            ->willReturn($this->quote);
         $this->quote->expects($this->once())->method('getItemsCount')->will($this->returnValue(1));
         $this->quote->expects($this->once())->method('isVirtual')->will($this->returnValue(false));
         $this->quote->expects($this->once())
-            ->method('getShippingAddress')->will($this->returnValue($this->shippingAddress));
-        $this->shippingAddress->expects($this->once())
-            ->method('getCountryId')->will($this->returnValue($countryId));
+            ->method('getShippingAddress')
+            ->willReturn($this->shippingAddress);
         $this->shippingAddress->expects($this->once())
-            ->method('setShippingMethod')->with($carrierCode . '_' . $methodCode);
+            ->method('getCountryId')
+            ->willReturn($countryId);
         $this->shippingAddress->expects($this->once())
-            ->method('getShippingRateByCode')->will($this->returnValue(true));
+            ->method('setShippingMethod')
+            ->with($carrierCode . '_' . $methodCode);
         $exception = new \Exception('Custom Error');
-        $this->quote->expects($this->once())->method('collectTotals')->will($this->returnSelf());
+        $this->quote->expects($this->once())->method('collectTotals')->willReturnSelf();
         $this->quoteRepository->expects($this->once())
             ->method('save')
             ->with($this->quote)
@@ -431,16 +408,18 @@ class ShippingMethodManagementTest extends \PHPUnit_Framework_TestCase
      */
     public function testSetMethodWithoutAddress()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $cartId = 12;
         $carrierCode = 34;
         $methodCode = 56;
-        $this->quoteRepository->expects($this->once())
-            ->method('getActive')->with($cartId)->will($this->returnValue($this->quote));
+        $this->quoteRepository->expects($this->exactly(2))
+            ->method('getActive')
+            ->with($cartId)
+            ->willReturn($this->quote);
         $this->quote->expects($this->once())->method('getItemsCount')->will($this->returnValue(1));
         $this->quote->expects($this->once())->method('isVirtual')->will($this->returnValue(false));
         $this->quote->expects($this->once())
-            ->method('getShippingAddress')->will($this->returnValue($this->shippingAddress));
+            ->method('getShippingAddress')
+            ->willReturn($this->shippingAddress);
         $this->shippingAddress->expects($this->once())->method('getCountryId');
 
         $this->model->set($cartId, $carrierCode, $methodCode);
@@ -448,13 +427,14 @@ class ShippingMethodManagementTest extends \PHPUnit_Framework_TestCase
 
     public function testSetMethod()
     {
-        $this->markTestSkipped('MAGETWO-48531');
         $cartId = 12;
         $carrierCode = 34;
         $methodCode = 56;
         $countryId = 1;
-        $this->quoteRepository->expects($this->once())
-            ->method('getActive')->with($cartId)->will($this->returnValue($this->quote));
+        $this->quoteRepository->expects($this->exactly(2))
+            ->method('getActive')
+            ->with($cartId)
+            ->willReturn($this->quote);
         $this->quote->expects($this->once())->method('getItemsCount')->will($this->returnValue(1));
         $this->quote->expects($this->once())->method('isVirtual')->will($this->returnValue(false));
         $this->quote->expects($this->once())
@@ -463,8 +443,6 @@ class ShippingMethodManagementTest extends \PHPUnit_Framework_TestCase
             ->method('getCountryId')->will($this->returnValue($countryId));
         $this->shippingAddress->expects($this->once())
             ->method('setShippingMethod')->with($carrierCode . '_' . $methodCode);
-        $this->shippingAddress->expects($this->once())
-            ->method('getShippingRateByCode')->will($this->returnValue(true));
         $this->quote->expects($this->once())->method('collectTotals')->will($this->returnSelf());
         $this->quoteRepository->expects($this->once())->method('save')->with($this->quote);
 
diff --git a/app/code/Magento/Review/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ReviewTest.php b/app/code/Magento/Review/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ReviewTest.php
index 7685fc0fed94df32b0e0638e65d6d15f6de1d5ce..b93cb70fdda3d9cc9b6d8d9f7bb565d576392de4 100644
--- a/app/code/Magento/Review/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ReviewTest.php
+++ b/app/code/Magento/Review/Test/Unit/Ui/DataProvider/Product/Form/Modifier/ReviewTest.php
@@ -8,6 +8,8 @@ namespace Magento\Review\Test\Unit\Ui\DataProvider\Product\Form\Modifier;
 use Magento\Catalog\Test\Unit\Ui\DataProvider\Product\Form\Modifier\AbstractModifierTest;
 use Magento\Framework\UrlInterface;
 use Magento\Review\Ui\DataProvider\Product\Form\Modifier\Review;
+use Magento\Framework\Module\Manager as ModuleManager;
+use Magento\Ui\DataProvider\Modifier\ModifierInterface;
 
 /**
  * Class ReviewTest
@@ -19,36 +21,73 @@ class ReviewTest extends AbstractModifierTest
      */
     protected $urlBuilderMock;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $moduleManagerMock;
+
     protected function setUp()
     {
         parent::setUp();
         $this->urlBuilderMock = $this->getMockBuilder(UrlInterface::class)
             ->getMockForAbstractClass();
+        $this->moduleManagerMock = $this->getMock(ModuleManager::class, [], [], '', false);
     }
 
+    /**
+     * @return ModifierInterface
+     */
     protected function createModel()
     {
-        return $this->objectManager->getObject(Review::class, [
+        $model = $this->objectManager->getObject(Review::class, [
             'locator' => $this->locatorMock,
             'urlBuilder' => $this->urlBuilderMock,
         ]);
+
+        $reviewClass = new \ReflectionClass(Review::class);
+        $moduleManagerProperty = $reviewClass->getProperty('moduleManager');
+        $moduleManagerProperty->setAccessible(true);
+        $moduleManagerProperty->setValue(
+            $model,
+            $this->moduleManagerMock
+        );
+
+        return $model;
     }
 
-    public function testModifyMetaToBeEmpty()
+    public function testModifyMetaDoesNotAddReviewSectionForNewProduct()
+    {
+        $this->productMock->expects($this->once())
+            ->method('getId');
+
+        $this->assertSame([], $this->getModel()->modifyMeta([]));
+    }
+
+    public function testModifyMetaDoesNotAddReviewSectionIfReviewModuleOutputIsDisabled()
     {
         $this->productMock->expects($this->once())
             ->method('getId')
-            ->willReturn(0);
+            ->willReturn(1);
+
+        $this->moduleManagerMock->expects($this->any())
+            ->method('isOutputEnabled')
+            ->with('Magento_Review')
+            ->willReturn(false);
 
         $this->assertSame([], $this->getModel()->modifyMeta([]));
     }
 
-    public function testModifyMeta()
+    public function testModifyMetaAddsReviewSectionForExistingProductIfReviewModuleOutputIsEnabled()
     {
         $this->productMock->expects($this->once())
             ->method('getId')
             ->willReturn(1);
 
+        $this->moduleManagerMock->expects($this->any())
+            ->method('isOutputEnabled')
+            ->with('Magento_Review')
+            ->willReturn(true);
+
         $this->assertArrayHasKey(Review::GROUP_REVIEW, $this->getModel()->modifyMeta([]));
     }
 
diff --git a/app/code/Magento/Review/Ui/DataProvider/Product/Form/Modifier/Review.php b/app/code/Magento/Review/Ui/DataProvider/Product/Form/Modifier/Review.php
index 82141b5ab2f12a03e44463555e7b0a302630b0d2..0ef1057eb4be7ffd23fe794bef67663dc247b5c6 100644
--- a/app/code/Magento/Review/Ui/DataProvider/Product/Form/Modifier/Review.php
+++ b/app/code/Magento/Review/Ui/DataProvider/Product/Form/Modifier/Review.php
@@ -12,6 +12,8 @@ use Magento\Catalog\Model\Locator\LocatorInterface;
 use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;
 use Magento\Ui\Component\Form;
 use Magento\Framework\UrlInterface;
+use Magento\Framework\Module\Manager as ModuleManager;
+use Magento\Framework\App\ObjectManager;
 
 /**
  * Class Review
@@ -34,6 +36,11 @@ class Review extends AbstractModifier
      */
     protected $urlBuilder;
 
+    /**
+     * @var ModuleManager
+     */
+    private $moduleManager;
+
     /**
      * @param LocatorInterface $locator
      * @param UrlInterface $urlBuilder
@@ -51,7 +58,7 @@ class Review extends AbstractModifier
      */
     public function modifyMeta(array $meta)
     {
-        if (!$this->locator->getProduct()->getId()) {
+        if (!$this->locator->getProduct()->getId() || !$this->getModuleManager()->isOutputEnabled('Magento_Review')) {
             return $meta;
         }
 
@@ -114,4 +121,19 @@ class Review extends AbstractModifier
 
         return $data;
     }
+
+    /**
+     * Retrieve module manager instance using dependency lookup to keep this class backward compatible.
+     *
+     * @return ModuleManager
+     *
+     * @deprecated
+     */
+    private function getModuleManager()
+    {
+        if ($this->moduleManager === null) {
+            $this->moduleManager = ObjectManager::getInstance()->get(ModuleManager::class);
+        }
+        return $this->moduleManager;
+    }
 }
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/History.php b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/History.php
index 8a6674aa154b060cf1030101ff1fb1a9c3e0b6cc..a68c543acf731f5f435eaea029c57e069acd5e87 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/History.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/History.php
@@ -157,13 +157,10 @@ class History extends \Magento\Backend\Block\Template implements \Magento\Backen
         if (!isset($item['created_at'])) {
             return '';
         }
-        $date = $item['created_at'] instanceof \DateTimeInterface
-            ? $item['created_at']
-            : new \DateTime($item['created_at']);
         if ('date' === $dateType) {
-            return $this->_localeDate->formatDateTime($date, $format, $format);
+            return $this->formatDate($item['created_at'], $format);
         }
-        return $this->_localeDate->formatDateTime($date, \IntlDateFormatter::NONE, $format);
+        return $this->formatTime($item['created_at'], $format);
     }
 
     /**
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php
index 33f1b07e4d56780b7d176cbf05732942700a6511..e15f469dde0c3c8cf2eb2fd6d5acde6fb50aa39c 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php
@@ -102,6 +102,7 @@ class Save extends \Magento\Backend\App\Action
                 $creditmemoManagement = $this->_objectManager->create(
                     \Magento\Sales\Api\CreditmemoManagementInterface::class
                 );
+                $creditmemo->getOrder()->setCustomerNoteNotify(!empty($data['send_email']));
                 $creditmemoManagement->refund($creditmemo, (bool)$data['do_offline']);
 
                 if (!empty($data['send_email'])) {
diff --git a/app/code/Magento/Sales/Model/AdminOrder/Create.php b/app/code/Magento/Sales/Model/AdminOrder/Create.php
index d5557b295647e282b9cec7c2425746c12816ec62..3715c02357a964bef3502a461db30574d6655ba1 100644
--- a/app/code/Magento/Sales/Model/AdminOrder/Create.php
+++ b/app/code/Magento/Sales/Model/AdminOrder/Create.php
@@ -1287,7 +1287,7 @@ class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\
             'adminhtml_checkout',
             $this->customerMapper->toFlatArray($customer),
             false,
-            CustomerForm::DONT_IGNORE_INVISIBLE
+            CustomerForm::IGNORE_INVISIBLE
         );
 
         return $customerForm;
@@ -1547,6 +1547,11 @@ class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\
     public function applyCoupon($code)
     {
         $code = trim((string)$code);
+        $this->getQuote()->getShippingAddress()->setCollectShippingRates(true);
+
+        if (empty($code)) {
+            $this->getQuote()->getShippingAddress()->setFreeShipping(null);
+        }
         $this->getQuote()->setCouponCode($code);
         $this->setRecollect(true);
 
@@ -1563,13 +1568,11 @@ class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\
     {
         $customer = $this->getQuote()->getCustomer();
         $form = $this->_createCustomerForm($customer);
-        $customerData = $this->customerMapper->toFlatArray($customer);
 
         // emulate request
         $request = $form->prepareRequest($accountData);
         $data = $form->extractData($request);
         $data = $form->restoreData($data);
-        $data = array_merge($customerData, array_filter($data));
         $customer = $this->customerFactory->create();
         $this->dataObjectHelper->populateWithArray(
             $customer,
@@ -1578,6 +1581,7 @@ class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\
         $this->getQuote()->updateCustomerData($customer);
         $data = [];
 
+        $customerData = $this->customerMapper->toFlatArray($customer);
         foreach ($form->getAttributes() as $attribute) {
             $code = sprintf('customer_%s', $attribute->getAttributeCode());
             $data[$code] = isset($customerData[$attribute->getAttributeCode()])
diff --git a/app/code/Magento/Sales/Model/InvoiceOrder.php b/app/code/Magento/Sales/Model/InvoiceOrder.php
index e51b46082d943d8ff609bacb80fae19c861afba4..c503b01a5ab21014683a7eaa5981f65fa16b558f 100644
--- a/app/code/Magento/Sales/Model/InvoiceOrder.php
+++ b/app/code/Magento/Sales/Model/InvoiceOrder.php
@@ -12,15 +12,12 @@ use Magento\Sales\Api\Data\InvoiceCreationArgumentsInterface;
 use Magento\Sales\Api\InvoiceOrderInterface;
 use Magento\Sales\Api\OrderRepositoryInterface;
 use Magento\Sales\Model\Order\Config as OrderConfig;
-use Magento\Sales\Model\Order\Invoice\InvoiceValidatorInterface;
 use Magento\Sales\Model\Order\Invoice\NotifierInterface;
 use Magento\Sales\Model\Order\InvoiceDocumentFactory;
-use Magento\Sales\Model\Order\InvoiceQuantityValidator;
 use Magento\Sales\Model\Order\InvoiceRepository;
 use Magento\Sales\Model\Order\OrderStateResolverInterface;
-use Magento\Sales\Model\Order\OrderValidatorInterface;
 use Magento\Sales\Model\Order\PaymentAdapterInterface;
-use Magento\Sales\Model\Order\Validation\CanInvoice;
+use Magento\Sales\Model\Order\Validation\InvoiceOrderInterface as InvoiceOrderValidator;
 use Psr\Log\LoggerInterface;
 
 /**
@@ -44,11 +41,6 @@ class InvoiceOrder implements InvoiceOrderInterface
      */
     private $invoiceDocumentFactory;
 
-    /**
-     * @var InvoiceValidatorInterface
-     */
-    private $invoiceValidator;
-
     /**
      * @var PaymentAdapterInterface
      */
@@ -69,6 +61,11 @@ class InvoiceOrder implements InvoiceOrderInterface
      */
     private $invoiceRepository;
 
+    /**
+     * @var InvoiceOrderValidator
+     */
+    private $invoiceOrderValidator;
+
     /**
      * @var NotifierInterface
      */
@@ -80,21 +77,15 @@ class InvoiceOrder implements InvoiceOrderInterface
     private $logger;
 
     /**
-     * @var OrderValidatorInterface
-     */
-    private $orderValidator;
-
-    /**
-     * OrderInvoice constructor.
+     * InvoiceOrder constructor.
      * @param ResourceConnection $resourceConnection
      * @param OrderRepositoryInterface $orderRepository
      * @param InvoiceDocumentFactory $invoiceDocumentFactory
-     * @param InvoiceValidatorInterface $invoiceValidator
-     * @param OrderValidatorInterface $orderValidator
      * @param PaymentAdapterInterface $paymentAdapter
      * @param OrderStateResolverInterface $orderStateResolver
      * @param OrderConfig $config
      * @param InvoiceRepository $invoiceRepository
+     * @param InvoiceOrderValidator $invoiceOrderValidator
      * @param NotifierInterface $notifierInterface
      * @param LoggerInterface $logger
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
@@ -103,24 +94,22 @@ class InvoiceOrder implements InvoiceOrderInterface
         ResourceConnection $resourceConnection,
         OrderRepositoryInterface $orderRepository,
         InvoiceDocumentFactory $invoiceDocumentFactory,
-        InvoiceValidatorInterface $invoiceValidator,
-        OrderValidatorInterface $orderValidator,
         PaymentAdapterInterface $paymentAdapter,
         OrderStateResolverInterface $orderStateResolver,
         OrderConfig $config,
         InvoiceRepository $invoiceRepository,
+        InvoiceOrderValidator $invoiceOrderValidator,
         NotifierInterface $notifierInterface,
         LoggerInterface $logger
     ) {
         $this->resourceConnection = $resourceConnection;
         $this->orderRepository = $orderRepository;
         $this->invoiceDocumentFactory = $invoiceDocumentFactory;
-        $this->invoiceValidator = $invoiceValidator;
-        $this->orderValidator = $orderValidator;
         $this->paymentAdapter = $paymentAdapter;
         $this->orderStateResolver = $orderStateResolver;
         $this->config = $config;
         $this->invoiceRepository = $invoiceRepository;
+        $this->invoiceOrderValidator = $invoiceOrderValidator;
         $this->notifierInterface = $notifierInterface;
         $this->logger = $logger;
     }
@@ -158,19 +147,19 @@ class InvoiceOrder implements InvoiceOrderInterface
             ($appendComment && $notify),
             $arguments
         );
-        $errorMessages = array_merge(
-            $this->invoiceValidator->validate(
-                $invoice,
-                [InvoiceQuantityValidator::class]
-            ),
-            $this->orderValidator->validate(
-                $order,
-                [CanInvoice::class]
-            )
+        $errorMessages = $this->invoiceOrderValidator->validate(
+            $order,
+            $invoice,
+            $capture,
+            $items,
+            $notify,
+            $appendComment,
+            $comment,
+            $arguments
         );
-        if (!empty($errorMessages)) {
+        if ($errorMessages->hasMessages()) {
             throw new \Magento\Sales\Exception\DocumentValidationException(
-                __("Invoice Document Validation Error(s):\n" . implode("\n", $errorMessages))
+                __("Invoice Document Validation Error(s):\n" . implode("\n", $errorMessages->getMessages()))
             );
         }
         $connection->beginTransaction();
diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/CreditmemoValidatorInterface.php b/app/code/Magento/Sales/Model/Order/Creditmemo/CreditmemoValidatorInterface.php
index 3889f3b985ff02603009084fa956fab65e505556..030a9a7d128de7d49d989c0e1af61a323786f5a5 100644
--- a/app/code/Magento/Sales/Model/Order/Creditmemo/CreditmemoValidatorInterface.php
+++ b/app/code/Magento/Sales/Model/Order/Creditmemo/CreditmemoValidatorInterface.php
@@ -8,6 +8,7 @@ namespace Magento\Sales\Model\Order\Creditmemo;
 use Magento\Sales\Api\Data\CreditmemoInterface;
 use Magento\Sales\Exception\DocumentValidationException;
 use Magento\Sales\Model\ValidatorInterface;
+use Magento\Sales\Model\ValidatorResultInterface;
 
 /**
  * Interface CreditmemoValidatorInterface
@@ -17,7 +18,7 @@ interface CreditmemoValidatorInterface
     /**
      * @param CreditmemoInterface $entity
      * @param ValidatorInterface[] $validators
-     * @return string[]
+     * @return ValidatorResultInterface
      * @throws DocumentValidationException
      */
     public function validate(CreditmemoInterface $entity, array $validators);
diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/ItemCreationValidatorInterface.php b/app/code/Magento/Sales/Model/Order/Creditmemo/ItemCreationValidatorInterface.php
index 9f8bb84ccd16a175ee23de755169281026dc053b..7a758122b8aac13d75dcf5784ef85e71d2298b2d 100644
--- a/app/code/Magento/Sales/Model/Order/Creditmemo/ItemCreationValidatorInterface.php
+++ b/app/code/Magento/Sales/Model/Order/Creditmemo/ItemCreationValidatorInterface.php
@@ -7,6 +7,7 @@ namespace Magento\Sales\Model\Order\Creditmemo;
 
 use Magento\Sales\Api\Data\CreditmemoItemCreationInterface;
 use Magento\Sales\Api\Data\OrderInterface;
+use Magento\Sales\Model\ValidatorResultInterface;
 
 /**
  * Interface ItemCreationValidatorInterface
@@ -17,7 +18,7 @@ interface ItemCreationValidatorInterface
      * @param CreditmemoItemCreationInterface $item
      * @param array $validators
      * @param OrderInterface|null $context
-     * @return mixed
+     * @return ValidatorResultInterface
      */
     public function validate(CreditmemoItemCreationInterface $item, array $validators, OrderInterface $context = null);
 }
diff --git a/app/code/Magento/Sales/Model/Order/CreditmemoDocumentFactory.php b/app/code/Magento/Sales/Model/Order/CreditmemoDocumentFactory.php
index 469b226053cdd4e2b0658dcd596d7d740572f0c7..816c3df3fc1f0c6b045f26f2ebb79e769c1be031 100644
--- a/app/code/Magento/Sales/Model/Order/CreditmemoDocumentFactory.php
+++ b/app/code/Magento/Sales/Model/Order/CreditmemoDocumentFactory.php
@@ -7,6 +7,8 @@ namespace Magento\Sales\Model\Order;
 
 /**
  * Class CreditmemoDocumentFactory
+ *
+ * @api
  */
 class CreditmemoDocumentFactory
 {
diff --git a/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidatorInterface.php b/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidatorInterface.php
index 568019a40fce5bc69ccab49ca8b3f4fee048505e..44d701b1426e79d3df390b46b7e76ee6743b691c 100644
--- a/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidatorInterface.php
+++ b/app/code/Magento/Sales/Model/Order/Invoice/InvoiceValidatorInterface.php
@@ -8,6 +8,7 @@ namespace Magento\Sales\Model\Order\Invoice;
 use Magento\Sales\Api\Data\InvoiceInterface;
 use Magento\Sales\Exception\DocumentValidationException;
 use Magento\Sales\Model\ValidatorInterface;
+use Magento\Sales\Model\ValidatorResultInterface;
 
 /**
  * Interface InvoiceValidatorInterface
@@ -17,7 +18,7 @@ interface InvoiceValidatorInterface
     /**
      * @param InvoiceInterface $entity
      * @param ValidatorInterface[] $validators
-     * @return string[]
+     * @return ValidatorResultInterface
      * @throws DocumentValidationException
      */
     public function validate(InvoiceInterface $entity, array $validators);
diff --git a/app/code/Magento/Sales/Model/Order/Invoice/Plugin/AddressUpdate.php b/app/code/Magento/Sales/Model/Order/Invoice/Plugin/AddressUpdate.php
new file mode 100644
index 0000000000000000000000000000000000000000..9fe280f5521e5ebca2fadb638abc5fb09d23fefe
--- /dev/null
+++ b/app/code/Magento/Sales/Model/Order/Invoice/Plugin/AddressUpdate.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Sales\Model\Order\Invoice\Plugin;
+
+class AddressUpdate
+{
+    /**
+     * @var \Magento\Sales\Model\ResourceModel\GridPool
+     */
+    private $gridPool;
+
+    /**
+     * @var \Magento\Sales\Model\ResourceModel\Attribute
+     */
+    private $attribute;
+
+    /**
+     * AddressUpdate constructor.
+     * @param \Magento\Sales\Model\ResourceModel\GridPool $gridPool
+     * @param \Magento\Sales\Model\ResourceModel\Attribute $attribute
+     */
+    public function __construct(
+        \Magento\Sales\Model\ResourceModel\GridPool $gridPool,
+        \Magento\Sales\Model\ResourceModel\Attribute $attribute
+    ) {
+        $this->gridPool = $gridPool;
+        $this->attribute = $attribute;
+    }
+
+    /**
+     * @param \Magento\Sales\Model\ResourceModel\Order\Handler\Address $subject
+     * @param \Magento\Sales\Model\ResourceModel\Order\Handler\Address $result
+     * @param \Magento\Sales\Model\Order $order
+     * @return void
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function afterProcess(
+        \Magento\Sales\Model\ResourceModel\Order\Handler\Address $subject,
+        \Magento\Sales\Model\ResourceModel\Order\Handler\Address $result,
+        \Magento\Sales\Model\Order $order
+    ) {
+        if ($order->hasInvoices()) {
+            $billingAddress = $order->getBillingAddress();
+            $shippingAddress = $order->getShippingAddress();
+
+            $orderInvoiceHasChanges = false;
+            /** @var \Magento\Sales\Model\Order\Invoice $invoice */
+            foreach ($order->getInvoiceCollection()->getItems() as $invoice) {
+                $invoiceAttributesForSave = [];
+
+                if (!$invoice->getBillingAddressId() && $billingAddress) {
+                    $invoice->setBillingAddressId($billingAddress->getId());
+                    $invoiceAttributesForSave[] = 'billing_address_id';
+                    $orderInvoiceHasChanges = true;
+                }
+
+                if (!$invoice->getShippingAddressId() && $shippingAddress) {
+                    $invoice->setShippingAddressId($shippingAddress->getId());
+                    $invoiceAttributesForSave[] = 'shipping_address_id';
+                    $orderInvoiceHasChanges = true;
+                }
+
+                if (!empty($invoiceAttributesForSave)) {
+                    $this->attribute->saveAttribute($invoice, $invoiceAttributesForSave);
+                }
+            }
+
+            if ($orderInvoiceHasChanges) {
+                $this->gridPool->refreshByOrderId($order->getId());
+            }
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Model/Order/OrderValidatorInterface.php b/app/code/Magento/Sales/Model/Order/OrderValidatorInterface.php
index c5a9a6c1d32963fcc223099efe1fcb81bb530464..dfc95043cbd33b214b46f26e7fcdc2a039e9272e 100644
--- a/app/code/Magento/Sales/Model/Order/OrderValidatorInterface.php
+++ b/app/code/Magento/Sales/Model/Order/OrderValidatorInterface.php
@@ -8,6 +8,7 @@ namespace Magento\Sales\Model\Order;
 use Magento\Sales\Api\Data\OrderInterface;
 use Magento\Sales\Exception\DocumentValidationException;
 use Magento\Sales\Model\ValidatorInterface;
+use Magento\Sales\Model\ValidatorResultInterface;
 
 /**
  * Interface OrderValidatorInterface
@@ -17,7 +18,7 @@ interface OrderValidatorInterface
     /**
      * @param OrderInterface $entity
      * @param ValidatorInterface[] $validators
-     * @return string[]
+     * @return ValidatorResultInterface
      * @throws DocumentValidationException
      */
     public function validate(OrderInterface $entity, array $validators);
diff --git a/app/code/Magento/Sales/Model/Order/Payment.php b/app/code/Magento/Sales/Model/Order/Payment.php
index 7f4f70350ab28d3f98b65fa98e772c38c5ebd282..5deb24a068de1d0ff8a48bb4cc7f6f916c1c6dde 100644
--- a/app/code/Magento/Sales/Model/Order/Payment.php
+++ b/app/code/Magento/Sales/Model/Order/Payment.php
@@ -8,6 +8,7 @@
 
 namespace Magento\Sales\Model\Order;
 
+use Magento\Framework\App\ObjectManager;
 use Magento\Framework\Pricing\PriceCurrencyInterface;
 use Magento\Sales\Api\OrderRepositoryInterface;
 use Magento\Sales\Model\Order\Payment\Info;
@@ -105,6 +106,11 @@ class Payment extends Info implements OrderPaymentInterface
      */
     protected $orderRepository;
 
+    /**
+     * @var OrderStateResolverInterface
+     */
+    private $orderStateResolver;
+
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
@@ -692,7 +698,12 @@ class Payment extends Info implements OrderPaymentInterface
         }
         $message = $message = $this->prependMessage($message);
         $message = $this->_appendTransactionToMessage($transaction, $message);
-        $this->setOrderStateProcessing($message);
+        $orderState = $this->getOrderStateResolver()->getStateForOrder($this->getOrder());
+        $this->getOrder()
+            ->addStatusHistoryComment(
+                $message,
+                $this->getOrder()->getConfig()->getStateDefaultStatus($orderState)
+            )->setIsCustomerNotified($creditmemo->getOrder()->getCustomerNoteNotify());
         $this->_eventManager->dispatch(
             'sales_order_payment_refund',
             ['payment' => $this, 'creditmemo' => $creditmemo]
@@ -1388,6 +1399,19 @@ class Payment extends Info implements OrderPaymentInterface
         return false;
     }
 
+    /**
+     * @deprecated
+     * @return OrderStateResolverInterface
+     */
+    private function getOrderStateResolver()
+    {
+        if ($this->orderStateResolver === null) {
+            $this->orderStateResolver = ObjectManager::getInstance()->get(OrderStateResolverInterface::class);
+        }
+
+        return$this->orderStateResolver;
+    }
+
     //@codeCoverageIgnoreStart
     /**
      * Returns account_status
diff --git a/app/code/Magento/Sales/Model/Order/Shipment/ShipmentValidatorInterface.php b/app/code/Magento/Sales/Model/Order/Shipment/ShipmentValidatorInterface.php
index 198a4019bf6b898e0c85fd2e2ff7c7ff77c2a9f6..43501a5b133140390e539a0d81985a4a5437598b 100644
--- a/app/code/Magento/Sales/Model/Order/Shipment/ShipmentValidatorInterface.php
+++ b/app/code/Magento/Sales/Model/Order/Shipment/ShipmentValidatorInterface.php
@@ -8,6 +8,7 @@ namespace Magento\Sales\Model\Order\Shipment;
 use Magento\Sales\Api\Data\ShipmentInterface;
 use Magento\Sales\Exception\DocumentValidationException;
 use Magento\Sales\Model\ValidatorInterface;
+use Magento\Sales\Model\ValidatorResultInterface;
 
 /**
  * Interface ShipmentValidatorInterface
@@ -17,7 +18,7 @@ interface ShipmentValidatorInterface
     /**
      * @param ShipmentInterface $shipment
      * @param ValidatorInterface[] $validators
-     * @return string[]
+     * @return ValidatorResultInterface
      * @throws DocumentValidationException
      */
     public function validate(ShipmentInterface $shipment, array $validators);
diff --git a/app/code/Magento/Sales/Model/Order/Validation/InvoiceOrder.php b/app/code/Magento/Sales/Model/Order/Validation/InvoiceOrder.php
new file mode 100644
index 0000000000000000000000000000000000000000..d912793afa157fbbd997e89ce46c8b84aa5d6f75
--- /dev/null
+++ b/app/code/Magento/Sales/Model/Order/Validation/InvoiceOrder.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Sales\Model\Order\Validation;
+
+use Magento\Sales\Api\Data\InvoiceCommentCreationInterface;
+use Magento\Sales\Api\Data\InvoiceCreationArgumentsInterface;
+use Magento\Sales\Api\Data\InvoiceInterface;
+use Magento\Sales\Api\Data\OrderInterface;
+use Magento\Sales\Model\Order\Invoice\InvoiceValidatorInterface;
+use Magento\Sales\Model\Order\InvoiceQuantityValidator;
+use Magento\Sales\Model\Order\OrderValidatorInterface;
+use Magento\Sales\Model\ValidatorResultInterface;
+use Magento\Sales\Model\ValidatorResultMerger;
+
+/**
+ * Class InvoiceOrder
+ * Validation for invoice order operation
+ */
+class InvoiceOrder implements InvoiceOrderInterface
+{
+    /**
+     * @var InvoiceValidatorInterface
+     */
+    private $invoiceValidator;
+
+    /**
+     * @var OrderValidatorInterface
+     */
+    private $orderValidator;
+
+    /**
+     * @var ValidatorResultMerger
+     */
+    private $validatorResultMerger;
+
+    /**
+     * InvoiceOrder constructor.
+     * @param InvoiceValidatorInterface $invoiceValidator
+     * @param OrderValidatorInterface $orderValidator
+     * @param ValidatorResultMerger $validatorResultMerger
+     */
+    public function __construct(
+        InvoiceValidatorInterface $invoiceValidator,
+        OrderValidatorInterface $orderValidator,
+        ValidatorResultMerger $validatorResultMerger
+    ) {
+        $this->invoiceValidator = $invoiceValidator;
+        $this->orderValidator = $orderValidator;
+        $this->validatorResultMerger = $validatorResultMerger;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function validate(
+        OrderInterface $order,
+        InvoiceInterface $invoice,
+        $capture = false,
+        array $items = [],
+        $notify = false,
+        $appendComment = false,
+        InvoiceCommentCreationInterface $comment = null,
+        InvoiceCreationArgumentsInterface $arguments = null
+    ) {
+        return $this->validatorResultMerger->merge(
+            $this->invoiceValidator->validate(
+                $invoice,
+                [InvoiceQuantityValidator::class]
+            ),
+            $this->orderValidator->validate(
+                $order,
+                [CanInvoice::class]
+            )
+        );
+    }
+}
diff --git a/app/code/Magento/Sales/Model/Order/Validation/InvoiceOrderInterface.php b/app/code/Magento/Sales/Model/Order/Validation/InvoiceOrderInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..5c27741a1985582ee547a21faf9747d68d2c35c4
--- /dev/null
+++ b/app/code/Magento/Sales/Model/Order/Validation/InvoiceOrderInterface.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Sales\Model\Order\Validation;
+
+use Magento\Sales\Api\Data\InvoiceCommentCreationInterface;
+use Magento\Sales\Api\Data\InvoiceCreationArgumentsInterface;
+use Magento\Sales\Api\Data\InvoiceInterface;
+use Magento\Sales\Api\Data\OrderInterface;
+use Magento\Sales\Model\ValidatorResultInterface;
+
+/**
+ * Interface InvoiceOrderInterface
+ *
+ * @api
+ */
+interface InvoiceOrderInterface
+{
+    /**
+     * @param OrderInterface $order
+     * @param InvoiceInterface $invoice
+     * @param bool $capture
+     * @param array $items
+     * @param bool $notify
+     * @param bool $appendComment
+     * @param InvoiceCommentCreationInterface|null $comment
+     * @param InvoiceCreationArgumentsInterface|null $arguments
+     * @return ValidatorResultInterface
+     */
+    public function validate(
+        OrderInterface $order,
+        InvoiceInterface $invoice,
+        $capture = false,
+        array $items = [],
+        $notify = false,
+        $appendComment = false,
+        InvoiceCommentCreationInterface $comment = null,
+        InvoiceCreationArgumentsInterface $arguments = null
+    );
+}
diff --git a/app/code/Magento/Sales/Model/Order/Validation/RefundInvoice.php b/app/code/Magento/Sales/Model/Order/Validation/RefundInvoice.php
new file mode 100644
index 0000000000000000000000000000000000000000..d6bc86005cf2c906154ca107cc97c4fac4242fd4
--- /dev/null
+++ b/app/code/Magento/Sales/Model/Order/Validation/RefundInvoice.php
@@ -0,0 +1,123 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Sales\Model\Order\Validation;
+
+use Magento\Sales\Api\Data\CreditmemoInterface;
+use Magento\Sales\Api\Data\InvoiceInterface;
+use Magento\Sales\Api\Data\OrderInterface;
+use Magento\Sales\Model\Order\Invoice\InvoiceValidatorInterface;
+use Magento\Sales\Model\Order\Creditmemo\CreditmemoValidatorInterface;
+use Magento\Sales\Model\Order\Creditmemo\Item\Validation\CreationQuantityValidator;
+use Magento\Sales\Model\Order\Creditmemo\ItemCreationValidatorInterface;
+use Magento\Sales\Model\Order\Creditmemo\Validation\QuantityValidator;
+use Magento\Sales\Model\Order\Creditmemo\Validation\TotalsValidator;
+use Magento\Sales\Model\Order\OrderValidatorInterface;
+use Magento\Sales\Model\ValidatorResultMerger;
+
+/**
+ * Class RefundInvoice
+ */
+class RefundInvoice implements RefundInvoiceInterface
+{
+    /**
+     * @var OrderValidatorInterface
+     */
+    private $orderValidator;
+
+    /**
+     * @var CreditmemoValidatorInterface
+     */
+    private $creditmemoValidator;
+
+    /**
+     * @var ItemCreationValidatorInterface
+     */
+    private $itemCreationValidator;
+
+    /**
+     * @var InvoiceValidatorInterface
+     */
+    private $invoiceValidator;
+
+    /**
+     * @var ValidatorResultMerger
+     */
+    private $validatorResultMerger;
+
+    /**
+     * RefundArguments constructor.
+     * @param OrderValidatorInterface $orderValidator
+     * @param CreditmemoValidatorInterface $creditmemoValidator
+     * @param ItemCreationValidatorInterface $itemCreationValidator
+     * @param InvoiceValidatorInterface $invoiceValidator
+     * @param ValidatorResultMerger $validatorResultMerger
+     */
+    public function __construct(
+        OrderValidatorInterface $orderValidator,
+        CreditmemoValidatorInterface $creditmemoValidator,
+        ItemCreationValidatorInterface $itemCreationValidator,
+        InvoiceValidatorInterface $invoiceValidator,
+        ValidatorResultMerger $validatorResultMerger
+    ) {
+        $this->orderValidator = $orderValidator;
+        $this->creditmemoValidator = $creditmemoValidator;
+        $this->itemCreationValidator = $itemCreationValidator;
+        $this->invoiceValidator = $invoiceValidator;
+        $this->validatorResultMerger = $validatorResultMerger;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function validate(
+        InvoiceInterface $invoice,
+        OrderInterface $order,
+        CreditmemoInterface $creditmemo,
+        array $items = [],
+        $isOnline = false,
+        $notify = false,
+        $appendComment = false,
+        \Magento\Sales\Api\Data\CreditmemoCommentCreationInterface $comment = null,
+        \Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface $arguments = null
+    ) {
+        $orderValidationResult = $this->orderValidator->validate(
+            $order,
+            [
+                CanRefund::class
+            ]
+        );
+        $creditmemoValidationResult = $this->creditmemoValidator->validate(
+            $creditmemo,
+            [
+                QuantityValidator::class,
+                TotalsValidator::class
+            ]
+        );
+
+        $itemsValidation = [];
+        foreach ($items as $item) {
+            $itemsValidation[] = $this->itemCreationValidator->validate(
+                $item,
+                [CreationQuantityValidator::class],
+                $order
+            )->getMessages();
+        }
+
+        $invoiceValidationResult = $this->invoiceValidator->validate(
+            $invoice,
+            [
+                \Magento\Sales\Model\Order\Invoice\Validation\CanRefund::class
+            ]
+        );
+
+        return $this->validatorResultMerger->merge(
+            $orderValidationResult,
+            $creditmemoValidationResult,
+            $invoiceValidationResult->getMessages(),
+            ...$itemsValidation
+        );
+    }
+}
diff --git a/app/code/Magento/Sales/Model/Order/Validation/RefundInvoiceInterface.php b/app/code/Magento/Sales/Model/Order/Validation/RefundInvoiceInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..83acc9811bb89f5ed8cff566274eb54a39668ad9
--- /dev/null
+++ b/app/code/Magento/Sales/Model/Order/Validation/RefundInvoiceInterface.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Sales\Model\Order\Validation;
+
+use Magento\Sales\Api\Data\CreditmemoInterface;
+use Magento\Sales\Api\Data\InvoiceInterface;
+use Magento\Sales\Api\Data\OrderInterface;
+use Magento\Sales\Model\ValidatorResultInterface;
+
+/**
+ * Interface RefundInvoiceInterface
+ *
+ * @api
+ */
+interface RefundInvoiceInterface
+{
+    /**
+     * @param InvoiceInterface $invoice
+     * @param OrderInterface $order
+     * @param CreditmemoInterface $creditmemo
+     * @param array $items
+     * @param bool $isOnline
+     * @param bool $notify
+     * @param bool $appendComment
+     * @param \Magento\Sales\Api\Data\CreditmemoCommentCreationInterface|null $comment
+     * @param \Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface|null $arguments
+     * @return ValidatorResultInterface
+     */
+    public function validate(
+        InvoiceInterface $invoice,
+        OrderInterface $order,
+        CreditmemoInterface $creditmemo,
+        array $items = [],
+        $isOnline = false,
+        $notify = false,
+        $appendComment = false,
+        \Magento\Sales\Api\Data\CreditmemoCommentCreationInterface $comment = null,
+        \Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface $arguments = null
+    );
+}
diff --git a/app/code/Magento/Sales/Model/Order/Validation/RefundOrder.php b/app/code/Magento/Sales/Model/Order/Validation/RefundOrder.php
new file mode 100644
index 0000000000000000000000000000000000000000..c2664fda6b9836df6c91a35aabd6c84ed54e5827
--- /dev/null
+++ b/app/code/Magento/Sales/Model/Order/Validation/RefundOrder.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Sales\Model\Order\Validation;
+
+use Magento\Sales\Api\Data\CreditmemoInterface;
+use Magento\Sales\Api\Data\OrderInterface;
+use Magento\Sales\Model\Order\Creditmemo\CreditmemoValidatorInterface;
+use Magento\Sales\Model\Order\Creditmemo\Item\Validation\CreationQuantityValidator;
+use Magento\Sales\Model\Order\Creditmemo\ItemCreationValidatorInterface;
+use Magento\Sales\Model\Order\Creditmemo\Validation\QuantityValidator;
+use Magento\Sales\Model\Order\Creditmemo\Validation\TotalsValidator;
+use Magento\Sales\Model\Order\OrderValidatorInterface;
+use Magento\Sales\Model\ValidatorResultMerger;
+
+/**
+ * Class RefundOrder
+ */
+class RefundOrder implements RefundOrderInterface
+{
+    /**
+     * @var OrderValidatorInterface
+     */
+    private $orderValidator;
+
+    /**
+     * @var CreditmemoValidatorInterface
+     */
+    private $creditmemoValidator;
+
+    /**
+     * @var ItemCreationValidatorInterface
+     */
+    private $itemCreationValidator;
+
+    /**
+     * @var ValidatorResultMerger
+     */
+    private $validatorResultMerger;
+
+    /**
+     * RefundArguments constructor.
+     *
+     * @param OrderValidatorInterface $orderValidator
+     * @param CreditmemoValidatorInterface $creditmemoValidator
+     * @param ItemCreationValidatorInterface $itemCreationValidator
+     * @param ValidatorResultMerger $validatorResultMerger
+     */
+    public function __construct(
+        OrderValidatorInterface $orderValidator,
+        CreditmemoValidatorInterface $creditmemoValidator,
+        ItemCreationValidatorInterface $itemCreationValidator,
+        ValidatorResultMerger $validatorResultMerger
+    ) {
+        $this->orderValidator = $orderValidator;
+        $this->creditmemoValidator = $creditmemoValidator;
+        $this->itemCreationValidator = $itemCreationValidator;
+        $this->validatorResultMerger = $validatorResultMerger;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function validate(
+        OrderInterface $order,
+        CreditmemoInterface $creditmemo,
+        array $items = [],
+        $notify = false,
+        $appendComment = false,
+        \Magento\Sales\Api\Data\CreditmemoCommentCreationInterface $comment = null,
+        \Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface $arguments = null
+    ) {
+        $orderValidationResult = $this->orderValidator->validate(
+            $order,
+            [
+                CanRefund::class
+            ]
+        );
+        $creditmemoValidationResult = $this->creditmemoValidator->validate(
+            $creditmemo,
+            [
+                QuantityValidator::class,
+                TotalsValidator::class
+            ]
+        );
+
+        $itemsValidation = [];
+        foreach ($items as $item) {
+            $itemsValidation[] = $this->itemCreationValidator->validate(
+                $item,
+                [CreationQuantityValidator::class],
+                $order
+            )->getMessages();
+        }
+
+        return $this->validatorResultMerger->merge(
+            $orderValidationResult,
+            $creditmemoValidationResult,
+            ...$itemsValidation
+        );
+    }
+}
diff --git a/app/code/Magento/Sales/Model/Order/Validation/RefundOrderInterface.php b/app/code/Magento/Sales/Model/Order/Validation/RefundOrderInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..2f770d20b513425dd67303490d67bb3d05fbc515
--- /dev/null
+++ b/app/code/Magento/Sales/Model/Order/Validation/RefundOrderInterface.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Sales\Model\Order\Validation;
+
+use Magento\Sales\Api\Data\CreditmemoInterface;
+use Magento\Sales\Api\Data\OrderInterface;
+use Magento\Sales\Model\ValidatorResultInterface;
+
+/**
+ * Interface RefundOrderInterface
+ *
+ * @api
+ */
+interface RefundOrderInterface
+{
+    /**
+     * @param OrderInterface $order
+     * @param CreditmemoInterface $creditmemo
+     * @param array $items
+     * @param bool $notify
+     * @param bool $appendComment
+     * @param \Magento\Sales\Api\Data\CreditmemoCommentCreationInterface|null $comment
+     * @param \Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface|null $arguments
+     * @return ValidatorResultInterface
+     */
+    public function validate(
+        OrderInterface $order,
+        CreditmemoInterface $creditmemo,
+        array $items = [],
+        $notify = false,
+        $appendComment = false,
+        \Magento\Sales\Api\Data\CreditmemoCommentCreationInterface $comment = null,
+        \Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface $arguments = null
+    );
+}
diff --git a/app/code/Magento/Sales/Model/Order/Validation/ShipOrder.php b/app/code/Magento/Sales/Model/Order/Validation/ShipOrder.php
new file mode 100644
index 0000000000000000000000000000000000000000..984c5f26fa7dbe50234b6f2b075397fb40f62ca1
--- /dev/null
+++ b/app/code/Magento/Sales/Model/Order/Validation/ShipOrder.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Sales\Model\Order\Validation;
+
+use Magento\Sales\Api\Data\OrderInterface;
+use Magento\Sales\Api\Data\ShipmentInterface;
+use Magento\Sales\Model\Order\Shipment\Validation\QuantityValidator;
+use Magento\Sales\Model\Order\OrderValidatorInterface;
+use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface;
+use Magento\Sales\Model\Order\Shipment\Validation\TrackValidator;
+use Magento\Sales\Model\ValidatorResultMerger;
+
+/**
+ * Class ShipOrder
+ */
+class ShipOrder implements ShipOrderInterface
+{
+    /**
+     * @var OrderValidatorInterface
+     */
+    private $orderValidator;
+
+    /**
+     * @var ShipmentValidatorInterface
+     */
+    private $shipmentValidator;
+
+    /**
+     * @var ValidatorResultMerger
+     */
+    private $validatorResultMerger;
+
+    /**
+     * ShipOrder constructor.
+     *
+     * @param OrderValidatorInterface $orderValidator
+     * @param ShipmentValidatorInterface $shipmentValidator
+     * @param ValidatorResultMerger $validatorResultMerger
+     */
+    public function __construct(
+        OrderValidatorInterface $orderValidator,
+        ShipmentValidatorInterface $shipmentValidator,
+        ValidatorResultMerger $validatorResultMerger
+    ) {
+        $this->orderValidator = $orderValidator;
+        $this->shipmentValidator = $shipmentValidator;
+        $this->validatorResultMerger = $validatorResultMerger;
+    }
+
+    /**
+     * @param OrderInterface $order
+     * @param ShipmentInterface $shipment
+     * @param array $items
+     * @param bool $notify
+     * @param bool $appendComment
+     * @param \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|null $comment
+     * @param array $tracks
+     * @param array $packages
+     * @param \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface|null $arguments
+     * @return \Magento\Sales\Model\ValidatorResultInterface
+     */
+    public function validate(
+        $order,
+        $shipment,
+        array $items = [],
+        $notify = false,
+        $appendComment = false,
+        \Magento\Sales\Api\Data\ShipmentCommentCreationInterface $comment = null,
+        array $tracks = [],
+        array $packages = [],
+        \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface $arguments = null
+    ) {
+        $orderValidationResult = $this->orderValidator->validate(
+            $order,
+            [
+                CanShip::class
+            ]
+        );
+        $shipmentValidationResult = $this->shipmentValidator->validate(
+            $shipment,
+            [
+                QuantityValidator::class,
+                TrackValidator::class
+            ]
+        );
+
+        return $this->validatorResultMerger->merge($orderValidationResult, $shipmentValidationResult);
+    }
+}
diff --git a/app/code/Magento/Sales/Model/Order/Validation/ShipOrderInterface.php b/app/code/Magento/Sales/Model/Order/Validation/ShipOrderInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..43f12df445b799621d220182bc009ff02f74c1bb
--- /dev/null
+++ b/app/code/Magento/Sales/Model/Order/Validation/ShipOrderInterface.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Sales\Model\Order\Validation;
+
+use Magento\Sales\Api\Data\OrderInterface;
+use Magento\Sales\Api\Data\ShipmentInterface;
+
+/**
+ * Interface ShipOrderInterface
+ *
+ * @api
+ */
+interface ShipOrderInterface
+{
+    /**
+     * @param OrderInterface $order
+     * @param ShipmentInterface $shipment
+     * @param array $items
+     * @param bool $notify
+     * @param bool $appendComment
+     * @param \Magento\Sales\Api\Data\ShipmentCommentCreationInterface|null $comment
+     * @param array $tracks
+     * @param array $packages
+     * @param \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface|null $arguments
+     * @return \Magento\Sales\Model\ValidatorResultInterface
+     */
+    public function validate(
+        $order,
+        $shipment,
+        array $items = [],
+        $notify = false,
+        $appendComment = false,
+        \Magento\Sales\Api\Data\ShipmentCommentCreationInterface $comment = null,
+        array $tracks = [],
+        array $packages = [],
+        \Magento\Sales\Api\Data\ShipmentCreationArgumentsInterface $arguments = null
+    );
+}
diff --git a/app/code/Magento/Sales/Model/OrderRepository.php b/app/code/Magento/Sales/Model/OrderRepository.php
index 5c14b3fd4433e4404db3921a1fffe5b13935643f..f0477fd76014adae7fefa22c6c16966819856266 100644
--- a/app/code/Magento/Sales/Model/OrderRepository.php
+++ b/app/code/Magento/Sales/Model/OrderRepository.php
@@ -146,6 +146,16 @@ class OrderRepository implements \Magento\Sales\Api\OrderRepositoryInterface
      */
     public function save(\Magento\Sales\Api\Data\OrderInterface $entity)
     {
+        /** @var  \Magento\Sales\Api\Data\OrderExtensionInterface $extensionAttributes */
+        $extensionAttributes = $entity->getExtensionAttributes();
+        if ($entity->getIsNotVirtual() && $extensionAttributes && $extensionAttributes->getShippingAssignments()) {
+            $shippingAssignments = $extensionAttributes->getShippingAssignments();
+            if (!empty($shippingAssignments)) {
+                $shipping = array_shift($shippingAssignments)->getShipping();
+                $entity->setShippingAddress($shipping->getAddress());
+                $entity->setShippingMethod($shipping->getMethod());
+            }
+        }
         $this->metadata->getMapper()->save($entity);
         $this->registry[$entity->getEntityId()] = $entity;
         return $this->registry[$entity->getEntityId()];
diff --git a/app/code/Magento/Sales/Model/RefundInvoice.php b/app/code/Magento/Sales/Model/RefundInvoice.php
index 37bf915aa505c6a757208b40a2c888515c6c8bc0..60c3a2ac121254591cdc171433770d6c2d539e80 100644
--- a/app/code/Magento/Sales/Model/RefundInvoice.php
+++ b/app/code/Magento/Sales/Model/RefundInvoice.php
@@ -11,18 +11,11 @@ use Magento\Sales\Api\InvoiceRepositoryInterface;
 use Magento\Sales\Api\OrderRepositoryInterface;
 use Magento\Sales\Api\RefundInvoiceInterface;
 use Magento\Sales\Model\Order\Config as OrderConfig;
-use Magento\Sales\Model\Order\Creditmemo\CreditmemoValidatorInterface;
-use Magento\Sales\Model\Order\Creditmemo\ItemCreationValidatorInterface;
 use Magento\Sales\Model\Order\Creditmemo\NotifierInterface;
-use Magento\Sales\Model\Order\Creditmemo\Item\Validation\CreationQuantityValidator;
-use Magento\Sales\Model\Order\Creditmemo\Validation\QuantityValidator;
-use Magento\Sales\Model\Order\Creditmemo\Validation\TotalsValidator;
 use Magento\Sales\Model\Order\CreditmemoDocumentFactory;
-use Magento\Sales\Model\Order\Invoice\InvoiceValidatorInterface;
+use Magento\Sales\Model\Order\Validation\RefundInvoiceInterface as RefundInvoiceValidator;
 use Magento\Sales\Model\Order\OrderStateResolverInterface;
-use Magento\Sales\Model\Order\OrderValidatorInterface;
 use Magento\Sales\Model\Order\PaymentAdapterInterface;
-use Magento\Sales\Model\Order\Validation\CanRefund;
 use Psr\Log\LoggerInterface;
 
 /**
@@ -51,33 +44,13 @@ class RefundInvoice implements RefundInvoiceInterface
      */
     private $invoiceRepository;
 
-    /**
-     * @var OrderValidatorInterface
-     */
-    private $orderValidator;
-
-    /**
-     * @var InvoiceValidatorInterface
-     */
-    private $invoiceValidator;
-
-    /**
-     * @var CreditmemoValidatorInterface
-     */
-    private $creditmemoValidator;
-
-    /**
-     * @var ItemCreationValidatorInterface
-     */
-    private $itemCreationValidator;
-
     /**
      * @var CreditmemoRepositoryInterface
      */
     private $creditmemoRepository;
 
     /**
-     * @var Order\PaymentAdapterInterface
+     * @var PaymentAdapterInterface
      */
     private $paymentAdapter;
 
@@ -87,7 +60,7 @@ class RefundInvoice implements RefundInvoiceInterface
     private $creditmemoDocumentFactory;
 
     /**
-     * @var Order\Creditmemo\NotifierInterface
+     * @var NotifierInterface
      */
     private $notifier;
 
@@ -101,6 +74,11 @@ class RefundInvoice implements RefundInvoiceInterface
      */
     private $logger;
 
+    /**
+     * @var RefundInvoiceValidator
+     */
+    private $validator;
+
     /**
      * RefundInvoice constructor.
      *
@@ -108,10 +86,7 @@ class RefundInvoice implements RefundInvoiceInterface
      * @param OrderStateResolverInterface $orderStateResolver
      * @param OrderRepositoryInterface $orderRepository
      * @param InvoiceRepositoryInterface $invoiceRepository
-     * @param OrderValidatorInterface $orderValidator
-     * @param InvoiceValidatorInterface $invoiceValidator
-     * @param CreditmemoValidatorInterface $creditmemoValidator
-     * @param Order\Creditmemo\ItemCreationValidatorInterface $itemCreationValidator
+     * @param RefundInvoiceValidator $validator
      * @param CreditmemoRepositoryInterface $creditmemoRepository
      * @param PaymentAdapterInterface $paymentAdapter
      * @param CreditmemoDocumentFactory $creditmemoDocumentFactory
@@ -125,10 +100,7 @@ class RefundInvoice implements RefundInvoiceInterface
         OrderStateResolverInterface $orderStateResolver,
         OrderRepositoryInterface $orderRepository,
         InvoiceRepositoryInterface $invoiceRepository,
-        OrderValidatorInterface $orderValidator,
-        InvoiceValidatorInterface $invoiceValidator,
-        CreditmemoValidatorInterface $creditmemoValidator,
-        ItemCreationValidatorInterface $itemCreationValidator,
+        RefundInvoiceValidator $validator,
         CreditmemoRepositoryInterface $creditmemoRepository,
         PaymentAdapterInterface $paymentAdapter,
         CreditmemoDocumentFactory $creditmemoDocumentFactory,
@@ -140,16 +112,13 @@ class RefundInvoice implements RefundInvoiceInterface
         $this->orderStateResolver = $orderStateResolver;
         $this->orderRepository = $orderRepository;
         $this->invoiceRepository = $invoiceRepository;
-        $this->orderValidator = $orderValidator;
-        $this->creditmemoValidator = $creditmemoValidator;
-        $this->itemCreationValidator = $itemCreationValidator;
+        $this->validator = $validator;
         $this->creditmemoRepository = $creditmemoRepository;
         $this->paymentAdapter = $paymentAdapter;
         $this->creditmemoDocumentFactory = $creditmemoDocumentFactory;
         $this->notifier = $notifier;
         $this->config = $config;
         $this->logger = $logger;
-        $this->invoiceValidator = $invoiceValidator;
     }
 
     /**
@@ -174,50 +143,27 @@ class RefundInvoice implements RefundInvoiceInterface
             ($appendComment && $notify),
             $arguments
         );
-        $orderValidationResult = $this->orderValidator->validate(
-            $order,
-            [
-                CanRefund::class
-            ]
-        );
-        $invoiceValidationResult = $this->invoiceValidator->validate(
+
+        $validationMessages = $this->validator->validate(
             $invoice,
-            [
-                \Magento\Sales\Model\Order\Invoice\Validation\CanRefund::class
-            ]
-        );
-        $creditmemoValidationResult = $this->creditmemoValidator->validate(
+            $order,
             $creditmemo,
-            [
-                QuantityValidator::class,
-                TotalsValidator::class
-            ]
-        );
-        $itemsValidation = [];
-        foreach ($items as $item) {
-            $itemsValidation = array_merge(
-                $itemsValidation,
-                $this->itemCreationValidator->validate(
-                    $item,
-                    [CreationQuantityValidator::class],
-                    $order
-                )
-            );
-        }
-        $validationMessages = array_merge(
-            $orderValidationResult,
-            $invoiceValidationResult,
-            $creditmemoValidationResult,
-            $itemsValidation
+            $items,
+            $isOnline,
+            $notify,
+            $appendComment,
+            $comment,
+            $arguments
         );
-        if (!empty($validationMessages )) {
+        if ($validationMessages->hasMessages()) {
             throw new \Magento\Sales\Exception\DocumentValidationException(
-                __("Creditmemo Document Validation Error(s):\n" . implode("\n", $validationMessages))
+                __("Creditmemo Document Validation Error(s):\n" . implode("\n", $validationMessages->getMessages()))
             );
         }
         $connection->beginTransaction();
         try {
             $creditmemo->setState(\Magento\Sales\Model\Order\Creditmemo::STATE_REFUNDED);
+            $order->setCustomerNoteNotify($notify);
             $order = $this->paymentAdapter->refund($creditmemo, $order, $isOnline);
             $order->setState(
                 $this->orderStateResolver->getStateForOrder($order, [])
diff --git a/app/code/Magento/Sales/Model/RefundOrder.php b/app/code/Magento/Sales/Model/RefundOrder.php
index 65d81df0d1de9fc4d2b2a7803369a0eda440ba12..abd6e25416729b3b995ba92425cbc3c3c7de8943 100644
--- a/app/code/Magento/Sales/Model/RefundOrder.php
+++ b/app/code/Magento/Sales/Model/RefundOrder.php
@@ -10,17 +10,11 @@ use Magento\Sales\Api\CreditmemoRepositoryInterface;
 use Magento\Sales\Api\OrderRepositoryInterface;
 use Magento\Sales\Api\RefundOrderInterface;
 use Magento\Sales\Model\Order\Config as OrderConfig;
-use Magento\Sales\Model\Order\Creditmemo\CreditmemoValidatorInterface;
-use Magento\Sales\Model\Order\Creditmemo\ItemCreationValidatorInterface;
 use Magento\Sales\Model\Order\Creditmemo\NotifierInterface;
-use Magento\Sales\Model\Order\Creditmemo\Item\Validation\CreationQuantityValidator;
-use Magento\Sales\Model\Order\Creditmemo\Validation\QuantityValidator;
-use Magento\Sales\Model\Order\Creditmemo\Validation\TotalsValidator;
 use Magento\Sales\Model\Order\CreditmemoDocumentFactory;
 use Magento\Sales\Model\Order\OrderStateResolverInterface;
-use Magento\Sales\Model\Order\OrderValidatorInterface;
 use Magento\Sales\Model\Order\PaymentAdapterInterface;
-use Magento\Sales\Model\Order\Validation\CanRefund;
+use Magento\Sales\Model\Order\Validation\RefundOrderInterface as RefundOrderValidator;
 use Psr\Log\LoggerInterface;
 
 /**
@@ -44,28 +38,13 @@ class RefundOrder implements RefundOrderInterface
      */
     private $orderRepository;
 
-    /**
-     * @var OrderValidatorInterface
-     */
-    private $orderValidator;
-
-    /**
-     * @var CreditmemoValidatorInterface
-     */
-    private $creditmemoValidator;
-
-    /**
-     * @var Order\Creditmemo\ItemCreationValidatorInterface
-     */
-    private $itemCreationValidator;
-
     /**
      * @var CreditmemoRepositoryInterface
      */
     private $creditmemoRepository;
 
     /**
-     * @var Order\PaymentAdapterInterface
+     * @var PaymentAdapterInterface
      */
     private $paymentAdapter;
 
@@ -75,7 +54,12 @@ class RefundOrder implements RefundOrderInterface
     private $creditmemoDocumentFactory;
 
     /**
-     * @var Order\Creditmemo\NotifierInterface
+     * @var RefundOrderValidator
+     */
+    private $validator;
+
+    /**
+     * @var NotifierInterface
      */
     private $notifier;
 
@@ -91,15 +75,14 @@ class RefundOrder implements RefundOrderInterface
 
     /**
      * RefundOrder constructor.
+     *
      * @param ResourceConnection $resourceConnection
      * @param OrderStateResolverInterface $orderStateResolver
      * @param OrderRepositoryInterface $orderRepository
-     * @param OrderValidatorInterface $orderValidator
-     * @param CreditmemoValidatorInterface $creditmemoValidator
-     * @param ItemCreationValidatorInterface $itemCreationValidator
      * @param CreditmemoRepositoryInterface $creditmemoRepository
      * @param PaymentAdapterInterface $paymentAdapter
      * @param CreditmemoDocumentFactory $creditmemoDocumentFactory
+     * @param RefundOrderValidator $validator
      * @param NotifierInterface $notifier
      * @param OrderConfig $config
      * @param LoggerInterface $logger
@@ -109,12 +92,10 @@ class RefundOrder implements RefundOrderInterface
         ResourceConnection $resourceConnection,
         OrderStateResolverInterface $orderStateResolver,
         OrderRepositoryInterface $orderRepository,
-        OrderValidatorInterface $orderValidator,
-        CreditmemoValidatorInterface $creditmemoValidator,
-        ItemCreationValidatorInterface $itemCreationValidator,
         CreditmemoRepositoryInterface $creditmemoRepository,
         PaymentAdapterInterface $paymentAdapter,
         CreditmemoDocumentFactory $creditmemoDocumentFactory,
+        RefundOrderValidator $validator,
         NotifierInterface $notifier,
         OrderConfig $config,
         LoggerInterface $logger
@@ -122,12 +103,10 @@ class RefundOrder implements RefundOrderInterface
         $this->resourceConnection = $resourceConnection;
         $this->orderStateResolver = $orderStateResolver;
         $this->orderRepository = $orderRepository;
-        $this->orderValidator = $orderValidator;
-        $this->creditmemoValidator = $creditmemoValidator;
-        $this->itemCreationValidator = $itemCreationValidator;
         $this->creditmemoRepository = $creditmemoRepository;
         $this->paymentAdapter = $paymentAdapter;
         $this->creditmemoDocumentFactory = $creditmemoDocumentFactory;
+        $this->validator = $validator;
         $this->notifier = $notifier;
         $this->config = $config;
         $this->logger = $logger;
@@ -153,39 +132,24 @@ class RefundOrder implements RefundOrderInterface
             ($appendComment && $notify),
             $arguments
         );
-        $orderValidationResult = $this->orderValidator->validate(
+        $validationMessages = $this->validator->validate(
             $order,
-            [
-                CanRefund::class
-            ]
-        );
-        $creditmemoValidationResult = $this->creditmemoValidator->validate(
             $creditmemo,
-            [
-                QuantityValidator::class,
-                TotalsValidator::class
-            ]
+            $items,
+            $notify,
+            $appendComment,
+            $comment,
+            $arguments
         );
-        $itemsValidation = [];
-        foreach ($items as $item) {
-            $itemsValidation = array_merge(
-                $itemsValidation,
-                $this->itemCreationValidator->validate(
-                    $item,
-                    [CreationQuantityValidator::class],
-                    $order
-                )
-            );
-        }
-        $validationMessages = array_merge($orderValidationResult, $creditmemoValidationResult, $itemsValidation);
-        if (!empty($validationMessages)) {
+        if ($validationMessages->hasMessages()) {
             throw new \Magento\Sales\Exception\DocumentValidationException(
-                __("Creditmemo Document Validation Error(s):\n" . implode("\n", $validationMessages))
+                __("Creditmemo Document Validation Error(s):\n" . implode("\n", $validationMessages->getMessages()))
             );
         }
         $connection->beginTransaction();
         try {
             $creditmemo->setState(\Magento\Sales\Model\Order\Creditmemo::STATE_REFUNDED);
+            $order->setCustomerNoteNotify($notify);
             $order = $this->paymentAdapter->refund($creditmemo, $order);
             $order->setState(
                 $this->orderStateResolver->getStateForOrder($order, [])
diff --git a/app/code/Magento/Sales/Model/Service/CreditmemoService.php b/app/code/Magento/Sales/Model/Service/CreditmemoService.php
index 4889ccd3750d5590c97a58e8b4f00643c1cf9fec..16c302111704371b0899c115fbf97c128326975f 100644
--- a/app/code/Magento/Sales/Model/Service/CreditmemoService.php
+++ b/app/code/Magento/Sales/Model/Service/CreditmemoService.php
@@ -182,7 +182,7 @@ class CreditmemoService implements \Magento\Sales\Api\CreditmemoManagementInterf
             $connection->commit();
         } catch (\Exception $e) {
             $connection->rollBack();
-            throw new \Magento\Framework\Exception\LocalizedException($e->getMessage());
+            throw new \Magento\Framework\Exception\LocalizedException(__($e->getMessage()));
         }
 
         return $creditmemo;
diff --git a/app/code/Magento/Sales/Model/ShipOrder.php b/app/code/Magento/Sales/Model/ShipOrder.php
index d051144cf73ca166c30ebd6eb9f626306b1720a6..034442a19c1f7e297e364e894ef53275574c4706 100644
--- a/app/code/Magento/Sales/Model/ShipOrder.php
+++ b/app/code/Magento/Sales/Model/ShipOrder.php
@@ -11,14 +11,10 @@ use Magento\Sales\Api\ShipmentRepositoryInterface;
 use Magento\Sales\Api\ShipOrderInterface;
 use Magento\Sales\Model\Order\Config as OrderConfig;
 use Magento\Sales\Model\Order\OrderStateResolverInterface;
-use Magento\Sales\Model\Order\OrderValidatorInterface;
 use Magento\Sales\Model\Order\ShipmentDocumentFactory;
 use Magento\Sales\Model\Order\Shipment\NotifierInterface;
-use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface;
-use Magento\Sales\Model\Order\Shipment\Validation\QuantityValidator;
-use Magento\Sales\Model\Order\Shipment\Validation\TrackValidator;
-use Magento\Sales\Model\Order\Validation\CanShip;
 use Magento\Sales\Model\Order\Shipment\OrderRegistrarInterface;
+use Magento\Sales\Model\Order\Validation\ShipOrderInterface as ShipOrderValidator;
 use Psr\Log\LoggerInterface;
 
 /**
@@ -42,11 +38,6 @@ class ShipOrder implements ShipOrderInterface
      */
     private $shipmentDocumentFactory;
 
-    /**
-     * @var ShipmentValidatorInterface
-     */
-    private $shipmentValidator;
-
     /**
      * @var OrderStateResolverInterface
      */
@@ -62,6 +53,11 @@ class ShipOrder implements ShipOrderInterface
      */
     private $shipmentRepository;
 
+    /**
+     * @var ShipOrderValidator
+     */
+    private $shipOrderValidator;
+
     /**
      * @var NotifierInterface
      */
@@ -72,11 +68,6 @@ class ShipOrder implements ShipOrderInterface
      */
     private $logger;
 
-    /**
-     * @var OrderValidatorInterface
-     */
-    private $orderValidator;
-
     /**
      * @var OrderRegistrarInterface
      */
@@ -86,11 +77,10 @@ class ShipOrder implements ShipOrderInterface
      * @param ResourceConnection $resourceConnection
      * @param OrderRepositoryInterface $orderRepository
      * @param ShipmentDocumentFactory $shipmentDocumentFactory
-     * @param ShipmentValidatorInterface $shipmentValidator
-     * @param OrderValidatorInterface $orderValidator
      * @param OrderStateResolverInterface $orderStateResolver
      * @param OrderConfig $config
      * @param ShipmentRepositoryInterface $shipmentRepository
+     * @param ShipOrderValidator $shipOrderValidator
      * @param NotifierInterface $notifierInterface
      * @param OrderRegistrarInterface $orderRegistrar
      * @param LoggerInterface $logger
@@ -100,11 +90,10 @@ class ShipOrder implements ShipOrderInterface
         ResourceConnection $resourceConnection,
         OrderRepositoryInterface $orderRepository,
         ShipmentDocumentFactory $shipmentDocumentFactory,
-        ShipmentValidatorInterface $shipmentValidator,
-        OrderValidatorInterface $orderValidator,
         OrderStateResolverInterface $orderStateResolver,
         OrderConfig $config,
         ShipmentRepositoryInterface $shipmentRepository,
+        ShipOrderValidator $shipOrderValidator,
         NotifierInterface $notifierInterface,
         OrderRegistrarInterface $orderRegistrar,
         LoggerInterface $logger
@@ -112,11 +101,10 @@ class ShipOrder implements ShipOrderInterface
         $this->resourceConnection = $resourceConnection;
         $this->orderRepository = $orderRepository;
         $this->shipmentDocumentFactory = $shipmentDocumentFactory;
-        $this->shipmentValidator = $shipmentValidator;
-        $this->orderValidator = $orderValidator;
         $this->orderStateResolver = $orderStateResolver;
         $this->config = $config;
         $this->shipmentRepository = $shipmentRepository;
+        $this->shipOrderValidator = $shipOrderValidator;
         $this->notifierInterface = $notifierInterface;
         $this->logger = $logger;
         $this->orderRegistrar = $orderRegistrar;
@@ -159,23 +147,19 @@ class ShipOrder implements ShipOrderInterface
             $packages,
             $arguments
         );
-        $orderValidationResult = $this->orderValidator->validate(
+        $validationMessages = $this->shipOrderValidator->validate(
             $order,
-            [
-                CanShip::class
-            ]
-        );
-        $shipmentValidationResult = $this->shipmentValidator->validate(
             $shipment,
-            [
-                QuantityValidator::class,
-                TrackValidator::class
-            ]
+            $items,
+            $notify,
+            $appendComment,
+            $comment,
+            $tracks,
+            $packages
         );
-        $validationMessages = array_merge($orderValidationResult, $shipmentValidationResult);
-        if (!empty($validationMessages)) {
+        if ($validationMessages->hasMessages()) {
             throw new \Magento\Sales\Exception\DocumentValidationException(
-                __("Shipment Document Validation Error(s):\n" . implode("\n", $validationMessages))
+                __("Shipment Document Validation Error(s):\n" . implode("\n", $validationMessages->getMessages()))
             );
         }
         $connection->beginTransaction();
diff --git a/app/code/Magento/Sales/Model/Validator.php b/app/code/Magento/Sales/Model/Validator.php
index 10aa0735b952e99e0d889b27ff378411d0d1d6d1..9239223fe3b4a84ee1e319e6f067ca9ba6cfb3e8 100644
--- a/app/code/Magento/Sales/Model/Validator.php
+++ b/app/code/Magento/Sales/Model/Validator.php
@@ -20,21 +20,30 @@ class Validator
      */
     private $objectManager;
 
+    /**
+     * @var ValidatorResultInterfaceFactory
+     */
+    private $validatorResultFactory;
+
     /**
      * Validator constructor.
      *
      * @param ObjectManagerInterface $objectManager
+     * @param ValidatorResultInterfaceFactory $validatorResult
      */
-    public function __construct(ObjectManagerInterface $objectManager)
-    {
+    public function __construct(
+        ObjectManagerInterface $objectManager,
+        ValidatorResultInterfaceFactory $validatorResult
+    ) {
         $this->objectManager = $objectManager;
+        $this->validatorResultFactory = $validatorResult;
     }
 
     /**
      * @param object $entity
      * @param ValidatorInterface[] $validators
      * @param object|null $context
-     * @return \string[]
+     * @return ValidatorResultInterface
      * @throws ConfigurationMismatchException
      */
     public function validate($entity, array $validators, $context = null)
@@ -56,7 +65,11 @@ class Validator
             }
             $messages = array_merge($messages, $validator->validate($entity));
         }
+        $validationResult = $this->validatorResultFactory->create();
+        foreach ($messages as $message) {
+            $validationResult->addMessage($message);
+        }
 
-        return $messages;
+        return $validationResult;
     }
 }
diff --git a/app/code/Magento/Sales/Model/ValidatorResult.php b/app/code/Magento/Sales/Model/ValidatorResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..6dc2933ac42a7c2974d397aebf3e3c599831b5bf
--- /dev/null
+++ b/app/code/Magento/Sales/Model/ValidatorResult.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Sales\Model;
+
+/**
+ * Class ValidatorResult
+ */
+class ValidatorResult implements ValidatorResultInterface
+{
+    /**
+     * @var \string[]
+     */
+    private $messages = [];
+
+    /**
+     * @inheritdoc
+     */
+    public function addMessage($message)
+    {
+        $this->messages[] = (string)$message;
+    }
+
+    /**
+     * @return bool
+     */
+    public function hasMessages()
+    {
+        return count($this->messages) > 0;
+    }
+
+    /**
+     * @return \string[]
+     */
+    public function getMessages()
+    {
+        return $this->messages;
+    }
+}
diff --git a/app/code/Magento/Sales/Model/ValidatorResultInterface.php b/app/code/Magento/Sales/Model/ValidatorResultInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..c4e284657bdd1f1261094f05337577ebf3656ad7
--- /dev/null
+++ b/app/code/Magento/Sales/Model/ValidatorResultInterface.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Sales\Model;
+
+/**
+ * Interface ValidatorResultInterface
+ * @api
+ */
+interface ValidatorResultInterface
+{
+    /**
+     * @param string $message
+     * @return void
+     */
+    public function addMessage($message);
+
+    /**
+     * @return bool
+     */
+    public function hasMessages();
+
+    /**
+     * @return \string[]
+     */
+    public function getMessages();
+}
diff --git a/app/code/Magento/Sales/Model/ValidatorResultMerger.php b/app/code/Magento/Sales/Model/ValidatorResultMerger.php
new file mode 100644
index 0000000000000000000000000000000000000000..41f38e8eef078b221c70cdb9520f6043ccfe4daf
--- /dev/null
+++ b/app/code/Magento/Sales/Model/ValidatorResultMerger.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Sales\Model;
+
+/**
+ * Class ValidatorResultMerger
+ */
+class ValidatorResultMerger
+{
+    /**
+     * @var ValidatorResultInterfaceFactory
+     */
+    private $validatorResultInterfaceFactory;
+
+    /**
+     * ValidatorResultMerger constructor.
+     *
+     * @param ValidatorResultInterfaceFactory $validatorResultInterfaceFactory
+     */
+    public function __construct(ValidatorResultInterfaceFactory $validatorResultInterfaceFactory)
+    {
+        $this->validatorResultInterfaceFactory = $validatorResultInterfaceFactory;
+    }
+
+    /**
+     * Merge two validator results and additional messages
+     *
+     * @param ValidatorResultInterface $first
+     * @param ValidatorResultInterface $second
+     * @param \string[] $validatorMessages
+     * @return ValidatorResultInterface
+     */
+    public function merge(ValidatorResultInterface $first, ValidatorResultInterface $second, ... $validatorMessages)
+    {
+        $messages = array_merge($first->getMessages(), $second->getMessages(), ...$validatorMessages);
+
+        $result = $this->validatorResultInterfaceFactory->create();
+        foreach ($messages as $message) {
+            $result->addMessage($message);
+        }
+
+        return $result;
+    }
+}
diff --git a/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/View/Tab/HistoryTest.php b/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/View/Tab/HistoryTest.php
index 6445fd36dd14669afda748c05a0d9b558f1c31e0..0edeac71709290d7a3f3a8ace81604e35dd92feb 100644
--- a/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/View/Tab/HistoryTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/View/Tab/HistoryTest.php
@@ -30,6 +30,16 @@ class HistoryTest extends \PHPUnit_Framework_TestCase
      */
     protected $coreRegistryMock;
 
+    /**
+     * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $localeDateMock;
+
+    /**
+     * @var \Magento\Backend\Block\Template\Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $contextMock;
+
     protected function setUp()
     {
         $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
@@ -37,11 +47,25 @@ class HistoryTest extends \PHPUnit_Framework_TestCase
         $this->coreRegistryMock = $this->getMock(\Magento\Framework\Registry::class, [], [], '', false);
         $this->adminHelperMock = $this->getMock(\Magento\Sales\Helper\Admin::class, [], [], '', false);
 
+        $this->contextMock = $this->getMockBuilder(\Magento\Backend\Block\Template\Context::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getLocaleDate'])
+            ->getMock();
+
+        $this->localeDateMock = $this->getMockBuilder(\Magento\Framework\Stdlib\DateTime\TimezoneInterface::class)
+            ->getMock();
+
+        $this->contextMock->expects($this->any())->method('getLocaleDate')->will(
+            $this->returnValue($this->localeDateMock)
+        );
+
         $this->commentsHistory = $this->objectManager->getObject(
             \Magento\Sales\Block\Adminhtml\Order\View\Tab\History::class,
             [
                 'adminHelper' => $this->adminHelperMock,
-                'registry' => $this->coreRegistryMock
+                'registry' => $this->coreRegistryMock,
+                'context' => $this->contextMock,
+                'localeDate' => $this->localeDateMock
             ]
         );
     }
@@ -63,4 +87,39 @@ class HistoryTest extends \PHPUnit_Framework_TestCase
         $this->adminHelperMock->expects($this->never())->method('escapeHtmlWithLinks');
         $this->assertEquals('', $this->commentsHistory->getItemComment($item));
     }
+
+    public function testGetItemCreatedAtDate()
+    {
+        $date = new \DateTime;
+        $item = ['created_at' => $date ];
+
+        $this->localeDateMock->expects($this->once())
+            ->method('formatDateTime')
+            ->with($date, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::NONE)
+            ->willReturn('date');
+
+        $this->assertEquals('date', $this->commentsHistory->getItemCreatedAt($item));
+    }
+
+    public function testGetItemCreatedAtTime()
+    {
+        $date = new \DateTime;
+        $item = ['created_at' => $date ];
+
+        $this->localeDateMock->expects($this->once())
+            ->method('formatDateTime')
+            ->with($date, \IntlDateFormatter::NONE, \IntlDateFormatter::MEDIUM)
+            ->willReturn('time');
+
+        $this->assertEquals('time', $this->commentsHistory->getItemCreatedAt($item, 'time'));
+    }
+
+    public function testGetItemCreatedAtEmpty()
+    {
+        $item = ['title' => "Test" ];
+
+        $this->localeDateMock->expects($this->never())->method('formatDateTime');
+        $this->assertEquals('', $this->commentsHistory->getItemCreatedAt($item));
+        $this->assertEquals('', $this->commentsHistory->getItemCreatedAt($item, 'time'));
+    }
 }
diff --git a/app/code/Magento/Sales/Test/Unit/Model/AdminOrder/CreateTest.php b/app/code/Magento/Sales/Test/Unit/Model/AdminOrder/CreateTest.php
index 7d8e5c66b3e6767e7295ef5a4a7a312ba6416a33..a922136e1d4e832b0bed6cad90137997161995a6 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/AdminOrder/CreateTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/AdminOrder/CreateTest.php
@@ -100,14 +100,14 @@ class CreateTest extends \PHPUnit_Framework_TestCase
         $loggerMock = $this->getMock(\Psr\Log\LoggerInterface::class);
         $copyMock = $this->getMock(\Magento\Framework\DataObject\Copy::class, [], [], '', false);
         $messageManagerMock = $this->getMock(\Magento\Framework\Message\ManagerInterface::class);
-        $this->formFactoryMock = $this->getMock(
+        $this->formFactoryMock = $this->getMock(
             \Magento\Customer\Model\Metadata\FormFactory::class,
             ['create'],
             [],
             '',
             false
         );
-        $this->customerFactoryMock = $this->getMock(
+        $this->customerFactoryMock = $this->getMock(
             \Magento\Customer\Api\Data\CustomerInterfaceFactory::class,
             ['create'],
             [],
@@ -122,56 +122,56 @@ class CreateTest extends \PHPUnit_Framework_TestCase
             ->setMethods(['create'])
             ->getMock();
 
-        $this->customerMapper = $this->getMockBuilder(
+        $this->customerMapper = $this->getMockBuilder(
             \Magento\Customer\Model\Customer\Mapper::class
         )->setMethods(['toFlatArray'])->disableOriginalConstructor()->getMock();
 
-        $this->quoteInitializerMock = $this->getMock(
+        $this->quoteInitializerMock = $this->getMock(
             \Magento\Sales\Model\AdminOrder\Product\Quote\Initializer::class,
             [],
             [],
             '',
             false
         );
-        $this->customerRepositoryMock = $this->getMockForAbstractClass(
+        $this->customerRepositoryMock = $this->getMockForAbstractClass(
             \Magento\Customer\Api\CustomerRepositoryInterface::class,
             [],
             '',
             false
         );
-        $this->addressRepositoryMock = $this->getMockForAbstractClass(
+        $this->addressRepositoryMock = $this->getMockForAbstractClass(
             \Magento\Customer\Api\AddressRepositoryInterface::class,
             [],
             '',
             false
         );
-        $this->addressFactoryMock = $this->getMock(
+        $this->addressFactoryMock = $this->getMock(
             \Magento\Customer\Api\Data\AddressInterfaceFactory::class,
             [],
             [],
             '',
             false
         );
-        $this->groupRepositoryMock = $this->getMockForAbstractClass(
+        $this->groupRepositoryMock = $this->getMockForAbstractClass(
             \Magento\Customer\Api\GroupRepositoryInterface::class,
             [],
             '',
             false
         );
-        $this->scopeConfigMock = $this->getMockForAbstractClass(
+        $this->scopeConfigMock = $this->getMockForAbstractClass(
             \Magento\Framework\App\Config\ScopeConfigInterface::class,
             [],
             '',
             false
         );
-        $this->emailSenderMock = $this->getMock(
+        $this->emailSenderMock = $this->getMock(
             \Magento\Sales\Model\AdminOrder\EmailSender::class,
             [],
             [],
             '',
             false
         );
-        $this->accountManagementMock = $this->getMockForAbstractClass(
+        $this->accountManagementMock = $this->getMockForAbstractClass(
             \Magento\Customer\Api\AccountManagementInterface::class,
             [],
             '',
@@ -182,7 +182,7 @@ class CreateTest extends \PHPUnit_Framework_TestCase
             ->getMock();
 
         $objectManagerHelper = new ObjectManagerHelper($this);
-        $this->adminOrderCreate = $objectManagerHelper->getObject(
+        $this->adminOrderCreate = $objectManagerHelper->getObject(
             \Magento\Sales\Model\AdminOrder\Create::class,
             [
                 'objectManager' => $objectManagerMock,
@@ -219,7 +219,7 @@ class CreateTest extends \PHPUnit_Framework_TestCase
         $attributeMocks = [];
 
         foreach ($attributes as $attribute) {
-            $attributeMock = $this->getMock(
+            $attributeMock = $this->getMock(
                 \Magento\Customer\Api\Data\AttributeMetadataInterface::class,
                 [],
                 [],
@@ -232,7 +232,7 @@ class CreateTest extends \PHPUnit_Framework_TestCase
             $attributeMocks[] = $attributeMock;
         }
 
-        $customerGroupMock = $this->getMockForAbstractClass(
+        $customerGroupMock = $this->getMockForAbstractClass(
             \Magento\Customer\Api\Data\GroupInterface::class,
             [],
             '',
@@ -243,9 +243,11 @@ class CreateTest extends \PHPUnit_Framework_TestCase
         );
         $customerGroupMock->expects($this->once())->method('getTaxClassId')->will($this->returnValue($taxClassId));
         $customerFormMock = $this->getMock(\Magento\Customer\Model\Metadata\Form::class, [], [], '', false);
-        $customerFormMock->expects($this->any())->method('getAttributes')->will($this->returnValue($attributeMocks));
+        $customerFormMock->expects($this->any())
+            ->method('getAttributes')
+            ->will($this->returnValue([$attributeMocks[1]]));
         $customerFormMock->expects($this->any())->method('extractData')->will($this->returnValue([]));
-        $customerFormMock->expects($this->any())->method('restoreData')->will($this->returnValue([]));
+        $customerFormMock->expects($this->any())->method('restoreData')->will($this->returnValue(['group_id' => 1]));
 
         $customerFormMock->expects($this->any())
             ->method('prepareRequest')
@@ -254,7 +256,7 @@ class CreateTest extends \PHPUnit_Framework_TestCase
         $customerMock = $this->getMock(\Magento\Customer\Api\Data\CustomerInterface::class, [], [], '', false);
         $this->customerMapper->expects($this->atLeastOnce())
             ->method('toFlatArray')
-            ->willReturn(['email' => 'user@example.com', 'group_id' => 1, 'gender' => 1]);
+            ->willReturn(['group_id' => 1]);
 
 
         $quoteMock = $this->getMock(\Magento\Quote\Model\Quote::class, [], [], '', false);
@@ -263,7 +265,6 @@ class CreateTest extends \PHPUnit_Framework_TestCase
             ->method('addData')
             ->with(
             [
-                'customer_email' => $attributes[0][1],
                 'customer_group_id' => $attributes[1][1],
                 'customer_tax_class_id' => $taxClassId
             ]
@@ -272,7 +273,7 @@ class CreateTest extends \PHPUnit_Framework_TestCase
             ->method('populateWithArray')
             ->with(
                 $customerMock,
-                ['email' => 'user@example.com', 'group_id' => 1, 'gender' => 1], \Magento\Customer\Api\Data\CustomerInterface::class
+                ['group_id' => 1], \Magento\Customer\Api\Data\CustomerInterface::class
             );
 
         $this->formFactoryMock->expects($this->any())->method('create')->will($this->returnValue($customerFormMock));
@@ -283,7 +284,7 @@ class CreateTest extends \PHPUnit_Framework_TestCase
             ->method('getById')
             ->will($this->returnValue($customerGroupMock));
 
-        $this->adminOrderCreate->setAccountData([]);
+        $this->adminOrderCreate->setAccountData(['group_id' => 1]);
     }
 
     public function testUpdateQuoteItemsNotArray()
@@ -350,4 +351,32 @@ class CreateTest extends \PHPUnit_Framework_TestCase
         $this->adminOrderCreate->setRecollect(false);
         $this->adminOrderCreate->updateQuoteItems($items);
     }
+
+    public function testApplyCoupon()
+    {
+        $couponCode = '';
+        $quoteMock = $this->getMock(
+            \Magento\Quote\Model\Quote::class,
+            ['getShippingAddress', 'setCouponCode'],
+            [],
+            '',
+            false
+        );
+        $this->sessionQuoteMock->expects($this->once())->method('getQuote')->willReturn($quoteMock);
+
+        $addressMock = $this->getMock(
+            \Magento\Quote\Model\Quote\Address::class,
+            ['setCollectShippingRates', 'setFreeShipping'],
+            [],
+            '',
+            false
+        );
+        $quoteMock->expects($this->exactly(2))->method('getShippingAddress')->willReturn($addressMock);
+        $quoteMock->expects($this->once())->method('setCouponCode')->with($couponCode)->willReturnSelf();
+
+        $addressMock->expects($this->once())->method('setCollectShippingRates')->with(true)->willReturnSelf();
+        $addressMock->expects($this->once())->method('setFreeShipping')->with(null)->willReturnSelf();
+
+        $this->adminOrderCreate->applyCoupon($couponCode);
+    }
 }
diff --git a/app/code/Magento/Sales/Test/Unit/Model/InvoiceOrderTest.php b/app/code/Magento/Sales/Test/Unit/Model/InvoiceOrderTest.php
index 6dfa929acb6290e0e95bf2011b76ec9811691ecc..1169e230e75421d150a2719edfb14c09fddf1120 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/InvoiceOrderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/InvoiceOrderTest.php
@@ -14,19 +14,19 @@ use Magento\Sales\Api\Data\OrderInterface;
 use Magento\Sales\Api\OrderRepositoryInterface;
 use Magento\Sales\Model\Order;
 use Magento\Sales\Model\Order\Config as OrderConfig;
-use Magento\Sales\Model\Order\Invoice\InvoiceValidatorInterface;
 use Magento\Sales\Model\Order\Invoice\NotifierInterface;
 use Magento\Sales\Model\Order\InvoiceDocumentFactory;
 use Magento\Sales\Model\Order\InvoiceRepository;
 use Magento\Sales\Model\Order\OrderStateResolverInterface;
-use Magento\Sales\Model\Order\OrderValidatorInterface;
+use Magento\Sales\Model\Order\Validation\InvoiceOrderInterface;
 use Magento\Sales\Model\Order\PaymentAdapterInterface;
+use Magento\Sales\Model\ValidatorResultInterface;
 use Magento\Sales\Model\InvoiceOrder;
 use Psr\Log\LoggerInterface;
 
 /**
  * Class InvoiceOrderTest
- * 
+ *
  * @SuppressWarnings(PHPMD.TooManyFields)
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
@@ -48,14 +48,9 @@ class InvoiceOrderTest extends \PHPUnit_Framework_TestCase
     private $invoiceDocumentFactoryMock;
 
     /**
-     * @var InvoiceValidatorInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var InvoiceOrderInterface|\PHPUnit_Framework_MockObject_MockObject
      */
-    private $invoiceValidatorMock;
-
-    /**
-     * @var OrderValidatorInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $orderValidatorMock;
+    private $invoiceOrderValidatorMock;
 
     /**
      * @var PaymentAdapterInterface|\PHPUnit_Framework_MockObject_MockObject
@@ -117,6 +112,11 @@ class InvoiceOrderTest extends \PHPUnit_Framework_TestCase
      */
     private $loggerMock;
 
+    /**
+     * @var ValidatorResultInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $errorMessagesMock;
+
     protected function setUp()
     {
         $this->resourceConnectionMock = $this->getMockBuilder(ResourceConnection::class)
@@ -131,14 +131,6 @@ class InvoiceOrderTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
 
-        $this->invoiceValidatorMock = $this->getMockBuilder(InvoiceValidatorInterface::class)
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        $this->orderValidatorMock = $this->getMockBuilder(OrderValidatorInterface::class)
-            ->disableOriginalConstructor()
-            ->getMock();
-
         $this->paymentAdapterMock = $this->getMockBuilder(PaymentAdapterInterface::class)
             ->disableOriginalConstructor()
             ->getMock();
@@ -183,22 +175,37 @@ class InvoiceOrderTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
 
+        $this->invoiceOrderValidatorMock = $this->getMockBuilder(InvoiceOrderInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->errorMessagesMock = $this->getMockBuilder(ValidatorResultInterface::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['hasMessages', 'getMessages', 'addMessage'])
+            ->getMock();
+
         $this->invoiceOrder = new InvoiceOrder(
             $this->resourceConnectionMock,
             $this->orderRepositoryMock,
             $this->invoiceDocumentFactoryMock,
-            $this->invoiceValidatorMock,
-            $this->orderValidatorMock,
             $this->paymentAdapterMock,
             $this->orderStateResolverMock,
             $this->configMock,
             $this->invoiceRepositoryMock,
+            $this->invoiceOrderValidatorMock,
             $this->notifierInterfaceMock,
             $this->loggerMock
         );
     }
 
     /**
+     * @param int $orderId
+     * @param bool $capture
+     * @param array $items
+     * @param bool $notify
+     * @param bool $appendComment
+     * @throws \Magento\Sales\Exception\CouldNotInvoiceException
+     * @throws \Magento\Sales\Exception\DocumentValidationException
      * @dataProvider dataProvider
      */
     public function testOrderInvoice($orderId, $capture, $items, $notify, $appendComment)
@@ -207,11 +214,9 @@ class InvoiceOrderTest extends \PHPUnit_Framework_TestCase
             ->method('getConnection')
             ->with('sales')
             ->willReturn($this->adapterInterface);
-
         $this->orderRepositoryMock->expects($this->once())
             ->method('get')
             ->willReturn($this->orderMock);
-
         $this->invoiceDocumentFactoryMock->expects($this->once())
             ->method('create')
             ->with(
@@ -221,66 +226,62 @@ class InvoiceOrderTest extends \PHPUnit_Framework_TestCase
                 ($appendComment && $notify),
                 $this->invoiceCreationArgumentsMock
             )->willReturn($this->invoiceMock);
-
-        $this->invoiceValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->invoiceMock)
-            ->willReturn([]);
-        $this->orderValidatorMock->expects($this->once())
+        $this->invoiceOrderValidatorMock->expects($this->once())
             ->method('validate')
-            ->with($this->orderMock)
-            ->willReturn([]);
-
+            ->with(
+                $this->orderMock,
+                $this->invoiceMock,
+                $capture,
+                $items,
+                $notify,
+                $appendComment,
+                $this->invoiceCommentCreationMock,
+                $this->invoiceCreationArgumentsMock
+            )
+            ->willReturn($this->errorMessagesMock);
+        $hasMessages = false;
+        $this->errorMessagesMock->expects($this->once())
+            ->method('hasMessages')->willReturn($hasMessages);
         $this->paymentAdapterMock->expects($this->once())
             ->method('pay')
             ->with($this->orderMock, $this->invoiceMock, $capture)
             ->willReturn($this->orderMock);
-
         $this->orderStateResolverMock->expects($this->once())
             ->method('getStateForOrder')
             ->with($this->orderMock, [OrderStateResolverInterface::IN_PROGRESS])
             ->willReturn(Order::STATE_PROCESSING);
-
         $this->orderMock->expects($this->once())
             ->method('setState')
             ->with(Order::STATE_PROCESSING)
             ->willReturnSelf();
-
         $this->orderMock->expects($this->once())
             ->method('getState')
             ->willReturn(Order::STATE_PROCESSING);
-
         $this->configMock->expects($this->once())
             ->method('getStateDefaultStatus')
             ->with(Order::STATE_PROCESSING)
             ->willReturn('Processing');
-
         $this->orderMock->expects($this->once())
             ->method('setStatus')
             ->with('Processing')
             ->willReturnSelf();
-
         $this->invoiceMock->expects($this->once())
             ->method('setState')
             ->with(\Magento\Sales\Model\Order\Invoice::STATE_PAID)
             ->willReturnSelf();
-
         $this->invoiceRepositoryMock->expects($this->once())
             ->method('save')
             ->with($this->invoiceMock)
             ->willReturn($this->invoiceMock);
-
         $this->orderRepositoryMock->expects($this->once())
             ->method('save')
             ->with($this->orderMock)
             ->willReturn($this->orderMock);
-
         if ($notify) {
             $this->notifierInterfaceMock->expects($this->once())
                 ->method('notify')
                 ->with($this->orderMock, $this->invoiceMock, $this->invoiceCommentCreationMock);
         }
-
         $this->invoiceMock->expects($this->once())
             ->method('getEntityId')
             ->willReturn(2);
@@ -325,14 +326,25 @@ class InvoiceOrderTest extends \PHPUnit_Framework_TestCase
                 $this->invoiceCreationArgumentsMock
             )->willReturn($this->invoiceMock);
 
-        $this->invoiceValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->invoiceMock)
-            ->willReturn($errorMessages);
-        $this->orderValidatorMock->expects($this->once())
+        $this->invoiceOrderValidatorMock->expects($this->once())
             ->method('validate')
-            ->with($this->orderMock)
-            ->willReturn([]);
+            ->with(
+                $this->orderMock,
+                $this->invoiceMock,
+                $capture,
+                $items,
+                $notify,
+                $appendComment,
+                $this->invoiceCommentCreationMock,
+                $this->invoiceCreationArgumentsMock
+            )
+            ->willReturn($this->errorMessagesMock);
+        $hasMessages = true;
+
+        $this->errorMessagesMock->expects($this->once())
+            ->method('hasMessages')->willReturn($hasMessages);
+        $this->errorMessagesMock->expects($this->once())
+            ->method('getMessages')->willReturn($errorMessages);
 
         $this->invoiceOrder->execute(
             $orderId,
@@ -374,16 +386,25 @@ class InvoiceOrderTest extends \PHPUnit_Framework_TestCase
                 $this->invoiceCreationArgumentsMock
             )->willReturn($this->invoiceMock);
 
-        $this->invoiceValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->invoiceMock)
-            ->willReturn([]);
-        $this->orderValidatorMock->expects($this->once())
+        $this->invoiceOrderValidatorMock->expects($this->once())
             ->method('validate')
-            ->with($this->orderMock)
-            ->willReturn([]);
-        $e = new \Exception();
+            ->with(
+                $this->orderMock,
+                $this->invoiceMock,
+                $capture,
+                $items,
+                $notify,
+                $appendComment,
+                $this->invoiceCommentCreationMock,
+                $this->invoiceCreationArgumentsMock
+            )
+            ->willReturn($this->errorMessagesMock);
 
+        $hasMessages = false;
+        $this->errorMessagesMock->expects($this->once())
+            ->method('hasMessages')->willReturn($hasMessages);
+
+        $e = new \Exception();
         $this->paymentAdapterMock->expects($this->once())
             ->method('pay')
             ->with($this->orderMock, $this->invoiceMock, $capture)
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Invoice/Plugin/AddressUpdateTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Invoice/Plugin/AddressUpdateTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..949ec38076db67f190eda22f626385282af922db
--- /dev/null
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Invoice/Plugin/AddressUpdateTest.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Sales\Test\Unit\Model\Order\Invoice\Plugin;
+
+class AddressUpdateTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Sales\Model\Order\Invoice\Plugin\AddressUpdate
+     */
+    private $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $gripPoolMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $attributeMock;
+
+    protected function setUp()
+    {
+        $this->gripPoolMock = $this->getMock(\Magento\Sales\Model\ResourceModel\GridPool::class, [], [], '', false);
+        $this->attributeMock = $this->getMock(\Magento\Sales\Model\ResourceModel\Attribute::class, [], [], '', false);
+        $this->model = new \Magento\Sales\Model\Order\Invoice\Plugin\AddressUpdate(
+            $this->gripPoolMock,
+            $this->attributeMock
+        );
+    }
+
+    public function testAfterProcess()
+    {
+        $billingId = 100;
+        $shippingId = 200;
+        $orderId = 50;
+
+        $orderMock = $this->getMock(
+            \Magento\Sales\Model\Order::class,
+            ['hasInvoices', 'getBillingAddress', 'getShippingAddress', 'getInvoiceCollection', 'getId'],
+            [],
+            '',
+            false
+        );
+
+        $shippingMock = $this->getMock(\Magento\Sales\Model\Order\Address::class, [], [], '', false);
+        $shippingMock->expects($this->once())->method('getId')->willReturn($shippingId);
+
+        $billingMock = $this->getMock(\Magento\Sales\Model\Order\Address::class, [], [], '', false);
+        $billingMock->expects($this->once())->method('getId')->willReturn($billingId);
+
+        $invoiceCollectionMock = $this->getMock(
+            \Magento\Sales\Model\ResourceModel\Order\Invoice\Collection::class,
+            [],
+            [],
+            '',
+            false
+        );
+        $invoiceMock = $this->getMock(\Magento\Sales\Model\Order\Invoice::class, [], [], '', false);
+        $invoiceCollectionMock->expects($this->once())->method('getItems')->willReturn([$invoiceMock]);
+
+        $orderMock->expects($this->once())->method('hasInvoices')->willReturn(true);
+        $orderMock->expects($this->once())->method('getBillingAddress')->willReturn($billingMock);
+        $orderMock->expects($this->once())->method('getShippingAddress')->willReturn($shippingMock);
+        $orderMock->expects($this->once())->method('getInvoiceCollection')->willReturn($invoiceCollectionMock);
+        $orderMock->expects($this->once())->method('getId')->willReturn($orderId);
+
+        $invoiceMock->expects($this->once())->method('getBillingAddressId')->willReturn(null);
+        $invoiceMock->expects($this->once())->method('getShippingAddressId')->willReturn(null);
+        $invoiceMock->expects($this->once())->method('setShippingAddressId')->with($shippingId)->willReturnSelf();
+        $invoiceMock->expects($this->once())->method('setBillingAddressId')->with($billingId)->willReturnSelf();
+
+        $this->attributeMock->expects($this->once())
+            ->method('saveAttribute')
+            ->with($invoiceMock, ['billing_address_id', 'shipping_address_id'])
+            ->willReturnSelf();
+
+        $this->gripPoolMock->expects($this->once())->method('refreshByOrderId')->with($orderId)->willReturnSelf();
+
+        $this->model->afterProcess(
+            $this->getMock(\Magento\Sales\Model\ResourceModel\Order\Handler\Address::class, [], [], '', false),
+            $this->getMock(\Magento\Sales\Model\ResourceModel\Order\Handler\Address::class, [], [], '', false),
+            $orderMock
+        );
+    }
+}
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/PaymentTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/PaymentTest.php
index 07db0e445b8aae3eae6ed0a1e6688ec8eceb44ca..f97e3be1dcb6dcb9ea6383efec081517751325b5 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/PaymentTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/PaymentTest.php
@@ -19,8 +19,16 @@ class PaymentTest extends \PHPUnit_Framework_TestCase
 {
     const TRANSACTION_ID = 'ewr34fM49V0';
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
     private $mockContext;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $orderStateResolverMock;
+
     /**
      * @var Payment
      */
@@ -59,6 +67,9 @@ class PaymentTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Sales\Model\Order\Invoice | \PHPUnit_Framework_MockObject_MockObject $orderMock */
     private $invoiceMock;
 
+    /**
+     * @var string
+     */
     private $transactionId;
 
     /**
@@ -271,14 +282,19 @@ class PaymentTest extends \PHPUnit_Framework_TestCase
                 'getGrandTotal',
                 'getBaseGrandTotal',
                 'getDoTransaction',
-                'getInvoice'
+                'getInvoice',
+                'getOrder'
             ],
             [],
             '',
             false
         );
-
+        $this->orderStateResolverMock = $this->getMockBuilder(Order\OrderStateResolverInterface::class)
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
         $this->payment = $this->initPayment();
+        $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $helper->setBackwardCompatibleProperty($this->payment, 'orderStateResolver', $this->orderStateResolverMock);
         $this->payment->setMethod('any');
         $this->payment->setOrder($this->orderMock);
         $this->transactionId = self::TRANSACTION_ID;
@@ -1465,6 +1481,9 @@ class PaymentTest extends \PHPUnit_Framework_TestCase
         $this->creditMemoMock->expects(static::once())
             ->method('getInvoice')
             ->willReturn($this->invoiceMock);
+        $this->creditMemoMock->expects(static::once())
+            ->method('getOrder')
+            ->willReturn($this->orderMock);
 
         $captureTranId = self::TRANSACTION_ID . '-' . Transaction::TYPE_CAPTURE;
         $captureTransaction = $this->getMockBuilder(Transaction::class)
@@ -1499,7 +1518,10 @@ class PaymentTest extends \PHPUnit_Framework_TestCase
 
         $status = 'status';
         $message = 'We refunded ' . $amount . ' online. Transaction ID: "' . $refundTranId . '"';
-        $this->mockGetDefaultStatus(Order::STATE_PROCESSING, $status);
+        $this->orderStateResolverMock->expects($this->once())->method('getStateForOrder')
+            ->with($this->orderMock)
+            ->willReturn(Order::STATE_CLOSED);
+        $this->mockGetDefaultStatus(Order::STATE_CLOSED, $status);
         $this->assertOrderUpdated(Order::STATE_PROCESSING, $status, $message);
 
         static::assertSame($this->payment, $this->payment->refund($this->creditMemoMock));
diff --git a/app/code/Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php b/app/code/Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php
index 5535ac85095c57e40420e47fa427e0205ebc6aff..f6bc3459c0cc354dd10a945613be75dcefed999d 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/OrderRepositoryTest.php
@@ -110,4 +110,40 @@ class OrderRepositoryTest extends \PHPUnit_Framework_TestCase
 
         $this->assertEquals($collectionMock, $this->model->getList($searchCriteriaMock));
     }
+
+    public function testSave()
+    {
+        $mapperMock = $this->getMockBuilder(\Magento\Sales\Model\ResourceModel\Order::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $orderEntity = $this->getMock(\Magento\Sales\Model\Order::class, [], [], '', false);
+        $extensionAttributes = $this->getMock(
+            \Magento\Sales\Api\Data\OrderExtension::class,
+            ['getShippingAssignments'],
+            [],
+            '',
+            false
+        );
+        $shippingAssignment = $this->getMockBuilder(\Magento\Sales\Model\Order\ShippingAssignment::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getShipping'])
+            ->getMock();
+        $shippingMock = $this->getMockBuilder(\Magento\Sales\Model\Order\Shipping::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getAddress', 'getMethod'])
+            ->getMock();
+        $orderEntity->expects($this->once())->method('getExtensionAttributes')->willReturn($extensionAttributes);
+        $orderEntity->expects($this->once())->method('getIsNotVirtual')->willReturn(true);
+        $extensionAttributes
+            ->expects($this->any())
+            ->method('getShippingAssignments')
+            ->willReturn([$shippingAssignment]);
+        $shippingAssignment->expects($this->once())->method('getShipping')->willReturn($shippingMock);
+        $shippingMock->expects($this->once())->method('getAddress');
+        $shippingMock->expects($this->once())->method('getMethod');
+        $this->metadata->expects($this->once())->method('getMapper')->willReturn($mapperMock);
+        $mapperMock->expects($this->once())->method('save');
+        $orderEntity->expects($this->any())->method('getEntityId')->willReturn(1);
+        $this->model->save($orderEntity);
+    }
 }
diff --git a/app/code/Magento/Sales/Test/Unit/Model/RefundInvoiceTest.php b/app/code/Magento/Sales/Test/Unit/Model/RefundInvoiceTest.php
index 1c4aab6dd2feb1f2ac4d260bc44245633bc17467..d249f039a140b69e0aeebf444aff1f3961f0c0b2 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/RefundInvoiceTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/RefundInvoiceTest.php
@@ -17,15 +17,13 @@ use Magento\Sales\Api\InvoiceRepositoryInterface;
 use Magento\Sales\Api\OrderRepositoryInterface;
 use Magento\Sales\Model\Order;
 use Magento\Sales\Model\Order\Config as OrderConfig;
-use Magento\Sales\Model\Order\Creditmemo\CreditmemoValidatorInterface;
-use Magento\Sales\Model\Order\Creditmemo\ItemCreationValidatorInterface;
 use Magento\Sales\Api\Data\CreditmemoItemCreationInterface;
 use Magento\Sales\Model\Order\CreditmemoDocumentFactory;
-use Magento\Sales\Model\Order\Invoice\InvoiceValidatorInterface;
 use Magento\Sales\Model\Order\OrderStateResolverInterface;
-use Magento\Sales\Model\Order\OrderValidatorInterface;
 use Magento\Sales\Model\Order\PaymentAdapterInterface;
 use Magento\Sales\Model\Order\Creditmemo\NotifierInterface;
+use Magento\Sales\Model\Order\Validation\RefundInvoiceInterface;
+use Magento\Sales\Model\ValidatorResultInterface;
 use Magento\Sales\Model\RefundInvoice;
 use Psr\Log\LoggerInterface;
 
@@ -56,21 +54,6 @@ class RefundInvoiceTest extends \PHPUnit_Framework_TestCase
      */
     private $creditmemoDocumentFactoryMock;
 
-    /**
-     * @var CreditmemoValidatorInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $creditmemoValidatorMock;
-
-    /**
-     * @var OrderValidatorInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $orderValidatorMock;
-
-    /**
-     * @var InvoiceValidatorInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $invoiceValidatorMock;
-
     /**
      * @var PaymentAdapterInterface|\PHPUnit_Framework_MockObject_MockObject
      */
@@ -137,9 +120,14 @@ class RefundInvoiceTest extends \PHPUnit_Framework_TestCase
     private $creditmemoItemCreationMock;
 
     /**
-     * @var ItemCreationValidatorInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var RefundInvoiceInterface|\PHPUnit_Framework_MockObject_MockObject
      */
-    private $itemCreationValidatorMock;
+    private $refundInvoiceValidatorMock;
+
+    /**
+     * @var ValidatorResultInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $validationMessagesMock;
 
     /**
      * @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
@@ -160,24 +148,15 @@ class RefundInvoiceTest extends \PHPUnit_Framework_TestCase
         $this->creditmemoDocumentFactoryMock = $this->getMockBuilder(CreditmemoDocumentFactory::class)
             ->disableOriginalConstructor()
             ->getMock();
-        $this->creditmemoValidatorMock = $this->getMockBuilder(CreditmemoValidatorInterface::class)
-            ->disableOriginalConstructor()
-            ->getMock();
-        $this->orderValidatorMock = $this->getMockBuilder(OrderValidatorInterface::class)
-            ->disableOriginalConstructor()
-            ->getMock();
-        $this->invoiceValidatorMock = $this->getMockBuilder(InvoiceValidatorInterface::class)
+        $this->paymentAdapterMock = $this->getMockBuilder(PaymentAdapterInterface::class)
             ->disableOriginalConstructor()
             ->getMock();
-        
-        $this->paymentAdapterMock = $this->getMockBuilder(PaymentAdapterInterface::class)
+        $this->refundInvoiceValidatorMock = $this->getMockBuilder(RefundInvoiceInterface::class)
             ->disableOriginalConstructor()
             ->getMock();
-
         $this->orderStateResolverMock = $this->getMockBuilder(OrderStateResolverInterface::class)
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
-
         $this->configMock = $this->getMockBuilder(OrderConfig::class)
             ->disableOriginalConstructor()
             ->getMock();
@@ -221,20 +200,17 @@ class RefundInvoiceTest extends \PHPUnit_Framework_TestCase
         $this->creditmemoItemCreationMock = $this->getMockBuilder(CreditmemoItemCreationInterface::class)
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
-
-        $this->itemCreationValidatorMock = $this->getMockBuilder(ItemCreationValidatorInterface::class)
+        $this->validationMessagesMock = $this->getMockBuilder(ValidatorResultInterface::class)
             ->disableOriginalConstructor()
-            ->getMockForAbstractClass();
+            ->setMethods(['hasMessages', 'getMessages', 'addMessage'])
+            ->getMock();
 
         $this->refundInvoice = new RefundInvoice(
             $this->resourceConnectionMock,
             $this->orderStateResolverMock,
             $this->orderRepositoryMock,
             $this->invoiceRepositoryMock,
-            $this->orderValidatorMock,
-            $this->invoiceValidatorMock,
-            $this->creditmemoValidatorMock,
-            $this->itemCreationValidatorMock,
+            $this->refundInvoiceValidatorMock,
             $this->creditmemoRepositoryMock,
             $this->paymentAdapterMock,
             $this->creditmemoDocumentFactoryMock,
@@ -245,22 +221,27 @@ class RefundInvoiceTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
+     * @param int $invoiceId
+     * @param bool $isOnline
+     * @param array $items
+     * @param bool $notify
+     * @param bool $appendComment
+     * @throws \Magento\Sales\Exception\CouldNotRefundException
+     * @throws \Magento\Sales\Exception\DocumentValidationException
      * @dataProvider dataProvider
      */
-    public function testOrderCreditmemo($invoiceId, $items, $notify, $appendComment)
+    public function testOrderCreditmemo($invoiceId, $isOnline, $items, $notify, $appendComment)
     {
         $this->resourceConnectionMock->expects($this->once())
             ->method('getConnection')
             ->with('sales')
             ->willReturn($this->adapterInterface);
-
         $this->invoiceRepositoryMock->expects($this->once())
             ->method('get')
             ->willReturn($this->invoiceMock);
         $this->orderRepositoryMock->expects($this->once())
             ->method('get')
             ->willReturn($this->orderMock);
-
         $this->creditmemoDocumentFactoryMock->expects($this->once())
             ->method('createFromInvoice')
             ->with(
@@ -270,23 +251,23 @@ class RefundInvoiceTest extends \PHPUnit_Framework_TestCase
                 ($appendComment && $notify),
                 $this->creditmemoCreationArgumentsMock
             )->willReturn($this->creditmemoMock);
-
-        $this->creditmemoValidatorMock->expects($this->once())
+        $this->refundInvoiceValidatorMock->expects($this->once())
             ->method('validate')
-            ->with($this->creditmemoMock)
-            ->willReturn([]);
-        $this->orderValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->orderMock)
-            ->willReturn([]);
-        $this->invoiceValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->invoiceMock)
-            ->willReturn([]);
-        $this->itemCreationValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->creditmemoItemCreationMock)
-            ->willReturn([]);
+            ->with(
+                $this->invoiceMock,
+                $this->orderMock,
+                $this->creditmemoMock,
+                $items,
+                $isOnline,
+                $notify,
+                $appendComment,
+                $this->creditmemoCommentCreationMock,
+                $this->creditmemoCreationArgumentsMock
+            )
+            ->willReturn($this->validationMessagesMock);
+        $hasMessages = false;
+        $this->validationMessagesMock->expects($this->once())
+            ->method('hasMessages')->willReturn($hasMessages);
         $this->paymentAdapterMock->expects($this->once())
             ->method('refund')
             ->with($this->creditmemoMock, $this->orderMock)
@@ -314,7 +295,6 @@ class RefundInvoiceTest extends \PHPUnit_Framework_TestCase
             ->method('setState')
             ->with(\Magento\Sales\Model\Order\Creditmemo::STATE_REFUNDED)
             ->willReturnSelf();
-
         $this->creditmemoRepositoryMock->expects($this->once())
             ->method('save')
             ->with($this->creditmemoMock)
@@ -337,7 +317,7 @@ class RefundInvoiceTest extends \PHPUnit_Framework_TestCase
             $this->refundInvoice->execute(
                 $invoiceId,
                 $items,
-                false,
+                true,
                 $notify,
                 $appendComment,
                 $this->creditmemoCommentCreationMock,
@@ -355,6 +335,7 @@ class RefundInvoiceTest extends \PHPUnit_Framework_TestCase
         $items = [1 => $this->creditmemoItemCreationMock];
         $notify = true;
         $appendComment = true;
+        $isOnline = false;
         $errorMessages = ['error1', 'error2'];
 
         $this->invoiceRepositoryMock->expects($this->once())
@@ -374,22 +355,25 @@ class RefundInvoiceTest extends \PHPUnit_Framework_TestCase
                 $this->creditmemoCreationArgumentsMock
             )->willReturn($this->creditmemoMock);
 
-        $this->creditmemoValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->creditmemoMock)
-            ->willReturn($errorMessages);
-        $this->orderValidatorMock->expects($this->once())
+        $this->refundInvoiceValidatorMock->expects($this->once())
             ->method('validate')
-            ->with($this->orderMock)
-            ->willReturn([]);
-        $this->invoiceValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->invoiceMock)
-            ->willReturn([]);
-        $this->itemCreationValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->creditmemoItemCreationMock)
-            ->willReturn([]);
+            ->with(
+                $this->invoiceMock,
+                $this->orderMock,
+                $this->creditmemoMock,
+                $items,
+                $isOnline,
+                $notify,
+                $appendComment,
+                $this->creditmemoCommentCreationMock,
+                $this->creditmemoCreationArgumentsMock
+            )
+            ->willReturn($this->validationMessagesMock);
+        $hasMessages = true;
+        $this->validationMessagesMock->expects($this->once())
+            ->method('hasMessages')->willReturn($hasMessages);
+        $this->validationMessagesMock->expects($this->once())
+            ->method('getMessages')->willReturn($errorMessages);
 
         $this->assertEquals(
             $errorMessages,
@@ -414,6 +398,7 @@ class RefundInvoiceTest extends \PHPUnit_Framework_TestCase
         $items = [1 => $this->creditmemoItemCreationMock];
         $notify = true;
         $appendComment = true;
+        $isOnline = false;
         $this->resourceConnectionMock->expects($this->once())
             ->method('getConnection')
             ->with('sales')
@@ -436,22 +421,23 @@ class RefundInvoiceTest extends \PHPUnit_Framework_TestCase
                 $this->creditmemoCreationArgumentsMock
             )->willReturn($this->creditmemoMock);
 
-        $this->creditmemoValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->creditmemoMock)
-            ->willReturn([]);
-        $this->orderValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->orderMock)
-            ->willReturn([]);
-        $this->invoiceValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->invoiceMock)
-            ->willReturn([]);
-        $this->itemCreationValidatorMock->expects($this->once())
+        $this->refundInvoiceValidatorMock->expects($this->once())
             ->method('validate')
-            ->with($this->creditmemoItemCreationMock)
-            ->willReturn([]);
+            ->with(
+                $this->invoiceMock,
+                $this->orderMock,
+                $this->creditmemoMock,
+                $items,
+                $isOnline,
+                $notify,
+                $appendComment,
+                $this->creditmemoCommentCreationMock,
+                $this->creditmemoCreationArgumentsMock
+            )
+            ->willReturn($this->validationMessagesMock);
+        $hasMessages = false;
+        $this->validationMessagesMock->expects($this->once())
+            ->method('hasMessages')->willReturn($hasMessages);
         $e = new \Exception();
 
         $this->paymentAdapterMock->expects($this->once())
@@ -484,8 +470,8 @@ class RefundInvoiceTest extends \PHPUnit_Framework_TestCase
             ->getMockForAbstractClass();
 
         return [
-            'TestWithNotifyTrue' => [1, [1 => $creditmemoItemCreationMock], true, true],
-            'TestWithNotifyFalse' => [1, [1 => $creditmemoItemCreationMock], false, true],
+            'TestWithNotifyTrue' => [1, true,  [1 => $creditmemoItemCreationMock], true, true],
+            'TestWithNotifyFalse' => [1, true,  [1 => $creditmemoItemCreationMock], false, true],
         ];
     }
 }
diff --git a/app/code/Magento/Sales/Test/Unit/Model/RefundOrderTest.php b/app/code/Magento/Sales/Test/Unit/Model/RefundOrderTest.php
index 7d684695664ba1d1b63a5b78cf610da019cf39bb..4b61453e3c6a2a9cc996dce60a52714fe0113cc2 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/RefundOrderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/RefundOrderTest.php
@@ -15,14 +15,13 @@ use Magento\Sales\Api\Data\OrderInterface;
 use Magento\Sales\Api\OrderRepositoryInterface;
 use Magento\Sales\Model\Order;
 use Magento\Sales\Model\Order\Config as OrderConfig;
-use Magento\Sales\Model\Order\Creditmemo\CreditmemoValidatorInterface;
-use Magento\Sales\Model\Order\Creditmemo\Item\Validation\CreationQuantityValidator;
 use Magento\Sales\Model\Order\CreditmemoDocumentFactory;
 use Magento\Sales\Model\Order\OrderStateResolverInterface;
-use Magento\Sales\Model\Order\OrderValidatorInterface;
+use Magento\Sales\Model\Order\Validation\RefundOrderInterface;
 use Magento\Sales\Model\Order\PaymentAdapterInterface;
 use Magento\Sales\Model\Order\Creditmemo\NotifierInterface;
 use Magento\Sales\Model\RefundOrder;
+use Magento\Sales\Model\ValidatorResultInterface;
 use Psr\Log\LoggerInterface;
 use Magento\Sales\Api\Data\CreditmemoItemCreationInterface;
 
@@ -48,16 +47,6 @@ class RefundOrderTest extends \PHPUnit_Framework_TestCase
      */
     private $creditmemoDocumentFactoryMock;
 
-    /**
-     * @var CreditmemoValidatorInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $creditmemoValidatorMock;
-
-    /**
-     * @var OrderValidatorInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $orderValidatorMock;
-
     /**
      * @var PaymentAdapterInterface|\PHPUnit_Framework_MockObject_MockObject
      */
@@ -119,15 +108,20 @@ class RefundOrderTest extends \PHPUnit_Framework_TestCase
     private $loggerMock;
 
     /**
-     * @var Order\Creditmemo\ItemCreationValidatorInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var RefundOrderInterface|\PHPUnit_Framework_MockObject_MockObject
      */
-    private $itemCreationValidatorMock;
+    private $refundOrderValidatorMock;
 
     /**
      * @var CreditmemoItemCreationInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     private $creditmemoItemCreationMock;
 
+    /**
+     * @var ValidatorResultInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $validationMessagesMock;
+
     protected function setUp()
     {
         $this->resourceConnectionMock = $this->getMockBuilder(ResourceConnection::class)
@@ -139,10 +133,7 @@ class RefundOrderTest extends \PHPUnit_Framework_TestCase
         $this->creditmemoDocumentFactoryMock = $this->getMockBuilder(CreditmemoDocumentFactory::class)
             ->disableOriginalConstructor()
             ->getMock();
-        $this->creditmemoValidatorMock = $this->getMockBuilder(CreditmemoValidatorInterface::class)
-            ->disableOriginalConstructor()
-            ->getMock();
-        $this->orderValidatorMock = $this->getMockBuilder(OrderValidatorInterface::class)
+        $this->refundOrderValidatorMock = $this->getMockBuilder(RefundOrderInterface::class)
             ->disableOriginalConstructor()
             ->getMock();
         $this->paymentAdapterMock = $this->getMockBuilder(PaymentAdapterInterface::class)
@@ -178,23 +169,22 @@ class RefundOrderTest extends \PHPUnit_Framework_TestCase
         $this->adapterInterface = $this->getMockBuilder(AdapterInterface::class)
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
-        $this->itemCreationValidatorMock = $this->getMockBuilder(Order\Creditmemo\ItemCreationValidatorInterface::class)
-            ->disableOriginalConstructor()
-            ->getMockForAbstractClass();
         $this->creditmemoItemCreationMock = $this->getMockBuilder(CreditmemoItemCreationInterface::class)
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
+        $this->validationMessagesMock = $this->getMockBuilder(ValidatorResultInterface::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['hasMessages', 'getMessages', 'addMessage'])
+            ->getMock();
 
         $this->refundOrder = new RefundOrder(
             $this->resourceConnectionMock,
             $this->orderStateResolverMock,
             $this->orderRepositoryMock,
-            $this->orderValidatorMock,
-            $this->creditmemoValidatorMock,
-            $this->itemCreationValidatorMock,
             $this->creditmemoRepositoryMock,
             $this->paymentAdapterMock,
             $this->creditmemoDocumentFactoryMock,
+            $this->refundOrderValidatorMock,
             $this->notifierMock,
             $this->configMock,
             $this->loggerMock
@@ -202,6 +192,11 @@ class RefundOrderTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
+     * @param int $orderId
+     * @param bool $notify
+     * @param bool $appendComment
+     * @throws \Magento\Sales\Exception\CouldNotRefundException
+     * @throws \Magento\Sales\Exception\DocumentValidationException
      * @dataProvider dataProvider
      */
     public function testOrderCreditmemo($orderId, $notify, $appendComment)
@@ -223,21 +218,21 @@ class RefundOrderTest extends \PHPUnit_Framework_TestCase
                 ($appendComment && $notify),
                 $this->creditmemoCreationArgumentsMock
             )->willReturn($this->creditmemoMock);
-        $this->creditmemoValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->creditmemoMock)
-            ->willReturn([]);
-        $this->orderValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->orderMock)
-            ->willReturn([]);
-        $this->itemCreationValidatorMock->expects($this->once())
+        $this->refundOrderValidatorMock->expects($this->once())
             ->method('validate')
             ->with(
-                reset($items),
-                [CreationQuantityValidator::class],
-                $this->orderMock
-            )->willReturn([]);
+                $this->orderMock,
+                $this->creditmemoMock,
+                $items,
+                $notify,
+                $appendComment,
+                $this->creditmemoCommentCreationMock,
+                $this->creditmemoCreationArgumentsMock
+            )
+            ->willReturn($this->validationMessagesMock);
+        $hasMessages = false;
+        $this->validationMessagesMock->expects($this->once())
+            ->method('hasMessages')->willReturn($hasMessages);
         $this->paymentAdapterMock->expects($this->once())
             ->method('refund')
             ->with($this->creditmemoMock, $this->orderMock)
@@ -246,47 +241,38 @@ class RefundOrderTest extends \PHPUnit_Framework_TestCase
             ->method('getStateForOrder')
             ->with($this->orderMock, [])
             ->willReturn(Order::STATE_CLOSED);
-
         $this->orderMock->expects($this->once())
             ->method('setState')
             ->with(Order::STATE_CLOSED)
             ->willReturnSelf();
-
         $this->orderMock->expects($this->once())
             ->method('getState')
             ->willReturn(Order::STATE_CLOSED);
-
         $this->configMock->expects($this->once())
             ->method('getStateDefaultStatus')
             ->with(Order::STATE_CLOSED)
             ->willReturn('Closed');
-
         $this->orderMock->expects($this->once())
             ->method('setStatus')
             ->with('Closed')
             ->willReturnSelf();
-
         $this->creditmemoMock->expects($this->once())
             ->method('setState')
             ->with(\Magento\Sales\Model\Order\Creditmemo::STATE_REFUNDED)
             ->willReturnSelf();
-
         $this->creditmemoRepositoryMock->expects($this->once())
             ->method('save')
             ->with($this->creditmemoMock)
             ->willReturn($this->creditmemoMock);
-
         $this->orderRepositoryMock->expects($this->once())
             ->method('save')
             ->with($this->orderMock)
             ->willReturn($this->orderMock);
-
         if ($notify) {
             $this->notifierMock->expects($this->once())
                 ->method('notify')
                 ->with($this->orderMock, $this->creditmemoMock, $this->creditmemoCommentCreationMock);
         }
-
         $this->creditmemoMock->expects($this->once())
             ->method('getEntityId')
             ->willReturn(2);
@@ -329,18 +315,23 @@ class RefundOrderTest extends \PHPUnit_Framework_TestCase
                 $this->creditmemoCreationArgumentsMock
             )->willReturn($this->creditmemoMock);
 
-        $this->creditmemoValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->creditmemoMock)
-            ->willReturn($errorMessages);
-        $this->orderValidatorMock->expects($this->once())
+        $this->refundOrderValidatorMock->expects($this->once())
             ->method('validate')
-            ->with($this->orderMock)
-            ->willReturn([]);
-        $this->itemCreationValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with(reset($items), [CreationQuantityValidator::class], $this->orderMock)
-            ->willReturn([]);
+            ->with(
+                $this->orderMock,
+                $this->creditmemoMock,
+                $items,
+                $notify,
+                $appendComment,
+                $this->creditmemoCommentCreationMock,
+                $this->creditmemoCreationArgumentsMock
+            )
+            ->willReturn($this->validationMessagesMock);
+        $hasMessages = true;
+        $this->validationMessagesMock->expects($this->once())
+            ->method('hasMessages')->willReturn($hasMessages);
+        $this->validationMessagesMock->expects($this->once())
+            ->method('getMessages')->willReturn($errorMessages);
 
         $this->assertEquals(
             $errorMessages,
@@ -380,18 +371,21 @@ class RefundOrderTest extends \PHPUnit_Framework_TestCase
                 ($appendComment && $notify),
                 $this->creditmemoCreationArgumentsMock
             )->willReturn($this->creditmemoMock);
-        $this->itemCreationValidatorMock->expects($this->once())
+        $this->refundOrderValidatorMock->expects($this->once())
             ->method('validate')
-            ->with(reset($items), [CreationQuantityValidator::class], $this->orderMock)
-            ->willReturn([]);
-        $this->creditmemoValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->creditmemoMock)
-            ->willReturn([]);
-        $this->orderValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->orderMock)
-            ->willReturn([]);
+            ->with(
+                $this->orderMock,
+                $this->creditmemoMock,
+                $items,
+                $notify,
+                $appendComment,
+                $this->creditmemoCommentCreationMock,
+                $this->creditmemoCreationArgumentsMock
+            )
+            ->willReturn($this->validationMessagesMock);
+        $hasMessages = false;
+        $this->validationMessagesMock->expects($this->once())
+            ->method('hasMessages')->willReturn($hasMessages);
         $e = new \Exception();
         $this->paymentAdapterMock->expects($this->once())
             ->method('refund')
diff --git a/app/code/Magento/Sales/Test/Unit/Model/ShipOrderTest.php b/app/code/Magento/Sales/Test/Unit/Model/ShipOrderTest.php
index b719babf209f0ceb98c4d019f1e5929b23e7e11f..1daf7a64263b817654bf73ee2155506ea9a5f42d 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/ShipOrderTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/ShipOrderTest.php
@@ -18,11 +18,11 @@ use Magento\Sales\Api\ShipmentRepositoryInterface;
 use Magento\Sales\Model\Order;
 use Magento\Sales\Model\Order\Config as OrderConfig;
 use Magento\Sales\Model\Order\OrderStateResolverInterface;
-use Magento\Sales\Model\Order\OrderValidatorInterface;
 use Magento\Sales\Model\Order\ShipmentDocumentFactory;
 use Magento\Sales\Model\Order\Shipment\NotifierInterface;
 use Magento\Sales\Model\Order\Shipment\OrderRegistrarInterface;
-use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface;
+use Magento\Sales\Model\Order\Validation\ShipOrderInterface;
+use Magento\Sales\Model\ValidatorResultInterface;
 use Magento\Sales\Model\ShipOrder;
 use Psr\Log\LoggerInterface;
 
@@ -49,14 +49,9 @@ class ShipOrderTest extends \PHPUnit_Framework_TestCase
     private $shipmentDocumentFactoryMock;
 
     /**
-     * @var ShipmentValidatorInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var ShipOrderInterface|\PHPUnit_Framework_MockObject_MockObject
      */
-    private $shipmentValidatorMock;
-
-    /**
-     * @var OrderValidatorInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $orderValidatorMock;
+    private $shipOrderValidatorMock;
 
     /**
      * @var OrderRegistrarInterface|\PHPUnit_Framework_MockObject_MockObject
@@ -109,20 +104,25 @@ class ShipOrderTest extends \PHPUnit_Framework_TestCase
     private $shipmentMock;
 
     /**
-     * @var AdapterInterface
+     * @var AdapterInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     private $adapterMock;
 
     /**
-     * @var ShipmentTrackCreationInterface
+     * @var ShipmentTrackCreationInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     private $trackMock;
 
     /**
-     * @var ShipmentPackageInterface
+     * @var ShipmentPackageInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     private $packageMock;
 
+    /**
+     * @var ValidatorResultInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $validationMessagesMock;
+
     /**
      * @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
@@ -133,75 +133,58 @@ class ShipOrderTest extends \PHPUnit_Framework_TestCase
         $this->resourceConnectionMock = $this->getMockBuilder(ResourceConnection::class)
             ->disableOriginalConstructor()
             ->getMock();
-
         $this->orderRepositoryMock = $this->getMockBuilder(OrderRepositoryInterface::class)
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
-
         $this->shipmentDocumentFactoryMock = $this->getMockBuilder(ShipmentDocumentFactory::class)
             ->disableOriginalConstructor()
             ->getMock();
-
-        $this->shipmentValidatorMock = $this->getMockBuilder(ShipmentValidatorInterface::class)
-            ->disableOriginalConstructor()
-            ->getMockForAbstractClass();
-
-        $this->orderValidatorMock = $this->getMockBuilder(OrderValidatorInterface::class)
-            ->disableOriginalConstructor()
-            ->getMockForAbstractClass();
-
         $this->orderRegistrarMock = $this->getMockBuilder(OrderRegistrarInterface::class)
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
-
         $this->orderStateResolverMock = $this->getMockBuilder(OrderStateResolverInterface::class)
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
-
         $this->configMock = $this->getMockBuilder(OrderConfig::class)
             ->disableOriginalConstructor()
             ->getMock();
-
         $this->shipmentRepositoryMock = $this->getMockBuilder(ShipmentRepositoryInterface::class)
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
-
         $this->notifierInterfaceMock = $this->getMockBuilder(NotifierInterface::class)
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
-
         $this->loggerMock = $this->getMockBuilder(LoggerInterface::class)
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
-
         $this->shipmentCommentCreationMock = $this->getMockBuilder(ShipmentCommentCreationInterface::class)
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
-
         $this->shipmentCreationArgumentsMock = $this->getMockBuilder(ShipmentCreationArgumentsInterface::class)
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
-
         $this->orderMock = $this->getMockBuilder(OrderInterface::class)
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
-
         $this->shipmentMock = $this->getMockBuilder(ShipmentInterface::class)
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
-
         $this->packageMock = $this->getMockBuilder(ShipmentPackageInterface::class)
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
-
         $this->trackMock = $this->getMockBuilder(ShipmentTrackCreationInterface::class)
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
-
         $this->adapterMock = $this->getMockBuilder(AdapterInterface::class)
             ->disableOriginalConstructor()
             ->getMockForAbstractClass();
-
+        $this->shipOrderValidatorMock = $this->getMockBuilder(ShipOrderInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->validationMessagesMock = $this->getMockBuilder(ValidatorResultInterface::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['hasMessages', 'getMessages', 'addMessage'])
+            ->getMock();
         $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
 
         $this->model = $helper->getObject(
@@ -209,20 +192,25 @@ class ShipOrderTest extends \PHPUnit_Framework_TestCase
             [
                 'resourceConnection' => $this->resourceConnectionMock,
                 'orderRepository' => $this->orderRepositoryMock,
-                'shipmentRepository' => $this->shipmentRepositoryMock,
                 'shipmentDocumentFactory' => $this->shipmentDocumentFactoryMock,
-                'shipmentValidator' => $this->shipmentValidatorMock,
-                'orderValidator' => $this->orderValidatorMock,
                 'orderStateResolver' => $this->orderStateResolverMock,
-                'orderRegistrar' => $this->orderRegistrarMock,
-                'notifierInterface' => $this->notifierInterfaceMock,
                 'config' => $this->configMock,
-                'logger' => $this->loggerMock
+                'shipmentRepository' => $this->shipmentRepositoryMock,
+                'shipOrderValidator' => $this->shipOrderValidatorMock,
+                'notifierInterface' => $this->notifierInterfaceMock,
+                'logger' => $this->loggerMock,
+                'orderRegistrar' => $this->orderRegistrarMock
             ]
         );
     }
 
     /**
+     * @param int $orderId
+     * @param array $items
+     * @param bool $notify
+     * @param bool $appendComment
+     * @throws \Magento\Sales\Exception\CouldNotShipException
+     * @throws \Magento\Sales\Exception\DocumentValidationException
      * @dataProvider dataProvider
      */
     public function testExecute($orderId, $items, $notify, $appendComment)
@@ -231,11 +219,9 @@ class ShipOrderTest extends \PHPUnit_Framework_TestCase
             ->method('getConnection')
             ->with('sales')
             ->willReturn($this->adapterMock);
-
         $this->orderRepositoryMock->expects($this->once())
             ->method('get')
             ->willReturn($this->orderMock);
-
         $this->shipmentDocumentFactoryMock->expects($this->once())
             ->method('create')
             ->with(
@@ -247,65 +233,61 @@ class ShipOrderTest extends \PHPUnit_Framework_TestCase
                 [$this->packageMock],
                 $this->shipmentCreationArgumentsMock
             )->willReturn($this->shipmentMock);
-
-        $this->shipmentValidatorMock->expects($this->once())
+        $this->shipOrderValidatorMock->expects($this->once())
             ->method('validate')
-            ->with($this->shipmentMock)
-            ->willReturn([]);
-        $this->orderValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->orderMock)
-            ->willReturn([]);
-
+            ->with(
+                $this->orderMock,
+                $this->shipmentMock,
+                $items,
+                $notify,
+                $appendComment,
+                $this->shipmentCommentCreationMock,
+                [$this->trackMock],
+                [$this->packageMock]
+            )
+            ->willReturn($this->validationMessagesMock);
+        $hasMessages = false;
+        $this->validationMessagesMock->expects($this->once())
+            ->method('hasMessages')->willReturn($hasMessages);
         $this->orderRegistrarMock->expects($this->once())
             ->method('register')
             ->with($this->orderMock, $this->shipmentMock)
             ->willReturn($this->orderMock);
-
         $this->orderStateResolverMock->expects($this->once())
             ->method('getStateForOrder')
             ->with($this->orderMock, [OrderStateResolverInterface::IN_PROGRESS])
             ->willReturn(Order::STATE_PROCESSING);
-
         $this->orderMock->expects($this->once())
             ->method('setState')
             ->with(Order::STATE_PROCESSING)
             ->willReturnSelf();
-
         $this->orderMock->expects($this->once())
             ->method('getState')
             ->willReturn(Order::STATE_PROCESSING);
-
         $this->configMock->expects($this->once())
             ->method('getStateDefaultStatus')
             ->with(Order::STATE_PROCESSING)
             ->willReturn('Processing');
-
         $this->orderMock->expects($this->once())
             ->method('setStatus')
             ->with('Processing')
             ->willReturnSelf();
-
         $this->shipmentRepositoryMock->expects($this->once())
             ->method('save')
             ->with($this->shipmentMock)
             ->willReturn($this->shipmentMock);
-
         $this->orderRepositoryMock->expects($this->once())
             ->method('save')
             ->with($this->orderMock)
             ->willReturn($this->orderMock);
-
         if ($notify) {
             $this->notifierInterfaceMock->expects($this->once())
                 ->method('notify')
                 ->with($this->orderMock, $this->shipmentMock, $this->shipmentCommentCreationMock);
         }
-
         $this->shipmentMock->expects($this->once())
             ->method('getEntityId')
             ->willReturn(2);
-
         $this->assertEquals(
             2,
             $this->model->execute(
@@ -348,14 +330,24 @@ class ShipOrderTest extends \PHPUnit_Framework_TestCase
                 $this->shipmentCreationArgumentsMock
             )->willReturn($this->shipmentMock);
 
-        $this->shipmentValidatorMock->expects($this->once())
+        $this->shipOrderValidatorMock->expects($this->once())
             ->method('validate')
-            ->with($this->shipmentMock)
-            ->willReturn($errorMessages);
-        $this->orderValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->orderMock)
-            ->willReturn([]);
+            ->with(
+                $this->orderMock,
+                $this->shipmentMock,
+                $items,
+                $notify,
+                $appendComment,
+                $this->shipmentCommentCreationMock,
+                [$this->trackMock],
+                [$this->packageMock]
+            )
+            ->willReturn($this->validationMessagesMock);
+        $hasMessages = true;
+        $this->validationMessagesMock->expects($this->once())
+            ->method('hasMessages')->willReturn($hasMessages);
+        $this->validationMessagesMock->expects($this->once())
+            ->method('getMessages')->willReturn($errorMessages);
 
         $this->model->execute(
             $orderId,
@@ -372,9 +364,12 @@ class ShipOrderTest extends \PHPUnit_Framework_TestCase
     /**
      * @expectedException \Magento\Sales\Api\Exception\CouldNotShipExceptionInterface
      */
-    public function testCouldNotInvoiceException()
+    public function testCouldNotShipException()
     {
         $orderId = 1;
+        $items = [1 => 2];
+        $notify = true;
+        $appendComment = true;
         $this->resourceConnectionMock->expects($this->once())
             ->method('getConnection')
             ->with('sales')
@@ -387,33 +382,53 @@ class ShipOrderTest extends \PHPUnit_Framework_TestCase
         $this->shipmentDocumentFactoryMock->expects($this->once())
             ->method('create')
             ->with(
-                $this->orderMock
+                $this->orderMock,
+                $items,
+                [$this->trackMock],
+                $this->shipmentCommentCreationMock,
+                ($appendComment && $notify),
+                [$this->packageMock],
+                $this->shipmentCreationArgumentsMock
             )->willReturn($this->shipmentMock);
-
-        $this->shipmentValidatorMock->expects($this->once())
+        $this->shipOrderValidatorMock->expects($this->once())
             ->method('validate')
-            ->with($this->shipmentMock)
-            ->willReturn([]);
-        $this->orderValidatorMock->expects($this->once())
-            ->method('validate')
-            ->with($this->orderMock)
-            ->willReturn([]);
-        $e = new \Exception();
+            ->with(
+                $this->orderMock,
+                $this->shipmentMock,
+                $items,
+                $notify,
+                $appendComment,
+                $this->shipmentCommentCreationMock,
+                [$this->trackMock],
+                [$this->packageMock]
+            )
+            ->willReturn($this->validationMessagesMock);
+        $hasMessages = false;
+        $this->validationMessagesMock->expects($this->once())
+            ->method('hasMessages')->willReturn($hasMessages);
+        $exception = new \Exception();
 
         $this->orderRegistrarMock->expects($this->once())
             ->method('register')
             ->with($this->orderMock, $this->shipmentMock)
-            ->willThrowException($e);
+            ->willThrowException($exception);
 
         $this->loggerMock->expects($this->once())
             ->method('critical')
-            ->with($e);
+            ->with($exception);
 
         $this->adapterMock->expects($this->once())
             ->method('rollBack');
 
         $this->model->execute(
-            $orderId
+            $orderId,
+            $items,
+            $notify,
+            $appendComment,
+            $this->shipmentCommentCreationMock,
+            [$this->trackMock],
+            [$this->packageMock],
+            $this->shipmentCreationArgumentsMock
         );
     }
 
diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml
index 03437a8e9801324e9346f55a63ffb6c7d5582a31..4e2487d9dcada2eaf224f8cc30f65fc8fa4a4fc8 100644
--- a/app/code/Magento/Sales/etc/di.xml
+++ b/app/code/Magento/Sales/etc/di.xml
@@ -105,6 +105,11 @@
     <preference for="Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface" type="Magento\Sales\Model\Order\Shipment\ShipmentValidator"/>
     <preference for="Magento\Sales\Model\Order\Creditmemo\CreditmemoValidatorInterface" type="Magento\Sales\Model\Order\Creditmemo\CreditmemoValidator"/>
     <preference for="Magento\Sales\Model\Order\Creditmemo\ItemCreationValidatorInterface" type="Magento\Sales\Model\Order\Creditmemo\ItemCreationValidator"/>
+    <preference for="Magento\Sales\Model\ValidatorResultInterface" type="Magento\Sales\Model\ValidatorResult"/>
+    <preference for="Magento\Sales\Model\Order\Validation\InvoiceOrderInterface" type="Magento\Sales\Model\Order\Validation\InvoiceOrder"/>
+    <preference for="Magento\Sales\Model\Order\Validation\RefundInvoiceInterface" type="Magento\Sales\Model\Order\Validation\RefundInvoice"/>
+    <preference for="Magento\Sales\Model\Order\Validation\RefundOrderInterface" type="Magento\Sales\Model\Order\Validation\RefundOrder"/>
+    <preference for="Magento\Sales\Model\Order\Validation\ShipOrderInterface" type="Magento\Sales\Model\Order\Validation\ShipOrder"/>
     <preference for="Magento\Sales\Model\Order\Creditmemo\NotifierInterface" type="Magento\Sales\Model\Order\Creditmemo\Notifier"/>
     <preference for="Magento\Sales\Api\RefundOrderInterface" type="Magento\Sales\Model\RefundOrder"/>
     <preference for="Magento\Sales\Api\RefundInvoiceInterface" type="Magento\Sales\Model\RefundInvoice"/>
@@ -948,4 +953,7 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Sales\Model\ResourceModel\Order\Handler\Address">
+        <plugin name="addressUpdate" type="Magento\Sales\Model\Order\Invoice\Plugin\AddressUpdate"/>
+    </type>
 </config>
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/create/form.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/create/form.phtml
index 4b53e0ccb1e9fefd91ea23c555dc64c7f617ca72..fe212490a2fd00c9e18fc6fea8ab28b01e34e45d 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/create/form.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/create/form.phtml
@@ -8,7 +8,7 @@
 
 /** @var \Magento\Sales\Block\Adminhtml\Order\Create\Form $block */
 ?>
-<form id="edit_form" data-order-config='<?php /* @escapeNotVerified */ echo $block->getOrderDataJson() ?>' data-load-base-url="<?php /* @escapeNotVerified */ echo $block->getLoadBlockUrl() ?>" action="<?php /* @escapeNotVerified */ echo $block->getSaveUrl() ?>" method="post" enctype="multipart/form-data">
+<form id="edit_form" data-order-config='<?php echo $block->escapeHtml($block->getOrderDataJson()) ?>' data-load-base-url="<?php /* @escapeNotVerified */ echo $block->getLoadBlockUrl() ?>" action="<?php /* @escapeNotVerified */ echo $block->getSaveUrl() ?>" method="post" enctype="multipart/form-data">
     <?php echo $block->getBlockHtml('formkey')?>
     <div id="order-message">
         <?php echo $block->getChildHtml('message') ?>
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 e97097aecacc7be9c5b74431034ee04916c7d306..aed235ba4e30622429ec58d49385e5db3638ead1 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
@@ -434,7 +434,7 @@ define([
         },
 
         applyCoupon : function(code){
-            this.loadArea(['items', 'shipping_method', 'totals', 'billing_method'], true, {'order[coupon][code]':code, reset_shipping: true});
+            this.loadArea(['items', 'shipping_method', 'totals', 'billing_method'], true, {'order[coupon][code]':code, reset_shipping: 0});
             this.orderItemChanged = false;
         },
 
diff --git a/app/code/Magento/SalesInventory/LICENSE.txt b/app/code/Magento/SalesInventory/LICENSE.txt
new file mode 100644
index 0000000000000000000000000000000000000000..49525fd99da9c51e6d85420266d41cb3d6b7a648
--- /dev/null
+++ b/app/code/Magento/SalesInventory/LICENSE.txt
@@ -0,0 +1,48 @@
+
+Open Software License ("OSL") v. 3.0
+
+This Open Software License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work:
+
+Licensed under the Open Software License version 3.0
+
+   1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following:
+
+         1. to reproduce the Original Work in copies, either alone or as part of a collective work;
+
+         2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work;
+
+         3. to distribute or communicate copies of the Original Work and Derivative Works to the public, with the proviso that copies of Original Work or Derivative Works that You distribute or communicate shall be licensed under this Open Software License;
+
+         4. to perform the Original Work publicly; and
+
+         5. to display the Original Work publicly. 
+
+   2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works.
+
+   3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work.
+
+   4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license.
+
+   5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c).
+
+   6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work.
+
+   7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer.
+
+   8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation.
+
+   9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including 'fair use' or 'fair dealing'). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c).
+
+  10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware.
+
+  11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License.
+
+  12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License.
+
+  13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable.
+
+  14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+  15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You.
+
+  16. Modification of This License. This License is Copyright (C) 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Open Software License" or "OSL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process.
\ No newline at end of file
diff --git a/app/code/Magento/SalesInventory/LICENSE_AFL.txt b/app/code/Magento/SalesInventory/LICENSE_AFL.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f39d641b18a19e56df6c8a3e4038c940fb886b32
--- /dev/null
+++ b/app/code/Magento/SalesInventory/LICENSE_AFL.txt
@@ -0,0 +1,48 @@
+
+Academic Free License ("AFL") v. 3.0
+
+This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work:
+
+Licensed under the Academic Free License version 3.0
+
+   1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following:
+
+         1. to reproduce the Original Work in copies, either alone or as part of a collective work;
+
+         2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work;
+
+         3. to distribute or communicate copies of the Original Work and Derivative Works to the public, under any license of your choice that does not contradict the terms and conditions, including Licensor's reserved rights and remedies, in this Academic Free License;
+
+         4. to perform the Original Work publicly; and
+
+         5. to display the Original Work publicly.
+
+   2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works.
+
+   3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work.
+
+   4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license.
+
+   5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c).
+
+   6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work.
+
+   7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer.
+
+   8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation.
+
+   9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including "fair use" or "fair dealing"). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c).
+
+  10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware.
+
+  11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License.
+
+  12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License.
+
+  13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable.
+
+  14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+  15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You.
+
+  16. Modification of This License. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Academic Free License" or "AFL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process.
diff --git a/app/code/Magento/SalesInventory/Model/Order/ReturnProcessor.php b/app/code/Magento/SalesInventory/Model/Order/ReturnProcessor.php
new file mode 100644
index 0000000000000000000000000000000000000000..7752d7131031cf0daa63f4c8b8bf49609e3090ed
--- /dev/null
+++ b/app/code/Magento/SalesInventory/Model/Order/ReturnProcessor.php
@@ -0,0 +1,156 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\SalesInventory\Model\Order;
+
+use Magento\Sales\Api\Data\CreditmemoInterface;
+use Magento\Sales\Api\Data\CreditmemoItemInterface;
+use Magento\Sales\Api\Data\OrderInterface;
+
+/**
+ * Class ReturnProcessor
+ */
+class ReturnProcessor
+{
+    /**
+     * @var \Magento\CatalogInventory\Api\StockManagementInterface
+     */
+    private $stockManagement;
+
+    /**
+     * @var \Magento\CatalogInventory\Model\Indexer\Stock\Processor
+     */
+    private $stockIndexerProcessor;
+
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Price\Processor
+     */
+    private $priceIndexer;
+
+    /**
+     * @var \Magento\Sales\Api\CreditmemoRepositoryInterface
+     */
+    private $creditmemoRepository;
+
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface
+     */
+    private $storeManager;
+
+    /**
+     * @var \Magento\Sales\Api\OrderRepositoryInterface
+     */
+    private $orderRepository;
+
+    /**
+     * @var \Magento\Sales\Api\OrderItemRepositoryInterface
+     */
+    private $orderItemRepository;
+
+    /**
+     * ReturnToStockPlugin constructor.
+     * @param \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration
+     * @param \Magento\CatalogInventory\Api\StockManagementInterface $stockManagement
+     * @param \Magento\CatalogInventory\Model\Indexer\Stock\Processor $stockIndexer
+     * @param \Magento\Catalog\Model\Indexer\Product\Price\Processor $priceIndexer
+     * @param \Magento\Sales\Api\CreditmemoRepositoryInterface $creditmemoRepository
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     * @param \Magento\Sales\Api\OrderRepositoryInterface $orderRepository
+     * @param \Magento\Sales\Api\OrderItemRepositoryInterface $orderItemRepository
+     */
+    public function __construct(
+        \Magento\CatalogInventory\Api\StockManagementInterface $stockManagement,
+        \Magento\CatalogInventory\Model\Indexer\Stock\Processor $stockIndexer,
+        \Magento\Catalog\Model\Indexer\Product\Price\Processor $priceIndexer,
+        \Magento\Sales\Api\CreditmemoRepositoryInterface $creditmemoRepository,
+        \Magento\Store\Model\StoreManagerInterface $storeManager,
+        \Magento\Sales\Api\OrderRepositoryInterface $orderRepository,
+        \Magento\Sales\Api\OrderItemRepositoryInterface $orderItemRepository
+    ) {
+        $this->stockManagement = $stockManagement;
+        $this->stockIndexerProcessor = $stockIndexer;
+        $this->priceIndexer = $priceIndexer;
+        $this->creditmemoRepository = $creditmemoRepository;
+        $this->storeManager = $storeManager;
+        $this->orderRepository = $orderRepository;
+        $this->orderItemRepository = $orderItemRepository;
+    }
+
+    /**
+     * @param CreditmemoInterface $creditmemo
+     * @param OrderInterface $order
+     * @param array $returnToStockItems
+     * @return void
+     */
+    public function execute(
+        CreditmemoInterface $creditmemo,
+        OrderInterface $order,
+        array $returnToStockItems = []
+    ) {
+        $itemsToUpdate = [];
+        foreach ($creditmemo->getItems() as $item) {
+            $qty = $item->getQty();
+            $productId = $item->getProductId();
+            $orderItem = $this->orderItemRepository->get($item->getOrderItemId());
+            $parentItemId = $orderItem->getParentItemId();
+            if ($this->canReturnItem($item, $qty, $parentItemId, $returnToStockItems)) {
+                $parentItem = $parentItemId ? $this->getItemByOrderId($creditmemo, $parentItemId) : false;
+                $qty = $parentItem ? $parentItem->getQty() * $qty : $qty;
+                if (isset($itemsToUpdate[$productId])) {
+                    $itemsToUpdate[$productId] += $qty;
+                } else {
+                    $itemsToUpdate[$productId] = $qty;
+                }
+            }
+        }
+
+        if (!empty($itemsToUpdate)) {
+            $store = $this->storeManager->getStore($order->getStoreId());
+            foreach ($itemsToUpdate as $productId => $qty) {
+                $this->stockManagement->backItemQty(
+                    $productId,
+                    $qty,
+                    $store->getWebsiteId()
+                );
+            }
+
+            $updatedItemIds = array_keys($itemsToUpdate);
+            $this->stockIndexerProcessor->reindexList($updatedItemIds);
+            $this->priceIndexer->reindexList($updatedItemIds);
+        }
+    }
+
+    /**
+     * @param \Magento\Sales\Api\Data\CreditmemoInterface $creditmemo
+     * @param int $parentItemId
+     * @return bool|CreditmemoItemInterface
+     */
+    private function getItemByOrderId(\Magento\Sales\Api\Data\CreditmemoInterface $creditmemo, $parentItemId)
+    {
+        foreach ($creditmemo->getItems() as $item) {
+            if ($item->getOrderItemId() == $parentItemId) {
+                return $item;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @param \Magento\Sales\Api\Data\CreditmemoItemInterface $item
+     * @param int $qty
+     * @param int[] $returnToStockItems
+     * @param int $parentItemId
+     * @return bool
+     */
+    private function canReturnItem(
+        \Magento\Sales\Api\Data\CreditmemoItemInterface $item,
+        $qty,
+        $parentItemId = null,
+        array $returnToStockItems = []
+    ) {
+        return (in_array($item->getOrderItemId(), $returnToStockItems) || in_array($parentItemId, $returnToStockItems))
+        && $qty;
+    }
+}
diff --git a/app/code/Magento/SalesInventory/Model/Order/ReturnValidator.php b/app/code/Magento/SalesInventory/Model/Order/ReturnValidator.php
new file mode 100644
index 0000000000000000000000000000000000000000..2195883334fcf6dfa21a55a49797f64a4ec0faa4
--- /dev/null
+++ b/app/code/Magento/SalesInventory/Model/Order/ReturnValidator.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\SalesInventory\Model\Order;
+
+use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Sales\Api\Data\CreditmemoInterface;
+use Magento\Sales\Api\Data\CreditmemoItemInterface;
+use Magento\Sales\Api\Data\OrderItemInterface;
+use Magento\Sales\Api\OrderItemRepositoryInterface;
+
+/**
+ * Class ReturnProcessor
+ */
+class ReturnValidator
+{
+    /**
+     * @var OrderItemRepositoryInterface
+     */
+    private $orderItemRepository;
+
+    /**
+     * ReturnValidator constructor.
+     * @param OrderItemRepositoryInterface $orderItemRepository
+     */
+    public function __construct(OrderItemRepositoryInterface $orderItemRepository)
+    {
+        $this->orderItemRepository = $orderItemRepository;
+    }
+
+    /**
+     * @param int[] $returnToStockItems
+     * @param CreditmemoInterface $creditmemo
+     * @return \Magento\Framework\Phrase|null
+     */
+    public function validate($returnToStockItems, CreditmemoInterface $creditmemo)
+    {
+        $creditmemoItems = $creditmemo->getItems();
+
+        /** @var int $item */
+        foreach ($returnToStockItems as $item) {
+            try {
+                $orderItem = $this->orderItemRepository->get($item);
+                if (!$this->isOrderItemPartOfCreditmemo($creditmemoItems, $orderItem)) {
+                    return __('The "%1" product is not part of the current creditmemo.', $orderItem->getSku());
+                }
+            } catch (NoSuchEntityException $e) {
+                return __('The return to stock argument contains product item that is not part of the original order.');
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @param CreditmemoItemInterface[] $creditmemoItems
+     * @param OrderItemInterface $orderItem
+     * @return bool
+     */
+    private function isOrderItemPartOfCreditmemo(array $creditmemoItems, OrderItemInterface $orderItem)
+    {
+        foreach ($creditmemoItems as $creditmemoItem) {
+            if ($creditmemoItem->getOrderItemId() == $orderItem->getItemId()) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/app/code/Magento/SalesInventory/Model/Plugin/Order/ReturnToStockInvoice.php b/app/code/Magento/SalesInventory/Model/Plugin/Order/ReturnToStockInvoice.php
new file mode 100644
index 0000000000000000000000000000000000000000..53a393d83353b4922f61641160dcf3c2aa8b6d85
--- /dev/null
+++ b/app/code/Magento/SalesInventory/Model/Plugin/Order/ReturnToStockInvoice.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\SalesInventory\Model\Plugin\Order;
+
+/**
+ * Class ReturnToStockInvoice
+ */
+class ReturnToStockInvoice
+{
+    /**
+     * @var \Magento\SalesInventory\Model\Order\ReturnProcessor
+     */
+    private $returnProcessor;
+
+    /**
+     * @var \Magento\Sales\Api\CreditmemoRepositoryInterface
+     */
+    private $creditmemoRepository;
+
+    /**
+     * @var \Magento\Sales\Api\OrderRepositoryInterface
+     */
+    private $orderRepository;
+
+    /**
+     * @var \Magento\Sales\Api\InvoiceRepositoryInterface
+     */
+    private $invoiceRepository;
+
+    /**
+     * @var \Magento\CatalogInventory\Api\StockConfigurationInterface
+     */
+    private $stockConfiguration;
+
+    /**
+     * ReturnToStockInvoice constructor.
+     * @param \Magento\SalesInventory\Model\Order\ReturnProcessor $returnProcessor
+     * @param \Magento\Sales\Api\CreditmemoRepositoryInterface $creditmemoRepository
+     * @param \Magento\Sales\Api\OrderRepositoryInterface $orderRepository
+     * @param \Magento\Sales\Api\InvoiceRepositoryInterface $invoiceRepository
+     * @param \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration
+     */
+    public function __construct(
+        \Magento\SalesInventory\Model\Order\ReturnProcessor $returnProcessor,
+        \Magento\Sales\Api\CreditmemoRepositoryInterface $creditmemoRepository,
+        \Magento\Sales\Api\OrderRepositoryInterface $orderRepository,
+        \Magento\Sales\Api\InvoiceRepositoryInterface $invoiceRepository,
+        \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration
+    ) {
+        $this->returnProcessor = $returnProcessor;
+        $this->creditmemoRepository = $creditmemoRepository;
+        $this->orderRepository = $orderRepository;
+        $this->invoiceRepository = $invoiceRepository;
+        $this->stockConfiguration = $stockConfiguration;
+    }
+
+    /**
+     * @param \Magento\Sales\Api\RefundInvoiceInterface $refundService
+     * @param int $resultEntityId
+     * @param int $invoiceId
+     * @param \Magento\Sales\Api\Data\CreditmemoItemCreationInterface[] $items
+     * @param bool|null $isOnline
+     * @param bool|null $notify
+     * @param bool|null $appendComment
+     * @param \Magento\Sales\Api\Data\CreditmemoCommentCreationInterface|null $comment
+     * @param \Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface|null $arguments
+     * @return int
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function afterExecute(
+        \Magento\Sales\Api\RefundInvoiceInterface $refundService,
+        $resultEntityId,
+        $invoiceId,
+        array $items = [],
+        $isOnline = false,
+        $notify = false,
+        $appendComment = false,
+        \Magento\Sales\Api\Data\CreditmemoCommentCreationInterface $comment = null,
+        \Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface $arguments = null
+    ) {
+        if ($this->stockConfiguration->isAutoReturnEnabled()) {
+            return $resultEntityId;
+        }
+
+        $invoice = $this->invoiceRepository->get($invoiceId);
+        $order = $this->orderRepository->get($invoice->getOrderId());
+
+        $returnToStockItems = [];
+        if ($arguments !== null
+            && $arguments->getExtensionAttributes() !== null
+            && $arguments->getExtensionAttributes()->getReturnToStockItems() !== null
+        ) {
+            $returnToStockItems = $arguments->getExtensionAttributes()->getReturnToStockItems();
+        }
+
+        $creditmemo = $this->creditmemoRepository->get($resultEntityId);
+        $this->returnProcessor->execute($creditmemo, $order, $returnToStockItems);
+
+        return $resultEntityId;
+    }
+}
diff --git a/app/code/Magento/SalesInventory/Model/Plugin/Order/ReturnToStockOrder.php b/app/code/Magento/SalesInventory/Model/Plugin/Order/ReturnToStockOrder.php
new file mode 100644
index 0000000000000000000000000000000000000000..b21f9f6b1050636738a67c88151ceb1780f3b820
--- /dev/null
+++ b/app/code/Magento/SalesInventory/Model/Plugin/Order/ReturnToStockOrder.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\SalesInventory\Model\Plugin\Order;
+
+use Magento\CatalogInventory\Api\StockConfigurationInterface;
+use Magento\SalesInventory\Model\Order\ReturnProcessor;
+use Magento\Sales\Api\CreditmemoRepositoryInterface;
+use Magento\Sales\Api\OrderRepositoryInterface;
+use Magento\Sales\Api\RefundOrderInterface;
+
+/**
+ * Class ReturnToStock
+ */
+class ReturnToStockOrder
+{
+    /**
+     * @var ReturnProcessor
+     */
+    private $returnProcessor;
+
+    /**
+     * @var CreditmemoRepositoryInterface
+     */
+    private $creditmemoRepository;
+
+    /**
+     * @var OrderRepositoryInterface
+     */
+    private $orderRepository;
+
+    /**
+     * @var StockConfigurationInterface
+     */
+    private $stockConfiguration;
+
+    /**
+     * ReturnToStockPlugin constructor.
+     *
+     * @param ReturnProcessor $returnProcessor
+     * @param CreditmemoRepositoryInterface $creditmemoRepository
+     * @param OrderRepositoryInterface $orderRepository
+     * @param StockConfigurationInterface $stockConfiguration
+     */
+    public function __construct(
+        ReturnProcessor $returnProcessor,
+        CreditmemoRepositoryInterface $creditmemoRepository,
+        OrderRepositoryInterface $orderRepository,
+        StockConfigurationInterface $stockConfiguration
+    ) {
+        $this->returnProcessor = $returnProcessor;
+        $this->creditmemoRepository = $creditmemoRepository;
+        $this->orderRepository = $orderRepository;
+        $this->stockConfiguration = $stockConfiguration;
+    }
+
+    /**
+     * @param RefundOrderInterface $refundService
+     * @param int $resultEntityId
+     * @param int $orderId
+     * @param \Magento\Sales\Api\Data\CreditmemoItemCreationInterface[] $items
+     * @param bool|null $notify
+     * @param bool|null $appendComment
+     * @param \Magento\Sales\Api\Data\CreditmemoCommentCreationInterface|null $comment
+     * @param \Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface|null $arguments
+     * @return int
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function afterExecute(
+        RefundOrderInterface $refundService,
+        $resultEntityId,
+        $orderId,
+        array $items = [],
+        $notify = false,
+        $appendComment = false,
+        \Magento\Sales\Api\Data\CreditmemoCommentCreationInterface $comment = null,
+        \Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface $arguments = null
+    ) {
+        if ($this->stockConfiguration->isAutoReturnEnabled()) {
+            return $resultEntityId;
+        }
+
+        $order = $this->orderRepository->get($orderId);
+
+        $returnToStockItems = [];
+        if ($arguments !== null
+            && $arguments->getExtensionAttributes() !== null
+            && $arguments->getExtensionAttributes()->getReturnToStockItems() !== null
+        ) {
+            $returnToStockItems = $arguments->getExtensionAttributes()->getReturnToStockItems();
+        }
+
+        $creditmemo = $this->creditmemoRepository->get($resultEntityId);
+        $this->returnProcessor->execute($creditmemo, $order, $returnToStockItems);
+
+        return $resultEntityId;
+    }
+}
diff --git a/app/code/Magento/SalesInventory/Model/Plugin/Order/Validation/InvoiceRefundCreationArguments.php b/app/code/Magento/SalesInventory/Model/Plugin/Order/Validation/InvoiceRefundCreationArguments.php
new file mode 100644
index 0000000000000000000000000000000000000000..7dfa2893c588f713438ee630e8f7fcc7a670bb32
--- /dev/null
+++ b/app/code/Magento/SalesInventory/Model/Plugin/Order/Validation/InvoiceRefundCreationArguments.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\SalesInventory\Model\Plugin\Order\Validation;
+
+use Magento\Sales\Api\Data\InvoiceInterface;
+use Magento\Sales\Model\Order\Validation\RefundInvoiceInterface;
+use Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface;
+use Magento\Sales\Api\Data\CreditmemoInterface;
+use Magento\Sales\Api\Data\OrderInterface;
+use Magento\SalesInventory\Model\Order\ReturnValidator;
+use Magento\Sales\Model\ValidatorResultInterface;
+
+/**
+ * Class CreditmemoCreationArguments
+ */
+class InvoiceRefundCreationArguments
+{
+    /**
+     * @var ReturnValidator
+     */
+    private $returnValidator;
+
+    /**
+     * InvoiceRefundCreationArguments constructor.
+     * @param ReturnValidator $returnValidator
+     */
+    public function __construct(
+        ReturnValidator $returnValidator
+    ) {
+        $this->returnValidator = $returnValidator;
+    }
+
+    /**
+     * @param RefundInvoiceInterface $refundInvoiceValidator
+     * @param ValidatorResultInterface $validationResults
+     * @param InvoiceInterface $invoice
+     * @param OrderInterface $order
+     * @param CreditmemoInterface $creditmemo
+     * @param array $items
+     * @param bool $isOnline
+     * @param bool $notify
+     * @param bool $appendComment
+     * @param \Magento\Sales\Api\Data\CreditmemoCommentCreationInterface|null $comment
+     * @param \Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface|null $arguments
+     * @return ValidatorResultInterface
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
+     */
+    public function afterValidate(
+        RefundInvoiceInterface $refundInvoiceValidator,
+        ValidatorResultInterface $validationResults,
+        InvoiceInterface $invoice,
+        OrderInterface $order,
+        CreditmemoInterface $creditmemo,
+        array $items = [],
+        $isOnline = false,
+        $notify = false,
+        $appendComment = false,
+        \Magento\Sales\Api\Data\CreditmemoCommentCreationInterface $comment = null,
+        \Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface $arguments = null
+    ) {
+        if ($this->isReturnToStockItems($arguments)) {
+            return $validationResults;
+        }
+
+        /** @var int[] $returnToStockItems */
+        $returnToStockItems = $arguments->getExtensionAttributes()->getReturnToStockItems();
+        $validationMessage = $this->returnValidator->validate($returnToStockItems, $creditmemo);
+        if ($validationMessage) {
+            $validationResults->addMessage($validationMessage);
+        }
+
+        return $validationResults;
+    }
+
+    /**
+     * @param CreditmemoCreationArgumentsInterface|null $arguments
+     * @return bool
+     */
+    private function isReturnToStockItems($arguments)
+    {
+        return $arguments === null
+        || $arguments->getExtensionAttributes() === null
+        || $arguments->getExtensionAttributes()->getReturnToStockItems() === null;
+    }
+}
diff --git a/app/code/Magento/SalesInventory/Model/Plugin/Order/Validation/OrderRefundCreationArguments.php b/app/code/Magento/SalesInventory/Model/Plugin/Order/Validation/OrderRefundCreationArguments.php
new file mode 100644
index 0000000000000000000000000000000000000000..29411c7c5e8c6b072203267660f8eafef1306ab7
--- /dev/null
+++ b/app/code/Magento/SalesInventory/Model/Plugin/Order/Validation/OrderRefundCreationArguments.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\SalesInventory\Model\Plugin\Order\Validation;
+
+use Magento\Sales\Api\Data\CreditmemoCommentCreationInterface;
+use Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface;
+use Magento\Sales\Api\Data\CreditmemoInterface;
+use Magento\Sales\Api\Data\OrderInterface;
+use Magento\Sales\Model\Order\Validation\RefundOrderInterface;
+use Magento\SalesInventory\Model\Order\ReturnValidator;
+use Magento\Sales\Model\ValidatorResultInterface;
+
+/**
+ * Class OrderRefundCreationArguments
+ */
+class OrderRefundCreationArguments
+{
+    /**
+     * @var ReturnValidator
+     */
+    private $returnValidator;
+
+    /**
+     * OrderRefundCreationArguments constructor.
+     * @param ReturnValidator $returnValidator
+     */
+    public function __construct(
+        ReturnValidator $returnValidator
+    ) {
+        $this->returnValidator = $returnValidator;
+    }
+
+    /**
+     * @param RefundOrderInterface $refundOrderValidator
+     * @param ValidatorResultInterface $validationResults
+     * @param OrderInterface $order
+     * @param CreditmemoInterface $creditmemo
+     * @param array $items
+     * @param bool $notify
+     * @param bool $appendComment
+     * @param CreditmemoCommentCreationInterface|null $comment
+     * @param CreditmemoCreationArgumentsInterface|null $arguments
+     * @return ValidatorResultInterface
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function afterValidate(
+        RefundOrderInterface $refundOrderValidator,
+        ValidatorResultInterface $validationResults,
+        OrderInterface $order,
+        CreditmemoInterface $creditmemo,
+        array $items = [],
+        $notify = false,
+        $appendComment = false,
+        CreditmemoCommentCreationInterface $comment = null,
+        CreditmemoCreationArgumentsInterface $arguments = null
+    ) {
+        if ($this->isReturnToStockItems($arguments)) {
+            return $validationResults;
+        }
+
+        $returnToStockItems = $arguments->getExtensionAttributes()->getReturnToStockItems();
+        $validationMessage = $this->returnValidator->validate($returnToStockItems, $creditmemo);
+        if ($validationMessage) {
+            $validationResults->addMessage($validationMessage);
+        }
+
+        return $validationResults;
+    }
+
+    /**
+     * @param CreditmemoCreationArgumentsInterface|null $arguments
+     * @return bool
+     */
+    private function isReturnToStockItems($arguments)
+    {
+        return $arguments === null
+        || $arguments->getExtensionAttributes() === null
+        || $arguments->getExtensionAttributes()->getReturnToStockItems() === null;
+    }
+}
diff --git a/app/code/Magento/SalesInventory/README.md b/app/code/Magento/SalesInventory/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..915569ddd3ce24a240f5938c4e38e5275e9ada2c
--- /dev/null
+++ b/app/code/Magento/SalesInventory/README.md
@@ -0,0 +1 @@
+Magento_SalesInventory module allows retrieve and update stock attributes related to Magento_Sales, such as status and quantity.
diff --git a/app/code/Magento/SalesInventory/Test/Unit/Model/Order/ReturnProcessorTest.php b/app/code/Magento/SalesInventory/Test/Unit/Model/Order/ReturnProcessorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..523759d54645a1e2db471db948fa116cf59cd32e
--- /dev/null
+++ b/app/code/Magento/SalesInventory/Test/Unit/Model/Order/ReturnProcessorTest.php
@@ -0,0 +1,195 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\SalesInventory\Test\Unit\Model\Order;
+
+use Magento\CatalogInventory\Api\StockConfigurationInterface;
+use Magento\CatalogInventory\Api\StockManagementInterface;
+use Magento\Sales\Api\CreditmemoRepositoryInterface;
+use Magento\Sales\Api\Data\CreditmemoInterface;
+use Magento\Sales\Api\Data\CreditmemoItemInterface;
+use Magento\Sales\Api\Data\OrderInterface;
+use Magento\Sales\Api\Data\OrderItemInterface;
+use Magento\Sales\Api\OrderItemRepositoryInterface;
+use Magento\Sales\Api\OrderRepositoryInterface;
+use Magento\Store\Api\Data\StoreInterface;
+use Magento\Store\Model\StoreManagerInterface;
+use Magento\SalesInventory\Model\Order\ReturnProcessor;
+
+/**
+ * Class ReturnProcessorTest
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class ReturnProcessorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|OrderInterface
+     */
+    private $orderMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|CreditmemoInterface
+     */
+    private $creditmemoMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|StockManagementInterface
+     */
+    private $stockManagementMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\CatalogInventory\Model\Indexer\Stock\Processor
+     */
+    private $stockIndexerProcessorMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Catalog\Model\Indexer\Product\Price\Processor
+     */
+    private $priceIndexerMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|CreditmemoRepositoryInterface
+     */
+    private $creditmemoRepositoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|StoreManagerInterface
+     */
+    private $storeManagerMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|OrderRepositoryInterface
+     */
+    private $orderRepositoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|OrderItemRepositoryInterface
+     */
+    private $orderItemRepositoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|CreditmemoItemInterface
+     */
+    private $creditmemoItemMock;
+
+    /** @var  ReturnProcessor */
+    private $returnProcessor;
+
+    /** @var  \PHPUnit_Framework_MockObject_MockObject|OrderItemInterface */
+    private $orderItemMock;
+
+    /** @var  \PHPUnit_Framework_MockObject_MockObject|StoreInterface */
+    private $storeMock;
+
+    public function setUp()
+    {
+        $this->stockManagementMock = $this->getMockBuilder(StockManagementInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->stockIndexerProcessorMock = $this->getMockBuilder(
+            \Magento\CatalogInventory\Model\Indexer\Stock\Processor::class
+        )->disableOriginalConstructor()
+            ->getMock();
+        $this->priceIndexerMock = $this->getMockBuilder(\Magento\Catalog\Model\Indexer\Product\Price\Processor::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->creditmemoRepositoryMock = $this->getMockBuilder(CreditmemoRepositoryInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->storeManagerMock = $this->getMockBuilder(StoreManagerInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->orderRepositoryMock = $this->getMockBuilder(OrderRepositoryInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->orderItemRepositoryMock = $this->getMockBuilder(OrderItemRepositoryInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->orderMock = $this->getMockBuilder(OrderInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->creditmemoMock = $this->getMockBuilder(CreditmemoInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->creditmemoItemMock = $this->getMockBuilder(CreditmemoItemInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->orderItemMock = $this->getMockBuilder(OrderItemInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->storeMock = $this->getMockBuilder(StoreInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->returnProcessor = new ReturnProcessor(
+            $this->stockManagementMock,
+            $this->stockIndexerProcessorMock,
+            $this->priceIndexerMock,
+            $this->creditmemoRepositoryMock,
+            $this->storeManagerMock,
+            $this->orderRepositoryMock,
+            $this->orderItemRepositoryMock
+        );
+    }
+
+    public function testExecute()
+    {
+        $orderItemId = 99;
+        $productId = 50;
+        $returnToStockItems = [$orderItemId];
+        $qty = 1;
+        $storeId = 0;
+        $webSiteId = 10;
+
+        $this->creditmemoMock->expects($this->once())
+            ->method('getItems')
+            ->willReturn([$this->creditmemoItemMock]);
+
+        $this->creditmemoItemMock->expects($this->once())
+            ->method('getQty')
+            ->willReturn($qty);
+
+        $this->creditmemoItemMock->expects($this->exactly(2))
+            ->method('getOrderItemId')
+            ->willReturn($orderItemId);
+
+        $this->creditmemoItemMock->expects($this->once())
+            ->method('getProductId')
+            ->willReturn($productId);
+
+        $this->orderItemRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($orderItemId)
+            ->willReturn($this->orderItemMock);
+
+        $this->orderMock->expects($this->once())
+            ->method('getStoreId')
+            ->willReturn($storeId);
+
+        $this->storeManagerMock->expects($this->once())
+            ->method('getStore')
+            ->with($storeId)
+            ->willReturn($this->storeMock);
+
+        $this->storeMock->expects($this->once())
+            ->method('getWebsiteId')
+            ->willReturn($webSiteId);
+
+        $this->stockManagementMock->expects($this->once())
+            ->method('backItemQty')
+            ->with($productId, $qty, $webSiteId)
+            ->willReturn(true);
+
+        $this->stockIndexerProcessorMock->expects($this->once())
+            ->method('reindexList')
+            ->with([$productId]);
+
+        $this->priceIndexerMock->expects($this->once())
+            ->method('reindexList')
+            ->with([$productId]);
+
+        $this->returnProcessor->execute($this->creditmemoMock, $this->orderMock, $returnToStockItems);
+    }
+}
diff --git a/app/code/Magento/SalesInventory/Test/Unit/Model/Order/ReturnValidatorTest.php b/app/code/Magento/SalesInventory/Test/Unit/Model/Order/ReturnValidatorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..da9d3fd8aefd103965f2d577b303e7e1a522223b
--- /dev/null
+++ b/app/code/Magento/SalesInventory/Test/Unit/Model/Order/ReturnValidatorTest.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\SalesInventory\Test\Unit\Model\Order;
+
+use Magento\SalesInventory\Model\Order\ReturnValidator;
+use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Sales\Api\Data\CreditmemoInterface;
+use Magento\Sales\Api\Data\CreditmemoItemInterface;
+use Magento\Sales\Api\Data\OrderItemInterface;
+use Magento\Sales\Api\OrderItemRepositoryInterface;
+
+/**
+ * Class ReturnValidatorTest
+ */
+class ReturnValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|OrderItemRepositoryInterface
+     */
+    private $orderItemRepositoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|CreditmemoInterface
+     */
+    private $creditMemoMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|CreditmemoItemInterface
+     */
+    private $creditMemoItemMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|OrderItemInterface
+     */
+    private $orderItemMock;
+
+    /**
+     * @var ReturnValidator
+     */
+    private $returnValidator;
+
+    protected function setUp()
+    {
+        $this->orderItemRepositoryMock = $this->getMockBuilder(OrderItemRepositoryInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->creditMemoMock = $this->getMockBuilder(CreditmemoInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->creditMemoItemMock = $this->getMockBuilder(CreditmemoItemInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->orderItemMock = $this->getMockBuilder(OrderItemInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->returnValidator = new ReturnValidator(
+            $this->orderItemRepositoryMock
+        );
+    }
+
+    /**
+     * @dataProvider dataProvider
+     */
+    public function testValidate(
+        $expectedResult,
+        $returnToStockItems,
+        $orderItemId,
+        $creditMemoItemId,
+        $productSku = null
+    ) {
+        $this->creditMemoMock->expects($this->once())
+            ->method('getItems')
+            ->willReturn([$this->creditMemoItemMock]);
+
+        $this->orderItemRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($returnToStockItems[0])
+            ->willReturn($this->orderItemMock);
+
+        $this->orderItemMock->expects($this->once())
+            ->method('getItemId')
+            ->willReturn($orderItemId);
+
+        $this->creditMemoItemMock->expects($this->once())
+            ->method('getOrderItemId')
+            ->willReturn($creditMemoItemId);
+
+        if ($productSku) {
+            $this->orderItemMock->expects($this->once())
+                ->method('getSku')
+                ->willReturn($productSku);
+        }
+
+        $this->assertEquals(
+            $this->returnValidator->validate($returnToStockItems, $this->creditMemoMock),
+            $expectedResult
+        );
+    }
+
+    public function testValidationWithWrongOrderItems()
+    {
+        $returnToStockItems = [1];
+        $this->creditMemoMock->expects($this->once())
+            ->method('getItems')
+            ->willReturn([$this->creditMemoItemMock]);
+        $this->orderItemRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($returnToStockItems[0])
+            ->willThrowException(new NoSuchEntityException);
+
+        $this->assertEquals(
+            $this->returnValidator->validate($returnToStockItems, $this->creditMemoMock),
+            __('The return to stock argument contains product item that is not part of the original order.')
+        );
+
+    }
+
+    public function dataProvider()
+    {
+        return [
+            'PostirivValidationTest' => [null, [1], 1, 1],
+            'WithWrongReturnToStockItems' => [
+                __('The "%1" product is not part of the current creditmemo.', 'sku1'), [2], 2, 1, 'sku1',
+            ],
+        ];
+    }
+}
diff --git a/app/code/Magento/SalesInventory/Test/Unit/Model/Plugin/Order/ReturnToStockInvoiceTest.php b/app/code/Magento/SalesInventory/Test/Unit/Model/Plugin/Order/ReturnToStockInvoiceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..35718a96bd509cc8b021c286ca44c042a8a1d67d
--- /dev/null
+++ b/app/code/Magento/SalesInventory/Test/Unit/Model/Plugin/Order/ReturnToStockInvoiceTest.php
@@ -0,0 +1,179 @@
+<?php
+/**
+ *
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\SalesInventory\Test\Unit\Model\Plugin\Order;
+
+/**
+ * Class ReturnToStockInvoiceTest
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class ReturnToStockInvoiceTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var  \Magento\SalesInventory\Model\Plugin\Order\ReturnToStockInvoice */
+    private $returnTOStock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\SalesInventory\Model\Order\ReturnProcessor
+     */
+    private $returnProcessorMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Sales\Api\CreditmemoRepositoryInterface
+     */
+    private $creditmemoRepositoryMock;
+
+    /**
+     * @var  \PHPUnit_Framework_MockObject_MockObject|\Magento\Sales\Api\InvoiceRepositoryInterface
+     */
+    private $invoiceRepositoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Sales\Api\OrderRepositoryInterface
+     */
+    private $orderRepositoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Sales\Api\RefundOrderInterface
+     */
+    private $refundInvoiceMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface
+     */
+    private $creditmemoCreationArgumentsMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Sales\Api\Data\OrderInterface
+     */
+    private $orderMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Sales\Api\Data\CreditmemoInterface
+     */
+    private $creditmemoMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Sales\Api\Data\InvoiceInterface
+     */
+    private $invoiceMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface
+     */
+    private $extencionAttributesMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\CatalogInventory\Api\StockConfigurationInterface
+     */
+    private $stockConfigurationMock;
+
+    protected function setUp()
+    {
+        $this->returnProcessorMock = $this->getMockBuilder(\Magento\SalesInventory\Model\Order\ReturnProcessor::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->creditmemoRepositoryMock = $this->getMockBuilder(\Magento\Sales\Api\CreditmemoRepositoryInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->orderRepositoryMock = $this->getMockBuilder(\Magento\Sales\Api\OrderRepositoryInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->invoiceRepositoryMock = $this->getMockBuilder(\Magento\Sales\Api\InvoiceRepositoryInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->refundInvoiceMock = $this->getMockBuilder(\Magento\Sales\Api\RefundInvoiceInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->creditmemoCreationArgumentsMock = $this->getMockBuilder(
+            \Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface::class
+        )->disableOriginalConstructor()
+            ->getMock();
+        $this->extencionAttributesMock = $this->getMockBuilder(
+            \Magento\Sales\Api\Data\CreditmemoCreationArgumentsExtensionInterface::class
+        )->disableOriginalConstructor()
+            ->setMethods(['getReturnToStockItems'])
+            ->getMock();
+        $this->orderMock = $this->getMockBuilder(\Magento\Sales\Api\Data\OrderInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->creditmemoMock = $this->getMockBuilder(\Magento\Sales\Api\Data\CreditmemoInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->invoiceMock = $this->getMockBuilder(\Magento\Sales\Api\Data\InvoiceInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->stockConfigurationMock = $this->getMockBuilder(
+            \Magento\CatalogInventory\Api\StockConfigurationInterface::class
+        )->disableOriginalConstructor()
+            ->getMock();
+
+        $this->returnTOStock = new \Magento\SalesInventory\Model\Plugin\Order\ReturnToStockInvoice(
+            $this->returnProcessorMock,
+            $this->creditmemoRepositoryMock,
+            $this->orderRepositoryMock,
+            $this->invoiceRepositoryMock,
+            $this->stockConfigurationMock
+        );
+    }
+
+    public function testAfterExecute()
+    {
+        $orderId = 1;
+        $creditmemoId = 99;
+        $items = [];
+        $returnToStockItems = [1];
+        $invoiceId = 98;
+        $this->creditmemoCreationArgumentsMock->expects($this->exactly(3))
+            ->method('getExtensionAttributes')
+            ->willReturn($this->extencionAttributesMock);
+
+        $this->invoiceRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($invoiceId)
+            ->willReturn($this->invoiceMock);
+
+        $this->extencionAttributesMock->expects($this->exactly(2))
+            ->method('getReturnToStockItems')
+            ->willReturn($returnToStockItems);
+
+        $this->orderRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($orderId)
+            ->willReturn($this->orderMock);
+
+        $this->creditmemoRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($creditmemoId)
+            ->willReturn($this->creditmemoMock);
+
+        $this->returnProcessorMock->expects($this->once())
+            ->method('execute')
+            ->with($this->creditmemoMock, $this->orderMock, $returnToStockItems);
+
+        $this->invoiceMock->expects($this->once())
+            ->method('getOrderId')
+            ->willReturn($orderId);
+
+        $this->stockConfigurationMock->expects($this->once())
+            ->method('isAutoReturnEnabled')
+            ->willReturn(false);
+
+        $this->assertEquals(
+            $this->returnTOStock->afterExecute(
+                $this->refundInvoiceMock,
+                $creditmemoId,
+                $invoiceId,
+                $items,
+                false,
+                false,
+                false,
+                null,
+                $this->creditmemoCreationArgumentsMock
+            ),
+            $creditmemoId
+        );
+    }
+}
diff --git a/app/code/Magento/SalesInventory/Test/Unit/Model/Plugin/Order/ReturnToStockOrderTest.php b/app/code/Magento/SalesInventory/Test/Unit/Model/Plugin/Order/ReturnToStockOrderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b4883dd1a7708a844e9c200162060fcac7cbf87a
--- /dev/null
+++ b/app/code/Magento/SalesInventory/Test/Unit/Model/Plugin/Order/ReturnToStockOrderTest.php
@@ -0,0 +1,158 @@
+<?php
+/**
+ *
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\SalesInventory\Test\Unit\Model\Plugin\Order;
+
+use Magento\CatalogInventory\Api\StockConfigurationInterface;
+use Magento\SalesInventory\Model\Order\ReturnProcessor;
+use Magento\SalesInventory\Model\Plugin\Order\ReturnToStockOrder;
+use Magento\Sales\Api\CreditmemoRepositoryInterface;
+use Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface;
+use Magento\Sales\Api\Data\CreditmemoCreationArgumentsExtensionInterface;
+use Magento\Sales\Api\Data\CreditmemoInterface;
+use Magento\Sales\Api\Data\OrderInterface;
+use Magento\Sales\Api\OrderRepositoryInterface;
+use Magento\Sales\Api\RefundOrderInterface;
+
+/**
+ * Class ReturnToStockOrderTest
+ */
+class ReturnToStockOrderTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var  ReturnToStockOrder */
+    private $returnTOStock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|ReturnProcessor
+     */
+    private $returnProcessorMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|CreditmemoRepositoryInterface
+     */
+    private $creditmemoRepositoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|OrderRepositoryInterface
+     */
+    private $orderRepositoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|RefundOrderInterface
+     */
+    private $refundOrderMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|CreditmemoCreationArgumentsInterface
+     */
+    private $creditmemoCreationArgumentsMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|OrderInterface
+     */
+    private $orderMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|CreditmemoInterface
+     */
+    private $creditmemoMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|StockConfigurationInterface
+     */
+    private $stockConfigurationMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|CreditmemoCreationArgumentsInterface
+     */
+    private $extencionAttributesMock;
+
+    protected function setUp()
+    {
+        $this->returnProcessorMock = $this->getMockBuilder(ReturnProcessor::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->creditmemoRepositoryMock = $this->getMockBuilder(CreditmemoRepositoryInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->orderRepositoryMock = $this->getMockBuilder(OrderRepositoryInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->refundOrderMock = $this->getMockBuilder(RefundOrderInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->creditmemoCreationArgumentsMock = $this->getMockBuilder(CreditmemoCreationArgumentsInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->extencionAttributesMock = $this->getMockBuilder(CreditmemoCreationArgumentsExtensionInterface::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getReturnToStockItems'])
+            ->getMock();
+        $this->orderMock = $this->getMockBuilder(OrderInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->creditmemoMock = $this->getMockBuilder(CreditmemoInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->stockConfigurationMock = $this->getMockBuilder(StockConfigurationInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->returnTOStock = new ReturnToStockOrder(
+            $this->returnProcessorMock,
+            $this->creditmemoRepositoryMock,
+            $this->orderRepositoryMock,
+            $this->stockConfigurationMock
+        );
+    }
+
+    public function testAfterExecute()
+    {
+        $orderId = 1;
+        $creditmemoId = 99;
+        $items = [];
+        $returnToStockItems = [1];
+        $this->creditmemoCreationArgumentsMock->expects($this->exactly(3))
+            ->method('getExtensionAttributes')
+            ->willReturn($this->extencionAttributesMock);
+
+        $this->extencionAttributesMock->expects($this->exactly(2))
+            ->method('getReturnToStockItems')
+            ->willReturn($returnToStockItems);
+
+        $this->orderRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($orderId)
+            ->willReturn($this->orderMock);
+
+        $this->creditmemoRepositoryMock->expects($this->once())
+            ->method('get')
+            ->with($creditmemoId)
+            ->willReturn($this->creditmemoMock);
+
+        $this->returnProcessorMock->expects($this->once())
+            ->method('execute')
+            ->with($this->creditmemoMock, $this->orderMock, $returnToStockItems);
+
+        $this->stockConfigurationMock->expects($this->once())
+            ->method('isAutoReturnEnabled')
+            ->willReturn(false);
+
+        $this->assertEquals(
+            $this->returnTOStock->afterExecute(
+                $this->refundOrderMock,
+                $creditmemoId,
+                $orderId,
+                $items,
+                false,
+                false,
+                null,
+                $this->creditmemoCreationArgumentsMock
+            ),
+            $creditmemoId
+        );
+    }
+}
diff --git a/app/code/Magento/SalesInventory/Test/Unit/Model/Plugin/Order/Validation/InvoiceRefundCreationArgumentsTest.php b/app/code/Magento/SalesInventory/Test/Unit/Model/Plugin/Order/Validation/InvoiceRefundCreationArgumentsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d59da679d15e21331efcba024f05e0c5b0e05d4a
--- /dev/null
+++ b/app/code/Magento/SalesInventory/Test/Unit/Model/Plugin/Order/Validation/InvoiceRefundCreationArgumentsTest.php
@@ -0,0 +1,150 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\SalesInventory\Test\Unit\Model\Plugin\Order\Validation;
+
+use Magento\SalesInventory\Model\Order\ReturnValidator;
+use Magento\SalesInventory\Model\Plugin\Order\Validation\InvoiceRefundCreationArguments;
+use Magento\Sales\Model\ValidatorResultInterface;
+use Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface;
+use Magento\Sales\Api\Data\CreditmemoCreationArgumentsExtensionInterface;
+use Magento\Sales\Api\Data\CreditmemoInterface;
+use Magento\Sales\Api\Data\InvoiceInterface;
+use Magento\Sales\Api\Data\OrderInterface;
+use Magento\Sales\Model\Order\Validation\RefundInvoiceInterface;
+
+/**
+ * Class InvoiceRefundCreatetionArgumentsTest
+ */
+class InvoiceRefundCreationArgumentsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var InvoiceRefundCreationArguments
+     */
+    private $plugin;
+
+    /**
+     * @var ReturnValidator|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $returnValidatorMock;
+
+    /**
+     * @var CreditmemoCreationArgumentsExtensionInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $extencionAttributesMock;
+
+    /**
+     * @var CreditmemoCreationArgumentsInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $creditmemoCreationArgumentsMock;
+
+    /**
+     * @var RefundInvoiceInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $refundInvoiceValidatorMock;
+
+    /**
+     * @var InvoiceInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $invoiceMock;
+
+    /**
+     * @var ValidatorResultInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $validateResultMock;
+
+    /**
+     * @var OrderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $orderMock;
+
+    /**
+     * @var CreditmemoInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $creditmemoMock;
+
+    protected function setUp()
+    {
+        $this->returnValidatorMock = $this->getMockBuilder(ReturnValidator::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->creditmemoCreationArgumentsMock = $this->getMockBuilder(CreditmemoCreationArgumentsInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->extencionAttributesMock = $this->getMockBuilder(CreditmemoCreationArgumentsExtensionInterface::class)
+            ->setMethods(['getReturnToStockItems'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->validateResultMock = $this->getMockBuilder(ValidatorResultInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->refundInvoiceValidatorMock = $this->getMockBuilder(RefundInvoiceInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->invoiceMock = $this->getMockBuilder(InvoiceInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->orderMock = $this->getMockBuilder(OrderInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->creditmemoMock = $this->getMockBuilder(CreditmemoInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->plugin = new InvoiceRefundCreationArguments($this->returnValidatorMock);
+    }
+
+    /**
+     * @dataProvider dataProvider
+     */
+    public function testAfterValidation($erroMessage)
+    {
+        $returnToStockItems = [1];
+        $this->creditmemoCreationArgumentsMock->expects($this->exactly(3))
+            ->method('getExtensionAttributes')
+            ->willReturn($this->extencionAttributesMock);
+
+        $this->extencionAttributesMock->expects($this->exactly(2))
+            ->method('getReturnToStockItems')
+            ->willReturn($returnToStockItems);
+
+        $this->returnValidatorMock->expects($this->once())
+            ->method('validate')
+            ->willReturn($erroMessage);
+
+        $this->validateResultMock->expects($erroMessage ? $this->once() : $this->never())
+            ->method('addMessage')
+            ->with($erroMessage);
+
+        $this->plugin->afterValidate(
+            $this->refundInvoiceValidatorMock,
+            $this->validateResultMock,
+            $this->invoiceMock,
+            $this->orderMock,
+            $this->creditmemoMock,
+            [],
+            false,
+            false,
+            false,
+            null,
+            $this->creditmemoCreationArgumentsMock
+        );
+    }
+
+    public function dataProvider()
+    {
+        return [
+            'withErrors' => ['Error!'],
+            'withoutErrors' => ['null'],
+        ];
+    }
+}
diff --git a/app/code/Magento/SalesInventory/Test/Unit/Model/Plugin/Order/Validation/OrderRefundCreationArgumentsTest.php b/app/code/Magento/SalesInventory/Test/Unit/Model/Plugin/Order/Validation/OrderRefundCreationArgumentsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6a6b88f3d4580df6cde0479297968e12291e8d5d
--- /dev/null
+++ b/app/code/Magento/SalesInventory/Test/Unit/Model/Plugin/Order/Validation/OrderRefundCreationArgumentsTest.php
@@ -0,0 +1,141 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\SalesInventory\Test\Unit\Model\Plugin\Order\Validation;
+
+use Magento\SalesInventory\Model\Order\ReturnValidator;
+use Magento\SalesInventory\Model\Plugin\Order\Validation\OrderRefundCreationArguments;
+use Magento\Sales\Model\Order\Validation\RefundOrderInterface;
+use Magento\Sales\Model\ValidatorResultInterface;
+use Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface;
+use Magento\Sales\Api\Data\CreditmemoCreationArgumentsExtensionInterface;
+use Magento\Sales\Api\Data\CreditmemoInterface;
+use Magento\Sales\Api\Data\OrderInterface;
+
+/**
+ * Class OrderRefundCreatetionArgumentsTest
+ */
+class OrderRefundCreationArgumentsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var OrderRefundCreationArguments
+     */
+    private $plugin;
+
+    /**
+     * @var ReturnValidator|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $returnValidatorMock;
+
+    /**
+     * @var CreditmemoCreationArgumentsExtensionInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $extencionAttributesMock;
+
+    /**
+     * @var CreditmemoCreationArgumentsInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $creditmemoCreationArgumentsMock;
+
+    /**
+     * @var RefundOrderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $refundOrderValidatorMock;
+
+    /**
+     * @var ValidatorResultInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $validateResultMock;
+
+    /**
+     * @var OrderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $orderMock;
+
+    /**
+     * @var CreditmemoInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $creditmemoMock;
+
+    protected function setUp()
+    {
+        $this->returnValidatorMock = $this->getMockBuilder(ReturnValidator::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->creditmemoCreationArgumentsMock = $this->getMockBuilder(CreditmemoCreationArgumentsInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->extencionAttributesMock = $this->getMockBuilder(CreditmemoCreationArgumentsExtensionInterface::class)
+            ->setMethods(['getReturnToStockItems'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->validateResultMock = $this->getMockBuilder(ValidatorResultInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->refundOrderValidatorMock = $this->getMockBuilder(RefundOrderInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->orderMock = $this->getMockBuilder(OrderInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->creditmemoMock = $this->getMockBuilder(CreditmemoInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->plugin = new OrderRefundCreationArguments($this->returnValidatorMock);
+    }
+
+    /**
+     * @dataProvider dataProvider
+     */
+    public function testAfterValidation($erroMessage)
+    {
+        $returnToStockItems = [1];
+        $this->creditmemoCreationArgumentsMock->expects($this->exactly(3))
+            ->method('getExtensionAttributes')
+            ->willReturn($this->extencionAttributesMock);
+
+        $this->extencionAttributesMock->expects($this->exactly(2))
+            ->method('getReturnToStockItems')
+            ->willReturn($returnToStockItems);
+
+        $this->returnValidatorMock->expects($this->once())
+            ->method('validate')
+            ->willReturn($erroMessage);
+
+        $this->validateResultMock->expects($erroMessage ? $this->once() : $this->never())
+            ->method('addMessage')
+            ->with($erroMessage);
+
+        $this->plugin->afterValidate(
+            $this->refundOrderValidatorMock,
+            $this->validateResultMock,
+            $this->orderMock,
+            $this->creditmemoMock,
+            [],
+            false,
+            false,
+            null,
+            $this->creditmemoCreationArgumentsMock
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function dataProvider()
+    {
+        return [
+            'withErrors' => ['Error!'],
+            'withoutErrors' => ['null'],
+        ];
+    }
+}
diff --git a/app/code/Magento/SalesInventory/composer.json b/app/code/Magento/SalesInventory/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..ff72ce7f0022690682b356235c506512e65497b9
--- /dev/null
+++ b/app/code/Magento/SalesInventory/composer.json
@@ -0,0 +1,26 @@
+{
+    "name": "magento/module-sales-inventory",
+    "description": "N/A",
+    "require": {
+        "php": "~5.6.0|7.0.2|7.0.4|~7.0.6",
+        "magento/module-catalog-inventory": "100.2.*",
+        "magento/module-sales": "100.2.*",
+        "magento/module-store": "100.2.*",
+        "magento/module-catalog": "101.2.*",
+        "magento/framework": "100.2.*"
+    },
+    "type": "magento2-module",
+    "version": "100.0.0-dev",
+    "license": [
+        "OSL-3.0",
+        "AFL-3.0"
+    ],
+    "autoload": {
+        "files": [
+            "registration.php"
+        ],
+        "psr-4": {
+            "Magento\\SalesInventory\\": ""
+        }
+    }
+}
diff --git a/app/code/Magento/SalesInventory/etc/di.xml b/app/code/Magento/SalesInventory/etc/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..aec39d3c51c29d398e7c52f45bf5cf1443d3bffa
--- /dev/null
+++ b/app/code/Magento/SalesInventory/etc/di.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
+    <type name="Magento\Sales\Model\RefundOrder">
+        <plugin name="refundOrderAfter" type="Magento\SalesInventory\Model\Plugin\Order\ReturnToStockOrder"/>
+    </type>
+    <type name="Magento\Sales\Model\RefundInvoice">
+        <plugin name="refundInvoiceAfter" type="Magento\SalesInventory\Model\Plugin\Order\ReturnToStockInvoice"/>
+    </type>
+    <type name="Magento\Sales\Model\Order\Validation\RefundOrderInterface">
+        <plugin name="refundOrderValidationAfter" type="Magento\SalesInventory\Model\Plugin\Order\Validation\OrderRefundCreationArguments"/>
+    </type>
+    <type name="Magento\Sales\Model\Order\Validation\RefundInvoiceInterface">
+        <plugin name="refundInvoiceValidationAfter" type="Magento\SalesInventory\Model\Plugin\Order\Validation\InvoiceRefundCreationArguments"/>
+    </type>
+</config>
diff --git a/app/code/Magento/SalesInventory/etc/extension_attributes.xml b/app/code/Magento/SalesInventory/etc/extension_attributes.xml
new file mode 100644
index 0000000000000000000000000000000000000000..de5b6d41c52621f6ba1b2bf432b912157431bc30
--- /dev/null
+++ b/app/code/Magento/SalesInventory/etc/extension_attributes.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
+    <extension_attributes for="Magento\Sales\Api\Data\CreditmemoCreationArgumentsInterface">
+        <attribute code="return_to_stock_items" type="int[]"/>
+    </extension_attributes>
+</config>
\ No newline at end of file
diff --git a/app/code/Magento/SalesInventory/etc/module.xml b/app/code/Magento/SalesInventory/etc/module.xml
new file mode 100644
index 0000000000000000000000000000000000000000..06c9d0d78554afed0c4ab3e2d81bdeaea03c4df9
--- /dev/null
+++ b/app/code/Magento/SalesInventory/etc/module.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
+    <module name="Magento_SalesInventory" setup_version="1.0.0">
+        <sequence>
+            <module name="Magento_Sales"/>
+            <module name="Magento_Catalog"/>
+            <module name="Magento_Store"/>
+            <module name="Magento_CatalogInventory"/>
+        </sequence>
+    </module>
+</config>
diff --git a/app/code/Magento/SalesInventory/registration.php b/app/code/Magento/SalesInventory/registration.php
new file mode 100644
index 0000000000000000000000000000000000000000..edb96135508d2c61e5078ca771409a37a2c1bf30
--- /dev/null
+++ b/app/code/Magento/SalesInventory/registration.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+\Magento\Framework\Component\ComponentRegistrar::register(
+    \Magento\Framework\Component\ComponentRegistrar::MODULE,
+    'Magento_SalesInventory',
+    __DIR__
+);
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Widget/Chooser.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Widget/Chooser.php
new file mode 100644
index 0000000000000000000000000000000000000000..b13ace25f020bfea737f6430916d957713ffa6f9
--- /dev/null
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Widget/Chooser.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\SalesRule\Controller\Adminhtml\Promo\Widget;
+
+class Chooser extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Widget\Chooser
+{
+    /**
+     * Authorization level of a basic admin session
+     *
+     * @see _isAllowed()
+     */
+    const ADMIN_RESOURCE = 'Magento_SalesRule::quote';
+}
diff --git a/app/code/Magento/SalesRule/Model/CouponRepository.php b/app/code/Magento/SalesRule/Model/CouponRepository.php
index ad9b43f90e1a21227b08f3ae82d8daf157876d74..ddc8e9eb50688626b8c6f7988714441ea7d18b47 100644
--- a/app/code/Magento/SalesRule/Model/CouponRepository.php
+++ b/app/code/Magento/SalesRule/Model/CouponRepository.php
@@ -163,15 +163,9 @@ class CouponRepository implements \Magento\SalesRule\Api\CouponRepositoryInterfa
         $this->extensionAttributesJoinProcessor->process($collection, $couponInterfaceName);
 
         $this->collectionProcessor->process($searchCriteria, $collection);
-        $coupons = [];
-        /** @var \Magento\SalesRule\Model\Coupon $couponModel */
-        foreach ($collection->getItems() as $couponModel) {
-            $coupons[] = $couponModel->getData();
-        }
-
         $searchResults = $this->searchResultFactory->create();
         $searchResults->setSearchCriteria($searchCriteria);
-        $searchResults->setItems($coupons);
+        $searchResults->setItems($collection->getItems());
         $searchResults->setTotalCount($collection->getSize());
         return $searchResults;
     }
diff --git a/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php b/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php
index f85daffd3f9625b08520548c1d96697aad3e58cf..1670819588e6106c13226f6d19ab23edcad93bd0 100644
--- a/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php
+++ b/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php
@@ -51,4 +51,26 @@ class Product extends \Magento\Rule\Model\Condition\Product\AbstractProduct
 
         return parent::validate($product);
     }
+
+    /**
+     * Retrieve value element chooser URL
+     *
+     * @return string
+     */
+    public function getValueElementChooserUrl()
+    {
+        $url = false;
+        switch ($this->getAttribute()) {
+            case 'sku':
+            case 'category_ids':
+                $url = 'sales_rule/promo_widget/chooser/attribute/' . $this->getAttribute();
+                if ($this->getJsFormObject()) {
+                    $url .= '/form/' . $this->getJsFormObject();
+                }
+                break;
+            default:
+                break;
+        }
+        return $url !== false ? $this->_backendData->getUrl($url) : '';
+    }
 }
diff --git a/app/code/Magento/SalesRule/Observer/SalesOrderAfterPlaceObserver.php b/app/code/Magento/SalesRule/Observer/SalesOrderAfterPlaceObserver.php
index e352ede867a69638c00598d59fde6455be46c05a..a75947629db5d5a97b054306e7908b74cca300d4 100644
--- a/app/code/Magento/SalesRule/Observer/SalesOrderAfterPlaceObserver.php
+++ b/app/code/Magento/SalesRule/Observer/SalesOrderAfterPlaceObserver.php
@@ -57,7 +57,7 @@ class SalesOrderAfterPlaceObserver implements ObserverInterface
     {
         $order = $observer->getEvent()->getOrder();
 
-        if (!$order || $order->getDiscountAmount() == 0) {
+        if (!$order || !$order->getAppliedRuleIds()) {
             return $this;
         }
 
diff --git a/app/code/Magento/SalesRule/Test/Unit/Model/CouponRepositoryTest.php b/app/code/Magento/SalesRule/Test/Unit/Model/CouponRepositoryTest.php
index 19dfc5e21c86ef1d8eceb6276f84e968becf6f84..39957d9d63f5679671f484ed66b7d6081dfbade6 100644
--- a/app/code/Magento/SalesRule/Test/Unit/Model/CouponRepositoryTest.php
+++ b/app/code/Magento/SalesRule/Test/Unit/Model/CouponRepositoryTest.php
@@ -233,6 +233,7 @@ class CouponRepositoryTest extends \PHPUnit_Framework_TestCase
     public function testGetList()
     {
         $collectionSize = 1;
+        $couponMock = $this->getMock(\Magento\SalesRule\Api\Data\CouponInterface::class);
         /**
          * @var \Magento\Framework\Api\SearchCriteriaInterface $searchCriteriaMock
          */
@@ -254,8 +255,8 @@ class CouponRepositoryTest extends \PHPUnit_Framework_TestCase
         $this->collectionFactory->expects($this->once())->method('create')->willReturn($collectionMock);
         $collectionMock->expects($this->once())->method('getSize')->willReturn($collectionSize);
         $this->searchResultsMock->expects($this->once())->method('setTotalCount')->with($collectionSize);
-        $collectionMock->expects($this->once())->method('getItems')->willReturn([]);
-        $this->searchResultsMock->expects($this->once())->method('setItems')->with([]);
+        $collectionMock->expects($this->once())->method('getItems')->willReturn([$couponMock]);
+        $this->searchResultsMock->expects($this->once())->method('setItems')->with([$couponMock]);
         $this->searchResultFactory->expects($this->once())->method('create')->willReturn($this->searchResultsMock);
 
         $this->assertEquals($this->searchResultsMock, $this->model->getList($searchCriteriaMock));
diff --git a/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php b/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a28ea216eda32ed78b368cf3a7b84c53659904dd
--- /dev/null
+++ b/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Condition/ProductTest.php
@@ -0,0 +1,161 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\SalesRule\Test\Unit\Model\Rule\Condition;
+
+use \Magento\Rule\Model\Condition\Context;
+use \Magento\Backend\Helper\Data;
+use \Magento\Eav\Model\Config;
+use \Magento\Catalog\Model\ProductFactory;
+use \Magento\Catalog\Api\ProductRepositoryInterface;
+use \Magento\Eav\Model\Entity\AbstractEntity;
+use \Magento\Catalog\Model\ResourceModel\Product;
+use \Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection;
+use \Magento\Framework\Locale\FormatInterface;
+use \Magento\Eav\Model\Entity\AttributeLoaderInterface;
+use \Magento\SalesRule\Model\Rule\Condition\Product as SalesRuleProduct;
+
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class ProductTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var SalesRuleProduct */
+    protected $model;
+
+    /** @var Context|\PHPUnit_Framework_MockObject_MockObject */
+    protected $contextMock;
+
+    /** @var Data|\PHPUnit_Framework_MockObject_MockObject */
+    protected $backendHelperMock;
+
+    /** @var Config|\PHPUnit_Framework_MockObject_MockObject */
+    protected $configMock;
+
+    /** @var ProductFactory|\PHPUnit_Framework_MockObject_MockObject */
+    protected $productFactoryMock;
+
+    /** @var ProductRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $productRepositoryMock;
+
+    /** @var Product|\PHPUnit_Framework_MockObject_MockObject */
+    protected $productMock;
+
+    /** @var Collection|\PHPUnit_Framework_MockObject_MockObject */
+    protected $collectionMock;
+
+    /** @var FormatInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $formatMock;
+
+    /** @var AttributeLoaderInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $attributeLoaderInterfaceMock;
+
+    /**
+     * Setup the test
+     */
+    protected function setUp()
+    {
+        $this->contextMock = $this->getMockBuilder(Context::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->backendHelperMock = $this->getMockBuilder(Data::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->configMock = $this->getMockBuilder(Config::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->productFactoryMock = $this->getMockBuilder(ProductFactory::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->productRepositoryMock = $this->getMockBuilder(ProductRepositoryInterface::class)
+            ->getMockForAbstractClass();
+        $this->attributeLoaderInterfaceMock = $this->getMockBuilder(AbstractEntity::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['getAttributesByCode'])
+            ->getMock();
+        $this->attributeLoaderInterfaceMock
+            ->expects($this->any())
+            ->method('getAttributesByCode')
+            ->will($this->returnValue([]));
+        $this->productMock = $this->getMockBuilder(Product::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['loadAllAttributes'])
+            ->getMock();
+        $this->productMock
+            ->expects($this->any())
+            ->method('loadAllAttributes')
+            ->will($this->returnValue($this->attributeLoaderInterfaceMock));
+        $this->collectionMock = $this->getMockBuilder(Collection::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->formatMock = $this->getMockBuilder(FormatInterface::class)
+            ->getMockForAbstractClass();
+        $this->model = new SalesRuleProduct(
+            $this->contextMock,
+            $this->backendHelperMock,
+            $this->configMock,
+            $this->productFactoryMock,
+            $this->productRepositoryMock,
+            $this->productMock,
+            $this->collectionMock,
+            $this->formatMock
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function testGetValueElementChooserUrlDataProvider()
+    {
+        return [
+            'category_ids_without_js_object' => [
+                'category_ids',
+                'sales_rule/promo_widget/chooser/attribute/'
+            ],
+            'category_ids_with_js_object' => [
+                'category_ids',
+                'sales_rule/promo_widget/chooser/attribute/',
+                'jsobject'
+            ],
+            'sku_without_js_object' => [
+                'sku',
+                'sales_rule/promo_widget/chooser/attribute/',
+                'jsobject'
+            ],
+            'sku_without_with_js_object' => [
+                'sku',
+                'sales_rule/promo_widget/chooser/attribute/'
+            ],
+            'none' => [
+                '',
+                ''
+            ]
+        ];
+    }
+
+    /**
+     * test getValueElementChooserUrl
+     * @param string $attribute
+     * @param string $url
+     * @param string $jsObject
+     * @dataProvider testGetValueElementChooserUrlDataProvider
+     */
+    public function testGetValueElementChooserUrl($attribute, $url, $jsObject = '')
+    {
+        $this->model->setJsFormObject($jsObject);
+        $this->model->setAttribute($attribute);
+        $url .= $this->model->getAttribute();
+        $this->backendHelperMock
+            ->expects($this->any())
+            ->method('getUrl')
+            ->willReturnArgument(0);
+
+        if ($this->model->getJsFormObject()) {
+            $url .= '/form/' . $this->model->getJsFormObject();
+        }
+
+        $this->assertEquals($url, $this->model->getValueElementChooserUrl());
+    }
+}
diff --git a/app/code/Magento/SalesRule/Test/Unit/Observer/SalesOrderAfterPlaceObserverTest.php b/app/code/Magento/SalesRule/Test/Unit/Observer/SalesOrderAfterPlaceObserverTest.php
index 0546dce56a3f6d6a27849708daf987c801e14a3c..c3d7e41acdf2801e3a6aaae7eb3f3db24d3a992c 100644
--- a/app/code/Magento/SalesRule/Test/Unit/Observer/SalesOrderAfterPlaceObserverTest.php
+++ b/app/code/Magento/SalesRule/Test/Unit/Observer/SalesOrderAfterPlaceObserverTest.php
@@ -121,10 +121,10 @@ class SalesOrderAfterPlaceObserverTest extends \PHPUnit_Framework_TestCase
     {
         $observer = $this->getMock(\Magento\Framework\Event\Observer::class, [], [], '', false);
         $order = $this->initOrderFromEvent($observer);
-        $discountAmount = 10;
+        $ruleIds = null;
         $order->expects($this->once())
-            ->method('getDiscountAmount')
-            ->will($this->returnValue($discountAmount));
+            ->method('getAppliedRuleIds')
+            ->will($this->returnValue($ruleIds));
 
         $this->ruleFactory->expects($this->never())
             ->method('create');
@@ -158,14 +158,10 @@ class SalesOrderAfterPlaceObserverTest extends \PHPUnit_Framework_TestCase
         $ruleId = 1;
         $couponId = 1;
         $customerId = 1;
-        $discountAmount = 10;
 
-        $order->expects($this->once())
+        $order->expects($this->exactly(2))
             ->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));
diff --git a/app/code/Magento/SalesRule/etc/di.xml b/app/code/Magento/SalesRule/etc/di.xml
index 2c731823b778fabe6faab37024f4e9ea60247538..83364f924397d857030a9f039ed1ab59dc0fd5f0 100644
--- a/app/code/Magento/SalesRule/etc/di.xml
+++ b/app/code/Magento/SalesRule/etc/di.xml
@@ -78,7 +78,7 @@
     <type name="Magento\Framework\Model\Entity\RepositoryFactory">
         <arguments>
             <argument name="entities" xsi:type="array">
-                <item name="Magento\SalesRule\Api\Data\RuleInterface" xsi:type="string">Magento\SalesRule\Api\RuleRepositoryInterface</item>
+                <item name="Magento\SalesRule\Api\Data\RuleInterface" xsi:type="string">Magento\SalesRule\Model\ResourceModel\Rule</item>
             </argument>
         </arguments>
     </type>
diff --git a/app/code/Magento/SalesSequence/Test/Unit/Model/ResourceModel/MetaTest.php b/app/code/Magento/SalesSequence/Test/Unit/Model/ResourceModel/MetaTest.php
index 42f4d098ebcba34d91b6eac8944ebb5072040af3..7a842b8d1c908309c887b2fb5dc5f85f1e36213a 100644
--- a/app/code/Magento/SalesSequence/Test/Unit/Model/ResourceModel/MetaTest.php
+++ b/app/code/Magento/SalesSequence/Test/Unit/Model/ResourceModel/MetaTest.php
@@ -161,6 +161,7 @@ class MetaTest extends \PHPUnit_Framework_TestCase
             ->willReturn($metaId);
         $this->metaFactory->expects($this->once())->method('create')->willReturn($this->meta);
         $this->stepCheckSaveWithActiveProfile($metaData);
+        $this->meta->expects($this->once())->method('beforeLoad');
         $this->assertEquals($this->meta, $this->resource->loadByEntityTypeAndStore($entityType, $storeId));
     }
 
@@ -177,7 +178,5 @@ class MetaTest extends \PHPUnit_Framework_TestCase
             ->method('quoteIdentifier');
         $this->connectionMock->expects($this->once())->method('fetchRow')->willReturn($metaData);
         $this->resourceProfile->expects($this->once())->method('loadActiveProfile')->willReturn($this->profile);
-        $this->meta->expects($this->at(0))->method('setData')->with($metaData);
-        $this->meta->expects($this->at(2))->method('setData')->with('active_profile', $this->profile);
     }
 }
diff --git a/app/code/Magento/SalesSequence/Test/Unit/Model/ResourceModel/ProfileTest.php b/app/code/Magento/SalesSequence/Test/Unit/Model/ResourceModel/ProfileTest.php
index c3c827ba2f97a4e795a8f4d5633ebbf0736ba58e..b17445e7014fa618d2eb9c014f5a6b9bbc7d7f43 100644
--- a/app/code/Magento/SalesSequence/Test/Unit/Model/ResourceModel/ProfileTest.php
+++ b/app/code/Magento/SalesSequence/Test/Unit/Model/ResourceModel/ProfileTest.php
@@ -156,7 +156,7 @@ class ProfileTest extends \PHPUnit_Framework_TestCase
         $this->connectionMock->expects($this->any())
             ->method('quoteIdentifier');
         $this->connectionMock->expects($this->once())->method('fetchRow')->willReturn($profileData);
-        $this->profile->expects($this->at(0))->method('setData')->with($profileData);
+        $this->profile->expects($this->at(1))->method('setData')->with($profileData);
         $this->assertEquals($this->profile, $this->resource->loadActiveProfile($metaId));
     }
 }
diff --git a/app/code/Magento/Security/Model/Plugin/AccountManagement.php b/app/code/Magento/Security/Model/Plugin/AccountManagement.php
index ba1d4af5618b706bbf2bf009568c526364c47108..c65442ec400209c8c789a7f3103cba6a6db01540 100644
--- a/app/code/Magento/Security/Model/Plugin/AccountManagement.php
+++ b/app/code/Magento/Security/Model/Plugin/AccountManagement.php
@@ -25,18 +25,26 @@ class AccountManagement
      */
     protected $securityManager;
 
+    /**
+     * @var int
+     */
+    protected $passwordRequestEvent;
+
     /**
      * AccountManagement constructor.
      *
      * @param \Magento\Framework\App\RequestInterface $request
      * @param SecurityManager $securityManager
+     * @param int $passwordRequestEvent
      */
     public function __construct(
         \Magento\Framework\App\RequestInterface $request,
-        \Magento\Security\Model\SecurityManager $securityManager
+        \Magento\Security\Model\SecurityManager $securityManager,
+        $passwordRequestEvent = PasswordResetRequestEvent::CUSTOMER_PASSWORD_RESET_REQUEST
     ) {
         $this->request = $request;
         $this->securityManager = $securityManager;
+        $this->passwordRequestEvent = $passwordRequestEvent;
     }
 
     /**
@@ -56,7 +64,7 @@ class AccountManagement
         $websiteId = null
     ) {
         $this->securityManager->performSecurityCheck(
-            PasswordResetRequestEvent::CUSTOMER_PASSWORD_RESET_REQUEST,
+            $this->passwordRequestEvent,
             $email
         );
         return [$email, $template, $websiteId];
diff --git a/app/code/Magento/Security/etc/adminhtml/di.xml b/app/code/Magento/Security/etc/adminhtml/di.xml
index 4cbd3c3adc567188fef3b0b487d064264d5a1c12..c134638d1266e50442a7bb17b5ea2e7bb6bb42c8 100644
--- a/app/code/Magento/Security/etc/adminhtml/di.xml
+++ b/app/code/Magento/Security/etc/adminhtml/di.xml
@@ -15,6 +15,11 @@
     <type name="Magento\Backend\Controller\Adminhtml\Auth\Login">
         <plugin name="security_login_form" type="Magento\Security\Model\Plugin\LoginController" />
     </type>
+    <type name="Magento\Security\Model\Plugin\AccountManagement">
+        <arguments>
+            <argument name="passwordRequestEvent" xsi:type="const">Magento\Security\Model\PasswordResetRequestEvent::ADMIN_PASSWORD_RESET_REQUEST</argument>
+        </arguments>
+    </type>
     <type name="Magento\Security\Model\SecurityManager">
         <arguments>
             <argument name="securityCheckers" xsi:type="array">
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php
index d265159bc630be220bc4a7a64b706e36786510ef..1c59c4033d377996da9d7b36dc5c9b0b6ba02fe8 100644
--- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php
@@ -107,6 +107,8 @@ class Save extends \Magento\Backend\App\Action
             $this->_objectManager->get(\Magento\Backend\Model\Session::class)->setCommentText($data['comment_text']);
         }
 
+        $isNeedCreateLabel = isset($data['create_shipping_label']) && $data['create_shipping_label'];
+
         try {
             $this->shipmentLoader->setOrderId($this->getRequest()->getParam('order_id'));
             $this->shipmentLoader->setShipmentId($this->getRequest()->getParam('shipment_id'));
@@ -128,10 +130,12 @@ class Save extends \Magento\Backend\App\Action
                 $shipment->setCustomerNote($data['comment_text']);
                 $shipment->setCustomerNoteNotify(isset($data['comment_customer_notify']));
             }
-            $errorMessages = $this->getShipmentValidator()->validate($shipment, [QuantityValidator::class]);
-            if (!empty($errorMessages)) {
+            $validationResult = $this->getShipmentValidator()
+                ->validate($shipment, [QuantityValidator::class]);
+
+            if ($validationResult->hasMessages()) {
                 $this->messageManager->addError(
-                    __("Shipment Document Validation Error(s):\n" . implode("\n", $errorMessages))
+                    __("Shipment Document Validation Error(s):\n" . implode("\n", $validationResult->getMessages()))
                 );
                 $this->_redirect('*/*/new', ['order_id' => $this->getRequest()->getParam('order_id')]);
                 return;
@@ -140,7 +144,6 @@ class Save extends \Magento\Backend\App\Action
 
             $shipment->getOrder()->setCustomerNoteNotify(!empty($data['send_email']));
             $responseAjax = new \Magento\Framework\DataObject();
-            $isNeedCreateLabel = isset($data['create_shipping_label']) && $data['create_shipping_label'];
 
             if ($isNeedCreateLabel) {
                 $this->labelGenerator->create($shipment, $this->_request);
diff --git a/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/SaveTest.php b/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/SaveTest.php
index f8d9c06dc8ec05c07c699c4b22e7b830c796e4dc..b1d2fc0d1d74456593b4cb4e3248e965b2033958 100644
--- a/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/SaveTest.php
+++ b/app/code/Magento/Shipping/Test/Unit/Controller/Adminhtml/Order/Shipment/SaveTest.php
@@ -9,6 +9,7 @@
 namespace Magento\Shipping\Test\Unit\Controller\Adminhtml\Order\Shipment;
 
 use Magento\Backend\App\Action;
+use Magento\Sales\Model\ValidatorResultInterface;
 use Magento\Sales\Model\Order\Email\Sender\ShipmentSender;
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
 use Magento\Sales\Model\Order\Shipment\ShipmentValidatorInterface;
@@ -18,6 +19,7 @@ use Magento\Sales\Model\Order\Shipment\Validation\QuantityValidator;
  * Class SaveTest
  *
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ * @SuppressWarnings(PHPMD.TooManyFields)
  */
 class SaveTest extends \PHPUnit_Framework_TestCase
 {
@@ -96,6 +98,11 @@ class SaveTest extends \PHPUnit_Framework_TestCase
      */
     private $shipmentValidatorMock;
 
+    /**
+     * @var ValidatorResultInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $validationResult;
+
     /**
      * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
      */
@@ -107,6 +114,9 @@ class SaveTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->setMethods([])
             ->getMock();
+        $this->validationResult = $this->getMockBuilder(ValidatorResultInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $this->labelGenerator = $this->getMockBuilder(\Magento\Shipping\Model\Shipping\LabelGenerator::class)
             ->disableOriginalConstructor()
             ->setMethods([])
@@ -362,7 +372,11 @@ class SaveTest extends \PHPUnit_Framework_TestCase
             $this->shipmentValidatorMock->expects($this->once())
                 ->method('validate')
                 ->with($shipment, [QuantityValidator::class])
-                ->willReturn([]);
+                ->willReturn($this->validationResult);
+
+            $this->validationResult->expects($this->once())
+                ->method('hasMessages')
+                ->willReturn(false);
 
             $this->saveAction->execute();
             $this->assertEquals($this->response, $this->saveAction->getResponse());
diff --git a/app/code/Magento/Swatches/view/adminhtml/web/js/type-change.js b/app/code/Magento/Swatches/view/adminhtml/web/js/type-change.js
index c2f95f85b311d2b4532d240731b840d9d3df6f04..8172d6d9a5f3015464a1fba6561f5b79aba0cabc 100644
--- a/app/code/Magento/Swatches/view/adminhtml/web/js/type-change.js
+++ b/app/code/Magento/Swatches/view/adminhtml/web/js/type-change.js
@@ -3,7 +3,8 @@
  * See COPYING.txt for license details.
  */
 require([
-    'jquery'
+    'jquery',
+    'mage/translate'
 ], function ($) {
     'use strict';
 
diff --git a/app/code/Magento/Theme/view/adminhtml/templates/browser/content/uploader.phtml b/app/code/Magento/Theme/view/adminhtml/templates/browser/content/uploader.phtml
index 8bfeda24a0d2a2d34068ff228b2caa396d06f7af..2dacb6b70c1d95a4793ff461038f648fc3968419 100644
--- a/app/code/Magento/Theme/view/adminhtml/templates/browser/content/uploader.phtml
+++ b/app/code/Magento/Theme/view/adminhtml/templates/browser/content/uploader.phtml
@@ -33,7 +33,8 @@ require([
     'jquery',
     'mage/template',
     'jquery/file-uploader',
-    'domReady!'
+    'domReady!',
+    'mage/translate'
 ], function ($, mageTemplate) {
 
     $('#fileupload').fileupload({
diff --git a/app/code/Magento/Theme/view/frontend/web/js/view/messages.js b/app/code/Magento/Theme/view/frontend/web/js/view/messages.js
index 48507343fe28dc928edf9e6af2038bfe29577216..b707659fb3f4c790eef6df14fd8e6c9d68eeef1d 100644
--- a/app/code/Magento/Theme/view/frontend/web/js/view/messages.js
+++ b/app/code/Magento/Theme/view/frontend/web/js/view/messages.js
@@ -32,7 +32,7 @@ define([
                 customerData.set('messages', {});
             }
 
-            $.cookieStorage.setConf({path: '/', expires: -1}).set('mage-messages', null);
+            $.cookieStorage.set('mage-messages', '');
         }
     });
 });
diff --git a/app/code/Magento/Ui/Component/Form/Element/DataType/Date.php b/app/code/Magento/Ui/Component/Form/Element/DataType/Date.php
index c074fcc056fc371e2d76c3a9d3ffb2fda82d2508..e9c0c8d7685166001b524af995d62bf6b3c84011 100644
--- a/app/code/Magento/Ui/Component/Form/Element/DataType/Date.php
+++ b/app/code/Magento/Ui/Component/Form/Element/DataType/Date.php
@@ -60,18 +60,15 @@ class Date extends AbstractDataType
     public function prepare()
     {
         $config = $this->getData('config');
-
-        if (!isset($config['timeOffset'])) {
-            $config['timeOffset'] = (new \DateTime(
-                'now',
-                new \DateTimeZone(
-                    $this->localeDate->getConfigTimezone()
-                )
-            ))->getOffset();
+        if (!isset($config['storeTimeZone'])) {
+            $storeTimeZone = $this->localeDate->getConfigTimezone();
+            $config['storeTimeZone'] = $storeTimeZone;
         }
-
+        // Set date format pattern by current locale
+        $localeDateFormat = $this->localeDate->getDateFormat();
+        $config['options']['dateFormat'] = $localeDateFormat;
+        $config['outputDateFormat'] = $localeDateFormat;
         $this->setData('config', $config);
-
         parent::prepare();
     }
 
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Form/Element/DataType/DateTest.php b/app/code/Magento/Ui/Test/Unit/Component/Form/Element/DataType/DateTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7a9df1a7df0a42cf40e98b2c7b0f115d78d5301a
--- /dev/null
+++ b/app/code/Magento/Ui/Test/Unit/Component/Form/Element/DataType/DateTest.php
@@ -0,0 +1,137 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Test\Unit\Component\Form\Element\DataType;
+
+use Magento\Ui\Component\Form\Element\DataType\Date;
+use Magento\Framework\Stdlib\DateTime\TimezoneInterface;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Framework\View\Element\UiComponent\Context;
+use Magento\Framework\Locale\ResolverInterface;
+use Magento\Framework\View\Element\UiComponent\Processor;
+
+class DateTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    private $contextMock;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    private $localeDateMock;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    private $localeResolverMock;
+
+    /** @var \Magento\Ui\Component\Form\Element\DataType\Date  */
+    private $date;
+
+    /** @var  \PHPUnit_Framework_MockObject_MockObject */
+    private $processorMock;
+
+    /** @var  \Magento\Framework\TestFramework\Unit\Helper\ObjectManager */
+    private $objectManagerHelper;
+
+    public function setUp()
+    {
+        $this->contextMock = $this->getMock(Context::class, [], [], '', false);
+        $this->localeDateMock = $this->getMock(TimezoneInterface::class, [], [], '', false);
+        $this->localeResolverMock = $this->getMock(ResolverInterface::class, [], [], '', false);
+        $this->objectManagerHelper = new ObjectManager($this);
+        $this->processorMock = $this->getMock(Processor::class, [], [], '', false);
+        $this->contextMock->expects($this->any())->method('getProcessor')->willReturn($this->processorMock);
+    }
+
+    public function testPrepareWithTimeOffset()
+    {
+        $this->date = new Date(
+            $this->contextMock,
+            $this->localeDateMock,
+            $this->localeResolverMock,
+            [],
+            [
+                'config' => [
+                    'timeOffset' => 1,
+                ],
+            ]
+        );
+
+        $localeDateFormat = 'dd/MM/y';
+
+        $this->localeDateMock->expects($this->once())
+            ->method('getDateFormat')
+            ->willReturn($localeDateFormat);
+
+        $this->date->prepare();
+
+        $config = $this->date->getConfig();
+        $this->assertTrue(is_array($config));
+
+        $this->assertArrayHasKey('options', $config);
+        $this->assertArrayHasKey('dateFormat', $config['options']);
+        $this->assertEquals($localeDateFormat, $config['options']['dateFormat']);
+
+        $this->assertArrayHasKey('outputDateFormat', $config);
+        $this->assertEquals($localeDateFormat, $config['outputDateFormat']);
+    }
+
+    public function testPrepareWithoutTimeOffset()
+    {
+        $defaultDateFormat = 'MM/dd/y';
+
+        $this->date = new Date(
+            $this->contextMock,
+            $this->localeDateMock,
+            $this->localeResolverMock,
+            [],
+            [
+                'config' => [
+                    'options' => [
+                        'dateFormat' => $defaultDateFormat,
+                    ],
+                    'outputDateFormat' => $defaultDateFormat,
+                ],
+            ]
+        );
+
+        $localeDateFormat = 'dd/MM/y';
+
+        $this->localeDateMock->expects($this->once())
+            ->method('getDateFormat')
+            ->willReturn($localeDateFormat);
+        $this->localeDateMock->expects($this->any())
+            ->method('getConfigTimezone')
+            ->willReturn('America/Los_Angeles');
+
+        $this->date->prepare();
+
+        $config = $this->date->getConfig();
+        $this->assertTrue(is_array($config));
+
+        $this->assertArrayHasKey('options', $config);
+        $this->assertArrayHasKey('dateFormat', $config['options']);
+        $this->assertEquals($localeDateFormat, $config['options']['dateFormat']);
+
+        $this->assertArrayHasKey('outputDateFormat', $config);
+        $this->assertEquals($localeDateFormat, $config['outputDateFormat']);
+    }
+
+    /**
+     * This tests ensures that userTimeZone is properly saved in the configuration
+     */
+    public function testPrepare()
+    {
+        $this->date = $this->objectManagerHelper->getObject(
+            Date::class,
+            [
+                'context' => $this->contextMock,
+                'localeDate' => $this->localeDateMock,
+                'localeResolver' => $this->localeResolverMock
+            ]
+        );
+        $this->localeDateMock->expects($this->any())->method('getConfigTimezone')->willReturn('America/Chicago');
+        $this->date->prepare();
+        $configArray = $this->date->getData('config');
+        $this->assertEquals('America/Chicago', $configArray['storeTimeZone']);
+    }
+}
diff --git a/app/code/Magento/Ui/view/adminhtml/web/templates/modal/modal-prompt-content.html b/app/code/Magento/Ui/view/adminhtml/web/templates/modal/modal-prompt-content.html
new file mode 100644
index 0000000000000000000000000000000000000000..b02f5af71529dce32475a352f93ad9cb916c4bd1
--- /dev/null
+++ b/app/code/Magento/Ui/view/adminhtml/web/templates/modal/modal-prompt-content.html
@@ -0,0 +1,20 @@
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<form <%= formAttr %>>
+    <fieldset class="admin__fieldset">
+        <div class="admin__field admin__field-wide">
+            <% if(data.label){ %>
+            <label for="prompt-field-<%- data.id %>" class="admin__field-label">
+                <span><%= data.label %></span>
+            </label>
+            <% } %>
+            <div class="admin__field-control">
+                <input type="text" data-role="promptField" id="prompt-field-<%- data.id %>" class="admin__control-text" <%= inputAttr %>/>
+            </div>
+        </div>
+    </fieldset>
+</form>
diff --git a/app/code/Magento/Ui/view/base/layout/default.xml b/app/code/Magento/Ui/view/base/layout/default.xml
index 7f2efbd8558728f386856acb5dd38bd1c4dcbb31..64d5f1483a2f307b85966eccb316ad8ee782507a 100644
--- a/app/code/Magento/Ui/view/base/layout/default.xml
+++ b/app/code/Magento/Ui/view/base/layout/default.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
 -->
-<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
     <body>
         <referenceContainer name="after.body.start">
             <block class="Magento\Ui\Block\Logger" name="logger" template="Magento_Ui::logger.phtml"/>
diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js b/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js
index b7031f1df85c24edc1c68761bb370682eb5bfcd0..d0799aad750d9f776b495717c832c6b1cb89d754 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js
@@ -19,6 +19,9 @@ define([
             level: 0,
             visible: true,
             disabled: false,
+            listens: {
+                'opened': 'onVisibilityChange'
+            },
             additionalClasses: {}
         },
 
@@ -30,7 +33,19 @@ define([
             _.bindAll(this, 'onChildrenUpdate', 'onChildrenError', 'onContentLoading');
 
             return this._super()
-                       ._setClasses();
+                ._setClasses();
+        },
+
+        /**
+         * Initializes components' configuration.
+         *
+         * @returns {Fieldset} Chainable.
+         */
+        initConfig: function () {
+            this._super();
+            this._wasOpened = this.opened || !this.collapsible;
+
+            return this;
         },
 
         /**
@@ -117,6 +132,17 @@ define([
             return this;
         },
 
+        /**
+         * Handler of the "opened" property changes.
+         *
+         * @param {Boolean} isOpened
+         */
+        onVisibilityChange: function (isOpened) {
+            if (!this._wasOpened) {
+                this._wasOpened = isOpened;
+            }
+        },
+
         /**
          * Is being invoked on children validation error.
          * Sets error property to one incoming.
diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/date.js b/app/code/Magento/Ui/view/base/web/js/form/element/date.js
index 1c9f0b9b3e81c40fd07137af298e91b4c62412e4..fde7faa72ed7c9307e0b2781b7301d421efe2fc0 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/element/date.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/element/date.js
@@ -5,7 +5,8 @@
 define([
     'moment',
     'mageUtils',
-    './abstract'
+    './abstract',
+    'moment-timezone-with-data'
 ], function (moment, utils, Abstract) {
     'use strict';
 
@@ -13,7 +14,7 @@ define([
         defaults: {
             options: {},
 
-            timeOffset: 0,
+            storeTimeZone: 'UTC',
 
             validationParams: {
                 dateFormat: '${ $.outputDateFormat }'
@@ -61,7 +62,7 @@ define([
 
             /**
              * Date/time value shifted to corresponding timezone
-             * according to this.timeOffset property. This value
+             * according to this.storeTimeZone property. This value
              * will be sent to the server.
              *
              * @type {String}
@@ -109,7 +110,7 @@ define([
 
             if (value) {
                 if (this.options.showsTime) {
-                    shiftedValue = moment.utc(value).add(this.timeOffset, 'seconds');
+                    shiftedValue = moment.tz(value, 'UTC').tz(this.storeTimeZone);
                 } else {
                     dateFormat = this.shiftedValue() ? this.outputDateFormat : this.inputDateFormat;
 
@@ -133,12 +134,13 @@ define([
          * @param {String} shiftedValue
          */
         onShiftedValueChange: function (shiftedValue) {
-            var value;
+            var value,
+                formattedValue;
 
             if (shiftedValue) {
                 if (this.options.showsTime) {
-                    value = moment.utc(shiftedValue, this.pickerDateTimeFormat);
-                    value = value.subtract(this.timeOffset, 'seconds').toISOString();
+                    formattedValue = moment(shiftedValue).format('YYYY-MM-DD HH:mm');
+                    value = moment.tz(formattedValue, this.storeTimeZone).tz('UTC').toISOString();
                 } else {
                     value = moment(shiftedValue, this.pickerDateTimeFormat);
                     value = value.format(this.outputDateFormat);
diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js b/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js
index 393b0f04e512cb9df9dd509044b26c599fd170c0..be312c71f1fb20a1a2140765d598d8567bfaf648 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/element/ui-select.js
@@ -9,7 +9,8 @@ define([
     'Magento_Ui/js/lib/key-codes',
     'mage/translate',
     'ko',
-    'jquery'
+    'jquery',
+    'Magento_Ui/js/lib/view/utils/async'
 ], function (_, Abstract, keyCodes, $t, ko, $) {
     'use strict';
 
@@ -148,9 +149,14 @@ define([
             showPath: true,
             labelsDecoration: false,
             disableLabel: false,
+            filterRateLimit: 500,
             closeBtnLabel: $t('Done'),
             optgroupTmpl: 'ui/grid/filters/elements/ui-select-optgroup',
             quantityPlaceholder: $t('options'),
+            hoverClass: '_hover',
+            rootListSelector: 'ul.admin__action-multiselect-menu-inner._root',
+            visibleOptionSelector: 'li.admin__action-multiselect-menu-inner-item:visible',
+            actionTargetSelector: '.action-menu-item',
             selectedPlaceholders: {
                 defaultPlaceholder: $t('Select...'),
                 lotPlaceholders: $t('Selected')
@@ -179,6 +185,23 @@ define([
             }
         },
 
+        /**
+         * Initializes UISelect component.
+         *
+         * @returns {UISelect} Chainable.
+         */
+        initialize: function () {
+            this._super();
+
+            $.async(
+                this.rootListSelector,
+                this,
+                this.onRootListRender.bind(this)
+            );
+
+            return this;
+        },
+
         /**
          * Parses options and merges the result with instance
          * Set defaults according to mode and levels configuration
@@ -281,6 +304,8 @@ define([
                 'filterOptionsFocus'
             ]);
 
+            this.filterInputValue.extend({rateLimit: this.filterRateLimit});
+
             return this;
         },
 
@@ -307,17 +332,22 @@ define([
          * @returns {Boolean} level visibility.
          */
         showLevels: function (data) {
-            var curLevel = ++data.level;
+            var curLevel = ++data.level,
+                isVisible;
 
-            if (!data.visible) {
-                data.visible = ko.observable(!!data.hasOwnProperty(this.separator) &&
+            if (data.visible) {
+                isVisible = data.visible();
+            } else {
+                isVisible = !!data.hasOwnProperty(this.separator) &&
                     _.isBoolean(this.levelsVisibility) &&
                     this.levelsVisibility ||
-                    data.hasOwnProperty(this.separator) && parseInt(this.levelsVisibility, 10) >= curLevel);
+                    data.hasOwnProperty(this.separator) && parseInt(this.levelsVisibility, 10) >= curLevel;
 
+                data.visible = ko.observable(isVisible);
+                data.isVisited = isVisible;
             }
 
-            return data.visible();
+            return isVisible;
         },
 
         /**
@@ -398,7 +428,13 @@ define([
             var value = this.filterInputValue().trim().toLowerCase(),
                 array = [];
 
-            if (value === '') {
+            if (value && value.length < 2) {
+                return false;
+            }
+
+            this.cleanHoveredElement();
+
+            if (!value) {
                 this.renderPath = false;
                 this.options(this.cacheOptions.tree);
                 this._setItemsQuantity(false);
@@ -421,7 +457,6 @@ define([
                     this.options(array);
                     this._setItemsQuantity(array.length);
                 }
-                this.cleanHoveredElement();
 
                 return false;
             }
@@ -509,8 +544,12 @@ define([
          * @returns {Object} Chainable
          */
         cleanHoveredElement: function () {
-            if (!_.isNull(this.hoverElIndex())) {
-                this.hoverElIndex(null);
+            if (this.hoveredElement) {
+                $(this.hoveredElement)
+                    .children(this.actionTargetSelector)
+                    .removeClass(this.hoverClass);
+
+                this.hoveredElement = null;
             }
 
             return this;
@@ -543,14 +582,16 @@ define([
          * @return {Boolean}
          */
         isHovered: function (data) {
-            var index = this.getOptionIndex(data),
-                status = this.hoverElIndex() === index;
+            var element = this.hoveredElement,
+                elementData;
 
-            if (this.selectType === 'optgroup' && data.hasOwnProperty(this.separator)) {
+            if (!element) {
                 return false;
             }
 
-            return status;
+            elementData = ko.dataFor(this.hoveredElement);
+
+            return data.value === elementData.value;
         },
 
         /**
@@ -612,10 +653,10 @@ define([
          * Change visibility to child level
          *
          * @param {Object} data - element data
-         * @param {Object} elem - element
          */
-        openChildLevel: function (data, elem) {
-            var contextElement;
+        openChildLevel: function (data) {
+            var contextElement = data,
+                isVisible;
 
             if (
                 this.openLevelsAction &&
@@ -623,8 +664,13 @@ define([
                 this.openLevelsAction &&
                 data.hasOwnProperty(this.separator) && parseInt(this.levelsVisibility, 10) <= data.level
             ) {
-                contextElement = ko.contextFor($(elem).parents('li').children('ul')[0]).$data.current;
-                contextElement.visible(!contextElement.visible());
+                isVisible = !contextElement.visible();
+
+                if (isVisible && !contextElement.isVisited) {
+                    contextElement.isVisited = true;
+                }
+
+                contextElement.visible(isVisible);
             }
         },
 
@@ -642,25 +688,23 @@ define([
         },
 
         /**
-         * Add hover to some list element and clears element ID to variable
+         * @deprecated
+         */
+        onMousemove: function () {},
+
+        /**
+         * Handles hover on list items.
          *
-         * @param {Object} data - object with data about this element
-         * @param {Number} index - element index
          * @param {Object} event - mousemove event
          */
-        onMousemove: function (data, index, event) {
-            var id,
-                context = ko.contextFor(event.target);
-
-            if (this.isCursorPositionChange(event)) {
-                return false;
-            }
+        onDelegatedMouseMouve: function (event) {
+            var target = $(event.currentTarget).closest(this.visibleOptionSelector)[0];
 
-            if (typeof context.$data === 'object') {
-                id = this.getOptionIndex(context.$data);
+            if (this.isCursorPositionChange(event) || this.hoveredElement === target) {
+                return;
             }
 
-            id !== this.hoverElIndex() ? this.hoverElIndex(id) : false;
+            this._hoverTo(target);
             this.setCursorPosition(event);
         },
 
@@ -736,8 +780,8 @@ define([
             }
 
             if (this.listVisible()) {
-                if (!_.isNull(this.hoverElIndex())) {
-                    this.toggleOptionSelected(this.cacheOptions.plain[this.hoverElIndex()]);
+                if (this.hoveredElement) {
+                    this.toggleOptionSelected(ko.dataFor(this.hoveredElement));
                 }
             } else {
                 this.setListVisible(true);
@@ -756,35 +800,7 @@ define([
          * selected first option in list
          */
         pageDownKeyHandler: function () {
-            var el,
-                nextEl,
-                nextData,
-                nextIndex;
-
-            if (!this.listVisible()) {
-                return false;
-            }
-
-            if (this.filterInputValue()) {
-                el = !_.isNull(this.hoverElIndex()) ?
-                    this._getElemByData(this.cacheOptions.plain[this.hoverElIndex()]) : false;
-                nextEl = el ? el.next() : $(this.cacheUiSelect).find('li:visible').eq(0);
-                nextIndex = nextEl.length ? nextEl.index() : 0;
-                nextData = this.options()[nextIndex];
-                this.hoverElIndex(this.getOptionIndex(nextData));
-
-                return false;
-            }
-
-            if (!_.isNull(this.hoverElIndex()) && this.hoverElIndex() !== this.cacheOptions.plain.length - 1) {
-                this._setHoverToElement(1);
-                this._scrollTo(this.hoverElIndex());
-
-                return false;
-            }
-
-            this._setHoverToElement(1, -1);
-            this._scrollTo(this.hoverElIndex());
+            this._setHoverToElement(1);
         },
 
         /**
@@ -813,28 +829,19 @@ define([
          * Set hover to visible element
          *
          * @param {Number} direction - iterator
-         * @param {Number} index - current hovered element
-         * @param {Array} list - collection items
          */
-        _setHoverToElement: function (direction, index, list) {
-            var modifiedIndex,
-                curData,
-                canBeHovered = true;
-
-            list = list || $(this.cacheUiSelect).find('li');
-            index = index || _.isNumber(index) ? index : this.hoverElIndex();
-            modifiedIndex = index + direction;
-            modifiedIndex < 0 ? modifiedIndex = this.cacheOptions.plain.length - 1 : false;
-            curData = this.cacheOptions.plain[modifiedIndex];
+        _setHoverToElement: function (direction) {
+            var element;
 
-            if (this.selectType === 'optgroup' && !_.findWhere(this.cacheOptions.lastOptions, {value: curData.value})) {
-                canBeHovered = false;
+            if (direction ===  1) {
+                element = this._getNextElement();
+            } else if (direction === -1) {
+                element = this._getPreviousElement();
             }
 
-            if (list.eq(modifiedIndex).is(':visible') && canBeHovered) {
-                this.hoverElIndex(modifiedIndex);
-            } else {
-                this._setHoverToElement(direction, modifiedIndex, list);
+            if (element) {
+                this._hoverTo(element);
+                this._scrollTo(element);
             }
         },
 
@@ -844,18 +851,15 @@ define([
          *
          * @param {Number} index - element index
          */
-        _scrollTo: function (index) {
-            var curEl,
-                parents,
-                wrapper,
+        _scrollTo: function (element) {
+            var curEl = $(element).children(this.actionTargetSelector),
+                wrapper = $(this.rootList),
                 curElPos = {},
                 wrapperPos = {};
 
-            curEl = $(this.cacheUiSelect).find('li').eq(index);
-            parents = curEl.parents('ul');
-            wrapper = parents.eq(parents.length - 1);
             curElPos.start = curEl.offset().top;
-            curElPos.end = curElPos.start + curEl.height();
+            curElPos.end = curElPos.start + curEl.outerHeight();
+
             wrapperPos.start = wrapper.offset().top;
             wrapperPos.end = wrapperPos.start + wrapper.height();
 
@@ -871,46 +875,7 @@ define([
          * selected last option in list
          */
         pageUpKeyHandler: function () {
-            var el,
-                nextEl,
-                nextIndex,
-                nextData;
-
-            if (!this.listVisible()) {
-                return false;
-            }
-
-            if (this.filterInputValue()) {
-                el = !_.isNull(this.hoverElIndex()) ?
-                    this._getElemByData(this.cacheOptions.plain[this.hoverElIndex()]) : false;
-                nextEl = el ? el.prev() : $(this.cacheUiSelect).find('li:visible').eq(this.options().length-1);
-                nextIndex = nextEl.length ? nextEl.index() : this.options().length-1;
-                nextData = this.options()[nextIndex];
-                this.hoverElIndex(this.getOptionIndex(nextData));
-
-                return false;
-            }
-
-
-            if (this.filterInputValue()) {
-                el = !_.isNull(this.hoverElIndex()) ?
-                    this._getElemByData(this.cacheOptions.plain[this.hoverElIndex()]) : false;
-                nextEl = el ? el.next() : $(this.cacheUiSelect).find('li:visible').eq(0);
-                nextIndex = nextEl.length ? nextEl.index() : 0;
-                nextData = this.options()[nextIndex];
-                this.hoverElIndex(this.getOptionIndex(nextData));
-
-                return false;
-            }
-
-            if (this.hoverElIndex()) {
-                this._setHoverToElement(-1);
-                this._scrollTo(this.hoverElIndex());
-
-                return false;
-            }
-            this._setHoverToElement(-1, this.cacheOptions.plain.length);
-            this._scrollTo(this.hoverElIndex());
+            this._setHoverToElement(-1);
         },
 
         /**
@@ -990,6 +955,129 @@ define([
             return selected.map(function (option) {
                 return option.label;
             }).join(', ');
+        },
+
+        /**
+         * Defines previous option element to
+         * the one that is currently hovered.
+         *
+         * @returns {Element}
+         */
+        _getPreviousElement: function () {
+            var currentElement = this.hoveredElement,
+                lastElement    = this._getLastIn(this.rootList),
+                previousElement;
+
+            if (!currentElement) {
+                return lastElement;
+            }
+
+            previousElement = $(currentElement).prev()[0];
+
+            return (
+                this._getLastIn(previousElement) ||
+                previousElement ||
+                this._getFirstParentOf(currentElement) ||
+                lastElement
+            );
+        },
+
+        /**
+         * Defines next option element to
+         * the one that is currently hovered.
+         *
+         * @returns {Element}
+         */
+        _getNextElement: function () {
+            var currentElement = this.hoveredElement,
+                firstElement   = this._getFirstIn(this.rootList);
+
+            if (!currentElement) {
+                return firstElement;
+            }
+
+            return (
+                this._getFirstIn(currentElement) ||
+                $(currentElement).next()[0] ||
+                this._getParentsOf(currentElement).next()[0] ||
+                firstElement
+            );
+        },
+
+        /**
+         * Returns first option element in provided scope.
+         *
+         * @param {Element} scope
+         * @returns {Element}
+         */
+        _getFirstIn: function (scope) {
+            return $(scope).find(this.visibleOptionSelector)[0];
+        },
+
+        /**
+         * Returns last descendant option element in provided scope.
+         *
+         * @param {Element} scope
+         * @returns {Element}
+         */
+        _getLastIn: function (scope) {
+            return $(scope).find(this.visibleOptionSelector).last()[0];
+        },
+
+        /**
+         * Returns a collection of parent option elements.
+         *
+         * @param {Element} scope
+         * @returns {jQueryCollection}
+         */
+        _getParentsOf: function (scope) {
+            return $(scope).parents(this.visibleOptionSelector);
+        },
+
+        /**
+         * Returns first parent option element.
+         *
+         * @param {Element} scope
+         * @returns {Element}
+         */
+        _getFirstParentOf: function (scope) {
+            return this._getParentsOf(scope)[0];
+        },
+
+        /**
+         * Sets hover class to provided option element.
+         *
+         * @param {Element} element
+         */
+        _hoverTo: function(element) {
+            if (this.hoveredElement) {
+                $(this.hoveredElement)
+                    .children(this.actionTargetSelector)
+                    .removeClass(this.hoverClass);
+            }
+
+            $(element)
+                .children(this.actionTargetSelector)
+                .addClass(this.hoverClass);
+
+            this.hoveredElement = element;
+        },
+
+        /**
+         * Callback which fires when root list element is rendered.
+         *
+         * @param {Element} element
+         */
+        onRootListRender: function (element) {
+            var targetSelector = 'li > ' + this.actionTargetSelector;
+
+            this.rootList = element;
+
+            $(this.rootList).on(
+                'mousemove',
+                targetSelector,
+                this.onDelegatedMouseMouve.bind(this)
+            );
         }
     });
 });
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/thumbnail.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/thumbnail.js
index 32247e03baa047133b438d774e0979f3a9f5284b..f4bde3969e00689a87d34e412ea2ce33c6b0661c 100644
--- a/app/code/Magento/Ui/view/base/web/js/grid/columns/thumbnail.js
+++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/thumbnail.js
@@ -7,7 +7,8 @@ define([
     'jquery',
     'mage/template',
     'text!Magento_Ui/templates/grid/cells/thumbnail/preview.html',
-    'Magento_Ui/js/modal/modal'
+    'Magento_Ui/js/modal/modal',
+    'mage/translate'
 ], function (Column, $, mageTemplate, thumbnailPreviewTemplate) {
     'use strict';
 
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/provider.js b/app/code/Magento/Ui/view/base/web/js/grid/provider.js
index 92a4a6fd38cc52ce93f4cce45dc823f5fa15d64e..7bca45d0253d047b056e7915d10a7ede491f93b6 100644
--- a/app/code/Magento/Ui/view/base/web/js/grid/provider.js
+++ b/app/code/Magento/Ui/view/base/web/js/grid/provider.js
@@ -43,6 +43,10 @@ define([
                 .initStorage()
                 .clearData();
 
+            // Load data when there will
+            // be no more pending assets.
+            resolver(this.reload, this);
+
             return this;
         },
 
@@ -122,9 +126,11 @@ define([
          * Handles changes of 'params' object.
          */
         onParamsChange: function () {
-            this.firstLoad ?
-                resolver(this.reload, this) :
+            // It's necessary to make a reload only
+            // after the initial loading has been made.
+            if (!this.firstLoad) {
                 this.reload();
+            }
         },
 
         /**
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/datepicker.js b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/datepicker.js
index 8f0fb7b007caf2aac8a2a59cf7f64849d61a5023..16c102b8367f4b8762030057c4d249adb132693b 100644
--- a/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/datepicker.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/knockout/bindings/datepicker.js
@@ -8,8 +8,10 @@ define([
     'underscore',
     'jquery',
     'mage/translate',
-    'mage/calendar'
-], function (ko, _, $, $t) {
+    'mage/calendar',
+    'moment',
+    'mageUtils'
+], function (ko, _, $, $t, calendar, moment, utils) {
     'use strict';
 
     var defaults = {
@@ -46,7 +48,12 @@ define([
             }
 
             $(el).calendar(options);
-            observable() && $(el).datepicker('setDate', observable());
+
+            observable() && $(el).datepicker(
+                'setDate',
+                moment(observable(), utils.normalizeDate(config.options.dateFormat)).toDate()
+            );
+
             $(el).blur();
 
             ko.utils.registerEventHandler(el, 'change', function () {
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js b/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js
index 71f2834190436123e34c31bd4e7219ecc4d9f7e4..1f031a3aefcbdd6f9f0bcc29f2654edd51c41b6d 100644
--- a/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js
@@ -9,8 +9,9 @@ define([
     'moment',
     'jquery/validate',
     'jquery/ui',
-    'mage/translate'
-], function ($, _, utils, moment) {
+    'mage/translate',
+    'mageUtils'
+], function ($, _, utils, moment, validate, ui, $t, mageUtils) {
     'use strict';
 
     /**
@@ -430,10 +431,10 @@ define([
                 var pass = $.trim(v);
                 var result = pass.length >= passwordMinLength;
                 if (result == false) {
-                    validator.passwordErrorMessage = $.mage.__(
-                        "Minimum length of this field must be equal or greater than %1 symbols." +
-                        " Leading and trailing spaces will be ignored."
-                    ).replace('%1', passwordMinLength);
+                    /*eslint-disable max-len*/
+                    validator.passwordErrorMessage = $.mage.__('Minimum length of this field must be equal or greater than %1 symbols. Leading and trailing spaces will be ignored.').replace('%1', passwordMinLength);
+
+                    /*eslint-enable max-len*/
                     return result;
                 }
                 if (pass.match(/\d+/)) {
@@ -450,10 +451,11 @@ define([
                 }
                 if (counter < passwordMinCharacterSets) {
                     result = false;
-                    validator.passwordErrorMessage = $.mage.__(
-                        "Minimum of different classes of characters in password is %1." +
-                        " Classes of characters: Lower Case, Upper Case, Digits, Special Characters."
-                    ).replace('%1', passwordMinCharacterSets);
+
+                    /*eslint-disable max-len*/
+                    validator.passwordErrorMessage = $.mage.__('Minimum of different classes of characters in password is %1. Classes of characters: Lower Case, Upper Case, Digits, Special Characters.').replace('%1', passwordMinCharacterSets);
+
+                    /*eslint-enable max-len*/
                 }
                 return result;
             }, function () {
@@ -682,9 +684,9 @@ define([
             $.mage.__('Please use only letters (a-z or A-Z) or numbers (0-9) in this field. No spaces or other characters are allowed.')
         ],
         "validate-date": [
-            function(value) {
-                var test = new Date(value);
-                return utils.isEmptyNoTrim(value) || !isNaN(test);
+            function(value, params, additionalParams) {
+                var test = moment(value, additionalParams.dateFormat);
+                return utils.isEmptyNoTrim(value) || test.isValid();
             },$.mage.__('Please enter a valid date.')
 
         ],
@@ -741,7 +743,8 @@ define([
                     }
                 }
                 return true;
-            }, "Please enter valid email addresses, separated by commas. For example, johndoe@domain.com, johnsmith@domain.com."
+            },
+            $.mage.__('Please enter valid email addresses, separated by commas. For example, johndoe@domain.com, johnsmith@domain.com.')
         ],
         "validate-cc-number": [
             /**
diff --git a/app/code/Magento/Ui/view/base/web/js/modal/modal.js b/app/code/Magento/Ui/view/base/web/js/modal/modal.js
index 759ea3be5e624b29dcd6b8a11bb933fbf01293b6..ab9dc497517746ce3d6570c105ef8e75abc0743a 100644
--- a/app/code/Magento/Ui/view/base/web/js/modal/modal.js
+++ b/app/code/Magento/Ui/view/base/web/js/modal/modal.js
@@ -42,6 +42,7 @@ define([
      */
     $.widget('mage.modal', {
         options: {
+            id: null,
             type: 'popup',
             title: '',
             subTitle: '',
@@ -121,6 +122,7 @@ define([
                 'closeModal'
             );
 
+            this.options.id = this.uuid;
             this.options.transitionEvent = transitionEvent;
             this._createWrapper();
             this._renderModal();
diff --git a/app/code/Magento/Ui/view/base/web/js/modal/prompt.js b/app/code/Magento/Ui/view/base/web/js/modal/prompt.js
index 17e78c0ea311bf702cf76abd3f4c62c7d86b7dd2..d32605d2db4f9d8eefb2da058aad37ff988bd975 100644
--- a/app/code/Magento/Ui/view/base/web/js/modal/prompt.js
+++ b/app/code/Magento/Ui/view/base/web/js/modal/prompt.js
@@ -6,19 +6,24 @@
 define([
     'jquery',
     'underscore',
+    'mage/template',
+    'text!ui/template/modal/modal-prompt-content.html',
     'jquery/ui',
     'Magento_Ui/js/modal/modal',
     'mage/translate'
-], function ($, _) {
+], function ($, _, template, promptContentTmpl) {
     'use strict';
 
     $.widget('mage.prompt', $.mage.modal, {
         options: {
             modalClass: 'prompt',
+            promptContentTmpl: promptContentTmpl,
             promptField: '[data-role="promptField"]',
             attributesForm: {},
             attributesField: {},
             value: '',
+            validation: false,
+            validationRules: [],
             actions: {
 
                 /**
@@ -64,61 +69,73 @@ define([
          */
         _create: function () {
             this.options.focus = this.options.promptField;
+            this.options.validation = this.options.validation && this.options.validationRules.length;
             this._super();
-            this.modal.find(this.options.modalContent).append(this.getFieldTemplate());
+            this.modal.find(this.options.modalContent).append(this.getFormTemplate());
             this.modal.find(this.options.modalCloseBtn).off().on('click',  _.bind(this.closeModal, this, false));
+
+            if (this.options.validation) {
+                this.setValidationClasses();
+            }
+
             this.openModal();
         },
 
         /**
-         * Field template getter.
+         * Form template getter.
          *
-         * @returns {Object} Field template
+         * @returns {Object} Form template.
          */
-        getFieldTemplate: function () {
-            var input = '<input data-role="promptField" id="prompt-field" class="admin__control-text" type="text"/>',
-                form = '<form/>',
-                wrapper = '<div class="prompt-message"/>',
-                $wrapper = $(wrapper),
-                $form = $(form),
-                $input = $(input),
+        getFormTemplate: function () {
+            var formTemplate,
+                formAttr = '',
+                inputAttr = '',
                 attributeName;
 
-            for (attributeName in this.options.attributesField) {
-                if (this.options.attributesField.hasOwnProperty(attributeName)) {
-                    $input.attr(attributeName, this.options.attributesField[attributeName]);
+            for (attributeName in this.options.attributesForm) {
+                if (this.options.attributesForm.hasOwnProperty(attributeName)) {
+                    formAttr = formAttr + ' ' + attributeName + '="' +
+                        this.options.attributesForm[attributeName] + '"';
                 }
             }
 
-            for (attributeName in this.options.attributesForm) {
-                if (this.options.attributesForm.hasOwnProperty(attributeName)) {
-                    $form.attr(attributeName, this.options.attributesForm[attributeName]);
+            for (attributeName in this.options.attributesField) {
+                if (this.options.attributesField.hasOwnProperty(attributeName)) {
+                    inputAttr = inputAttr + ' ' + attributeName + '="' +
+                        this.options.attributesField[attributeName] + '"';
                 }
             }
 
-            $form.append($input);
+            formTemplate = $(template(this.options.promptContentTmpl, {
+                data: this.options,
+                formAttr: formAttr,
+                inputAttr: inputAttr
+            }));
 
-            return $wrapper.append($form);
+            return formTemplate;
         },
 
         /**
-         * Compile template and append to wrapper.
+         * Remove widget
          */
-        _renderModal: function () {
-            this._super();
-
-            if (this.options.label) {
-                this.element.append(this.options.label);
-            }
+        _remove: function () {
+            this.modal.remove();
+        },
 
-            this.element.wrap('<label for="prompt-field"></label>');
+        /**
+         * Validate prompt field
+         */
+        validate: function () {
+            return $.validator.validateSingleElement(this.options.promptField);
         },
 
         /**
-         * Remove widget
+         * Add validation classes to prompt field
          */
-        _remove: function () {
-            this.modal.remove();
+        setValidationClasses: function () {
+            this.modal.find(this.options.promptField).attr('class', $.proxy(function (i, val) {
+                return val + ' ' + this.options.validationRules.join(' ');
+            }, this));
         },
 
         /**
@@ -136,11 +153,16 @@ define([
             var value;
 
             if (result) {
+                if (this.options.validation && !this.validate()) {
+                    return false;
+                }
+
                 value = this.modal.find(this.options.promptField).val();
-                this.options.actions.confirm(value);
+                this.options.actions.confirm.call(this, value);
             } else {
                 this.options.actions.cancel.call(this, result);
             }
+
             this.options.actions.always();
             this.element.bind('promptclosed', _.bind(this._remove, this));
 
@@ -149,6 +171,6 @@ define([
     });
 
     return function (config) {
-        return $('<div></div>').html(config.content).prompt(config);
+        return $('<div class="prompt-message"></div>').html(config.content).prompt(config);
     };
 });
diff --git a/app/code/Magento/Ui/view/base/web/templates/form/fieldset.html b/app/code/Magento/Ui/view/base/web/templates/form/fieldset.html
index b45e5385d037ac9b4cecca6888a7318e6ec8e384..6cb7fb62b3a911309797333c12f33435850243cb 100644
--- a/app/code/Magento/Ui/view/base/web/templates/form/fieldset.html
+++ b/app/code/Magento/Ui/view/base/web/templates/form/fieldset.html
@@ -9,7 +9,8 @@
      attr="'data-level': $data.level, 'data-index': index"
      data-bind="visible: $data.visible === undefined ? true: $data.visible">
     <div class="fieldset-wrapper-title"
-         attr="tabindex: !collapsible ? -1 : 0"
+         attr="tabindex: !collapsible ? -1 : 0,
+               'data-state-collapsible': collapsible ? opened() ? 'open' : 'closed' : null"
          click="toggleOpened"
          keyboard="13: toggleOpened"
          if="label">
@@ -30,7 +31,7 @@
                 <span class="admin__page-nav-item-message _error">
                     <span class="admin__page-nav-item-message-icon"></span>
                     <span class="admin__page-nav-item-message-tooltip"
-                            data-bind="i18n: 'This tab contains invalid data. Please resolve this before saving.'">
+                          data-bind="i18n: 'This tab contains invalid data. Please resolve this before saving.'">
                     </span>
                 </span>
                 <span class="admin__page-nav-item-message-loader">
@@ -43,7 +44,10 @@
     </div>
 
     <div class="admin__fieldset-wrapper-content"
-         css="'admin__collapsible-content': collapsible, '_show': opened, '_hide': !opened">
-        <fieldset class="admin__fieldset" each="data: elems, as: 'element'" render=""/>
+         css="'admin__collapsible-content': collapsible, '_show': opened, '_hide': !opened()">
+        <fieldset
+                if="opened() || _wasOpened"
+                class="admin__fieldset"
+                each="data: elems, as: 'element'" render=""/>
     </div>
 </div>
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select-optgroup.html b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select-optgroup.html
index 506aa4381c9b816bb4608802732bb7ffed3c3a46..5f938b6e343128e4d3700d605234eec16a216f47 100644
--- a/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select-optgroup.html
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select-optgroup.html
@@ -10,6 +10,7 @@
     attr: {
         'data-level': $data.current.level++
     }">
+    <!-- ko if: $data.current.visible() || $data.current.isVisited  -->
     <!-- ko foreach: { data: $data.current.optgroup, as: 'option'}  -->
     <li class="admin__action-multiselect-menu-inner-item"
         data-bind="css: { _parent: $data.optgroup }">
@@ -56,4 +57,5 @@
         <!-- /ko-->
     </li>
     <!-- /ko -->
+    <!-- /ko -->
 </ul>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select.html b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select.html
index a913d27c8aa5aeba6968ab6283dc4717e65e3a9d..fae89160e138e8d56ba6a99a34f5957d36f6a35b 100644
--- a/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select.html
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/filters/elements/ui-select.html
@@ -178,4 +178,4 @@
         </div>
         <!-- /ko -->
     </div>
-</div>
+</div>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/modal/modal-component.html b/app/code/Magento/Ui/view/base/web/templates/modal/modal-component.html
index c856f9fd68d077b3df7b9d3692a5406915c1e41e..8b45955b5a480363ac05fb5fee3cd4e50632a446 100644
--- a/app/code/Magento/Ui/view/base/web/templates/modal/modal-component.html
+++ b/app/code/Magento/Ui/view/base/web/templates/modal/modal-component.html
@@ -4,9 +4,6 @@
  * See COPYING.txt for license details.
  */
 -->
-
-<div data-bind="css: modalClass, hasFocus: focused">
-    <!-- ko foreach: { data: elems, as: 'element' } -->
-        <!-- ko template: element.getTemplate() --><!-- /ko -->
-    <!-- /ko -->
+<div css="modalClass" hasFocus="focused">
+    <each if="state() || $data.modal" args="data: elems, as: 'element'" render=""/>
 </div>
diff --git a/app/code/Magento/Ui/view/base/web/templates/modal/modal-prompt-content.html b/app/code/Magento/Ui/view/base/web/templates/modal/modal-prompt-content.html
new file mode 100644
index 0000000000000000000000000000000000000000..b5b2693ef3664e353385bddd10de1b046a99dc10
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/modal/modal-prompt-content.html
@@ -0,0 +1,20 @@
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<form <%= formAttr %>>
+    <fieldset class="fieldset">
+        <div class="field">
+            <% if(data.label){ %>
+            <label for="prompt-field-<%- data.id %>" class="label">
+                <span><%= data.label %></span>
+            </label>
+            <% } %>
+            <div class="control">
+                <input type="text" data-role="promptField" id="prompt-field-<%- data.id %>" class="input-text" <%= inputAttr %>/>
+            </div>
+        </div>
+    </fieldset>
+</form>
diff --git a/app/code/Magento/Vault/Api/PaymentMethodListInterface.php b/app/code/Magento/Vault/Api/PaymentMethodListInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..f9d3e628594ef0f809429f39564271e6f52e7b23
--- /dev/null
+++ b/app/code/Magento/Vault/Api/PaymentMethodListInterface.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Vault\Api;
+
+use Magento\Vault\Model\VaultPaymentInterface;
+
+/**
+ * Contains methods to retrieve vault payment methods
+ * This interface is consistent with \Magento\Payment\Api\PaymentMethodListInterface
+ * @api
+ */
+interface PaymentMethodListInterface
+{
+    /**
+     * Get list of available vault payments
+     * @param int $storeId
+     * @return VaultPaymentInterface[]
+     */
+    public function getList($storeId);
+
+    /**
+     * Get list of enabled in the configuration vault payments
+     * @param int $storeId
+     * @return VaultPaymentInterface[]
+     */
+    public function getActiveList($storeId);
+}
diff --git a/app/code/Magento/Vault/Model/Method/Vault.php b/app/code/Magento/Vault/Model/Method/Vault.php
index ce85936607192b81fcdd9da59fb48704fc92d48e..41a2d6b0e26efcd1c6745f5d5fbc2842ae6c8513 100644
--- a/app/code/Magento/Vault/Model/Method/Vault.php
+++ b/app/code/Magento/Vault/Model/Method/Vault.php
@@ -457,13 +457,13 @@ final class Vault implements VaultPaymentInterface
     private function attachTokenExtensionAttribute(OrderPaymentInterface $orderPayment)
     {
         $additionalInformation = $orderPayment->getAdditionalInformation();
-        if (empty($additionalInformation[PaymentTokenInterface::CUSTOMER_ID]) ||
-            empty($additionalInformation[PaymentTokenInterface::PUBLIC_HASH])
-        ) {
-            throw new \LogicException('Customer id and public hash should be defined');
+        if (empty($additionalInformation[PaymentTokenInterface::PUBLIC_HASH])) {
+            throw new \LogicException('Public hash should be defined');
         }
 
-        $customerId = $additionalInformation[PaymentTokenInterface::CUSTOMER_ID];
+        $customerId = isset($additionalInformation[PaymentTokenInterface::CUSTOMER_ID]) ?
+            $additionalInformation[PaymentTokenInterface::CUSTOMER_ID] : null;
+
         $publicHash = $additionalInformation[PaymentTokenInterface::PUBLIC_HASH];
 
         $paymentToken = $this->tokenManagement->getByPublicHash($publicHash, $customerId);
diff --git a/app/code/Magento/Vault/Model/PaymentMethodList.php b/app/code/Magento/Vault/Model/PaymentMethodList.php
new file mode 100644
index 0000000000000000000000000000000000000000..bec073df7971154ee74cd0b794d4cd11d347c832
--- /dev/null
+++ b/app/code/Magento/Vault/Model/PaymentMethodList.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Vault\Model;
+
+use Magento\Payment\Api\Data\PaymentMethodInterface;
+use Magento\Payment\Api\PaymentMethodListInterface;
+use Magento\Payment\Model\Method\InstanceFactory;
+use Magento\Payment\Model\MethodInterface;
+use Magento\Vault\Api\PaymentMethodListInterface as VaultPaymentMethodListInterface;
+
+/**
+ * Contains methods to retrieve configured vault payments
+ */
+class PaymentMethodList implements VaultPaymentMethodListInterface
+{
+    /**
+     * @var InstanceFactory
+     */
+    private $instanceFactory;
+
+    /**
+     * @var PaymentMethodListInterface
+     */
+    private $paymentMethodList;
+
+    /**
+     * PaymentMethodList constructor.
+     * @param PaymentMethodListInterface $paymentMethodList
+     * @param InstanceFactory $instanceFactory
+     */
+    public function __construct(PaymentMethodListInterface $paymentMethodList, InstanceFactory $instanceFactory)
+    {
+        $this->instanceFactory = $instanceFactory;
+        $this->paymentMethodList = $paymentMethodList;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getList($storeId)
+    {
+        return $this->filterList($this->paymentMethodList->getList($storeId));
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getActiveList($storeId)
+    {
+        return $this->filterList($this->paymentMethodList->getActiveList($storeId));
+    }
+
+    /**
+     * Filter vault methods from payments
+     * @param PaymentMethodInterface[] $list
+     * @return VaultPaymentInterface[]
+     */
+    private function filterList(array $list)
+    {
+        $paymentMethods = array_map(
+            function (PaymentMethodInterface $paymentMethod) {
+                return $this->instanceFactory->create($paymentMethod);
+            },
+            $list
+        );
+
+        $availableMethods = array_filter(
+            $paymentMethods,
+            function (MethodInterface $methodInstance) {
+                return $methodInstance instanceof VaultPaymentInterface;
+            }
+        );
+        return array_values($availableMethods);
+    }
+}
diff --git a/app/code/Magento/Vault/Model/Ui/TokensConfigProvider.php b/app/code/Magento/Vault/Model/Ui/TokensConfigProvider.php
index 6a86ed694642c31407ba0c08e3ac39f646244cca..40343c29620e1a5c9ecc6e9779baf77336a09481 100644
--- a/app/code/Magento/Vault/Model/Ui/TokensConfigProvider.php
+++ b/app/code/Magento/Vault/Model/Ui/TokensConfigProvider.php
@@ -7,10 +7,9 @@ namespace Magento\Vault\Model\Ui;
 
 use Magento\Checkout\Model\ConfigProviderInterface;
 use Magento\Framework\App\ObjectManager;
-use Magento\Payment\Api\Data\PaymentMethodInterface;
 use Magento\Store\Model\StoreManagerInterface;
+use Magento\Vault\Api\PaymentMethodListInterface;
 use Magento\Vault\Model\CustomerTokenManagement;
-use Magento\Vault\Model\VaultPaymentInterface;
 
 /**
  * Class ConfigProvider
@@ -39,14 +38,9 @@ final class TokensConfigProvider implements ConfigProviderInterface
     private $customerTokenManagement;
 
     /**
-     * @var \Magento\Payment\Api\PaymentMethodListInterface
+     * @var PaymentMethodListInterface
      */
-    private $paymentMethodList;
-
-    /**
-     * @var \Magento\Payment\Model\Method\InstanceFactory
-     */
-    private $paymentMethodInstanceFactory;
+    private $vaultPaymentList;
 
     /**
      * Constructor
@@ -89,8 +83,10 @@ final class TokensConfigProvider implements ConfigProviderInterface
 
             $componentProvider = $providers[$paymentCode];
             $component = $componentProvider->getComponentForToken($token);
-            $vaultPayments[$paymentCode . '_item_' . $i] = [
-                'config' => $component->getConfig(),
+            $config = $component->getConfig();
+            $vaultPaymentCode = !empty($config['code']) ? $config['code'] : $paymentCode;
+            $vaultPayments[$vaultPaymentCode . '_' . $i] = [
+                'config' => $config,
                 'component' => $component->getName()
             ];
         }
@@ -110,7 +106,8 @@ final class TokensConfigProvider implements ConfigProviderInterface
     private function getComponentProviders()
     {
         $providers = [];
-        $vaultPaymentMethods = $this->getVaultPaymentMethodList();
+        $storeId = $this->storeManager->getStore()->getId();
+        $vaultPaymentMethods = $this->getVaultPaymentList()->getActiveList($storeId);
 
         foreach ($vaultPaymentMethods as $method) {
             $providerCode = $method->getProviderCode();
@@ -139,60 +136,15 @@ final class TokensConfigProvider implements ConfigProviderInterface
     }
 
     /**
-     * Get list of active Vault payment methods.
-     *
-     * @return VaultPaymentInterface[]
-     */
-    private function getVaultPaymentMethodList()
-    {
-        $storeId = $this->storeManager->getStore()->getId();
-
-        $paymentMethods = array_map(
-            function (PaymentMethodInterface $paymentMethod) {
-                return $this->getPaymentMethodInstanceFactory()->create($paymentMethod);
-            },
-            $this->getPaymentMethodList()->getActiveList($storeId)
-        );
-
-        $availableMethods = array_filter(
-            $paymentMethods,
-            function (\Magento\Payment\Model\MethodInterface $methodInstance) {
-                return $methodInstance instanceof VaultPaymentInterface;
-            }
-        );
-
-        return $availableMethods;
-    }
-
-    /**
-     * Get payment method list.
-     *
-     * @return \Magento\Payment\Api\PaymentMethodListInterface
-     * @deprecated
-     */
-    private function getPaymentMethodList()
-    {
-        if ($this->paymentMethodList === null) {
-            $this->paymentMethodList = ObjectManager::getInstance()->get(
-                \Magento\Payment\Api\PaymentMethodListInterface::class
-            );
-        }
-        return $this->paymentMethodList;
-    }
-
-    /**
-     * Get payment method instance factory.
-     *
-     * @return \Magento\Payment\Model\Method\InstanceFactory
+     * Get instance of vault payment list instance
+     * @return PaymentMethodListInterface
      * @deprecated
      */
-    private function getPaymentMethodInstanceFactory()
+    private function getVaultPaymentList()
     {
-        if ($this->paymentMethodInstanceFactory === null) {
-            $this->paymentMethodInstanceFactory = ObjectManager::getInstance()->get(
-                \Magento\Payment\Model\Method\InstanceFactory::class
-            );
+        if ($this->vaultPaymentList === null) {
+            $this->vaultPaymentList = ObjectManager::getInstance()->get(PaymentMethodListInterface::class);
         }
-        return $this->paymentMethodInstanceFactory;
+        return $this->vaultPaymentList;
     }
 }
diff --git a/app/code/Magento/Vault/Model/Ui/VaultConfigProvider.php b/app/code/Magento/Vault/Model/Ui/VaultConfigProvider.php
index 9cd7b97562df98e309b9ddd182a5ced144b2e555..bc3110a101452b40deb5506bc659d88a5f4e34a1 100644
--- a/app/code/Magento/Vault/Model/Ui/VaultConfigProvider.php
+++ b/app/code/Magento/Vault/Model/Ui/VaultConfigProvider.php
@@ -8,9 +8,8 @@ namespace Magento\Vault\Model\Ui;
 use Magento\Checkout\Model\ConfigProviderInterface;
 use Magento\Framework\App\ObjectManager;
 use Magento\Framework\Session\SessionManagerInterface;
-use Magento\Payment\Api\Data\PaymentMethodInterface;
 use Magento\Store\Model\StoreManagerInterface;
-use Magento\Vault\Model\VaultPaymentInterface;
+use Magento\Vault\Api\PaymentMethodListInterface;
 
 class VaultConfigProvider implements ConfigProviderInterface
 {
@@ -32,14 +31,9 @@ class VaultConfigProvider implements ConfigProviderInterface
     private $session;
 
     /**
-     * @var \Magento\Payment\Api\PaymentMethodListInterface
+     * @var PaymentMethodListInterface
      */
-    private $paymentMethodList;
-
-    /**
-     * @var \Magento\Payment\Model\Method\InstanceFactory
-     */
-    private $paymentMethodInstanceFactory;
+    private $vaultPaymentList;
 
     /**
      * VaultConfigProvider constructor.
@@ -62,9 +56,9 @@ class VaultConfigProvider implements ConfigProviderInterface
     public function getConfig()
     {
         $availableMethods = [];
-        $vaultPayments = $this->getVaultPaymentMethodList();
-        $customerId = $this->session->getCustomerId();
         $storeId = $this->storeManager->getStore()->getId();
+        $vaultPayments = $this->getVaultPaymentList()->getActiveList($storeId);
+        $customerId = $this->session->getCustomerId();
 
         foreach ($vaultPayments as $method) {
             $availableMethods[$method->getCode()] = [
@@ -78,60 +72,15 @@ class VaultConfigProvider implements ConfigProviderInterface
     }
 
     /**
-     * Get list of active Vault payment methods.
-     *
-     * @return VaultPaymentInterface[]
-     */
-    private function getVaultPaymentMethodList()
-    {
-        $storeId = $this->storeManager->getStore()->getId();
-
-        $paymentMethods = array_map(
-            function (PaymentMethodInterface $paymentMethod) {
-                return $this->getPaymentMethodInstanceFactory()->create($paymentMethod);
-            },
-            $this->getPaymentMethodList()->getActiveList($storeId)
-        );
-
-        $availableMethods = array_filter(
-            $paymentMethods,
-            function (\Magento\Payment\Model\MethodInterface $methodInstance) {
-                return $methodInstance instanceof VaultPaymentInterface;
-            }
-        );
-
-        return $availableMethods;
-    }
-
-    /**
-     * Get payment method list.
-     *
-     * @return \Magento\Payment\Api\PaymentMethodListInterface
-     * @deprecated
-     */
-    private function getPaymentMethodList()
-    {
-        if ($this->paymentMethodList === null) {
-            $this->paymentMethodList = ObjectManager::getInstance()->get(
-                \Magento\Payment\Api\PaymentMethodListInterface::class
-            );
-        }
-        return $this->paymentMethodList;
-    }
-
-    /**
-     * Get payment method instance factory.
-     *
-     * @return \Magento\Payment\Model\Method\InstanceFactory
+     * Get vault payment list instance
+     * @return PaymentMethodListInterface
      * @deprecated
      */
-    private function getPaymentMethodInstanceFactory()
+    private function getVaultPaymentList()
     {
-        if ($this->paymentMethodInstanceFactory === null) {
-            $this->paymentMethodInstanceFactory = ObjectManager::getInstance()->get(
-                \Magento\Payment\Model\Method\InstanceFactory::class
-            );
+        if ($this->vaultPaymentList === null) {
+            $this->vaultPaymentList = ObjectManager::getInstance()->get(PaymentMethodListInterface::class);
         }
-        return $this->paymentMethodInstanceFactory;
+        return $this->vaultPaymentList;
     }
 }
diff --git a/app/code/Magento/Vault/Setup/UpgradeData.php b/app/code/Magento/Vault/Setup/UpgradeData.php
index 3925aaa6c94fb39f512ce8e44e66f5a74663093d..757b5f4d3167cb00254e8f2ef20fad3addc1cb27 100644
--- a/app/code/Magento/Vault/Setup/UpgradeData.php
+++ b/app/code/Magento/Vault/Setup/UpgradeData.php
@@ -5,6 +5,9 @@
  */
 namespace Magento\Vault\Setup;
 
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\App\ResourceConnection;
+use Magento\Framework\DB\Adapter\AdapterInterface;
 use Magento\Framework\Setup\ModuleContextInterface;
 use Magento\Framework\Setup\ModuleDataSetupInterface;
 use Magento\Framework\Setup\UpgradeDataInterface;
@@ -16,13 +19,18 @@ use Magento\Vault\Model\CreditCardTokenFactory;
  */
 class UpgradeData implements UpgradeDataInterface
 {
+    /**
+     * @var AdapterInterface
+     */
+    private $connection;
+
     /**
      * @inheritdoc
      */
     public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
     {
         $setup->startSetup();
-        $connection = $setup->getConnection();
+        $connection = $this->getConnection();
 
         // data update for Vault module < 2.0.1
         if (version_compare($context->getVersion(), '2.0.1', '<')) {
@@ -59,4 +67,23 @@ class UpgradeData implements UpgradeDataInterface
 
         $setup->endSetup();
     }
+
+    /**
+     * Tries to get connection for scalable sales DB, otherwise returns default connection
+     * @return AdapterInterface
+     */
+    private function getConnection()
+    {
+        if ($this->connection === null) {
+            /** @var ResourceConnection $conn */
+            $conn = ObjectManager::getInstance()->get(ResourceConnection::class);
+            try {
+                $this->connection = $conn->getConnectionByName('sales');
+            } catch (\DomainException $e) {
+                $this->connection = $conn->getConnection();
+            }
+        }
+
+        return $this->connection;
+    }
 }
diff --git a/app/code/Magento/Vault/Test/Unit/Model/Method/VaultTest.php b/app/code/Magento/Vault/Test/Unit/Model/Method/VaultTest.php
index e5c83911025246d10c56687604d343b233db382b..8bded498dab765a442ced658ba2562db81ca5b7e 100644
--- a/app/code/Magento/Vault/Test/Unit/Model/Method/VaultTest.php
+++ b/app/code/Magento/Vault/Test/Unit/Model/Method/VaultTest.php
@@ -52,7 +52,7 @@ class VaultTest extends \PHPUnit_Framework_TestCase
     /**
      * @param array $additionalInfo
      * @expectedException \LogicException
-     * @expectedExceptionMessage Customer id and public hash should be defined
+     * @expectedExceptionMessage Public hash should be defined
      * @dataProvider additionalInfoDataProvider
      */
     public function testAuthorizeNoTokenMetadata(array $additionalInfo)
@@ -79,7 +79,7 @@ class VaultTest extends \PHPUnit_Framework_TestCase
         return [
             ['additionalInfo' => []],
             ['additionalInfo' => ['customer_id' => 1]],
-            ['additionalInfo' => ['public_hash' => 'df768aak12uf']],
+            ['additionalInfo' => ['public_hash' => null]],
         ];
     }
 
diff --git a/app/code/Magento/Vault/Test/Unit/Model/PaymentMethodListTest.php b/app/code/Magento/Vault/Test/Unit/Model/PaymentMethodListTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9e9d426fa8f3a487335f1f3fd0242833fbcc6e9d
--- /dev/null
+++ b/app/code/Magento/Vault/Test/Unit/Model/PaymentMethodListTest.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Vault\Test\Unit\Model;
+
+use Magento\Payment\Api\Data\PaymentMethodInterface;
+use Magento\Payment\Api\PaymentMethodListInterface;
+use Magento\Payment\Model\Method\InstanceFactory;
+use Magento\Payment\Model\MethodInterface;
+use Magento\Vault\Model\VaultPaymentInterface;
+use Magento\Vault\Model\PaymentMethodList;
+use PHPUnit_Framework_MockObject_MockObject as MockObject;
+
+class PaymentMethodListTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var PaymentMethodListInterface|MockObject
+     */
+    private $paymentMethodList;
+
+    /**
+     * @var InstanceFactory|MockObject
+     */
+    private $instanceFactory;
+
+    /**
+     * @var PaymentMethodList
+     */
+    private $vaultPaymentList;
+
+    protected function setUp()
+    {
+        $this->paymentMethodList = $this->getMock(PaymentMethodListInterface::class);
+        $this->instanceFactory = $this->getMockBuilder(InstanceFactory::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+
+        $this->vaultPaymentList = new PaymentMethodList($this->paymentMethodList, $this->instanceFactory);
+    }
+
+    /**
+     * @covers \Magento\Vault\Model\PaymentMethodList::getActiveList
+     */
+    public function testGetActivePaymentList()
+    {
+        $storeId = 1;
+        $vaultPayment = $this->getMock(VaultPaymentInterface::class);
+        $paymentMethodInterface1 = $this->getMock(PaymentMethodInterface::class);
+        $paymentMethodInterface2 = $this->getMock(PaymentMethodInterface::class);
+        $activePayments = [
+            $paymentMethodInterface1,
+            $paymentMethodInterface2
+        ];
+
+        $this->paymentMethodList->expects(static::once())
+            ->method('getActiveList')
+            ->with($storeId)
+            ->willReturn($activePayments);
+
+        $this->instanceFactory->expects(static::exactly(2))
+            ->method('create')
+            ->willReturnMap([
+                [$paymentMethodInterface1, $this->getMock(MethodInterface::class)],
+                [$paymentMethodInterface2, $vaultPayment]
+            ]);
+
+        $vaultPayments = $this->vaultPaymentList->getActiveList($storeId);
+        static::assertCount(1, $vaultPayments);
+        static::assertInstanceOf(VaultPaymentInterface::class, $vaultPayment);
+    }
+}
diff --git a/app/code/Magento/Vault/Test/Unit/Model/Ui/TokensConfigProviderTest.php b/app/code/Magento/Vault/Test/Unit/Model/Ui/TokensConfigProviderTest.php
index 3e4b8b145af67da759d6445234d18bd528832810..34b7c5240497164327cadac60fc00a33eb390c58 100644
--- a/app/code/Magento/Vault/Test/Unit/Model/Ui/TokensConfigProviderTest.php
+++ b/app/code/Magento/Vault/Test/Unit/Model/Ui/TokensConfigProviderTest.php
@@ -5,11 +5,11 @@
  */
 namespace Magento\Vault\Test\Unit\Model\Ui;
 
-use Magento\Customer\Model\Session;
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
 use Magento\Store\Api\Data\StoreInterface;
 use Magento\Store\Model\StoreManagerInterface;
 use Magento\Vault\Api\Data\PaymentTokenInterface;
+use Magento\Vault\Api\PaymentMethodListInterface;
 use Magento\Vault\Model\CustomerTokenManagement;
 use Magento\Vault\Model\Ui\TokensConfigProvider;
 use Magento\Vault\Model\Ui\TokenUiComponentInterface;
@@ -31,25 +31,10 @@ class TokensConfigProviderTest extends \PHPUnit_Framework_TestCase
      */
     private $storeManager;
 
-    /**
-     * @var \Magento\Payment\Api\PaymentMethodListInterface|MockObject
-     */
-    private $paymentMethodList;
-
-    /**
-     * @var \Magento\Payment\Model\Method\InstanceFactory|MockObject
-     */
-    private $paymentMethodInstanceFactory;
-
-    /**
-     * @var \Magento\Payment\Api\Data\PaymentMethodInterface|MockObject
-     */
-    private $vaultPayment;
-
     /**
      * @var VaultPaymentInterface|MockObject
      */
-    private $vaultPaymentInstance;
+    private $vaultPayment;
 
     /**
      * @var StoreInterface|MockObject
@@ -61,6 +46,11 @@ class TokensConfigProviderTest extends \PHPUnit_Framework_TestCase
      */
     private $customerTokenManagement;
 
+    /**
+     * @var PaymentMethodListInterface|MockObject
+     */
+    private $vaultPaymentList;
+
     /**
      * @var ObjectManager
      */
@@ -68,20 +58,12 @@ class TokensConfigProviderTest extends \PHPUnit_Framework_TestCase
 
     protected function setUp()
     {
-        $this->paymentMethodList = $this->getMockBuilder(\Magento\Payment\Api\PaymentMethodListInterface::class)
-            ->disableOriginalConstructor()
-            ->getMockForAbstractClass();
-
-        $this->paymentMethodInstanceFactory = $this->getMockBuilder(
-            \Magento\Payment\Model\Method\InstanceFactory::class
-        )->disableOriginalConstructor()->getMock();
-
-        $this->vaultPayment = $this->getMockForAbstractClass(\Magento\Payment\Api\Data\PaymentMethodInterface::class);
-        $this->vaultPaymentInstance = $this->getMockForAbstractClass(VaultPaymentInterface::class);
+        $this->objectManager = new ObjectManager($this);
+        $this->vaultPaymentList = $this->getMock(PaymentMethodListInterface::class);
+        $this->vaultPayment = $this->getMockForAbstractClass(VaultPaymentInterface::class);
         $this->storeManager = $this->getMock(StoreManagerInterface::class);
         $this->store = $this->getMock(StoreInterface::class);
 
-        $this->objectManager = new ObjectManager($this);
         $this->customerTokenManagement = $this->getMockBuilder(CustomerTokenManagement::class)
             ->disableOriginalConstructor()
             ->getMock();
@@ -95,7 +77,7 @@ class TokensConfigProviderTest extends \PHPUnit_Framework_TestCase
         $expectedConfig = [
             'payment' => [
                 'vault' => [
-                    $vaultProviderCode . '_item_' . '0' => [
+                    $vaultProviderCode . '_' . '0' => [
                         'config' => ['token_code' => 'code'],
                         'component' => 'Vendor_Module/js/vault_component'
                     ]
@@ -114,16 +96,12 @@ class TokensConfigProviderTest extends \PHPUnit_Framework_TestCase
             ->method('getId')
             ->willReturn($storeId);
 
-        $this->paymentMethodList->expects(static::once())
+        $this->vaultPaymentList->expects(static::once())
             ->method('getActiveList')
             ->with($storeId)
             ->willReturn([$this->vaultPayment]);
-
-        $this->paymentMethodInstanceFactory->expects($this->once())
-            ->method('create')
-            ->willReturn($this->vaultPaymentInstance);
         
-        $this->vaultPaymentInstance->expects(static::once())
+        $this->vaultPayment->expects(static::once())
             ->method('getProviderCode')
             ->willReturn($vaultProviderCode);
 
@@ -153,16 +131,10 @@ class TokensConfigProviderTest extends \PHPUnit_Framework_TestCase
                 $vaultProviderCode => $tokenUiComponentProvider
             ]
         );
-
-        $this->objectManager->setBackwardCompatibleProperty(
-            $configProvider,
-            'paymentMethodList',
-            $this->paymentMethodList
-        );
         $this->objectManager->setBackwardCompatibleProperty(
             $configProvider,
-            'paymentMethodInstanceFactory',
-            $this->paymentMethodInstanceFactory
+            'vaultPaymentList',
+            $this->vaultPaymentList
         );
 
         static::assertEquals($expectedConfig, $configProvider->getConfig());
diff --git a/app/code/Magento/Vault/Test/Unit/Model/Ui/VaultConfigProviderTest.php b/app/code/Magento/Vault/Test/Unit/Model/Ui/VaultConfigProviderTest.php
index d00531637b86d4e509662a31ce2da32752ba4a8b..e9d6af3bec356f518fbea6b1ce8be5ab841f78d4 100644
--- a/app/code/Magento/Vault/Test/Unit/Model/Ui/VaultConfigProviderTest.php
+++ b/app/code/Magento/Vault/Test/Unit/Model/Ui/VaultConfigProviderTest.php
@@ -9,35 +9,20 @@ use Magento\Customer\Model\Session;
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
 use Magento\Store\Api\Data\StoreInterface;
 use Magento\Store\Model\StoreManagerInterface;
+use Magento\Vault\Api\PaymentMethodListInterface;
 use Magento\Vault\Model\Ui\VaultConfigProvider;
 use Magento\Vault\Model\VaultPaymentInterface;
 use PHPUnit_Framework_MockObject_MockObject as MockObject;
 
 /**
  * Class VaultConfigProviderTest
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class VaultConfigProviderTest extends \PHPUnit_Framework_TestCase
 {
-    /**
-     * @var \Magento\Payment\Api\PaymentMethodListInterface|MockObject
-     */
-    private $paymentMethodList;
-
-    /**
-     * @var \Magento\Payment\Model\Method\InstanceFactory|MockObject
-     */
-    private $paymentMethodInstanceFactory;
-
-    /**
-     * @var \Magento\Payment\Api\Data\PaymentMethodInterface|MockObject
-     */
-    private $vaultPayment;
-
     /**
      * @var VaultPaymentInterface|MockObject
      */
-    private $vaultPaymentInstance;
+    private $vaultPayment;
 
     /**
      * @var Session|MockObject
@@ -54,6 +39,11 @@ class VaultConfigProviderTest extends \PHPUnit_Framework_TestCase
      */
     private $storeManager;
 
+    /**
+     * @var PaymentMethodListInterface|MockObject
+     */
+    private $vaultPaymentList;
+
     /**
      * @var VaultConfigProvider
      */
@@ -61,33 +51,20 @@ class VaultConfigProviderTest extends \PHPUnit_Framework_TestCase
 
     protected function setUp()
     {
-        $this->paymentMethodList = $this->getMockBuilder(\Magento\Payment\Api\PaymentMethodListInterface::class)
-            ->disableOriginalConstructor()
-            ->getMockForAbstractClass();
-
-        $this->paymentMethodInstanceFactory = $this->getMockBuilder(
-            \Magento\Payment\Model\Method\InstanceFactory::class
-        )->disableOriginalConstructor()->getMock();
-
-        $this->vaultPayment = $this->getMockForAbstractClass(\Magento\Payment\Api\Data\PaymentMethodInterface::class);
-        $this->vaultPaymentInstance = $this->getMockForAbstractClass(VaultPaymentInterface::class);
+        $this->vaultPayment = $this->getMockForAbstractClass(VaultPaymentInterface::class);
         $this->storeManager = $this->getMockForAbstractClass(StoreManagerInterface::class);
         $this->store = $this->getMockForAbstractClass(StoreInterface::class);
         $this->session = $this->getMockBuilder(Session::class)
             ->disableOriginalConstructor()
             ->getMock();
+        $this->vaultPaymentList = $this->getMock(PaymentMethodListInterface::class);
 
         $objectManager = new ObjectManager($this);
         $this->vaultConfigProvider = new VaultConfigProvider($this->storeManager, $this->session);
         $objectManager->setBackwardCompatibleProperty(
             $this->vaultConfigProvider,
-            'paymentMethodList',
-            $this->paymentMethodList
-        );
-        $objectManager->setBackwardCompatibleProperty(
-            $this->vaultConfigProvider,
-            'paymentMethodInstanceFactory',
-            $this->paymentMethodInstanceFactory
+            'vaultPaymentList',
+            $this->vaultPaymentList
         );
     }
 
@@ -112,26 +89,21 @@ class VaultConfigProviderTest extends \PHPUnit_Framework_TestCase
         $this->session->expects(static::once())
             ->method('getCustomerId')
             ->willReturn($customerId);
-        $this->storeManager->expects(static::exactly(2))
+        $this->storeManager->expects(static::once())
             ->method('getStore')
             ->willReturn($this->store);
-        $this->store->expects(static::exactly(2))
+        $this->store->expects(static::once())
             ->method('getId')
             ->willReturn($storeId);
 
-        $this->paymentMethodList->expects(static::once())
+        $this->vaultPaymentList->expects(static::once())
             ->method('getActiveList')
-            ->with($storeId)
             ->willReturn([$this->vaultPayment]);
 
-        $this->paymentMethodInstanceFactory->expects($this->once())
-            ->method('create')
-            ->willReturn($this->vaultPaymentInstance);
-
-        $this->vaultPaymentInstance->expects(static::once())
+        $this->vaultPayment->expects(static::once())
             ->method('getCode')
             ->willReturn($vaultPaymentCode);
-        $this->vaultPaymentInstance->expects($customerId !== null ? static::once() : static::never())
+        $this->vaultPayment->expects($customerId !== null ? static::once() : static::never())
             ->method('isActive')
             ->with($storeId)
             ->willReturn($vaultEnabled);
diff --git a/app/code/Magento/Vault/etc/di.xml b/app/code/Magento/Vault/etc/di.xml
index e44e1da3e3d61f3c5d230c978b798fa05e84db7e..14354da7e2c528e910a0af6bd15706f25dbeadb4 100644
--- a/app/code/Magento/Vault/etc/di.xml
+++ b/app/code/Magento/Vault/etc/di.xml
@@ -11,6 +11,7 @@
     <preference for="Magento\Vault\Api\Data\PaymentTokenInterface" type="Magento\Vault\Model\PaymentToken"/>
     <preference for="Magento\Vault\Api\PaymentTokenRepositoryInterface" type="Magento\Vault\Model\PaymentTokenRepository" />
     <preference for="Magento\Vault\Api\PaymentTokenManagementInterface" type="Magento\Vault\Model\PaymentTokenManagement" />
+    <preference for="Magento\Vault\Api\PaymentMethodListInterface" type="Magento\Vault\Model\PaymentMethodList" />
     <preference for="Magento\Vault\Api\Data\PaymentTokenSearchResultsInterface" type="Magento\Framework\Api\SearchResults" />
     <preference for="Magento\Vault\Model\Ui\TokenUiComponentInterface" type="Magento\Vault\Model\Ui\TokenUiComponent" />
 
diff --git a/app/code/Magento/Vault/view/frontend/web/js/view/payment/vault.js b/app/code/Magento/Vault/view/frontend/web/js/view/payment/vault.js
index cba9256f2a56396890774c3e6e7bae7ec35b12ad..05d56e305f23eea9473c5c3da2d0a130ca2c42a5 100644
--- a/app/code/Magento/Vault/view/frontend/web/js/view/payment/vault.js
+++ b/app/code/Magento/Vault/view/frontend/web/js/view/payment/vault.js
@@ -31,7 +31,8 @@ define(
                      * @return {Boolean}
                      */
                     typeComparatorCallback: function (typeA, typeB) {
-                        return typeA.indexOf(typeB) === 0;
+                        // vault token items have the same name as vault payment without index
+                        return typeA.substring(0, typeA.lastIndexOf('_')) === typeB;
                     }
                 }
             );
diff --git a/app/code/Magento/Widget/Test/Unit/Block/Adminhtml/Widget/Instance/Edit/Chooser/AbstractContainerTest.php b/app/code/Magento/Widget/Test/Unit/Block/Adminhtml/Widget/Instance/Edit/Chooser/AbstractContainerTest.php
index e31bd1b356431beab50b3a336e40ed42f87b8afa..a01df75bca596934a2f9e27f24c20704a3df7f8d 100644
--- a/app/code/Magento/Widget/Test/Unit/Block/Adminhtml/Widget/Instance/Edit/Chooser/AbstractContainerTest.php
+++ b/app/code/Magento/Widget/Test/Unit/Block/Adminhtml/Widget/Instance/Edit/Chooser/AbstractContainerTest.php
@@ -103,7 +103,14 @@ abstract class AbstractContainerTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
 
-        $this->escaperMock = $this->getMock(\Magento\Framework\Escaper::class, ['escapeHtml'], [], '', false);
+        $this->escaperMock = $this->getMock(
+            \Magento\Framework\Escaper::class,
+            ['escapeHtml', 'escapeHtmlAttr'],
+            [],
+            '',
+            false
+        );
+        $this->escaperMock->expects($this->any())->method('escapeHtmlAttr')->willReturnArgument(0);
 
         $this->contextMock = $this->getMockBuilder(\Magento\Backend\Block\Context::class)
             ->setMethods(['getEventManager', 'getScopeConfig', 'getEscaper'])
diff --git a/app/code/Magento/Widget/Test/Unit/Block/Adminhtml/Widget/Instance/Edit/Chooser/ContainerTest.php b/app/code/Magento/Widget/Test/Unit/Block/Adminhtml/Widget/Instance/Edit/Chooser/ContainerTest.php
index 737dbc905fabf18a4e228062879162a610612f3b..47f4507d7e2de8f532220877236809e1679d4202 100644
--- a/app/code/Magento/Widget/Test/Unit/Block/Adminhtml/Widget/Instance/Edit/Chooser/ContainerTest.php
+++ b/app/code/Magento/Widget/Test/Unit/Block/Adminhtml/Widget/Instance/Edit/Chooser/ContainerTest.php
@@ -66,7 +66,7 @@ class ContainerTest extends AbstractContainerTest
             . 'Main Content Area</option><option value="content.bottom" >Main Content Bottom</option>'
             . '<option value="content.top" >Main Content Top</option></select>';
 
-        $this->eventManagerMock->expects($this->once())->method('dispatch')->willReturn(true);
+        $this->eventManagerMock->expects($this->exactly(2))->method('dispatch')->willReturn(true);
         $this->scopeConfigMock->expects($this->once())->method('getValue')->willReturn(false);
 
         $this->themeCollectionFactoryMock->expects($this->once())
@@ -153,7 +153,7 @@ class ContainerTest extends AbstractContainerTest
             . '<option value="sidebar.additional" >Sidebar Additional</option>'
             . '<option value="sidebar.main" >Sidebar Main</option></select>';
 
-        $this->eventManagerMock->expects($this->once())->method('dispatch')->willReturn(true);
+        $this->eventManagerMock->expects($this->exactly(2))->method('dispatch')->willReturn(true);
         $this->scopeConfigMock->expects($this->once())->method('getValue')->willReturn(false);
 
         $this->themeCollectionFactoryMock->expects($this->once())
@@ -284,7 +284,7 @@ class ContainerTest extends AbstractContainerTest
             . '<option value="sidebar.additional" >Sidebar Additional</option>'
             . '<option value="sidebar.main" >Sidebar Main</option></select>';
 
-        $this->eventManagerMock->expects($this->once())->method('dispatch')->willReturn(true);
+        $this->eventManagerMock->expects($this->exactly(2))->method('dispatch')->willReturn(true);
         $this->scopeConfigMock->expects($this->once())->method('getValue')->willReturn(false);
 
         $this->themeCollectionFactoryMock->expects($this->once())
@@ -402,7 +402,7 @@ class ContainerTest extends AbstractContainerTest
             . '<option value="sidebar.additional" >Sidebar Additional</option><option value="sidebar.main" >'
             . 'Sidebar Main</option></select>';
 
-        $this->eventManagerMock->expects($this->once())->method('dispatch')->willReturn(true);
+        $this->eventManagerMock->expects($this->exactly(2))->method('dispatch')->willReturn(true);
         $this->scopeConfigMock->expects($this->once())->method('getValue')->willReturn(false);
 
         $this->themeCollectionFactoryMock->expects($this->once())
diff --git a/app/design/adminhtml/Magento/backend/web/css/source/components/_modals_extend.less b/app/design/adminhtml/Magento/backend/web/css/source/components/_modals_extend.less
index 7e88ff91b857cb2b46178b8014f48e7807ee02c5..b6524e2d49bf55fca4e32a7074627129308edffc 100644
--- a/app/design/adminhtml/Magento/backend/web/css/source/components/_modals_extend.less
+++ b/app/design/adminhtml/Magento/backend/web/css/source/components/_modals_extend.less
@@ -69,7 +69,7 @@
 .modal-popup {
     &.prompt {
         .prompt-message {
-            padding: @modal-prompt-message__padding 0;
+            padding-bottom: @modal-prompt-message__padding;
 
             input {
                 width: 100%;
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payments.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payments.less
index ca692754416437bec127a1d6efdb0f0231b6a461..7731595870f061c990acc5cc36d68980e8ba590f 100644
--- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payments.less
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payments.less
@@ -72,7 +72,6 @@
 
         .payment-method-content {
             display: none;
-
             .lib-css(padding, 0 0 @indent__base @checkout-payment-method-content__padding__xl);
             .fieldset {
                 &:not(:last-child) {
@@ -90,7 +89,7 @@
             margin: 0 0 @indent__s;
         }
 
-        .payment-method-billing-address {
+        .checkout-billing-address {
             margin: 0 0 @indent__base;
 
             .primary {
@@ -106,15 +105,11 @@
             .billing-address-details {
                 .lib-css(line-height, @checkout-billing-address-details__line-height);
                 .lib-css(padding, @checkout-billing-address-details__padding);
-
-                .action-edit-address {
-                    &:extend(.abs-action-button-as-link all);
-                }
             }
         }
 
         .payment-method-note {
-            & + .payment-method-billing-address {
+            & + .checkout-billing-address {
                 margin-top: @indent__base;
             }
         }
@@ -161,7 +156,7 @@
             .lib-css(padding, 0 @checkout-payment-method-title-mobile__padding @indent__base);
         }
 
-        .payment-method-billing-address {
+        .checkout-billing-address {
             .action-cancel {
                 margin-top: @indent__s;
             }
@@ -175,12 +170,10 @@
 
 .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
     .checkout-payment-method {
-        .payment-methods {
-            .actions-toolbar {
-                .primary {
-                    float: right;
-                    margin: 0;
-                }
+        .actions-toolbar {
+            .primary {
+                float: right;
+                margin: 0;
             }
         }
 
@@ -214,7 +207,7 @@
         }
     }
 
-    .payment-method-billing-address {
+    .checkout-billing-address {
         .action-update {
             float: right;
         }
diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_payments.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_payments.less
index 3c3ee77ed00e02ddfdc7b14f3ba45620cab96377..85b2e96e6ea4add2316a572f0ce4ad16bfe073d2 100644
--- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_payments.less
+++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_payments.less
@@ -89,7 +89,7 @@
             margin: 0 0 @indent__s;
         }
 
-        .payment-method-billing-address {
+        .checkout-billing-address {
             margin: 0 0 @indent__base;
 
             .primary {
@@ -105,15 +105,11 @@
             .billing-address-details {
                 .lib-css(line-height, @checkout-billing-address-details__line-height);
                 .lib-css(padding, @checkout-billing-address-details__padding);
-
-                .action-edit-address {
-                    &:extend(.abs-action-button-as-link all);
-                }
             }
         }
 
         .payment-method-note {
-            & + .payment-method-billing-address {
+            & + .checkout-billing-address {
                 margin-top: @indent__base;
             }
         }
@@ -160,7 +156,7 @@
             .lib-css(padding, 0 @checkout-payment-method-title-mobile__padding @indent__base);
         }
 
-        .payment-method-billing-address {
+        .checkout-billing-address {
             .action-cancel {
                 margin-top: @indent__s;
             }
@@ -174,12 +170,10 @@
 
 .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
     .checkout-payment-method {
-        .payment-methods {
-            .actions-toolbar {
-                .primary {
-                    float: right;
-                    margin: 0;
-                }
+        .actions-toolbar {
+            .primary {
+                float: right;
+                margin: 0;
             }
         }
 
@@ -193,7 +187,7 @@
         }
     }
 
-    .payment-method-billing-address {
+    .checkout-billing-address {
         .action-update {
             float: right;
         }
diff --git a/app/etc/di.xml b/app/etc/di.xml
index 28f0d024c3ae234583e19b31800c10c950a5b42d..643390068a5e3e857ccb0e0d2d07fb5e26b8ea81 100755
--- a/app/etc/di.xml
+++ b/app/etc/di.xml
@@ -1205,7 +1205,6 @@
         <arguments>
             <argument name="mappers" xsi:type="array">
                 <item name="mapper" xsi:type="object">Magento\Framework\EntityManager\Mapper</item>
-                <item name="customAttributesMapper" xsi:type="object">Magento\Framework\EntityManager\CustomAttributesMapper</item>
             </argument>
         </arguments>
     </type>
diff --git a/composer.json b/composer.json
index a5f4b8c427ffffcbf85d9be78bcd89bf0928625a..fed4465140724cef3c24cd7facdd2ec5ceeba5b6 100644
--- a/composer.json
+++ b/composer.json
@@ -31,9 +31,9 @@
         "zendframework/zend-serializer": "~2.4.6",
         "zendframework/zend-log": "~2.4.6",
         "zendframework/zend-http": "~2.4.6",
-        "magento/zendframework1": "1.12.16",
+        "magento/zendframework1": "~1.12.16",
         "colinmollenhour/credis": "1.6",
-        "colinmollenhour/php-redis-session-abstract": "1.1",
+        "colinmollenhour/php-redis-session-abstract": "1.2",
         "colinmollenhour/cache-backend-redis": "1.9",
         "colinmollenhour/cache-backend-file": "1.4",
         "composer/composer": "1.0.0-beta1",
@@ -151,6 +151,7 @@
         "magento/module-rss": "100.2.0-dev",
         "magento/module-rule": "100.2.0-dev",
         "magento/module-sales": "100.2.0-dev",
+        "magento/module-sales-inventory": "100.0.0-dev",
         "magento/module-sales-rule": "100.2.0-dev",
         "magento/module-sales-sequence": "100.2.0-dev",
         "magento/module-sample-data": "100.2.0-dev",
diff --git a/composer.lock b/composer.lock
index d842cdec858b705c27295b5b1b1d6e89ae5a6b19..7feb568d766d012e009c59a50226f3ea8bd7b74a 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,8 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "1c5d7ca4fa68bea1ab7490cb8ac62342",
-    "content-hash": "ecfa548096f500a6a98a5fc41c21e53b",
+    "hash": "c23e80be1cc71ab108ce5ac19b3fe509",
+    "content-hash": "5b9734c1bdbda68cf20507525cafa0f2",
     "packages": [
         {
             "name": "braintree/braintree_php",
@@ -167,21 +167,21 @@
         },
         {
             "name": "colinmollenhour/php-redis-session-abstract",
-            "version": "v1.1",
+            "version": "v1.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/colinmollenhour/php-redis-session-abstract.git",
-                "reference": "95330b7f29663dab81f53d1a438e4d927b6c5f66"
+                "reference": "2b552c9bbe06967329dd41e1bd3e0aed02313ddb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/colinmollenhour/php-redis-session-abstract/zipball/95330b7f29663dab81f53d1a438e4d927b6c5f66",
-                "reference": "95330b7f29663dab81f53d1a438e4d927b6c5f66",
+                "url": "https://api.github.com/repos/colinmollenhour/php-redis-session-abstract/zipball/2b552c9bbe06967329dd41e1bd3e0aed02313ddb",
+                "reference": "2b552c9bbe06967329dd41e1bd3e0aed02313ddb",
                 "shasum": ""
             },
             "require": {
                 "colinmollenhour/credis": "1.6",
-                "magento/zendframework1": "1.12.16",
+                "magento/zendframework1": "~1.12.0",
                 "php": "~5.5.0|~5.6.0|~7.0.0"
             },
             "type": "library",
@@ -201,7 +201,7 @@
             ],
             "description": "A Redis-based session handler with optimistic locking",
             "homepage": "https://github.com/colinmollenhour/php-redis-session-abstract",
-            "time": "2016-02-03 18:13:49"
+            "time": "2016-08-04 18:05:51"
         },
         {
             "name": "composer/composer",
@@ -280,16 +280,16 @@
         },
         {
             "name": "composer/semver",
-            "version": "1.4.1",
+            "version": "1.4.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/composer/semver.git",
-                "reference": "03c9de5aa25e7672c4ad251eeaba0c47a06c8b98"
+                "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/composer/semver/zipball/03c9de5aa25e7672c4ad251eeaba0c47a06c8b98",
-                "reference": "03c9de5aa25e7672c4ad251eeaba0c47a06c8b98",
+                "url": "https://api.github.com/repos/composer/semver/zipball/c7cb9a2095a074d131b65a8a0cd294479d785573",
+                "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573",
                 "shasum": ""
             },
             "require": {
@@ -338,20 +338,20 @@
                 "validation",
                 "versioning"
             ],
-            "time": "2016-06-02 09:04:51"
+            "time": "2016-08-30 16:08:34"
         },
         {
             "name": "composer/spdx-licenses",
-            "version": "1.1.4",
+            "version": "1.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/composer/spdx-licenses.git",
-                "reference": "88c26372b1afac36d8db601cdf04ad8716f53d88"
+                "reference": "96c6a07b05b716e89a44529d060bc7f5c263cb13"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/88c26372b1afac36d8db601cdf04ad8716f53d88",
-                "reference": "88c26372b1afac36d8db601cdf04ad8716f53d88",
+                "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/96c6a07b05b716e89a44529d060bc7f5c263cb13",
+                "reference": "96c6a07b05b716e89a44529d060bc7f5c263cb13",
                 "shasum": ""
             },
             "require": {
@@ -399,7 +399,7 @@
                 "spdx",
                 "validator"
             ],
-            "time": "2016-05-04 12:27:30"
+            "time": "2016-09-28 07:17:45"
         },
         {
             "name": "justinrainbow/json-schema",
@@ -633,16 +633,16 @@
         },
         {
             "name": "magento/zendframework1",
-            "version": "1.12.16",
+            "version": "1.12.16-patch1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/magento/zf1.git",
-                "reference": "c9d607bfd9454bc18b9deff737ccd5d044e2ab10"
+                "reference": "b4502f38f88ff2bc22a906c108cc3da18dcce12f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/magento/zf1/zipball/c9d607bfd9454bc18b9deff737ccd5d044e2ab10",
-                "reference": "c9d607bfd9454bc18b9deff737ccd5d044e2ab10",
+                "url": "https://api.github.com/repos/magento/zf1/zipball/b4502f38f88ff2bc22a906c108cc3da18dcce12f",
+                "reference": "b4502f38f88ff2bc22a906c108cc3da18dcce12f",
                 "shasum": ""
             },
             "require": {
@@ -676,7 +676,7 @@
                 "ZF1",
                 "framework"
             ],
-            "time": "2015-10-29 14:34:55"
+            "time": "2016-09-14 12:04:33"
         },
         {
             "name": "monolog/monolog",
@@ -1014,22 +1014,30 @@
         },
         {
             "name": "psr/log",
-            "version": "1.0.0",
+            "version": "1.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/php-fig/log.git",
-                "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
+                "reference": "5277094ed527a1c4477177d102fe4c53551953e0"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
-                "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
+                "url": "https://api.github.com/repos/php-fig/log/zipball/5277094ed527a1c4477177d102fe4c53551953e0",
+                "reference": "5277094ed527a1c4477177d102fe4c53551953e0",
                 "shasum": ""
             },
+            "require": {
+                "php": ">=5.3.0"
+            },
             "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
             "autoload": {
-                "psr-0": {
-                    "Psr\\Log\\": ""
+                "psr-4": {
+                    "Psr\\Log\\": "Psr/Log/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -1043,12 +1051,13 @@
                 }
             ],
             "description": "Common interface for logging libraries",
+            "homepage": "https://github.com/php-fig/log",
             "keywords": [
                 "log",
                 "psr",
                 "psr-3"
             ],
-            "time": "2012-12-21 11:40:51"
+            "time": "2016-09-19 16:02:08"
         },
         {
             "name": "ramsey/uuid",
@@ -1180,16 +1189,16 @@
         },
         {
             "name": "seld/jsonlint",
-            "version": "1.4.0",
+            "version": "1.4.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/Seldaek/jsonlint.git",
-                "reference": "66834d3e3566bb5798db7294619388786ae99394"
+                "reference": "e827b5254d3e58c736ea2c5616710983d80b0b70"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/66834d3e3566bb5798db7294619388786ae99394",
-                "reference": "66834d3e3566bb5798db7294619388786ae99394",
+                "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/e827b5254d3e58c736ea2c5616710983d80b0b70",
+                "reference": "e827b5254d3e58c736ea2c5616710983d80b0b70",
                 "shasum": ""
             },
             "require": {
@@ -1222,7 +1231,7 @@
                 "parser",
                 "validator"
             ],
-            "time": "2015-11-21 02:21:41"
+            "time": "2016-09-14 15:17:56"
         },
         {
             "name": "seld/phar-utils",
@@ -1381,7 +1390,7 @@
         },
         {
             "name": "symfony/event-dispatcher",
-            "version": "v2.8.9",
+            "version": "v2.8.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher.git",
@@ -1441,16 +1450,16 @@
         },
         {
             "name": "symfony/filesystem",
-            "version": "v2.8.9",
+            "version": "v2.8.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/filesystem.git",
-                "reference": "ab4c3f085c8f5a56536845bf985c4cef30bf75fd"
+                "reference": "44b499521defddf2eae17a18c811bbdae4f98bdf"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/filesystem/zipball/ab4c3f085c8f5a56536845bf985c4cef30bf75fd",
-                "reference": "ab4c3f085c8f5a56536845bf985c4cef30bf75fd",
+                "url": "https://api.github.com/repos/symfony/filesystem/zipball/44b499521defddf2eae17a18c811bbdae4f98bdf",
+                "reference": "44b499521defddf2eae17a18c811bbdae4f98bdf",
                 "shasum": ""
             },
             "require": {
@@ -1486,20 +1495,20 @@
             ],
             "description": "Symfony Filesystem Component",
             "homepage": "https://symfony.com",
-            "time": "2016-07-20 05:41:28"
+            "time": "2016-09-06 10:55:00"
         },
         {
             "name": "symfony/finder",
-            "version": "v3.1.3",
+            "version": "v3.1.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/finder.git",
-                "reference": "8201978de88a9fa0923e18601bb17f1df9c721e7"
+                "reference": "e568ef1784f447a0e54dcb6f6de30b9747b0f577"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/finder/zipball/8201978de88a9fa0923e18601bb17f1df9c721e7",
-                "reference": "8201978de88a9fa0923e18601bb17f1df9c721e7",
+                "url": "https://api.github.com/repos/symfony/finder/zipball/e568ef1784f447a0e54dcb6f6de30b9747b0f577",
+                "reference": "e568ef1784f447a0e54dcb6f6de30b9747b0f577",
                 "shasum": ""
             },
             "require": {
@@ -1535,20 +1544,20 @@
             ],
             "description": "Symfony Finder Component",
             "homepage": "https://symfony.com",
-            "time": "2016-06-29 05:41:56"
+            "time": "2016-08-26 12:04:02"
         },
         {
             "name": "symfony/process",
-            "version": "v2.8.9",
+            "version": "v2.8.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/process.git",
-                "reference": "d20332e43e8774ff8870b394f3dd6020cc7f8e0c"
+                "reference": "05a03ed27073638658cab9405d99a67dd1014987"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/process/zipball/d20332e43e8774ff8870b394f3dd6020cc7f8e0c",
-                "reference": "d20332e43e8774ff8870b394f3dd6020cc7f8e0c",
+                "url": "https://api.github.com/repos/symfony/process/zipball/05a03ed27073638658cab9405d99a67dd1014987",
+                "reference": "05a03ed27073638658cab9405d99a67dd1014987",
                 "shasum": ""
             },
             "require": {
@@ -1584,7 +1593,7 @@
             ],
             "description": "Symfony Process Component",
             "homepage": "https://symfony.com",
-            "time": "2016-07-28 11:13:19"
+            "time": "2016-09-06 10:55:00"
         },
         {
             "name": "tedivm/jshrink",
@@ -3233,16 +3242,16 @@
         },
         {
             "name": "friendsofphp/php-cs-fixer",
-            "version": "v1.12.0",
+            "version": "v1.12.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
-                "reference": "ddac737e1c06a310a0bb4b3da755a094a31a916a"
+                "reference": "baa7112bef3b86c65fcfaae9a7a50436e3902b41"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/ddac737e1c06a310a0bb4b3da755a094a31a916a",
-                "reference": "ddac737e1c06a310a0bb4b3da755a094a31a916a",
+                "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/baa7112bef3b86c65fcfaae9a7a50436e3902b41",
+                "reference": "baa7112bef3b86c65fcfaae9a7a50436e3902b41",
                 "shasum": ""
             },
             "require": {
@@ -3287,7 +3296,7 @@
                 }
             ],
             "description": "A tool to automatically fix PHP code style",
-            "time": "2016-08-17 00:17:27"
+            "time": "2016-09-27 07:57:59"
         },
         {
             "name": "lusitanian/oauth",
@@ -4320,16 +4329,16 @@
         },
         {
             "name": "symfony/config",
-            "version": "v2.8.9",
+            "version": "v2.8.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/config.git",
-                "reference": "4275ef5b59f18959df0eee3991e9ca0cc208ffd4"
+                "reference": "005bf10c156335ede2e89fb9a9ee10a0b742bc84"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/config/zipball/4275ef5b59f18959df0eee3991e9ca0cc208ffd4",
-                "reference": "4275ef5b59f18959df0eee3991e9ca0cc208ffd4",
+                "url": "https://api.github.com/repos/symfony/config/zipball/005bf10c156335ede2e89fb9a9ee10a0b742bc84",
+                "reference": "005bf10c156335ede2e89fb9a9ee10a0b742bc84",
                 "shasum": ""
             },
             "require": {
@@ -4369,20 +4378,20 @@
             ],
             "description": "Symfony Config Component",
             "homepage": "https://symfony.com",
-            "time": "2016-07-26 08:02:44"
+            "time": "2016-08-16 14:56:08"
         },
         {
             "name": "symfony/dependency-injection",
-            "version": "v2.8.9",
+            "version": "v2.8.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/dependency-injection.git",
-                "reference": "f2b5a00d176f6a201dc430375c0ef37706ea3d12"
+                "reference": "0a732a9cafc30e54077967da4d019e1d618a8cb9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f2b5a00d176f6a201dc430375c0ef37706ea3d12",
-                "reference": "f2b5a00d176f6a201dc430375c0ef37706ea3d12",
+                "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/0a732a9cafc30e54077967da4d019e1d618a8cb9",
+                "reference": "0a732a9cafc30e54077967da4d019e1d618a8cb9",
                 "shasum": ""
             },
             "require": {
@@ -4432,11 +4441,11 @@
             ],
             "description": "Symfony DependencyInjection Component",
             "homepage": "https://symfony.com",
-            "time": "2016-07-30 07:20:35"
+            "time": "2016-09-06 23:19:39"
         },
         {
             "name": "symfony/stopwatch",
-            "version": "v3.1.3",
+            "version": "v3.1.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/stopwatch.git",
@@ -4485,16 +4494,16 @@
         },
         {
             "name": "symfony/yaml",
-            "version": "v2.8.9",
+            "version": "v2.8.11",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/yaml.git",
-                "reference": "0ceab136f43ed9d3e97b3eea32a7855dc50c121d"
+                "reference": "e7540734bad981fe59f8ef14b6fc194ae9df8d9c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/yaml/zipball/0ceab136f43ed9d3e97b3eea32a7855dc50c121d",
-                "reference": "0ceab136f43ed9d3e97b3eea32a7855dc50c121d",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/e7540734bad981fe59f8ef14b6fc194ae9df8d9c",
+                "reference": "e7540734bad981fe59f8ef14b6fc194ae9df8d9c",
                 "shasum": ""
             },
             "require": {
@@ -4530,7 +4539,7 @@
             ],
             "description": "Symfony Yaml Component",
             "homepage": "https://symfony.com",
-            "time": "2016-07-17 09:06:15"
+            "time": "2016-09-02 01:57:56"
         },
         {
             "name": "theseer/fdomdocument",
diff --git a/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductLinkManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductLinkManagementTest.php
index 070de886077ffd60f74c2e380f6459089bdcc078..0b8e468b014d689db4b61f6884b69adf51e0ae2c 100644
--- a/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductLinkManagementTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductLinkManagementTest.php
@@ -51,7 +51,6 @@ class ProductLinkManagementTest extends \Magento\TestFramework\TestCase\WebapiAb
      */
     public function testRemoveChild()
     {
-        $this->markTestSkipped('must be unskipped after fixing bug about wrong saving bundle option price');
         $productSku = 'bundle-product';
         $childSku = 'simple';
         $optionIds = $this->getProductOptions(3);
diff --git a/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductServiceTest.php
index 47e6db6a27e0bdce53e7aded9c11ef0c9fe41ce6..63b5b76a8d15d968d1105e94c873f54561a80092 100644
--- a/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductServiceTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductServiceTest.php
@@ -144,16 +144,12 @@ class ProductServiceTest extends WebapiAbstract
      */
     public function testUpdateBundleModifyExistingOptionOnly()
     {
-        $this->markTestSkipped('Skipped, due to MAGETWO-46857');
         $bundleProduct = $this->createFixedPriceBundleProduct();
         $bundleProductOptions = $this->getBundleProductOptions($bundleProduct);
 
-        $existingSelectionId = $bundleProductOptions[0]['product_links'][0]['id'];
-
         //Change the type of existing option
         $bundleProductOptions[0]['type'] = 'select';
-        //unset product_links attribute
-        unset($bundleProductOptions[0]['product_links']);
+
         $this->setBundleProductOptions($bundleProduct, $bundleProductOptions);
 
         $updatedProduct = $this->saveProduct($bundleProduct);
@@ -162,7 +158,6 @@ class ProductServiceTest extends WebapiAbstract
         $this->assertEquals('select', $bundleOptions[0]['type']);
         $this->assertEquals('simple', $bundleOptions[0]['product_links'][0]['sku']);
         $this->assertEquals(1, $bundleOptions[0]['product_links'][0]['qty']);
-        $this->assertEquals($existingSelectionId, $bundleOptions[0]['product_links'][0]['id']);
         $this->assertEquals(20, $bundleOptions[0]['product_links'][0]['price']);
         $this->assertEquals(1, $bundleOptions[0]['product_links'][0]['price_type']);
     }
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryLinkRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryLinkRepositoryTest.php
index 9828d85fb5de0ff6ce0ebe328692d41e8712e5dc..3e03ea49771c938170940316f9026f715c966c23 100644
--- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryLinkRepositoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryLinkRepositoryTest.php
@@ -27,8 +27,6 @@ class CategoryLinkRepositoryTest extends WebapiAbstract
      */
     public function testSave($productLink, $productId, $productPosition = 0)
     {
-        $this->checkIfTestable();
-
         $serviceInfo = [
             'rest' => [
                 'resourcePath' => self::RESOURCE_PATH_SUFFIX
@@ -71,8 +69,6 @@ class CategoryLinkRepositoryTest extends WebapiAbstract
      */
     public function testUpdateProduct($productLink, $productId, $productPosition = 0)
     {
-        $this->checkIfTestable();
-
         $serviceInfo = [
             'rest' => [
                 'resourcePath' => self::RESOURCE_PATH_SUFFIX
@@ -111,8 +107,6 @@ class CategoryLinkRepositoryTest extends WebapiAbstract
      */
     public function testDelete()
     {
-        $this->checkIfTestable();
-
         $serviceInfo = [
             'rest' => [
                 'resourcePath' => self::RESOURCE_PATH_SUFFIX . '/' . $this->categoryId .
@@ -153,20 +147,4 @@ class CategoryLinkRepositoryTest extends WebapiAbstract
             return false;
         }
     }
-
-    /**
-     * MAGETWO-41737: Skip tests when the flag 'custom_categories_sort' is up
-     * @return void
-     */
-    private function checkIfTestable()
-    {
-        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-
-        /** @var \Magento\Framework\App\Config\ScopeConfigInterface $config */
-        $config = $objectManager->get(\Magento\Framework\App\Config\ScopeConfigInterface::class);
-
-        if ($config->getValue('catalog/custom_categories_sort') == 1) {
-            $this->markTestSkipped('Will be fixed after MAGETWO-41737');
-        }
-    }
 }
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionManagementInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionManagementInterfaceTest.php
index cd8a43e5105ed0a1b190006d07bc46fe9eb9fd31..82f7433d949ceef1b7283bcb65115d62f714a178 100644
--- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionManagementInterfaceTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionManagementInterfaceTest.php
@@ -50,8 +50,9 @@ class ProductAttributeOptionManagementInterfaceTest extends WebapiAbstract
 
     /**
      * @magentoApiDataFixture Magento/Catalog/Model/Product/Attribute/_files/select_attribute.php
+     * @dataProvider addDataProvider
      */
-    public function testAdd()
+    public function testAdd($optionData)
     {
         $this->_markTestAsRestOnly('Fix inconsistencies in WSDL and Data interfaces');
         $testAttributeCode = 'select_attribute';
@@ -67,18 +68,6 @@ class ProductAttributeOptionManagementInterfaceTest extends WebapiAbstract
             ],
         ];
 
-        $optionData = [
-            AttributeOptionInterface::LABEL => 'new color',
-            AttributeOptionInterface::SORT_ORDER => 100,
-            AttributeOptionInterface::IS_DEFAULT => true,
-            AttributeOptionInterface::STORE_LABELS => [
-                [
-                    AttributeOptionLabelInterface::LABEL => 'DE label',
-                    AttributeOptionLabelInterface::STORE_ID => 1,
-                ],
-            ],
-        ];
-
         $response = $this->_webApiCall(
             $serviceInfo,
             [
@@ -96,6 +85,37 @@ class ProductAttributeOptionManagementInterfaceTest extends WebapiAbstract
         );
     }
 
+    /**
+     * @return array
+     */
+    public function addDataProvider()
+    {
+        $optionPayload = [
+            AttributeOptionInterface::LABEL => 'new color',
+            AttributeOptionInterface::SORT_ORDER => 100,
+            AttributeOptionInterface::IS_DEFAULT => true,
+            AttributeOptionInterface::STORE_LABELS => [
+                [
+                    AttributeOptionLabelInterface::LABEL => 'DE label',
+                    AttributeOptionLabelInterface::STORE_ID => 1,
+                ],
+            ],
+        ];
+
+        return [
+            'option_without_value_node' => [
+                $optionPayload
+            ],
+            'option_with_value_node_that_starts_with_text' => [
+                array_merge($optionPayload, [AttributeOptionInterface::VALUE => 'some_text'])
+            ],
+            'option_with_value_node_that_starts_with_a_number' => [
+                array_merge($optionPayload, [AttributeOptionInterface::VALUE => '123_some_text'])
+            ],
+
+        ];
+    }
+
     /**
      * @magentoApiDataFixture Magento/Catalog/Model/Product/Attribute/_files/select_attribute.php
      */
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php
index 0571aa9ddad0354aeeda7e0add3ca6eff22aebca..558c7a020f35662b9eeff879766300a59c6fb667 100644
--- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php
@@ -142,8 +142,9 @@ class ProductAttributeRepositoryTest extends \Magento\TestFramework\TestCase\Web
             'attribute' => [
                 'attribute_id' => $attribute['attribute_id'],
                 'attribute_code' => $attributeCode,
+                'default_frontend_label' => 'default_label_new',
                 'frontend_labels' => [
-                    ['store_id' => 0, 'label' => 'front_lbl_new'],
+                    ['store_id' => 1, 'label' => 'front_lbl_new'],
                 ],
                 "options" => [
                     //Update existing
@@ -183,7 +184,7 @@ class ProductAttributeRepositoryTest extends \Magento\TestFramework\TestCase\Web
 
         $this->assertEquals($attribute['attribute_id'], $result['attribute_id']);
         $this->assertEquals($attributeCode, $result['attribute_code']);
-        $this->assertEquals('front_lbl_new', $result['default_frontend_label']);
+        $this->assertEquals('default_label_new', $result['default_frontend_label']);
         //New option set as default
         $this->assertEquals($result['options'][3]['value'], $result['default_value']);
         $this->assertEquals("Default Blue Updated", $result['options'][1]['label']);
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php
index f30c1bffa007546866cfd5c23ea24a3eefed42b7..4191ec1faa959aa1203ee45850c298f1d43bb988 100644
--- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php
@@ -275,6 +275,35 @@ class ProductRepositoryInterfaceTest extends WebapiAbstract
         $this->deleteProduct($fixtureProduct[ProductInterface::SKU]);
     }
 
+    /**
+     * Test creating product with all store code on single store
+     *
+     * @param array $fixtureProduct
+     * @dataProvider productCreationProvider
+     */
+    public function testCreateAllStoreCodeForSingleWebsite($fixtureProduct)
+    {
+        $response = $this->saveProduct($fixtureProduct, 'all');
+        $this->assertArrayHasKey(ProductInterface::SKU, $response);
+
+        /** @var \Magento\Store\Model\StoreManagerInterface $storeManager */
+        $storeManager = \Magento\TestFramework\ObjectManager::getInstance()->get(
+            \Magento\Store\Model\StoreManagerInterface::class
+        );
+
+        foreach ($storeManager->getStores(true) as $store) {
+            $code = $store->getCode();
+            if ($code === Store::ADMIN_CODE) {
+                continue;
+            }
+            $this->assertArrayHasKey(
+                ProductInterface::SKU,
+                $this->getProduct($fixtureProduct[ProductInterface::SKU], $code)
+            );
+        }
+        $this->deleteProduct($fixtureProduct[ProductInterface::SKU]);
+    }
+
     public function testCreateInvalidPriceFormat()
     {
         $this->_markTestAsRestOnly("In case of SOAP type casting is handled by PHP SoapServer, no need to test it");
diff --git a/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestBillingAddressManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestBillingAddressManagementTest.php
index fe811eb2dcd254cb0161324df4579820556a0c53..6a6d7073aca45c38b4d7a55d2b42b2130f5aa681 100644
--- a/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestBillingAddressManagementTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestBillingAddressManagementTest.php
@@ -88,8 +88,9 @@ class GuestBillingAddressManagementTest extends WebapiAbstract
 
     /**
      * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php
+     * @dataProvider setAddressDataProvider
      */
-    public function testSetAddress()
+    public function testSetAddress($useForShipping)
     {
         /** @var \Magento\Quote\Model\Quote $quote */
         $quote = $this->objectManager->create(\Magento\Quote\Model\Quote::class);
@@ -125,8 +126,9 @@ class GuestBillingAddressManagementTest extends WebapiAbstract
             'fax' => '44332255',
         ];
         $requestData = [
-            "cartId" => $cartId,
+            'cartId' => $cartId,
             'address' => $addressData,
+            'useForShipping' => $useForShipping
         ];
 
         $addressId = $this->_webApiCall($serviceInfo, $requestData);
@@ -149,5 +151,27 @@ class GuestBillingAddressManagementTest extends WebapiAbstract
         foreach ($addressData as $key => $value) {
             $this->assertEquals($value, $savedData[$key]);
         }
+        $address = $quote->getShippingAddress();
+        $address->getRegionCode();
+        $savedData = $address->getData();
+        if ($useForShipping) {
+            //check that shipping address set
+            $this->assertEquals('shipping', $savedData['address_type']);
+            $this->assertEquals(1, $savedData['same_as_billing']);
+            //check the rest of fields
+            foreach ($addressData as $key => $value) {
+                $this->assertEquals($value, $savedData[$key]);
+            }
+        } else {
+            $this->assertEquals(0, $savedData['same_as_billing']);
+        }
+    }
+
+    public function setAddressDataProvider()
+    {
+        return [
+            [true],
+            [false]
+        ];
     }
 }
diff --git a/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestCartTotalRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestCartTotalRepositoryTest.php
index c7227d4ecca16daa0b7757e957c9d6adef301083..3bf5d592fef3cef2942174cf59212442cb8d8a29 100644
--- a/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestCartTotalRepositoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestCartTotalRepositoryTest.php
@@ -54,7 +54,6 @@ class GuestCartTotalRepositoryTest extends WebapiAbstract
      */
     public function testGetTotals()
     {
-        $this->markTestSkipped('Will be fixed after MAGETWO-35573');
         /** @var \Magento\Quote\Model\Quote $quote */
         $quote = $this->objectManager->create(\Magento\Quote\Model\Quote::class);
         $quote->load('test_order_1', 'reserved_order_id');
@@ -86,6 +85,7 @@ class GuestCartTotalRepositoryTest extends WebapiAbstract
             Totals::KEY_BASE_SHIPPING_INCL_TAX => $shippingAddress->getBaseShippingInclTax(),
             Totals::KEY_BASE_CURRENCY_CODE => $quote->getBaseCurrencyCode(),
             Totals::KEY_QUOTE_CURRENCY_CODE => $quote->getQuoteCurrencyCode(),
+            Totals::KEY_ITEMS_QTY => $quote->getItemsQty(),
             Totals::KEY_ITEMS => [$this->getQuoteItemTotalsData($quote)],
         ];
 
@@ -93,7 +93,17 @@ class GuestCartTotalRepositoryTest extends WebapiAbstract
 
         $data = $this->formatTotalsData($data);
 
-        $this->assertEquals($data, $this->_webApiCall($this->getServiceInfoForTotalsService($cartId), $requestData));
+        $actual = $this->_webApiCall($this->getServiceInfoForTotalsService($cartId), $requestData);
+
+        unset($actual['items'][0]['options']);
+        unset($actual['weee_tax_applied_amount']);
+
+        unset($actual['total_segments']);
+        if (array_key_exists('extension_attributes', $actual)) {
+            unset($actual['extension_attributes']);
+        }
+
+        $this->assertEquals($data, $actual);
     }
 
     /**
@@ -162,6 +172,7 @@ class GuestCartTotalRepositoryTest extends WebapiAbstract
         $item = array_shift($items);
 
         return [
+            ItemTotals::KEY_ITEM_ID => $item->getItemId(),
             ItemTotals::KEY_PRICE => $item->getPrice(),
             ItemTotals::KEY_BASE_PRICE => $item->getBasePrice(),
             ItemTotals::KEY_QTY => $item->getQty(),
@@ -178,6 +189,9 @@ class GuestCartTotalRepositoryTest extends WebapiAbstract
             ItemTotals::KEY_BASE_PRICE_INCL_TAX => $item->getBasePriceInclTax(),
             ItemTotals::KEY_ROW_TOTAL_INCL_TAX => $item->getRowTotalInclTax(),
             ItemTotals::KEY_BASE_ROW_TOTAL_INCL_TAX => $item->getBaseRowTotalInclTax(),
+            ItemTotals::KEY_WEEE_TAX_APPLIED_AMOUNT => $item->getWeeeTaxAppliedAmount(),
+            ItemTotals::KEY_WEEE_TAX_APPLIED => $item->getWeeeTaxApplied(),
+            ItemTotals::KEY_NAME => $item->getName(),
         ];
     }
 }
diff --git a/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestShipmentEstimationTest.php b/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestShipmentEstimationTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9dea7ab05119d6767191445066b4994ce18998f7
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestShipmentEstimationTest.php
@@ -0,0 +1,109 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Quote\Api;
+
+use Magento\TestFramework\ObjectManager;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Quote\Api\Data\AddressInterface;
+
+class GuestShipmentEstimationTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+    const SERVICE_NAME = 'quoteGuestShipmentEstimationV1';
+    const RESOURCE_PATH = '/V1/guest-carts/';
+
+    /**
+     * @var ObjectManager
+     */
+    private $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/SalesRule/_files/cart_rule_free_shipping.php
+     * @magentoApiDataFixture Magento/Sales/_files/quote.php
+     */
+    public function testEstimateByExtendedAddress()
+    {
+        /** @var \Magento\Quote\Model\Quote $quote */
+        $quote = $this->objectManager->create(\Magento\Quote\Model\Quote::class);
+        $quote->load('test01', 'reserved_order_id');
+        $cartId = $quote->getId();
+        if (!$cartId) {
+            $this->fail('quote fixture failed');
+        }
+
+        /** @var \Magento\Quote\Model\QuoteIdMask $quoteIdMask */
+        $quoteIdMask = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
+            ->create(\Magento\Quote\Model\QuoteIdMaskFactory::class)
+            ->create();
+        $quoteIdMask->load($cartId, 'quote_id');
+        //Use masked cart Id
+        $cartId = $quoteIdMask->getMaskedId();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/guest-carts/' . $cartId . '/estimate-shipping-methods',
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => 'V1',
+                'operation' => self::SERVICE_NAME . 'EstimateByExtendedAddress',
+            ],
+        ];
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            /** @var \Magento\Quote\Model\Quote\Address $address */
+            $address = $quote->getBillingAddress();
+
+            $data = [
+                AddressInterface::KEY_ID => (int)$address->getId(),
+                AddressInterface::KEY_REGION => $address->getRegion(),
+                AddressInterface::KEY_REGION_ID => $address->getRegionId(),
+                AddressInterface::KEY_REGION_CODE => $address->getRegionCode(),
+                AddressInterface::KEY_COUNTRY_ID => $address->getCountryId(),
+                AddressInterface::KEY_STREET => $address->getStreet(),
+                AddressInterface::KEY_COMPANY => $address->getCompany(),
+                AddressInterface::KEY_TELEPHONE => $address->getTelephone(),
+                AddressInterface::KEY_POSTCODE => $address->getPostcode(),
+                AddressInterface::KEY_CITY => $address->getCity(),
+                AddressInterface::KEY_FIRSTNAME => $address->getFirstname(),
+                AddressInterface::KEY_LASTNAME => $address->getLastname(),
+                AddressInterface::KEY_CUSTOMER_ID => $address->getCustomerId(),
+                AddressInterface::KEY_EMAIL => $address->getEmail(),
+                AddressInterface::SAME_AS_BILLING => $address->getSameAsBilling(),
+                AddressInterface::CUSTOMER_ADDRESS_ID => $address->getCustomerAddressId(),
+                AddressInterface::SAVE_IN_ADDRESS_BOOK => $address->getSaveInAddressBook(),
+            ];
+
+            $requestData = [
+                'cartId' => $cartId,
+                'address' => $data
+            ];
+        } else {
+            $requestData = [
+                'address' => [
+                    'country_id' => "US",
+                    'postcode' => null,
+                    'region' => null,
+                    'region_id' => null
+                ],
+            ];
+        }
+        // Cart must be anonymous (see fixture)
+        $this->assertEmpty($quote->getCustomerId());
+
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertNotEmpty($result);
+        $this->assertEquals(1, count($result));
+        foreach ($result as $rate) {
+            $this->assertEquals("flatrate", $rate['carrier_code']);
+            $this->assertEquals(0, $rate['amount']);
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Quote/Api/ShippingMethodManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Quote/Api/ShippingMethodManagementTest.php
index 8ab7c765409b564ac55224f5e56ff06d52eb1b83..941a27cdbb69907d89936fce4442d55224bf3ff0 100644
--- a/dev/tests/api-functional/testsuite/Magento/Quote/Api/ShippingMethodManagementTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Quote/Api/ShippingMethodManagementTest.php
@@ -78,7 +78,6 @@ class ShippingMethodManagementTest extends WebapiAbstract
      */
     public function testGetListForMyCart()
     {
-        $this->markTestSkipped('Will be fixed after MAGETWO-35573');
         $this->_markTestAsRestOnly();
 
         $this->quote->load('test_order_1', 'reserved_order_id');
@@ -89,9 +88,9 @@ class ShippingMethodManagementTest extends WebapiAbstract
         );
         $token = $customerTokenService->createCustomerAccessToken('customer@example.com', 'password');
 
-        /** @var \Magento\Quote\Api\ShippingMethodManagementInterface $shippingMethodManagementService */
+        /** @var \Magento\Quote\Model\ShippingMethodManagementInterface $shippingMethodManagementService */
         $shippingMethodManagementService = $this->objectManager->create(
-            \Magento\Quote\Api\ShippingMethodManagementInterface::class
+            \Magento\Quote\Model\ShippingMethodManagementInterface::class
         );
         $shippingMethodManagementService->set($this->quote->getId(), 'flatrate', 'flatrate');
 
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoCancelTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoCancelTest.php
index d9f7bf1425c9663ab1b067436ce8348e873c1c34..8446c27d3d45ff60dee832290e6ade27999c621a 100644
--- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoCancelTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoCancelTest.php
@@ -20,10 +20,11 @@ class CreditmemoCancelTest extends WebapiAbstract
 
     /**
      * @magentoApiDataFixture Magento/Sales/_files/creditmemo_with_list.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage You can not cancel Credit Memo
      */
     public function testCreditmemoCancel()
     {
-        $this->markTestSkipped('You can not cancel Credit Memo');
         $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
 
         /** @var \Magento\Sales\Model\ResourceModel\Order\Creditmemo\Collection $creditmemoCollection */
@@ -44,7 +45,6 @@ class CreditmemoCancelTest extends WebapiAbstract
             ],
         ];
         $requestData = ['id' => $creditmemo->getId()];
-        $result = $this->_webApiCall($serviceInfo, $requestData);
-        $this->assertTrue($result);
+        $this->_webApiCall($serviceInfo, $requestData);
     }
 }
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderCreateTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderCreateTest.php
index 1bee8cdfa17804a7eb91db20d4400717aca50080..1279057089918c2154a42731799063dffc91f329 100755
--- a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderCreateTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderCreateTest.php
@@ -31,6 +31,9 @@ class OrderCreateTest extends WebapiAbstract
         $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
     }
 
+    /**
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
     protected function prepareOrder()
     {
         /** @var \Magento\Sales\Model\Order $orderBuilder */
@@ -41,6 +44,8 @@ class OrderCreateTest extends WebapiAbstract
         $orderPaymentFactory = $this->objectManager->get(\Magento\Sales\Model\Order\PaymentFactory::class);
         /** @var \Magento\Sales\Model\Order\AddressRepository $orderAddressRepository */
         $orderAddressRepository = $this->objectManager->get(\Magento\Sales\Model\Order\AddressRepository::class);
+        /** @var  \Magento\Store\Model\StoreManagerInterface $storeManager */
+        $storeManager = $this->objectManager->get(\Magento\Store\Model\StoreManagerInterface::class);
 
         $order = $orderFactory->create(
             ['data' => $this->getDataStructure(\Magento\Sales\Api\Data\OrderInterface::class)]
@@ -68,6 +73,32 @@ class OrderCreateTest extends WebapiAbstract
         $order->setCustomerEmail($email);
         $order->setBaseGrandTotal(100);
         $order->setGrandTotal(100);
+        $order->setShippingDescription('Flat Rate - Fixed');
+        $order->setIsVirtual(0);
+        $order->setStoreId($storeManager->getDefaultStoreView()->getId());
+        $order->setBaseDiscountAmount(0);
+        $order->setBaseShippingAmount(5);
+        $order->setBaseShippingTaxAmount(0);
+        $order->setBaseSubtotal(100);
+        $order->setBaseTaxAmount(0);
+        $order->setBaseToGlobalRate(1);
+        $order->setBaseToOrderRate(1);
+        $order->setDiscountAmount(0);
+        $order->setShippingAmount(0);
+        $order->setShippingTaxAmount(0);
+        $order->setStoreToOrderRate(0);
+        $order->setBaseToOrderRate(0);
+        $order->setSubtotal(100);
+        $order->setTaxAmount(0);
+        $order->setTotalQtyOrdered(1);
+        $order->setCustomerIsGuest(1);
+        $order->setCustomerNoteNotify(0);
+        $order->setCustomerGroupId(0);
+        $order->setBaseSubtotalInclTax(100);
+        $order->setWeight(1);
+        $order->setBaseCurrencyCode('USD');
+        $order->setShippingInclTax(5);
+        $order->setBaseShippingInclTax(5);
 
         $this->addProductOption($orderItem);
 
@@ -82,12 +113,39 @@ class OrderCreateTest extends WebapiAbstract
         $orderAddressBilling->setFirstname('First Name');
         $orderAddressBilling->setTelephone('+00(000)-123-45-57');
         $orderAddressBilling->setStreet(['Street']);
-        $orderAddressBilling->setCountryId(1);
+        $orderAddressBilling->setCountryId('US');
+        $orderAddressBilling->setRegion('California');
         $orderAddressBilling->setAddressType('billing');
+        $orderAddressBilling->setRegionId(12);
+
+        $orderAddressShipping = $orderAddressRepository->create();
+        $orderAddressShipping->setCity('City2');
+        $orderAddressShipping->setPostcode('12345');
+        $orderAddressShipping->setLastname('Last Name2');
+        $orderAddressShipping->setFirstname('First Name2');
+        $orderAddressShipping->setTelephone('+00(000)-123-45-57');
+        $orderAddressShipping->setStreet(['Street']);
+        $orderAddressShipping->setCountryId('US');
+        $orderAddressShipping->setRegion('California');
+        $orderAddressShipping->setAddressType('shipping');
+        $orderAddressShipping->setRegionId(12);
 
         $orderData = $order->getData();
         $orderData['billing_address'] = $orderAddressBilling->getData();
         $orderData['billing_address']['street'] = ['Street'];
+        $address = $orderAddressShipping->getData();
+        $address['street'] = ['Street'];
+        $orderData['extension_attributes']['shipping_assignments'] =
+            [
+                [
+                    'shipping' => [
+                        'address' => $address,
+                        'method' => 'Flat Rate - Fixed'
+                    ],
+                    'items' => [$orderItem->getData()],
+                    'stock_id' => null,
+                ]
+            ];
         return $orderData;
     }
 
@@ -172,5 +230,8 @@ class OrderCreateTest extends WebapiAbstract
         $this->assertTrue((bool)$model->getId());
         $this->assertEquals($order['base_grand_total'], $model->getBaseGrandTotal());
         $this->assertEquals($order['grand_total'], $model->getGrandTotal());
+        $this->assertNotNull($model->getShippingAddress());
+        $this->assertTrue((bool)$model->getShippingAddress()->getId());
+        $this->assertEquals('Flat Rate - Fixed', $model->getShippingMethod());
     }
 }
diff --git a/dev/tests/api-functional/testsuite/Magento/SalesInventory/Api/Service/V1/ReturnItemsAfterRefundOrderTest.php b/dev/tests/api-functional/testsuite/Magento/SalesInventory/Api/Service/V1/ReturnItemsAfterRefundOrderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..68ecebec27c0b0812d76eb7be8c2ac063aff54ef
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/SalesInventory/Api/Service/V1/ReturnItemsAfterRefundOrderTest.php
@@ -0,0 +1,114 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\SalesInventory\Api\Service\V1;
+
+/**
+ * API test for return items to stock
+ */
+class ReturnItemsAfterRefundOrderTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    const SERVICE_REFUND_ORDER_NAME = 'salesRefundOrderV1';
+    const SERVICE_STOCK_ITEMS_NAME = 'stockItems';
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    private $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @dataProvider dataProvider
+     * @magentoApiDataFixture Magento/Sales/_files/order_with_shipping_and_invoice.php
+     */
+    public function testRefundWithReturnItemsToStock($qtyRefund)
+    {
+        $productSku = 'simple';
+        /** @var \Magento\Sales\Model\Order $existingOrder */
+        $existingOrder = $this->objectManager->create(\Magento\Sales\Model\Order::class)
+            ->loadByIncrementId('100000001');
+        $orderItems = $existingOrder->getItems();
+        $orderItem = array_shift($orderItems);
+        $expectedItems = [['order_item_id' => $orderItem->getItemId(), 'qty' => $qtyRefund]];
+        $qtyBeforeRefund = $this->getQtyInStockBySku($productSku);
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/order/' . $existingOrder->getEntityId() . '/refund',
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_REFUND_ORDER_NAME,
+                'serviceVersion' => 'V1',
+                'operation' => self::SERVICE_REFUND_ORDER_NAME . 'execute',
+            ]
+        ];
+
+        $this->_webApiCall(
+            $serviceInfo,
+            [
+                'orderId' => $existingOrder->getEntityId(),
+                'items' => $expectedItems,
+                'arguments' => [
+                    'extension_attributes' => [
+                        'return_to_stock_items' => [
+                            (int)$orderItem->getItemId()
+                        ],
+                    ],
+                ],
+            ]
+        );
+
+        $qtyAfterRefund = $this->getQtyInStockBySku($productSku);
+
+        try {
+            $this->assertEquals(
+                $qtyBeforeRefund + $expectedItems[0]['qty'],
+                $qtyAfterRefund,
+                'Failed asserting qty of returned items incorrect.'
+            );
+
+        } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
+            $this->fail('Failed asserting that Creditmemo was created');
+        }
+    }
+
+    /**
+     * @return array
+     */
+    public function dataProvider()
+    {
+        return [
+            'refundAllOrderItems' => [2],
+            'refundPartition' => [1],
+        ];
+    }
+
+    /**
+     * @param string $sku
+     * @return int
+     */
+    private function getQtyInStockBySku($sku)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/' . self::SERVICE_STOCK_ITEMS_NAME . "/$sku",
+                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => 'catalogInventoryStockRegistryV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'catalogInventoryStockRegistryV1GetStockItemBySku',
+            ],
+        ];
+        $arguments = ['productSku' => $sku];
+        $apiResult = $this->_webApiCall($serviceInfo, $arguments);
+        return $apiResult['qty'];
+    }
+}
diff --git a/dev/tests/functional/lib/Magento/Mtf/Util/Command/Cli/Setup.php b/dev/tests/functional/lib/Magento/Mtf/Util/Command/Cli/Setup.php
new file mode 100644
index 0000000000000000000000000000000000000000..ceb84eb46acc97c590440e2f7f5e6031ddc969b4
--- /dev/null
+++ b/dev/tests/functional/lib/Magento/Mtf/Util/Command/Cli/Setup.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Mtf\Util\Command\Cli;
+
+use Magento\Mtf\Util\Command\Cli;
+
+/**
+ * Setup Magento for tests executions.
+ */
+class Setup extends Cli
+{
+    /**
+     * Parameter for uninstall Magento command.
+     */
+    const PARAM_SETUP_UNINSTALL = 'setup:uninstall';
+
+    /**
+     * Options for uninstall Magento command.
+     *
+     * @var array
+     */
+    private $options = ['-n'];
+
+    /**
+     * Uninstall Magento.
+     *
+     * @return void
+     */
+    public function uninstall()
+    {
+        parent::execute(Setup::PARAM_SETUP_UNINSTALL, $this->options);
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.xml
index 58612f7dee1701313654dcad53fa7819add8a382..6e214d4c205aacc72fa8b93cbd4c082d2d02fa96 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/SaveUseDeleteVaultForPaypalBraintreeTest.xml
@@ -19,6 +19,7 @@
                 <item name="grandTotal" xsi:type="string">15.00</item>
             </data>
             <data name="payment/method" xsi:type="string">braintree_paypal</data>
+            <data name="vault/method" xsi:type="string">braintree_paypal_vault</data>
             <data name="creditCardSave" xsi:type="string">Yes</data>
             <data name="configData" xsi:type="string">braintree, braintree_paypal, braintree_paypal_use_vault</data>
             <data name="status" xsi:type="string">Processing</data>
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultOnCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultOnCheckoutTest.xml
index 4b061fb2664b83b558700654aa9565ed39556b6b..00eb9c4802db6216bd1dbc0202231612166b306c 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultOnCheckoutTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultOnCheckoutTest.xml
@@ -16,6 +16,7 @@
             <data name="shipping/shipping_service" xsi:type="string">Flat Rate</data>
             <data name="shipping/shipping_method" xsi:type="string">Fixed</data>
             <data name="payment/method" xsi:type="string">braintree</data>
+            <data name="vault/method" xsi:type="string">braintree_cc_vault</data>
             <data name="creditCardClass" xsi:type="string">credit_card_braintree</data>
             <data name="creditCard/dataset" xsi:type="string">visa_braintree</data>
             <data name="creditCardSave" xsi:type="string">Yes</data>
diff --git a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.xml
index 1aaa684db5c66ab86ab46165a0ec9242dfe0e042..0f00ff93612b8b1ef7792971b38846efbe3d2b43 100644
--- a/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Braintree/Test/TestCase/UseVaultWith3dSecureOnCheckoutTest.xml
@@ -16,6 +16,7 @@
             <data name="shipping/shipping_service" xsi:type="string">Flat Rate</data>
             <data name="shipping/shipping_method" xsi:type="string">Fixed</data>
             <data name="payment/method" xsi:type="string">braintree</data>
+            <data name="vault/method" xsi:type="string">braintree_cc_vault</data>
             <data name="creditCardClass" xsi:type="string">credit_card_braintree</data>
             <data name="creditCard/dataset" xsi:type="string">visa_braintree_3dsecure</data>
             <data name="paymentInformation" xsi:type="array">
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct/CheckoutData.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct/CheckoutData.xml
index 97c11284d77c88194a5a5271e31ca7b91a4babf3..3e7550b9d784e3858bd9800e66b88b8c60326b1b 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct/CheckoutData.xml
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/BundleProduct/CheckoutData.xml
@@ -95,9 +95,9 @@
             </field>
             <field name="qty" xsi:type="string">1</field>
             <field name="cartItem" xsi:type="array">
-                <item name="price" xsi:type="string">756</item>
+                <item name="price" xsi:type="string">755</item>
                 <item name="qty" xsi:type="string">1</item>
-                <item name="subtotal" xsi:type="string">756</item>
+                <item name="subtotal" xsi:type="string">755</item>
             </field>
         </dataset>
 
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.xml
index 42f490d76191a524b12c7837ab5958907199fece..dff1a9fd71d865dd52fd6cdd0e05d3e3d000db94 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.xml
@@ -8,7 +8,7 @@
 <sections>
     <general_information>
         <class>\Magento\Ui\Test\Block\Adminhtml\Section</class>
-        <selector>div[class=fieldset-wrapper]</selector>
+        <selector>[data-index="general"]</selector>
         <strategy>css selector</strategy>
         <fields>
             <is_active>
@@ -31,8 +31,8 @@
     </general_information>
     <content>
         <class>\Magento\Ui\Test\Block\Adminhtml\Section</class>
-        <selector>//div[contains(@class,'admin__collapsible-block-wrapper')][descendant::select[@name='landing_page']]</selector>
-        <strategy>xpath</strategy>
+        <selector>[data-index="content"]</selector>
+        <strategy>css selector</strategy>
         <fields>
             <description>
                 <input>textarea</input>
@@ -45,8 +45,8 @@
     </content>
     <display_setting>
         <class>\Magento\Ui\Test\Block\Adminhtml\Section</class>
-        <selector>//div[contains(@class,'admin__collapsible-block-wrapper')][descendant::input[@name='is_anchor']]</selector>
-        <strategy>xpath</strategy>
+        <selector>[data-index="display_settings"]</selector>
+        <strategy>css selector</strategy>
         <fields>
             <display_mode>
                 <input>select</input>
@@ -83,8 +83,8 @@
     </display_setting>
     <seo>
         <class>\Magento\Ui\Test\Block\Adminhtml\Section</class>
-        <selector>//div[contains(@class,'admin__collapsible-block-wrapper')][descendant::input[@name='meta_title']]</selector>
-        <strategy>xpath</strategy>
+        <selector>[data-index="search_engine_optimization"]</selector>
+        <strategy>css selector</strategy>
         <fields>
             <url_key>
                 <input>input</input>
@@ -98,13 +98,13 @@
     </seo>
     <category_products>
         <class>\Magento\Catalog\Test\Block\Adminhtml\Category\Edit\Section\Products</class>
-        <selector>//div[contains(@class,'admin__collapsible-block-wrapper')][descendant::div[@id='catalog_category_products']]</selector>
-        <strategy>xpath</strategy>
+        <selector>[data-index="assign_products"]</selector>
+        <strategy>css selector</strategy>
     </category_products>
     <design>
         <class>\Magento\Ui\Test\Block\Adminhtml\Section</class>
-        <selector>//div[contains(@class,'admin__collapsible-block-wrapper')][descendant::select[@name='page_layout']]</selector>
-        <strategy>xpath</strategy>
+        <selector>[data-index="design"]</selector>
+        <strategy>css selector</strategy>
         <fields>
             <use_parent_category_settings>
                 <input>checkbox</input>
@@ -130,8 +130,8 @@
     </design>
     <schedule_design_update>
         <class>\Magento\Ui\Test\Block\Adminhtml\Section</class>
-        <selector>//div[contains(@class,'admin__collapsible-block-wrapper')][descendant::input[@name='custom_design_to']]</selector>
-        <strategy>xpath</strategy>
+        <selector>[data-index="schedule_design_update"]</selector>
+        <strategy>css selector</strategy>
         <fields>
             <schedule_update_from>
                 <input>datepicker</input>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/Attribute.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/Attribute.php
deleted file mode 100644
index ca29475c03c90181f7caa0849e11a7639b023158..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/Attribute.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-/**
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Action;
-
-use Magento\Mtf\Fixture\FixtureInterface;
-use Magento\Mtf\Block\Form;
-use Magento\Mtf\Client\Element\SimpleElement;
-
-/**
- * Product attribute massaction edit page.
- */
-class Attribute extends Form
-{
-    /**
-     * Fill the root form.
-     *
-     * @param FixtureInterface $fixture
-     * @param SimpleElement|null $element
-     * @return $this
-     */
-    public function fill(FixtureInterface $fixture, SimpleElement $element = null)
-    {
-        $data = $fixture->getData();
-        $fields = [];
-        foreach ($data as $name => $dataValue) {
-            $fields['toggle_' . $name] = 'Yes';
-            $fields[$name] = $dataValue;
-        }
-        $mapping = $this->dataMapping($fields);
-        $this->_fill($mapping, $element);
-
-        return $this;
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/Attribute.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/Attribute.xml
deleted file mode 100644
index 59b367e49bd66b8dce3cfb1e25dc4b46f9e2eff8..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/Attribute.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" ?>
-<!--
-/**
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<mapping strict="0">
-    <wrapper>attributes</wrapper>
-    <fields>
-        <toggle_price>
-            <selector>[name='toggle_price']</selector>
-            <input>checkbox</input>
-        </toggle_price>
-        <price />
-    </fields>
-</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/Tab/UpdateAttributeTab.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/Tab/UpdateAttributeTab.php
new file mode 100644
index 0000000000000000000000000000000000000000..d61c2001a2096ebaedd895a0c483d5a93a9ae8bd
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/Tab/UpdateAttributeTab.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Action\Tab;
+
+use Magento\Mtf\Client\Element\SimpleElement;
+use Magento\Mtf\Client\Locator;
+use Magento\Backend\Test\Block\Widget\Tab;
+
+/**
+ * Tab on Product update attributes Form.
+ */
+class UpdateAttributeTab extends Tab
+{
+    /**
+     * Change checkbox.
+     *
+     * @var string
+     */
+    private $changeCheckbox = [
+        'selector' => './/./ancestor::div[contains(@class,"control")]'
+            . '//input[@data-role="toggle-editability-all" or contains(@id, "toggle_")]',
+        'strategy' => Locator::SELECTOR_XPATH,
+        'input' => 'checkbox',
+        'value' => 'Yes',
+    ];
+
+    /**
+     * Fill data into fields in the container.
+     *
+     * @param array $fields
+     * @param SimpleElement|null $contextElement
+     * @return $this
+     */
+    public function setFieldsData(array $fields, SimpleElement $contextElement = null)
+    {
+        $context = ($contextElement === null) ? $this->_rootElement : $contextElement;
+        $mapping = $this->dataMapping($fields);
+        foreach ($mapping as $field) {
+            $this->_fill([$this->changeCheckbox], $context->find($field['selector'], $field['strategy']));
+            $this->_fill([$field], $context);
+        }
+
+        return $this;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/UpdateAttributeForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/UpdateAttributeForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..a264c491de43aa6fdfd22eb98793316e79996054
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/UpdateAttributeForm.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Action;
+
+use Magento\Backend\Test\Block\Widget\FormTabs;
+
+/**
+ * Product update Attributes Form.
+ */
+class UpdateAttributeForm extends FormTabs
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/UpdateAttributeForm.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/UpdateAttributeForm.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba8effd797a3dc85e92601fd7037815ef02c91a9
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/UpdateAttributeForm.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<tabs>
+    <product-details>
+        <class>Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Action\Tab\UpdateAttributeTab</class>
+        <selector>#attributes_update_tabs_attributes</selector>
+        <fields>
+            <price>
+                <selector>#price</selector>
+            </price>
+        </fields>
+    </product-details>
+    <advanced-inventory>
+        <class>Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Action\Tab\UpdateAttributeTab</class>
+        <selector>#attributes_update_tabs_inventory</selector>
+        <fields>
+            <stock_data>
+                <selector>#inventory_stock_availability</selector>
+                <input>select</input>
+            </stock_data>
+        </fields>
+    </advanced-inventory>
+</tabs>
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 d5e81ad56fd3290ef906c8cb141da8e583757c24..db73f7cc87f177fb1eb05f0184b238cb82cd47f1 100755
--- 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
@@ -7,6 +7,7 @@
 namespace Magento\Catalog\Test\Block\Adminhtml\Product;
 
 use Magento\Ui\Test\Block\Adminhtml\DataGrid;
+use Magento\Mtf\Fixture\FixtureInterface;
 
 /**
  * Backend catalog product grid.
@@ -72,12 +73,17 @@ class Grid extends DataGrid
     /**
      * Update attributes for selected items.
      *
-     * @param array $items [optional]
+     * @param array $items
      * @return void
      */
     public function updateAttributes(array $items = [])
     {
-        $this->massaction($items, 'Update attributes');
+        $products = [];
+        /** @var FixtureInterface $product */
+        foreach ($items as $product) {
+            $products[] = ["sku" => $product->getSku()];
+        }
+        $this->massaction($products, 'Update attributes');
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Compare/ListCompare.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Compare/ListCompare.php
index 546b055b0045b29d6cfe216b1b0efdc7407ebc0a..4de51f3e2ca9b8d5089cb6818d380f0ac9465e46 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Compare/ListCompare.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Compare/ListCompare.php
@@ -86,6 +86,13 @@ class ListCompare extends Block
      */
     protected $messageBlock = '#messages';
 
+    /**
+     * Selector for confirm.
+     *
+     * @var string
+     */
+    protected $confirmModal = '.confirm._show[data-role=modal]';
+
     /**
      * Get product info.
      *
@@ -189,6 +196,13 @@ class ListCompare extends Block
     public function removeProduct($index = 1)
     {
         $this->_rootElement->find(sprintf($this->removeButton, $index), Locator::SELECTOR_XPATH)->click();
+        $modalElement = $this->browser->find($this->confirmModal);
+        /** @var \Magento\Ui\Test\Block\Adminhtml\Modal $modal */
+        $modal = $this->blockFactory->create(
+            \Magento\Ui\Test\Block\Adminhtml\Modal::class,
+            ['element' => $modalElement]
+        );
+        $modal->acceptAlert();
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Compare/Sidebar.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Compare/Sidebar.php
index 596dbd38664b3b097302e6f6f0e62d13fbe96017..ab65865af6534c2b2478490b7f08fd7f108496fe 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Compare/Sidebar.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Compare/Sidebar.php
@@ -32,6 +32,13 @@ class Sidebar extends ListCompare
      */
     protected $clearAll = '#compare-clear-all';
 
+    /**
+     * Selector for confirm.
+     *
+     * @var string
+     */
+    protected $confirmModal = '.confirm._show[data-role=modal]';
+
     /**
      * Get compare products block content.
      *
@@ -79,5 +86,12 @@ class Sidebar extends ListCompare
             }
         );
         $this->_rootElement->find($this->clearAll)->click();
+        $modalElement = $this->browser->find($this->confirmModal);
+        /** @var \Magento\Ui\Test\Block\Adminhtml\Modal $modal */
+        $modal = $this->blockFactory->create(
+            \Magento\Ui\Test\Block\Adminhtml\Modal::class,
+            ['element' => $modalElement]
+        );
+        $modal->acceptAlert();
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/TopToolbar.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/TopToolbar.php
index 100930ad20aea7a40eff2fcf6b367c85db48a242..3d5e550560e857b8530037637b4f97f7763874e2 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/TopToolbar.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/TopToolbar.php
@@ -28,7 +28,9 @@ class TopToolbar extends Block
      */
     public function getSelectSortType()
     {
-        return $this->_rootElement->find("#sorter")->getElements('option[selected]')[0]->getText();
+        $selectedOption = $this->_rootElement->find($this->sorter)->getElements('option[selected]')[0]->getText();
+        preg_match('/\w+\s?\w+/', $selectedOption, $matches);
+        return $matches[0];
     }
 
     /**
@@ -38,7 +40,8 @@ class TopToolbar extends Block
      */
     public function getSortType()
     {
-        $content = str_replace("\r", '', $this->_rootElement->find($this->sorter)->getText());
-        return explode("\n", $content);
+        $content = $this->_rootElement->find($this->sorter)->getText();
+        preg_match_all('/\w+\s?\w+/', $content, $matches);
+        return $matches[0];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddedProductAttributeOnProductForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddedProductAttributeOnProductForm.php
index 78e28abebe44bfd8f009fa8aee49f0d77e6c974a..54bf06f70b5f1c0f192b79bda3ade75a85cd37f7 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddedProductAttributeOnProductForm.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddedProductAttributeOnProductForm.php
@@ -92,9 +92,8 @@ class AssertAddedProductAttributeOnProductForm extends AbstractConstraint
         $catalogProductAttribute = ($productAttributeOriginal !== null)
             ? array_merge($productAttributeOriginal->getData(), $attribute->getData())
             : $attribute->getData();
-        if ($catalogProductEdit->getProductForm()->isSectionVisible(self::ATTRIBUTES)) {
-            $catalogProductEdit->getProductForm()->openSection(self::ATTRIBUTES);
-        }
+        $catalogProductEdit->getProductForm()->openSection(self::ATTRIBUTES);
+
         \PHPUnit_Framework_Assert::assertTrue(
             $catalogProductEdit->getProductForm()->checkAttributeLabel($catalogProductAttribute),
             "Product Attribute is absent on Product form."
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertMassProductUpdateSuccessMessage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertMassProductUpdateSuccessMessage.php
index 1666244802ed2e81c5375c2d41b0df0dff0a0191..df326a9ca0023a3c3fbeb45a2c960e88d9fffc32 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertMassProductUpdateSuccessMessage.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertMassProductUpdateSuccessMessage.php
@@ -23,13 +23,12 @@ class AssertMassProductUpdateSuccessMessage extends AbstractConstraint
      * Assert that after mass update successful message appears.
      *
      * @param CatalogProductIndex $productGrid
-     * @param array $products
+     * @param int $productsCount
      * @return void
      */
-    public function processAssert(CatalogProductIndex $productGrid, $products = [])
+    public function processAssert(CatalogProductIndex $productGrid, $productsCount)
     {
-        $countProducts = count($products) ? count($products) : 1;
-        $expectedMessage = sprintf(self::SUCCESS_MESSAGE, $countProducts);
+        $expectedMessage = sprintf(self::SUCCESS_MESSAGE, $productsCount);
         $actualMessage = $productGrid->getMessagesBlock()->getSuccessMessage();
         \PHPUnit_Framework_Assert::assertEquals(
             $expectedMessage,
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductsInStock.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductsInStock.php
new file mode 100644
index 0000000000000000000000000000000000000000..f485076d5c018b97dfc67624d505bb617929b901
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductsInStock.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Catalog\Test\Constraint;
+
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
+use Magento\Mtf\Client\BrowserInterface;
+use Magento\Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Assert that all products are in stock.
+ */
+class AssertProductsInStock extends AbstractConstraint
+{
+    /**
+     * Assert that In Stock status is displayed for products.
+     *
+     * @param CatalogProductView $catalogProductView
+     * @param BrowserInterface $browser
+     * @param AssertProductInStock $assertProductInStock
+     * @param array $products
+     * @return void
+     */
+    public function processAssert(
+        CatalogProductView $catalogProductView,
+        BrowserInterface $browser,
+        AssertProductInStock $assertProductInStock,
+        array $products
+    ) {
+        foreach ($products as $product) {
+            $assertProductInStock->processAssert($catalogProductView, $browser, $product);
+        }
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'In stock control is visible for each product.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductActionAttributeEdit.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductActionAttributeEdit.xml
index e875bdc0817e9bcd97b4c933de90ede7498aec7a..1ff06177a5a20b716f1a24201a785c1ff12eecd6 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductActionAttributeEdit.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductActionAttributeEdit.xml
@@ -7,7 +7,7 @@
  -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd">
     <page name="CatalogProductActionAttributeEdit" area="Adminhtml" mca="catalog/product_action_attribute/edit" module="Magento_Catalog">
-        <block name="attributesBlockForm" class="Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Action\Attribute" locator="body" strategy="css selector" />
+        <block name="attributesBlockForm" class="Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Action\UpdateAttributeForm" locator="body" strategy="css selector" />
         <block name="formPageActions" class="Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Action\FormPageActions" locator=".page-main-actions" strategy="css selector" />
     </page>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual/CheckoutData.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual/CheckoutData.xml
index 026b32c0219803432c69b250e786de07d2f5e13d..5fb85d4c4f0532244824289a2e14267b6679253a 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual/CheckoutData.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual/CheckoutData.xml
@@ -34,6 +34,11 @@
 
         <dataset name="virtual_update_mini_shopping_cart">
             <field name="qty" xsi:type="string">2</field>
+            <field name="cartItem" xsi:type="array">
+                <item name="price" xsi:type="string">10</item>
+                <item name="qty" xsi:type="string">2</item>
+                <item name="subtotal" xsi:type="string">20</item>
+            </field>
         </dataset>
     </repository>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Category.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Category.xml
index 30f870dea88f063a7278d7380f5d4fe24f508c9f..2fd8c04d1d80dfe643616ee7c550699da91aeece 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Category.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Category.xml
@@ -67,7 +67,7 @@
             <field name="name" xsi:type="string">Category%isolation%</field>
             <field name="url_key" xsi:type="string">category-%isolation%</field>
             <field name="parent_id" xsi:type="array">
-                <item name="dataset" xsi:type="string">default_subcategory</item>
+                <item name="dataset" xsi:type="string">default</item>
             </field>
             <field name="is_active" xsi:type="string">Yes</field>
             <field name="include_in_menu" xsi:type="string">Yes</field>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/ConfigData.xml
index 0b3452cc147824b89443c33ca86d29cbebcb7ae7..9ae1e2ebfacca405f8505496f546cf2182e2dd3f 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/ConfigData.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/ConfigData.xml
@@ -23,5 +23,16 @@
                 <item name="value" xsi:type="number">0</item>
             </field>
         </dataset>
+        <dataset name="empty_product_mask_sku">
+            <field name="catalog/fields_masks/sku" xsi:type="array">
+                <item name="value" xsi:type="string"/>
+            </field>
+        </dataset>
+        <dataset name="empty_product_mask_sku_rollback">
+            <field name="catalog/fields_masks/sku" xsi:type="array">
+                <item name="value" xsi:type="string">{{name}}</item>
+                <item name="inherit" xsi:type="number">1</item>
+            </field>
+        </dataset>
     </repository>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Product/TierPrice.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Product/TierPrice.xml
index bdfb5deabe5c2828b947130284f0308353fa6bdc..412818cbe40e71634eb1e635d8dc8e1630913b49 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Product/TierPrice.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/Product/TierPrice.xml
@@ -66,5 +66,16 @@
                 </item>
             </field>
         </dataset>
+
+        <dataset name="not_logged_in">
+            <field name="0" xsi:type="array">
+                <item name="price" xsi:type="string">90</item>
+                <item name="website" xsi:type="string">All Websites [USD]</item>
+                <item name="price_qty" xsi:type="string">2</item>
+                <item name="customer_group" xsi:type="array">
+                    <item name="dataset" xsi:type="string">NOT_LOGGED_IN</item>
+                </item>
+            </field>
+        </dataset>
     </repository>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml
index 7e6f913dda6e7fd88c0723ccbd5e899ccbeeaafe..22cdab45ac875c6a6987892898e3c8dda3382944 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.xml
@@ -39,8 +39,8 @@
             <data name="category/data/layout_update_xml" xsi:type="string">&#60;referenceContainer name=&quot;catalog.leftnav&quot; remove=&quot;true&quot;/&#62;</data>
             <data name="category/data/new_theme" xsi:type="string">Magento Luma</data>
             <data name="category/data/apply_design_to_products" xsi:type="string">Yes</data>
-            <data name="category/data/schedule_update_from" xsi:type="string">Jan 10, 2014</data>
-            <data name="category/data/schedule_update_to" xsi:type="string">Dec 31, 2024</data>
+            <data name="category/data/schedule_update_from" xsi:type="string">01/10/2014</data>
+            <data name="category/data/schedule_update_to" xsi:type="string">12/31/2024</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertCategorySaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryForm" />
         </variation>
@@ -82,8 +82,8 @@
             <data name="category/data/layout_update_xml" xsi:type="string">&#60;referenceContainer name=&quot;content.aside&quot; remove=&quot;true&quot;/&#62;</data>
             <data name="category/data/new_theme" xsi:type="string">Magento Luma</data>
             <data name="category/data/apply_design_to_products" xsi:type="string">Yes</data>
-            <data name="category/data/schedule_update_from" xsi:type="string">Jan 1, 2014</data>
-            <data name="category/data/schedule_update_to" xsi:type="string">Dec 31, 2024</data>
+            <data name="category/data/schedule_update_from" xsi:type="string">01/10/2014</data>
+            <data name="category/data/schedule_update_to" xsi:type="string">12/31/2024</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertCategorySaveMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryForm" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertCategoryPage" />
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.xml
index e46ad32551e7496f8ffb443543612567304ce5ee..9e410c525deef720573e7c93e0de4d463b9b2ac7 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleProductEntityTest.xml
@@ -168,7 +168,7 @@
             <data name="product/data/url_key" xsi:type="string">simple-product-%isolation%</data>
             <data name="product/data/name" xsi:type="string">Simple Product %isolation%</data>
             <data name="product/data/sku" xsi:type="string">simple_sku_%isolation%</data>
-            <data name="product/data/price/value" xsi:type="string">10008</data>
+            <data name="product/data/price/value" xsi:type="string">10008.88</data>
             <data name="product/data/short_description" xsi:type="string">Simple Product short_description %isolation%</data>
             <data name="product/data/description" xsi:type="string">Simple Product description %isolation%</data>
             <data name="product/data/weight" xsi:type="string">58</data>
@@ -461,5 +461,44 @@
             <data name="product/data/country_of_manufacture" xsi:type="string">Antarctica</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
         </variation>
+        <variation name="CreateSimpleProductEntityTestVariation28" summary="Create product with tier price for not logged in customer">
+            <data name="product/data/url_key" xsi:type="string">simple-product-%isolation%</data>
+            <data name="product/data/name" xsi:type="string">Simple Product %isolation%</data>
+            <data name="product/data/sku" xsi:type="string">simple_sku_%isolation%</data>
+            <data name="product/data/price/value" xsi:type="string">100</data>
+            <data name="product/data/weight" xsi:type="string">50</data>
+            <data name="product/data/quantity_and_stock_status/qty" xsi:type="string">667</data>
+            <data name="product/data/tier_price/dataset" xsi:type="string">not_logged_in</data>
+            <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
+            <constraint name="Magento\Catalog\Test\Constraint\AssertProductTierPriceOnProductPage" />
+        </variation>
+        <variation name="CreateSimpleProductEntityTestVariation29" summary="Create Simple Product and assign it to custom website">
+            <data name="product/data/url_key" xsi:type="string">simple-product-%isolation%</data>
+            <data name="product/data/name" xsi:type="string">Simple Product %isolation%</data>
+            <data name="product/data/sku" xsi:type="string">simple_sku_%isolation%</data>
+            <data name="product/data/price/value" xsi:type="string">200.20</data>
+            <data name="product/data/weight" xsi:type="string">50</data>
+            <data name="product/data/quantity_and_stock_status/qty" xsi:type="string">668</data>
+            <data name="product/data/website_ids/0/dataset" xsi:type="string">custom_store</data>
+            <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
+            <constraint name="Magento\Catalog\Test\Constraint\AssertProductOnCustomWebsite" />
+        </variation>
+        <variation name="CreateSimpleProductEntityWithEmptySkuMaskTest1"  summary="Create Simple Product Entity With Empty Sku Mask" ticketId="MAGETWO-58951">
+            <data name="configData" xsi:type="string">empty_product_mask_sku</data>
+            <data name="description" xsi:type="string">Create product with custom options(fixed price)</data>
+            <data name="product/data/url_key" xsi:type="string">simple-product-%isolation%</data>
+            <data name="product/data/name" xsi:type="string">Simple Product %isolation%</data>
+            <data name="product/data/sku" xsi:type="string">simple_sku_%isolation%</data>
+            <data name="product/data/price/value" xsi:type="string">10000</data>
+            <data name="product/data/weight" xsi:type="string">50</data>
+            <data name="product/data/quantity_and_stock_status/qty" xsi:type="string">657</data>
+            <data name="product/data/checkout_data/dataset" xsi:type="string">simple_drop_down_with_one_option_fixed_price</data>
+            <data name="product/data/price/dataset" xsi:type="string">drop_down_with_one_option_fixed_price</data>
+            <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
+            <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
+            <constraint name="Magento\Catalog\Test\Constraint\AssertProductInCategory" />
+            <constraint name="Magento\Catalog\Test\Constraint\AssertProductPage" />
+            <constraint name="Magento\Catalog\Test\Constraint\AssertProductInCart" />
+        </variation>
     </testCase>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/MassProductUpdateTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/MassProductUpdateTest.php
index f7fd82e3342bfdce8760c253215ad8189ef33643..9c38ff1b479fe6a02f2217572bea170b1906f00d 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/MassProductUpdateTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/MassProductUpdateTest.php
@@ -6,10 +6,13 @@
 
 namespace Magento\Catalog\Test\TestCase\Product;
 
+use Magento\Mtf\Fixture\FixtureFactory;
+use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\TestCase\Injectable;
 use Magento\Catalog\Test\Fixture\CatalogProductSimple;
 use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
 use Magento\Catalog\Test\Page\Adminhtml\CatalogProductActionAttributeEdit;
+use Magento\Mtf\TestStep\TestStepFactory;
 
 /**
  * Precondition:
@@ -58,35 +61,58 @@ class MassProductUpdateTest extends Injectable
      */
     protected $configData;
 
+    /**
+     * Factory for Test Steps.
+     *
+     * @var TestStepFactory
+     */
+    private $testStepFactory;
+
+    /**
+     * Factory for Fixtures.
+     *
+     * @var FixtureFactory
+     */
+    private $fixtureFactory;
+
     /**
      * Injection data.
      *
      * @param CatalogProductIndex $productGrid
      * @param CatalogProductActionAttributeEdit $attributeMassActionPage
+     * @param TestStepFactory $testStepFactory
+     * @param FixtureFactory $fixtureFactory
      * @return void
      */
     public function __inject(
         CatalogProductIndex $productGrid,
-        CatalogProductActionAttributeEdit $attributeMassActionPage
+        CatalogProductActionAttributeEdit $attributeMassActionPage,
+        TestStepFactory $testStepFactory,
+        FixtureFactory $fixtureFactory
     ) {
         $this->productGrid = $productGrid;
         $this->attributeMassActionPage = $attributeMassActionPage;
+        $this->testStepFactory = $testStepFactory;
+        $this->fixtureFactory = $fixtureFactory;
     }
 
     /**
      * Run mass update product simple entity test.
      *
-     * @param CatalogProductSimple $initialProduct
      * @param CatalogProductSimple $product
      * @param string $configData
+     * @param array $initialProducts
      * @return array
      */
-    public function test(CatalogProductSimple $initialProduct, CatalogProductSimple $product, $configData)
+    public function test(CatalogProductSimple $product, $configData, array $initialProducts)
     {
         $this->configData = $configData;
 
         // Preconditions
-        $initialProduct->persist();
+        $products = $this->testStepFactory->create(
+            \Magento\Catalog\Test\TestStep\CreateProductsStep::class,
+            ['products' => $initialProducts]
+        )->run()['products'];
 
         $this->objectManager->create(
             \Magento\Config\Test\TestStep\SetupConfigurationStep::class,
@@ -95,19 +121,33 @@ class MassProductUpdateTest extends Injectable
 
         // Steps
         $this->productGrid->open();
-        $this->productGrid->getProductGrid()->updateAttributes([['sku' => $initialProduct->getSku()]]);
+        $this->productGrid->getProductGrid()->updateAttributes($products);
         $this->attributeMassActionPage->getAttributesBlockForm()->fill($product);
         $this->attributeMassActionPage->getFormPageActions()->save();
-        $data = array_merge($initialProduct->getData(), $product->getData());
-        $product = $this->objectManager->create(
-            \Magento\Catalog\Test\Fixture\CatalogProductSimple::class,
-            ['data' => $data]
-        );
-
-        return [
-            'category' => $initialProduct->getDataFieldConfig('category_ids')['source']->getCategories()[0],
-            'product' => $product,
-        ];
+        $updatedProducts = $this->prepareUpdatedProducts($products, $product);
+        
+        return ['products' => $updatedProducts];
+    }
+
+    /**
+     * Prepare updated products.
+     *
+     * @param array $products
+     * @param CatalogProductSimple $product
+     * @return array
+     */
+    private function prepareUpdatedProducts(array $products, CatalogProductSimple $product)
+    {
+        $productsReturn = [];
+        /** @var FixtureInterface $item */
+        foreach ($products as $item) {
+            $productsReturn[] = $this->fixtureFactory->create(
+                get_class($item),
+                ['data' => array_merge($item->getData(), $product->getData())]
+            );
+        }
+
+        return $productsReturn;
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/MassProductUpdateTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/MassProductUpdateTest.xml
index 6f937999f3c34cc172b3552b6280b7563d07a1d1..5435ea89669f6f1a3d0d3d98cb8e1a5bb5aabed0 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/MassProductUpdateTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/MassProductUpdateTest.xml
@@ -9,11 +9,12 @@
     <testCase name="Magento\Catalog\Test\TestCase\Product\MassProductUpdateTest" summary="Edit Products Using Mass Actions" ticketId="MAGETWO-21128">
         <variation name="MassProductPriceUpdateTestVariation1">
             <data name="configData" xsi:type="string">product_flat</data>
-            <data name="initialProduct/dataset" xsi:type="string">simple_10_dollar</data>
+            <data name="initialProducts/0" xsi:type="string">catalogProductSimple::simple_10_dollar</data>
+            <data name="initialProducts/1" xsi:type="string">catalogProductSimple::simple_10_dollar</data>
+            <data name="productsCount" xsi:type="number">2</data>
             <data name="product/data/price/value" xsi:type="string">1.99</data>
             <constraint name="Magento\Catalog\Test\Constraint\AssertMassProductUpdateSuccessMessage" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
-            <constraint name="Magento\Catalog\Test\Constraint\AssertProductInCategory" />
         </variation>
     </testCase>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.xml
index 323246949d1a55825bfe49317af6662be585d15c..0395f9f5ed8cf83c0aa570252cc5ed7df32da3c8 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.xml
@@ -145,5 +145,19 @@
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductInCategory" />
         </variation>
+        <variation name="EditSimpleProductTestVariation11" summary="Update simple product with custom option">
+            <data name="initialProduct/dataset" xsi:type="string">product_with_category</data>
+            <data name="product/data/name" xsi:type="string">Test simple product %isolation%</data>
+            <data name="product/data/sku" xsi:type="string">test_simple_product_%isolation%</data>
+            <data name="product/data/price/value" xsi:type="string">245.00</data>
+            <data name="product/data/quantity_and_stock_status/qty" xsi:type="string">200</data>
+            <data name="product/data/custom_options/dataset" xsi:type="string">drop_down_with_one_option_percent_price</data>
+            <data name="product/data/checkout_data/dataset" xsi:type="string">simple_drop_down_with_one_option_percent_price</data>
+            <data name="product/data/url_key" xsi:type="string">test-simple-product-%isolation%</data>
+            <data name="product/data/weight" xsi:type="string">120.0000</data>
+            <constraint name="Magento\Catalog\Test\Constraint\AssertProductSaveMessage" />
+            <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" />
+            <constraint name="Magento\Catalog\Test\Constraint\AssertProductInCart" />
+        </variation>
     </testCase>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/PromoForm.xml b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/PromoForm.xml
index 25e8617faf11292f03e40461bb146cbd6a1779c1..4474370eebbc75d27383be14700bdbb6f47d90c4 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/PromoForm.xml
+++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/PromoForm.xml
@@ -8,8 +8,8 @@
 <sections>
     <rule_information>
         <class>\Magento\CatalogRule\Test\Block\Adminhtml\Promo\Catalog\Edit\Section\RuleInformation</class>
-        <selector>//div[contains(@class,'admin__collapsible-block-wrapper')][descendant::input[@name='name']]</selector>
-        <strategy>xpath</strategy>
+        <selector>[data-index="rule_information"]</selector>
+        <strategy>css selector</strategy>
         <fields>
             <is_active>
                 <input>select</input>
@@ -26,19 +26,20 @@
     </rule_information>
     <conditions>
         <class>\Magento\CatalogRule\Test\Block\Adminhtml\Promo\Catalog\Edit\Section\Conditions</class>
-        <selector>//div[contains(@class,'admin__collapsible-block-wrapper')][descendant::div[@class='rule-tree']]</selector>
-        <strategy>xpath</strategy>
+        <selector>[data-index="block_promo_catalog_edit_tab_conditions"]</selector>
+        <strategy>css selector</strategy>
         <fields>
             <conditions>
                 <selector>[id^="catalog_rule_formrule_conditions_fieldset_"]</selector>
+                <strategy>css selector</strategy>
                 <input>conditions</input>
             </conditions>
         </fields>
     </conditions>
     <actions>
         <class>\Magento\Ui\Test\Block\Adminhtml\Section</class>
-        <selector>//div[contains(@class,'admin__collapsible-block-wrapper')][descendant::select[@name='simple_action']]</selector>
-        <strategy>xpath</strategy>
+        <selector>[data-index="actions"]</selector>
+        <strategy>css selector</strategy>
         <fields>
             <simple_action>
                 <input>select</input>
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php
index e8178d07a1e9e26b6494d0b06551149636e4e4c1..697733fd3c33d8856f5d775452aca8ad977e77e9 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php
@@ -129,7 +129,7 @@ class Cart extends Block
                 Locator::SELECTOR_XPATH
             );
             $cartItem = $this->blockFactory->create(
-                \Magento\Checkout\Test\Block\Cart\CartItem::class,
+                '\\' . get_class($this) . '\CartItem',
                 ['element' => $cartItemBlock]
             );
         }
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Sidebar/Item.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Sidebar/Item.php
index b171a7062e94297ad73bebf4da5e15bbc19b8511..1eb5ddf43fc5259e9252b15507bb91429df16c8c 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Sidebar/Item.php
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Sidebar/Item.php
@@ -46,7 +46,7 @@ class Item extends Sidebar
      *
      * @var string
      */
-    protected $price = '.product .price';
+    protected $price = '.minicart-price .price';
 
     /**
      * CSS selector for update button.
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Totals.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Totals.php
index ef7ac1fc55f329d7b61fab9a0895dca554943b08..240ae1c183201f2c479564b5dfad59a274e84b9d 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Totals.php
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart/Totals.php
@@ -205,6 +205,8 @@ class Totals extends Block
      */
     public function getDiscount()
     {
+        $this->waitForElementNotVisible($this->blockWaitElement);
+        $this->waitForElementVisible($this->discount, Locator::SELECTOR_CSS);
         $priceElement = $this->_rootElement->find($this->discount, Locator::SELECTOR_CSS);
         return $priceElement->isVisible() ? $this->escapeCurrency($priceElement->getText()) : null;
     }
@@ -238,7 +240,7 @@ class Totals extends Block
      */
     public function isVisibleShippingPriceBlock()
     {
-        return  $this->_rootElement->find($this->shippingPriceBlockSelector, Locator::SELECTOR_CSS)->isVisible();
+        return $this->_rootElement->find($this->shippingPriceBlockSelector, Locator::SELECTOR_CSS)->isVisible();
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Payment/Method.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Payment/Method.php
index 48f1b4a99823dded713e7e32ebd5eb81a5d96eb2..55351dbe5fd5eb5105843dfba1311d4d1cb2c029 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Payment/Method.php
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Onepage/Payment/Method.php
@@ -40,7 +40,7 @@ class Method extends Block
      *
      * @var string
      */
-    protected $vaultCheckbox = '#%s_vault_enabler';
+    protected $vaultCheckbox = '#%s_enable_vault';
 
     /**
      * PayPal load spinner.
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.xml b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.xml
index f64258b1de297587789b5f675f56a36fb04d89ae..30688723ae8edb8c83b761e89f2805f5dcdcd588 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/AddProductsToShoppingCartEntityTest.xml
@@ -99,8 +99,8 @@
             <data name="productsData/4" xsi:type="string">configurableProduct::default</data>
             <data name="productsData/5" xsi:type="string">bundleProduct::bundle_fixed_product</data>
             <data name="productsData/6" xsi:type="string">bundleProduct::bundle_dynamic_product</data>
-            <data name="cart/data/grand_total" xsi:type="string">2922.43</data>
-            <data name="cart/data/subtotal" xsi:type="string">2852.43</data>
+            <data name="cart/data/grand_total" xsi:type="string">3473.43</data>
+            <data name="cart/data/subtotal" xsi:type="string">3408.43</data>
             <constraint name="Magento\Checkout\Test\Constraint\AssertPriceInShoppingCart" />
             <constraint name="Magento\Checkout\Test\Constraint\AssertProductQtyInShoppingCart" />
             <constraint name="Magento\Checkout\Test\Constraint\AssertSubtotalInShoppingCart" />
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsBlockEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsBlockEntityTest.php
index 7e3c3f0ebb3c95b69fdf1f5c766b8184c25d736c..79da8791af2be7ef41bd026bee326d8a4708aa33 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsBlockEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsBlockEntityTest.php
@@ -27,6 +27,7 @@ class CreateCmsBlockEntityTest extends AbstractCmsBlockEntityTest
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = 'extended_acceptance_test';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsBlockEntityTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsBlockEntityTest.xml
index a2bbdb817961d7fd474f402907adc88d548d7c0a..51c0853a24dbcbf270dcabae4a73420131f77e3d 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsBlockEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsBlockEntityTest.xml
@@ -8,7 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Cms\Test\TestCase\CreateCmsBlockEntityTest" summary="Create CMS Block" ticketId="MAGETWO-25578">
         <variation name="CreateCmsBlockEntityTestVariation1">
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data>
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, severity:S1</data>
             <data name="cmsBlock/data/title" xsi:type="string">block_%isolation%</data>
             <data name="cmsBlock/data/identifier" xsi:type="string">identifier_%isolation%</data>
             <data name="cmsBlock/data/stores/dataset/option_0" xsi:type="string">All Store Views</data>
@@ -19,13 +19,13 @@
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsBlockOnCategoryPage" />
         </variation>
         <variation name="CreateCmsBlockEntityTestVariation2">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="cmsBlock/data/title" xsi:type="string">block_%isolation%</data>
             <data name="cmsBlock/data/identifier" xsi:type="string">identifier_%isolation%</data>
             <data name="cmsBlock/data/stores/dataset/option_0" xsi:type="string">default</data>
             <data name="cmsBlock/data/is_active" xsi:type="string">No</data>
             <data name="cmsBlock/data/content" xsi:type="string">description_%isolation%</data>
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsBlockSuccessSaveMessage" />
-            <constraint name="Magento\Cms\Test\Constraint\AssertCmsBlockInGrid" />
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsBlockNotOnCategoryPage" />
         </variation>
     </testCase>
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageEntityTest.php
index f5035a2eaf76d734e7288a84d2657c897d90b5b4..250c55ff00d444635f08c2ea4a5f31d8b225fe10 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageEntityTest.php
@@ -29,6 +29,7 @@ class CreateCmsPageEntityTest extends Injectable
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = 'acceptance_test, extended_acceptance_test';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageEntityTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageEntityTest.xml
index 60b440fc0868bad88969d4dab7adbfa13ea802e3..67b4421182848ebb9b2633c4d9212e6679cccf51 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageEntityTest.xml
@@ -8,18 +8,19 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Cms\Test\TestCase\CreateCmsPageEntityTest" summary="Create Cms Page" ticketId="MAGETWO-25580">
         <variation name="CreateCmsPageEntityTestVariation1" summary="Create CMS Content Page" ticketId="MAGETWO-12399">
+            <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test, severity:S1</data>
             <data name="fixtureType" xsi:type="string">cmsPage</data>
             <data name="data/is_active" xsi:type="string">Yes</data>
             <data name="data/title" xsi:type="string">NewCmsPage%isolation%</data>
             <data name="data/identifier" xsi:type="string">identifier-%isolation%</data>
             <data name="data/store_id" xsi:type="string">All Store Views</data>
             <data name="data/content/content" xsi:type="string">cms_page_text_content%isolation%</data>
-            <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test</data>
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageSuccessSaveMessage" />
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageInGrid" />
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsPagePreview" />
         </variation>
         <variation name="CreateCmsPageEntityTestVariation2" summary="Create page for default store view">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="fixtureType" xsi:type="string">cmsPage</data>
             <data name="data/is_active" xsi:type="string">Yes</data>
             <data name="data/title" xsi:type="string">NewCmsPage%isolation%</data>
@@ -30,6 +31,7 @@
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageForm" />
         </variation>
         <variation name="CreateCmsPageEntityTestVariation3" summary="Create page with widget and system variable">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="fixtureType" xsi:type="string">cmsPage</data>
             <data name="data/is_active" xsi:type="string">Yes</data>
             <data name="data/title" xsi:type="string">NewCmsPage%isolation%</data>
@@ -39,11 +41,10 @@
             <data name="data/content/widget/dataset" xsi:type="string">default</data>
             <data name="data/content/variable" xsi:type="string">General Contact Name</data>
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageSuccessSaveMessage" />
-            <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageForm" />
-            <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageInGrid" />
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsPagePreview" />
         </variation>
         <variation name="CreateCmsPageEntityTestVariation4" summary="Create disabled page">
+            <data name="tag" xsi:type="string">severity:S3</data>
             <data name="fixtureType" xsi:type="string">cmsPage</data>
             <data name="data/title" xsi:type="string">NewCmsPage%isolation%</data>
             <data name="data/identifier" xsi:type="string">identifier-%isolation%</data>
@@ -51,8 +52,6 @@
             <data name="data/is_active" xsi:type="string">No</data>
             <data name="data/content/content" xsi:type="string">cms_page_text_content%isolation%</data>
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageSuccessSaveMessage" />
-            <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageForm" />
-            <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageInGrid" />
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageDisabledOnFrontend" />
         </variation>
     </testCase>
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageRewriteEntityTest.php
index 296525540073fee5a0e12101cd9575ffcc2a15f5..42796d8fbb726cd283308abb84c708f16e62ae70 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageRewriteEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageRewriteEntityTest.php
@@ -33,6 +33,7 @@ class CreateCmsPageRewriteEntityTest extends Injectable
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = 'extended_acceptance_test';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageRewriteEntityTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageRewriteEntityTest.xml
index 19b5053fc4097f75b63ace56bfbf61159d13863e..3f413f78331d2f86363784f6d28871f34ba88e1b 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageRewriteEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCmsPageRewriteEntityTest.xml
@@ -8,7 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Cms\Test\TestCase\CreateCmsPageRewriteEntityTest" summary="Create CMS Page URL Rewrites" ticketId="MAGETWO-24847">
         <variation name="CreateCmsPageRewriteEntityTestVariation1">
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data>
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, severity:S1</data>
             <data name="urlRewrite/data/entity_type" xsi:type="string">For CMS page</data>
             <data name="urlRewrite/data/target_path/entity" xsi:type="string">cms/page/view/page_id/%cmsPage::default%</data>
             <data name="urlRewrite/data/request_path" xsi:type="string">request_path%isolation%</data>
@@ -19,6 +19,7 @@
             <constraint name="Magento\Cms\Test\Constraint\AssertUrlRewriteCmsPageRedirect" />
         </variation>
         <variation name="CreateCmsPageRewriteEntityTestVariation2">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="urlRewrite/data/entity_type" xsi:type="string">For CMS page</data>
             <data name="urlRewrite/data/target_path/entity" xsi:type="string">cms/page/view/page_id/%cmsPage::default%</data>
             <data name="urlRewrite/data/request_path" xsi:type="string">request_path%isolation%.html</data>
@@ -29,6 +30,7 @@
             <constraint name="Magento\Cms\Test\Constraint\AssertUrlRewriteCmsPageRedirect" />
         </variation>
         <variation name="CreateCmsPageRewriteEntityTestVariation3">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="urlRewrite/data/entity_type" xsi:type="string">For CMS page</data>
             <data name="urlRewrite/data/target_path/entity" xsi:type="string">cms/page/view/page_id/%cmsPage::default%</data>
             <data name="urlRewrite/data/request_path" xsi:type="string">request_path%isolation%.htm</data>
@@ -39,6 +41,7 @@
             <constraint name="Magento\Cms\Test\Constraint\AssertUrlRewriteCmsPageRedirect" />
         </variation>
         <variation name="CreateCmsPageRewriteEntityTestVariation4">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="urlRewrite/data/entity_type" xsi:type="string">For CMS page</data>
             <data name="urlRewrite/data/target_path/entity" xsi:type="string">cms/page/view/page_id/%cmsPage::default%</data>
             <data name="urlRewrite/data/request_path" xsi:type="string">request_path%isolation%.aspx</data>
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCustomUrlRewriteEntityTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCustomUrlRewriteEntityTest.xml
index 9f14cefa8147d6fac8aeae923dc9993456a1ee72..90f40a55e8f649d6f152da95529d8e0a5841cae8 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCustomUrlRewriteEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/CreateCustomUrlRewriteEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\UrlRewrite\Test\TestCase\CreateCustomUrlRewriteEntityTest" summary="Create Custom URL Rewrites" ticketId="MAGETWO-25474">
         <variation name="CreateCustomUrlRewriteEntityTestVariation3">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="urlRewrite/data/entity_type" xsi:type="string">Custom</data>
             <data name="urlRewrite/data/store_id" xsi:type="string">Main Website/Main Website Store/Default Store View</data>
             <data name="urlRewrite/data/target_path/entity" xsi:type="string">cms/page/view/page_id/%cmsPage::default%</data>
@@ -15,10 +16,10 @@
             <data name="urlRewrite/data/redirect_type" xsi:type="string">No</data>
             <data name="urlRewrite/data/description" xsi:type="string">test description_full path</data>
             <constraint name="Magento\UrlRewrite\Test\Constraint\AssertUrlRewriteSaveMessage" />
-            <constraint name="Magento\UrlRewrite\Test\Constraint\AssertUrlRewriteInGrid" />
             <constraint name="Magento\UrlRewrite\Test\Constraint\AssertUrlRewriteCustomRedirect" />
         </variation>
         <variation name="CreateCustomUrlRewriteEntityTestVariation4">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="urlRewrite/data/entity_type" xsi:type="string">Custom</data>
             <data name="urlRewrite/data/store_id" xsi:type="string">Main Website/Main Website Store/Default Store View</data>
             <data name="urlRewrite/data/target_path/entity" xsi:type="string">cms/page/view/page_id/%cmsPage::default%</data>
@@ -26,7 +27,6 @@
             <data name="urlRewrite/data/redirect_type" xsi:type="string">Temporary (302)</data>
             <data name="urlRewrite/data/description" xsi:type="string">test description_full path</data>
             <constraint name="Magento\UrlRewrite\Test\Constraint\AssertUrlRewriteSaveMessage" />
-            <constraint name="Magento\UrlRewrite\Test\Constraint\AssertUrlRewriteInGrid" />
             <constraint name="Magento\UrlRewrite\Test\Constraint\AssertUrlRewriteCustomRedirect" />
         </variation>
     </testCase>
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.php
index ad2ae5689c98588aa3964d948dd6e04e7a1a0fd2..62c703960e7277eff1482475ff75ca871161e211 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.php
@@ -31,6 +31,7 @@ class DeleteCmsBlockEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.xml
index d9c52aba53d5279a288128101bae3f300d39536b..fc043effe5a77682ef1a30307350ad72aab8401b 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsBlockEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Cms\Test\TestCase\DeleteCmsBlockEntityTest" summary="Delete CMS Block" ticketId="MAGETWO-25698">
         <variation name="DeleteCmsBlockEntityTestVariation1">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsBlockDeleteMessage" />
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsBlockNotInGrid" />
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsBlockNotOnCategoryPage" />
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.php
index 25225917014fcbee5385f1cb2334ba9889300390..d893bdbe2d13e7e9fcff2ba491c1410f1092db71 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.php
@@ -29,6 +29,7 @@ class DeleteCmsPageEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.xml
index 5c476928ca6ee9ab6698ff9177272e858b867bde..2a85425890e8e455a4ba6e32960f6d329bfcdf5b 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Cms\Test\TestCase\DeleteCmsPageEntityTest" summary="Delete CMS Page" ticketId="MAGETWO-23291">
         <variation name="DeleteCmsPageEntityTestVariation1">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="cmsPage/dataset" xsi:type="string">default</data>
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageDeleteMessage" />
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageNotInGrid" />
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageUrlRewriteEntityTest.php
index 68d0ae541253d779e60cd374e8055600446b4641..a07303875a54bf2c8b6ce82b531ddbf4c56f7ca4 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageUrlRewriteEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageUrlRewriteEntityTest.php
@@ -30,6 +30,7 @@ class DeleteCmsPageUrlRewriteEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const SEVERITY = 'S2';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageUrlRewriteEntityTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageUrlRewriteEntityTest.xml
index a065c37513ac5c2fa185b29d655f5b3a6d0ceabd..77e54edfb85f906986bb4ceb800424b65ef610ed 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageUrlRewriteEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/DeleteCmsPageUrlRewriteEntityTest.xml
@@ -8,21 +8,22 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Cms\Test\TestCase\DeleteCmsPageUrlRewriteEntityTest" summary="Delete Cms Page URL Rewrites" ticketId="MAGETWO-25915">
         <variation name="DeleteCmsPageUrlRewriteEntityTestVariation1">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="urlRewrite/dataset" xsi:type="string">cms_default_no_redirect</data>
             <constraint name="Magento\UrlRewrite\Test\Constraint\AssertUrlRewriteDeletedMessage" />
             <constraint name="Magento\UrlRewrite\Test\Constraint\AssertUrlRewriteNotInGrid" />
             <constraint name="Magento\UrlRewrite\Test\Constraint\AssertPageByUrlRewriteIsNotFound" />
         </variation>
         <variation name="DeleteCmsPageUrlRewriteEntityTestVariation2">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="urlRewrite/dataset" xsi:type="string">cms_default_permanent_redirect</data>
             <constraint name="Magento\UrlRewrite\Test\Constraint\AssertUrlRewriteDeletedMessage" />
-            <constraint name="Magento\UrlRewrite\Test\Constraint\AssertUrlRewriteNotInGrid" />
             <constraint name="Magento\UrlRewrite\Test\Constraint\AssertPageByUrlRewriteIsNotFound" />
         </variation>
         <variation name="DeleteCmsPageUrlRewriteEntityTestVariation3">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="urlRewrite/dataset" xsi:type="string">cms_default_temporary_redirect</data>
             <constraint name="Magento\UrlRewrite\Test\Constraint\AssertUrlRewriteDeletedMessage" />
-            <constraint name="Magento\UrlRewrite\Test\Constraint\AssertUrlRewriteNotInGrid" />
             <constraint name="Magento\UrlRewrite\Test\Constraint\AssertPageByUrlRewriteIsNotFound" />
         </variation>
     </testCase>
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridFilteringTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridFilteringTest.xml
index af26b1f11f177bdc43d4ead0ad16156a0b432d46..715190039162b4fdbab91af72ca564e0c0732858 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridFilteringTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridFilteringTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Ui\Test\TestCase\GridFilteringTest" summary="Grid UI Component Filtering" ticketId="MAGETWO-41329">
         <variation name="CmsPageGridFiltering">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="description" xsi:type="string">Verify cms page grid filtering</data>
             <data name="itemsCount" xsi:type="string">2</data>
             <data name="fixtureName" xsi:type="string">cmsPage</data>
@@ -28,6 +29,7 @@
             <constraint name="\Magento\Ui\Test\Constraint\AssertGridFiltering"/>
         </variation>
         <variation name="CmsBlockGridFiltering">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="description" xsi:type="string">Verify cms block grid filtering</data>
             <data name="itemsCount" xsi:type="string">2</data>
             <data name="fixtureName" xsi:type="string">cmsBlock</data>
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridFullTextSearchTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridFullTextSearchTest.xml
index 21a0dd32a56b2aa97b54ebda8c295c6bbc7300ef..893cfc2f0dacc75f92b31b3a14fcc54a41aaf6b5 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridFullTextSearchTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridFullTextSearchTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Ui\Test\TestCase\GridFullTextSearchTest" summary="Grid UI Component Full Text Search" ticketId="MAGETWO-41023">
         <variation name="CmsPageGridFullTextSearch">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="description" xsi:type="string">Verify cms page grid full text search</data>
             <data name="itemsCount" xsi:type="string">2</data>
             <data name="fixtureName" xsi:type="string">cmsPage</data>
@@ -19,6 +20,7 @@
             <constraint name="Magento\Ui\Test\Constraint\AssertGridFullTextSearch"/>
         </variation>
         <variation name="CmsBlockGridFullTextSearch">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="description" xsi:type="string">Verify cms blocks grid full text search</data>
             <data name="itemsCount" xsi:type="string">2</data>
             <data name="fixtureName" xsi:type="string">cmsBlock</data>
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridSortingTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridSortingTest.xml
index 595277423b39c9d14d667344213da0776ae5c9b3..d6467a53e15659a1e5859002c04be6ad3e91b3e3 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridSortingTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/GridSortingTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Ui\Test\TestCase\GridSortingTest" summary="Grid UI Component Sorting" ticketId="MAGETWO-41328">
         <variation name="CmsPagesGridSorting">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="description" xsi:type="string">Verify cms page grid sorting</data>
             <data name="columnsForSorting" xsi:type="array">
                 <item name="id" xsi:type="string">ID</item>
@@ -18,6 +19,7 @@
             <constraint name="Magento\Ui\Test\Constraint\AssertGridSorting"/>
         </variation>
         <variation name="CmsBlocksGridSorting">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="description" xsi:type="string">Verify cms blocks grid sorting</data>
             <data name="steps" xsi:type="array">
                 <item name="0" xsi:type="string">-</item>
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/NavigateMenuTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/NavigateMenuTest.xml
index 38c9e8cf8f21dbae3689f2bef5bc58621ee659bd..127c85f84010299c5d12e932ab1199f2ae653d8b 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/NavigateMenuTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/NavigateMenuTest.xml
@@ -8,11 +8,13 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Backend\Test\TestCase\NavigateMenuTest">
         <variation name="NavigateMenuTest18">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="menuItem" xsi:type="string">Content > Pages</data>
             <data name="pageTitle" xsi:type="string">Pages</data>
             <constraint name="Magento\Backend\Test\Constraint\AssertBackendPageIsAvailable"/>
         </variation>
         <variation name="NavigateMenuTest19">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="menuItem" xsi:type="string">Content > Blocks</data>
             <data name="pageTitle" xsi:type="string">Blocks</data>
             <constraint name="Magento\Backend\Test\Constraint\AssertBackendPageIsAvailable"/>
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsBlockEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsBlockEntityTest.php
index 8fa92fba59f8e65dc8a528c26a239b0ed54b2e48..6272eff0cf69978fde4b62ae4291a1f072337a14 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsBlockEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsBlockEntityTest.php
@@ -27,6 +27,7 @@ class UpdateCmsBlockEntityTest extends AbstractCmsBlockEntityTest
 {
     /* tags */
     const MVP = 'yes';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsBlockEntityTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsBlockEntityTest.xml
index 652166b0fe00d194ea6f638fe88b94f8993499fb..a2cd59dd89db89b70c731cde6d2cb16cd1b0ee90 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsBlockEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsBlockEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Cms\Test\TestCase\UpdateCmsBlockEntityTest" summary="Update CMS Block" ticketId="MAGETWO-25941">
         <variation name="UpdateCmsBlockEntityTestVariation1">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="cmsBlock/data/title" xsi:type="string">block_updated_%isolation%</data>
             <data name="cmsBlock/data/identifier" xsi:type="string">identifier_updated_%isolation%</data>
             <data name="cmsBlock/data/stores/dataset/option_0" xsi:type="string">all_store_views</data>
@@ -18,13 +19,13 @@
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsBlockOnCategoryPage" />
         </variation>
         <variation name="UpdateCmsBlockEntityTestVariation2">
+            <data name="tag" xsi:type="string">severity:S3</data>
             <data name="cmsBlock/data/title" xsi:type="string">block_updated_%isolation%</data>
             <data name="cmsBlock/data/identifier" xsi:type="string">identifier_updated_%isolation%</data>
             <data name="cmsBlock/data/stores/dataset/option_0" xsi:type="string">default</data>
             <data name="cmsBlock/data/is_active" xsi:type="string">No</data>
             <data name="cmsBlock/data/content" xsi:type="string">description_updated_%isolation%</data>
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsBlockSuccessSaveMessage" />
-            <constraint name="Magento\Cms\Test\Constraint\AssertCmsBlockInGrid" />
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsBlockNotOnCategoryPage" />
         </variation>
     </testCase>
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.php
index b16f4384f27d50e75411b3fcd20a388f514cd9d5..a9a98e8dd21c0512fe46709bcbd76d3740d58322 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.php
@@ -31,6 +31,7 @@ class UpdateCmsPageEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.xml
index a24fe83e503cec1a096fea11b8538d0943dd1980..75f8cf63f645e333e001ba26ef940f62ae95581c 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageEntityTest.xml
@@ -8,19 +8,21 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Cms\Test\TestCase\UpdateCmsPageEntityTest" summary="Update Cms Page" ticketId="MAGETWO-25186">
         <variation name="UpdateCmsPageEntityTestVariation1">
+            <data name="tag" xsi:type="string">severity:S3</data>
             <data name="cms/data/title" xsi:type="string">CmsPageEdited%isolation%</data>
             <data name="cms/data/is_active" xsi:type="string">No</data>
             <data name="cms/data/content/content" xsi:type="string">cms_page_text_content_after_edit</data>
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageSuccessSaveMessage" />
-            <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageForm" />
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageDisabledOnFrontend" />
         </variation>
         <variation name="UpdateCmsPageEntityTestVariation2">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="cms/data/title" xsi:type="string">CmsPageEdited%isolation%</data>
             <data name="cms/data/identifier" xsi:type="string">cms_page_url_edited_%isolation%</data>
             <data name="cms/data/content_heading" xsi:type="string">Content Heading TextEdited</data>
             <data name="cms/data/content/content" xsi:type="string">cms_page_text_content_after_edit</data>
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageSuccessSaveMessage" />
+            <constraint name="Magento\Cms\Test\Constraint\AssertCmsPageForm" />
             <constraint name="Magento\Cms\Test\Constraint\AssertCmsPagePreview" />
         </variation>
     </testCase>
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageRewriteEntityTest.php
index 43fd7e69ac35930fc3274c6042cdcc6e43ef4f9a..bfa992dd81c8db604fc5bc92c205b0d61948cab7 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageRewriteEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageRewriteEntityTest.php
@@ -35,6 +35,7 @@ class UpdateCmsPageRewriteEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const SEVERITY = 'S2';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageRewriteEntityTest.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageRewriteEntityTest.xml
index e8a1a637f7ef90d1308158a52b297e4fc848c3fa..40664ee7c131310d03770fb5a8beaea0f6342a73 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageRewriteEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/TestCase/UpdateCmsPageRewriteEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Cms\Test\TestCase\UpdateCmsPageRewriteEntityTest" summary="Update Cms Page URL Rewrites " ticketId="MAGETWO-26173">
         <variation name="UpdateCmsPageRewriteEntityTestVariation1">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="cmsPageRewrite/dataset" xsi:type="string">cms_default_no_redirect</data>
             <data name="urlRewrite/data/store_id" xsi:type="string">Main Website/Main Website Store/%default%</data>
             <data name="urlRewrite/data/request_path" xsi:type="string">request_path%isolation%</data>
@@ -17,6 +18,7 @@
             <constraint name="Magento\Cms\Test\Constraint\AssertUrlRewriteCmsPageRedirect" />
         </variation>
         <variation name="UpdateCmsPageRewriteEntityTestVariation2">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="cmsPageRewrite/dataset" xsi:type="string">cms_default_temporary_redirect</data>
             <data name="urlRewrite/data/store_id" xsi:type="string">Main Website/Main Website Store/Default Store View</data>
             <data name="urlRewrite/data/request_path" xsi:type="string">request_path%isolation%.html</data>
@@ -26,6 +28,7 @@
             <constraint name="Magento\Cms\Test\Constraint\AssertUrlRewriteCmsPageRedirect" />
         </variation>
         <variation name="UpdateCmsPageRewriteEntityTestVariation3">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="cmsPageRewrite/dataset" xsi:type="string">cms_default_permanent_redirect</data>
             <data name="urlRewrite/data/store_id" xsi:type="string">Main Website/Main Website Store/Default Store View</data>
             <data name="urlRewrite/data/request_path" xsi:type="string">request_path%isolation%.htm</data>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Grid.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..e6fa3271ea6cd60d1f8ae7e509a3c873344e7e7d
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Grid.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\ConfigurableProduct\Test\Block\Adminhtml\Product;
+
+use Magento\ConfigurableProduct\Test\Fixture\ConfigurableProduct;
+
+/**
+ * Backend catalog product grid.
+ */
+class Grid extends \Magento\Catalog\Test\Block\Adminhtml\Product\Grid
+{
+    /**
+     * Prepare data.
+     *
+     * @param ConfigurableProduct $product
+     * @return array
+     */
+    public function prepareData($product)
+    {
+        $configurableAttributesData = $product->getConfigurableAttributesData();
+        $productItems[] = ['sku' => $product->getSku()];
+        foreach ($configurableAttributesData['matrix'] as $variation) {
+            $productItems[] = ['sku' => $variation['sku']];
+        }
+
+        return $productItems;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml
index 2a3703a10607554c2682f19b036201cc700dc477..4a69a7604bca3d74119b07bdcea3b2115a1f6648 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct.xml
@@ -41,6 +41,35 @@
             </field>
         </dataset>
 
+        <dataset name="out_of_stock">
+            <field name="name" xsi:type="string">Test configurable product %isolation%</field>
+            <field name="sku" xsi:type="string">sku_test_configurable_product_%isolation%</field>
+            <field name="price" xsi:type="array">
+                <item name="value" xsi:type="string">40</item>
+                <item name="dataset" xsi:type="string">price_40</item>
+            </field>
+            <field name="status" xsi:type="string">Yes</field>
+            <field name="visibility" xsi:type="string">Catalog, Search</field>
+            <field name="tax_class_id" xsi:type="array">
+                <item name="dataset" xsi:type="string">taxable_goods</item>
+            </field>
+            <field name="url_key" xsi:type="string">configurable-product-%isolation%</field>
+            <field name="configurable_attributes_data" xsi:type="array">
+                <item name="dataset" xsi:type="string">two_options_with_assigned_product</item>
+            </field>
+            <field name="quantity_and_stock_status" xsi:type="array">
+                <item name="is_in_stock" xsi:type="string">Out of Stock</item>
+            </field>
+            <field name="website_ids" xsi:type="array">
+                <item name="0" xsi:type="array">
+                    <item name="dataset" xsi:type="string">default</item>
+                </item>
+            </field>
+            <field name="attribute_set_id" xsi:type="array">
+                <item name="dataset" xsi:type="string">default</item>
+            </field>
+        </dataset>
+
         <dataset name="configurable_with_qty_1">
             <field name="name" xsi:type="string">Test configurable product %isolation%</field>
             <field name="sku" xsi:type="string">sku_test_configurable_product_%isolation%</field>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/CheckoutData.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/CheckoutData.xml
index f075312343c210b8f86f73d109e31b6f9e85a9f3..bb9f7a4ae03b19500b954e187a8765121579acf7 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/CheckoutData.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/CheckoutData.xml
@@ -64,7 +64,7 @@
             </field>
             <field name="qty" xsi:type="string">1</field>
             <field name="cartItem" xsi:type="array">
-                <item name="price" xsi:type="string">120</item>
+                <item name="price" xsi:type="string">42</item>
                 <item name="qty" xsi:type="string">1</item>
                 <item name="subtotal" xsi:type="string">172</item>
             </field>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.xml
index 58435b066261ed28cc7f33ff01fc250940b6eb17..da44fd2eaf99e55e925d9c946b6d7e8ee8370408 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/CreateConfigurableProductEntityTest.xml
@@ -110,7 +110,7 @@
             <constraint name="Magento\ConfigurableProduct\Test\Constraint\AssertConfigurableProductPage" />
         </variation>
         <variation name="CreateConfigurableProductEntityTestVariation6" summary="Create Configurable Product with Creating New Category and New Attribute (Required Fields Only)" ticketId="MAGETWO-13361">
-            <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test</data>
+            <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test, stable:no</data>
             <data name="product/data/configurable_attributes_data/dataset" xsi:type="string">two_searchable_options</data>
             <data name="product/data/name" xsi:type="string">Configurable Product %isolation%</data>
             <data name="product/data/sku" xsi:type="string">configurable_sku_%isolation%</data>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/MassProductUpdateTest.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/MassProductUpdateTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3d58645d618ffe4f34beb84cd3a1d58212649148
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/MassProductUpdateTest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\Catalog\Test\TestCase\Product\MassProductUpdateTest" summary="Edit Products Using Mass Actions" ticketId="MAGETWO-21128">
+        <variation name="MassProductUpdateTestVariation2" summary="Update stock data for simple and configurable">
+            <data name="configData" xsi:type="string">product_flat</data>
+            <data name="initialProducts/1" xsi:type="string">configurableProduct::out_of_stock</data>
+            <data name="initialProducts/0" xsi:type="string">catalogProductSimple::out_of_stock</data>
+            <data name="productsCount" xsi:type="number">2</data>
+            <data name="product/data/stock_data" xsi:type="string">In Stock</data>
+            <constraint name="Magento\Catalog\Test\Constraint\AssertMassProductUpdateSuccessMessage" />
+            <constraint name="Magento\Catalog\Test\Constraint\AssertProductInGrid" />
+            <constraint name="Magento\Catalog\Test\Constraint\AssertProductsInStock" />
+        </variation>
+    </testCase>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.php b/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.php
index 4d397bde28bf6a11dc2a11032de62c4b317154bc..bc40a2ab98f6d913b80736346c7c06ef6f1c7f9e 100644
--- a/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.php
+++ b/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.php
@@ -31,6 +31,7 @@ class CreateCurrencyRateTest extends Injectable
 {
     /* tags */
     const TEST_TYPE = 'acceptance_test, extended_acceptance_test';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.xml b/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.xml
index e3eb961bcfe9d5cb1e028fd69b91878865408d39..dd42950c18a78175ce51fb7cfce85fe7fbc85a0c 100644
--- a/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Directory/Test/TestCase/CreateCurrencyRateTest.xml
@@ -8,7 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Directory\Test\TestCase\CreateCurrencyRateTest" summary="Create Currency Rate" ticketId="MAGETWO-36824">
         <variation name="CreateCurrencyRateTestVariation1">
-            <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test</data>
+            <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test, severity:S1</data>
             <data name="currencyRate/data/currency_from" xsi:type="string">USD</data>
             <data name="currencyRate/data/currency_to" xsi:type="string">EUR</data>
             <data name="currencyRate/data/rate" xsi:type="number">0.8</data>
diff --git a/dev/tests/functional/tests/app/Magento/Directory/Test/etc/di.xml b/dev/tests/functional/tests/app/Magento/Directory/Test/etc/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d85076bd922cdd84d382cd51c1c29ab35e225706
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Directory/Test/etc/di.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
+    <type name="Magento\Directory\Test\Constraint\AssertCurrencyRateAppliedOnCatalogPage">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Directory\Test\Constraint\AssertCurrencyRateSuccessSaveMessage">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/DownloadableProduct/CheckoutData.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/DownloadableProduct/CheckoutData.xml
index 74abeeb6cb325f3e010f3270f693a065cc71ca0a..5170d8f9c54272eb0a2b92031efbb6110f71db83 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/DownloadableProduct/CheckoutData.xml
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/DownloadableProduct/CheckoutData.xml
@@ -73,8 +73,8 @@
                 </item>
             </field>
             <field name="cartItem" xsi:type="array">
-                <item name="price" xsi:type="string">23</item>
-                <item name="subtotal" xsi:type="string">23</item>
+                <item name="price" xsi:type="string">25.43</item>
+                <item name="subtotal" xsi:type="string">25.43</item>
             </field>
         </dataset>
 
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Block/Devdocs.php b/dev/tests/functional/tests/app/Magento/Install/Test/Block/Devdocs.php
new file mode 100644
index 0000000000000000000000000000000000000000..1be88c0bbf7b89f7dbf529456a9ee1235df1e163
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Block/Devdocs.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Install\Test\Block;
+
+use Magento\Mtf\Block\Block;
+
+/**
+ * Developer Documentation block.
+ */
+class Devdocs extends Block
+{
+    /**
+     * Developer Documentation title.
+     *
+     * @var string
+     */
+    protected $devdocsTitle = '.page-heading';
+
+    /**
+     * Get Developer Documentation title text.
+     *
+     * @return string
+     */
+    public function getDevdocsTitle()
+    {
+        return $this->_rootElement->find($this->devdocsTitle)->getText();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Block/Landing.php b/dev/tests/functional/tests/app/Magento/Install/Test/Block/Landing.php
index 5b92b332b26960fdfc0e285459e39b78f5c72f67..d809fb861b66c92138a3231aeae8a7bd35ea15d9 100644
--- a/dev/tests/functional/tests/app/Magento/Install/Test/Block/Landing.php
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Block/Landing.php
@@ -14,6 +14,13 @@ use Magento\Mtf\Client\Locator;
  */
 class Landing extends Block
 {
+    /**
+     * Link by text.
+     *
+     * @var string
+     */
+    protected $linkSelector = '//a[text()="%s"]';
+
     /**
      * 'Agree and Set up Magento' button.
      *
@@ -47,4 +54,15 @@ class Landing extends Block
     {
         $this->_rootElement->find($this->termsAndAgreement, Locator::SELECTOR_CSS)->click();
     }
+    
+    /**
+     * Click on link.
+     *
+     * @param string $text
+     * @return void
+     */
+    public function clickLink($text)
+    {
+        $this->_rootElement->find(sprintf($this->linkSelector, $text), Locator::SELECTOR_XPATH)->click();
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertDevdocsLink.php b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertDevdocsLink.php
new file mode 100644
index 0000000000000000000000000000000000000000..d397cc1882b6f39c2fa5423a9ccecbceec002aaa
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertDevdocsLink.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Install\Test\Constraint;
+
+use Magento\Install\Test\Page\DevdocsInstall;
+use Magento\Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Check Developer Documentation link.
+ */
+class AssertDevdocsLink extends AbstractConstraint
+{
+    /**
+     * Developer Documentation title.
+     */
+    const DEVDOCS_TITLE_TEXT = 'Setup Wizard installation';
+
+    /**
+     * Check Developer Documentation link.
+     *
+     * @param DevdocsInstall $devdocsInstallPage
+     * @return void
+     */
+    public function processAssert(DevdocsInstall $devdocsInstallPage)
+    {
+        \PHPUnit_Framework_Assert::assertEquals(
+            self::DEVDOCS_TITLE_TEXT,
+            $devdocsInstallPage->getDevdocsBlock()->getDevdocsTitle(),
+            'Developer Documentation link is wrong.'
+        );
+    }
+
+    /**
+     * Returns a string representation of successful assertion.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return "Developer Documentation link is correct.";
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Page/DevdocsInstall.xml b/dev/tests/functional/tests/app/Magento/Install/Test/Page/DevdocsInstall.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d2dc975cc2b2bd82a72b6b9e4e1d71b97fd635b4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Page/DevdocsInstall.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/pages.xsd">
+    <page name="DevdocsInstall" mca="http://devdocs.magento.com/guides/v2.0/install-gde/install/web/install-web.html" module="Magento_Install">
+        <block name="devdocsBlock" class="Magento\Install\Test\Block\Devdocs" locator="body" strategy="css selector"/>
+    </page>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php
index f7931b03e3def69ddb02f6c73c7c0381fd8cf0c1..ee51c4eee82271b2744d63167d56b82e526049a9 100644
--- a/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php
@@ -7,6 +7,7 @@
 namespace Magento\Install\Test\TestCase;
 
 use Magento\Install\Test\Page\Install;
+use Magento\Install\Test\Page\DevdocsInstall;
 use Magento\Install\Test\Fixture\Install as InstallConfig;
 use Magento\User\Test\Fixture\User;
 use Magento\Mtf\Fixture\FixtureFactory;
@@ -14,6 +15,9 @@ use Magento\Mtf\TestCase\Injectable;
 use Magento\Install\Test\Constraint\AssertAgreementTextPresent;
 use Magento\Install\Test\Constraint\AssertSuccessfulReadinessCheck;
 use Magento\Install\Test\Constraint\AssertAdminUriAutogenerated;
+use Magento\Install\Test\Constraint\AssertDevdocsLink;
+use Magento\Mtf\Util\Command\Cli\Setup;
+use Magento\Mtf\Client\BrowserInterface;
 
 /**
  * PLEASE ADD NECESSARY INFO BEFORE RUNNING TEST TO
@@ -24,24 +28,47 @@ use Magento\Install\Test\Constraint\AssertAdminUriAutogenerated;
  *
  * Steps:
  * 1. Go setup landing page.
- * 2. Click on "Terms and agreements" button.
- * 3. Check license agreement text.
- * 4. Return back to landing page and click "Agree and Setup" button.
- * 5. Click "Start Readiness Check" button.
- * 6. Make sure PHP Version, PHP Extensions and File Permission are ok.
- * 7. Click "Next" and fill DB credentials.
- * 8. Click "Test Connection and Authentication" and make sure connection successful.
- * 9. Click "Next" and fill store address and admin path.
- * 10. Click "Next" and leave all default values.
- * 11. Click "Next" and fill admin user info.
- * 12. Click "Next" and on the "Step 6: Install" page click "Install Now" button.
- * 13. Perform assertions.
+ * 2. Click on Developer Documentation link.
+ * 3. Check Developer Documentation title.
+ * 4. Click on "Terms and agreements" button.
+ * 5. Check license agreement text.
+ * 6. Return back to landing page and click "Agree and Setup" button.
+ * 7. Click "Start Readiness Check" button.
+ * 8. Make sure PHP Version, PHP Extensions and File Permission are ok.
+ * 9. Click "Next" and fill DB credentials.
+ * 10. Click "Test Connection and Authentication" and make sure connection successful.
+ * 11. Click "Next" and fill store address and admin path.
+ * 12. Click "Next" and leave all default values.
+ * 13. Click "Next" and fill admin user info.
+ * 14. Click "Next" and on the "Step 6: Install" page click "Install Now" button.
+ * 15. Perform assertions.
  *
  * @group Installer_and_Upgrade/Downgrade
  * @ZephyrId MAGETWO-31431
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class InstallTest extends Injectable
 {
+    /**
+     * Developer Documentation link text.
+     */
+    const DEVDOCS_LINK_TEXT = 'Getting Started';
+
+    /**
+     * Developer Documentation install page.
+     *
+     * @var DevdocsInstall
+     */
+    protected $devdocsInstallPage;
+
+    /**
+     * Terms and agreement selector.
+     *
+     * @var string
+     */
+    protected $termsLink = '.text-terms>a';
+
     /**
      * Install page.
      *
@@ -72,14 +99,16 @@ class InstallTest extends Injectable
      * Uninstall Magento.
      *
      * @param Install $installPage
+     * @param Setup $magentoSetup
+     * @param DevdocsInstall $devdocsInstallPage
      * @return void
      */
-    public function __inject(Install $installPage)
+    public function __inject(Install $installPage, Setup $magentoSetup, DevdocsInstall $devdocsInstallPage)
     {
-        $magentoBaseDir = dirname(dirname(dirname(MTF_BP)));
         // Uninstall Magento.
-        shell_exec("php -f $magentoBaseDir/bin/magento setup:uninstall -n");
+        $magentoSetup->uninstall();
         $this->installPage = $installPage;
+        $this->devdocsInstallPage = $devdocsInstallPage;
     }
 
     /**
@@ -91,6 +120,8 @@ class InstallTest extends Injectable
      * @param AssertAgreementTextPresent $assertLicense
      * @param AssertSuccessfulReadinessCheck $assertReadiness
      * @param AssertAdminUriAutogenerated $assertAdminUri
+     * @param AssertDevdocsLink $assertDevdocsLink
+     * @param BrowserInterface $browser
      * @param array $install [optional]
      * @return array
      */
@@ -101,6 +132,8 @@ class InstallTest extends Injectable
         AssertAgreementTextPresent $assertLicense,
         AssertSuccessfulReadinessCheck $assertReadiness,
         AssertAdminUriAutogenerated $assertAdminUri,
+        AssertDevdocsLink $assertDevdocsLink,
+        BrowserInterface $browser,
         array $install = []
     ) {
         $dataConfig = array_merge($install, $configData);
@@ -111,6 +144,14 @@ class InstallTest extends Injectable
         $installConfig = $fixtureFactory->create(\Magento\Install\Test\Fixture\Install::class, ['data' => $dataConfig]);
         // Steps
         $this->installPage->open();
+        // Verify Developer Documentation link.
+        $handle = $browser->getCurrentWindow();
+        $this->installPage->getLandingBlock()->clickLink(self::DEVDOCS_LINK_TEXT);
+        $this->waitTillTermsLinkNotVisible($browser);
+        $docHandle = $browser->getCurrentWindow();
+        $assertDevdocsLink->processAssert($this->devdocsInstallPage);
+        $browser->closeWindow($docHandle);
+        $browser->selectWindow($handle);
         // Verify license agreement.
         $this->installPage->getLandingBlock()->clickTermsAndAgreement();
         $assertLicense->processAssert($this->installPage);
@@ -139,4 +180,20 @@ class InstallTest extends Injectable
 
         return ['installConfig' => $installConfig];
     }
+
+    /**
+     * Wait till terms link is not visible.
+     *
+     * @param BrowserInterface $browser
+     * @return void
+     */
+    private function waitTillTermsLinkNotVisible(BrowserInterface $browser)
+    {
+        $browser->waitUntil(
+            function () use ($browser) {
+                $browser->selectWindow();
+                return $browser->find($this->termsLink)->isVisible() ? null : true;
+            }
+        );
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushAdditionalCachesTest.php b/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushAdditionalCachesTest.php
index 8fd543d88a8af536a15e90e68bdeb7fdfc44a3ef..13aa7bbcb197d860915f507ff3ca17c8b66b329e 100644
--- a/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushAdditionalCachesTest.php
+++ b/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushAdditionalCachesTest.php
@@ -22,6 +22,7 @@ class FlushAdditionalCachesTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const SEVERITY = 'S2';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushAdditionalCachesTest.xml b/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushAdditionalCachesTest.xml
index 65a9b2d17a262f404062a27407be285a3649baff..b57fb31733978c360b1819432c67a88114ec1fee 100644
--- a/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushAdditionalCachesTest.xml
+++ b/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushAdditionalCachesTest.xml
@@ -8,16 +8,19 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\PageCache\Test\TestCase\FlushAdditionalCachesTest" summary="Flush Additional Caches" ticketId="MAGETWO-34052">
         <variation name="FlushCatalogImagesCacheTest">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="flushButtonName" xsi:type="string">Flush Catalog Images Cache</data>
             <data name="successMessage" xsi:type="string">The image cache was cleaned.</data>
             <constraint name="Magento\PageCache\Test\Constraint\AssertCacheFlushSuccessMessage" />
         </variation>
         <variation name="FlushJavaScriptCSSCacheTest">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="flushButtonName" xsi:type="string">Flush JavaScript/CSS Cache</data>
             <data name="successMessage" xsi:type="string">The JavaScript/CSS cache has been cleaned.</data>
             <constraint name="Magento\PageCache\Test\Constraint\AssertCacheFlushSuccessMessage" />
         </variation>
         <variation name="FlushStaticFilesCacheTest">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="flushButtonName" xsi:type="string">Flush Static Files Cache</data>
             <data name="successMessage" xsi:type="string">The static files cache has been cleaned.</data>
             <constraint name="Magento\PageCache\Test\Constraint\AssertCacheFlushSuccessMessage" />
diff --git a/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushStaticFilesCacheButtonVisibilityTest.php b/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushStaticFilesCacheButtonVisibilityTest.php
index 28090b866290370fff0ec8b48bde0d196ffb6d5b..9cfdf2551218b654fca882aee6011250ff802bbf 100644
--- a/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushStaticFilesCacheButtonVisibilityTest.php
+++ b/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushStaticFilesCacheButtonVisibilityTest.php
@@ -21,6 +21,7 @@ class FlushStaticFilesCacheButtonVisibilityTest extends Injectable
 {
     /* tags */
     const MVP = 'no';
+    const SEVERITY = 'S2';
     /* end tags */
     
     /**
diff --git a/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushStaticFilesCacheButtonVisibilityTest.xml b/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushStaticFilesCacheButtonVisibilityTest.xml
index 670c46b3214a31b9641e8eaa8bc14a4111068e61..ae6605b28a088759945b44354bf2cf2ec0e13dda 100644
--- a/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushStaticFilesCacheButtonVisibilityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/PageCache/Test/TestCase/FlushStaticFilesCacheButtonVisibilityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\PageCache\Test\TestCase\FlushStaticFilesCacheButtonVisibilityTest" summary="Flush Static Files Cache button visibility" ticketId="MAGETWO-39934">
         <variation name="FlushStaticFilesCacheButtonVisibilityTest">
+            <data name="tag" xsi:type="string">severity:S3</data>
             <constraint name="Magento\PageCache\Test\Constraint\AssertFlushStaticFilesCacheButtonVisibility" />
         </variation>
     </testCase>
diff --git a/dev/tests/functional/tests/app/Magento/PageCache/Test/etc/di.xml b/dev/tests/functional/tests/app/Magento/PageCache/Test/etc/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..70b7881a3558d3ff2b2dd9b6561c70bb97c788fa
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/PageCache/Test/etc/di.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
+    <type name="Magento\PageCache\Test\Constraint\AssertCacheFlushSuccessMessage">
+        <arguments>
+            <argument name="severity" xsi:type="string">S2</argument>
+      </arguments>
+    </type>
+    <type name="Magento\PageCache\Test\Constraint\AssertCacheIsRefreshableAndInvalidated">
+        <arguments>
+            <argument name="severity" xsi:type="string">S2</argument>
+        </arguments>
+    </type>
+    <type name="Magento\PageCache\Test\Constraint\AssertFlushStaticFilesCacheButtonVisibility">
+        <arguments>
+            <argument name="severity" xsi:type="string">S3</argument>
+        </arguments>
+    </type>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Payment/Test/Constraint/AssertCardRequiredFields.php b/dev/tests/functional/tests/app/Magento/Payment/Test/Constraint/AssertCardRequiredFields.php
new file mode 100644
index 0000000000000000000000000000000000000000..2b1d9bdcf2df8fdb32869731b7b3af05d47bc417
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Payment/Test/Constraint/AssertCardRequiredFields.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Payment\Test\Constraint;
+
+use Magento\Mtf\Constraint\AbstractConstraint;
+use Magento\Payment\Test\Repository\CreditCardAdmin;
+use Magento\Sales\Test\Page\Adminhtml\OrderCreateIndex;
+
+/**
+ * Class AssertCardRequiredFields
+ *
+ * Assert that fields are active.
+ */
+class AssertCardRequiredFields extends AbstractConstraint
+{
+    /**
+     * Expected required field message.
+     */
+    const REQUIRE_MESSAGE = 'This is a required field.';
+
+    /**
+     * Expected required valid number message.
+     */
+    const VALID_NUMBER_MESSAGE = 'Please enter a valid number in this field.';
+
+    /**
+     * Assert required fields on credit card payment method in backend.
+     * @param OrderCreateIndex $orderCreateIndex
+     * @param CreditCardAdmin $creditCard
+     * @return void
+     */
+    public function processAssert(OrderCreateIndex $orderCreateIndex, CreditCardAdmin $creditCard)
+    {
+        $actualRequiredFields = $orderCreateIndex->getCreateBlock()->getBillingMethodBlock()
+            ->getJsErrors();
+        $creditCardEmpty = $creditCard->get('visa_empty');
+        foreach (array_keys($creditCardEmpty) as $field) {
+            \PHPUnit_Framework_Assert::assertTrue(
+                isset($actualRequiredFields[$field]),
+                "Field '$field' is not highlighted with an JS error."
+            );
+            $expected = self::REQUIRE_MESSAGE;
+            if (in_array($field, ['cc_number', 'cc_cid'])) {
+                $expected = self::VALID_NUMBER_MESSAGE;
+            }
+            \PHPUnit_Framework_Assert::assertEquals(
+                $expected,
+                $actualRequiredFields[$field],
+                "Field '$field' is not highlighted as required."
+            );
+        }
+    }
+
+    /**
+     * Returns string representation of successful assertion.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'All required fields on customer form are highlighted.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Payment/Test/Repository/CreditCardAdmin.xml b/dev/tests/functional/tests/app/Magento/Payment/Test/Repository/CreditCardAdmin.xml
index 1109b70eec7cc14dd343e06fb21c8d8f0eb9c52b..371c8f350c6af028ddc544c23142f2886d699dbd 100644
--- a/dev/tests/functional/tests/app/Magento/Payment/Test/Repository/CreditCardAdmin.xml
+++ b/dev/tests/functional/tests/app/Magento/Payment/Test/Repository/CreditCardAdmin.xml
@@ -22,5 +22,11 @@
             <field name="cc_exp_year" xsi:type="string">2020</field>
             <field name="cc_cid" xsi:type="string">123</field>
         </dataset>
+        <dataset name="visa_empty">
+            <field name="cc_type" xsi:type="string">Please Select</field>
+            <field name="cc_number" xsi:type="string" />
+            <field name="cc_exp_month" xsi:type="string">Month</field>
+            <field name="cc_cid" xsi:type="string" />
+        </dataset>
     </repository>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/CreatePayFlowOrderBackendNegativeTest.php b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/CreatePayFlowOrderBackendNegativeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d4ec11acd51bf53c38de3be6e927b8a24037c1d8
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/CreatePayFlowOrderBackendNegativeTest.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Paypal\Test\TestCase;
+
+use Magento\Mtf\TestCase\Scenario;
+
+/**
+ * Preconditions:
+ * 1. Create customer.
+ * 2. Create product.
+ *
+ * Steps:
+ * 1. Open Backend.
+ * 2. Open Sales -> Orders.
+ * 3. Click Create New Order.
+ * 4. Select Customer created in preconditions.
+ * 5. Add Product.
+ * 6. Fill data according dataset.
+ * 7. Click Update Product qty.
+ * 8. Fill data according dataset.
+ * 9. Click Get Shipping Method and rates.
+ * 10. Fill data according dataset.
+ * 11. Select payment method Credit Card (PayFlow Pro)
+ * 12. Leave empty required fields for credit card 
+ * 13. Click Submit order button
+ *
+ * @group PayPal
+ * @ZephyrId MAGETWO-58934
+ */
+class CreatePayFlowOrderBackendNegativeTest extends Scenario
+{
+    /* tags */
+    const MVP = 'yes';
+    const TEST_TYPE = '3rd_party_test';
+    /* end tags */
+
+    /**
+     * Runs sales order on backend.
+     *
+     * @return void
+     */
+    public function test()
+    {
+        $this->executeScenario();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/CreatePayFlowOrderBackendNegativeTest.xml b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/CreatePayFlowOrderBackendNegativeTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..04b34813e59ceacd332657d66366d2789f469e71
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/CreatePayFlowOrderBackendNegativeTest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\Paypal\Test\TestCase\CreatePayFlowOrderBackendNegativeTest" summary="Verify required fields validation for PayPal Payflow Pro credit card on admin order creation" ticketId="MAGETWO-58934">
+        <variation name="CreatePayFlowOrderBackendNegativeTestPayflowProVariation1" summary="Verify required fields validation for credit card on admin order creation" ticketId="MAGETWO-58934">
+            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <data name="products/0" xsi:type="string">catalogProductSimple::product_10_dollar</data>
+            <data name="customer/dataset" xsi:type="string">default</data>
+            <data name="billingAddress/dataset" xsi:type="string">US_address_1_without_email</data>
+            <data name="saveAddress" xsi:type="string">No</data>
+            <data name="shipping/shipping_service" xsi:type="string">Flat Rate</data>
+            <data name="shipping/shipping_method" xsi:type="string">Fixed</data>
+            <data name="prices" xsi:type="array">
+                <item name="grandTotal" xsi:type="string">15.00</item>
+            </data>
+            <data name="payment/method" xsi:type="string">payflowpro</data>
+            <data name="creditCardClass" xsi:type="string">credit_card_admin</data>
+            <data name="creditCard/dataset" xsi:type="string">visa_empty</data>
+            <data name="creditCardSave" xsi:type="string">Yes</data>
+            <data name="configData" xsi:type="string">payflowpro, payflowpro_use_vault</data>
+            <constraint name="Magento\Payment\Test\Constraint\AssertCardRequiredFields" />
+        </variation>
+    </testCase>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/UseVaultOnCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/UseVaultOnCheckoutTest.xml
index a71dd812b50f7bf982fd28678991e9205c0f0b70..bde3837d71fda02bad93ac1ced7c3c08835deafe 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/UseVaultOnCheckoutTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/TestCase/UseVaultOnCheckoutTest.xml
@@ -15,6 +15,7 @@
             <data name="shipping/shipping_service" xsi:type="string">Flat Rate</data>
             <data name="shipping/shipping_method" xsi:type="string">Fixed</data>
             <data name="payment/method" xsi:type="string">payflowpro</data>
+            <data name="vault/method" xsi:type="string">payflowpro_cc_vault</data>
             <data name="creditCardClass" xsi:type="string">credit_card</data>
             <data name="creditCard/dataset" xsi:type="string">visa_default</data>
             <data name="creditCardSave" xsi:type="string">Yes</data>
diff --git a/dev/tests/functional/tests/app/Magento/Paypal/Test/etc/testcase.xml b/dev/tests/functional/tests/app/Magento/Paypal/Test/etc/testcase.xml
index f361530def8617d5e4d13451b24e329d31794ef2..53f10b10d38b6329a9b5119088e89443fb85105c 100644
--- a/dev/tests/functional/tests/app/Magento/Paypal/Test/etc/testcase.xml
+++ b/dev/tests/functional/tests/app/Magento/Paypal/Test/etc/testcase.xml
@@ -69,4 +69,19 @@
         <step name="checkPayflowProConfig" module="Magento_Paypal" next="checkPayflowLinkConfig" />
         <step name="checkPayflowLinkConfig" module="Magento_Paypal" />
     </scenario>
+    <scenario name="CreatePayFlowOrderBackendNegativeTest" firstStep="setupConfiguration">
+        <step name="setupConfiguration" module="Magento_Config" next="createProducts" />
+        <step name="createProducts" module="Magento_Catalog" next="createCustomer" />
+        <step name="createCustomer" module="Magento_Customer" next="openSalesOrders" />
+        <step name="openSalesOrders" module="Magento_Sales" next="createNewOrder" />
+        <step name="createNewOrder" module="Magento_Sales" next="selectCustomerOrder" />
+        <step name="selectCustomerOrder" module="Magento_Sales" next="selectStore" />
+        <step name="selectStore" module="Magento_Sales" next="addProducts" />
+        <step name="addProducts" module="Magento_Sales" next="fillAccountInformation" />
+        <step name="fillAccountInformation" module="Magento_Sales" next="fillBillingAddress" />
+        <step name="fillBillingAddress" module="Magento_Sales" next="selectShippingMethodForOrder" />
+        <step name="selectShippingMethodForOrder" module="Magento_Sales" next="saveCreditCardOnBackend" />
+        <step name="saveCreditCardOnBackend" module="Magento_Vault" next="submitOrderNegative" />
+        <step name="submitOrderNegative" module="Magento_Sales" />
+    </scenario>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create.php
index 874fe2844c476cd530b682143b3099c41646e28d..b86ac18ea3dd4a70a5b3ba2530edbf89cfe1068c 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create.php
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create.php
@@ -165,7 +165,7 @@ class Create extends Block
      *
      * @return \Magento\Sales\Test\Block\Adminhtml\Order\Create\Billing\Method
      */
-    protected function getBillingMethodBlock()
+    public function getBillingMethodBlock()
     {
         return $this->blockFactory->create(
             \Magento\Sales\Test\Block\Adminhtml\Order\Create\Billing\Method::class,
@@ -279,25 +279,40 @@ class Create extends Block
     }
 
     /**
-     * Fill addresses based on present data in customer and order fixtures.
+     * Fill Billing Address.
      *
-     * @param FixtureInterface $address
-     * @param string $saveAddress
+     * @param FixtureInterface $billingAddress
+     * @param string $saveAddress [optional]
      * @param bool $setShippingAddress [optional]
      * @return void
      */
-    public function fillAddresses(FixtureInterface $address, $saveAddress = 'No', $setShippingAddress = true)
-    {
+    public function fillBillingAddress(
+        FixtureInterface $billingAddress,
+        $saveAddress = 'No',
+        $setShippingAddress = true
+    ) {
         if ($setShippingAddress) {
             $this->getShippingAddressBlock()->uncheckSameAsBillingShippingAddress();
         }
-        $this->browser->find($this->header)->hover();
-        $this->getBillingAddressBlock()->fill($address);
+        $this->getBillingAddressBlock()->fill($billingAddress);
         $this->getBillingAddressBlock()->saveInAddressBookBillingAddress($saveAddress);
         $this->getTemplateBlock()->waitLoader();
-        if ($setShippingAddress) {
+    }
+
+    /**
+     * Fill Shipping Address.
+     *
+     * @param FixtureInterface $shippingAddress [optional]
+     * @return void
+     */
+    public function fillShippingAddress(FixtureInterface $shippingAddress = null)
+    {
+        if (!$shippingAddress) {
             $this->getShippingAddressBlock()->setSameAsBillingShippingAddress();
             $this->getTemplateBlock()->waitLoader();
+        } else {
+            $this->getShippingAddressBlock()->fill($shippingAddress);
+            $this->getTemplateBlock()->waitLoader();
         }
     }
 
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Billing/Method.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Billing/Method.php
index 280211c7ef20f54e43f31227551a2b832d7c1ea6..8477af0087fd47e07b8fee3e6c5138c690369d05 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Billing/Method.php
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Billing/Method.php
@@ -8,6 +8,7 @@ namespace Magento\Sales\Test\Block\Adminhtml\Order\Create\Billing;
 
 use Magento\Mtf\Block\Block;
 use Magento\Mtf\Fixture\InjectableFixture;
+use Magento\Mtf\Client\Locator;
 
 /**
  * Adminhtml sales order create payment method block.
@@ -42,6 +43,20 @@ class Method extends Block
      */
     protected $loader = '[data-role=loader]';
 
+    /**
+     * Field with Mage error.
+     *
+     * @var string
+     */
+    protected $mageErrorField = '//fieldset/*[contains(@class,"field ")][.//*[contains(@class,"error")]]';
+
+    /**
+     * Mage error text.
+     *
+     * @var string
+     */
+    protected $mageErrorText = './/label[contains(@class,"error")]';
+
     /**
      * Select payment method.
      *
@@ -69,4 +84,23 @@ class Method extends Block
             $formBlock->fill($creditCard);
         }
     }
+
+    /**
+     * @return array
+     */
+    public function getJsErrors()
+    {
+        $data = [];
+        $elements = $this->_rootElement->getElements($this->mageErrorField, Locator::SELECTOR_XPATH);
+        foreach ($elements as $element) {
+            $error = $element->find($this->mageErrorText, Locator::SELECTOR_XPATH);
+            if ($error->isVisible()) {
+                $label = $element->find('.//*[contains(@name,"payment")]', Locator::SELECTOR_XPATH);
+                $label = $label->getAttribute('name');
+                $label = preg_replace('/payment\[(.*)\]/u', '$1', $label);
+                $data[$label] = $error->getText();
+            }
+        }
+        return $data;
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Shipping/Address.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Shipping/Address.php
index 044286ea1434a369b31074b739b8ee998b405c8f..f52d898d232d145c117911d77968431001eeba70 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Shipping/Address.php
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Shipping/Address.php
@@ -9,6 +9,7 @@ namespace Magento\Sales\Test\Block\Adminhtml\Order\Create\Shipping;
 use Magento\Mtf\Block\Form;
 use Magento\Mtf\Client\Locator;
 use Magento\Backend\Test\Block\Template;
+use Magento\Mtf\Client\Element\SimpleElement;
 
 /**
  * Adminhtml sales order create shipping address block.
@@ -29,6 +30,13 @@ class Address extends Form
      */
     protected $sameAsBilling = '#order-shipping_same_as_billing';
 
+    /**
+     * Wait element.
+     *
+     * @var string
+     */
+    private $waitElement = '.loading-mask';
+
     /**
      * Shipping address title selector.
      *
@@ -95,4 +103,41 @@ class Address extends Form
             ['element' => $this->_rootElement->find($this->templateBlock, Locator::SELECTOR_XPATH)]
         );
     }
+
+    /**
+     * Fill specified form data.
+     *
+     * @param array $fields
+     * @param SimpleElement $element
+     * @return void
+     * @throws \Exception
+     */
+    protected function _fill(array $fields, SimpleElement $element = null)
+    {
+        $context = ($element === null) ? $this->_rootElement : $element;
+        foreach ($fields as $name => $field) {
+            $this->waitFormLoading();
+            $element = $this->getElement($context, $field);
+            if (!$element->isDisabled()) {
+                $element->setValue($field['value']);
+            } else {
+                throw new \Exception("Unable to set value to field '$name' as it's disabled.");
+            }
+        }
+    }
+
+    /**
+     * Wait for form loading.
+     *
+     * @return void
+     */
+    private function waitFormLoading()
+    {
+        $this->_rootElement->click();
+        $this->browser->waitUntil(
+            function () {
+                return $this->browser->find($this->waitElement)->isVisible() ? null : true;
+            }
+        );
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Shipping/Address.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Shipping/Address.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2dc30a686c0d9c3b997f49a2998fff971b6b1b64
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Shipping/Address.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<mapping strict="0">
+    <wrapper>order[shipping_address]</wrapper>
+    <fields>
+        <firstname />
+        <lastname />
+        <company />
+        <street>
+            <selector>[name='order[shipping_address][street][0]']</selector>
+        </street>
+        <city />
+        <country_id>
+            <input>select</input>
+        </country_id>
+        <region_id>
+            <input>select</input>
+        </region_id>
+        <postcode />
+        <telephone />
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Shipping/Method.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Shipping/Method.php
index 3d9673e29805dee1383ac9b3354c4905886748e8..90a75f665cbf9f95eebe2dfa26d135082d3912f4 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Shipping/Method.php
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/Create/Shipping/Method.php
@@ -28,6 +28,13 @@ class Method extends Block
      */
     protected $shippingMethod = '//dt[contains(.,"%s")]/following-sibling::*//*[contains(text(), "%s")]';
 
+    /**
+     * Wait element.
+     *
+     * @var string
+     */
+    private $waitElement = '.loading-mask';
+
     /**
      * Select shipping method.
      *
@@ -36,6 +43,7 @@ class Method extends Block
      */
     public function selectShippingMethod(array $shippingMethod)
     {
+        $this->waitFormLoading();
         if ($this->_rootElement->find($this->shippingMethodsLink)->isVisible()) {
             $this->_rootElement->find($this->shippingMethodsLink)->click();
         }
@@ -46,4 +54,19 @@ class Method extends Block
         );
         $this->_rootElement->find($selector, Locator::SELECTOR_XPATH)->click();
     }
+
+    /**
+     * Wait for form loading.
+     *
+     * @return void
+     */
+    private function waitFormLoading()
+    {
+        $this->_rootElement->click();
+        $this->browser->waitUntil(
+            function () {
+                return $this->browser->find($this->waitElement)->isVisible() ? null : true;
+            }
+        );
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/History.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/History.php
index 2235122955a723ccc0cafcafc51d24934405e896..740f8f03fe6394a18ceed667a0ba695262229cf2 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/History.php
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Block/Adminhtml/Order/History.php
@@ -21,6 +21,20 @@ class History extends Block
      */
     protected $commentHistory = '.note-list-comment';
 
+    /**
+     * Comment history status.
+     *
+     * @var string
+     */
+    protected $commentHistoryStatus = '.note-list-status';
+
+    /**
+     * Comment history notified status.
+     *
+     * @var string
+     */
+    protected $commentHistoryNotifiedStatus = '.note-list-customer';
+
     /**
      * Authorized Amount.
      *
@@ -103,6 +117,28 @@ class History extends Block
         return $result;
     }
 
+    /**
+     * Gets the status which presented in comment
+     *
+     * @return string
+     */
+    public function getStatus()
+    {
+        $this->waitCommentsHistory();
+        return $this->_rootElement->find($this->commentHistoryStatus, Locator::SELECTOR_CSS)->getText();
+    }
+
+    /**
+     * Gets the is customer notified status which presented in comment
+     *
+     * @return string
+     */
+    public function getNotifiedStatus()
+    {
+        $this->waitCommentsHistory();
+        return $this->_rootElement->find($this->commentHistoryNotifiedStatus, Locator::SELECTOR_CSS)->getText();
+    }
+
     /**
      * Wait for comments history is visible.
      *
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertInvoiceInInvoicesTab.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertInvoiceInInvoicesTab.php
index 501d3ec65dd743348ab02473aac355c043fd2412..9b15cfb39a30b0c23401005c4ae65e9804782fb1 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertInvoiceInInvoicesTab.php
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertInvoiceInInvoicesTab.php
@@ -36,13 +36,13 @@ class AssertInvoiceInInvoicesTab extends AbstractConstraint
         $orderIndex->getSalesOrderGrid()->searchAndOpen(['id' => $order->getId()]);
         $salesOrderView->getOrderForm()->openTab('invoices');
         /** @var Grid $grid */
-        $grid = $salesOrderView->getOrderForm()->getTab('invoices')->getGridBlock();
+        $grid = $salesOrderView->getOrderInvoiceGrid();
         $amount = $order->getPrice();
         foreach ($ids['invoiceIds'] as $key => $invoiceId) {
             $filter = [
                 'id' => $invoiceId,
-                'amount_from' => $amount[$key]['grand_invoice_total'],
-                'amount_to' => $amount[$key]['grand_invoice_total'],
+                'grand_total_from' => $amount[$key]['grand_invoice_total'],
+                'grand_total_to' => $amount[$key]['grand_invoice_total'],
             ];
             $grid->search($filter);
             $filter['amount_from'] = number_format($amount[$key]['grand_invoice_total'], 2);
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCommentsHistoryNotifyStatus.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCommentsHistoryNotifyStatus.php
new file mode 100644
index 0000000000000000000000000000000000000000..013c3562b709096a12f8e5f88a4c8f806640af57
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertOrderCommentsHistoryNotifyStatus.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Sales\Test\Constraint;
+
+use Magento\Sales\Test\Page\Adminhtml\SalesOrderView;
+use Magento\Sales\Test\Page\Adminhtml\OrderIndex;
+use Magento\Mtf\Constraint\AbstractConstraint;
+use Magento\Sales\Test\Fixture\OrderInjectable;
+
+/**
+ * Class AssertOrderCommentsHistoryNotifyStatus
+ */
+class AssertOrderCommentsHistoryNotifyStatus extends AbstractConstraint
+{
+    /**
+     * Assert that comment about refunded amount exist in Comments History section on order page in Admin.
+     *
+     * @param SalesOrderView $salesOrderView
+     * @param OrderIndex $salesOrder
+     * @param OrderInjectable $order
+     * @param array $data
+     */
+    public function processAssert(
+        SalesOrderView $salesOrderView,
+        OrderIndex $salesOrder,
+        OrderInjectable $order,
+        array $data
+    ) {
+        $salesOrder->open();
+        $salesOrder->getSalesOrderGrid()->searchAndOpen(['id' => $order->getId()]);
+        $sendMail = isset($data['form_data']['send_email']) ? filter_var(
+            $data['form_data']['send_email'],
+            FILTER_VALIDATE_BOOLEAN
+        ) : false;
+        \PHPUnit_Framework_Assert::assertContains(
+            $salesOrderView->getOrderHistoryBlock()->getNotifiedStatus(),
+            (bool)$sendMail ? 'Customer Notified' : 'Customer Not Notified'
+        );
+    }
+
+    /**
+     * Returns string representation of successful assertion.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return "Message with appropriate notification status is available in Comments History section.";
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertRefundOrderStatusInCommentsHistory.php b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertRefundOrderStatusInCommentsHistory.php
new file mode 100644
index 0000000000000000000000000000000000000000..89faffc8ec0729082c81839ccd4762fdc335a8f3
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Constraint/AssertRefundOrderStatusInCommentsHistory.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Sales\Test\Constraint;
+
+use Magento\Sales\Test\Page\Adminhtml\SalesOrderView;
+use Magento\Sales\Test\Page\Adminhtml\OrderIndex;
+use Magento\Mtf\Constraint\AbstractConstraint;
+use Magento\Sales\Test\Fixture\OrderInjectable;
+
+/**
+ * Class AssertRefundOrderStatusInCommentsHistory
+ */
+class AssertRefundOrderStatusInCommentsHistory extends AbstractConstraint
+{
+    /**
+     * Assert that comment about refunded amount exist in Comments History section on order page in Admin.
+     *
+     * @param SalesOrderView $salesOrderView
+     * @param OrderIndex $salesOrder
+     * @param OrderInjectable $order
+     * @return void
+     */
+    public function processAssert(
+        SalesOrderView $salesOrderView,
+        OrderIndex $salesOrder,
+        OrderInjectable $order
+    ) {
+        $salesOrder->open();
+        $salesOrder->getSalesOrderGrid()->searchAndOpen(['id' => $order->getId()]);
+        \PHPUnit_Framework_Assert::assertContains(
+            $salesOrderView->getOrderForm()->getOrderInfoBlock()->getOrderStatus(),
+            $salesOrderView->getOrderHistoryBlock()->getStatus()
+        );
+    }
+
+    /**
+     * Returns string representation of successful assertion.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return "Message with appropriate order status is available in Comments History section.";
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/Page/Adminhtml/SalesOrderView.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/Page/Adminhtml/SalesOrderView.xml
index d5b7d99661806e4cf3f49f29575ab0c1100520a9..674b42732d2cd955db0e05b03ef79a8021492642 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/Page/Adminhtml/SalesOrderView.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/Page/Adminhtml/SalesOrderView.xml
@@ -16,5 +16,6 @@
         <block name="orderHistoryBlock" class="Magento\Sales\Test\Block\Adminhtml\Order\History" locator=".order-comments-history" strategy="css selector" />
         <block name="informationBlock" class="Magento\Sales\Test\Block\Adminhtml\Order\View\Info" locator=".order-account-information" strategy="css selector" />
         <block name="orderInfoBlock" class="Magento\Sales\Test\Block\Adminhtml\Order\View\Tab\Info" locator="[data-ui-id='sales-order-tabs-tab-content-order-info']" strategy="css selector" />
+        <block name="orderInvoiceGrid" class="Magento\Sales\Test\Block\Adminhtml\Invoice\Grid" locator="//div[contains(@data-bind, 'sales_order_view_invoice_grid.sales_order_view_invoice_grid')]" strategy="xpath" />
     </page>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.php
index 1779ad437c76e4192fd8c9774fc5a6f0ab8ccafb..71575ffb16b858cd43353c02d82f2d496eac4a51 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.php
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.php
@@ -10,12 +10,13 @@ use Magento\Sales\Test\Fixture\OrderInjectable;
 use Magento\Sales\Test\Page\Adminhtml\OrderIndex;
 use Magento\Sales\Test\Page\Adminhtml\SalesOrderView;
 use Magento\Mtf\TestCase\Injectable;
+use Magento\Mtf\TestStep\TestStepFactory;
 
 /**
  * Preconditions:
- * 1. Enable payment method "Check/Money Order".
- * 2. Enable shipping method one of "Flat Rate".
- * 3. Create order
+ * 1. Enable payment method: "Check/Money Order/Bank Transfer/Cash on Delivery/Purchase Order/Zero Subtotal Checkout".
+ * 2. Enable shipping method one of "Flat Rate/Free Shipping".
+ * 3. Create order.
  *
  * Steps:
  * 1. Login to backend.
@@ -48,20 +49,7 @@ class CancelCreatedOrderTest extends Injectable
     protected $salesOrderView;
 
     /**
-     * Enable "Check/Money Order" and "Flat Rate" in configuration.
-     *
-     * @return void
-     */
-    public function __prepare()
-    {
-        $this->objectManager->create(
-            \Magento\Config\Test\TestStep\SetupConfigurationStep::class,
-            ['configData' => 'checkmo, flatrate', 'rollback' => true]
-        )->run();
-    }
-
-    /**
-     * Inject pages
+     * Inject pages.
      *
      * @param OrderIndex $orderIndex
      * @param SalesOrderView $salesOrderView
@@ -77,11 +65,17 @@ class CancelCreatedOrderTest extends Injectable
      * Cancel created order.
      *
      * @param OrderInjectable $order
+     * @param TestStepFactory $stepFactory
+     * @param string $configData
      * @return array
      */
-    public function test(OrderInjectable $order)
+    public function test(OrderInjectable $order, TestStepFactory $stepFactory, $configData)
     {
         // Preconditions
+        $stepFactory->create(
+            \Magento\Config\Test\TestStep\SetupConfigurationStep::class,
+            ['configData' => $configData]
+        )->run();
         $order->persist();
 
         // Steps
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.xml
index bcacacc57589a88806a2bcad18912ab84760ec8f..b65b9a31f72f3d7ff7290afb4393edeaf73679bc 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CancelCreatedOrderTest.xml
@@ -7,14 +7,49 @@
  -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Sales\Test\TestCase\CancelCreatedOrderTest" summary="Cancel Created Order for Offline Payment Methods" ticketId="MAGETWO-28191">
-        <variation name="CancelCreatedOrderTestVariation1">
-            <data name="description" xsi:type="string">cancel order and check status on storefront</data>
+        <variation name="CancelCreatedOrderTestVariationWithCheckMoneyOrderPaymentMethod" summary="Cancel order with check/money order payment method and check status on storefront">
             <data name="order/dataset" xsi:type="string">default</data>
             <data name="order/data/entity_id/products" xsi:type="string">catalogProductSimple::default,catalogProductSimple::default</data>
             <data name="status" xsi:type="string">Canceled</data>
+            <data name="configData" xsi:type="string">checkmo</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderCancelSuccessMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGrid" />
             <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGridOnFrontend" />
         </variation>
+        <variation name="CancelCreatedOrderTestVariationWithZeroSubtotalCheckout" summary="Cancel order with zero subtotal checkout payment method and check status on storefront">
+            <data name="order/dataset" xsi:type="string">default</data>
+            <data name="order/data/payment_auth_expiration/method" xsi:type="string">free</data>
+            <data name="order/data/shipping_method" xsi:type="string">freeshipping_freeshipping</data>
+            <data name="order/data/coupon_code/dataset" xsi:type="string">active_sales_rule_with_fixed_price_discount_coupon</data>
+            <data name="order/data/entity_id/products" xsi:type="string">catalogProductSimple::product_10_dollar</data>
+            <data name="status" xsi:type="string">Canceled</data>
+            <data name="configData" xsi:type="string">zero_subtotal_checkout, freeshipping</data>
+            <constraint name="Magento\Sales\Test\Constraint\AssertOrderCancelSuccessMessage" />
+            <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGridOnFrontend" />
+        </variation>
+        <variation name="CancelCreatedOrderTestVariationWithBankTransferPaymentMethod" summary="Cancel order with bank transfer payment method and check status on storefront">
+            <data name="order/dataset" xsi:type="string">default</data>
+            <data name="order/data/payment_auth_expiration/method" xsi:type="string">banktransfer</data>
+            <data name="status" xsi:type="string">Canceled</data>
+            <data name="configData" xsi:type="string">banktransfer</data>
+            <constraint name="Magento\Sales\Test\Constraint\AssertOrderCancelSuccessMessage" />
+            <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGridOnFrontend" />
+        </variation>
+        <variation name="CancelCreatedOrderTestVariationWithCashOnDeliveryPaymentMethod" summary="Cancel order with cash on delivery payment method and check status on storefront">
+            <data name="order/dataset" xsi:type="string">default</data>
+            <data name="order/data/payment_auth_expiration/method" xsi:type="string">cashondelivery</data>
+            <data name="status" xsi:type="string">Canceled</data>
+            <data name="configData" xsi:type="string">cashondelivery</data>
+            <constraint name="Magento\Sales\Test\Constraint\AssertOrderCancelSuccessMessage" />
+            <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGridOnFrontend" />
+        </variation>
+        <variation name="CancelCreatedOrderTestVariationWithPurchaseOrderPaymentMethod" summary="Cancel order with purchase order payment method and check status on storefront">
+            <data name="order/dataset" xsi:type="string">default</data>
+            <data name="order/data/payment_auth_expiration/method" xsi:type="string">purchaseorder</data>
+            <data name="status" xsi:type="string">Canceled</data>
+            <data name="configData" xsi:type="string">purchaseorder</data>
+            <constraint name="Magento\Sales\Test\Constraint\AssertOrderCancelSuccessMessage" />
+            <constraint name="Magento\Sales\Test\Constraint\AssertOrderInOrdersGridOnFrontend" />
+        </variation>
     </testCase>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php
index ed00a414bd0e689cfdb15b75ccf5d795ca40c992..9d19d10f4d40c6c3e317a97e7e83cd3c79e6f8ae 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.php
@@ -10,10 +10,11 @@ use Magento\Sales\Test\Fixture\OrderInjectable;
 use Magento\Mtf\Fixture\FixtureFactory;
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\TestCase\Injectable;
+use Magento\Mtf\TestStep\TestStepFactory;
 
 /**
  * Preconditions:
- * 1. Enable payment method "Check/Money Order".
+ * 1. Enable payment method one of "Check/Money Order/Bank Transfer/Cash on Delivery/Purchase Order".
  * 2. Enable shipping method one of "Flat Rate/Free Shipping".
  * 3. Create order.
  * 4. Create Invoice.
@@ -54,38 +55,34 @@ class CreateCreditMemoEntityTest extends Injectable
         'price',
     ];
 
-    /**
-     * Set up configuration.
-     *
-     * @param FixtureFactory $fixtureFactory
-     * @return void
-     */
-    public function __prepare(FixtureFactory $fixtureFactory)
-    {
-        $this->fixtureFactory = $fixtureFactory;
-
-        $setupConfigurationStep = $this->objectManager->create(
-            \Magento\Config\Test\TestStep\SetupConfigurationStep::class,
-            ['configData' => 'checkmo, flatrate']
-        );
-        $setupConfigurationStep->run();
-    }
-
     /**
      * Create credit memo.
      *
+     * @param TestStepFactory $stepFactory
+     * @param FixtureFactory $fixtureFactory
      * @param OrderInjectable $order
      * @param array $data
+     * @param string $configData
      * @return array
      */
-    public function test(OrderInjectable $order, array $data)
-    {
+    public function test(
+        TestStepFactory $stepFactory,
+        FixtureFactory $fixtureFactory,
+        OrderInjectable $order,
+        array $data,
+        $configData
+    ) {
         // Preconditions
+        $this->fixtureFactory = $fixtureFactory;
+        $stepFactory->create(
+            \Magento\Config\Test\TestStep\SetupConfigurationStep::class,
+            ['configData' => $configData]
+        )->run();
         $order->persist();
-        $this->objectManager->create(\Magento\Sales\Test\TestStep\CreateInvoiceStep::class, ['order' => $order])->run();
+        $stepFactory->create(\Magento\Sales\Test\TestStep\CreateInvoiceStep::class, ['order' => $order])->run();
 
         // Steps
-        $createCreditMemoStep = $this->objectManager->create(
+        $createCreditMemoStep = $stepFactory->create(
             \Magento\Sales\Test\TestStep\CreateCreditMemoStep::class,
             ['order' => $order, 'data' => $data]
         );
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.xml
index 40f5c0aefc60ae574e14122e1a5ac8a3ac77307e..02b9640acbea4159c0560e8a4727a13cc36e1199 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateCreditMemoEntityTest.xml
@@ -7,30 +7,33 @@
  -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Sales\Test\TestCase\CreateCreditMemoEntityTest" summary="Create Credit Memo for Offline Payment Methods" ticketId="MAGETWO-29116">
-        <variation name="CreateCreditMemoEntityTestVariation1">
-            <data name="description" xsi:type="string">Assert items return to stock (partial refund)</data>
+        <variation name="CreateCreditMemoEntityTestVariation1" summary="Assert items return to stock (partial refund)">
             <data name="data/items_data/0/back_to_stock" xsi:type="string">Yes</data>
             <data name="data/items_data/0/qty" xsi:type="string">1</data>
+            <data name="data/form_data/send_email" xsi:type="string">Yes</data>
             <data name="order/dataset" xsi:type="string">default</data>
             <data name="order/data/entity_id/products" xsi:type="string">catalogProductSimple::product_100_dollar</data>
             <data name="order/data/price/dataset" xsi:type="string">partial_refund</data>
+            <data name="configData" xsi:type="string">checkmo</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertRefundSuccessCreateMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertCreditMemoButton" />
             <constraint name="Magento\Sales\Test\Constraint\AssertRefundInCreditMemoTab" />
             <constraint name="Magento\Sales\Test\Constraint\AssertRefundInRefundsGrid" />
+            <constraint name="Magento\Sales\Test\Constraint\AssertRefundOrderStatusInCommentsHistory" />
+            <constraint name="Magento\Sales\Test\Constraint\AssertOrderCommentsHistoryNotifyStatus" />
             <constraint name="Magento\Sales\Test\Constraint\AssertRefundedGrandTotalOnFrontend" />
             <constraint name="Magento\Catalog\Test\Constraint\AssertProductForm" />
             <constraint name="Magento\Sales\Test\Constraint\AssertCreditMemoItems" />
         </variation>
-        <variation name="CreateCreditMemoEntityTestVariation2">
-            <data name="description" xsi:type="string">Assert 0 shipping refund</data>
+        <variation name="CreateCreditMemoEntityTestVariation2" summary="Assert 0 shipping refund">
             <data name="data/items_data/0/qty" xsi:type="string">1</data>
             <data name="data/form_data/shipping_amount" xsi:type="string">0</data>
             <data name="data/form_data/adjustment_positive" xsi:type="string">5</data>
             <data name="data/form_data/adjustment_negative" xsi:type="string">10</data>
             <data name="order/dataset" xsi:type="string">default</data>
-            <data name="order/data/entity_id/products" xsi:type="string">catalogProductSimple::default</data>
+            <data name="order/data/payment_auth_expiration/method" xsi:type="string">banktransfer</data>
             <data name="order/data/price/dataset" xsi:type="string">full_refund_with_zero_shipping_refund</data>
+            <data name="configData" xsi:type="string">banktransfer</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertRefundSuccessCreateMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertCreditMemoButton" />
             <constraint name="Magento\Sales\Test\Constraint\AssertRefundInCreditMemoTab" />
@@ -38,5 +41,29 @@
             <constraint name="Magento\Sales\Test\Constraint\AssertRefundedGrandTotalOnFrontend" />
             <constraint name="Magento\Sales\Test\Constraint\AssertCreditMemoItems" />
         </variation>
+        <variation name="CreateCreditMemoEntityTestVariationWithCashOnDeliveryPaymentMethod" summary="Assert 0 shipping refund with Cash on delivery payment method">
+            <data name="data/items_data/0/qty" xsi:type="string">1</data>
+            <data name="data/form_data/shipping_amount" xsi:type="string">0</data>
+            <data name="data/form_data/adjustment_positive" xsi:type="string">5</data>
+            <data name="data/form_data/adjustment_negative" xsi:type="string">10</data>
+            <data name="order/dataset" xsi:type="string">default</data>
+            <data name="order/data/payment_auth_expiration/method" xsi:type="string">cashondelivery</data>
+            <data name="order/data/price/dataset" xsi:type="string">full_refund_with_zero_shipping_refund</data>
+            <data name="configData" xsi:type="string">cashondelivery</data>
+            <constraint name="Magento\Sales\Test\Constraint\AssertRefundSuccessCreateMessage" />
+            <constraint name="Magento\Sales\Test\Constraint\AssertRefundedGrandTotalOnFrontend" />
+        </variation>
+        <variation name="CreateCreditMemoEntityTestVariationWithPurchaseOrderPaymentMethod" summary="Assert 0 shipping refund with Purchase Order payment method">
+            <data name="data/items_data/0/qty" xsi:type="string">1</data>
+            <data name="data/form_data/shipping_amount" xsi:type="string">0</data>
+            <data name="data/form_data/adjustment_positive" xsi:type="string">5</data>
+            <data name="data/form_data/adjustment_negative" xsi:type="string">10</data>
+            <data name="order/dataset" xsi:type="string">default</data>
+            <data name="order/data/payment_auth_expiration/method" xsi:type="string">purchaseorder</data>
+            <data name="order/data/price/dataset" xsi:type="string">full_refund_with_zero_shipping_refund</data>
+            <data name="configData" xsi:type="string">purchaseorder</data>
+            <constraint name="Magento\Sales\Test\Constraint\AssertRefundSuccessCreateMessage" />
+            <constraint name="Magento\Sales\Test\Constraint\AssertRefundedGrandTotalOnFrontend" />
+        </variation>
     </testCase>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php
index f62583583c3dc565579196d24ed564a14613eef9..f7cdaf74ab0f57e0544a392f6a936498bcb8efee 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.php
@@ -8,10 +8,11 @@ namespace Magento\Sales\Test\TestCase;
 
 use Magento\Sales\Test\Fixture\OrderInjectable;
 use Magento\Mtf\TestCase\Injectable;
+use Magento\Mtf\TestStep\TestStepFactory;
 
 /**
  * Preconditions:
- * 1. Enable payment method "Check/Money Order".
+ * 1. Enable payment method: "Check/Money Order/Bank Transfer/Cash on Delivery/Purchase Order/Zero Subtotal Checkout".
  * 2. Enable shipping method one of "Flat Rate/Free Shipping".
  * 3. Create order.
  *
@@ -33,16 +34,21 @@ class CreateInvoiceEntityTest extends Injectable
     /* end tags */
 
     /**
-     * Set up configuration.
+     * Factory for Test Steps.
      *
+     * @var TestStepFactory
+     */
+    protected $stepFactory;
+
+    /**
+     * Prepare data.
+     *
+     * @param TestStepFactory $stepFactory
      * @return void
      */
-    public function __prepare()
+    public function __prepare(TestStepFactory $stepFactory)
     {
-        $this->objectManager->create(
-            \Magento\Config\Test\TestStep\SetupConfigurationStep::class,
-            ['configData' => 'checkmo, flatrate']
-        )->run();
+        $this->stepFactory = $stepFactory;
     }
 
     /**
@@ -50,15 +56,20 @@ class CreateInvoiceEntityTest extends Injectable
      *
      * @param OrderInjectable $order
      * @param array $data
+     * @param string $configData
      * @return array
      */
-    public function test(OrderInjectable $order, array $data)
+    public function test(OrderInjectable $order, array $data, $configData)
     {
         // Preconditions
+        $this->stepFactory->create(
+            \Magento\Config\Test\TestStep\SetupConfigurationStep::class,
+            ['configData' => $configData]
+        )->run();
         $order->persist();
 
         // Steps
-        $result = $this->objectManager->create(
+        $result = $this->stepFactory->create(
             \Magento\Sales\Test\TestStep\CreateInvoiceStep::class,
             ['order' => $order, 'data' => $data]
         )->run();
@@ -73,6 +84,6 @@ class CreateInvoiceEntityTest extends Injectable
      */
     public function tearDown()
     {
-        $this->objectManager->create(\Magento\Customer\Test\TestStep\LogoutCustomerOnFrontendStep::class)->run();
+        $this->stepFactory->create(\Magento\Customer\Test\TestStep\LogoutCustomerOnFrontendStep::class)->run();
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.xml
index afc4bad5e706db538cd5957201a4a5c9347a3605..8753de91d1f4301710f15a968b7a7ea24e04d663 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestCase/CreateInvoiceEntityTest.xml
@@ -10,11 +10,11 @@
         <variation name="CreateInvoiceEntityTestVariation1">
             <data name="order/dataset" xsi:type="string">default</data>
             <data name="order/data/price/dataset" xsi:type="string">full_invoice</data>
-            <data name="order/data/entity_id/products" xsi:type="string">catalogProductSimple::default</data>
             <data name="order/data/total_qty_ordered/0" xsi:type="string">1</data>
             <data name="data/items_data/0/qty" xsi:type="string">-</data>
             <data name="data/form_data/do_shipment" xsi:type="string">Yes</data>
             <data name="data/form_data/comment_text" xsi:type="string">comments</data>
+            <data name="configData" xsi:type="string">checkmo</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertInvoiceWithShipmentSuccessMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertNoInvoiceButton" />
             <constraint name="Magento\Sales\Test\Constraint\AssertInvoiceInInvoicesTab" />
@@ -29,14 +29,57 @@
             <data name="order/data/price/dataset" xsi:type="string">partial_invoice</data>
             <data name="order/data/entity_id/products" xsi:type="string">catalogProductSimple::product_100_dollar</data>
             <data name="order/data/total_qty_ordered/0" xsi:type="string">-</data>
+            <data name="order/data/payment_auth_expiration/method" xsi:type="string">banktransfer</data>
             <data name="data/items_data/0/qty" xsi:type="string">1</data>
             <data name="data/form_data/do_shipment" xsi:type="string">No</data>
             <data name="data/form_data/comment_text" xsi:type="string">comments</data>
+            <data name="configData" xsi:type="string">banktransfer</data>
             <constraint name="Magento\Sales\Test\Constraint\AssertInvoiceSuccessCreateMessage" />
             <constraint name="Magento\Sales\Test\Constraint\AssertInvoiceInInvoicesTab" />
             <constraint name="Magento\Sales\Test\Constraint\AssertInvoiceInInvoicesGrid" />
             <constraint name="Magento\Sales\Test\Constraint\AssertInvoiceItems" />
             <constraint name="Magento\Sales\Test\Constraint\AssertInvoicedAmountOnFrontend" />
         </variation>
+        <variation name="CreateInvoiceEntityTestVariationWithCashOnDeliveryPaymentMethod">
+            <data name="order/dataset" xsi:type="string">default</data>
+            <data name="order/data/price/dataset" xsi:type="string">partial_invoice</data>
+            <data name="order/data/entity_id/products" xsi:type="string">catalogProductSimple::product_100_dollar</data>
+            <data name="order/data/total_qty_ordered/0" xsi:type="string">-</data>
+            <data name="order/data/payment_auth_expiration/method" xsi:type="string">cashondelivery</data>
+            <data name="data/items_data/0/qty" xsi:type="string">1</data>
+            <data name="data/form_data/do_shipment" xsi:type="string">No</data>
+            <data name="data/form_data/comment_text" xsi:type="string">comments</data>
+            <data name="configData" xsi:type="string">cashondelivery</data>
+            <constraint name="Magento\Sales\Test\Constraint\AssertInvoiceSuccessCreateMessage" />
+            <constraint name="Magento\Sales\Test\Constraint\AssertInvoicedAmountOnFrontend" />
+        </variation>
+        <variation name="CreateInvoiceEntityTestVariationWithPurchaseOrderPaymentMethod">
+            <data name="order/dataset" xsi:type="string">default</data>
+            <data name="order/data/price/dataset" xsi:type="string">partial_invoice</data>
+            <data name="order/data/entity_id/products" xsi:type="string">catalogProductSimple::product_100_dollar</data>
+            <data name="order/data/total_qty_ordered/0" xsi:type="string">-</data>
+            <data name="order/data/payment_auth_expiration/method" xsi:type="string">purchaseorder</data>
+            <data name="data/items_data/0/qty" xsi:type="string">1</data>
+            <data name="data/form_data/do_shipment" xsi:type="string">No</data>
+            <data name="data/form_data/comment_text" xsi:type="string">comments</data>
+            <data name="configData" xsi:type="string">purchaseorder</data>
+            <constraint name="Magento\Sales\Test\Constraint\AssertInvoiceSuccessCreateMessage" />
+            <constraint name="Magento\Sales\Test\Constraint\AssertInvoicedAmountOnFrontend" />
+        </variation>
+        <variation name="CreateInvoiceEntityTestVariationWithZeroSubtotalCheckout">
+            <data name="order/dataset" xsi:type="string">default</data>
+            <data name="order/data/price/dataset" xsi:type="string">partial_invoice</data>
+            <data name="order/data/entity_id/products" xsi:type="string">catalogProductSimple::product_10_dollar</data>
+            <data name="order/data/total_qty_ordered/0" xsi:type="string">-</data>
+            <data name="order/data/payment_auth_expiration/method" xsi:type="string">free</data>
+            <data name="order/data/shipping_method" xsi:type="string">freeshipping_freeshipping</data>
+            <data name="order/data/coupon_code/dataset" xsi:type="string">active_sales_rule_with_fixed_price_discount_coupon</data>
+            <data name="data/items_data/0/qty" xsi:type="string">1</data>
+            <data name="data/form_data/do_shipment" xsi:type="string">No</data>
+            <data name="data/form_data/comment_text" xsi:type="string">comments</data>
+            <data name="configData" xsi:type="string">zero_subtotal_checkout, freeshipping</data>
+            <constraint name="Magento\Sales\Test\Constraint\AssertInvoiceSuccessCreateMessage" />
+            <constraint name="Magento\Sales\Test\Constraint\AssertInvoicedAmountOnFrontend" />
+        </variation>
     </testCase>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/FillBillingAddressStep.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/FillBillingAddressStep.php
index bde5bff6de9d4e1f53969137ac86c94d8323c7fd..f6d0c8325bfc38500c4cd5a5d7289e8b3416439a 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/FillBillingAddressStep.php
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/FillBillingAddressStep.php
@@ -11,7 +11,7 @@ use Magento\Sales\Test\Page\Adminhtml\OrderCreateIndex;
 use Magento\Mtf\TestStep\TestStepInterface;
 
 /**
- * Fill Sales Data.
+ * Fill Billing Address.
  */
 class FillBillingAddressStep implements TestStepInterface
 {
@@ -23,7 +23,7 @@ class FillBillingAddressStep implements TestStepInterface
     protected $orderCreateIndex;
 
     /**
-     * Address.
+     * Billing Address fixture.
      *
      * @var Address
      */
@@ -37,14 +37,13 @@ class FillBillingAddressStep implements TestStepInterface
     protected $saveAddress;
 
     /**
-     * Flag for set same as billing shipping address.
+     * Flag to set 'Same as billing address' for shipping address.
      *
      * @var string
      */
     protected $setShippingAddress;
 
     /**
-     * @constructor
      * @param OrderCreateIndex $orderCreateIndex
      * @param Address $billingAddress
      * @param string $saveAddress
@@ -63,14 +62,14 @@ class FillBillingAddressStep implements TestStepInterface
     }
 
     /**
-     * Fill Sales Data.
+     * Fill Billing Address.
      *
-     * @return Address
+     * @return array
      */
     public function run()
     {
         $this->orderCreateIndex->getCreateBlock()
-            ->fillAddresses($this->billingAddress, $this->saveAddress, $this->setShippingAddress);
+            ->fillBillingAddress($this->billingAddress, $this->saveAddress, $this->setShippingAddress);
 
         return ['billingAddress' => $this->billingAddress];
     }
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/FillShippingAddressStep.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/FillShippingAddressStep.php
new file mode 100644
index 0000000000000000000000000000000000000000..8ff05dfca95bb016b4b72e5db07f5fa2ffb139ca
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/FillShippingAddressStep.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Sales\Test\TestStep;
+
+use Magento\Customer\Test\Fixture\Address;
+use Magento\Sales\Test\Page\Adminhtml\OrderCreateIndex;
+use Magento\Mtf\TestStep\TestStepInterface;
+
+/**
+ * Fill Shipping Address.
+ */
+class FillShippingAddressStep implements TestStepInterface
+{
+    /**
+     * Sales order create index page.
+     *
+     * @var OrderCreateIndex
+     */
+    protected $orderCreateIndex;
+
+    /**
+     * Shipping Address fixture.
+     *
+     * @var Address
+     */
+    protected $shippingAddress;
+
+    /**
+     * @param OrderCreateIndex $orderCreateIndex
+     * @param Address $shippingAddress [optional]
+     */
+    public function __construct(
+        OrderCreateIndex $orderCreateIndex,
+        Address $shippingAddress = null
+    ) {
+        $this->orderCreateIndex = $orderCreateIndex;
+        $this->shippingAddress = $shippingAddress;
+    }
+
+    /**
+     * Fill Shipping Address.
+     *
+     * @return void
+     */
+    public function run()
+    {
+        $this->orderCreateIndex->getCreateBlock()->fillShippingAddress($this->shippingAddress);
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/SubmitOrderNegativeStep.php b/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/SubmitOrderNegativeStep.php
new file mode 100644
index 0000000000000000000000000000000000000000..ece554eee9c9c32fdc94c74c48589e804aa9090f
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/TestStep/SubmitOrderNegativeStep.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Sales\Test\TestStep;
+
+use Magento\Sales\Test\Page\Adminhtml\OrderCreateIndex;
+use Magento\Mtf\TestStep\TestStepInterface;
+
+/**
+ * Submit Order step.
+ */
+class SubmitOrderNegativeStep implements TestStepInterface
+{
+    /**
+     * Sales order create index page.
+     *
+     * @var OrderCreateIndex
+     */
+    protected $orderCreateIndex;
+
+    /**
+     * @constructor
+     * @param OrderCreateIndex $orderCreateIndex
+     */
+    public function __construct(
+        OrderCreateIndex $orderCreateIndex
+    ) {
+        $this->orderCreateIndex = $orderCreateIndex;
+    }
+
+    /**
+     * Fill Sales Data.
+     *
+     * @return void
+     */
+    public function run()
+    {
+        $this->orderCreateIndex->getCreateBlock()->submitOrder();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Sales/Test/etc/testcase.xml b/dev/tests/functional/tests/app/Magento/Sales/Test/etc/testcase.xml
index c48430b00e7ea4412265dfaf4d91ed85cbd2819c..ec2da3f2607b2dda7e4b375e11192f9844d839fd 100644
--- a/dev/tests/functional/tests/app/Magento/Sales/Test/etc/testcase.xml
+++ b/dev/tests/functional/tests/app/Magento/Sales/Test/etc/testcase.xml
@@ -28,7 +28,8 @@
         <step name="addProducts" module="Magento_Sales" next="updateProductsData" />
         <step name="updateProductsData" module="Magento_Sales" next="fillAccountInformation" />
         <step name="fillAccountInformation" module="Magento_Sales" next="fillBillingAddress" />
-        <step name="fillBillingAddress" module="Magento_Sales" next="selectShippingMethodForOrder" />
+        <step name="fillBillingAddress" module="Magento_Sales" next="fillShippingAddress" />
+        <step name="fillShippingAddress" module="Magento_Sales" next="selectShippingMethodForOrder" />
         <step name="selectShippingMethodForOrder" module="Magento_Sales" next="selectPaymentMethodForOrder" />
         <step name="selectPaymentMethodForOrder" module="Magento_Sales" next="submitOrder" />
         <step name="submitOrder" module="Magento_Sales" />
diff --git a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Block/Adminhtml/Promo/Quote/Edit/PromoQuoteForm.xml b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Block/Adminhtml/Promo/Quote/Edit/PromoQuoteForm.xml
index cc48c0fc1cfb54ee51bc4e8ddffed12df210348e..6dcb041efa0703e86dcb2de2fbf38e1456600775 100644
--- a/dev/tests/functional/tests/app/Magento/SalesRule/Test/Block/Adminhtml/Promo/Quote/Edit/PromoQuoteForm.xml
+++ b/dev/tests/functional/tests/app/Magento/SalesRule/Test/Block/Adminhtml/Promo/Quote/Edit/PromoQuoteForm.xml
@@ -40,8 +40,8 @@
     </rule_information>
     <conditions>
         <class>\Magento\Ui\Test\Block\Adminhtml\Section</class>
-        <selector>//div[contains(@class,'admin__collapsible-block-wrapper')][descendant::div[@class='rule-tree']]</selector>
-        <strategy>xpath</strategy>
+        <selector>[data-index="conditions"]</selector>
+        <strategy>css selector</strategy>
         <fields>
             <conditions_serialized>
                 <selector>.fieldset[id^="sales_rule_formrule_conditions_fieldset_"]</selector>
@@ -51,8 +51,8 @@
     </conditions>
     <actions>
         <class>\Magento\Ui\Test\Block\Adminhtml\Section</class>
-        <selector>//div[contains(@class,'admin__collapsible-block-wrapper')][descendant::select[@name='simple_action']]</selector>
-        <strategy>xpath</strategy>
+        <selector>[data-index="actions"]</selector>
+        <strategy>css selector</strategy>
         <fields>
             <simple_action>
                 <input>select</input>
@@ -77,7 +77,7 @@
     </actions>
     <labels>
         <class>\Magento\SalesRule\Test\Block\Adminhtml\Promo\Quote\Edit\Section\Labels</class>
-        <selector>//div[contains(@class,'admin__collapsible-block-wrapper')][descendant::input[@name='store_labels[0]']]</selector>
-        <strategy>xpath</strategy>
+        <selector>[data-index="labels"]</selector>
+        <strategy>css selector</strategy>
     </labels>
 </sections>
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewIntegrationTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewIntegrationTest.php
index cc75c27949c0e739c6e1b8eb3ae2cd9742583be7..b977a8f098f49dbf5ee39a3d3e478aeb9c3767ce 100644
--- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewIntegrationTest.php
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewIntegrationTest.php
@@ -33,6 +33,7 @@ class LockAdminUserWhenCreatingNewIntegrationTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const SEVERITY = 'S2';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewIntegrationTest.xml b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewIntegrationTest.xml
index 87f109ac81bcfca9acb352ad70315b03fc18aeed..aed87c9db773079abd07521898a5f22db1c0ea91 100644
--- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewIntegrationTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewIntegrationTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Security\Test\TestCase\LockAdminUserWhenCreatingNewIntegrationTest" summary="Lock admin user after entering incorrect password while creating new integration">
         <variation name="LockAdminUserWhenCreatingNewIntegrationTestVariation1">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="configData" xsi:type="string">user_lockout_failures</data>
             <data name="customAdmin/dataset" xsi:type="string">custom_admin_with_default_role</data>
             <data name="integration/data/name" xsi:type="string">Integration%isolation%</data>
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewRoleTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewRoleTest.php
index 23a43100de85421927f774600aac3a316cc309e2..7c76e4c4d43b80afd252fab2f0711a0442b12dc7 100644
--- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewRoleTest.php
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewRoleTest.php
@@ -33,6 +33,7 @@ class LockAdminUserWhenCreatingNewRoleTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const SEVERITY = 'S2';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewRoleTest.xml b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewRoleTest.xml
index 3b9b5fd6295eed01d963015b50e4069fe2833d59..7e5c44696d832faa85ea298a6668eaf3030a9cfd 100644
--- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewRoleTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockAdminUserWhenCreatingNewRoleTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Security\Test\TestCase\LockAdminUserWhenCreatingNewRoleTest" summary="Lock admin user after entering incorrect password while creating new role">
         <variation name="LockAdminUserWhenCreatingNewRoleTestVariation1">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="configData" xsi:type="string">user_lockout_failures</data>
             <data name="customAdmin/dataset" xsi:type="string">custom_admin_with_default_role</data>
             <data name="role/data/rolename" xsi:type="string">AdminRole%isolation%</data>
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnEditPageTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnEditPageTest.php
index c5b910c12470793916b8fa4aa68f64ff2d6b38f0..df1f872006561462b6cec1631796115ace1a5279 100644
--- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnEditPageTest.php
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnEditPageTest.php
@@ -35,6 +35,7 @@ class LockCustomerOnEditPageTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnEditPageTest.xml b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnEditPageTest.xml
index 3e53235c075a624fb98b1721e09cdb2262f2f4f4..eeb0dd7ab12e9e33eec107f17d3678d4ec1827ad 100644
--- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnEditPageTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnEditPageTest.xml
@@ -8,12 +8,13 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Security\Test\TestCase\LockCustomerOnEditPageTest" summary="Lock customer from edit page">
         <variation name="LockCustomerOnEditPageTest1">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="configData" xsi:type="string">customer_max_login_failures_number</data>
             <data name="initialCustomer/dataset" xsi:type="string">default</data>
             <data name="customer/data/current_password" xsi:type="string">incorrect password</data>
             <data name="customer/data/password" xsi:type="string">123123^a</data>
             <data name="customer/data/password_confirmation" xsi:type="string">123123^a</data>
-            <data name="attempts" xsi:type="string">6</data>
+            <data name="attempts" xsi:type="string">7</data>
             <constraint name="Magento\Security\Test\Constraint\AssertCustomerIsLocked" />
         </variation>
     </testCase>
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnLoginPageTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnLoginPageTest.php
index 1612f1dac24e417393e861a0bbc04918791ab9d0..795a8531512c60a7a0a23fef0ed3daca8ccf35ad 100644
--- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnLoginPageTest.php
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnLoginPageTest.php
@@ -29,6 +29,7 @@ class LockCustomerOnLoginPageTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnLoginPageTest.xml b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnLoginPageTest.xml
index 21318c5f3f0d5f1dae4a776b2653ddc834710d55..a5376d73685bad9e54d4ff094348b7100c2a2a8d 100644
--- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnLoginPageTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/LockCustomerOnLoginPageTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Security\Test\TestCase\LockCustomerOnLoginPageTest" summary="Lock customer on login page">
         <variation name="LockCustomerOnLoginPageTestVariation1">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="configData" xsi:type="string">customer_max_login_failures_number</data>
             <data name="initialCustomer/dataset" xsi:type="string">default</data>
             <data name="incorrectPassword" xsi:type="string">incorrect password</data>
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/NewCustomerPasswordComplexityTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/NewCustomerPasswordComplexityTest.php
index 8fdab9165db036361d22ad2a6d211fbb7f45acd1..3c77248a0debc922ff09f0f37e9d9f8d059f756e 100644
--- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/NewCustomerPasswordComplexityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/NewCustomerPasswordComplexityTest.php
@@ -25,6 +25,7 @@ class NewCustomerPasswordComplexityTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/NewCustomerPasswordComplexityTest.xml b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/NewCustomerPasswordComplexityTest.xml
index 925b8145f59adb171f958901ca2583d1af9f8e35..579c7fcfc05cb786013d5194e093e8c0167473be 100644
--- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/NewCustomerPasswordComplexityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/NewCustomerPasswordComplexityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Security\Test\TestCase\NewCustomerPasswordComplexityTest" summary="New customer password complexity" ticketId="MAGETWO-49044">
         <variation name="PasswordLengthTest" summary="Customer password length is below 8 characters">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="customer/data/firstname" xsi:type="string">john</data>
             <data name="customer/data/lastname" xsi:type="string">doe</data>
             <data name="customer/data/email" xsi:type="string">johndoe%isolation%@example.com</data>
@@ -17,6 +18,7 @@
             <constraint name="Magento\Security\Test\Constraint\AssertPasswordLengthErrorMessage" />
         </variation>
         <variation name="PasswordComplexityTest" summary="Customer password is not secure enough">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="customer/data/firstname" xsi:type="string">john</data>
             <data name="customer/data/lastname" xsi:type="string">doe</data>
             <data name="customer/data/email" xsi:type="string">johndoe%isolation%@example.com</data>
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetCustomerPasswordFailedTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetCustomerPasswordFailedTest.php
index d3b7a3ccb130490244e4081a1bd7b22813f00b48..71bd5e562c6dcb30805d80e3fa1fe7787368e8e9 100644
--- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetCustomerPasswordFailedTest.php
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetCustomerPasswordFailedTest.php
@@ -27,6 +27,7 @@ class ResetCustomerPasswordFailedTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetCustomerPasswordFailedTest.xml b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetCustomerPasswordFailedTest.xml
index 88be6fae63d9b7666c3080a8a90769af233fb1e3..92ce965b8bc4e43b558a144df23071e782149b80 100644
--- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetCustomerPasswordFailedTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetCustomerPasswordFailedTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Security\Test\TestCase\ResetCustomerPasswordFailedTest" summary="Reset customer password.">
         <variation name="ResetPasswordTestVariation">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="customer/dataset" xsi:type="string">customer_US</data>
             <data name="attempts" xsi:type="string">2</data>
             <constraint name="Magento\Security\Test\Constraint\AssertCustomerResetPasswordFailed" />
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetUserPasswordFailedTest.php b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetUserPasswordFailedTest.php
index 0bf600a7042f9889239507d06e51aa24a1fc4287..cc7683f251bef6b63f924088a6464c3ecbb54a28 100644
--- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetUserPasswordFailedTest.php
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetUserPasswordFailedTest.php
@@ -27,6 +27,7 @@ class ResetUserPasswordFailedTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetUserPasswordFailedTest.xml b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetUserPasswordFailedTest.xml
index 3301cd8624a7cdd1790476a1bdb3f9745937f190..644f494844a5b1a2a36334e0f276e1febcae5784 100644
--- a/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetUserPasswordFailedTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/TestCase/ResetUserPasswordFailedTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Security\Test\TestCase\ResetUserPasswordFailedTest" summary="Prevent Locked Admin User to Log In into the Backend">
         <variation name="ResetUserPasswordTestVariation1">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="customAdmin/dataset" xsi:type="string">custom_admin_with_default_role</data>
             <data name="attempts" xsi:type="string">2</data>
             <constraint name="Magento\Security\Test\Constraint\AssertUserPasswordResetFailed" />
diff --git a/dev/tests/functional/tests/app/Magento/Security/Test/etc/di.xml b/dev/tests/functional/tests/app/Magento/Security/Test/etc/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7e29aefb0475dc03725cdc56ddeec5881fa0462e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Security/Test/etc/di.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
+    <type name="Magento\Security\Test\Constraint\AssertCustomerIsLocked">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Security\Test\Constraint\AssertCustomerResetPasswordFailed">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Security\Test\Constraint\AssertPasswordIsNotSecureEnoughMessage">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Security\Test\Constraint\AssertPasswordLengthErrorMessage">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Security\Test\Constraint\AssertUserIsLocked">
+        <arguments>
+            <argument name="severity" xsi:type="string">S2</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Security\Test\Constraint\AssertUserPasswordResetFailed">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.php b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.php
index f820e92f9a5265b8b6db984b21e3fdf768d642f2..1329fab583d881a9085f2b764ce0113a1a143d15 100644
--- a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.php
@@ -30,6 +30,7 @@ class CreateSitemapEntityTest extends Injectable
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = 'extended_acceptance_test';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.xml b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.xml
index 36a9708cd3da50bf0ebcb079bb3a959399b98cdc..cd948084a3befea8c83aeadbb96ed56bda4d04f2 100644
--- a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/CreateSitemapEntityTest.xml
@@ -8,18 +8,20 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Sitemap\Test\TestCase\CreateSitemapEntityTest" summary="Create Sitemap" ticketId="MAGETWO-23277">
         <variation name="CreateSitemapEntityTestVariation1">
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data>
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, severity:S1</data>
             <data name="sitemap/data/sitemap_filename" xsi:type="string">sitemap.xml</data>
             <data name="sitemap/data/sitemap_path" xsi:type="string">/</data>
             <constraint name="Magento\Sitemap\Test\Constraint\AssertSitemapSuccessSaveMessage" />
             <constraint name="Magento\Sitemap\Test\Constraint\AssertSitemapInGrid" />
         </variation>
         <variation name="CreateSitemapEntityTestVariation2">
+            <data name="tag" xsi:type="string">severity:S3</data>
             <data name="sitemap/data/sitemap_filename" xsi:type="string">%isolation%</data>
             <data name="sitemap/data/sitemap_path" xsi:type="string">/</data>
             <constraint name="Magento\Sitemap\Test\Constraint\AssertSitemapFailPathSaveMessage" />
         </variation>
         <variation name="CreateSitemapEntityTestVariation3">
+            <data name="tag" xsi:type="string">severity:S3</data>
             <data name="sitemap/data/sitemap_filename" xsi:type="string">sitemap.xml</data>
             <data name="sitemap/data/sitemap_path" xsi:type="string">/%isolation%</data>
             <constraint name="Magento\Sitemap\Test\Constraint\AssertSitemapFailFolderSaveMessage" />
diff --git a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.php b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.php
index e8f24bfccc05691525a46bed378a23bb088768b7..5ea826345da84a78ab67bc5e418d33cecc2d5fe8 100644
--- a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.php
@@ -31,6 +31,7 @@ class DeleteSitemapEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const SEVERITY = 'S2';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.xml b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.xml
index 432f7a9026670f773e072ac025744dbc3075a6de..b0c30897fc7e830e8a4b89446dba38e9ed6c8a7e 100644
--- a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/DeleteSitemapEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Sitemap\Test\TestCase\DeleteSitemapEntityTest" summary="Delete Sitemap Entity" ticketId="MAGETWO-23296">
         <variation name="DeleteSitemapEntityTestVariation1">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="sitemap/dataset" xsi:type="string">default</data>
             <constraint name="Magento\Sitemap\Test\Constraint\AssertSitemapSuccessDeleteMessage" />
             <constraint name="Magento\Sitemap\Test\Constraint\AssertSitemapNotInGrid" />
diff --git a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/NavigateMenuTest.xml b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/NavigateMenuTest.xml
index cc5de2a32735d2f965d2a5c286402f104d38d78c..67d70772a0c1895975dcefaae3d26f5dea67778d 100644
--- a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/NavigateMenuTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/NavigateMenuTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Backend\Test\TestCase\NavigateMenuTest">
         <variation name="NavigateMenuTest85">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="menuItem" xsi:type="string">Marketing > Site Map</data>
             <data name="pageTitle" xsi:type="string">Site Map</data>
             <constraint name="Magento\Backend\Test\Constraint\AssertBackendPageIsAvailable"/>
diff --git a/dev/tests/functional/tests/app/Magento/Sitemap/Test/etc/di.xml b/dev/tests/functional/tests/app/Magento/Sitemap/Test/etc/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..546ef7f8d4ee385dc2a23d646b05769ff4aa89ab
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Sitemap/Test/etc/di.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
+    <type name="Magento\Sitemap\Test\Constraint\AssertSitemapContent">
+        <arguments>
+            <argument name="severity" xsi:type="string">S2</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Sitemap\Test\Constraint\AssertSitemapFailFolderSaveMessage">
+        <arguments>
+            <argument name="severity" xsi:type="string">S3</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Sitemap\Test\Constraint\AssertSitemapFailPathSaveMessage">
+        <arguments>
+            <argument name="severity" xsi:type="string">S3</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Sitemap\Test\Constraint\AssertSitemapInGrid">
+        <arguments>
+            <argument name="severity" xsi:type="string">S2</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Sitemap\Test\Constraint\AssertSitemapNotInGrid">
+        <arguments>
+            <argument name="severity" xsi:type="string">S3</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Sitemap\Test\Constraint\AssertSitemapSuccessDeleteMessage">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Sitemap\Test\Constraint\AssertSitemapSuccessGenerateMessage">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Sitemap\Test\Constraint\AssertSitemapSuccessSaveAndGenerateMessages">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Sitemap\Test\Constraint\AssertSitemapSuccessSaveMessage">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.xml
index 595ce66010ed6996eb505867c77b56a3c046a446..5d338af60555fbb68836d8abb8a53cf9c2d7ceae 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.xml
@@ -60,7 +60,7 @@
             <constraint name="Magento\Tax\Test\Constraint\AssertTaxRuleForm" />
         </variation>
         <variation name="CreateTaxRuleEntityTestVariation5" summary="Create Tax Rule with New and Existing Tax Rate, Customer Tax Class, Product Tax Class" ticketId="MAGETWO-12438">
-            <data name="tag" xsi:type="string">test_type:acceptance_test, stable:no, test_type:extended_acceptance_test</data>
+            <data name="tag" xsi:type="string">test_type:acceptance_test, test_type:extended_acceptance_test</data>
             <data name="taxRule/data/code" xsi:type="string">TaxIdentifier%isolation%</data>
             <data name="taxRule/data/tax_rate/dataset/rate_0" xsi:type="string">US-CA-*-Rate 1</data>
             <data name="taxRule/data/tax_rate/dataset/rate_1" xsi:type="string">us_ny_rate_8_1</data>
diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/AbstractFormContainers.php b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/AbstractFormContainers.php
index b6ed37af715be90fc600aa5728744ccd3a160d68..180afa8fe7ec6b3a862ef9f80e077fcca70b354e 100644
--- a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/AbstractFormContainers.php
+++ b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/AbstractFormContainers.php
@@ -158,7 +158,7 @@ abstract class AbstractFormContainers extends Form
 
     /**
      * Fill specified form with containers data.
-     * 
+     *
      * Input data in format
      * [[container => [field => [attribute_name => attribute_value, ..], ..], ..]
      * where container name can be empty if a field is not assigned to any container.
diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/DataGrid.php b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/DataGrid.php
index 3fc6f044f88521794f579aa653bacd6d87e44d14..80df7e6f8c631722fb314525b2d6733e2ac605ad 100644
--- a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/DataGrid.php
+++ b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/DataGrid.php
@@ -142,7 +142,7 @@ class DataGrid extends Grid
      *
      * @var string
      */
-    protected $currentPage = '[data-ui-id="current-page-input"]';
+    protected $currentPage = ".//*[@data-ui-id='current-page-input'][not(ancestor::*[@class='sticky-header'])]";
 
     /**
      * Clear all applied Filters.
@@ -347,7 +347,7 @@ class DataGrid extends Grid
             $this->sortGridByField('ID');
         }
         foreach ($items as $item) {
-            $this->_rootElement->find($this->currentPage)->setValue('');
+            $this->_rootElement->find($this->currentPage, Locator::SELECTOR_XPATH)->setValue('');
             $this->waitLoader();
             $selectItem = $this->getRow($item)->find($this->selectItem);
             do {
diff --git a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/FormSections.php b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/FormSections.php
index 6a5919b8cb1cfcfc2c8a666009e977ab0baafe0b..b5edbc6c791939cbf8f7d2e3b54ded1b22add3d7 100644
--- a/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/FormSections.php
+++ b/dev/tests/functional/tests/app/Magento/Ui/Test/Block/Adminhtml/FormSections.php
@@ -6,50 +6,26 @@
 
 namespace Magento\Ui\Test\Block\Adminhtml;
 
-use Magento\Mtf\Client\Locator;
-use Magento\Mtf\Client\ElementInterface;
 use Magento\Mtf\Fixture\InjectableFixture;
 
 /**
- * Is used to represent a new unified form with collapsible sections on the page.
+ * Is used to represent a new unified form with collapsible sections inside.
  */
 class FormSections extends AbstractFormContainers
 {
     /**
-     * CSS locator of the section collapsible title
+     * CSS locator of collapsed section.
      *
      * @var string
      */
-    protected $sectionTitle = '.fieldset-wrapper-title';
+    protected $collapsedSection = '[data-state-collapsible="closed"]';
 
     /**
-     * CSS locator of the section content
+     * CSS locator of expanded section.
      *
      * @var string
      */
-    protected $content = '.admin__fieldset-wrapper-content';
-
-    /**
-     * XPath locator of the collapsible fieldset
-     *
-     * @var string
-     */
-    protected $collapsible =
-        'div[contains(@class,"fieldset-wrapper")][contains(@class,"admin__collapsible-block-wrapper")]';
-
-    /**
-     * Locator for opened collapsible tab.
-     *
-     * @var string
-     */
-    protected $opened = '._show';
-
-    /**
-     * Locator for error messages.
-     *
-     * @var string
-     */
-    protected $errorMessages = '[data-ui-id="messages-message-error"]';
+    protected $expandedSection = '[data-state-collapsible="open"]';
 
     /**
      * Get Section class.
@@ -72,58 +48,39 @@ class FormSections extends AbstractFormContainers
     }
 
     /**
-     * Get the section title element
-     *
-     * @param string $sectionName
-     * @return ElementInterface
-     */
-    protected function getSectionTitleElement($sectionName)
-    {
-        $container = $this->getContainerElement($sectionName);
-        return $container->find($this->sectionTitle);
-    }
-
-    /**
-     * Opens the section.
+     * Expand section by its name.
      *
      * @param string $sectionName
      * @return $this
      */
     public function openSection($sectionName)
     {
-        if ($this->isCollapsible($sectionName) && !$this->isCollapsed($sectionName)) {
-            $this->getSectionTitleElement($sectionName)->click();
-        } else {
-            //Scroll to the top of the page so that the page actions header does not overlap any controls
-            $this->browser->find($this->header)->hover();
+        $section = $this->getContainerElement($sectionName)->find($this->collapsedSection);
+        if ($section->isVisible()) {
+            $section->click();
         }
+
         return $this;
     }
 
     /**
-     * Checks if the section is collapsible on the form.
+     * Check if section is collapsible.
      *
+     * @deprecated
      * @param string $sectionName
      * @return bool
      */
     public function isCollapsible($sectionName)
     {
-        $title = $this->getSectionTitleElement($sectionName);
-        if (!$title->isVisible()) {
-            return false;
-        };
-        return $title->find('parent::' . $this->collapsible, Locator::SELECTOR_XPATH)->isVisible();
-    }
+        $section = $this->getContainerElement($sectionName);
 
-    /**
-     * Check if collapsible section is opened.
-     *
-     * @param string $sectionName
-     * @return bool
-     */
-    private function isCollapsed($sectionName)
-    {
-        return $this->getContainerElement($sectionName)->find($this->opened)->isVisible();
+        if ($section->find($this->collapsedSection)->isVisible()) {
+            return true;
+        } elseif ($section->find($this->expandedSection)->isVisible()) {
+            return true;
+        } else {
+            return false;
+        }
     }
 
     /**
@@ -151,11 +108,12 @@ class FormSections extends AbstractFormContainers
     /**
      * Check if section is visible.
      *
+     * @deprecated
      * @param string $sectionName
      * @return bool
      */
     public function isSectionVisible($sectionName)
     {
-        return ($this->isCollapsible($sectionName) && !$this->isCollapsed($sectionName));
+        return !$this->getContainerElement($sectionName)->find($this->collapsedSection)->isVisible();
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Usps/Test/TestCase/OnePageCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Usps/Test/TestCase/OnePageCheckoutTest.xml
index 6170b8bbe0616f70fa14cdf50722a96199cf92c3..28c2b0f16239c735c927a8d3f7ef8eb0ebc1b01b 100644
--- a/dev/tests/functional/tests/app/Magento/Usps/Test/TestCase/OnePageCheckoutTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Usps/Test/TestCase/OnePageCheckoutTest.xml
@@ -28,15 +28,13 @@
         </variation>
         <variation name="OnePageCheckoutUspsTestVariation2" summary="Check Out as Guest using USPS with US shipping origin and UK customer">
             <data name="products/0" xsi:type="string">catalogProductSimple::default</data>
-            <data name="products/1" xsi:type="string">configurableProduct::default</data>
-            <data name="products/2" xsi:type="string">bundleProduct::bundle_fixed_product</data>
             <data name="checkoutMethod" xsi:type="string">guest</data>
             <data name="customer/dataset" xsi:type="string">default</data>
             <data name="address/dataset" xsi:type="string">UK_address</data>
             <data name="shippingAddress/dataset" xsi:type="string">UK_address</data>
             <data name="shipping/shipping_service" xsi:type="string">United States Postal Service</data>
-            <data name="shipping/shipping_method" xsi:type="string">Priority Mail International</data>
-            <data name="cart/data/shipping_method" xsi:type="string">Priority Mail International</data>
+            <data name="shipping/shipping_method" xsi:type="string">Priority Mail Express International Flat Rate Envelope</data>
+            <data name="cart/data/shipping_method" xsi:type="string">Priority Mail Express International Flat Rate Envelope</data>
             <data name="payment/method" xsi:type="string">checkmo</data>
             <data name="configData" xsi:type="string">checkmo, usps, shipping_origin_US_CA</data>
             <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php
index a90bd37f33047ea9e339254f1f30f294b983f160..17db35df1b44e6d2be519426ba962f6696fee23d 100644
--- a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php
+++ b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.php
@@ -92,7 +92,7 @@ class DeleteSavedCreditCardTest extends Injectable
             }
             $this->fillShippingMethod($shipping);
             if ($key >= 2) { // if this order will be placed via stored credit card
-                $this->useSavedCreditCard($payment);
+                $this->useSavedCreditCard($payment['vault']);
             } else {
                 $this->selectPaymentMethod($payment, $payment['creditCardClass'], $payment['creditCard']);
                 $this->saveCreditCard($payment, $creditCardSave);
@@ -291,7 +291,7 @@ class DeleteSavedCreditCardTest extends Injectable
     {
         $useSavedCreditCardStep = ObjectManager::getInstance()->create(
             \Magento\Vault\Test\TestStep\UseSavedPaymentMethodStep::class,
-            ['payment' => $payment]
+            ['vault' => $payment]
         );
         $useSavedCreditCardStep->run();
     }
diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.xml b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.xml
index 5a2e2903e2c49794a89cf33564e088219f10f3f8..ae303b695277c53272efedc40231bf305b66fea5 100644
--- a/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Vault/Test/TestCase/DeleteSavedCreditCardTest.xml
@@ -35,6 +35,9 @@
                     <item name="creditCard" xsi:type="array">
                         <item name="dataset" xsi:type="string">visa_braintree</item>
                     </item>
+                    <item name="vault" xsi:type="array">
+                        <item name="method" xsi:type="string">braintree_cc_vault</item>
+                    </item>
                 </item>
                 <item name="3" xsi:type="array">
                     <item name="method" xsi:type="string">payflowpro</item>
@@ -42,6 +45,9 @@
                     <item name="creditCard" xsi:type="array">
                         <item name="dataset" xsi:type="string">amex_default</item>
                     </item>
+                    <item name="vault" xsi:type="array">
+                        <item name="method" xsi:type="string">payflowpro_cc_vault</item>
+                    </item>
                 </item>
             </data>
             <data name="creditCardSave" xsi:type="string">Yes</data>
diff --git a/dev/tests/functional/tests/app/Magento/Vault/Test/TestStep/UseSavedPaymentMethodStep.php b/dev/tests/functional/tests/app/Magento/Vault/Test/TestStep/UseSavedPaymentMethodStep.php
index b4b21670d2e0c117bbe51911a8947ab8a0edccad..1470bde4f77e51a7d1938a5b91cc5e74d383e38e 100644
--- a/dev/tests/functional/tests/app/Magento/Vault/Test/TestStep/UseSavedPaymentMethodStep.php
+++ b/dev/tests/functional/tests/app/Magento/Vault/Test/TestStep/UseSavedPaymentMethodStep.php
@@ -22,21 +22,21 @@ class UseSavedPaymentMethodStep implements TestStepInterface
     protected $checkoutOnepage;
 
     /**
-     * Payment information.
+     * Vault provider.
      *
      * @var array
      */
-    protected $payment;
+    protected $vault;
 
     /**
      * @constructor
      * @param CheckoutOnepage $checkoutOnepage
-     * @param array $payment
+     * @param array $vault
      */
-    public function __construct (CheckoutOnepage $checkoutOnepage, array $payment)
+    public function __construct (CheckoutOnepage $checkoutOnepage, array $vault)
     {
         $this->checkoutOnepage = $checkoutOnepage;
-        $this->payment = $payment;
+        $this->vault = $vault;
     }
 
     /**
@@ -46,7 +46,6 @@ class UseSavedPaymentMethodStep implements TestStepInterface
      */
     public function run()
     {
-        $this->payment['method'] .= '_item_';
-        $this->checkoutOnepage->getPaymentBlock()->selectPaymentMethod($this->payment);
+        $this->checkoutOnepage->getPaymentBlock()->selectPaymentMethod($this->vault);
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php
index edd021713f8923afef6901d32c5ab1bf974ff5b4..6358ac8821f26b621de3e83f7ef8380ffb7c3efc 100644
--- a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.php
@@ -26,6 +26,7 @@ class CreateWidgetEntityTest extends AbstractCreateWidgetEntityTest
     /* tags */
     const MVP = 'yes';
     const TEST_TYPE = 'extended_acceptance_test';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.xml b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.xml
index 42d81d2f16c812933292f6355c2a0e5eb0842f88..f533e115253ed52100fa5c9a9d51f4aa2303ca6b 100644
--- a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/CreateWidgetEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Widget\Test\TestCase\CreateWidgetEntityTest" summary="Create Widget" ticketId="MAGETWO-27916">
         <variation name="CreateWidgetEntityTestVariation1">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="widget/data/code" xsi:type="string">CMS Static Block</data>
             <data name="widget/data/theme_id" xsi:type="string">Magento Luma</data>
             <data name="widget/data/title" xsi:type="string">Title_%isolation%</data>
@@ -15,11 +16,10 @@
             <data name="widget/data/widget_instance/dataset" xsi:type="string">on_category</data>
             <data name="widget/data/parameters/dataset" xsi:type="string">cmsStaticBlock</data>
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetSuccessSaveMessage" />
-            <constraint name="Magento\Widget\Test\Constraint\AssertWidgetInGrid" />
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetOnFrontendInCatalog" />
         </variation>
         <variation name="CreateWidgetEntityTestVariation2">
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data>
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, severity:S1</data>
             <data name="widget/data/code" xsi:type="string">CMS Page Link</data>
             <data name="widget/data/theme_id" xsi:type="string">Magento Luma</data>
             <data name="widget/data/title" xsi:type="string">Title_%isolation%</data>
@@ -31,6 +31,7 @@
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetCmsPageLink" />
         </variation>
         <variation name="CreateWidgetEntityTestVariation3">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="widget/data/code" xsi:type="string">Recently Viewed Products</data>
             <data name="widget/data/theme_id" xsi:type="string">Magento Luma</data>
             <data name="widget/data/title" xsi:type="string">Title_%isolation%</data>
@@ -38,10 +39,10 @@
             <data name="widget/data/widget_instance/dataset" xsi:type="string">for_viewed_products</data>
             <data name="widget/data/parameters/dataset" xsi:type="string">recentlyViewedProducts</data>
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetSuccessSaveMessage" />
-            <constraint name="Magento\Widget\Test\Constraint\AssertWidgetInGrid" />
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetRecentlyViewedProducts" />
         </variation>
         <variation name="CreateWidgetEntityTestVariation4">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="widget/data/code" xsi:type="string">Recently Compared Products</data>
             <data name="widget/data/theme_id" xsi:type="string">Magento Luma</data>
             <data name="widget/data/title" xsi:type="string">Title_%isolation%</data>
@@ -49,10 +50,10 @@
             <data name="widget/data/widget_instance/dataset" xsi:type="string">for_compared_products</data>
             <data name="widget/data/parameters/dataset" xsi:type="string">recentlyComparedProducts</data>
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetSuccessSaveMessage" />
-            <constraint name="Magento\Widget\Test\Constraint\AssertWidgetInGrid" />
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetRecentlyComparedProducts" />
         </variation>
         <variation name="CreateWidgetEntityTestVariation5">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="widget/data/code" xsi:type="string">Catalog Category Link</data>
             <data name="widget/data/theme_id" xsi:type="string">Magento Luma</data>
             <data name="widget/data/title" xsi:type="string">Title_%isolation%</data>
@@ -60,11 +61,10 @@
             <data name="widget/data/widget_instance/dataset" xsi:type="string">for_category_link</data>
             <data name="widget/data/parameters/dataset" xsi:type="string">catalogCategoryLink</data>
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetSuccessSaveMessage" />
-            <constraint name="Magento\Widget\Test\Constraint\AssertWidgetInGrid" />
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetCatalogCategoryLink" />
         </variation>
         <variation name="CreateWidgetEntityTestVariation6">
-            <data name="tag" xsi:type="string">test_type:extended_acceptance_test</data>
+            <data name="tag" xsi:type="string">test_type:extended_acceptance_test, severity:S1</data>
             <data name="widget/data/code" xsi:type="string">Catalog Product Link</data>
             <data name="widget/data/theme_id" xsi:type="string">Magento Luma</data>
             <data name="widget/data/title" xsi:type="string">Title_%isolation%</data>
@@ -72,11 +72,11 @@
             <data name="widget/data/widget_instance/dataset" xsi:type="string">on_product_link</data>
             <data name="widget/data/parameters/dataset" xsi:type="string">catalogProductLink</data>
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetSuccessSaveMessage" />
-            <constraint name="Magento\Widget\Test\Constraint\AssertWidgetInGrid" />
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetOnFrontendInCatalog" />
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetProductLink" />
         </variation>
         <variation name="CreateWidgetEntityTestVariation7" summary="Assert widget with disabled block_html cache type">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="caches/block_html" xsi:type="string">Disabled</data>
             <data name="widget/data/code" xsi:type="string">CMS Static Block</data>
             <data name="widget/data/theme_id" xsi:type="string">Magento Luma</data>
@@ -91,6 +91,7 @@
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetOnFrontendInCatalog" />
         </variation>
         <variation name="CreateWidgetEntityTestVariation8" summary="Assert widget with invalidated block_html cache type">
+            <data name="tag" xsi:type="string">severity:S3</data>
             <data name="caches/block_html" xsi:type="string">Invalidated</data>
             <data name="widget/data/code" xsi:type="string">Catalog Category Link</data>
             <data name="widget/data/theme_id" xsi:type="string">Magento Luma</data>
@@ -105,6 +106,7 @@
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetAbsentOnFrontendHome" />
         </variation>
         <variation name="CreateWidgetEntityTestVariation9" summary="Create Catalog New Products List type widget">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="widget/data/code" xsi:type="string">Catalog New Products List</data>
             <data name="widget/data/theme_id" xsi:type="string">Magento Luma</data>
             <data name="widget/data/title" xsi:type="string">Title_%isolation%</data>
diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/DeleteWidgetEntityTest.php b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/DeleteWidgetEntityTest.php
index ba89d591e36406475ebd3783e777d049ff599517..f80389d64acff7ed304c789e6cccd6c349421bdd 100644
--- a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/DeleteWidgetEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/DeleteWidgetEntityTest.php
@@ -29,6 +29,7 @@ class DeleteWidgetEntityTest extends Injectable
 {
     /* tags */
     const MVP = 'yes';
+    const SEVERITY = 'S1';
     /* end tags */
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/DeleteWidgetEntityTest.xml b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/DeleteWidgetEntityTest.xml
index fc63d3f5c266071544398e519953714700a1988a..c30eda8810f22683a52c3ba860647f7f532671ca 100644
--- a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/DeleteWidgetEntityTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/DeleteWidgetEntityTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Widget\Test\TestCase\DeleteWidgetEntityTest" summary="Delete Widget" ticketId="MAGETWO-28459">
         <variation name="DeleteWidgetEntityTestVariation1">
+            <data name="tag" xsi:type="string">severity:S1</data>
             <data name="widget/dataset" xsi:type="string">default</data>
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetSuccessDeleteMessage" />
             <constraint name="Magento\Widget\Test\Constraint\AssertWidgetAbsentOnFrontendHome" />
diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/NavigateMenuTest.xml b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/NavigateMenuTest.xml
index 99c383d8748eea8ff5847847da1d90a7a97f6d8f..02201d6fb4a3ba9cfaa1d3d1809a51fa7e73bc7b 100644
--- a/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/NavigateMenuTest.xml
+++ b/dev/tests/functional/tests/app/Magento/Widget/Test/TestCase/NavigateMenuTest.xml
@@ -8,6 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
     <testCase name="Magento\Backend\Test\TestCase\NavigateMenuTest">
         <variation name="NavigateMenuTest96">
+            <data name="tag" xsi:type="string">severity:S2</data>
             <data name="menuItem" xsi:type="string">Content > Widgets</data>
             <data name="pageTitle" xsi:type="string">Widgets</data>
             <constraint name="Magento\Backend\Test\Constraint\AssertBackendPageIsAvailable" />
diff --git a/dev/tests/functional/tests/app/Magento/Widget/Test/etc/di.xml b/dev/tests/functional/tests/app/Magento/Widget/Test/etc/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..122a9659cf2b6be0706218e1f761870784179ea7
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Widget/Test/etc/di.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
+    <type name="Magento\Widget\Test\Constraint\AssertWidgetAbsentOnFrontendHome">
+        <arguments>
+            <argument name="severity" xsi:type="string">S2</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Widget\Test\Constraint\AssertWidgetCatalogCategoryLink">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Widget\Test\Constraint\AssertWidgetCatalogNewProductsList">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Widget\Test\Constraint\AssertWidgetCmsPageLink">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Widget\Test\Constraint\AssertWidgetInGrid">
+        <arguments>
+            <argument name="severity" xsi:type="string">S2</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Widget\Test\Constraint\AssertWidgetOnFrontendInCatalog">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Widget\Test\Constraint\AssertWidgetOnProductPage">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Widget\Test\Constraint\AssertWidgetProductLink">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Widget\Test\Constraint\AssertWidgetRecentlyComparedProducts">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Widget\Test\Constraint\AssertWidgetRecentlyViewedProducts">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Widget\Test\Constraint\AssertWidgetSuccessDeleteMessage">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Widget\Test\Constraint\AssertWidgetSuccessSaveMessage">
+        <arguments>
+            <argument name="severity" xsi:type="string">S1</argument>
+        </arguments>
+    </type>
+</config>
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/Widget/Form/ContainerTest.php b/dev/tests/integration/testsuite/Magento/Backend/Block/Widget/Form/ContainerTest.php
index 466a1314907fe7c402064d37ab5deb50c7d3d0b3..329e627903ccb8969b09d2907b91cc6e52f83755 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Block/Widget/Form/ContainerTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Block/Widget/Form/ContainerTest.php
@@ -33,4 +33,23 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
         $form->setText($expectedHtml);
         $this->assertEquals($expectedHtml, $block->getFormHtml());
     }
+
+    public function testPseudoConstruct()
+    {
+        /** @var $block \Magento\Backend\Block\Widget\Form\Container */
+        $block = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            \Magento\Framework\View\LayoutInterface::class
+        )->createBlock(
+            \Magento\Backend\Block\Widget\Form\Container::class,
+            '',
+            [
+                'data' => [
+                    \Magento\Backend\Block\Widget\Container::PARAM_CONTROLLER => 'user',
+                    \Magento\Backend\Block\Widget\Form\Container::PARAM_MODE => 'edit',
+                    \Magento\Backend\Block\Widget\Form\Container::PARAM_BLOCK_GROUP => 'Magento_User'
+                ]
+            ]
+        );
+        $this->assertInstanceOf(\Magento\User\Block\User\Edit\Form::class, $block->getChildBlock('form'));
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Braintree/Model/PaymentMethodListTest.php b/dev/tests/integration/testsuite/Magento/Braintree/Model/PaymentMethodListTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0e38adda5498facd9f6213193f536128f2b20c8f
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Braintree/Model/PaymentMethodListTest.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Braintree\Model;
+
+use Magento\Braintree\Model\Ui\ConfigProvider;
+use Magento\Braintree\Model\Ui\PayPal\ConfigProvider as PayPalConfigProvider;
+use Magento\Store\Model\StoreManagerInterface;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Vault\Api\PaymentMethodListInterface;
+use Magento\Vault\Model\VaultPaymentInterface;
+
+/**
+ * Contains tests for vault payment list methods
+ */
+class PaymentMethodListTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var PaymentMethodListInterface
+     */
+    private $paymentMethodList;
+
+    /**
+     * @var int
+     */
+    private $storeId;
+
+    protected function setUp()
+    {
+        $objectManager = Bootstrap::getObjectManager();
+        $this->storeId = $objectManager->get(StoreManagerInterface::class)
+            ->getStore()
+            ->getId();
+        $this->paymentMethodList = $objectManager->get(PaymentMethodListInterface::class);
+    }
+
+    /**
+     * @magentoDataFixture Magento/Braintree/_files/payments.php
+     */
+    public function testGetList()
+    {
+        $vaultPayments = $this->paymentMethodList->getList($this->storeId);
+
+        static::assertNotEmpty($vaultPayments);
+
+        $paymentCodes = array_map(function (VaultPaymentInterface $payment) {
+            return $payment->getCode();
+        }, $vaultPayments);
+
+        $expectedCodes = [
+            PayPalConfigProvider::PAYPAL_VAULT_CODE,
+            ConfigProvider::CC_VAULT_CODE
+        ];
+        static::assertNotEmpty(array_intersect($expectedCodes, $paymentCodes));
+    }
+
+    /**
+     * @magentoDataFixture Magento/Braintree/_files/payments.php
+     */
+    public function testGetActiveList()
+    {
+        $vaultPayments = $this->paymentMethodList->getActiveList($this->storeId);
+
+        static::assertNotEmpty($vaultPayments);
+        static::assertCount(1, $vaultPayments);
+        $payment = array_pop($vaultPayments);
+        static::assertEquals(PayPalConfigProvider::PAYPAL_VAULT_CODE, $payment->getCode());
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Braintree/Model/Ui/TokensConfigProviderTest.php b/dev/tests/integration/testsuite/Magento/Braintree/Model/Ui/TokensConfigProviderTest.php
index b8550ae20542929511afb8c20da0bb26c5830ca4..440f7674f12279757fbd336bbd9a7fc23ba4e819 100644
--- a/dev/tests/integration/testsuite/Magento/Braintree/Model/Ui/TokensConfigProviderTest.php
+++ b/dev/tests/integration/testsuite/Magento/Braintree/Model/Ui/TokensConfigProviderTest.php
@@ -72,7 +72,7 @@ class TokensConfigProviderTest extends \PHPUnit_Framework_TestCase
         /** @var PaymentTokenManagement $tokenManagement */
         $tokenManagement = $this->objectManager->get(PaymentTokenManagement::class);
         $paymentToken = $tokenManagement->getByGatewayToken($token, PayPalConfigProvider::PAYPAL_CODE, $customerId);
-        $item = PayPalConfigProvider::PAYPAL_CODE . '_item_' . $paymentToken->getEntityId();
+        $item = PayPalConfigProvider::PAYPAL_VAULT_CODE . '_' . $paymentToken->getEntityId();
 
         /** @var Session $session */
         $session = $this->objectManager->get(Session::class);
diff --git a/dev/tests/integration/testsuite/Magento/Braintree/_files/payments.php b/dev/tests/integration/testsuite/Magento/Braintree/_files/payments.php
new file mode 100644
index 0000000000000000000000000000000000000000..99ff4481f2982f5076282161931017893380e491
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Braintree/_files/payments.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+use Magento\Braintree\Model\Ui\PayPal\ConfigProvider;
+use Magento\Config\Model\Config;
+use Magento\TestFramework\Helper\Bootstrap;
+
+$objectManager = Bootstrap::getObjectManager();
+/** @var Config $config */
+$config = $objectManager->get(Config::class);
+$config->setDataByPath('payment/' . ConfigProvider::PAYPAL_CODE . '/active', 1);
+$config->save();
+$config->setDataByPath('payment/' . ConfigProvider::PAYPAL_VAULT_CODE . '/active', 1);
+$config->save();
diff --git a/dev/tests/integration/testsuite/Magento/BundleImportExport/Model/Export/RowCustomizerTest.php b/dev/tests/integration/testsuite/Magento/BundleImportExport/Model/Export/RowCustomizerTest.php
index 25372e548d0371b2c75b36526e38f815c3f3b257..646add0682a022a57de9d7b57a46a628465083eb 100644
--- a/dev/tests/integration/testsuite/Magento/BundleImportExport/Model/Export/RowCustomizerTest.php
+++ b/dev/tests/integration/testsuite/Magento/BundleImportExport/Model/Export/RowCustomizerTest.php
@@ -33,6 +33,9 @@ class RowCustomizerTest extends \PHPUnit_Framework_TestCase
      */
     public function testPrepareData()
     {
+        $parsedAdditionalAttributes = 'text_attribute=!@#$%^&*()_+1234567890-=|\\:;"\'<,>.?/'
+            . ',text_attribute2=,';
+        $allAdditionalAttributes = $parsedAdditionalAttributes . ',weight_type=0,price_type=1';
         /** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $collection */
         $collection = $this->objectManager->get(\Magento\Catalog\Model\ResourceModel\Product\Collection::class);
         $select = $collection->getConnection()->select()
@@ -42,7 +45,7 @@ class RowCustomizerTest extends \PHPUnit_Framework_TestCase
         $select = (string)$collection->getSelect();
         $this->model->prepareData($collection, array_values($ids));
         $this->assertEquals($select, (string)$collection->getSelect());
-        $result = $this->model->addData([], $ids['bundle-product']);
+        $result = $this->model->addData(['additional_attributes' => $allAdditionalAttributes], $ids['bundle-product']);
         $this->assertArrayHasKey('bundle_price_type', $result);
         $this->assertArrayHasKey('bundle_shipment_type', $result);
         $this->assertArrayHasKey('bundle_sku_type', $result);
@@ -51,5 +54,6 @@ class RowCustomizerTest extends \PHPUnit_Framework_TestCase
         $this->assertArrayHasKey('bundle_values', $result);
         $this->assertContains('sku=simple,', $result['bundle_values']);
         $this->assertEquals([], $this->model->addData([], $ids['simple']));
+        $this->assertEquals($parsedAdditionalAttributes, $result['additional_attributes']);
     }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Category/CategoryImageTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Category/CategoryImageTest.php
deleted file mode 100644
index 22acb1197631580dba7245a1fbc39f13fd1b59dc..0000000000000000000000000000000000000000
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Category/CategoryImageTest.php
+++ /dev/null
@@ -1,99 +0,0 @@
-<?php
-/**
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-/**
- * This test was moved to the separate file.
- * Because of fixture applying order magentoAppIsolation -> magentoDataFixture -> magentoConfigFixture
- * (https://wiki.magento.com/display/PAAS/Integration+Tests+Development+Guide
- * #IntegrationTestsDevelopmentGuide-ApplyingAnnotations)
- * config fixtures can't be applied before data fixture.
- */
-namespace Magento\Catalog\Model\Category;
-
-use Magento\Catalog\Model\Category\CategoryImageTest\StubZendLogWriterStream;
-
-class CategoryImageTest extends \PHPUnit_Framework_TestCase
-{
-    /** @var int */
-    protected $_oldLogActive;
-
-    /** @var string */
-    protected $_oldExceptionFile;
-
-    /** @var string */
-    protected $_oldWriterModel;
-
-    protected function setUp()
-    {
-        $this->_oldLogActive = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            \Magento\Store\Model\StoreManagerInterface::class
-        )->getStore()->getConfig(
-            'dev/log/active'
-        );
-        $this->_oldExceptionFile = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            \Magento\Store\Model\StoreManagerInterface::class
-        )->getStore()->getConfig(
-            'dev/log/exception_file'
-        );
-    }
-
-    protected function tearDown()
-    {
-        \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            \Magento\Framework\App\Config\MutableScopeConfigInterface::class
-        )->setValue(
-            'dev/log/active',
-            $this->_oldLogActive,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-        );
-
-        $this->_oldLogActive = null;
-
-        \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            \Magento\Framework\App\Config\MutableScopeConfigInterface::class
-        )->setValue(
-            'dev/log/exception_file',
-            $this->_oldExceptionFile,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-        );
-
-        $this->_oldExceptionFile = null;
-
-        $this->_oldWriterModel = null;
-
-        /**
-         * @TODO: refactor this test
-         * Changing store configuration in such a way totally breaks the idea of application isolation.
-         * Class declaration in data fixture file is dumb too.
-         * Added a quick fix to be able run separate tests with "phpunit --filter testMethod"
-         */
-        if (class_exists(\Magento\Catalog\Model\Category\CategoryImageTest\StubZendLogWriterStreamTest::class, false)) {
-            StubZendLogWriterStream::$exceptions = [];
-        }
-    }
-
-    /**
-     * Test that there is no exception '$_FILES array is empty' in \Magento\Framework\File\Uploader::_setUploadFileId()
-     * if category image was not set
-     *
-     */
-    public function testSaveCategoryWithoutImage()
-    {
-        $this->markTestSkipped('MAGETWO-15096');
-
-        /** @var $objectManager \Magento\TestFramework\ObjectManager */
-        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-
-        /** @var $category \Magento\Catalog\Model\Category */
-        $category = $objectManager->get(\Magento\Framework\Registry::class)
-            ->registry('_fixture/Magento\Catalog\Model\Category');
-        $this->assertNotEmpty($category->getId());
-
-        foreach (StubZendLogWriterStream::$exceptions as $exception) {
-            $this->assertNotContains('$_FILES array is empty', $exception['message']);
-        }
-    }
-}
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Category/CategoryImageTest/StubZendLogWriterStream.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Category/CategoryImageTest/StubZendLogWriterStream.php
deleted file mode 100644
index 3915ad47b3b1c3108c001b7b80969600a09d92c5..0000000000000000000000000000000000000000
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Category/CategoryImageTest/StubZendLogWriterStream.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-/**
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Catalog\Model\Category\CategoryImageTest;
-
-\Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-    \Magento\Framework\App\Config\MutableScopeConfigInterface::class
-)->setValue(
-    'dev/log/active',
-    1,
-    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-);
-
-\Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-    \Magento\Framework\App\Config\MutableScopeConfigInterface::class
-)->setValue(
-    'dev/log/exception_file',
-    'save_category_without_image.log',
-    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-);
-class StubZendLogWriterStream extends \Zend_Log_Writer_Stream
-{
-    /** @var array */
-    public static $exceptions = [];
-
-    public function write($event)
-    {
-        self::$exceptions[] = $event;
-
-        parent::write($event);
-    }
-}
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTest.php
index 83e0f352a68ea0e2bb02df78fe7ffba3fd3fdf91..a3e90819912f03a9413311600c7cd5cbcfddff60 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTest.php
@@ -275,6 +275,27 @@ class CategoryTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals('5', $category->getPosition());
     }
 
+    /**
+     * @magentoDbIsolation enabled
+     */
+    public function testSaveCategoryWithoutImage()
+    {
+        $model = $this->objectManager->create(\Magento\Catalog\Model\Category::class);
+        $repository = $this->objectManager->get(\Magento\Catalog\Api\CategoryRepositoryInterface::class);
+
+        $model->setName('Test Category 100')
+            ->setParentId(2)
+            ->setLevel(2)
+            ->setAvailableSortBy(['position', 'name'])
+            ->setDefaultSortBy('name')
+            ->setIsActive(true)
+            ->setPosition(1)
+            ->isObjectNew(true);
+
+        $repository->save($model);
+        $this->assertNull($model->getImage());
+    }
+
     /**
      * @magentoAppArea adminhtml
      */
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Gallery/CreateHandlerTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Gallery/CreateHandlerTest.php
index 992c3bf310f51995ece1b78f6c566fd1d3baf1a4..2c42a289bd4c017a15591d9a110220fce74de346 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Gallery/CreateHandlerTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Gallery/CreateHandlerTest.php
@@ -18,6 +18,10 @@ class CreateHandlerTest extends \PHPUnit_Framework_TestCase
      */
     protected $createHandler;
 
+    private $fileName = '/m/a/magento_image.jpg';
+
+    private $fileLabel = 'Magento image';
+
     protected function setUp()
     {
         $this->createHandler = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
@@ -28,10 +32,8 @@ class CreateHandlerTest extends \PHPUnit_Framework_TestCase
     /**
      * @covers \Magento\Catalog\Model\Product\Gallery\CreateHandler::execute
      */
-    public function testExecute()
+    public function testExecuteWithImageDuplicate()
     {
-        $fileName = '/m/a/magento_image.jpg';
-        $fileLabel = 'Magento image';
         /** @var $product \Magento\Catalog\Model\Product */
         $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
             \Magento\Catalog\Model\Product::class
@@ -39,20 +41,141 @@ class CreateHandlerTest extends \PHPUnit_Framework_TestCase
         $product->load(1);
         $product->setData(
             'media_gallery',
-            ['images' => ['image' => ['file' => $fileName, 'label' => $fileLabel]]]
+            ['images' => ['image' => ['file' => $this->fileName, 'label' => $this->fileLabel]]]
         );
-        $product->setData('image', $fileName);
+        $product->setData('image', $this->fileName);
         $this->createHandler->execute($product);
         $this->assertStringStartsWith('/m/a/magento_image', $product->getData('media_gallery/images/image/new_file'));
-        $this->assertEquals($fileLabel, $product->getData('image_label'));
+        $this->assertEquals($this->fileLabel, $product->getData('image_label'));
 
         $product->setIsDuplicate(true);
         $product->setData(
             'media_gallery',
-            ['images' => ['image' => ['value_id' => '100', 'file' => $fileName, 'label' => $fileLabel]]]
+            ['images' => ['image' => ['value_id' => '100', 'file' => $this->fileName, 'label' => $this->fileLabel]]]
         );
         $this->createHandler->execute($product);
         $this->assertStringStartsWith('/m/a/magento_image', $product->getData('media_gallery/duplicate/100'));
-        $this->assertEquals($fileLabel, $product->getData('image_label'));
+        $this->assertEquals($this->fileLabel, $product->getData('image_label'));
+    }
+
+    /**
+     * @dataProvider executeDataProvider
+     * @param $image
+     * @param $smallImage
+     * @param $swatchImage
+     * @param $thumbnail
+     */
+    public function testExecuteWithImageRoles($image, $smallImage, $swatchImage, $thumbnail)
+    {
+        /** @var $product \Magento\Catalog\Model\Product */
+        $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            \Magento\Catalog\Model\Product::class
+        );
+        $product->load(1);
+        $product->setData(
+            'media_gallery',
+            ['images' => ['image' => ['file' => $this->fileName, 'label' => '']]]
+        );
+        $product->setData('image', $image);
+        $product->setData('small_image', $smallImage);
+        $product->setData('swatch_image', $swatchImage);
+        $product->setData('thumbnail', $thumbnail);
+        $this->createHandler->execute($product);
+
+        $resource = $product->getResource();
+        $id = $product->getId();
+        $storeId = $product->getStoreId();
+
+        $this->assertStringStartsWith('/m/a/magento_image', $product->getData('media_gallery/images/image/new_file'));
+        $this->assertEquals(
+            $image,
+            $resource->getAttributeRawValue($id, $resource->getAttribute('image'), $storeId)
+        );
+        $this->assertEquals(
+            $smallImage,
+            $resource->getAttributeRawValue($id, $resource->getAttribute('small_image'), $storeId)
+        );
+        $this->assertEquals(
+            $swatchImage,
+            $resource->getAttributeRawValue($id, $resource->getAttribute('swatch_image'), $storeId)
+        );
+        $this->assertEquals(
+            $thumbnail,
+            $resource->getAttributeRawValue($id, $resource->getAttribute('thumbnail'), $storeId)
+        );
+    }
+
+    /**
+     * @dataProvider executeDataProvider
+     * @param $image
+     * @param $smallImage
+     * @param $swatchImage
+     * @param $thumbnail
+     */
+    public function testExecuteWithoutImages($image, $smallImage, $swatchImage, $thumbnail)
+    {
+        /** @var $product \Magento\Catalog\Model\Product */
+        $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            \Magento\Catalog\Model\Product::class
+        );
+        $product->load(1);
+        $product->setData(
+            'media_gallery',
+            ['images' => ['image' => ['file' => $this->fileName, 'label' => '']]]
+        );
+        $product->setData('image', $image);
+        $product->setData('small_image', $smallImage);
+        $product->setData('swatch_image', $swatchImage);
+        $product->setData('thumbnail', $thumbnail);
+        $this->createHandler->execute($product);
+
+        $product->unsetData('image');
+        $product->unsetData('small_image');
+        $product->unsetData('swatch_image');
+        $product->unsetData('thumbnail');
+        $this->createHandler->execute($product);
+
+        $resource = $product->getResource();
+        $id = $product->getId();
+        $storeId = $product->getStoreId();
+
+        $this->assertStringStartsWith('/m/a/magento_image', $product->getData('media_gallery/images/image/new_file'));
+        $this->assertEquals(
+            $image,
+            $resource->getAttributeRawValue($id, $resource->getAttribute('image'), $storeId)
+        );
+        $this->assertEquals(
+            $smallImage,
+            $resource->getAttributeRawValue($id, $resource->getAttribute('small_image'), $storeId)
+        );
+        $this->assertEquals(
+            $swatchImage,
+            $resource->getAttributeRawValue($id, $resource->getAttribute('swatch_image'), $storeId)
+        );
+        $this->assertEquals(
+            $thumbnail,
+            $resource->getAttributeRawValue($id, $resource->getAttribute('thumbnail'), $storeId)
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function executeDataProvider()
+    {
+        return [
+            [
+                'image' => $this->fileName,
+                'small_image' => $this->fileName,
+                'swatch_image' => $this->fileName,
+                'thumbnail' => $this->fileName
+            ],
+            [
+                'image' => 'no_selection',
+                'small_image' => 'no_selection',
+                'swatch_image' => 'no_selection',
+                'thumbnail' => 'no_selection'
+            ]
+        ];
     }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php
index f610ee5e15473c89cc2f4fe4f6f3cc9e92a48eac..3c27a65c4a74385f546c108c077c128ebb4edcfb 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php
@@ -476,13 +476,24 @@ class ProductTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * @magentoDataFixture Magento/Catalog/_files/product_simple.php
+     * @magentoDataFixture Magento/Catalog/_files/product_simple_with_custom_options.php
      * @magentoAppIsolation enabled
      */
     public function testGetOptions()
     {
-        $this->_model = $this->productRepository->get('simple');
-
-        $this->assertEquals(4, count($this->_model->getOptions()));
+        $this->_model = $this->productRepository->get('simple_with_custom_options');
+        $options = $this->_model->getOptions();
+        $this->assertNotEmpty($options);
+        $expectedValue = [
+            '3-1-select' => 3000.00,
+            '3-2-select' => 5000.00,
+            '4-1-radio' => 600.234,
+            '4-2-radio' => 40000.00
+        ];
+        foreach ($options as $option) {
+            foreach ($option->getValues() as $value) {
+                $this->assertEquals($expectedValue[$value->getSku()], floatval($value->getPrice()));
+            }
+        }
     }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php
index aadf1e74a883ce823d574178cba29ca617f5abf0..3125cc2a690ba9a0788079f37be339e5e6b5c28f 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple.php
@@ -160,14 +160,14 @@ $oldOptions = [
         'sort_order' => 0,
         'values'    => [
             [
-                'option_type_id' => -1,
+                'option_type_id' => null,
                 'title'         => 'Option 1',
                 'price'         => 3,
                 'price_type'    => 'fixed',
                 'sku'           => '3-1-select',
             ],
             [
-                'option_type_id' => -1,
+                'option_type_id' => null,
                 'title'         => 'Option 2',
                 'price'         => 3,
                 'price_type'    => 'fixed',
@@ -183,14 +183,14 @@ $oldOptions = [
         'sort_order' => 0,
         'values'    => [
             [
-                'option_type_id' => -1,
+                'option_type_id' => null,
                 'title'         => 'Option 1',
                 'price'         => 3,
                 'price_type'    => 'fixed',
                 'sku'           => '4-1-radio',
             ],
             [
-                'option_type_id' => -1,
+                'option_type_id' => null,
                 'title'         => 'Option 2',
                 'price'         => 3,
                 'price_type'    => 'fixed',
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_admin_store.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_admin_store.php
index 18c70968039f8f6df0056daa98da1dbef068e055..d933cd00656d3c8ffde5bd37526aa31aaacba681 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_admin_store.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_admin_store.php
@@ -98,14 +98,14 @@ $oldOptions = [
         'sort_order' => 0,
         'values'    => [
             [
-                'option_type_id' => -1,
+                'option_type_id' => null,
                 'title'         => 'Option 1',
                 'price'         => 3,
                 'price_type'    => 'fixed',
                 'sku'           => '3-1-select',
             ],
             [
-                'option_type_id' => -1,
+                'option_type_id' => null,
                 'title'         => 'Option 2',
                 'price'         => 3,
                 'price_type'    => 'fixed',
@@ -121,14 +121,14 @@ $oldOptions = [
         'sort_order' => 0,
         'values'    => [
             [
-                'option_type_id' => -1,
+                'option_type_id' => null,
                 'title'         => 'Option 1',
                 'price'         => 3,
                 'price_type'    => 'fixed',
                 'sku'           => '4-1-radio',
             ],
             [
-                'option_type_id' => -1,
+                'option_type_id' => null,
                 'title'         => 'Option 2',
                 'price'         => 3,
                 'price_type'    => 'fixed',
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_custom_options.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_custom_options.php
new file mode 100644
index 0000000000000000000000000000000000000000..a0a29753bfeed384aa1a4131e4ca2fed26491e95
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_custom_options.php
@@ -0,0 +1,114 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+\Magento\TestFramework\Helper\Bootstrap::getInstance()->reinitialize();
+
+/** @var \Magento\TestFramework\ObjectManager $objectManager */
+$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+/** @var \Magento\Catalog\Api\CategoryLinkManagementInterface $categoryLinkManagement */
+$categoryLinkManagement = $objectManager->create(\Magento\Catalog\Api\CategoryLinkManagementInterface::class);
+
+/** @var $product \Magento\Catalog\Model\Product */
+$product = $objectManager->create(\Magento\Catalog\Model\Product::class);
+$product->isObjectNew(true);
+$product->setTypeId(\Magento\Catalog\Model\Product\Type::TYPE_SIMPLE)
+    ->setAttributeSetId(4)
+    ->setWebsiteIds([1])
+    ->setName('Simple Product')
+    ->setSku('simple_with_custom_options')
+    ->setPrice(10)
+    ->setWeight(1)
+    ->setShortDescription("Short description")
+    ->setTaxClassId(0)
+    ->setDescription('Description with <b>html tag</b>')
+    ->setMetaTitle('meta title')
+    ->setMetaKeyword('meta keyword')
+    ->setMetaDescription('meta description')
+    ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
+    ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
+    ->setStockData(
+        [
+            'use_config_manage_stock' => 1,
+            'qty' => 100,
+            'is_qty_decimal' => 0,
+            'is_in_stock' => 1,
+        ]
+    )->setCanSaveCustomOptions(true)
+    ->setHasOptions(true);
+
+$oldOptions = [
+    [
+        'previous_group' => 'select',
+        'title' => 'Test Select',
+        'type' => 'drop_down',
+        'is_require' => 1,
+        'sort_order' => 0,
+        'values' => [
+            [
+                'option_type_id' => null,
+                'title' => 'Option 1',
+                'price' => '3,000.00',
+                'price_type' => 'fixed',
+                'sku' => '3-1-select',
+            ],
+            [
+                'option_type_id' => null,
+                'title' => 'Option 2',
+                'price' => '5,000.00',
+                'price_type' => 'fixed',
+                'sku' => '3-2-select',
+            ],
+        ]
+    ],
+    [
+        'previous_group' => 'select',
+        'title' => 'Test Radio',
+        'type' => 'radio',
+        'is_require' => 1,
+        'sort_order' => 0,
+        'values' => [
+            [
+                'option_type_id' => null,
+                'title' => 'Option 1',
+                'price' => '600.234',
+                'price_type' => 'fixed',
+                'sku' => '4-1-radio',
+            ],
+            [
+                'option_type_id' => null,
+                'title' => 'Option 2',
+                'price' => '40,000.00',
+                'price_type' => 'fixed',
+                'sku' => '4-2-radio',
+            ],
+        ]
+    ]
+];
+
+$options = [];
+
+/** @var \Magento\Catalog\Api\Data\ProductCustomOptionInterfaceFactory $customOptionFactory */
+$customOptionFactory = $objectManager->create(\Magento\Catalog\Api\Data\ProductCustomOptionInterfaceFactory::class);
+
+foreach ($oldOptions as $option) {
+    /** @var \Magento\Catalog\Api\Data\ProductCustomOptionInterface $option */
+    $option = $customOptionFactory->create(['data' => $option]);
+    $option->setProductSku($product->getSku());
+
+    $options[] = $option;
+}
+
+$product->setOptions($options);
+
+/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepositoryFactory */
+$productRepositoryFactory = $objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
+$productRepositoryFactory->save($product);
+
+$categoryLinkManagement->assignProductToCategories(
+    $product->getSku(),
+    [2]
+);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_custom_options_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_custom_options_rollback.php
new file mode 100644
index 0000000000000000000000000000000000000000..88e0fb198576060eb8295e633a985d9d6e3ff96a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_with_custom_options_rollback.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+use Magento\Framework\Exception\NoSuchEntityException;
+
+\Magento\TestFramework\Helper\Bootstrap::getInstance()->getInstance()->reinitialize();
+
+/** @var \Magento\Framework\Registry $registry */
+$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class);
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', true);
+
+/** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
+$productRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
+    ->get(\Magento\Catalog\Api\ProductRepositoryInterface::class);
+try {
+    $product = $productRepository->get('simple_with_custom_options', false, null, true);
+    $productRepository->delete($product);
+} catch (NoSuchEntityException $e) {
+
+}
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', false);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_text_attribute.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_text_attribute.php
new file mode 100644
index 0000000000000000000000000000000000000000..d727745e7dd2cfe5e5c3157b93c640248a48d029
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_text_attribute.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+/** @var \Magento\Catalog\Setup\CategorySetup $installer */
+$installer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
+    ->create(\Magento\Catalog\Setup\CategorySetup::class);
+/** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */
+$attribute = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
+    ->create(\Magento\Catalog\Model\ResourceModel\Eav\Attribute::class);
+$attribute->setData(
+    [
+        'attribute_code' => 'text_attribute',
+        'entity_type_id' => $installer->getEntityTypeId('catalog_product'),
+        'is_global' => 1,
+        'is_user_defined' => 1,
+        'frontend_input' => 'textarea',
+        'is_unique' => 0,
+        'is_required' => 0,
+        'is_searchable' => 0,
+        'is_visible_in_advanced_search' => 0,
+        'is_comparable' => 0,
+        'is_filterable' => 0,
+        'is_filterable_in_search' => 0,
+        'is_used_for_promo_rules' => 0,
+        'is_html_allowed_on_front' => 1,
+        'is_visible_on_front' => 0,
+        'used_in_product_listing' => 0,
+        'used_for_sort_by' => 0,
+        'frontend_label' => ['Text Attribute'],
+        'backend_type' => 'text',
+    ]
+);
+$attribute->save();
+/* Assign attribute to attribute set */
+$installer->addAttributeToGroup('catalog_product', 'Default', 'General', $attribute->getId());
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php
index 67e866cf18807f22360cd20a090220d175e994b2..9b06764ce264cfe9aaa6be03a6e61f2f01210631 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Export/ProductTest.php
@@ -83,6 +83,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
         $this->assertContains('Option 4 ""!@#$%^&*', $exportData);
         $this->assertContains('test_option_code_2', $exportData);
         $this->assertContains('max_characters=10', $exportData);
+        $this->assertContains('text_attribute=!@#$%^&*()_+1234567890-=|\\:;""\'<,>.?/', $exportData);
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
index db5511bf9d8ff32be83947c691d063bd4d143205..a5c1f07c164156a0941b0f8da05c43bdff644b5e 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
@@ -20,6 +20,7 @@ use Magento\Catalog\Model\Category;
 use Magento\Framework\App\Bootstrap;
 use Magento\Framework\App\Filesystem\DirectoryList;
 use Magento\ImportExport\Model\Import;
+use Magento\CatalogImportExport\Model\Import\Product\RowValidatorInterface;
 
 /**
  * Class ProductTest
@@ -387,9 +388,13 @@ class ProductTest extends \Magento\TestFramework\Indexer\TestCase
             );
             $productAfterImport->load($productBeforeImport->getId());
             $this->assertEquals(
-                @strtotime($row['news_from_date']),
+                @strtotime(date('m/d/Y', @strtotime($row['news_from_date']))),
                 @strtotime($productAfterImport->getNewsFromDate())
             );
+            $this->assertEquals(
+                @strtotime($row['news_to_date']),
+                @strtotime($productAfterImport->getNewsToDate())
+            );
             unset($productAfterImport);
         }
         unset($productsBeforeImport, $product);
@@ -1050,9 +1055,9 @@ class ProductTest extends \Magento\TestFramework\Indexer\TestCase
      * @magentoAppIsolation enabled
      * @dataProvider validateUrlKeysDataProvider
      * @param $importFile string
-     * @param $errorsCount int
+     * @param $expectedErrors array
      */
-    public function testValidateUrlKeys($importFile, $errorsCount)
+    public function testValidateUrlKeys($importFile, $expectedErrors)
     {
         $filesystem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
             \Magento\Framework\Filesystem::class
@@ -1066,19 +1071,16 @@ class ProductTest extends \Magento\TestFramework\Indexer\TestCase
                 'directory' => $directory
             ]
         );
+        /** @var \Magento\ImportExport\Model\Import\ErrorProcessing\ProcessingErrorAggregatorInterface $errors */
         $errors = $this->_model->setParameters(
             ['behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND, 'entity' => 'catalog_product']
         )->setSource(
             $source
         )->validateData();
-
-        $this->assertTrue($errors->getErrorsCount() == $errorsCount);
-        if ($errorsCount >= 1) {
-            $this->assertEquals(
-            "Specified URL key already exists",
-            $errors->getErrorByRowNumber(1)[0]->getErrorMessage()
-            );
-        }
+        $this->assertEquals(
+            $expectedErrors[RowValidatorInterface::ERROR_DUPLICATE_URL_KEY],
+            count($errors->getErrorsByCode([RowValidatorInterface::ERROR_DUPLICATE_URL_KEY]))
+        );
     }
 
     /**
@@ -1087,9 +1089,24 @@ class ProductTest extends \Magento\TestFramework\Indexer\TestCase
     public function validateUrlKeysDataProvider()
     {
         return [
-            ['products_to_check_valid_url_keys.csv', 0],
-            ['products_to_check_duplicated_url_keys.csv', 2],
-            ['products_to_check_duplicated_names.csv' , 1]
+            [
+                'products_to_check_valid_url_keys.csv',
+                 [
+                     RowValidatorInterface::ERROR_DUPLICATE_URL_KEY => 0
+                 ]
+            ],
+            [
+                'products_to_check_duplicated_url_keys.csv',
+                [
+                    RowValidatorInterface::ERROR_DUPLICATE_URL_KEY => 2
+                ]
+            ],
+            [
+                'products_to_check_duplicated_names.csv' ,
+                [
+                    RowValidatorInterface::ERROR_DUPLICATE_URL_KEY => 1
+                ]
+            ]
         ];
     }
 
@@ -1197,7 +1214,6 @@ class ProductTest extends \Magento\TestFramework\Indexer\TestCase
      */
     public function testExistingProductWithUrlKeys()
     {
-        $this->markTestSkipped('Test must be unskiped after implementation MAGETWO-48871');
         $products = [
             'simple1' => 'url-key1',
             'simple2' => 'url-key2',
@@ -1231,6 +1247,42 @@ class ProductTest extends \Magento\TestFramework\Indexer\TestCase
         }
     }
 
+    /**
+     * @magentoDataFixture Magento/Catalog/_files/product_simple_with_url_key.php
+     * @magentoAppIsolation enabled
+     */
+    public function testImportWithoutUrlKeys()
+    {
+        $products = [
+            'simple1' => 'simple-1',
+            'simple2' => 'simple-2',
+            'simple3' => 'simple-3'
+        ];
+        $filesystem = $this->objectManager->create(\Magento\Framework\Filesystem::class);
+        $directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
+        $source = $this->objectManager->create(
+            \Magento\ImportExport\Model\Import\Source\Csv::class,
+            [
+                'file' => __DIR__ . '/_files/products_to_import_without_url_keys.csv',
+                'directory' => $directory
+            ]
+        );
+
+        $errors = $this->_model->setParameters(
+            ['behavior' => \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND, 'entity' => 'catalog_product']
+        )
+            ->setSource($source)
+            ->validateData();
+
+        $this->assertTrue($errors->getErrorsCount() == 0);
+        $this->_model->importData();
+
+        $productRepository = $this->objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
+        foreach ($products as $productSku => $productUrlKey) {
+            $this->assertEquals($productUrlKey, $productRepository->get($productSku)->getUrlKey());
+        }
+    }
+
     /**
      * @magentoAppIsolation enabled
      */
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_datetime.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_datetime.csv
index ae7e27dbd95c0984548142c93c5d4e35afa0cc20..265e29fab65bb88f469454a7c77185c654e26acc 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_datetime.csv
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_with_datetime.csv
@@ -1,4 +1,4 @@
-sku,news_from_date
-simple1,"1/1/2015 20:00"
-simple2,"10/8/2012 23:58"
-simple3,"12/31/1998 17:30"
+sku,news_from_date,news_to_date
+simple1,"1/1/2015 20:00","1/2/2015"
+simple2,"10/8/2012 23:58","1/3/2015"
+simple3,"12/31/1998 17:30","1/4/2015"
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_without_url_keys.csv b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_without_url_keys.csv
new file mode 100644
index 0000000000000000000000000000000000000000..ff1b9f4b02afb1951a3bb6ab945c58af66040422
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/_files/products_to_import_without_url_keys.csv
@@ -0,0 +1,4 @@
+sku,product_type,store_view_code,name,price,attribute_set_code,url_key
+simple1,simple,,"simple 1",25,Default,""
+simple2,simple,,"simple 2",34,Default,""
+simple3,simple,,"simple 3",58,Default,""
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data.php
index 2d81b9bacb89d58391d49e12c67e9157ccde14c7..ffee568b0622fa8ef3f5af185e24805367ee9203 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/_files/product_export_data.php
@@ -9,23 +9,39 @@
 require dirname(dirname(__DIR__)) . '/Catalog/_files/category.php';
 require dirname(dirname(__DIR__)) . '/Store/_files/second_store.php';
 require dirname(dirname(__DIR__)) . '/Catalog/_files/products_with_multiselect_attribute.php';
+require dirname(dirname(__DIR__)) . '/Catalog/_files/product_text_attribute.php';
 
 $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
 
+/** @var \Magento\Catalog\Model\Product $productModel */
 $productModel = $objectManager->create(\Magento\Catalog\Model\Product::class);
 
 $customOptions = [
     [
-        'id' => 'test_option_code_1',
-        'option_id' => '0',
+        'option_id' => null,
         'sort_order' => '0',
         'title' => 'Option 1',
         'type' => 'drop_down',
         'is_require' => 1,
         'values' => [
-            1 => ['option_type_id' => -1, 'title' => 'Option 1 & Value 1"', 'price' => '1.00', 'price_type' => 'fixed'],
-            2 => ['option_type_id' => -1, 'title' => 'Option 1 & Value 2"', 'price' => '2.00', 'price_type' => 'fixed'],
-            3 => ['option_type_id' => -1, 'title' => 'Option 1 & Value 3"', 'price' => '3.00', 'price_type' => 'fixed']
+            1 => [
+                'option_type_id' => null,
+                'title' => 'Option 1 & Value 1"',
+                'price' => '1.00',
+                'price_type' => 'fixed'
+            ],
+            2 => [
+                'option_type_id' => null,
+                'title' => 'Option 1 & Value 2"',
+                'price' => '2.00',
+                'price_type' => 'fixed'
+            ],
+            3 => [
+                'option_type_id' => null,
+                'title' => 'Option 1 & Value 3"',
+                'price' => '3.00',
+                'price_type' => 'fixed'
+            ]
         ]
     ],
     [
@@ -52,6 +68,8 @@ $productModel->setTypeId(
     'simple'
 )->setPrice(
     10
+)->addData(
+    ['text_attribute' => '!@#$%^&*()_+1234567890-=|\\:;"\'<,>.?/']
 )->setTierPrice(
     [0 => ['website_id' => 0, 'cust_group' => 0, 'price_qty' => 3, 'price' => 8]]
 )->setVisibility(
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_address_saved.php b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_address_saved.php
index 21486448f6191e913cdc75e3d5181186541730aa..7a9e73fe78f166ca5d37cf71a430fe4cddf9efcb 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_address_saved.php
+++ b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_address_saved.php
@@ -11,7 +11,11 @@
 
 require 'quote_with_address.php';
 
-$quote->collectTotals()->save();
+
+$quoteRepository = \Magento\Framework\App\ObjectManager::getInstance()->get(
+    \Magento\Quote\Api\CartRepositoryInterface::class
+);
+$quoteRepository->save($quote);
 
 /** @var \Magento\Quote\Model\QuoteIdMask $quoteIdMask */
 $quoteIdMask = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
diff --git a/dev/tests/integration/testsuite/Magento/Cms/Model/PageTest.php b/dev/tests/integration/testsuite/Magento/Cms/Model/PageTest.php
index 65e578c1181db4cc44d463d62bf210d4a26a55ee..525b3161ffcd921b6b0b9ea048b1f8e077c094f8 100644
--- a/dev/tests/integration/testsuite/Magento/Cms/Model/PageTest.php
+++ b/dev/tests/integration/testsuite/Magento/Cms/Model/PageTest.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Cms\Model;
 
+use Magento\Cms\Api\PageRepositoryInterface;
+
 /**
  * @magentoAppArea adminhtml
  */
@@ -44,6 +46,22 @@ class PageTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($expectedIdentifier, $page->getIdentifier());
     }
 
+    /**
+     * @magentoDbIsolation enabled
+     */
+    public function testUpdateTime()
+    {
+        $updateTime = '2016-09-01 00:00:00';
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var \Magento\Cms\Model\Page $page */
+        $page = $objectManager->create(\Magento\Cms\Model\Page::class);
+        $page->setData(['title' => 'Test', 'stores' => [1]]);
+        $page->setUpdateTime($updateTime);
+        $page->save();
+        $page = $objectManager->get(PageRepositoryInterface::class)->getById($page->getId());
+        $this->assertEquals($updateTime, $page->getUpdateTime());
+    }
+
     public function generateIdentifierFromTitleDataProvider()
     {
         return [
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/OptionRepositoryTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/OptionRepositoryTest.php
index 90fac3c4caca7af34b5ddde487a3b048091831d0..37a087eaa02b2e9c02d58cb4b963e26568336763 100644
--- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/OptionRepositoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/OptionRepositoryTest.php
@@ -12,7 +12,6 @@ class OptionRepositoryTest extends \PHPUnit_Framework_TestCase
      */
     public function testGetListWithExtensionAttributes()
     {
-        $this->markTestSkipped('Test skipped due to MAGETWO-45654');
         $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
         $productSku = 'configurable';
         /** @var \Magento\ConfigurableProduct\Api\OptionRepositoryInterface $optionRepository */
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/Configurable/PriceTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/Configurable/PriceTest.php
index 053e33da09fe9f812aa7a1d4164cf274467a3a6c..6322a60cef8a5fda1b50e220b10de7c5385956d4 100644
--- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/Configurable/PriceTest.php
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/Configurable/PriceTest.php
@@ -90,8 +90,7 @@ class PriceTest extends \PHPUnit_Framework_TestCase
         $options = $this->prepareOptions(
             [
                 [
-                    'id' => 1,
-                    'option_id' => 0,
+                    'option_id' => null,
                     'previous_group' => 'text',
                     'title' => 'Test Field',
                     'type' => 'field',
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProductsTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProductsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0639c7353d55e597fe57cebe6fdf64e97b3e7ec4
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Ui/DataProvider/Product/Form/Modifier/Data/AssociatedProductsTest.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\ConfigurableProduct\Ui\DataProvider\Product\Form\Modifier\Data;
+
+class AssociatedProductsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface $objectManager
+     */
+    private $objectManager;
+
+    /**
+     * @var \Magento\Framework\Registry $registry
+     */
+    private $registry;
+
+    public function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->registry = $this->objectManager->get(\Magento\Framework\Registry::class);
+
+    }
+
+    /**
+     * @dataProvider getProductMatrixDataProvider
+     * @param string $interfaceLocale
+     * @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     * @magentoAppArea adminhtml
+     */
+    public function testGetProductMatrix($interfaceLocale)
+    {
+        $productSku = 'configurable';
+        $associatedProductsData = [
+            [10 => '10.000'],
+            [20 => '20.000']
+        ];
+        /** @var \Magento\Catalog\Api\ProductRepositoryInterface $productRepository */
+        $productRepository = $this->objectManager->create(\Magento\Catalog\Api\ProductRepositoryInterface::class);
+        $this->registry->register('current_product', $productRepository->get($productSku));
+        /** @var $store \Magento\Store\Model\Store */
+        $store = $this->objectManager->create(\Magento\Store\Model\Store::class);
+        $store->load('admin');
+        $this->registry->register('current_store', $store);
+        /** @var \Magento\Framework\Locale\ResolverInterface|\PHPUnit_Framework_MockObject_MockObject $localeResolver */
+        $localeResolver = $this->getMockBuilder(\Magento\Framework\Locale\ResolverInterface::class)
+            ->setMethods(['getLocale'])
+            ->getMockForAbstractClass();
+        $localeResolver->expects($this->any())->method('getLocale')->willReturn($interfaceLocale);
+        $localeCurrency = $this->objectManager->create(
+            \Magento\Framework\Locale\CurrencyInterface::class,
+            ['localeResolver' => $localeResolver]
+        );
+        $associatedProducts = $this->objectManager->create(
+            AssociatedProducts::class,
+            ['localeCurrency' => $localeCurrency]
+        );
+        foreach ($associatedProducts->getProductMatrix() as $productMatrixId => $productMatrixData) {
+            $this->assertEquals(
+                $associatedProductsData[$productMatrixId][$productMatrixData['id']],
+                $productMatrixData['price']
+            );
+        }
+    }
+
+    /**
+     * @return array
+     */
+    public function getProductMatrixDataProvider()
+    {
+        return [
+            ['en_US'],
+            ['zh_Hans_CN']
+        ];
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_simple_77.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_simple_77.php
index b35d87d48063a39011a92e5184090402ea64b4c0..ff08056e4b18def3f520d2a5d9f2090b168d5ec8 100644
--- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_simple_77.php
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/_files/product_simple_77.php
@@ -104,14 +104,14 @@ $oldOptions = [
         'sort_order' => 0,
         'values'    => [
             [
-                'option_type_id' => -1,
+                'option_type_id' => null,
                 'title'         => 'Option 1',
                 'price'         => 3,
                 'price_type'    => 'fixed',
                 'sku'           => '3-1-select',
             ],
             [
-                'option_type_id' => -1,
+                'option_type_id' => null,
                 'title'         => 'Option 2',
                 'price'         => 3,
                 'price_type'    => 'fixed',
@@ -127,14 +127,14 @@ $oldOptions = [
         'sort_order' => 0,
         'values'    => [
             [
-                'option_type_id' => -1,
+                'option_type_id' => null,
                 'title'         => 'Option 1',
                 'price'         => 3,
                 'price_type'    => 'fixed',
                 'sku'           => '4-1-radio',
             ],
             [
-                'option_type_id' => -1,
+                'option_type_id' => null,
                 'title'         => 'Option 2',
                 'price'         => 3,
                 'price_type'    => 'fixed',
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f3571c17ddffe72511037e07af3617244831f66b
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+/**
+ * ResetPassword controller test.
+ *
+ * @magentoAppArea adminhtml
+ */
+class ResetPasswordTest extends \Magento\TestFramework\TestCase\AbstractBackendController
+{
+    /**
+     * Base controller URL
+     *
+     * @var string
+     */
+    protected $baseControllerUrl = 'http://localhost/index.php/backend/customer/index/';
+
+    /**
+     * Checks reset password functionality with default settings and customer reset request event.
+     *
+     * @magentoConfigFixture current_store admin/security/limit_password_reset_requests_method 1
+     * @magentoConfigFixture current_store admin/security/min_time_between_password_reset_requests 10
+     * @magentoDataFixture Magento/Customer/_files/customer.php
+     */
+    public function testResetPasswordSuccess()
+    {
+        $this->passwordResetRequestEventCreate(
+            \Magento\Security\Model\PasswordResetRequestEvent::CUSTOMER_PASSWORD_RESET_REQUEST
+        );
+        $this->getRequest()->setPostValue(['customer_id' => '1']);
+        $this->dispatch('backend/customer/index/resetPassword');
+        $this->assertSessionMessages(
+            $this->equalTo(['The customer will receive an email with a link to reset password.']),
+            \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS
+        );
+        $this->assertRedirect($this->stringStartsWith($this->baseControllerUrl . 'edit'));
+    }
+
+    /**
+     * Checks reset password functionality with default settings, customer and admin reset request events.
+     *
+     * @magentoConfigFixture current_store admin/security/limit_password_reset_requests_method 1
+     * @magentoConfigFixture current_store admin/security/min_time_between_password_reset_requests 10
+     * @magentoConfigFixture current_store contact/email/recipient_email hello@example.com
+     * @magentoDataFixture Magento/Customer/_files/customer.php
+     */
+    public function testResetPasswordWithSecurityViolationException()
+    {
+        $this->passwordResetRequestEventCreate(
+            \Magento\Security\Model\PasswordResetRequestEvent::CUSTOMER_PASSWORD_RESET_REQUEST
+        );
+        $this->passwordResetRequestEventCreate(
+            \Magento\Security\Model\PasswordResetRequestEvent::ADMIN_PASSWORD_RESET_REQUEST
+        );
+        $this->getRequest()->setPostValue(['customer_id' => '1']);
+        $this->dispatch('backend/customer/index/resetPassword');
+        $this->assertSessionMessages(
+            $this->equalTo(
+                ['Too many password reset requests. Please wait and try again or contact hello@example.com.']
+            ),
+            \Magento\Framework\Message\MessageInterface::TYPE_ERROR
+        );
+        $this->assertRedirect($this->stringStartsWith($this->baseControllerUrl . 'edit'));
+    }
+
+    /**
+     * Create and save reset request event with provided request type.
+     *
+     * @param int $requestType
+     */
+    private function passwordResetRequestEventCreate($requestType)
+    {
+        $passwordResetRequestEventFactory = $this->_objectManager->get(
+            \Magento\Security\Model\PasswordResetRequestEventFactory::class
+        );
+        $passwordResetRequestEvent = $passwordResetRequestEventFactory->create();
+        $passwordResetRequestEvent
+            ->setRequestType($requestType)
+            ->setAccountReference('customer@example.com')
+            ->setCreatedAt(strtotime('now'))
+            ->setIp('3232249856')
+            ->save();
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/CustomerImportExport/Model/Import/_files/customers_to_import.csv b/dev/tests/integration/testsuite/Magento/CustomerImportExport/Model/Import/_files/customers_to_import.csv
index 310babaa9b0787f405adf805c3ee80494cb9833e..30a283ce0502fc03341d1e561e36dad64883edfe 100644
--- a/dev/tests/integration/testsuite/Magento/CustomerImportExport/Model/Import/_files/customers_to_import.csv
+++ b/dev/tests/integration/testsuite/Magento/CustomerImportExport/Model/Import/_files/customers_to_import.csv
@@ -1,7 +1,7 @@
 email,_website,_store,confirmation,created_at,created_in,default_billing,default_shipping,disable_auto_group_change,dob,firstname,gender,group_id,lastname,middlename,password_hash,prefix,rp_token,rp_token_created_at,store_id,suffix,taxvat,website_id,password
-AnthonyANealy@magento.com,base,admin,,5/6/2012 15:53,Admin,1,1,0,,Anthony,Male,1,Nealy,A.,6a9c9bfb2ba88a6ad2a64e7402df44a763e0c48cd21d7af9e7e796cd4677ee28:RF,,,,0,,,1,
-LoriBBanks@magento.com,admin,admin,,5/6/2012 15:59,Admin,3,3,0,,Lori,Female,1,Banks,B.,7ad6dbdc83d3e9f598825dc58b84678c7351e4281f6bc2b277a32dcd88b9756b:pz,,,,0,,,0,
+AnthonyANealy@magento.com,base,admin,,5/6/2012 15:53,Admin,1,1,0,5/6/2010,Anthony,Male,1,Nealy,A.,6a9c9bfb2ba88a6ad2a64e7402df44a763e0c48cd21d7af9e7e796cd4677ee28:RF,,,,0,,,1,
+LoriBBanks@magento.com,admin,admin,,5/6/2012 15:59,Admin,3,3,0,5/6/2010,Lori,Female,1,Banks,B.,7ad6dbdc83d3e9f598825dc58b84678c7351e4281f6bc2b277a32dcd88b9756b:pz,,,,0,,,0,
 CharlesTAlston@teleworm.us,base,admin,,5/6/2012 16:13,Admin,4,4,0,,Jhon,Female,1,Doe,T.,145d12bfff8a6a279eb61e277e3d727c0ba95acc1131237f1594ddbb7687a564:l1,,,,0,,,2,
 customer@example.com,base,admin,,5/6/2012 16:15,Admin,4,4,0,,Firstname,Male,1,Lastname,T.,145d12bfff8a6a279eb61e277e3d727c0ba95acc1131237f1594ddbb7687a564:l1,,,,0,,,2,
 julie.worrell@example.com,base,admin,,5/6/2012 16:19,Admin,4,4,0,,Julie,Female,1,Worrell,T.,145d12bfff8a6a279eb61e277e3d727c0ba95acc1131237f1594ddbb7687a564:l1,,,,0,,,2,
-david.lamar@example.com,base,admin,,5/6/2012 16:25,Admin,4,4,0,,David,Male,1,Lamar,T.,145d12bfff8a6a279eb61e277e3d727c0ba95acc1131237f1594ddbb7687a564:l1,,,,0,,,2,
+david.lamar@example.com,base,admin,,5/6/2012 16:25,Admin,4,4,0,,David,,1,Lamar,T.,145d12bfff8a6a279eb61e277e3d727c0ba95acc1131237f1594ddbb7687a564:l1,,,,0,,,2,
diff --git a/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/DownloadableTest.php b/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/DownloadableTest.php
index 3a9bee9f8aad26f68b7d3499d41cecff13bcc507..ff908c78b9fed8703ad939ce0c1219b2d70b8922 100644
--- a/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/DownloadableTest.php
+++ b/dev/tests/integration/testsuite/Magento/DownloadableImportExport/Model/DownloadableTest.php
@@ -43,11 +43,11 @@ class DownloadableTest extends AbstractProductExportImportTestCase
      * @dataProvider exportImportDataProvider
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      *
-     * @todo remove after MAGETWO-49467 resolved
+     * @todo remove after MAGETWO-38240 resolved
      */
     public function testExport($fixtures, $skus, $skippedAttributes = [], $rollbackFixtures = [])
     {
-        $this->markTestSkipped('Uncomment after MAGETWO-49467 resolved');
+        $this->markTestSkipped('Uncomment after MAGETWO-38240 resolved');
     }
 
     /**
@@ -56,11 +56,11 @@ class DownloadableTest extends AbstractProductExportImportTestCase
      * @dataProvider exportImportDataProvider
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      *
-     * @todo remove after MAGETWO-49467 resolved
+     * @todo remove after MAGETWO-38240 resolved
      */
     public function testImportDelete($fixtures, $skus, $skippedAttributes = [], $rollbackFixtures = [])
     {
-        $this->markTestSkipped('Uncomment after MAGETWO-49467 resolved');
+        $this->markTestSkipped('Uncomment after MAGETWO-38240 resolved');
     }
 
     /**
@@ -72,12 +72,13 @@ class DownloadableTest extends AbstractProductExportImportTestCase
      * @param string[] $skus
      * @param string[] $skippedAttributes
      * @dataProvider importReplaceDataProvider
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      *
-     * @todo remove after MAGETWO-49467 resolved
+     * @todo remove after MAGETWO-38240 resolved
      */
     public function testImportReplace($fixtures, $skus, $skippedAttributes = [], $rollbackFixtures = [])
     {
-        $this->markTestSkipped('Uncomment after MAGETWO-49467 resolved');
+        $this->markTestSkipped('Uncomment after MAGETWO-38240 resolved');
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Backup/FilesystemTest.php b/dev/tests/integration/testsuite/Magento/Framework/Backup/FilesystemTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a28a92d9658d60dd804d8a900e231bf79f23cb62
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Framework/Backup/FilesystemTest.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Backup;
+
+use \Magento\TestFramework\Helper\Bootstrap;
+use \Magento\Framework\App\Filesystem\DirectoryList;
+
+class FilesystemTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    private $objectManager;
+
+    /**
+     * @var \Magento\Framework\Backup\Filesystem
+     */
+    private $filesystem;
+
+    protected function setUp()
+    {
+        $this->objectManager = Bootstrap::getObjectManager();
+        $this->filesystem = $this->objectManager->create(\Magento\Framework\Backup\Filesystem::class);
+    }
+
+    /**
+     * @magentoAppIsolation enabled
+     */
+    public function testRollback()
+    {
+        $rootDir = Bootstrap::getInstance()->getAppTempDir()
+            . '/rollback_test_' . time();
+        $backupsDir = __DIR__ . '/_files/var/backups';
+        $fileName = 'test.txt';
+
+        mkdir($rootDir);
+
+        $this->filesystem->setRootDir($rootDir)
+            ->setBackupsDir($backupsDir)
+            ->setTime(1474538269)
+            ->setName('code')
+            ->setBackupExtension('tgz');
+
+        $this->assertTrue($this->filesystem->rollback());
+        $this->assertTrue(file_exists($rootDir . '/' . $fileName));
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Backup/_files/var/backups/1474538269_filesystem_code.tgz b/dev/tests/integration/testsuite/Magento/Framework/Backup/_files/var/backups/1474538269_filesystem_code.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..6e972c35672a8fbee6f29c71c415648b410275f1
Binary files /dev/null and b/dev/tests/integration/testsuite/Magento/Framework/Backup/_files/var/backups/1474538269_filesystem_code.tgz differ
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Composer/RemoveTest.php b/dev/tests/integration/testsuite/Magento/Framework/Composer/RemoveTest.php
index 3ec88e7ed4f0c00d1b447c623b6bc69370132e23..e852eea2ae4493eb1944a0b90f7dd0b4f5bcf351 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Composer/RemoveTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Composer/RemoveTest.php
@@ -5,31 +5,31 @@
  */
 namespace Magento\Framework\Composer;
 
-use Magento\Framework\App\Filesystem\DirectoryList;
+use Magento\Composer\MagentoComposerApplication;
 
 class RemoveTest extends \PHPUnit_Framework_TestCase
 {
     public function testRemove()
     {
-        $composerAppFactory = $this->getMock(
-            \Magento\Framework\Composer\MagentoComposerApplicationFactory::class,
-            [],
-            [],
-            '',
-            false
-        );
+        $composerAppFactory = $this->getMockBuilder(MagentoComposerApplicationFactory::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $composerApp = $this->getMockBuilder(MagentoComposerApplication::class)
+            ->disableOriginalConstructor()
+            ->getMock();
 
-        $composerApp = $this->getMock(
-            \Magento\Composer\MagentoComposerApplication::class,
-            [],
-            [],
-            '',
-            false
-        );
-
-        $composerApp->expects($this->once())->method('runComposerCommand');
-
-        $composerAppFactory->expects($this->once())->method('create')->willReturn($composerApp);
+        $composerApp->expects($this->once())
+            ->method('runComposerCommand')
+            ->with(
+                [
+                    'command' => 'remove',
+                    'packages' => ['magento/package-a', 'magento/package-b'],
+                    '--no-update' => true,
+                ]
+            );
+        $composerAppFactory->expects($this->once())
+            ->method('create')
+            ->willReturn($composerApp);
 
         $remove = new Remove($composerAppFactory);
         $remove->remove(['magento/package-a', 'magento/package-b']);
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php b/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php
index 341b710d5a82f3bf15c831650663345be000c761..324e93770f048d3e76eca7bc9d7219132808f562 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Image/Adapter/InterfaceTest.php
@@ -547,6 +547,9 @@ class InterfaceTest extends \PHPUnit_Framework_TestCase
      */
     public function testCreatePngFromString($pixel1, $expectedColor1, $pixel2, $expectedColor2, $adapterType)
     {
+        if (!function_exists('imagettfbbox')) {
+            $this->markTestSkipped('Workaround for problem with imagettfbbox() function on Travis');
+        }
         $adapter = $this->_getAdapter($adapterType);
 
         /** @var \Magento\Framework\Filesystem\Directory\ReadFactory readFactory */
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Session/SaveHandlerTest.php b/dev/tests/integration/testsuite/Magento/Framework/Session/SaveHandlerTest.php
index 7ba149d361f4fcd15c9d5989ff619d9f81b53cc2..40fafeceae44cb8342e03de9cb3a204675c52a88 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Session/SaveHandlerTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Session/SaveHandlerTest.php
@@ -29,32 +29,20 @@ class SaveHandlerTest extends \PHPUnit_Framework_TestCase
      */
     public function testSetSaveHandler($deploymentConfigHandler, $iniHandler)
     {
-        $this->markTestSkipped('MAGETWO-56529');
-        // Set expected session.save_handler config
-        if ($deploymentConfigHandler) {
-            if ($deploymentConfigHandler !== 'files') {
-                $expected = 'user';
-            } else {
-                $expected = $deploymentConfigHandler;
-            }
-        } else if ($iniHandler) {
-            $expected = $iniHandler;
-        } else {
-            $expected = SaveHandlerInterface::DEFAULT_HANDLER;
-        }
+        $expected = $this->getExpectedSaveHandler($deploymentConfigHandler, $iniHandler);
 
         // Set ini configuration
         if ($iniHandler) {
             ini_set('session.save_handler', $iniHandler);
         }
-
+        $defaultHandler = ini_get('session.save_handler') ?: SaveHandlerInterface::DEFAULT_HANDLER;
         /** @var DeploymentConfig | \PHPUnit_Framework_MockObject_MockObject $deploymentConfigMock */
         $deploymentConfigMock = $this->getMockBuilder(DeploymentConfig::class)
             ->disableOriginalConstructor()
             ->getMock();
         $deploymentConfigMock->expects($this->once())
             ->method('get')
-            ->with(Config::PARAM_SESSION_SAVE_METHOD, SaveHandlerInterface::DEFAULT_HANDLER)
+            ->with(Config::PARAM_SESSION_SAVE_METHOD, $defaultHandler)
             ->willReturn($deploymentConfigHandler ?: SaveHandlerInterface::DEFAULT_HANDLER);
 
         new SaveHandler(
@@ -85,4 +73,31 @@ class SaveHandlerTest extends \PHPUnit_Framework_TestCase
             [false, false],
         ];
     }
+
+    /**
+     * Retrieve expected session.save_handler
+     *
+     * @param string $deploymentConfigHandler
+     * @param string $iniHandler
+     * @return string
+     */
+    private function getExpectedSaveHandler($deploymentConfigHandler, $iniHandler)
+    {
+        // Set expected session.save_handler config
+        if ($deploymentConfigHandler) {
+            if ($deploymentConfigHandler !== 'files') {
+                $expected = 'user';
+                return $expected;
+            } else {
+                $expected = $deploymentConfigHandler;
+                return $expected;
+            }
+        } elseif ($iniHandler) {
+            $expected = $iniHandler;
+            return $expected;
+        } else {
+            $expected = SaveHandlerInterface::DEFAULT_HANDLER;
+            return $expected;
+        }
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/MemoryUsageTest.php b/dev/tests/integration/testsuite/Magento/MemoryUsageTest.php
index 8a6e4747a0d7a8868659fa413d454f16dc0bd9dd..9afc2ca119bbab23bf59f751ba581d247894c15b 100644
--- a/dev/tests/integration/testsuite/Magento/MemoryUsageTest.php
+++ b/dev/tests/integration/testsuite/Magento/MemoryUsageTest.php
@@ -20,7 +20,7 @@ class MemoryUsageTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         if (defined('HHVM_VERSION')) {
-            $this->markTestSkipped("For HHVM it's not relevant while MAGETWO-33679 is not resolved");
+            $this->markTestSkipped("Test not relevant because no gc in HHVM.");
         }
         $this->_helper = new \Magento\TestFramework\Helper\Memory(
             new \Magento\Framework\Shell(new \Magento\Framework\Shell\CommandRenderer())
@@ -32,7 +32,7 @@ class MemoryUsageTest extends \PHPUnit_Framework_TestCase
      */
     public function testAppReinitializationNoMemoryLeak()
     {
-        $this->markTestSkipped('Test fails at Travis. Skipped in scope of MAGETWO-48538');
+        $this->markTestSkipped('Test fails at Travis. Skipped until MAGETWO-47111');
 
         $this->_deallocateUnusedMemory();
         $actualMemoryUsage = $this->_helper->getRealMemoryUsage();
diff --git a/dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates.php b/dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates.php
new file mode 100644
index 0000000000000000000000000000000000000000..5cac40809565e1ed28df9529446550975b39f9f3
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+$resource = $objectManager->get(\Magento\Framework\App\ResourceConnection::class);
+$connection = $resource->getConnection();
+$resourceModel = $objectManager->create(\Magento\OfflineShipping\Model\ResourceModel\Carrier\Tablerate::class);
+$entityTable = $resourceModel->getTable('shipping_tablerate');
+$data =
+    [
+        'website_id' => 1,
+        'dest_country_id' => 'US',
+        'dest_region_id' => 0,
+        'dest_zip' => '*',
+        'condition_name' => 'package_qty',
+        'condition_value' => 1,
+        'price' => 10,
+        'cost' => 10
+    ];
+$connection->query(
+    "INSERT INTO {$entityTable} (`website_id`,  `dest_country_id`, `dest_region_id`, `dest_zip`, `condition_name`,"
+    . "`condition_value`, `price`, `cost`) VALUES (:website_id,  :dest_country_id, :dest_region_id, :dest_zip,"
+    . " :condition_name, :condition_value, :price, :cost);",
+    $data
+);
diff --git a/dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates_rollback.php b/dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates_rollback.php
new file mode 100644
index 0000000000000000000000000000000000000000..10f5563eee8aae9c826a8967e93658b59d9c2eca
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/OfflineShipping/_files/tablerates_rollback.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+$resource = $objectManager->get(\Magento\Framework\App\ResourceConnection::class);
+$connection = $resource->getConnection();
+$resourceModel = $objectManager->create(\Magento\OfflineShipping\Model\ResourceModel\Carrier\Tablerate::class);
+$entityTable = $resourceModel->getTable('shipping_tablerate');
+$connection->query("DELETE FROM {$entityTable};");
diff --git a/dev/tests/integration/testsuite/Magento/Quote/Model/ShippingMethodManagementTest.php b/dev/tests/integration/testsuite/Magento/Quote/Model/ShippingMethodManagementTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7ed966d0c9b998a23145bde4f2432019628a3c6f
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Quote/Model/ShippingMethodManagementTest.php
@@ -0,0 +1,95 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Quote\Model;
+
+/**
+ * Class ShippingMethodManagementTest
+ */
+class ShippingMethodManagementTest extends \PHPUnit_Framework_TestCase
+{
+
+    /**
+     * @magentoAppIsolation enabled
+     * @magentoDbIsolation enabled
+     * @magentoConfigFixture current_store carriers/tablerate/active 1
+     * @magentoConfigFixture current_store carriers/tablerate/condition_name package_qty
+     * @magentoDataFixture Magento/SalesRule/_files/cart_rule_free_shipping.php
+     * @magentoDataFixture Magento/Sales/_files/quote.php
+     * @magentoDataFixture Magento/OfflineShipping/_files/tablerates.php
+     */
+    public function testEstimateByAddressWithCartPriceRule()
+    {
+        $this->executeTestFlow(0, 0);
+    }
+
+    /**
+     * @magentoAppIsolation enabled
+     * @magentoDbIsolation enabled
+     * @magentoConfigFixture current_store carriers/tablerate/active 1
+     * @magentoConfigFixture current_store carriers/tablerate/condition_name package_qty
+     * @magentoDataFixture Magento/Sales/_files/quote.php
+     * @magentoDataFixture Magento/OfflineShipping/_files/tablerates.php
+     */
+    public function testEstimateByAddress()
+    {
+        $this->executeTestFlow(5, 10);
+    }
+
+    /**
+     * Provide testing of shipping method estimation based on address
+     *
+     * @param int $flatRateAmount
+     * @param int $tableRateAmount
+     */
+    private function executeTestFlow($flatRateAmount, $tableRateAmount)
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var \Magento\Quote\Model\Quote $quote */
+        $quote = $objectManager->get(\Magento\Quote\Model\Quote::class);
+        $quote->load('test01', 'reserved_order_id');
+        $cartId = $quote->getId();
+        if (!$cartId) {
+            $this->fail('quote fixture failed');
+        }
+        /** @var \Magento\Quote\Model\QuoteIdMask $quoteIdMask */
+        $quoteIdMask = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
+            ->create(\Magento\Quote\Model\QuoteIdMaskFactory::class)
+            ->create();
+        $quoteIdMask->load($cartId, 'quote_id');
+        //Use masked cart Id
+        $cartId = $quoteIdMask->getMaskedId();
+        $data = [
+            'data' => [
+                'country_id' => "US",
+                'postcode' => null,
+                'region' => null,
+                'region_id' => null
+            ]
+        ];
+        /** @var \Magento\Quote\Api\Data\EstimateAddressInterface $address */
+        $address = $objectManager->create(\Magento\Quote\Api\Data\EstimateAddressInterface::class, $data);
+        /** @var  \Magento\Quote\Api\GuestShippingMethodManagementInterface $shippingEstimation */
+        $shippingEstimation = $objectManager->get(\Magento\Quote\Api\GuestShippingMethodManagementInterface::class);
+        $result = $shippingEstimation->estimateByAddress($cartId, $address);
+        $this->assertNotEmpty($result);
+        $expectedResult = [
+            'tablerate' =>
+                [
+                    'method_code' => 'bestway',
+                    'amount' => $tableRateAmount
+                ],
+            'flatrate' => [
+                'method_code' => 'flatrate',
+                'amount' => $flatRateAmount
+            ]
+        ];
+        foreach ($result as $rate) {
+            $this->assertEquals($expectedResult[$rate->getCarrierCode()]['amount'], $rate->getAmount());
+            $this->assertEquals($expectedResult[$rate->getCarrierCode()]['method_code'], $rate->getMethodCode());
+        }
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_shipping_and_invoice_rollback.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_shipping_and_invoice_rollback.php
new file mode 100644
index 0000000000000000000000000000000000000000..48cf991c848b067b7a3f631b13da812ab0de39b5
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_with_shipping_and_invoice_rollback.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+require 'default_rollback.php';
diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/_files/cart_rule_free_shipping.php b/dev/tests/integration/testsuite/Magento/SalesRule/_files/cart_rule_free_shipping.php
new file mode 100644
index 0000000000000000000000000000000000000000..7ea38c04ccc074d35f256de81411a7dd50c5cd25
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/SalesRule/_files/cart_rule_free_shipping.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+$salesRuleFactory = $objectManager->create(\Magento\SalesRule\Model\RuleFactory::class);
+/** @var \Magento\SalesRule\Model\Rule $salesRule */
+$salesRule = $salesRuleFactory->create();
+$row =
+    [
+        'name' => 'Free shipping if item price >10',
+        'is_active' => 1,
+        'customer_group_ids' => [\Magento\Customer\Model\GroupManagement::NOT_LOGGED_IN_ID],
+        'coupon_type' => \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON,
+        'conditions' => [
+            1 =>
+                [
+                    'type' => \Magento\SalesRule\Model\Rule\Condition\Combine::class,
+                    'attribute' => null,
+                    'operator' => null,
+                    'value' => '1',
+                    'is_value_processed' => null,
+                    'aggregator' => 'all',
+                ]
+
+        ],
+        'actions' => [
+            1 => [
+                'type' => Magento\SalesRule\Model\Rule\Condition\Product\Combine::class,
+                'attribute' => null,
+                'operator' => null,
+                'value' => '1',
+                'is_value_processed' => null,
+                'aggregator' => 'all',
+                'conditions' => [
+                    [
+                        'type' => Magento\SalesRule\Model\Rule\Condition\Product::class,
+                        'attribute' => 'quote_item_price',
+                        'operator' => '==',
+                        'value' => '7',
+                        'is_value_processed' => false,
+                    ]
+                ]
+            ]
+        ],
+        'is_advanced' => 1,
+        'simple_action' => 'by_percent',
+        'discount_amount' => 0,
+        'stop_rules_processing' => 0,
+        'discount_qty' => 0,
+        'discount_step' => 0,
+        'apply_to_shipping' => 1,
+        'times_used' => 0,
+        'is_rss' => 1,
+        'use_auto_generation' => 0,
+        'uses_per_coupon' => 0,
+        'simple_free_shipping' => 1,
+
+        'website_ids' => [
+            \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+                \Magento\Store\Model\StoreManagerInterface::class
+            )->getWebsite()->getId()
+        ]
+    ];
+$salesRule->loadPost($row);
+$salesRule->save();
+/** @var Magento\Framework\Registry $registry */
+$registry = $objectManager->get(\Magento\Framework\Registry::class);
+
+$registry->unregister('cart_rule_free_shipping');
+$registry->register('cart_rule_free_shipping', $salesRule);
diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/_files/cart_rule_free_shipping_rollback.php b/dev/tests/integration/testsuite/Magento/SalesRule/_files/cart_rule_free_shipping_rollback.php
new file mode 100644
index 0000000000000000000000000000000000000000..4669d6a5169661c54e854db48b99bd647ce0d661
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/SalesRule/_files/cart_rule_free_shipping_rollback.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+/** @var Magento\Framework\Registry $registry */
+$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(\Magento\Framework\Registry::class);
+
+/** @var Magento\SalesRule\Model\Rule $rule */
+$rule = $registry->registry('cart_rule_free_shipping');
+if ($rule) {
+    $rule->delete();
+}
diff --git a/dev/tests/integration/testsuite/Magento/Setup/Fixtures/FixtureModelTest.php b/dev/tests/integration/testsuite/Magento/Setup/Fixtures/FixtureModelTest.php
index 358786901713b987d897e2147a6f574a590fc832..b47d45e3815e7c55334ca24ef73788a929497506 100644
--- a/dev/tests/integration/testsuite/Magento/Setup/Fixtures/FixtureModelTest.php
+++ b/dev/tests/integration/testsuite/Magento/Setup/Fixtures/FixtureModelTest.php
@@ -27,6 +27,14 @@ class FixtureModelTest extends \Magento\TestFramework\Indexer\TestCase
 
     public static function setUpBeforeClass()
     {
+        $db = \Magento\TestFramework\Helper\Bootstrap::getInstance()->getBootstrap()
+            ->getApplication()
+            ->getDbInstance();
+        if (!$db->isDbDumpExists()) {
+            throw new \LogicException('DB dump does not exist.');
+        }
+        $db->restoreFromDbDump();
+
         self::$_generatorWorkingDir = realpath(__DIR__ . '/../../../../../../../setup/src/Magento/Setup/Fixtures');
         copy(
             self::$_generatorWorkingDir . '/tax_rates.csv',
@@ -72,38 +80,4 @@ class FixtureModelTest extends \Magento\TestFramework\Indexer\TestCase
             ]
         );
     }
-
-    /**
-     * Apply fixture file
-     *
-     * @param string $fixtureFilename
-     */
-    public function applyFixture($fixtureFilename)
-    {
-        require $fixtureFilename;
-    }
-
-    /**
-     * Get object manager
-     *
-     * @return \Magento\Framework\ObjectManagerInterface
-     */
-    public function getObjectManager()
-    {
-        if (!$this->_objectManager) {
-            $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-        }
-        return $this->_objectManager;
-    }
-
-    /**
-     * Reset object manager
-     *
-     * @return \Magento\Framework\ObjectManagerInterface
-     */
-    public function resetObjectManager()
-    {
-        $this->_objectManager = null;
-        return $this;
-    }
 }
diff --git a/dev/tests/static/framework/Magento/TestFramework/Integrity/AbstractConfig.php b/dev/tests/static/framework/Magento/TestFramework/Integrity/AbstractConfig.php
index afa5981e70f7e340bed21b2325dbc91b2fb032e0..811f62186eeae49bd290e53894377ccf281aaf4c 100644
--- a/dev/tests/static/framework/Magento/TestFramework/Integrity/AbstractConfig.php
+++ b/dev/tests/static/framework/Magento/TestFramework/Integrity/AbstractConfig.php
@@ -36,7 +36,7 @@ abstract class AbstractConfig extends \PHPUnit_Framework_TestCase
     public function testSchemaUsingInvalidXml($expectedErrors = null)
     {
         if (!function_exists('libxml_set_external_entity_loader')) {
-            $this->markTestSkipped('Skipped due to MAGETWO-44919');
+            $this->markTestSkipped('Skipped due to MAGETWO-45033');
         }
         $xmlFile = $this->_getKnownInvalidXml();
         $schema = $this->_getXsd();
@@ -46,7 +46,7 @@ abstract class AbstractConfig extends \PHPUnit_Framework_TestCase
     public function testFileSchemaUsingPartialXml()
     {
         if (!function_exists('libxml_set_external_entity_loader')) {
-            $this->markTestSkipped('Skipped due to MAGETWO-44919');
+            $this->markTestSkipped('Skipped due to MAGETWO-45033');
         }
         $xmlFile = $this->_getKnownValidPartialXml();
         if ($xmlFile === null) {
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Library/DependencyTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Library/DependencyTest.php
index 3ec08a1692bbc0ce907fc18a602cab2dcd1b1c3d..c970c90f20473a49eea849b699b4705d9d64dcef 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/Library/DependencyTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Library/DependencyTest.php
@@ -27,13 +27,33 @@ class DependencyTest extends \PHPUnit_Framework_TestCase
     protected $errors = [];
 
     /**
-     * Forbidden base namespaces
+     * Allowed sub namespaces
      *
      * @return array
      */
-    protected function getForbiddenNamespaces()
+    protected function getAllowedNamespaces()
     {
-        return ['Magento'];
+        return [
+            'Framework',
+            'SomeModule',
+            'ModuleName',
+            'Setup\Console\CommandList',
+            'Setup\Console\CompilerPreparation',
+            'Setup\Model\ObjectManagerProvider',
+            'Setup\Mvc\Bootstrap\InitParamListener',
+            'Store\Model\ScopeInterface',
+            'Store\Model\StoreManagerInterface',
+            'Directory\Model\CurrencyFactory',
+            'PageCache\Model\Cache\Type',
+            'Backup\Model\ResourceModel\Db',
+            'Backend\Block\Widget\Button',
+            'Ui\Component\Container',
+            'SalesRule\Model\Rule',
+            'SalesRule\Api\Data\RuleInterface',
+            'SalesRule\Model\Rule\Interceptor',
+            'SalesRule\Model\Rule\Proxy',
+            'Theme\Model\View\Design'
+        ];
     }
 
     public function testCheckDependencies()
@@ -53,15 +73,15 @@ class DependencyTest extends \PHPUnit_Framework_TestCase
                     (new Injectable())->getDependencies($fileReflection),
                     $tokens->getDependencies()
                 );
-
-                $pattern = '#^(\\\\|)' . implode('|', $this->getForbiddenNamespaces()) . '\\\\#';
+                $allowedNamespaces = str_replace('\\', '\\\\', implode('|', $this->getAllowedNamespaces()));
+                $pattern = '#Magento\\\\(?!' . $allowedNamespaces . ').*#';
                 foreach ($dependencies as $dependency) {
-                    $dependencyPaths = explode('/', $dependency);
+                    $dependencyPaths = explode('\\', $dependency);
                     $dependencyPaths = array_slice($dependencyPaths, 2);
-                    $dependency = implode('\\', $dependencyPaths);
+                    $dependencyPath = implode('\\', $dependencyPaths);
                     $libraryPaths = $componentRegistrar->getPaths(ComponentRegistrar::LIBRARY);
                     foreach ($libraryPaths as $libraryPath) {
-                        $filePath = str_replace('\\', '/', $libraryPath .  '/' . $dependency . '.php');
+                        $filePath = str_replace('\\', '/', $libraryPath .  '/' . $dependencyPath . '.php');
                         if (preg_match($pattern, $dependency) && !file_exists($filePath)) {
                             $this->errors[$fileReflection->getFileName()][] = $dependency;
                         }
@@ -142,12 +162,11 @@ class DependencyTest extends \PHPUnit_Framework_TestCase
         $componentRegistrar = new ComponentRegistrar();
         include_once $componentRegistrar->getPath(ComponentRegistrar::LIBRARY, 'magento/framework')
             . '/Option/ArrayInterface.php';
-        $blackList = Files::init()->readLists(__DIR__ . '/_files/blacklist.txt');
+        $blackList = Files::init()->readLists(__DIR__ . '/_files/blacklist*.txt');
         $dataProvider = Files::init()->getPhpFiles(Files::INCLUDE_LIBS | Files::AS_DATA_SET);
 
         foreach ($dataProvider as $key => $data) {
-            $file = str_replace(BP . '/', '', $data[0]);
-            if (in_array($file, $blackList)) {
+            if (in_array($data[0], $blackList)) {
                 unset($dataProvider[$key]);
             } else {
                 include_once $data[0];
diff --git a/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/magento.txt b/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/magento.txt
index 77cf93864b0bd4e172da599e9ad854c7b14a5b0a..29b5280ec6693f70c8d65a1f40e25c644897ace1 100644
--- a/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/magento.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/magento.txt
@@ -41,13 +41,11 @@ app/code/Magento/Catalog/view/base/web/js/price-utils.js
 app/code/Magento/Catalog/view/base/web/js/tier-price.js
 app/code/Magento/Catalog/view/frontend/requirejs-config.js
 app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js
-app/code/Magento/Catalog/view/frontend/web/js/compare.js
 app/code/Magento/Catalog/view/frontend/web/js/gallery.js
 app/code/Magento/Catalog/view/frontend/web/js/list.js
 app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js
 app/code/Magento/Catalog/view/frontend/web/js/related-products.js
 app/code/Magento/Catalog/view/frontend/web/js/upsell-products.js
-app/code/Magento/Catalog/view/frontend/web/js/view/compare-products.js
 app/code/Magento/Catalog/view/frontend/web/js/view/image.js
 app/code/Magento/Catalog/view/frontend/web/js/zoom.js
 app/code/Magento/Catalog/view/frontend/web/product/view/validation.js
@@ -218,16 +216,16 @@ app/code/Magento/PageCache/view/frontend/web/js/page-cache.js
 app/code/Magento/Payment/view/adminhtml/web/transparent.js
 app/code/Magento/Payment/view/frontend/requirejs-config.js
 app/code/Magento/Payment/view/frontend/web/cc-type.js
-app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/credit-card-data.js
-app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/credit-card-number-validator.js
-app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/credit-card-number-validator/credit-card-type.js
-app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/credit-card-number-validator/luhn10-validator.js
-app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/cvv-validator.js
-app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator.js
-app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator/expiration-month-validator.js
-app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator/expiration-year-validator.js
-app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator/parse-date.js
-app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/validator.js
+app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/credit-card-data.js
+app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/credit-card-number-validator.js
+app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/credit-card-number-validator/credit-card-type.js
+app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/credit-card-number-validator/luhn10-validator.js
+app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/cvv-validator.js
+app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/expiration-date-validator.js
+app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/expiration-date-validator/expiration-month-validator.js
+app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/expiration-date-validator/expiration-year-validator.js
+app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/expiration-date-validator/parse-date.js
+app/code/Magento/Payment/view/base/web/js/model/credit-card-validation/validator.js
 app/code/Magento/Payment/view/frontend/web/js/view/payment/cc-form.js
 app/code/Magento/Payment/view/frontend/web/js/view/payment/iframe.js
 app/code/Magento/Payment/view/frontend/web/js/view/payment/method-renderer/free-method.js
@@ -511,7 +509,6 @@ lib/web/mage/captcha.js
 lib/web/mage/collapsible.js
 lib/web/mage/common.js
 lib/web/mage/cookies.js
-lib/web/mage/dataPost.js
 lib/web/mage/decorate.js
 lib/web/mage/deletable-item.js
 lib/web/mage/dialog.js
@@ -603,13 +600,11 @@ vendor/magento/module-catalog/view/base/web/js/price-utils.js
 vendor/magento/module-catalog/view/base/web/js/tier-price.js
 vendor/magento/module-catalog/view/frontend/requirejs-config.js
 vendor/magento/module-catalog/view/frontend/web/js/catalog-add-to-cart.js
-vendor/magento/module-catalog/view/frontend/web/js/compare.js
 vendor/magento/module-catalog/view/frontend/web/js/gallery.js
 vendor/magento/module-catalog/view/frontend/web/js/list.js
 vendor/magento/module-catalog/view/frontend/web/js/product/list/toolbar.js
 vendor/magento/module-catalog/view/frontend/web/js/related-products.js
 vendor/magento/module-catalog/view/frontend/web/js/upsell-products.js
-vendor/magento/module-catalog/view/frontend/web/js/view/compare-products.js
 vendor/magento/module-catalog/view/frontend/web/js/view/image.js
 vendor/magento/module-catalog/view/frontend/web/js/zoom.js
 vendor/magento/module-catalog/view/frontend/web/product/view/validation.js
@@ -776,16 +771,16 @@ vendor/magento/module-page-cache/view/frontend/web/js/page-cache.js
 vendor/magento/module-payment/view/adminhtml/web/transparent.js
 vendor/magento/module-payment/view/frontend/requirejs-config.js
 vendor/magento/module-payment/view/frontend/web/cc-type.js
-vendor/magento/module-payment/view/frontend/web/js/model/credit-card-validation/credit-card-data.js
-vendor/magento/module-payment/view/frontend/web/js/model/credit-card-validation/credit-card-number-validator.js
-vendor/magento/module-payment/view/frontend/web/js/model/credit-card-validation/credit-card-number-validator/credit-card-type.js
-vendor/magento/module-payment/view/frontend/web/js/model/credit-card-validation/credit-card-number-validator/luhn10-validator.js
-vendor/magento/module-payment/view/frontend/web/js/model/credit-card-validation/cvv-validator.js
-vendor/magento/module-payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator.js
-vendor/magento/module-payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator/expiration-month-validator.js
-vendor/magento/module-payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator/expiration-year-validator.js
-vendor/magento/module-payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator/parse-date.js
-vendor/magento/module-payment/view/frontend/web/js/model/credit-card-validation/validator.js
+vendor/magento/module-payment/view/base/web/js/model/credit-card-validation/credit-card-data.js
+vendor/magento/module-payment/view/base/web/js/model/credit-card-validation/credit-card-number-validator.js
+vendor/magento/module-payment/view/base/web/js/model/credit-card-validation/credit-card-number-validator/credit-card-type.js
+vendor/magento/module-payment/view/base/web/js/model/credit-card-validation/credit-card-number-validator/luhn10-validator.js
+vendor/magento/module-payment/view/base/web/js/model/credit-card-validation/cvv-validator.js
+vendor/magento/module-payment/view/base/web/js/model/credit-card-validation/expiration-date-validator.js
+vendor/magento/module-payment/view/base/web/js/model/credit-card-validation/expiration-date-validator/expiration-month-validator.js
+vendor/magento/module-payment/view/base/web/js/model/credit-card-validation/expiration-date-validator/expiration-year-validator.js
+vendor/magento/module-payment/view/base/web/js/model/credit-card-validation/expiration-date-validator/parse-date.js
+vendor/magento/module-payment/view/base/web/js/model/credit-card-validation/validator.js
 vendor/magento/module-payment/view/frontend/web/js/view/payment/cc-form.js
 vendor/magento/module-payment/view/frontend/web/js/view/payment/iframe.js
 vendor/magento/module-payment/view/frontend/web/js/view/payment/method-renderer/free-method.js
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/CopyrightTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/CopyrightTest.php
index 582a63ceb19ed8dbb079fdc19abb2358004d891a..a1ede987dac78a6f5de8a2519d481bb81490ac16 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/CopyrightTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/CopyrightTest.php
@@ -27,7 +27,7 @@ class CopyrightTest extends \PHPUnit_Framework_TestCase
 
     public function copyrightDataProvider()
     {
-        $blackList = include __DIR__ . '/_files/copyright/blacklist.php';
+        $blackList = $this->getFilesData('blacklist*.php');
 
         $changedFiles = [];
         foreach (glob(__DIR__ . '/../_files/changed_files*') as $listFile) {
@@ -56,4 +56,18 @@ class CopyrightTest extends \PHPUnit_Framework_TestCase
         );
         return $changedFiles;
     }
+
+    /**
+     * @param string $filePattern
+     * @return array
+     */
+    protected function getFilesData($filePattern)
+    {
+        $result = [];
+        foreach (glob(__DIR__ . '/_files/copyright/' . $filePattern) as $file) {
+            $fileData = include $file;
+            $result = array_merge($result, $fileData);
+        }
+        return $result;
+    }
 }
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/UnsecureFunctionsUsageTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/UnsecureFunctionsUsageTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6b18eb2b71478463e39e815dec078478c4034a07
--- /dev/null
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/UnsecureFunctionsUsageTest.php
@@ -0,0 +1,167 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Test\Legacy;
+
+use Magento\Framework\App\Utility\Files;
+
+/**
+ * Tests to detect unsecure functions usage
+ */
+class UnsecureFunctionsUsageTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * File extensions pattern to search for
+     *
+     * @var string
+     */
+    private $fileExtensions = '/\.(php|phtml|js)$/';
+
+    /**
+     * Php unsecure functions to detect
+     *
+     * @var array
+     */
+    private $phpUnsecureFunctions = [
+        'unserialize',
+        'serialize',
+        'eval',
+        'md5',
+        'srand',
+        'mt_srand'
+    ];
+
+    /**
+     * JS unsecure functions to detect
+     *
+     * @var array
+     */
+    private $jsUnsecureFunctions = [];
+
+    /**
+     * Detect unsecure functions usage for changed files in whitelist with the exception of blacklist
+     *
+     * @return void
+     */
+    public function testUnsecureFunctionsUsage()
+    {
+        $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this);
+        $invoker(
+            function ($fileName) {
+                $result = '';
+                $errorMessage = 'The following functions are non secure and should be avoided: '
+                    . implode(', ', $this->phpUnsecureFunctions)
+                    . ' for PHP';
+                if (!empty($this->jsUnsecureFunctions)) {
+                    $errorMessage .= ', and '
+                        . implode(', ', $this->jsUnsecureFunctions)
+                        . ' for JavaScript';
+                }
+                $errorMessage .= ".\n";
+                $regexp = $this->getRegexpByFileExtension(pathinfo($fileName, PATHINFO_EXTENSION));
+                if ($regexp) {
+                    $matches = preg_grep(
+                        $regexp,
+                        file($fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)
+                    );
+                    if (!empty($matches)) {
+                        foreach (array_keys($matches) as $line) {
+                            $result .= $fileName . ':' . ($line + 1) . "\n";
+                        }
+                    }
+                    $this->assertEmpty($result, $errorMessage . $result);
+                }
+            },
+            $this->unsecureFunctionsUsageDataProvider()
+        );
+    }
+
+    /**
+     * Data provider for test
+     *
+     * @return array
+     */
+    public function unsecureFunctionsUsageDataProvider()
+    {
+        $fileExtensions = $this->fileExtensions;
+        $directoriesToScan = Files::init()->readLists(__DIR__ . '/_files/security/whitelist.txt');
+        $blackListFiles = include __DIR__ . '/_files/security/blacklist.php';
+
+        $filesToVerify = [];
+        foreach (glob(__DIR__ . '/../_files/changed_files*') as $listFile) {
+            $filesToVerify = array_merge(
+                $filesToVerify,
+                file($listFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)
+            );
+        }
+        array_walk(
+            $filesToVerify,
+            function (&$file) {
+                $file = [BP . '/' . $file];
+            }
+        );
+        $filesToVerify = array_filter(
+            $filesToVerify,
+            function ($path) use ($directoriesToScan, $fileExtensions, $blackListFiles) {
+                if (!file_exists($path[0])) {
+                    return false;
+                }
+                $path = realpath($path[0]);
+                foreach ($directoriesToScan as $directory) {
+                    $directory = realpath($directory);
+                    if (strpos($path, $directory) === 0) {
+                        if (preg_match($fileExtensions, $path)) {
+                            foreach ($blackListFiles as $blackListFile) {
+                                if (preg_match($blackListFile, $path)) {
+                                    return false;
+                                }
+                            }
+                            return true;
+                        }
+                    }
+                }
+                return false;
+            }
+        );
+        return $filesToVerify;
+    }
+
+    /**
+     * Get regular expression by file extension
+     *
+     * @param string $fileExtension
+     * @return string|bool
+     */
+    private function getRegexpByFileExtension($fileExtension)
+    {
+        $regexp = false;
+        if ($fileExtension == 'php') {
+            $regexp = $this->prepareRegexp($this->phpUnsecureFunctions);
+        } elseif ($fileExtension == 'js') {
+            $regexp = $this->prepareRegexp($this->jsUnsecureFunctions);
+        } elseif ($fileExtension == 'phtml') {
+            $regexp = $this->prepareRegexp($this->phpUnsecureFunctions + $this->jsUnsecureFunctions);
+        }
+        return $regexp;
+    }
+
+    /**
+     * Prepare regular expression for unsecure function names
+     *
+     * @param array $functions
+     * @return string
+     */
+    private function prepareRegexp(array $functions)
+    {
+        if (empty($functions)) {
+            return '';
+        }
+        $regexArray = [];
+        foreach ($functions as $function) {
+            $regexArray[] = '\b' . $function . '\b\(';
+        }
+        return '/' . implode('|', $regexArray) . '/i';
+    }
+}
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 78342c886de968a02ceed79c215c5dc26ddd9928..f5ae2f2dfd67b5628326149d6d28f055c9d2485f 100755
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
@@ -785,6 +785,7 @@ return [
     ['Mage_Core_Model_Config_Fieldset', 'Magento\Core\Model\Fieldset\Config'],
     ['Mage_Core_Model_Config_Options', 'Magento\Framework\Filesystem'],
     ['Magento\Framework\App\Dir', 'Magento\Framework\Filesystem'],
+    ['Magento\Framework\EntityManager\CustomAttributesMapper'],
     ['Magento\Framework\Filesystem\Adapter\Local', 'Magento\Framework\Filesystem\Driver\File'],
     ['Magento\Framework\Filesystem\Adapter\Zlib', 'Magento\Framework\Filesystem\Driver\Zlib'],
     ['Magento\Framework\Filesystem\AdapterInterface'],
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/blacklist.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/blacklist.php
new file mode 100644
index 0000000000000000000000000000000000000000..f055f0a732c664dd8ed109d7ec52b178c537a4d0
--- /dev/null
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/blacklist.php
@@ -0,0 +1,8 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+return [
+    '/Test\/Unit/'
+];
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/whitelist.txt b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/whitelist.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2567475de6a035b2a369ac342c076ce1e5cad07d
--- /dev/null
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/whitelist.txt
@@ -0,0 +1,4 @@
+module * /
+library * /
+setup
+pub
\ No newline at end of file
diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt
index 852bb6707cd84154f8e23c878fbd04ea63fb8295..56e0d51516c2632a28acd50ca2c3999e984720df 100644
--- a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt
@@ -1,5 +1,3 @@
-app/code/Magento
-lib/internal/Magento
 Magento/Adminhtml
 Magento/Authorizenet/Model
 Magento/Backend
@@ -160,3 +158,42 @@ Magento/Sales/Setup
 Magento/SalesRule/Setup
 Magento/Eav/Setup
 setup/src/Magento/Setup/Fixtures
+Magento/ConfigurableProduct/Setup
+Magento/Weee/Setup
+Magento/Wishlist/Setup
+Magento/CatalogUrlRewrite/Setup
+Magento/AdvancedSalesRule/Setup
+Magento/VisualMerchandiser/Setup
+Magento/Catalog/Model
+Magento/Catalog/Ui/Component/Listing
+Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Variations/Config
+Magento/Payment/Gateway/Data/Order
+Magento/ProductAlert/Controller/Unsubscribe
+Magento/Reports/Model/ResourceModel/Customer/Orders
+Magento/Sales/Model/ResourceModel/Report
+Magento/SalesRule/Model
+Magento/Search/Ui/Component/Listing/Column/Scope
+Magento/Tax/Model/Calculation
+Magento/Tax/Observer
+Magento/Vault/Model/Ui
+Magento/GroupedProduct/Model/ResourceModel/Product/Indexer/Price
+Magento/AdvancedSalesRule/Model/Rule/Condition/Product
+Magento/CmsStaging/Controller/Adminhtml/Block/Update
+Magento/Customer/Block/Widget
+Magento/Persistent/Observer
+Magento/Elasticsearch/Model/Adapter/Container
+Magento/Elasticsearch/SearchAdapter
+Magento/Staging/Model/Entity/DataProvider
+Magento/CatalogStaging/Model/Update/Grid
+Magento/Eav/Model/Api/SearchCriteria/CollectionProcessor
+Magento/Framework/App/AreaList
+Magento/Framework/App/Route/ConfigInterface
+Magento/Framework/DataObject/Copy/Config/Data
+Magento/Framework/Backup/Filesystem/Iterator
+Magento/Theme/Model/Indexer/Design
+Magento/Framework/EntityManager/Db
+Magento/Framework/Mview/Config/Data
+Magento/Framework/View/File/Collector/Override
+Magento/Framework/MessageQueue/Consumer/Config/ConsumerConfigItem
+Magento/Framework/MessageQueue/Publisher/Config/PublisherConfigItem
+Magento/Framework/MessageQueue/Topology/Config/ExchangeConfigItem
\ No newline at end of file
diff --git a/lib/internal/Magento/Framework/App/Cache/FlushCacheByTags.php b/lib/internal/Magento/Framework/App/Cache/FlushCacheByTags.php
index a739c1de8ed49d3bbc92f48dc83bae5024641a08..4abb5b66924e35d2bd996ca94d50aa862132aab8 100644
--- a/lib/internal/Magento/Framework/App/Cache/FlushCacheByTags.php
+++ b/lib/internal/Magento/Framework/App/Cache/FlushCacheByTags.php
@@ -26,21 +26,29 @@ class FlushCacheByTags
      */
     private $cacheState;
 
+    /**
+     * @var Tag\Resolver
+     */
+    private $tagResolver;
+
     /**
      * FlushCacheByTags constructor.
      *
      * @param Type\FrontendPool $cachePool
      * @param StateInterface $cacheState
      * @param array $cacheList
+     * @param Tag\Resolver $tagResolver
      */
     public function __construct(
         \Magento\Framework\App\Cache\Type\FrontendPool $cachePool,
         \Magento\Framework\App\Cache\StateInterface $cacheState,
-        array $cacheList
+        array $cacheList,
+        \Magento\Framework\App\Cache\Tag\Resolver $tagResolver
     ) {
         $this->cachePool = $cachePool;
         $this->cacheState = $cacheState;
         $this->cacheList = $cacheList;
+        $this->tagResolver = $tagResolver;
     }
 
     /**
@@ -58,9 +66,9 @@ class FlushCacheByTags
         \Magento\Framework\Model\AbstractModel $object
     ) {
         $result = $proceed($object);
-        if ($object instanceof \Magento\Framework\DataObject\IdentityInterface) {
-            $this->cleanCacheByTags($object->getIdentities());
-        }
+        $tags = $this->tagResolver->getTags($object);
+        $this->cleanCacheByTags($tags);
+
         return $result;
     }
 
@@ -78,10 +86,7 @@ class FlushCacheByTags
         \Closure $proceed,
         \Magento\Framework\Model\AbstractModel $object
     ) {
-        $tags = [];
-        if ($object instanceof \Magento\Framework\DataObject\IdentityInterface) {
-            $tags = $object->getIdentities();
-        }
+        $tags = $this->tagResolver->getTags($object);
         $result = $proceed($object);
         $this->cleanCacheByTags($tags);
         return $result;
diff --git a/lib/internal/Magento/Framework/App/Cache/Tag/Resolver.php b/lib/internal/Magento/Framework/App/Cache/Tag/Resolver.php
new file mode 100644
index 0000000000000000000000000000000000000000..1013c97da527e6a24e9ea1d4221c55e559abd381
--- /dev/null
+++ b/lib/internal/Magento/Framework/App/Cache/Tag/Resolver.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\App\Cache\Tag;
+
+/**
+ * Resolves invalidation tags for specified object using different strategies
+ */
+class Resolver
+{
+    /**
+     * Tag strategies factory
+     *
+     * @var Strategy\Factory
+     */
+    private $strategyFactory;
+
+    /**
+     * Resolver constructor.
+     *
+     * @param Strategy\Factory $factory
+     */
+    public function __construct(\Magento\Framework\App\Cache\Tag\Strategy\Factory $factory)
+    {
+        $this->strategyFactory = $factory;
+    }
+
+    /**
+     * Identify invalidation tags for the object using custom strategies
+     *
+     * @param object $object
+     * @throws \InvalidArgumentException
+     * @return array
+     */
+    public function getTags($object)
+    {
+        if (!is_object($object)) {
+            throw new \InvalidArgumentException('Provided argument is not an object');
+        }
+
+        return $this->strategyFactory->getStrategy($object)->getTags($object);
+    }
+}
diff --git a/lib/internal/Magento/Framework/App/Cache/Tag/Strategy/Dummy.php b/lib/internal/Magento/Framework/App/Cache/Tag/Strategy/Dummy.php
new file mode 100644
index 0000000000000000000000000000000000000000..84f448149991c9a259f6cff69c468beb036bfdca
--- /dev/null
+++ b/lib/internal/Magento/Framework/App/Cache/Tag/Strategy/Dummy.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\App\Cache\Tag\Strategy;
+
+use Magento\Framework\App\Cache\Tag\StrategyInterface;
+
+/**
+ * Always return empty tags array
+ */
+class Dummy implements StrategyInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getTags($object)
+    {
+        if (!is_object($object)) {
+            throw new \InvalidArgumentException('Provided argument is not an object');
+        }
+
+        return [];
+    }
+}
diff --git a/lib/internal/Magento/Framework/App/Cache/Tag/Strategy/Factory.php b/lib/internal/Magento/Framework/App/Cache/Tag/Strategy/Factory.php
new file mode 100644
index 0000000000000000000000000000000000000000..1c152407163cd6412faf604f440d86fd2c6577d4
--- /dev/null
+++ b/lib/internal/Magento/Framework/App/Cache/Tag/Strategy/Factory.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\App\Cache\Tag\Strategy;
+
+use Magento\Framework\App\Cache\Tag\StrategyInterface;
+
+/**
+ * Creates strategies using configuration
+ */
+class Factory
+{
+    /**
+     * Default strategy for objects which implement Identity interface
+     *
+     * @var StrategyInterface
+     */
+    private $identifierStrategy;
+
+    /**
+     * Strategy for objects which don't implement Identity interface
+     *
+     * @var StrategyInterface
+     */
+    private $dummyStrategy;
+
+    /**
+     * Strategies map
+     *
+     * @var array
+     */
+    private $customStrategies = [];
+
+    /**
+     * Factory constructor.
+     *
+     * @param Identifier $identifierStrategy
+     * @param Dummy $dummyStrategy
+     * @param array $customStrategies
+     */
+    public function __construct(
+        \Magento\Framework\App\Cache\Tag\Strategy\Identifier $identifierStrategy,
+        \Magento\Framework\App\Cache\Tag\Strategy\Dummy $dummyStrategy,
+        $customStrategies = []
+    ) {
+        $this->customStrategies = $customStrategies;
+        $this->identifierStrategy = $identifierStrategy;
+        $this->dummyStrategy = $dummyStrategy;
+    }
+
+    /**
+     * Return tag strategy for specified object
+     *
+     * @param object $object
+     * @throws \InvalidArgumentException
+     * @return \Magento\Framework\App\Cache\Tag\StrategyInterface
+     */
+    public function getStrategy($object)
+    {
+        if (!is_object($object)) {
+            throw new \InvalidArgumentException('Provided argument is not an object');
+        }
+
+        $classHierarchy = array_merge(
+            [get_class($object) => get_class($object)],
+            class_parents($object),
+            class_implements($object)
+        );
+
+        $result = array_intersect(array_keys($this->customStrategies), $classHierarchy);
+        if ($result) {
+            return $this->customStrategies[array_shift($result)];
+        }
+
+        if ($object instanceof \Magento\Framework\DataObject\IdentityInterface) {
+            return $this->identifierStrategy;
+        }
+
+        return $this->dummyStrategy;
+    }
+}
diff --git a/lib/internal/Magento/Framework/App/Cache/Tag/Strategy/Identifier.php b/lib/internal/Magento/Framework/App/Cache/Tag/Strategy/Identifier.php
new file mode 100644
index 0000000000000000000000000000000000000000..2b3de631b621481710b31aa8be339d87c4dd122f
--- /dev/null
+++ b/lib/internal/Magento/Framework/App/Cache/Tag/Strategy/Identifier.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\App\Cache\Tag\Strategy;
+
+use Magento\Framework\App\Cache\Tag\StrategyInterface;
+
+/**
+ * Produce cache tags using IdentityInterface
+ */
+class Identifier implements StrategyInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getTags($object)
+    {
+        if (!is_object($object)) {
+            throw new \InvalidArgumentException('Provided argument is not an object');
+        }
+
+        if ($object instanceof \Magento\Framework\DataObject\IdentityInterface) {
+            return $object->getIdentities();
+        }
+
+        return [];
+    }
+}
diff --git a/lib/internal/Magento/Framework/App/Cache/Tag/StrategyInterface.php b/lib/internal/Magento/Framework/App/Cache/Tag/StrategyInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..f848608b0596901133d43db3047aa162068e8916
--- /dev/null
+++ b/lib/internal/Magento/Framework/App/Cache/Tag/StrategyInterface.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\App\Cache\Tag;
+
+/**
+ * Invalidation tags generator
+ */
+interface StrategyInterface
+{
+    /**
+     * Return invalidation tags for specified object
+     *
+     * @param object $object
+     * @throws \InvalidArgumentException
+     * @return array
+     */
+    public function getTags($object);
+}
diff --git a/lib/internal/Magento/Framework/App/Router/Base.php b/lib/internal/Magento/Framework/App/Router/Base.php
index 9be178838732387a42b623ed3ece641478674f97..91ae3fc3664ec874f5bc9363582b50fcff88e6ad 100644
--- a/lib/internal/Magento/Framework/App/Router/Base.php
+++ b/lib/internal/Magento/Framework/App/Router/Base.php
@@ -7,9 +7,6 @@
  */
 namespace Magento\Framework\App\Router;
 
-use Magento\Framework\App\RequestInterface;
-use Magento\Store\Model\ScopeInterface;
-
 /**
  * @SuppressWarnings(PHPMD.TooManyFields)
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Action/AbstractActionTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Action/AbstractActionTest.php
index af7f904418f266b4dfc99a4da6ca943bf029b7a5..5a47246ddd3f975cdba98051c4b24f7da2fdb951 100644
--- a/lib/internal/Magento/Framework/App/Test/Unit/Action/AbstractActionTest.php
+++ b/lib/internal/Magento/Framework/App/Test/Unit/Action/AbstractActionTest.php
@@ -36,7 +36,7 @@ class AbstractActionTest extends \PHPUnit_Framework_TestCase
             ->setMethods(['setRefererOrBaseUrl'])
             ->disableOriginalConstructor()
             ->getMock();
-        $this->redirectFactory = $this->getMockBuilder(\Magento\Backend\Model\View\Result\RedirectFactory::class)
+        $this->redirectFactory = $this->getMockBuilder(\Magento\Framework\Controller\Result\RedirectFactory::class)
             ->setMethods(['create'])
             ->disableOriginalConstructor()
             ->getMock();
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Cache/FlushCacheByTagsTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Cache/FlushCacheByTagsTest.php
index c3230bc23abc8c00489cf1b6eae02ce0b0d8cdd5..afc745f33c5a942ee9bb2c80e0779772c49ebc27 100644
--- a/lib/internal/Magento/Framework/App/Test/Unit/Cache/FlushCacheByTagsTest.php
+++ b/lib/internal/Magento/Framework/App/Test/Unit/Cache/FlushCacheByTagsTest.php
@@ -18,6 +18,11 @@ class FlushCacheByTagsTest extends \PHPUnit_Framework_TestCase
      */
     private $frontendPool;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\Cache\Tag\Resolver
+     */
+    private $tagResolver;
+
     /**
      * @var \Magento\Framework\App\Cache\FlushCacheByTags
      */
@@ -27,10 +32,13 @@ class FlushCacheByTagsTest extends \PHPUnit_Framework_TestCase
     {
         $this->cacheState = $this->getMockForAbstractClass(\Magento\Framework\App\Cache\StateInterface::class);
         $this->frontendPool = $this->getMock(\Magento\Framework\App\Cache\Type\FrontendPool::class, [], [], '', false);
+        $this->tagResolver = $this->getMock(\Magento\Framework\App\Cache\Tag\Resolver::class, [], [], '', false);
+
         $this->plugin = new \Magento\Framework\App\Cache\FlushCacheByTags(
             $this->frontendPool,
             $this->cacheState,
-            ['test']
+            ['test'],
+            $this->tagResolver
         );
 
     }
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/ResolverTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/ResolverTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..5b5e14f620e2fb8ec4e0b76d6657b43c1ca52df4
--- /dev/null
+++ b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/ResolverTest.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\App\Test\Unit\Cache\Tag;
+
+use \Magento\Framework\App\Cache\Tag\Resolver;
+
+class ResolverTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\Cache\Tag\Strategy\Factory
+     */
+    private $strategyFactory;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\Cache\Tag\StrategyInterface
+     */
+    private $strategy;
+
+    /**
+     * @var Resolver
+     */
+    private $model;
+
+    protected function setUp()
+    {
+        $this->strategyFactory = $this->getMock(
+            \Magento\Framework\App\Cache\Tag\Strategy\Factory::class,
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->strategy = $this->getMockForAbstractClass(\Magento\Framework\App\Cache\Tag\StrategyInterface::class);
+
+        $this->strategyFactory->expects($this->any())
+            ->method('getStrategy')
+            ->willReturn($this->strategy);
+
+        $this->model = new Resolver($this->strategyFactory);
+    }
+
+    public function testGetTagsForNotObject()
+    {
+        $this->setExpectedException(\InvalidArgumentException::class, 'Provided argument is not an object');
+        $this->model->getTags('some scalar');
+    }
+
+    public function testGetTagsForObject()
+    {
+        $strategyReturnValue = ['test tag'];
+        $object = new \StdClass;
+        $this->strategy->expects($this->once())
+            ->method('getTags')
+            ->with($object)
+            ->willReturn($strategyReturnValue);
+
+        $this->assertEquals($strategyReturnValue, $this->model->getTags($object));
+    }
+}
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/DummyTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/DummyTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..4bc2bf12947607a44f6d485f8bd30d332bd0a2c6
--- /dev/null
+++ b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/DummyTest.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\App\Test\Unit\Cache\Tag\Strategy;
+
+use \Magento\Framework\App\Cache\Tag\Strategy\Dummy;
+
+class DummyTest extends \PHPUnit_Framework_TestCase
+{
+
+    private $model;
+
+    protected function setUp()
+    {
+        $this->model = new Dummy();
+    }
+
+    public function testGetTagsWithScalar()
+    {
+        $this->setExpectedException(\InvalidArgumentException::class, 'Provided argument is not an object');
+        $this->model->getTags('scalar');
+    }
+
+    public function testGetTagsWithObject()
+    {
+        $emptyArray = [];
+
+        $this->assertEquals($emptyArray, $this->model->getTags(new \StdClass));
+
+        $identityInterface = $this->getMockForAbstractClass(\Magento\Framework\DataObject\IdentityInterface::class);
+        $this->assertEquals($emptyArray, $this->model->getTags($identityInterface));
+    }
+}
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/FactoryTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/FactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e36ddc92cfe3f3a053e73318815ce4d0e7436dd8
--- /dev/null
+++ b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/FactoryTest.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\App\Test\Unit\Cache\Tag\Strategy;
+
+use \Magento\Framework\App\Cache\Tag\Strategy\Factory;
+
+class FactoryTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\Cache\Tag\Strategy\Identifier
+     */
+    private $identifierStrategy;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\Cache\Tag\Strategy\Dummy
+     */
+    private $dummyStrategy;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\Cache\Tag\StrategyInterface
+     */
+    private $customStrategy;
+
+    /**
+     * @var Factory
+     */
+    private $model;
+
+    protected function setUp()
+    {
+        $this->identifierStrategy = $this->getMock(
+            \Magento\Framework\App\Cache\Tag\Strategy\Identifier::class,
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->dummyStrategy = $this->getMock(
+            \Magento\Framework\App\Cache\Tag\Strategy\Dummy::class,
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->customStrategy = $this->getMockForAbstractClass(
+            \Magento\Framework\App\Cache\Tag\StrategyInterface::class
+        );
+
+        $this->model = new Factory(
+            $this->identifierStrategy,
+            $this->dummyStrategy,
+            ['PDO' => $this->customStrategy]
+        );
+    }
+
+    public function testGetStrategyWithScalar()
+    {
+        $this->setExpectedException(\InvalidArgumentException::class, 'Provided argument is not an object');
+        $this->model->getStrategy('some scalar');
+    }
+
+    public function testGetStrategyWithObject()
+    {
+        $this->assertEquals($this->dummyStrategy, $this->model->getStrategy(new \StdClass));
+    }
+
+    public function testGetStrategyWithIdentityInterface()
+    {
+        $object = $this->getMockForAbstractClass(\Magento\Framework\DataObject\IdentityInterface::class);
+
+        $this->assertEquals($this->identifierStrategy, $this->model->getStrategy($object));
+    }
+
+    public function testGetStrategyForCustomClass()
+    {
+        $object = $this->getMockForAbstractClass('\PDO', [], '', false, false, false, []);
+
+        $this->assertEquals($this->customStrategy, $this->model->getStrategy($object));
+    }
+}
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/IdentifierTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/IdentifierTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..04ca03326148348d27cfa17d4a7f12d784ed9aba
--- /dev/null
+++ b/lib/internal/Magento/Framework/App/Test/Unit/Cache/Tag/Strategy/IdentifierTest.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\App\Test\Unit\Cache\Tag\Strategy;
+
+use \Magento\Framework\App\Cache\Tag\Strategy\Identifier;
+
+class IdentifierTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Identifier
+     */
+    private $model;
+
+    protected function setUp()
+    {
+        $this->model = new Identifier;
+    }
+
+    public function testGetWithScalar()
+    {
+        $this->setExpectedException(\InvalidArgumentException::class, 'Provided argument is not an object');
+        $this->model->getTags('scalar');
+    }
+
+    public function testGetTagsWithObject()
+    {
+        $this->assertEquals([], $this->model->getTags(new \StdClass));
+    }
+
+    public function testGetTagsWithIdentityInterface()
+    {
+        $object = $this->getMockForAbstractClass(\Magento\Framework\DataObject\IdentityInterface::class);
+
+        $identities = ['id1', 'id2'];
+
+        $object->expects($this->once())
+            ->method('getIdentities')
+            ->willReturn($identities);
+
+        $this->assertEquals($identities, $this->model->getTags($object));
+    }
+}
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Router/BaseTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Router/BaseTest.php
index bf49959b67007a03f8587dd02126d43050b6c54c..e17e3990f8695d97fd5e42b28d958efcac9a9d27 100644
--- a/lib/internal/Magento/Framework/App/Test/Unit/Router/BaseTest.php
+++ b/lib/internal/Magento/Framework/App/Test/Unit/Router/BaseTest.php
@@ -80,7 +80,7 @@ class BaseTest extends \Magento\Framework\TestFramework\Unit\BaseTestCase
         $moduleFrontName = 'module front name';
         $actionPath = 'action path';
         $actionName = 'action name';
-        $actionClassName = \Magento\Cms\Controller\Index\Index::class;
+        $actionClassName = \Magento\Framework\App\Action\Action::class;
         $moduleName = 'module name';
         $moduleList = [$moduleName];
 
@@ -109,7 +109,7 @@ class BaseTest extends \Magento\Framework\TestFramework\Unit\BaseTestCase
         $moduleFrontName = 'module front name';
         $actionPath = 'action path';
         $actionName = 'action name';
-        $actionClassName = \Magento\Cms\Controller\Index\Index::class;
+        $actionClassName = \Magento\Framework\App\Action\Action::class;
         $moduleName = 'module name';
         $moduleList = [$moduleName];
         $paramList = $moduleFrontName . '/' . $actionPath . '/' . $actionName . '/key/val/key2/val2/';
@@ -137,7 +137,7 @@ class BaseTest extends \Magento\Framework\TestFramework\Unit\BaseTestCase
         $moduleFrontName = 'module front name';
         $actionPath = 'action path';
         $actionName = 'action name';
-        $actionClassName = \Magento\Cms\Controller\Index\Index::class;
+        $actionClassName = \Magento\Framework\App\Action\Action::class;
         $moduleName = 'module name';
         $moduleList = [$moduleName];
 
@@ -169,7 +169,7 @@ class BaseTest extends \Magento\Framework\TestFramework\Unit\BaseTestCase
         $moduleFrontName = 'module front name';
         $actionPath = 'action path';
         $actionName = 'action name';
-        $actionClassName = \Magento\Cms\Controller\Index\Index::class;
+        $actionClassName = \Magento\Framework\App\Action\Action::class;
         $emptyModuleList = [];
 
         // Stubs
@@ -192,7 +192,7 @@ class BaseTest extends \Magento\Framework\TestFramework\Unit\BaseTestCase
         $moduleFrontName = 'module front name';
         $actionPath = 'action path';
         $actionName = 'action name';
-        $actionClassName = \Magento\Cms\Controller\Index\Index::class;
+        $actionClassName = \Magento\Framework\App\Action\Action::class;
         $moduleName = 'module name';
         $moduleList = [$moduleName];
 
diff --git a/lib/internal/Magento/Framework/Backup/Filesystem.php b/lib/internal/Magento/Framework/Backup/Filesystem.php
index 2d77fa164b0a4ec228288a011de95e3c3ea5dee8..7fe469441eeaf6bd53a5144a5180669ff47b4583 100644
--- a/lib/internal/Magento/Framework/Backup/Filesystem.php
+++ b/lib/internal/Magento/Framework/Backup/Filesystem.php
@@ -316,7 +316,7 @@ class Filesystem extends AbstractBackup
         if (!$this->rollBackFtp) {
             $this->rollBackFtp = ObjectManager::getInstance()->create(
                 \Magento\Framework\Backup\Filesystem\Rollback\Ftp::class,
-                [$this]
+                ['snapshotObject' => $this]
             );
         }
 
@@ -332,7 +332,7 @@ class Filesystem extends AbstractBackup
         if (!$this->rollBackFs) {
             $this->rollBackFs = ObjectManager::getInstance()->create(
                 \Magento\Framework\Backup\Filesystem\Rollback\Fs::class,
-                [$this]
+                ['snapshotObject' => $this]
             );
         }
 
diff --git a/lib/internal/Magento/Framework/Communication/Config/ReflectionGenerator.php b/lib/internal/Magento/Framework/Communication/Config/ReflectionGenerator.php
index 4f9277af752eb7f8f00a2a57ae246471cdc9ce4b..c1852d3dd8342519cb4ac9df28ac2dfdb1fedb07 100644
--- a/lib/internal/Magento/Framework/Communication/Config/ReflectionGenerator.php
+++ b/lib/internal/Magento/Framework/Communication/Config/ReflectionGenerator.php
@@ -14,6 +14,7 @@ use Magento\Framework\Reflection\MethodsMap;
 class ReflectionGenerator
 {
     const DEFAULT_HANDLER = 'defaultHandler';
+
     /**
      * @var MethodsMap
      */
@@ -79,4 +80,23 @@ class ReflectionGenerator
                 ?: [self::DEFAULT_HANDLER => $methodMetadata[Config::SCHEMA_METHOD_HANDLER]]
         ];
     }
+
+    /**
+     * Generate topic name based on service type and method name.
+     *
+     * Perform the following conversion:
+     * \Magento\Customer\Api\RepositoryInterface + getById => magento.customer.api.repositoryInterface.getById
+     *
+     * @param string $typeName
+     * @param string $methodName
+     * @return string
+     */
+    public function generateTopicName($typeName, $methodName)
+    {
+        $parts = explode('\\', ltrim($typeName, '\\'));
+        foreach ($parts as &$part) {
+            $part = lcfirst($part);
+        }
+        return implode('.', $parts) . '.' . $methodName;
+    }
 }
diff --git a/lib/internal/Magento/Framework/Composer/Remove.php b/lib/internal/Magento/Framework/Composer/Remove.php
index 66e0063302bf41b32db83f9772ed41284038508d..6a2f8c3da00a5f543670616516881505aa6642ad 100644
--- a/lib/internal/Magento/Framework/Composer/Remove.php
+++ b/lib/internal/Magento/Framework/Composer/Remove.php
@@ -45,7 +45,8 @@ class Remove
         return $composerApplication->runComposerCommand(
             [
                 'command' => 'remove',
-                'packages' => $packages
+                'packages' => $packages,
+                '--no-update' => true,
             ]
         );
     }
diff --git a/lib/internal/Magento/Framework/Data/Argument/Interpreter/ArrayType.php b/lib/internal/Magento/Framework/Data/Argument/Interpreter/ArrayType.php
index 24b321c689dc8dc78573f99c5a0e16790a53f5c8..d714caa1724f07c3aab05de714048e8ec72a6a80 100644
--- a/lib/internal/Magento/Framework/Data/Argument/Interpreter/ArrayType.php
+++ b/lib/internal/Magento/Framework/Data/Argument/Interpreter/ArrayType.php
@@ -39,9 +39,85 @@ class ArrayType implements InterpreterInterface
             throw new \InvalidArgumentException('Array items are expected.');
         }
         $result = [];
+        $items = $this->sortItems($items);
         foreach ($items as $itemKey => $itemData) {
             $result[$itemKey] = $this->itemInterpreter->evaluate($itemData);
         }
         return $result;
     }
+
+    /**
+     * Sort items by sort order attribute.
+     *
+     * @param array $items
+     * @return array
+     */
+    private function sortItems($items)
+    {
+        $sortOrderDefined = $this->isSortOrderDefined($items);
+        if ($sortOrderDefined) {
+            $indexedItems = [];
+            foreach ($items as $key => $item) {
+                $indexedItems[] = ['key' => $key, 'item' => $item];
+            }
+            uksort(
+                $indexedItems,
+                function ($firstItemKey, $secondItemKey) use ($indexedItems) {
+                    return $this->compareItems($firstItemKey, $secondItemKey, $indexedItems);
+                }
+            );
+            // Convert array of sorted items back to initial format
+            $items = [];
+            foreach ($indexedItems as $indexedItem) {
+                $items[$indexedItem['key']] = $indexedItem['item'];
+            }
+        }
+        return $items;
+    }
+
+    /**
+     * Compare sortOrder of item
+     *
+     * @param mixed $firstItemKey
+     * @param mixed $secondItemKey
+     * @param array $indexedItems
+     * @return int
+     */
+    private function compareItems($firstItemKey, $secondItemKey, $indexedItems)
+    {
+        $firstItem = $indexedItems[$firstItemKey]['item'];
+        $secondItem = $indexedItems[$secondItemKey]['item'];
+        $firstValue = 0;
+        $secondValue = 0;
+        if (isset($firstItem['sortOrder'])) {
+            $firstValue = intval($firstItem['sortOrder']);
+        }
+
+        if (isset($secondItem['sortOrder'])) {
+            $secondValue = intval($secondItem['sortOrder']);
+        }
+
+        if ($firstValue == $secondValue) {
+            // These keys reflect initial relative position of items.
+            // Allows stable sort for items with equal 'sortOrder'
+            return $firstItemKey < $secondItemKey ? -1 : 1;
+        }
+        return $firstValue < $secondValue ? -1 : 1;
+    }
+
+    /**
+     * Determine if a sort order exists for any of the items.
+     *
+     * @param array $items
+     * @return bool
+     */
+    private function isSortOrderDefined($items)
+    {
+        foreach ($items as $itemData) {
+            if (isset($itemData['sortOrder'])) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
diff --git a/lib/internal/Magento/Framework/Data/Test/Unit/Argument/Interpreter/ArrayTypeTest.php b/lib/internal/Magento/Framework/Data/Test/Unit/Argument/Interpreter/ArrayTypeTest.php
index 17bc5aef5def7d34679a47eb0d714f1fc2a99ea4..e1bc7528cbe1a00a0d5abebb2739cf9a83c7f43a 100644
--- a/lib/internal/Magento/Framework/Data/Test/Unit/Argument/Interpreter/ArrayTypeTest.php
+++ b/lib/internal/Magento/Framework/Data/Test/Unit/Argument/Interpreter/ArrayTypeTest.php
@@ -87,6 +87,56 @@ class ArrayTypeTest extends \PHPUnit_Framework_TestCase
                     'key3' => '-value 3-',
                 ],
             ],
+            'sorted array items' => [
+                [
+                    'item' => [
+                        'key1' => ['value' => 'value 1', 'sortOrder' => 50],
+                        'key2' => ['value' => 'value 2'],
+                        'key3' => ['value' => 'value 3', 'sortOrder' => 10],
+                        'key4' => ['value' => 'value 4'],
+                    ],
+                ],
+                [
+                    'key2' => '-value 2-',
+                    'key4' => '-value 4-',
+                    'key3' => '-value 3-',
+                    'key1' => '-value 1-',
+                ],
+            ],
+            'pre-sorted array items' => [
+                [
+                    'item' => [
+                        'key1' => ['value' => 'value 1'],
+                        'key4' => ['value' => 'value 4'],
+                        'key2' => ['value' => 'value 2', 'sortOrder' => 10],
+                        'key3' => ['value' => 'value 3'],
+                    ],
+                ],
+                [
+                    'key1' => '-value 1-',
+                    'key4' => '-value 4-',
+                    'key3' => '-value 3-',
+                    'key2' => '-value 2-',
+                ],
+            ],
+            'sort order edge case values' => [
+                [
+                    'item' => [
+                        'key1' => ['value' => 'value 1', 'sortOrder' => 101],
+                        'key4' => ['value' => 'value 4'],
+                        'key2' => ['value' => 'value 2', 'sortOrder' => -10],
+                        'key3' => ['value' => 'value 3'],
+                        'key5' => ['value' => 'value 5', 'sortOrder' => 20],
+                    ],
+                ],
+                [
+                    'key2' => '-value 2-',
+                    'key4' => '-value 4-',
+                    'key3' => '-value 3-',
+                    'key5' => '-value 5-',
+                    'key1' => '-value 1-',
+                ],
+            ],
         ];
     }
 }
diff --git a/lib/internal/Magento/Framework/EntityManager/Db/CreateRow.php b/lib/internal/Magento/Framework/EntityManager/Db/CreateRow.php
index f4362e4d4a210defe41a380b30516c93130e6751..5eeb1d948ba39b7e8a1a8e3c942eb8a21009cadf 100644
--- a/lib/internal/Magento/Framework/EntityManager/Db/CreateRow.php
+++ b/lib/internal/Magento/Framework/EntityManager/Db/CreateRow.php
@@ -50,11 +50,12 @@ class CreateRow
     {
         $output = [];
         foreach ($connection->describeTable($metadata->getEntityTable()) as $column) {
-
-            if ($column['DEFAULT'] == 'CURRENT_TIMESTAMP') {
+            $columnName = strtolower($column['COLUMN_NAME']);
+            if ($this->canNotSetTimeStamp($columnName, $column, $data)) {
                 continue;
             }
-            if (isset($data[strtolower($column['COLUMN_NAME'])])) {
+
+            if (isset($data[$columnName])) {
                 $output[strtolower($column['COLUMN_NAME'])] = $data[strtolower($column['COLUMN_NAME'])];
             } elseif ($column['DEFAULT'] === null) {
                 $output[strtolower($column['COLUMN_NAME'])] = null;
@@ -66,6 +67,18 @@ class CreateRow
         return $output;
     }
 
+    /**
+     * @param string $columnName
+     * @param string $column
+     * @param array $data
+     * @return bool
+     */
+    private function canNotSetTimeStamp($columnName, $column, array $data)
+    {
+        return $column['DEFAULT'] == 'CURRENT_TIMESTAMP' && !isset($data[$columnName])
+        && empty($column['NULLABLE']);
+    }
+
     /**
      * @param string $entityType
      * @param array $data
diff --git a/lib/internal/Magento/Framework/EntityManager/Db/UpdateRow.php b/lib/internal/Magento/Framework/EntityManager/Db/UpdateRow.php
index 3f65774cf10a615d7cfd95b30b06b0fb1ccd4a1e..0c9189261bc45e1b427fc2bffcdde71d27fc8571 100644
--- a/lib/internal/Magento/Framework/EntityManager/Db/UpdateRow.php
+++ b/lib/internal/Magento/Framework/EntityManager/Db/UpdateRow.php
@@ -50,11 +50,12 @@ class UpdateRow
     {
         $output = [];
         foreach ($connection->describeTable($metadata->getEntityTable()) as $column) {
-            if ($column['DEFAULT'] == 'CURRENT_TIMESTAMP' || $column['IDENTITY']) {
+            $columnName = strtolower($column['COLUMN_NAME']);
+            if ($this->canNotSetTimeStamp($columnName, $column, $data) || $column['IDENTITY']) {
                 continue;
             }
 
-            if (isset($data[strtolower($column['COLUMN_NAME'])])) {
+            if (isset($data[$columnName])) {
                 $output[strtolower($column['COLUMN_NAME'])] = $data[strtolower($column['COLUMN_NAME'])];
             } elseif (!empty($column['NULLABLE'])) {
                 $output[strtolower($column['COLUMN_NAME'])] = null;
@@ -67,6 +68,18 @@ class UpdateRow
         return $output;
     }
 
+    /**
+     * @param string $columnName
+     * @param string $column
+     * @param array $data
+     * @return bool
+     */
+    private function canNotSetTimeStamp($columnName, $column, array $data)
+    {
+        return $column['DEFAULT'] == 'CURRENT_TIMESTAMP' && !isset($data[$columnName])
+        && empty($column['NULLABLE']);
+    }
+
     /**
      * @param string $entityType
      * @param array $data
diff --git a/lib/internal/Magento/Framework/EntityManager/Observer/AfterEntityLoad.php b/lib/internal/Magento/Framework/EntityManager/Observer/AfterEntityLoad.php
index 010cafdd2f7148156bd02b0f2c28db5e469c0f54..3de6bd8fbcdd55840c39d31bf449f1f3ae5c6486 100644
--- a/lib/internal/Magento/Framework/EntityManager/Observer/AfterEntityLoad.php
+++ b/lib/internal/Magento/Framework/EntityManager/Observer/AfterEntityLoad.php
@@ -32,6 +32,7 @@ class AfterEntityLoad implements ObserverInterface
             }
             $entity->getResource()->afterLoad($entity);
             $entity->afterLoad();
+            $entity->setOrigData();
             $entity->setHasDataChanges(false);
         }
     }
diff --git a/lib/internal/Magento/Framework/EntityManager/Observer/BeforeEntityLoad.php b/lib/internal/Magento/Framework/EntityManager/Observer/BeforeEntityLoad.php
new file mode 100644
index 0000000000000000000000000000000000000000..1d292a2e5b3f81516563336f11dbf195b93b64d1
--- /dev/null
+++ b/lib/internal/Magento/Framework/EntityManager/Observer/BeforeEntityLoad.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\EntityManager\Observer;
+
+use Magento\Framework\Event\Observer;
+use Magento\Framework\Model\AbstractModel;
+
+/**
+ * Class BeforeEntityLoad
+ */
+class BeforeEntityLoad
+{
+    /**
+     * Apply model before load operation
+     *
+     * @param Observer $observer
+     * @throws \Magento\Framework\Validator\Exception
+     * @return void
+     */
+    public function execute(Observer $observer)
+    {
+        $identifier = $observer->getEvent()->getIdentifier();
+        $entity = $observer->getEvent()->getEntity();
+        if ($entity instanceof AbstractModel) {
+            $entity->beforeLoad($identifier);
+        }
+    }
+}
diff --git a/lib/internal/Magento/Framework/EntityManager/Operation/Read.php b/lib/internal/Magento/Framework/EntityManager/Operation/Read.php
index 1cd988f53a0050aeaffa1e55b96270a2eb84ce2c..19a3912890db5af5f50cfab964e0c2ca0de572c4 100644
--- a/lib/internal/Magento/Framework/EntityManager/Operation/Read.php
+++ b/lib/internal/Magento/Framework/EntityManager/Operation/Read.php
@@ -5,7 +5,6 @@
  */
 namespace Magento\Framework\EntityManager\Operation;
 
-use Magento\Framework\EntityManager\Operation\ReadInterface;
 use Magento\Framework\EntityManager\Operation\Read\ReadMain;
 use Magento\Framework\EntityManager\Operation\Read\ReadAttributes;
 use Magento\Framework\EntityManager\Operation\Read\ReadExtensions;
@@ -13,7 +12,6 @@ use Magento\Framework\EntityManager\HydratorPool;
 use Magento\Framework\EntityManager\MetadataPool;
 use Magento\Framework\EntityManager\EventManager;
 use Magento\Framework\EntityManager\TypeResolver;
-use Magento\Framework\App\ResourceConnection;
 
 /**
  * Class Read
@@ -83,11 +81,7 @@ class Read implements ReadInterface
     }
 
     /**
-     * @param object $entity
-     * @param string $identifier
-     * @param array $arguments
-     * @return object
-     * @throws \Exception
+     * {@inheritDoc}
      */
     public function execute($entity, $identifier, $arguments = [])
     {
@@ -107,6 +101,7 @@ class Read implements ReadInterface
             'load_before',
             [
                 'identifier' => $identifier,
+                'entity' => $entity,
                 'arguments' => $arguments
             ]
         );
diff --git a/lib/internal/Magento/Framework/EntityManager/Test/Unit/Db/UpdateRowTest.php b/lib/internal/Magento/Framework/EntityManager/Test/Unit/Db/UpdateRowTest.php
index b22334f4402b1597a7af220cfc168379cde449be..1379ca072bf91898c25a06a796b40f26f2fc2899 100644
--- a/lib/internal/Magento/Framework/EntityManager/Test/Unit/Db/UpdateRowTest.php
+++ b/lib/internal/Magento/Framework/EntityManager/Test/Unit/Db/UpdateRowTest.php
@@ -63,33 +63,14 @@ class UpdateRowTest extends \PHPUnit_Framework_TestCase
         ]);
     }
 
-    public function testExecute()
+    /**
+     * @dataProvider columnsDataProvider
+     * @param array $data
+     * @param array $columns
+     * @param array $preparedColumns
+     */
+    public function testExecute(array $data, array $columns, array $preparedColumns)
     {
-        $data = [
-            'test_link_field' => 1,
-            'identified_field' => 'test_identified_field',
-            'test_simple' => 'test_value',
-        ];
-        $columns = [
-            'test_nullable' => [
-                'NULLABLE' => true,
-                'DEFAULT' => false,
-                'IDENTITY' => false,
-                'COLUMN_NAME' => 'test_nullable',
-            ],
-            'test_simple' => [
-                'NULLABLE' => true,
-                'DEFAULT' => false,
-                'IDENTITY' => false,
-                'COLUMN_NAME' => 'test_simple',
-            ],
-        ];
-        $preparedColumns = [
-            'test_identified_field' => null,
-            'test_nullable' => null,
-            'test_simple' => 'test_value',
-        ];
-
         $this->metadataPoolMock->expects($this->once())
             ->method('getMetadata')
             ->with('test')
@@ -115,7 +96,78 @@ class UpdateRowTest extends \PHPUnit_Framework_TestCase
         $this->metadataMock->expects($this->exactly(2))
             ->method('getIdentifierField')
             ->willReturn('test_identified_field');
-
+        if (empty($data['updated_at'])) {
+            unset($data['updated_at']);
+        }
         $this->assertSame($data, $this->model->execute('test', $data));
     }
+
+    /**
+     * @return array
+     */
+    public function columnsDataProvider()
+    {
+        $data = [
+            'test_link_field' => 1,
+            'identified_field' => 'test_identified_field',
+            'test_simple' => 'test_value',
+        ];
+        $columns = [
+            'test_nullable' => [
+                'NULLABLE' => true,
+                'DEFAULT' => false,
+                'IDENTITY' => false,
+                'COLUMN_NAME' => 'test_nullable',
+            ],
+            'test_simple' => [
+                'NULLABLE' => true,
+                'DEFAULT' => false,
+                'IDENTITY' => false,
+                'COLUMN_NAME' => 'test_simple',
+            ],
+        ];
+        $preparedColumns = [
+            'test_identified_field' => null,
+            'test_nullable' => null,
+            'test_simple' => 'test_value',
+        ];
+
+        return [
+            'default' => [
+                'data' => $data,
+                'columns' => $columns,
+                'preparedColumns' => $preparedColumns,
+            ],
+            'empty timestamp field' => [
+                'data' => array_merge($data, ['updated_at' => '']),
+                'columns' => array_merge(
+                    $columns,
+                    [
+                        'updated_at' => [
+                            'NULLABLE' => false,
+                            'DEFAULT' => 'CURRENT_TIMESTAMP',
+                            'IDENTITY' => false,
+                            'COLUMN_NAME' => 'updated_at',
+                        ],
+                    ]
+                ),
+                'preparedColumns' => $preparedColumns,
+            ],
+            'filled timestamp field' => [
+                'data' => array_merge($data, ['updated_at' => '2016-01-01 00:00:00']),
+                'columns' => array_merge(
+                    $columns,
+                    [
+                        'updated_at' => [
+                            'NULLABLE' => false,
+                            'DEFAULT' => 'CURRENT_TIMESTAMP',
+                            'IDENTITY' => false,
+                            'COLUMN_NAME' => 'updated_at',
+                        ],
+                    ]
+                ),
+                'preparedColumns' => array_merge($preparedColumns, ['updated_at' => '2016-01-01 00:00:00']),
+            ],
+        ];
+    }
 }
diff --git a/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php b/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php
index befff770156178dd2324e42365b62ac52414c9e8..ecfb67320cb0d58decdf67de64d2058814f1eaf8 100644
--- a/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php
+++ b/lib/internal/Magento/Framework/Interception/PluginList/PluginList.php
@@ -75,6 +75,11 @@ class PluginList extends Scoped implements InterceptionPluginList
      */
     protected $_pluginInstances = [];
 
+    /**
+     * @var \Psr\Log\LoggerInterface
+     */
+    private $logger;
+
     /**
      * @param ReaderInterface $reader
      * @param ScopeInterface $configScope
@@ -149,6 +154,7 @@ class PluginList extends Scoped implements InterceptionPluginList
             }
             $this->_inherited[$type] = null;
             if (is_array($plugins) && count($plugins)) {
+                $this->filterPlugins($plugins);
                 uasort($plugins, [$this, '_sort']);
                 $this->trimInstanceStartingBackslash($plugins);
                 $this->_inherited[$type] = $plugins;
@@ -348,4 +354,34 @@ class PluginList extends Scoped implements InterceptionPluginList
             }
         }
     }
+
+    /**
+     * Remove from list not existing plugins
+     *
+     * @param array $plugins
+     * @return void
+     */
+    private function filterPlugins(array &$plugins)
+    {
+        foreach ($plugins as $name => $plugin) {
+            if (empty($plugin['instance'])) {
+                unset($plugins[$name]);
+                $this->getLogger()->info("Reference to undeclared plugin with name '{$name}'.");
+            }
+        }
+    }
+
+    /**
+     * Returns logger instance
+     *
+     * @deprecated
+     * @return \Psr\Log\LoggerInterface
+     */
+    private function getLogger()
+    {
+        if ($this->logger === null) {
+            $this->logger = $this->_objectManager->get(\Psr\Log\LoggerInterface::class);
+        }
+        return $this->logger;
+    }
 }
diff --git a/lib/internal/Magento/Framework/Interception/Test/Unit/PluginList/PluginListTest.php b/lib/internal/Magento/Framework/Interception/Test/Unit/PluginList/PluginListTest.php
index 1291ae44bce6522bf61f1bdbc42c3089a09abd48..b3fe011a0a490727c0682f1863aa731622753264 100644
--- a/lib/internal/Magento/Framework/Interception/Test/Unit/PluginList/PluginListTest.php
+++ b/lib/internal/Magento/Framework/Interception/Test/Unit/PluginList/PluginListTest.php
@@ -60,7 +60,6 @@ class PluginListTest extends \PHPUnit_Framework_TestCase
         $omConfigMock->expects($this->any())->method('getOriginalInstanceType')->will($this->returnArgument(0));
 
         $this->_objectManagerMock = $this->getMock(\Magento\Framework\ObjectManagerInterface::class);
-        $this->_objectManagerMock->expects($this->any())->method('get')->will($this->returnArgument(0));
 
         $definitions = new \Magento\Framework\ObjectManager\Definition\Runtime();
 
@@ -80,6 +79,7 @@ class PluginListTest extends \PHPUnit_Framework_TestCase
 
     public function testGetPlugin()
     {
+        $this->_objectManagerMock->expects($this->any())->method('get')->will($this->returnArgument(0));
         $this->_configScopeMock->expects($this->any())->method('getCurrentScope')->will($this->returnValue('backend'));
         $this->_model->getNext(\Magento\Framework\Interception\Test\Unit\Custom\Module\Model\Item::class, 'getName');
         $this->_model->getNext(
@@ -131,6 +131,7 @@ class PluginListTest extends \PHPUnit_Framework_TestCase
      */
     public function testGetPlugins($expectedResult, $type, $method, $scopeCode, $code = '__self')
     {
+        $this->_objectManagerMock->expects($this->any())->method('get')->will($this->returnArgument(0));
         $this->_configScopeMock->expects(
             $this->any()
         )->method(
@@ -206,6 +207,7 @@ class PluginListTest extends \PHPUnit_Framework_TestCase
      */
     public function testInheritPluginsWithNonExistingClass()
     {
+        $this->_objectManagerMock->expects($this->any())->method('get')->will($this->returnArgument(0));
         $this->_configScopeMock->expects($this->any())
             ->method('getCurrentScope')
             ->will($this->returnValue('frontend'));
@@ -213,12 +215,34 @@ class PluginListTest extends \PHPUnit_Framework_TestCase
         $this->_model->getNext('SomeType', 'someMethod');
     }
 
+    /**
+     * @covers \Magento\Framework\Interception\PluginList\PluginList::getNext
+     * @covers \Magento\Framework\Interception\PluginList\PluginList::_inheritPlugins
+     */
+    public function testInheritPluginsWithNotExistingPlugin()
+    {
+        $loggerMock = $this->getMock(\Psr\Log\LoggerInterface::class);
+        $this->_objectManagerMock->expects($this->once())
+            ->method('get')
+            ->with(\Psr\Log\LoggerInterface::class)
+            ->willReturn($loggerMock);
+        $loggerMock->expects($this->once())
+            ->method('info')
+            ->with("Reference to undeclared plugin with name 'simple_plugin'.");
+        $this->_configScopeMock->expects($this->any())
+            ->method('getCurrentScope')
+            ->will($this->returnValue('frontend'));
+
+        $this->assertNull($this->_model->getNext('typeWithoutInstance', 'someMethod'));
+    }
+
     /**
      * @covers \Magento\Framework\Interception\PluginList\PluginList::getNext
      * @covers \Magento\Framework\Interception\PluginList\PluginList::_loadScopedData
      */
     public function testLoadScopedDataCached()
     {
+        $this->_objectManagerMock->expects($this->any())->method('get')->will($this->returnArgument(0));
         $this->_configScopeMock->expects($this->once())
             ->method('getCurrentScope')
             ->will($this->returnValue('scope'));
diff --git a/lib/internal/Magento/Framework/Interception/Test/Unit/_files/reader_mock_map.php b/lib/internal/Magento/Framework/Interception/Test/Unit/_files/reader_mock_map.php
index 832a5a67599da7f9dbfe46e2732324b536f267c8..87bbe0d35dd2561799cd5d2024347c8fb48c2b73 100644
--- a/lib/internal/Magento/Framework/Interception/Test/Unit/_files/reader_mock_map.php
+++ b/lib/internal/Magento/Framework/Interception/Test/Unit/_files/reader_mock_map.php
@@ -70,6 +70,11 @@ return [
                         'instance' => 'NonExistingPluginClass',
                     ],
                 ],
+            ],
+            'typeWithoutInstance' => [
+                'plugins' => [
+                    'simple_plugin' => [],
+                ],
             ]
         ]
     ]
diff --git a/lib/internal/Magento/Framework/Model/AbstractModel.php b/lib/internal/Magento/Framework/Model/AbstractModel.php
index dbbb20021b9f4dcc03765aee89bdbd81339bac08..34536d47097796d18e1ff517f2fd1ad2a7317735 100644
--- a/lib/internal/Magento/Framework/Model/AbstractModel.php
+++ b/lib/internal/Magento/Framework/Model/AbstractModel.php
@@ -527,12 +527,7 @@ abstract class AbstractModel extends \Magento\Framework\DataObject
      */
     public function load($modelId, $field = null)
     {
-        $this->_beforeLoad($modelId, $field);
         $this->_getResource()->load($this, $modelId, $field);
-        $this->_afterLoad();
-        $this->setOrigData();
-        $this->_hasDataChanges = false;
-        $this->updateStoredData();
         return $this;
     }
 
@@ -577,6 +572,18 @@ abstract class AbstractModel extends \Magento\Framework\DataObject
         return $this;
     }
 
+    /**
+     * Process operation before object load
+     *
+     * @param string $identifier
+     * @param string|null $field
+     * @return void
+     */
+    public function beforeLoad($identifier, $field = null)
+    {
+        $this->_beforeLoad($identifier, $field);
+    }
+
     /**
      * Object after load processing. Implemented as public interface for supporting objects after load in collections
      *
@@ -584,7 +591,6 @@ abstract class AbstractModel extends \Magento\Framework\DataObject
      */
     public function afterLoad()
     {
-        $this->getResource()->afterLoad($this);
         $this->_afterLoad();
         $this->updateStoredData();
         return $this;
diff --git a/lib/internal/Magento/Framework/Model/ResourceModel/Db/AbstractDb.php b/lib/internal/Magento/Framework/Model/ResourceModel/Db/AbstractDb.php
index fc189473505abd258acb159f32ff9d2b77d44958..7febcb450f9720d9999f19704808df90ca69deea 100644
--- a/lib/internal/Magento/Framework/Model/ResourceModel/Db/AbstractDb.php
+++ b/lib/internal/Magento/Framework/Model/ResourceModel/Db/AbstractDb.php
@@ -332,6 +332,7 @@ abstract class AbstractDb extends AbstractResource
      */
     public function load(\Magento\Framework\Model\AbstractModel $object, $value, $field = null)
     {
+        $object->beforeLoad($value, $field);
         if ($field === null) {
             $field = $this->getIdFieldName();
         }
@@ -348,7 +349,10 @@ abstract class AbstractDb extends AbstractResource
 
         $this->unserializeFields($object);
         $this->_afterLoad($object);
-
+        $object->afterLoad();
+        $object->setOrigData();
+        $object->setHasDataChanges(false);
+        
         return $this;
     }
 
diff --git a/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/AbstractDbTest.php b/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/AbstractDbTest.php
index 1dcb84d276840185af916c1bc6036cc4b1ea5071..0a2e6f2262173f244dc0dddf8c53fa44c9bf3558 100644
--- a/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/AbstractDbTest.php
+++ b/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/AbstractDbTest.php
@@ -269,29 +269,19 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
 
     public function testLoad()
     {
-        $contextMock = $this->getMock(\Magento\Framework\Model\Context::class, [], [], '', false);
-        $registryMock = $this->getMock(\Magento\Framework\Registry::class, [], [], '', false);
-        $abstractModelMock = $this->getMockForAbstractClass(
-            \Magento\Framework\Model\AbstractModel::class,
-            [$contextMock, $registryMock],
-            '',
-            false,
-            true,
-            true,
-            ['__wakeup']
-        );
-
-        $value = 'some_value';
-        $idFieldName = new \ReflectionProperty(
-            \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
-            '_idFieldName'
-        );
-        $idFieldName->setAccessible(true);
-        $idFieldName->setValue($this->_model, 'field_value');
-
+        /** @var \Magento\Framework\Model\AbstractModel|\PHPUnit_Framework_MockObject_MockObject $object */
+        $object = $this->getMockBuilder(\Magento\Framework\Model\AbstractModel::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $object->expects($this->once())->method('beforeLoad')->with('some_value', 'field_name');
+        $object->expects($this->once())->method('afterLoad')->willReturnSelf();
+        $object->expects($this->once())->method('setOrigData')->willReturnSelf();
+        $object->expects($this->once())->method('setHasDataChanges')->with(false)->willReturnSelf();
+        $result = $this->_model->load($object, 'some_value', 'field_name');
+        $this->assertEquals($this->_model, $result);
         $this->assertInstanceOf(
             \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
-            $this->_model->load($abstractModelMock, $value, $idFieldName)
+        $result
         );
     }
 
@@ -497,7 +487,6 @@ class AbstractDbTest extends \PHPUnit_Framework_TestCase
         $idFieldNameReflection->setValue($this->_model, 'idFieldName');
         $connectionMock->expects($this->any())->method('save')->with('tableName', 'idFieldName');
         $connectionMock->expects($this->any())->method('quoteInto')->will($this->returnValue('idFieldName'));
-
         $abstractModelMock->setIdFieldName('id');
         $abstractModelMock->setData(
             [
diff --git a/lib/internal/Magento/Framework/ObjectManager/ObjectManager.php b/lib/internal/Magento/Framework/ObjectManager/ObjectManager.php
index f8be1abe0d1f140b035dfb215d86d56316e13d00..d3ed381c239bec15eae825fb38fdb172a990a7e6 100644
--- a/lib/internal/Magento/Framework/ObjectManager/ObjectManager.php
+++ b/lib/internal/Magento/Framework/ObjectManager/ObjectManager.php
@@ -75,6 +75,7 @@ class ObjectManager implements \Magento\Framework\ObjectManagerInterface
 
     /**
      * Configure di instance
+     * Note: All arguments should be pre-processed (sort order, translations, etc) before passing to method configure.
      *
      * @param array $configuration
      * @return void
diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Config/_files/invalidConfigXmlArray.php b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Config/_files/invalidConfigXmlArray.php
index 54d6da41ecbaa8d1a95834bf5c9470ed4f1021ce..696d0efffcee416186c5585bdb4f3215ed7defdc 100644
--- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Config/_files/invalidConfigXmlArray.php
+++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Config/_files/invalidConfigXmlArray.php
@@ -155,5 +155,21 @@ return [
             "Element 'argument': Duplicate key-sequence ['same_param_name'] in key identity-constraint"
                 . " 'argumentName'.\nLine: 6\n"
         ],
-    ]
+    ],
+    'sorted_object_list_with_invalid_sortOrder_attribute_value' => [
+        '<?xml version="1.0"?>
+        <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+            <type name="Some_Name">
+                <arguments>
+                    <argument name="sorted_object_list" xsi:type="array">
+                        <item name="someObject" xsi:type="object" sortOrder="false">Some_Class_Name</item>
+                    </argument>
+                </arguments>
+            </type>
+        </config>',
+        [
+            "Element 'item', attribute 'sortOrder': 'false' is not a valid value of the atomic type 'xs:integer'." .
+            "\nLine: 6\n"
+        ],
+    ],
 ];
diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Config/_files/valid_config.xml b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Config/_files/valid_config.xml
index df900f0ce4a9ce60d9ae96627af4f47e7544ce0a..5c9d6354be9a03594054c42ecbae922ce2369a3a 100644
--- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Config/_files/valid_config.xml
+++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Config/_files/valid_config.xml
@@ -57,6 +57,11 @@
                 </item>
             </argument>
             <argument name="baseController" xsi:type="string">some_value</argument>
+            <argument name="sortedList" xsi:type="array">
+                <item name="itemTwo" xsi:type="object" sortOrder="20">Instance_test_name_two</item>
+                <item name="itemOne" xsi:type="object">Instance_test_name_one</item>
+                <item name="itemThree" xsi:type="object" sortOrder="30">Instance_test_name_three</item>
+            </argument>
         </arguments>
     </type>
 </config>
diff --git a/lib/internal/Magento/Framework/ObjectManager/etc/config.xsd b/lib/internal/Magento/Framework/ObjectManager/etc/config.xsd
index adb514bbdbde1a8db54e8279afdba1c650749dcf..29e754bc06b876e6c697429c77b24918a97bbaeb 100644
--- a/lib/internal/Magento/Framework/ObjectManager/etc/config.xsd
+++ b/lib/internal/Magento/Framework/ObjectManager/etc/config.xsd
@@ -20,6 +20,7 @@
             <xs:complexContent>
                 <xs:extension base="object">
                     <xs:attribute name="shared" use="optional" type="xs:boolean"/>
+                    <xs:attribute name="sortOrder" use="optional" type="xs:integer"/>
                 </xs:extension>
             </xs:complexContent>
         </xs:complexType>
diff --git a/lib/internal/Magento/Framework/Pricing/Render/PriceBox.php b/lib/internal/Magento/Framework/Pricing/Render/PriceBox.php
index 4048f2d105ac0f1d455e2a07f9ecc4acdc9bd962..ddf14cdc659a26533a60f4e79a25b39e5b94fddd 100644
--- a/lib/internal/Magento/Framework/Pricing/Render/PriceBox.php
+++ b/lib/internal/Magento/Framework/Pricing/Render/PriceBox.php
@@ -86,7 +86,7 @@ class PriceBox extends Template implements PriceBoxRenderInterface, IdentityInte
      */
     protected function getCacheLifetime()
     {
-        return parent::hasCacheLifetime() ? parent::getCacheLifetime() : self::DEFAULT_LIFETIME;
+        return parent::hasCacheLifetime() ? parent::getCacheLifetime() : null;
     }
     
     /**
diff --git a/lib/internal/Magento/Framework/Pricing/Test/Unit/Adjustment/CalculatorTest.php b/lib/internal/Magento/Framework/Pricing/Test/Unit/Adjustment/CalculatorTest.php
index 55f68f47407f56c7dd1079724d28f51af4769595..f1c4d443bd756faf21c9290da0b6531c4c9537ae 100644
--- a/lib/internal/Magento/Framework/Pricing/Test/Unit/Adjustment/CalculatorTest.php
+++ b/lib/internal/Magento/Framework/Pricing/Test/Unit/Adjustment/CalculatorTest.php
@@ -60,12 +60,12 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase
             ->with($this->equalTo($totalAmount), $this->equalTo($expectedAdjustments))
             ->will($this->returnValue($amountBaseMock));
 
-        $productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
+        $productMock = $this->getMockBuilder(\Magento\Framework\Pricing\SaleableInterface::class)
             ->disableOriginalConstructor()
             ->setMethods(['getPriceInfo', '__wakeup'])
-            ->getMock();
+            ->getMockForAbstractClass();
 
-        $weeeAdjustmentMock = $this->getMockBuilder(\Magento\Weee\Pricing\Adjustment::class)
+        $weeeAdjustmentMock = $this->getMockBuilder(\Magento\Framework\Pricing\Adjustment\AdjustmentInterface::class)
             ->disableOriginalConstructor()
             ->getMock();
         $weeeAdjustmentMock->expects($this->once())
@@ -82,7 +82,7 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase
             ->with($this->equalTo($amountInclTax), $this->equalTo($productMock))
             ->will($this->returnValue($weeeAdjustment + $amountInclTax));
 
-        $taxAdjustmentMock = $this->getMockBuilder(\Magento\Tax\Pricing\Adjustment::class)
+        $taxAdjustmentMock = $this->getMockBuilder(\Magento\Framework\Pricing\Adjustment\AdjustmentInterface::class)
             ->disableOriginalConstructor()
             ->getMock();
         $taxAdjustmentMock->expects($this->once())
@@ -127,12 +127,12 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase
         $adjustment = 5;
         $expectedAdjustments = [];
 
-        $productMock = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
+        $productMock = $this->getMockBuilder(\Magento\Framework\Pricing\SaleableInterface::class)
             ->disableOriginalConstructor()
             ->setMethods(['getPriceInfo', '__wakeup'])
-            ->getMock();
+            ->getMockForAbstractClass();
 
-        $taxAdjustmentMock = $this->getMockBuilder(\Magento\Tax\Pricing\Adjustment::class)
+        $taxAdjustmentMock = $this->getMockBuilder(\Magento\Framework\Pricing\Adjustment\AdjustmentInterface::class)
             ->disableOriginalConstructor()
             ->getMock();
         $taxAdjustmentMock->expects($this->once())
@@ -150,7 +150,7 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase
             ->with($this->equalTo($fullamount), $this->equalTo($productMock))
             ->will($this->returnValue($amount));
 
-        $weeeAdjustmentMock = $this->getMockBuilder(\Magento\Weee\Pricing\Adjustment::class)
+        $weeeAdjustmentMock = $this->getMockBuilder(\Magento\Framework\Pricing\Adjustment\AdjustmentInterface::class)
             ->disableOriginalConstructor()
             ->getMock();
         $weeeAdjustmentMock->expects($this->once())
diff --git a/lib/internal/Magento/Framework/Pricing/Test/Unit/Render/PriceBoxTest.php b/lib/internal/Magento/Framework/Pricing/Test/Unit/Render/PriceBoxTest.php
index 86e2dde6359d8a9f759905042d86521c135da04d..9a0dfcd7099ee94718f38f18c4af3ab3ed521109 100644
--- a/lib/internal/Magento/Framework/Pricing/Test/Unit/Render/PriceBoxTest.php
+++ b/lib/internal/Magento/Framework/Pricing/Test/Unit/Render/PriceBoxTest.php
@@ -241,4 +241,17 @@ class PriceBoxTest extends \PHPUnit_Framework_TestCase
     {
         $this->assertEquals($this->rendererPool, $this->model->getRendererPool());
     }
+
+    /**
+     * This tests ensures that protected method getCacheLifetime() returns a null value when cacheLifeTime is not
+     * explicitly set in the parent block
+     */
+    public function testCacheLifetime()
+    {
+        $reflectionClass = new \ReflectionClass(get_class($this->model));
+        $methodReflection = $reflectionClass->getMethod('getCacheLifetime');
+        $methodReflection->setAccessible(true);
+        $cacheLifeTime = $methodReflection->invoke($this->model);
+        $this->assertNull($cacheLifeTime, 'Expected null cache lifetime');
+    }
 }
diff --git a/lib/internal/Magento/Framework/Pricing/Test/Unit/RenderTest.php b/lib/internal/Magento/Framework/Pricing/Test/Unit/RenderTest.php
index 1f6c7b98c129d9a090596c4a7d87d8ce64b5634b..1bc82365bf16881e2e8149409750c54de02c8651 100644
--- a/lib/internal/Magento/Framework/Pricing/Test/Unit/RenderTest.php
+++ b/lib/internal/Magento/Framework/Pricing/Test/Unit/RenderTest.php
@@ -23,7 +23,7 @@ class RenderTest extends \PHPUnit_Framework_TestCase
     protected $priceLayout;
 
     /**
-     * @var \Magento\Catalog\Pricing\Price\BasePrice|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\Pricing\Price\PriceInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $price;
 
@@ -33,7 +33,7 @@ class RenderTest extends \PHPUnit_Framework_TestCase
     protected $amount;
 
     /**
-     * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\Pricing\SaleableInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $saleableItem;
 
@@ -48,17 +48,17 @@ class RenderTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
 
-        $this->price = $this->getMockBuilder(\Magento\Catalog\Pricing\Price\BasePrice::class)
+        $this->price = $this->getMockBuilder(\Magento\Framework\Pricing\Price\PriceInterface::class)
             ->disableOriginalConstructor()
-            ->getMock();
+            ->getMockForAbstractClass();
 
         $this->amount = $this->getMockBuilder(\Magento\Framework\Pricing\Amount\Base::class)
             ->disableOriginalConstructor()
             ->getMock();
 
-        $this->saleableItem = $this->getMockBuilder(\Magento\Catalog\Model\Product::class)
+        $this->saleableItem = $this->getMockBuilder(\Magento\Framework\Pricing\SaleableInterface::class)
             ->disableOriginalConstructor()
-            ->getMock();
+            ->getMockForAbstractClass();
 
         $this->renderPool = $this->getMockBuilder(\Magento\Framework\Pricing\Render\RendererPool::class)
             ->disableOriginalConstructor()
diff --git a/lib/internal/Magento/Framework/View/Element/AbstractBlock.php b/lib/internal/Magento/Framework/View/Element/AbstractBlock.php
index c5269275586978dc8409a006214983cdfb68ffb6..d80c83883975b3e41f862466a72c8ccfa4cd2c98 100644
--- a/lib/internal/Magento/Framework/View/Element/AbstractBlock.php
+++ b/lib/internal/Magento/Framework/View/Element/AbstractBlock.php
@@ -670,6 +670,18 @@ abstract class AbstractBlock extends \Magento\Framework\DataObject implements Bl
         }
         $html = $this->_afterToHtml($html);
 
+        /** @var \Magento\Framework\DataObject */
+        $transportObject = new \Magento\Framework\DataObject(
+            [
+                'html' => $html,
+            ]
+        );
+        $this->_eventManager->dispatch('view_block_abstract_to_html_after', [
+            'block' => $this,
+            'transport' => $transportObject
+        ]);
+        $html = $transportObject->getHtml();
+
         return $html;
     }
 
diff --git a/lib/internal/Magento/Framework/View/Element/Html/Link.php b/lib/internal/Magento/Framework/View/Element/Html/Link.php
index c4e5460c7de0b951c35127ef456f1c8dd342eb0e..e6f22f14784e0a8c119175d01501797f62b4128d 100644
--- a/lib/internal/Magento/Framework/View/Element/Html/Link.php
+++ b/lib/internal/Magento/Framework/View/Element/Html/Link.php
@@ -22,6 +22,7 @@ class Link extends \Magento\Framework\View\Element\Template
         'title',
         'charset',
         'name',
+        'target',
         'hreflang',
         'rel',
         'rev',
diff --git a/lib/internal/Magento/Framework/View/Element/Html/Select.php b/lib/internal/Magento/Framework/View/Element/Html/Select.php
index e388e665dfdbab281940a9ade50972059d4d9156..7e0c07ff75e45a70b17f513f5a0f2ed7c2aa6022 100644
--- a/lib/internal/Magento/Framework/View/Element/Html/Select.php
+++ b/lib/internal/Magento/Framework/View/Element/Html/Select.php
@@ -140,7 +140,7 @@ class Select extends \Magento\Framework\View\Element\AbstractBlock
             '" class="' .
             $this->getClass() .
             '" title="' .
-            $this->getTitle() .
+            $this->escapeHtml($this->getTitle()) .
             '" ' .
             $this->getExtraParams() .
             '>';
@@ -166,7 +166,8 @@ class Select extends \Magento\Framework\View\Element\AbstractBlock
             }
 
             if (is_array($value)) {
-                $html .= '<optgroup label="' . $label . '" data-optgroup-name="' . $optgroupName . '">';
+                $html .= '<optgroup label="' . $this->escapeHtml($label)
+                    . '" data-optgroup-name="' . $this->escapeHtml($optgroupName) . '">';
                 foreach ($value as $keyGroup => $optionGroup) {
                     if (!is_array($optionGroup)) {
                         $optionGroup = ['value' => $keyGroup, 'label' => $optionGroup];
@@ -204,10 +205,10 @@ class Select extends \Magento\Framework\View\Element\AbstractBlock
             foreach ($option['params'] as $key => $value) {
                 if (is_array($value)) {
                     foreach ($value as $keyMulti => $valueMulti) {
-                        $params .= sprintf(' %s="%s" ', $keyMulti, $valueMulti);
+                        $params .= sprintf(' %s="%s" ', $keyMulti, $this->escapeHtml($valueMulti));
                     }
                 } else {
-                    $params .= sprintf(' %s="%s" ', $key, $value);
+                    $params .= sprintf(' %s="%s" ', $key, $this->escapeHtml($value));
                 }
             }
         }
diff --git a/lib/internal/Magento/Framework/View/Layout/Generator/Block.php b/lib/internal/Magento/Framework/View/Layout/Generator/Block.php
index 9dd316d5efb756728c828850ba500a22eeffb8df..a0ceed86e819a920b72c9f1dbb25a3c76db83fcb 100755
--- a/lib/internal/Magento/Framework/View/Layout/Generator/Block.php
+++ b/lib/internal/Magento/Framework/View/Layout/Generator/Block.php
@@ -261,7 +261,10 @@ class Block implements Layout\GeneratorInterface
         }
         if (!$block instanceof \Magento\Framework\View\Element\AbstractBlock) {
             throw new \Magento\Framework\Exception\LocalizedException(
-                new \Magento\Framework\Phrase('Invalid block type: %1', [$block]),
+                new \Magento\Framework\Phrase(
+                    'Invalid block type: %1',
+                    [is_object($block) ? get_class($block) : (string) $block]
+                ),
                 $e
             );
         }
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Element/AbstractBlockTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Element/AbstractBlockTest.php
index dad0d22d188c9e817abcfda8461bf7423fb16028..68cb485f571dd116092d667c00df4a48c0bce4ed 100644
--- a/lib/internal/Magento/Framework/View/Test/Unit/Element/AbstractBlockTest.php
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Element/AbstractBlockTest.php
@@ -19,6 +19,9 @@ use Magento\Framework\App\CacheInterface;
 use Magento\Framework\Session\SidResolverInterface;
 use Magento\Framework\Session\SessionManagerInterface;
 
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class AbstractBlockTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -204,7 +207,7 @@ class AbstractBlockTest extends \PHPUnit_Framework_TestCase
         $moduleName = 'Test';
         $this->block->setData('module_name', $moduleName);
 
-        $this->eventManagerMock->expects($this->once())
+        $this->eventManagerMock->expects($this->any())
             ->method('dispatch')
             ->with('view_block_abstract_to_html_before', ['block' => $this->block]);
         $this->scopeConfigMock->expects($this->once())
@@ -219,6 +222,7 @@ class AbstractBlockTest extends \PHPUnit_Framework_TestCase
      * @param string|bool $cacheLifetime
      * @param string|bool $dataFromCache
      * @param string $dataForSaveCache
+     * @param \PHPUnit_Framework_MockObject_Matcher_InvokedCount $expectsDispatchEvent
      * @param \PHPUnit_Framework_MockObject_Matcher_InvokedCount $expectsCacheLoad
      * @param \PHPUnit_Framework_MockObject_Matcher_InvokedCount $expectsCacheSave
      * @param string $expectedResult
@@ -229,6 +233,7 @@ class AbstractBlockTest extends \PHPUnit_Framework_TestCase
         $cacheLifetime,
         $dataFromCache,
         $dataForSaveCache,
+        $expectsDispatchEvent,
         $expectsCacheLoad,
         $expectsCacheSave,
         $expectedResult
@@ -239,9 +244,8 @@ class AbstractBlockTest extends \PHPUnit_Framework_TestCase
         $this->block->setData('module_name', $moduleName);
         $this->block->setData('cache_lifetime', $cacheLifetime);
 
-        $this->eventManagerMock->expects($this->once())
-            ->method('dispatch')
-            ->with('view_block_abstract_to_html_before', ['block' => $this->block]);
+        $this->eventManagerMock->expects($expectsDispatchEvent)
+            ->method('dispatch');
         $this->scopeConfigMock->expects($this->once())
             ->method('getValue')
             ->with('advanced/modules_disable_output/' . $moduleName, \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
@@ -278,6 +282,7 @@ class AbstractBlockTest extends \PHPUnit_Framework_TestCase
                 'cacheLifetime' => null,
                 'dataFromCache' => 'dataFromCache',
                 'dataForSaveCache' => '',
+                'expectsDispatchEvent' => $this->exactly(2),
                 'expectsCacheLoad' => $this->never(),
                 'expectsCacheSave' => $this->never(),
                 'expectedResult' => '',
@@ -286,6 +291,7 @@ class AbstractBlockTest extends \PHPUnit_Framework_TestCase
                 'cacheLifetime' => false,
                 'dataFromCache' => 'dataFromCache',
                 'dataForSaveCache' => '',
+                'expectsDispatchEvent' => $this->exactly(2),
                 'expectsCacheLoad' => $this->once(),
                 'expectsCacheSave' => $this->never(),
                 'expectedResult' => 'dataFromCache',
@@ -294,6 +300,7 @@ class AbstractBlockTest extends \PHPUnit_Framework_TestCase
                 'cacheLifetime' => 120,
                 'dataFromCache' => 'dataFromCache',
                 'dataForSaveCache' => '',
+                'expectsDispatchEvent' => $this->exactly(2),
                 'expectsCacheLoad' => $this->once(),
                 'expectsCacheSave' => $this->never(),
                 'expectedResult' => 'dataFromCache',
@@ -302,6 +309,7 @@ class AbstractBlockTest extends \PHPUnit_Framework_TestCase
                 'cacheLifetime' => '120string',
                 'dataFromCache' => 'dataFromCache',
                 'dataForSaveCache' => '',
+                'expectsDispatchEvent' => $this->exactly(2),
                 'expectsCacheLoad' => $this->once(),
                 'expectsCacheSave' => $this->never(),
                 'expectedResult' => 'dataFromCache',
@@ -310,6 +318,7 @@ class AbstractBlockTest extends \PHPUnit_Framework_TestCase
                 'cacheLifetime' => 120,
                 'dataFromCache' => false,
                 'dataForSaveCache' => '',
+                'expectsDispatchEvent' => $this->exactly(2),
                 'expectsCacheLoad' => $this->once(),
                 'expectsCacheSave' => $this->once(),
                 'expectedResult' => '',
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Element/Html/SelectTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Element/Html/SelectTest.php
index 6e1099810565457a5c054d4eede96fb8ee4dd42e..4986aa3e5873bd24e82f3afebbb0d47f7f70b743 100644
--- a/lib/internal/Magento/Framework/View/Test/Unit/Element/Html/SelectTest.php
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Element/Html/SelectTest.php
@@ -6,6 +6,7 @@
 namespace Magento\Framework\View\Test\Unit\Element\Html;
 
 use \Magento\Framework\View\Element\Html\Select;
+use Magento\Framework\Escaper;
 
 class SelectTest extends \PHPUnit_Framework_TestCase
 {
@@ -14,25 +15,27 @@ class SelectTest extends \PHPUnit_Framework_TestCase
      */
     protected $select;
 
+    /**
+     * @var Escaper|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $escaper;
+
     protected function setUp()
     {
         $eventManager = $this->getMock(\Magento\Framework\Event\ManagerInterface::class);
 
         $scopeConfig = $this->getMock(\Magento\Framework\App\Config\ScopeConfigInterface::class);
 
-        $escaper = $this->getMockBuilder(\Magento\Framework\Escaper::class)
+        $this->escaper = $this->getMockBuilder(\Magento\Framework\Escaper::class)
             ->disableOriginalConstructor()
             ->getMock();
-        $escaper->expects($this->any())
-            ->method('escapeHtml')
-            ->will($this->returnArgument(0));
 
         $context = $this->getMockBuilder(\Magento\Framework\View\Element\Context::class)
             ->disableOriginalConstructor()
             ->getMock();
         $context->expects($this->once())
             ->method('getEscaper')
-            ->will($this->returnValue($escaper));
+            ->will($this->returnValue($this->escaper));
         $context->expects($this->once())
             ->method('getEventManager')
             ->will($this->returnValue($eventManager));
@@ -92,8 +95,52 @@ class SelectTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($selectTitle, $this->select->getTitle());
     }
 
+    public function testGetHtmlJs()
+    {
+        $this->escaper->expects($this->any())
+            ->method('escapeHtml')
+            ->will($this->returnArgument(0));
+        $this->escaper->expects($this->any())
+            ->method('escapeHtmlAttr')
+            ->will($this->returnArgument(0));
+
+        $selectId = 'testId';
+        $selectClass = 'testClass';
+        $selectTitle = 'testTitle';
+        $selectName = 'testName';
+
+        $options = [
+            'testValue' => 'testLabel',
+            'selectedValue' => 'selectedLabel',
+        ];
+        $selectedValue = 'selectedValue';
+
+        $this->select->setId($selectId);
+        $this->select->setClass($selectClass);
+        $this->select->setTitle($selectTitle);
+        $this->select->setName($selectName);
+        $this->select->setOptions($options);
+        $this->select->setValue($selectedValue);
+
+        $result = '<select name="testName" id="testId" class="testClass" title="testTitle" >'
+            . '<option value="testValue" <%= option_extra_attrs.option_4016862802 %> >testLabel</option>'
+            . '<option value="selectedValue" selected="selected" <%= option_extra_attrs.option_662265145 %> >'
+            . 'selectedLabel</option>'
+            . '</select>';
+
+        $this->select->setIsRenderToJsTemplate(true);
+        $this->assertEquals($result, $this->select->getHtml());
+    }
+
     public function testGetHtml()
     {
+        $this->escaper->expects($this->any())
+            ->method('escapeHtml')
+            ->will($this->returnArgument(0));
+        $this->escaper->expects($this->any())
+            ->method('escapeHtmlAttr')
+            ->will($this->returnArgument(0));
+
         $selectId = 'testId';
         $selectClass = 'testClass';
         $selectTitle = 'testTitle';
@@ -137,33 +184,112 @@ class SelectTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($result, $this->select->getHtml());
     }
 
-    public function testGetHtmlJs()
+    public function testGetHtmlEscapes()
     {
-        $selectId = 'testId';
-        $selectClass = 'testClass';
-        $selectTitle = 'testTitle';
-        $selectName = 'testName';
+        $this->escaper->expects($this->any())
+            ->method('escapeHtml')
+            ->will($this->returnValue('ESCAPED'));
+        $this->escaper->expects($this->any())
+            ->method('escapeHtmlAttr')
+            ->will($this->returnValue('ESCAPED_ATTR'));
 
-        $options = [
-            'testValue' => 'testLabel',
-            'selectedValue' => 'selectedLabel',
+        $optionsSets = [
+            $this->getOptionsWithSingleQuotes(),
+            $this->getOptionsWithDoubleQuotes()
         ];
-        $selectedValue = 'selectedValue';
-
-        $this->select->setId($selectId);
-        $this->select->setClass($selectClass);
-        $this->select->setTitle($selectTitle);
-        $this->select->setName($selectName);
-        $this->select->setOptions($options);
-        $this->select->setValue($selectedValue);
 
-        $result = '<select name="testName" id="testId" class="testClass" title="testTitle" >'
-            . '<option value="testValue" <%= option_extra_attrs.option_4016862802 %> >testLabel</option>'
-            . '<option value="selectedValue" selected="selected" <%= option_extra_attrs.option_662265145 %> >'
-            . 'selectedLabel</option>'
+        $expectedResult = '<select name="test[name]" id="testId" class="test class" title="ESCAPED" >'
+            .   '<option value="ESCAPED"  paramKey="ESCAPED" >ESCAPED</option>'
+            .   '<option value="ESCAPED" selected="selected" >ESCAPED</option>'
+            .   '<optgroup label="ESCAPED" data-optgroup-name="ESCAPED">'
+            .       '<option value="ESCAPED" >ESCAPED</option>'
+            .       '<option value="ESCAPED" selected="selected" >ESCAPED</option>'
+            .   '</optgroup>'
             . '</select>';
 
-        $this->select->setIsRenderToJsTemplate(true);
-        $this->assertEquals($result, $this->select->getHtml());
+        foreach ($optionsSets as $inOptions) {
+            $this->select->setId($inOptions['id']);
+            $this->select->setClass($inOptions['class']);
+            $this->select->setTitle($inOptions['title']);
+            $this->select->setName($inOptions['name']);
+
+            foreach ($inOptions['options'] as $option) {
+                $this->select->addOption($option['value'], $option['label'], $option['params']);
+            }
+            $this->select->setValue($inOptions['values']);
+
+            $this->assertEquals($expectedResult, $this->select->getHtml());
+
+            // reset
+            $this->select->setOptions([]);
+        }
+    }
+
+    /**
+     * @return array
+     */
+    private function getOptionsWithSingleQuotes()
+    {
+        return [
+            'id' => "testId",
+            'name' => "test[name]",
+            'class' => "test class",
+            'title' => "test'Title",
+            'options' => [
+                'regular' => [
+                    'value' => 'testValue',
+                    'label' => "test'Label",
+                    'params' => ['paramKey' => "param'Value"]
+                ],
+                'selected' => [
+                    'value' => 'selectedValue',
+                    'label' => "selected'Label",
+                    'params' => []
+                ],
+                'optgroup' => [
+                    'value' => [
+                        'groupElementValue' => "GroupElement'Label",
+                        'selectedGroupElementValue' => "SelectedGroupElement'Label"
+                    ],
+                    'label' => "group'Label",
+                    'params' => []
+                ]
+            ],
+            'values' => ['selectedValue', 'selectedGroupElementValue']
+        ];
+    }
+
+    /**
+     * @return array
+     */
+    private function getOptionsWithDoubleQuotes()
+    {
+        return [
+            'id' => 'testId',
+            'name' => 'test[name]',
+            'class' => 'test class',
+            'title' => 'test"Title',
+            'options' => [
+                'regular' => [
+                    'value' => 'testValue',
+                    'label' => 'test"Label',
+                    'params' => ['paramKey' => 'param"Value']
+                ],
+                'selected' => [
+                    'value' => 'selectedValue',
+                    'label' => 'selected"Label',
+                    'params' => []
+                ],
+                'optgroup' => [
+                    'value' => [
+                        'groupElementValue' => 'GroupElement"Label',
+                        'selectedGroupElementValue' => 'SelectedGroupElement"Label'
+                    ],
+                    'label' => 'group"Label',
+                    'params' => []
+                ]
+            ],
+            'values' => ['selectedValue', 'selectedGroupElementValue']
+        ];
     }
 }
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Layout/_files/arguments.xml b/lib/internal/Magento/Framework/View/Test/Unit/Layout/_files/arguments.xml
index 3be95e59dfa1115f97cddc0f3c5f4f01ebce251a..d92121ddb77be765fd291832d53b0a1eb289d695 100644
--- a/lib/internal/Magento/Framework/View/Test/Unit/Layout/_files/arguments.xml
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Layout/_files/arguments.xml
@@ -33,7 +33,7 @@
                     <item name="label" xsi:type="string">Excel XML</item>
                 </argument>
                 <argument name="testArrayWithUpdater" xsi:type="array">
-                    <updater>Magento\Sales\Model\Order\Grid\Massaction\ItemsUpdater</updater>
+                    <updater>Magento\Framework\View\Layout\Argument\UpdaterInterface</updater>
                     <item name="add" xsi:type="array">
                         <item name="label" xsi:type="string" translate="true">Move to Archive</item>
                         <item name="url" xsi:type="string">*/sales_archive/massAdd</item>
diff --git a/lib/internal/Magento/Framework/composer.json b/lib/internal/Magento/Framework/composer.json
index e86bed1c03fafc40369900f092fc0a6b59d5d108..98338ed4b099d202ce7d8e482b2bda9e3a675068 100644
--- a/lib/internal/Magento/Framework/composer.json
+++ b/lib/internal/Magento/Framework/composer.json
@@ -20,7 +20,9 @@
         "ext-openssl": "*",
         "lib-libxml": "*",
         "ext-xsl": "*",
-        "symfony/process": "~2.1"
+        "symfony/process": "~2.1",
+        "zendframework/zend-stdlib": "~2.4.6",
+        "zendframework/zend-http": "~2.4.6"
     },
     "suggest": {
         "ext-imagick": "Use Image Magick >=3.0.0 as an optional alternative image processing library"
diff --git a/lib/web/fotorama/fotorama.js b/lib/web/fotorama/fotorama.js
index f92fa7209abfe1374e34f733911c6f02514a38da..1f489fa31d07c0a300287cb78a0bcd739c9c014e 100644
--- a/lib/web/fotorama/fotorama.js
+++ b/lib/web/fotorama/fotorama.js
@@ -1433,8 +1433,14 @@ fotoramaVersion = '4.6.4';
                 xWin = (tail.go || tail.x || xyDiff >= 0) && !tail.noSwipe,
                 yWin = xyDiff < 0;
 
-            stopEvent(e);
-            (options.onMove || noop).call(el, e, {touch: touchFLAG});
+            if (touchFLAG && !tail.checked) {
+                if (touchEnabledFLAG = xWin) {
+                    stopEvent(e);
+                }
+            } else {
+                stopEvent(e);
+                (options.onMove || noop).call(el, e, {touch: touchFLAG});
+            }
 
             if (!moved && Math.sqrt(Math.pow(xDiff, 2) + Math.pow(yDiff, 2)) > tolerance) {
                 moved = true;
diff --git a/lib/web/fotorama/fotorama.min.js b/lib/web/fotorama/fotorama.min.js
index ca94e77cebd1f5a5a9988bb69bd7262b524a3c88..0139babea4bfe4ac65e364a36436fc757d981878 100644
--- a/lib/web/fotorama/fotorama.min.js
+++ b/lib/web/fotorama/fotorama.min.js
@@ -1,5 +1,5 @@
 /*!
  * Fotorama 4.6.4 | http://fotorama.io/license/
  */
-fotoramaVersion="4.6.4",function(t,n,e,o,i){"use strict";function a(t){var n="bez_"+o.makeArray(arguments).join("_").replace(".","p");if("function"!=typeof o.easing[n]){var e=function(t,n){var e=[null,null],o=[null,null],i=[null,null],a=function(a,r){return i[r]=3*t[r],o[r]=3*(n[r]-t[r])-i[r],e[r]=1-i[r]-o[r],a*(i[r]+a*(o[r]+a*e[r]))},r=function(t){return i[0]+t*(2*o[0]+3*e[0]*t)},s=function(t){for(var n,e=t,o=0;++o<14&&(n=a(e,0)-t,!(Math.abs(n)<.001));)e-=n/r(e);return e};return function(t){return a(s(t),1)}};o.easing[n]=function(n,o,i,a,r){return a*e([t[0],t[1]],[t[2],t[3]])(o/r)+i}}return n}function r(){}function s(t,n,e){return Math.max(isNaN(n)?-(1/0):n,Math.min(isNaN(e)?1/0:e,t))}function u(t,n){return t.match(/ma/)&&t.match(/-?\d+(?!d)/g)[t.match(/3d/)?"vertical"===n?13:12:"vertical"===n?5:4]}function c(t,n){return Ln?+u(t.css("transform"),n):+t.css("vertical"===n?"top":"left").replace("px","")}function l(t,n){var e={};if(Ln)switch(n){case"vertical":e.transform="translate3d(0, "+t+"px,0)";break;case"list":break;default:e.transform="translate3d("+t+"px,0,0)"}else"vertical"===n?e.top=t:e.left=t;return e}function d(t){return{"transition-duration":t+"ms"}}function h(t,n){return isNaN(t)?n:t}function f(t,n){return h(+String(t).replace(n||"px",""))}function m(t){return/%$/.test(t)?f(t,"%"):i}function v(t,n){return h(m(t)/100*n,f(t))}function p(t){return(!isNaN(f(t))||!isNaN(f(t,"%")))&&t}function g(t,n,e,o){return(t-(o||0))*(n+(e||0))}function w(t,n,e,o){return-Math.round(t/(n+(e||0))-(o||0))}function b(t){var n=t.data();if(!n.tEnd){var e=t[0],o={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",msTransition:"MSTransitionEnd",transition:"transitionend"};Q(e,o[Pn.prefixed("transition")],function(t){n.tProp&&t.propertyName.match(n.tProp)&&n.onEndFn()}),n.tEnd=!0}}function y(t,n,e,o){var i,a=t.data();a&&(a.onEndFn=function(){i||(i=!0,clearTimeout(a.tT),e())},a.tProp=n,clearTimeout(a.tT),a.tT=setTimeout(function(){a.onEndFn()},1.5*o),b(t))}function x(t,n){var e=t.navdir||"horizontal";if(t.length){var o=t.data();Ln?(t.css(d(0)),o.onEndFn=r,clearTimeout(o.tT)):t.stop();var i=_(n,function(){return c(t,e)});return t.css(l(i,e)),i}}function _(){for(var t,n=0,e=arguments.length;e>n&&(t=n?arguments[n]():arguments[n],"number"!=typeof t);n++);return t}function C(t,n){return Math.round(t+(n-t)/1.5)}function k(){return k.p=k.p||("https:"===e.protocol?"https://":"http://"),k.p}function S(t){var e=n.createElement("a");return e.href=t,e}function P(t,n){if("string"!=typeof t)return t;t=S(t);var e,o;if(t.host.match(/youtube\.com/)&&t.search){if(e=t.search.split("v=")[1]){var i=e.indexOf("&");-1!==i&&(e=e.substring(0,i)),o="youtube"}}else t.host.match(/youtube\.com|youtu\.be/)?(e=t.pathname.replace(/^\/(embed\/|v\/)?/,"").replace(/\/.*/,""),o="youtube"):t.host.match(/vimeo\.com/)&&(o="vimeo",e=t.pathname.replace(/^\/(video\/)?/,"").replace(/\/.*/,""));return e&&o||!n||(e=t.href,o="custom"),e?{id:e,type:o,s:t.search.replace(/^\?/,""),p:k()}:!1}function T(t,n,e){var i,a,r=t.video;return"youtube"===r.type?(a=k()+"img.youtube.com/vi/"+r.id+"/default.jpg",i=a.replace(/\/default.jpg$/,"/hqdefault.jpg"),t.thumbsReady=!0):"vimeo"===r.type?o.ajax({url:k()+"vimeo.com/api/v2/video/"+r.id+".json",dataType:"jsonp",success:function(o){t.thumbsReady=!0,F(n,{img:o[0].thumbnail_large,thumb:o[0].thumbnail_small},t.i,e)}}):t.thumbsReady=!0,{img:i,thumb:a}}function F(t,n,e,i){for(var a=0,r=t.length;r>a;a++){var s=t[a];if(s.i===e&&s.thumbsReady){var u={videoReady:!0};u[Jn]=u[te]=u[Zn]=!1,i.splice(a,1,o.extend({},s,u,n));break}}}function E(t){function n(t,n,i){var a=t.children("img").eq(0),r=t.attr("href"),s=t.attr("src"),u=a.attr("src"),c=n.video,l=i?P(r,c===!0):!1;l?r=!1:l=c,e(t,a,o.extend(n,{video:l,img:n.img||r||s||u,thumb:n.thumb||u||s||r}))}function e(t,n,e){var i=e.thumb&&e.img!==e.thumb,a=f(e.width||t.attr("width")),r=f(e.height||t.attr("height"));o.extend(e,{width:a,height:r,thumbratio:K(e.thumbratio||f(e.thumbwidth||n&&n.attr("width")||i||a)/f(e.thumbheight||n&&n.attr("height")||i||r))})}var i=[];return t.children().each(function(){var t=o(this),a=H(o.extend(t.data(),{id:t.attr("id")}));if(t.is("a, img"))n(t,a,!0);else{if(t.is(":empty"))return;e(t,null,o.extend(a,{html:this,_html:t.html()}))}i.push(a)}),i}function M(t){return 0===t.offsetWidth&&0===t.offsetHeight}function j(t){return!o.contains(n.documentElement,t)}function $(t,n,e,o){return $.i||($.i=1,$.ii=[!0]),o=o||$.i,"undefined"==typeof $.ii[o]&&($.ii[o]=!0),t()?n():$.ii[o]&&setTimeout(function(){$.ii[o]&&$(t,n,e,o)},e||100),$.i++}function z(t,n){var e=t.data(),o=e.measures;if(o&&(!e.l||e.l.W!==o.width||e.l.H!==o.height||e.l.r!==o.ratio||e.l.w!==n.w||e.l.h!==n.h)){var i=s(n.h,0,o.height),a=i*o.ratio;he.setRatio(t,a,i),e.l={W:o.width,H:o.height,r:o.ratio,w:n.w,h:n.h}}return!0}function q(t,n){var e=t[0];e.styleSheet?e.styleSheet.cssText=n:t.html(n)}function N(t,n,e,o){return n===e?!1:"vertical"===o?n>=t?"top":t>=e?"bottom":"top bottom":n>=t?"left":t>=e?"right":"left right"}function A(t,n,e){e=e||{},t.each(function(){var t,i=o(this),a=i.data();a.clickOn||(a.clickOn=!0,o.extend(ot(i,{onStart:function(n){t=n,(e.onStart||r).call(this,n)},onMove:e.onMove||r,onTouchEnd:e.onTouchEnd||r,onEnd:function(e){e.moved||n.call(this,t)}}),{noMove:!0}))})}function L(t,n){return'<div class="'+t+'">'+(n||"")+"</div>"}function O(t){return"."+t}function D(t){var n='<iframe src="'+t.p+t.type+".com/embed/"+t.id+'" frameborder="0" allowfullscreen></iframe>';return n}function I(t){for(var n=t.length;n;){var e=Math.floor(Math.random()*n--),o=t[n];t[n]=t[e],t[e]=o}return t}function W(t){return"[object Array]"==Object.prototype.toString.call(t)&&o.map(t,function(t){return o.extend({},t)})}function R(t,n,e){t.scrollLeft(n||0).scrollTop(e||0)}function H(t){if(t){var n={};return o.each(t,function(t,e){n[t.toLowerCase()]=e}),n}}function K(t){if(t){var n=+t;return isNaN(n)?(n=t.split("/"),+n[0]/+n[1]||i):n}}function Q(t,n,e,o){n&&(t.addEventListener?t.addEventListener(n,e,!!o):t.attachEvent("on"+n,e))}function V(t,n){return t>n.max?t=n.max:t<n.min&&(t=n.min),t}function X(t,n,e,o,i,a,r){var s,u,c;return"horizontal"===r?(u=t.thumbwidth,c=a.width()):(u=t.thumbheight,c=a.height()),s=(u+t.margin)*(e+1)>=c-o?"horizontal"===r?-i.position().left:-i.position().top:(u+t.margin)*e<=Math.abs(o)?"horizontal"===r?-i.position().left+c-(u+t.margin):-i.position().top+c-(u+t.margin):o,s=V(s,n),s||0}function B(t){return!!t.getAttribute("disabled")}function Y(t,n){return n?{disabled:t}:{tabindex:-1*t+"",disabled:t}}function U(t,n){Q(t,"keyup",function(e){B(t)||13==e.keyCode&&n.call(t,e)})}function G(t,n){Q(t,"focus",t.onfocusin=function(e){n.call(t,e)},!0)}function J(t,n){t.preventDefault?t.preventDefault():t.returnValue=!1,n&&t.stopPropagation&&t.stopPropagation()}function Z(t){return t?">":"<"}function tt(t,n){var e=t.data(),i=Math.round(n.pos),a=function(){e&&e.sliding&&(e.sliding=!1),(n.onEnd||r)()};"undefined"!=typeof n.overPos&&n.overPos!==n.pos&&(i=n.overPos);var s=o.extend(l(i,n.direction),n.width&&{width:n.width},n.height&&{height:n.height});e&&e.sliding&&(e.sliding=!0),Ln?(t.css(o.extend(d(n.time),s)),n.time>10?y(t,"transform",a,n.time):a()):t.stop().animate(s,n.time,ee,a)}function nt(t,n,e,i,a,s){var u="undefined"!=typeof s;if(u||(a.push(arguments),Array.prototype.push.call(arguments,a.length),!(a.length>1))){t=t||o(t),n=n||o(n);var c=t[0],l=n[0],d="crossfade"===i.method,h=function(){if(!h.done){h.done=!0;var t=(u||a.shift())&&a.shift();t&&nt.apply(this,t),(i.onEnd||r)(!!t)}},f=i.time/(s||1);e.removeClass(Kt+" "+Ht),t.stop().addClass(Kt),n.stop().addClass(Ht),d&&l&&t.fadeTo(0,0),t.fadeTo(d?f:0,1,d&&h),n.fadeTo(f,0,h),c&&d||l||h()}}function et(t){var n=(t.touches||[])[0]||t;t._x=n.pageX||n.originalEvent.pageX,t._y=n.clientY||n.originalEvent.clientY,t._now=o.now()}function ot(t,e){function i(t){return h=o(t.target),y.checked=v=p=w=!1,l||y.flow||t.touches&&t.touches.length>1||t.which>1||se&&se.type!==t.type&&ce||(v=e.select&&h.is(e.select,b))?v:(m="touchstart"===t.type,p=h.is("a, a *",b),f=y.control,g=y.noMove||y.noSwipe||f?16:y.snap?0:4,et(t),d=se=t,ue=t.type.replace(/down|start/,"move").replace(/Down/,"Move"),(e.onStart||r).call(b,t,{control:f,$target:h}),l=y.flow=!0,void((!m||y.go)&&J(t)))}function a(t){if(t.touches&&t.touches.length>1||Rn&&!t.isPrimary||ue!==t.type||!l)return l&&s(),void(e.onTouchEnd||r)();et(t);var n=Math.abs(t._x-d._x),o=Math.abs(t._y-d._y),i=n-o,a=(y.go||y.x||i>=0)&&!y.noSwipe,u=0>i;J(t),(e.onMove||r).call(b,t,{touch:m}),!w&&Math.sqrt(Math.pow(n,2)+Math.pow(o,2))>g&&(w=!0),y.checked=y.checked||a||u}function s(t){(e.onTouchEnd||r)();var n=l;y.control=l=!1,n&&(y.flow=!1),!n||p&&!y.checked||(t&&J(t),ce=!0,clearTimeout(le),le=setTimeout(function(){ce=!1},1e3),(e.onEnd||r).call(b,{moved:w,$target:h,control:f,touch:m,startEvent:d,aborted:!t||"MSPointerCancel"===t.type}))}function u(){y.flow||(y.flow=!0)}function c(){y.flow&&(y.flow=!1)}var l,d,h,f,m,v,p,g,w,b=t[0],y={};return Rn?(Q(b,"MSPointerDown",i),Q(n,"MSPointerMove",a),Q(n,"MSPointerCancel",s),Q(n,"MSPointerUp",s)):(Q(b,"touchstart",i),Q(b,"touchmove",a),Q(b,"touchend",s),Q(n,"touchstart",u),Q(n,"touchend",c),Q(n,"touchcancel",c),zn.on("scroll",c),t.on("mousedown pointerdown",i),qn.on("mousemove pointermove",a).on("mouseup pointerup",s)),de=Pn.touch?"a":"div",t.on("click",de,function(t){y.checked&&J(t)}),y}function it(t,n){function e(e,o){T=!0,c=d="vertical"===_?e._y:e._x,p=e._now,v=[[p,c]],h=f=M.noMove||o?0:x(t,(n.getPos||r)()),(n.onStart||r).call(F,e)}function i(n,o){w=M.min,b=M.max,y=M.snap,_=M.direction||"horizontal",t.navdir=_,k=n.altKey,T=P=!1,S=o.control,S||E.sliding||e(n)}function a(o,i){M.noSwipe||(T||e(o),d="vertical"===_?o._y:o._x,v.push([o._now,d]),f=h-(c-d),m=N(f,w,b,_),w>=f?f=C(f,w):f>=b&&(f=C(f,b)),M.noMove||(t.css(l(f,_)),P||(P=!0,i.touch||Rn||t.addClass(un)),(n.onMove||r).call(F,o,{pos:f,edge:m})))}function u(i){if(!M.noSwipe||!i.moved){T||e(i.startEvent,!0),i.touch||Rn||t.removeClass(un),g=o.now();for(var a,u,c,l,m,p,x,C,S,P=g-Kn,E=null,j=Qn,$=n.friction,z=v.length-1;z>=0;z--){if(a=v[z][0],u=Math.abs(a-P),null===E||c>u)E=a,l=v[z][1];else if(E===P||u>c)break;c=u}x=s(f,w,b);var q=l-d,N=q>=0,A=g-E,L=A>Kn,O=!L&&f!==h&&x===f;y&&(x=s(Math[O?N?"floor":"ceil":"round"](f/y)*y,w,b),w=b=x),O&&(y||x===f)&&(S=-(q/A),j*=s(Math.abs(S),n.timeLow,n.timeHigh),m=Math.round(f+S*j/$),y||(x=m),(!N&&m>b||N&&w>m)&&(p=N?w:b,C=m-p,y||(x=p),C=s(x+.03*C,p-50,p+50),j=Math.abs((f-C)/(S/$)))),j*=k?10:1,(n.onEnd||r).call(F,o.extend(i,{moved:i.moved||L&&y,pos:f,newPos:x,overPos:C,time:j,dir:_}))}}var c,d,h,f,m,v,p,g,w,b,y,_,k,S,P,T,F=t[0],E=t.data(),M={};return M=o.extend(ot(n.$wrap,o.extend({},n,{onStart:i,onMove:a,onEnd:u})),M)}function at(t,n){var e,i,a,s=t[0],u={prevent:{}};return Q(s,Hn,function(t){var s=t.wheelDeltaY||-1*t.deltaY||0,c=t.wheelDeltaX||-1*t.deltaX||0,l=Math.abs(c)&&!Math.abs(s),d=Z(0>c),h=i===d,f=o.now(),m=Kn>f-a;i=d,a=f,l&&u.ok&&(!u.prevent[d]||e)&&(J(t,!0),e&&h&&m||(n.shift&&(e=!0,clearTimeout(u.t),u.t=setTimeout(function(){e=!1},Vn)),(n.onEnd||r)(t,n.shift?d:c)))}),u}function rt(){o.each(o.Fotorama.instances,function(t,n){n.index=t})}function st(t){o.Fotorama.instances.push(t),rt()}function ut(t){o.Fotorama.instances.splice(t.index,1),rt()}var ct="fotorama",lt="fotorama__fullscreen",dt=ct+"__wrap",ht=dt+"--css2",ft=dt+"--css3",mt=dt+"--video",vt=dt+"--fade",pt=dt+"--slide",gt=dt+"--no-controls",wt=dt+"--no-shadows",bt=dt+"--pan-y",yt=dt+"--rtl",xt=dt+"--no-captions",_t=dt+"--toggle-arrows",Ct=ct+"__stage",kt=Ct+"__frame",St=kt+"--video",Pt=Ct+"__shaft",Tt=ct+"__grab",Ft=ct+"__pointer",Et=ct+"__arr",Mt=Et+"--disabled",jt=Et+"--prev",$t=Et+"--next",zt=ct+"__nav",qt=zt+"-wrap",Nt=zt+"__shaft",At=qt+"--vertical",Lt=qt+"--list",Ot=qt+"--horizontal",Dt=zt+"--dots",It=zt+"--thumbs",Wt=zt+"__frame",Rt=ct+"__fade",Ht=Rt+"-front",Kt=Rt+"-rear",Qt=ct+"__shadow",Vt=Qt+"s",Xt=Vt+"--left",Bt=Vt+"--right",Yt=Vt+"--top",Ut=Vt+"--bottom",Gt=ct+"__active",Jt=ct+"__select",Zt=ct+"--hidden",tn=ct+"--fullscreen",nn=ct+"__fullscreen-icon",en=ct+"__error",on=ct+"__loading",an=ct+"__loaded",rn=an+"--full",sn=an+"--img",un=ct+"__grabbing",cn=ct+"__img",ln=cn+"--full",dn=ct+"__thumb",hn=dn+"__arr--left",fn=dn+"__arr--right",mn=dn+"-border",vn=ct+"__html",pn=ct+"-video-container",gn=ct+"__video",wn=gn+"-play",bn=gn+"-close",yn=ct+"_horizontal_ratio",xn=ct+"_vertical_ratio",_n=ct+"__spinner",Cn=_n+"--show",kn=o&&o.fn.jquery.split(".");if(!kn||kn[0]<1||1==kn[0]&&kn[1]<8)throw"Fotorama requires jQuery 1.8 or later and will not run without it.";var Sn={},Pn=function(t,n,e){function o(t){g.cssText=t}function i(t,n){return typeof t===n}function a(t,n){return!!~(""+t).indexOf(n)}function r(t,n){for(var o in t){var i=t[o];if(!a(i,"-")&&g[i]!==e)return"pfx"==n?i:!0}return!1}function s(t,n,o){for(var a in t){var r=n[t[a]];if(r!==e)return o===!1?t[a]:i(r,"function")?r.bind(o||n):r}return!1}function u(t,n,e){var o=t.charAt(0).toUpperCase()+t.slice(1),a=(t+" "+y.join(o+" ")+o).split(" ");return i(n,"string")||i(n,"undefined")?r(a,n):(a=(t+" "+x.join(o+" ")+o).split(" "),s(a,n,e))}var c,l,d,h="2.8.3",f={},m=n.documentElement,v="modernizr",p=n.createElement(v),g=p.style,w=({}.toString," -webkit- -moz- -o- -ms- ".split(" ")),b="Webkit Moz O ms",y=b.split(" "),x=b.toLowerCase().split(" "),_={},C=[],k=C.slice,S=function(t,e,o,i){var a,r,s,u,c=n.createElement("div"),l=n.body,d=l||n.createElement("body");if(parseInt(o,10))for(;o--;)s=n.createElement("div"),s.id=i?i[o]:v+(o+1),c.appendChild(s);return a=["&#173;",'<style id="s',v,'">',t,"</style>"].join(""),c.id=v,(l?c:d).innerHTML+=a,d.appendChild(c),l||(d.style.background="",d.style.overflow="hidden",u=m.style.overflow,m.style.overflow="hidden",m.appendChild(d)),r=e(c,t),l?c.parentNode.removeChild(c):(d.parentNode.removeChild(d),m.style.overflow=u),!!r},P={}.hasOwnProperty;d=i(P,"undefined")||i(P.call,"undefined")?function(t,n){return n in t&&i(t.constructor.prototype[n],"undefined")}:function(t,n){return P.call(t,n)},Function.prototype.bind||(Function.prototype.bind=function(t){var n=this;if("function"!=typeof n)throw new TypeError;var e=k.call(arguments,1),o=function(){if(this instanceof o){var i=function(){};i.prototype=n.prototype;var a=new i,r=n.apply(a,e.concat(k.call(arguments)));return Object(r)===r?r:a}return n.apply(t,e.concat(k.call(arguments)))};return o}),_.touch=function(){var e;return"ontouchstart"in t||t.DocumentTouch&&n instanceof DocumentTouch?e=!0:S(["@media (",w.join("touch-enabled),("),v,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(t){e=9===t.offsetTop}),e},_.csstransforms3d=function(){var t=!!u("perspective");return t&&"webkitPerspective"in m.style&&S("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(n,e){t=9===n.offsetLeft&&3===n.offsetHeight}),t},_.csstransitions=function(){return u("transition")};for(var T in _)d(_,T)&&(l=T.toLowerCase(),f[l]=_[T](),C.push((f[l]?"":"no-")+l));return f.addTest=function(t,n){if("object"==typeof t)for(var o in t)d(t,o)&&f.addTest(o,t[o]);else{if(t=t.toLowerCase(),f[t]!==e)return f;n="function"==typeof n?n():n,"undefined"!=typeof enableClasses&&enableClasses&&(m.className+=" "+(n?"":"no-")+t),f[t]=n}return f},o(""),p=c=null,f._version=h,f._prefixes=w,f._domPrefixes=x,f._cssomPrefixes=y,f.testProp=function(t){return r([t])},f.testAllProps=u,f.testStyles=S,f.prefixed=function(t,n,e){return n?u(t,n,e):u(t,"pfx")},f}(t,n),Tn={ok:!1,is:function(){return!1},request:function(){},cancel:function(){},event:"",prefix:""},Fn="webkit moz o ms khtml".split(" ");if("undefined"!=typeof n.cancelFullScreen)Tn.ok=!0;else for(var En=0,Mn=Fn.length;Mn>En;En++)if(Tn.prefix=Fn[En],"undefined"!=typeof n[Tn.prefix+"CancelFullScreen"]){Tn.ok=!0;break}Tn.ok&&(Tn.event=Tn.prefix+"fullscreenchange",Tn.is=function(){switch(this.prefix){case"":return n.fullScreen;case"webkit":return n.webkitIsFullScreen;default:return n[this.prefix+"FullScreen"]}},Tn.request=function(t){return""===this.prefix?t.requestFullScreen():t[this.prefix+"RequestFullScreen"]()},Tn.cancel=function(t){return""===this.prefix?n.cancelFullScreen():n[this.prefix+"CancelFullScreen"]()});var jn,$n,zn=o(t),qn=o(n),Nn="quirks"===e.hash.replace("#",""),An=Pn.csstransforms3d,Ln=An&&!Nn,On=An||"CSS1Compat"===n.compatMode,Dn=Tn.ok,In=navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i),Wn=!Ln||In,Rn=navigator.msPointerEnabled,Hn="onwheel"in n.createElement("div")?"wheel":n.onmousewheel!==i?"mousewheel":"DOMMouseScroll",Kn=250,Qn=300,Vn=1400,Xn=5e3,Bn=2,Yn=64,Un=500,Gn=333,Jn="$stageFrame",Zn="$navDotFrame",te="$navThumbFrame",ne="auto",ee=a([.1,0,.25,1]),oe=1200,ie=1,ae={width:null,minwidth:null,maxwidth:"100%",height:null,minheight:null,maxheight:null,ratio:null,margin:Bn,nav:"dots",navposition:"bottom",navwidth:null,thumbwidth:Yn,thumbheight:Yn,thumbmargin:Bn,thumbborderwidth:Bn,allowfullscreen:!1,transition:"slide",clicktransition:null,transitionduration:Qn,captions:!0,startindex:0,loop:!1,autoplay:!1,stopautoplayontouch:!0,keyboard:!1,arrows:!0,click:!0,swipe:!1,trackpad:!1,shuffle:!1,direction:"ltr",shadows:!0,showcaption:!0,navdir:"horizontal",navarrows:!0,navtype:"thumbs"},re={left:!0,right:!0,down:!0,up:!0,space:!1,home:!1,end:!1};$.stop=function(t){$.ii[t]=!1};var se,ue,ce,le,de,he=function(){function t(t,n,e){var o=n/e;1>=o?(t.parent().removeClass(yn),t.parent().addClass(xn)):(t.parent().removeClass(xn),t.parent().addClass(yn))}function n(t,n,e){var a=e;t.attr(a)||t.attr(a)===i||t.attr(a,n),t.find("["+a+"]").length&&t.find("["+a+"]").each(function(){o(this).attr(a,n)})}function e(t,n,e){var o,i=!1;return o=t.showCaption===e||t.showCaption===!0?!0:!1,n?(t.caption&&o&&(i=!0),i):!1}return{setRatio:t,setThumbAttr:n,isExpectedCaption:e}}(he||{},jQuery);jQuery.Fotorama=function(e,a){function r(){o.each(qe,function(t,n){if(!n.i){n.i=_o++;var e=P(n.video,!0);if(e){var o={};n.video=e,n.img||n.thumb?n.thumbsReady=!0:o=T(n,qe,wo),F(qe,{img:o.img,thumb:o.thumb},n.i,wo)}}})}function u(t){return ro[t]}function h(){if(To!==i)if("vertical"==a.navdir){var t=a.thumbwidth+a.thumbmargin;To.css("left",t),jo.css("right",t),Wo.css("right",t),Po.css("width",Po.css("width")+t),Fo.css("max-width",Po.width()-t)}else To.css("left",""),jo.css("right",""),Wo.css("right",""),Po.css("width",Po.css("width")+t),Fo.css("max-width","")}function m(t){var n,e="keydown."+ct,i=ct+bo,r="keydown."+i,s="keyup."+i,c="resize."+i+" orientationchange."+i;t?(qn.on(r,function(t){var e,i;Le&&27===t.keyCode?(e=!0,_e(Le,!0,!0)):(wo.fullScreen||a.keyboard&&!wo.index)&&(27===t.keyCode?(e=!0,wo.cancelFullScreen()):t.shiftKey&&32===t.keyCode&&u("space")||37===t.keyCode&&u("left")||38===t.keyCode&&u("up")&&o(":focus").attr("data-gallery-role")?(wo.longPress.progress(),i="<"):32===t.keyCode&&u("space")||39===t.keyCode&&u("right")||40===t.keyCode&&u("down")&&o(":focus").attr("data-gallery-role")?(wo.longPress.progress(),i=">"):36===t.keyCode&&u("home")?(wo.longPress.progress(),i="<<"):35===t.keyCode&&u("end")&&(wo.longPress.progress(),i=">>")),(e||i)&&J(t),n={index:i,slow:t.altKey,user:!0},i&&(wo.longPress.inProgress?wo.showWhileLongPress(n):wo.show(n))}),t&&qn.on(s,function(t){wo.longPress.inProgress&&wo.showEndLongPress({user:!0}),wo.longPress.reset()}),wo.index||qn.off(e).on(e,"textarea, input, select",function(t){!$n.hasClass(lt)&&t.stopPropagation()}),zn.on(c,wo.resize)):(qn.off(r),zn.off(c))}function b(t){t!==b.f&&(t?(e.addClass(ct+" "+yo).before(So).before(ko),st(wo)):(So.detach(),ko.detach(),e.html(Co.urtext).removeClass(yo),ut(wo)),m(t),b.f=t)}function y(){qe=wo.data=qe||W(a.data)||E(e),Ne=wo.size=qe.length,ze.ok&&a.shuffle&&I(qe),r(),Xo=et(Xo),Ne&&b(!0)}function C(){var t=2>Ne||Le;Uo.noMove=t||Ze,Uo.noSwipe=t||!a.swipe,!oo&&Fo.toggleClass(Tt,!a.click&&!Uo.noMove&&!Uo.noSwipe),Rn&&Po.toggleClass(bt,!Uo.noSwipe)}function k(t){t===!0&&(t=""),a.autoplay=Math.max(+t||Xn,1.5*eo)}function S(t){t.navarrows&&"thumbs"===t.nav?(Do.show(),Io.show()):(Do.hide(),Io.hide())}function M(t,n){return Math.floor(Po.width()/(n.thumbwidth+n.thumbmargin))}function Q(){function t(t,e){n[t?"add":"remove"].push(e)}a.nav&&"dots"!==a.nav||(a.navdir="horizontal"),wo.options=a=H(a),ie=M(Po,a),Ze="crossfade"===a.transition||"dissolve"===a.transition,Xe=a.loop&&(Ne>2||Ze&&(!oo||"slide"!==oo)),eo=+a.transitionduration||Qn,ao="rtl"===a.direction,ro=o.extend({},a.keyboard&&re,a.keyboard),S(a);var n={add:[],remove:[]};Ne>1?(Be=a.nav,Ue="top"===a.navposition,n.remove.push(Jt),$o.toggle(a.arrows)):(Be=!1,$o.hide()),An(),Hn(),In(),a.autoplay&&k(a.autoplay),to=f(a.thumbwidth)||Yn,no=f(a.thumbheight)||Yn,Go.ok=Zo.ok=a.trackpad&&!Wn,C(),le(a,[Yo]),Ye="thumbs"===Be,zo.filter(":hidden")&&Be&&zo.show(),Ye?(kn(Ne,"navThumb"),Ae=Lo,go=te,q(ko,o.Fotorama.jst.style({w:to,h:no,b:a.thumbborderwidth,m:a.thumbmargin,s:bo,q:!On})),qo.addClass(It).removeClass(Dt)):"dots"===Be?(kn(Ne,"navDot"),Ae=Ao,go=Zn,qo.addClass(Dt).removeClass(It)):(zo.hide(),Be=!1,qo.removeClass(It+" "+Dt)),Be&&(Ue?zo.insertBefore(To):zo.insertAfter(To),En.nav=!1,En(Ae,No,"nav")),Ge=a.allowfullscreen,Ge?(Wo.prependTo(To),Je=Dn&&"native"===Ge):(Wo.detach(),Je=!1),t(Ze,vt),t(!Ze,pt),t(!a.captions,xt),t(ao,yt),t(a.arrows,_t),io=a.shadows&&!Wn,t(!io,wt),Po.addClass(n.add.join(" ")).removeClass(n.remove.join(" ")),Bo=o.extend({},a),h()}function B(t){return 0>t?(Ne+t%Ne)%Ne:t>=Ne?t%Ne:t}function et(t){return s(t,0,Ne-1)}function ot(t){return Xe?B(t):et(t)}function rt(t){return t>0||Xe?t-1:!1}function Rt(t){return Ne-1>t||Xe?t+1:!1}function Ht(){Uo.min=Xe?-(1/0):-g(Ne-1,Yo.w,a.margin,Ie),Uo.max=Xe?1/0:-g(0,Yo.w,a.margin,Ie),Uo.snap=Yo.w+a.margin}function Kt(){var t="vertical"===a.navdir,n=t?No.height():No.width(),e=t?Yo.h:Yo.nw;Jo.min=Math.min(0,e-n),Jo.max=0,Jo.direction=a.navdir,No.toggleClass(Tt,!(Jo.noMove=Jo.min===Jo.max))}function Qt(t,n,e){if("number"==typeof t){t=new Array(t);var i=!0}return o.each(t,function(t,o){if(i&&(o=t),"number"==typeof o){var a=qe[B(o)];if(a){var r="$"+n+"Frame",s=a[r];e.call(this,t,o,a,s,r,s&&s.data())}}})}function un(t,n,e,o){(!so||"*"===so&&o===Ve)&&(t=p(a.width)||p(t)||Un,n=p(a.height)||p(n)||Gn,wo.resize({width:t,ratio:a.ratio||e||t/n},0,o!==Ve&&"*"))}function dn(t,n,e,i){Qt(t,n,function(t,r,s,u,c,l){function d(t){var n=B(r);de(t,{index:n,src:y,frame:qe[n]})}function h(){g.remove(),o.Fotorama.cache[y]="error",s.html&&"stage"===n||!x||x===y?(!y||s.html||v?"stage"===n&&(u.trigger("f:load").removeClass(on+" "+en).addClass(an),d("load"),un()):(u.trigger("f:error").removeClass(on).addClass(en),d("error")),l.state="error",!(Ne>1&&qe[r]===s)||s.html||s.deleted||s.video||v||(s.deleted=!0,wo.splice(r,1))):(s[b]=y=x,l.$full=null,dn([r],n,e,!0))}function f(){o.Fotorama.measures[y]=w.measures=o.Fotorama.measures[y]||{width:p.width,height:p.height,ratio:p.width/p.height},un(w.measures.width,w.measures.height,w.measures.ratio,r),g.off("load error").addClass(""+(v?ln:cn)).attr("aria-hidden","false").prependTo(u),u.hasClass(kt)&&!u.hasClass(pn)&&u.attr("href",g.attr("src")),z(g,(o.isFunction(e)?e():e)||Yo),o.Fotorama.cache[y]=l.state="loaded",setTimeout(function(){u.trigger("f:load").removeClass(on+" "+en).addClass(an+" "+(v?rn:sn)),"stage"===n?d("load"):(s.thumbratio===ne||!s.thumbratio&&a.thumbratio===ne)&&(s.thumbratio=w.measures.ratio,je())},0)}function m(){var t=10;$(function(){return!vo||!t--&&!Wn},function(){f()})}if(u){var v=wo.fullScreen&&!l.$full&&"stage"===n;if(!l.$img||i||v){var p=new Image,g=o(p),w=g.data();l[v?"$full":"$img"]=g;var b="stage"===n?v?"full":"img":"thumb",y=s[b],x=v?s.img:s["stage"===n?"thumb":"img"];if("navThumb"===n&&(u=l.$wrap),!y)return void h();o.Fotorama.cache[y]?!function _(){"error"===o.Fotorama.cache[y]?h():"loaded"===o.Fotorama.cache[y]?setTimeout(m,0):setTimeout(_,100)}():(o.Fotorama.cache[y]="*",g.on("load",m).on("error",h)),l.state="",p.src=y,l.data.caption&&(p.alt=l.data.caption||""),l.data.full&&o(p).data("original",l.data.full),he.isExpectedCaption(s,a.showcaption)&&o(p).attr("aria-labelledby",s.labelledby)}}})}function yn(){var t=Oe[Jn];t&&!t.data().state&&(Vo.addClass(Cn),t.on("f:load f:error",function(){t.off("f:load f:error"),Vo.removeClass(Cn)}))}function xn(t){U(t,Fe),G(t,function(){setTimeout(function(){R(qo)},0),ee({time:eo,guessIndex:o(this).data().eq,minMax:Jo})})}function kn(t,n){Qt(t,n,function(t,e,i,r,s,u){if(!r){r=i[s]=Po[s].clone(),u=r.data(),u.data=i;var c=r[0],l="labelledby"+o.now();"stage"===n?(i.html&&o('<div class="'+vn+'"></div>').append(i._html?o(i.html).removeAttr("id").html(i._html):i.html).appendTo(r),i.id&&(l=i.id||l),i.labelledby=l,he.isExpectedCaption(i,a.showcaption)&&o(o.Fotorama.jst.frameCaption({caption:i.caption,labelledby:l})).appendTo(r),i.video&&r.addClass(St).append(Ho.clone()),G(c,function(){setTimeout(function(){R(To)},0),Se({index:u.eq,user:!0})}),Eo=Eo.add(r)):"navDot"===n?(xn(c),Ao=Ao.add(r)):"navThumb"===n&&(xn(c),u.$wrap=r.children(":first"),Lo=Lo.add(r),i.video&&u.$wrap.append(Ho.clone()))}})}function Sn(t,n){return t&&t.length&&z(t,n)}function Pn(t){Qt(t,"stage",function(t,n,e,i,r,s){if(i){var u=B(n);s.eq=u,ni[Jn][u]=i.css(o.extend({left:Ze?0:g(n,Yo.w,a.margin,Ie)},Ze&&d(0))),j(i[0])&&(i.appendTo(Fo),_e(e.$video)),Sn(s.$img,Yo),Sn(s.$full,Yo),!i.hasClass(kt)||"false"===i.attr("aria-hidden")&&i.hasClass(Gt)||i.attr("aria-hidden","true")}})}function Fn(t,n){var e,i;"thumbs"!==Be||isNaN(t)||(e=-t,i=-t+Yo.nw,"vertical"===a.navdir&&(t-=a.thumbheight,i=-t+Yo.h),Lo.each(function(){var t=o(this),r=t.data(),s=r.eq,u=function(){return{h:no,w:r.w}},c=u(),l="vertical"===a.navdir?r.t>i:r.l>i;c.w=r.w,r.l+r.w<e||l||Sn(r.$img,c)||n&&dn([s],"navThumb",u)}))}function En(t,n,e){if(!En[e]){var i="nav"===e&&Ye,r=0,s=0;n.append(t.filter(function(){for(var t,n=o(this),e=n.data(),i=0,a=qe.length;a>i;i++)if(e.data===qe[i]){t=!0,e.eq=i;break}return t||n.remove()&&!1}).sort(function(t,n){return o(t).data().eq-o(n).data().eq}).each(function(){var t=o(this),n=t.data();he.setThumbAttr(t,n.data.caption,"aria-label")}).each(function(){if(i){var t=o(this),n=t.data(),e=Math.round(no*n.data.thumbratio)||to,u=Math.round(to/n.data.thumbratio)||no;n.t=s,n.h=u,n.l=r,n.w=e,t.css({width:e}),s+=u+a.thumbmargin,r+=e+a.thumbmargin}})),En[e]=!0}}function Mn(t){return t-ei>Yo.w/3}function Nn(t){return!(Xe||Xo+t&&Xo-Ne+t||Le)}function An(){var t=Nn(0),n=Nn(1);Mo.toggleClass(Mt,t).attr(Y(t,!1)),jo.toggleClass(Mt,n).attr(Y(n,!1))}function In(){var t=!1,n=!1;if("thumbs"!==a.navtype||a.loop||(t=0==Xo?!0:!1,n=Xo==a.data.length-1?!0:!1),"slides"===a.navtype){var e=c(No,a.navdir);t=e>=Jo.max?!0:!1,n=e<=Jo.min?!0:!1}Do.toggleClass(Mt,t).attr(Y(t,!0)),Io.toggleClass(Mt,n).attr(Y(n,!0))}function Hn(){Go.ok&&(Go.prevent={"<":Nn(0),">":Nn(1)})}function Vn(t){var n,e,o,i,r=t.data();Ye?(n=r.l,e=r.t,o=r.w,i=r.h):(n=t.position().left,o=t.width());var s={c:n+o/2,min:-n+10*a.thumbmargin,max:-n+Yo.w-o-10*a.thumbmargin},u={c:e+i/2,min:-e+10*a.thumbmargin,max:-e+Yo.h-i-10*a.thumbmargin};return"vertical"===a.navdir?u:s}function Bn(t){var n=Oe[go].data();tt(Oo,{time:1.2*t,pos:"vertical"===a.navdir?n.t:n.l,width:n.w,height:n.h,direction:a.navdir})}function ee(t){var n,e,o,i,r,u,l,d,h=qe[t.guessIndex][go],f=a.navtype;h&&("thumbs"===f?(n=Jo.min!==Jo.max,o=t.minMax||n&&Vn(Oe[go]),i=n&&(t.keep&&ee.t?ee.l:s((t.coo||Yo.nw/2)-Vn(h).c,o.min,o.max)),r=n&&(t.keep&&ee.l?ee.l:s((t.coo||Yo.nw/2)-Vn(h).c,o.min,o.max)),u="vertical"===a.navdir?i:r,l=n&&s(u,Jo.min,Jo.max)||0,e=1.1*t.time,tt(No,{time:e,pos:l,direction:a.navdir,onEnd:function(){Fn(l,!0),In()}}),xe(qo,N(l,Jo.min,Jo.max,a.navdir)),ee.l=u):(d=c(No,a.navdir),e=1.11*t.time,l=X(a,Jo,t.guessIndex,d,h,zo,a.navdir),tt(No,{time:e,pos:l,direction:a.navdir,onEnd:function(){Fn(l,!0),In()}}),xe(qo,N(l,Jo.min,Jo.max,a.navdir))))}function ae(){se(go),ti[go].push(Oe[go].addClass(Gt).attr("data-active",!0))}function se(t){for(var n=ti[t];n.length;)n.shift().removeClass(Gt).attr("data-active",!1)}function ue(t){var n=ni[t];o.each(De,function(t,e){delete n[B(e)]}),o.each(n,function(t,e){delete n[t],e.detach()})}function ce(t){Ie=We=Xo;var n=Oe[Jn];n&&(se(Jn),ti[Jn].push(n.addClass(Gt).attr("data-active",!0)),n.hasClass(kt)&&n.attr("aria-hidden","false"),t||wo.showStage.onEnd(!0),x(Fo,0,!0),ue(Jn),Pn(De),Ht(),Kt(),U(Fo[0],function(){e.hasClass(tn)||(wo.requestFullScreen(),Wo.focus())}))}function le(t,n){t&&o.each(n,function(n,e){e&&o.extend(e,{width:t.width||e.width,height:t.height,minwidth:t.minwidth,maxwidth:t.maxwidth,minheight:t.minheight,maxheight:t.maxheight,ratio:K(t.ratio)})})}function de(t,n){e.trigger(ct+":"+t,[wo,n])}function fe(){clearTimeout(me.t),vo=1,a.stopautoplayontouch?wo.stopAutoplay():ho=!0}function me(){vo&&(a.stopautoplayontouch||(ve(),pe()),me.t=setTimeout(function(){vo=0},Qn+Kn))}function ve(){ho=!(!Le&&!fo)}function pe(){if(clearTimeout(pe.t),$.stop(pe.w),!a.autoplay||ho)return void(wo.autoplay&&(wo.autoplay=!1,de("stopautoplay")));wo.autoplay||(wo.autoplay=!0,de("startautoplay"));var t=Xo,n=Oe[Jn].data();pe.w=$(function(){return n.state||t!==Xo},function(){pe.t=setTimeout(function(){if(!ho&&t===Xo){var n=Qe,e=qe[n][Jn].data();pe.w=$(function(){return e.state||n!==Qe},function(){ho||n!==Qe||wo.show(Xe?Z(!ao):Qe)})}},a.autoplay)})}function ge(t){var n;return"object"!=typeof t?(n=t,t={}):n=t.index,n=">"===n?We+1:"<"===n?We-1:"<<"===n?0:">>"===n?Ne-1:n,n=isNaN(n)?i:n,n="undefined"==typeof n?Xo||0:n}function we(t){wo.activeIndex=Xo=ot(t),He=rt(Xo),Ke=Rt(Xo),Qe=B(Xo+(ao?-1:1)),De=[Xo,He,Ke],We=Xe?t:Xo}function be(t){var n=Math.abs(Re-We),e=_(t.time,function(){return Math.min(eo*(1+(n-1)/12),2*eo)});return t.slow&&(e*=10),e}function ye(){wo.fullScreen&&(wo.fullScreen=!1,Dn&&Tn.cancel(xo),$n.removeClass(lt),jn.removeClass(lt),e.removeClass(tn).insertAfter(So),Yo=o.extend({},mo),_e(Le,!0,!0),Te("x",!1),wo.resize(),dn(De,"stage"),R(zn,co,uo),de("fullscreenexit"))}function xe(t,n){io&&(t.removeClass(Xt+" "+Bt),t.removeClass(Yt+" "+Ut),n&&!Le&&t.addClass(n.replace(/^|\s/g," "+Vt+"--")))}function _e(t,n,e){n&&(Po.removeClass(mt),Le=!1,C()),t&&t!==Le&&(t.remove(),de("unloadvideo")),e&&(ve(),pe())}function Ce(t){Po.toggleClass(gt,t)}function ke(t){if(!Uo.flow){var n=t?t.pageX:ke.x,e=n&&!Nn(Mn(n))&&a.click;ke.p!==e&&To.toggleClass(Ft,e)&&(ke.p=e,ke.x=n)}}function Se(t){clearTimeout(Se.t),a.clicktransition&&a.clicktransition!==a.transition?setTimeout(function(){var n=a.transition;wo.setOptions({transition:a.clicktransition}),oo=n,Se.t=setTimeout(function(){wo.show(t)},10)},0):wo.show(t)}function Pe(t,n){var i=t.target,a=o(i);a.hasClass(wn)?wo.playVideo():i===Ro?wo.toggleFullScreen():Le?i===Qo&&_e(Le,!0,!0):e.hasClass(tn)||wo.requestFullScreen()}function Te(t,n){Uo[t]=Jo[t]=n}function Fe(t){var n=o(this).data().eq;Se("thumbs"===a.navtype?{index:n,slow:t.altKey,user:!0,coo:t._x-qo.offset().left}:{index:n,slow:t.altKey,user:!0})}function Ee(t){Se({index:$o.index(this)?">":"<",slow:t.altKey,user:!0})}function Me(t){G(t,function(){setTimeout(function(){R(To)},0),Ce(!1)})}function je(){if(y(),Q(),!je.i){je.i=!0;var t=a.startindex;Xo=Ie=We=Re=Ve=ot(t)||0}if(Ne){if($e())return;Le&&_e(Le,!0),De=[],ue(Jn),je.ok=!0,wo.show({index:Xo,time:0}),wo.resize()}else wo.destroy()}function $e(){return!$e.f===ao?($e.f=ao,Xo=Ne-1-Xo,wo.reverse(),!0):void 0}function ze(){ze.ok&&(ze.ok=!1,de("ready"))}jn=o("html"),$n=o("body");var qe,Ne,Ae,Le,Oe,De,Ie,We,Re,He,Ke,Qe,Ve,Xe,Be,Ye,Ue,Ge,Je,Ze,to,no,eo,oo,io,ao,ro,so,uo,co,lo,ho,fo,mo,vo,po,go,wo=this,bo=o.now(),yo=ct+bo,xo=e[0],_o=1,Co=e.data(),ko=o("<style></style>"),So=o(L(Zt)),Po=e.find(O(dt)),To=Po.find(O(Ct)),Fo=(To[0],e.find(O(Pt))),Eo=o(),Mo=e.find(O(jt)),jo=e.find(O($t)),$o=e.find(O(Et)),zo=e.find(O(qt)),qo=zo.find(O(zt)),No=qo.find(O(Nt)),Ao=o(),Lo=o(),Oo=(Fo.data(),No.data(),e.find(O(mn))),Do=e.find(O(hn)),Io=e.find(O(fn)),Wo=e.find(O(nn)),Ro=Wo[0],Ho=o(L(wn)),Ko=e.find(O(bn)),Qo=Ko[0],Vo=e.find(O(_n)),Xo=!1,Bo={},Yo={},Uo={},Go={},Jo={},Zo={},ti={},ni={},ei=0,oi=[];Po[Jn]=o('<div class="'+kt+'"></div>'),Po[te]=o(o.Fotorama.jst.thumb()),Po[Zn]=o(o.Fotorama.jst.dots()),ti[Jn]=[],ti[te]=[],
-    ti[Zn]=[],ni[Jn]={},Po.addClass(Ln?ft:ht),Co.fotorama=this,wo.startAutoplay=function(t){return wo.autoplay?this:(ho=fo=!1,k(t||a.autoplay),pe(),this)},wo.stopAutoplay=function(){return wo.autoplay&&(ho=fo=!0,pe()),this},wo.showSlide=function(t){var n,e=c(No,a.navdir),o=550,i="horizontal"===a.navdir?a.thumbwidth:a.thumbheight,r=function(){In()};"next"===t&&(n=e-(i+a.margin)*ie),"prev"===t&&(n=e+(i+a.margin)*ie),n=V(n,Jo),Fn(n,!0),tt(No,{time:o,pos:n,direction:a.navdir,onEnd:r})},wo.showWhileLongPress=function(t){if(!wo.longPress.singlePressInProgress){var n=ge(t);we(n);var e=be(t)/50,o=Oe;wo.activeFrame=Oe=qe[Xo];var i=o===Oe&&!t.user;return wo.showNav(i,t,e),this}},wo.showEndLongPress=function(t){if(!wo.longPress.singlePressInProgress){var n=ge(t);we(n);var e=be(t)/50,o=Oe;wo.activeFrame=Oe=qe[Xo];var i=o===Oe&&!t.user;return wo.showStage(i,t,e),lo="undefined"!=typeof Re&&Re!==Xo,Re=Xo,this}},wo.showStage=function(t,n,e){_e(Le,Oe.i!==qe[B(Ie)].i),kn(De,"stage"),Pn(Wn?[We]:[We,rt(We),Rt(We)]),Te("go",!0),t||de("show",{user:n.user,time:e}),ho=!0;var o=n.overPos,i=wo.showStage.onEnd=function(e){if(!i.ok){if(i.ok=!0,e||ce(!0),t||de("showend",{user:n.user}),!e&&oo&&oo!==a.transition)return wo.setOptions({transition:oo}),void(oo=!1);yn(),dn(De,"stage"),Te("go",!1),Hn(),ke(),ve(),pe(),wo.fullScreen?(Oe[Jn].find("."+ln).attr("aria-hidden",!1),Oe[Jn].find("."+cn).attr("aria-hidden",!0)):(Oe[Jn].find("."+ln).attr("aria-hidden",!0),Oe[Jn].find("."+cn).attr("aria-hidden",!1))}};if(Ze){var r=Oe[Jn],s=qe[Re]&&Xo!==Re?qe[Re][Jn]:null;nt(r,s,Eo,{time:e,method:a.transition,onEnd:i},oi)}else tt(Fo,{pos:-g(We,Yo.w,a.margin,Ie),overPos:o,time:e,onEnd:i});An()},wo.showNav=function(t,n,e){if(In(),Be){ae();var o=et(Xo+s(We-Re,-1,1));ee({time:e,coo:o!==Xo&&n.coo,guessIndex:"undefined"!=typeof n.coo?o:Xo,keep:t}),Ye&&Bn(e)}},wo.show=function(t){wo.longPress.singlePressInProgress=!0;var n=ge(t);we(n);var e=be(t),o=Oe;wo.activeFrame=Oe=qe[Xo];var i=o===Oe&&!t.user;return wo.showStage(i,t,e),wo.showNav(i,t,e),lo="undefined"!=typeof Re&&Re!==Xo,Re=Xo,wo.longPress.singlePressInProgress=!1,this},wo.requestFullScreen=function(){if(Ge&&!wo.fullScreen){var n=o((wo.activeFrame||{}).$stageFrame||{}).hasClass("fotorama-video-container");if(n)return;uo=zn.scrollTop(),co=zn.scrollLeft(),R(zn),Te("x",!0),mo=o.extend({},Yo),e.addClass(tn).appendTo($n.addClass(lt)),jn.addClass(lt),_e(Le,!0,!0),wo.fullScreen=!0,Je&&Tn.request(xo),wo.resize(),dn(De,"stage"),yn(),de("fullscreenenter"),"ontouchstart"in t||Wo.focus()}return this},wo.cancelFullScreen=function(){return Je&&Tn.is()?Tn.cancel(n):ye(),this},wo.toggleFullScreen=function(){return wo[(wo.fullScreen?"cancel":"request")+"FullScreen"]()},wo.resize=function(n){if(!qe)return this;var e=arguments[1]||0,i=arguments[2];ie=M(Po,a),le(wo.fullScreen?{width:o(t).width(),maxwidth:null,minwidth:null,height:o(t).height(),maxheight:null,minheight:null}:H(n),[Yo,i||wo.fullScreen||a]);var r=Yo.width,u=Yo.height,c=Yo.ratio,l=zn.height()-(Be?qo.height():0);if(p(r)&&(Po.css({width:""}),Po.css({height:""}),To.css({width:""}),To.css({height:""}),Fo.css({width:""}),Fo.css({height:""}),qo.css({width:""}),qo.css({height:""}),Po.css({minWidth:Yo.minwidth||0,maxWidth:Yo.maxwidth||oe}),"dots"===Be&&zo.hide(),r=Yo.W=Yo.w=Po.width(),Yo.nw=Be&&v(a.navwidth,r)||r,Fo.css({width:Yo.w,marginLeft:(Yo.W-Yo.w)/2}),u=v(u,l),u=u||c&&r/c)){if(r=Math.round(r),u=Yo.h=Math.round(s(u,v(Yo.minheight,l),v(Yo.maxheight,l))),To.css({width:r,height:u}),"vertical"!==a.navdir||wo.fullscreen||qo.width(a.thumbwidth+2*a.thumbmargin),"horizontal"!==a.navdir||wo.fullscreen||qo.height(a.thumbheight+2*a.thumbmargin),"dots"===Be&&(qo.width(r).height("auto"),zo.show()),"vertical"===a.navdir&&wo.fullScreen&&To.css("height",zn.height()),"horizontal"===a.navdir&&wo.fullScreen&&To.css("height",zn.height()-qo.height()),Be){switch(a.navdir){case"vertical":zo.removeClass(Ot),zo.removeClass(Lt),zo.addClass(At),qo.stop().animate({height:Yo.h,width:a.thumbwidth},e);break;case"list":zo.removeClass(At),zo.removeClass(Ot),zo.addClass(Lt);break;default:zo.removeClass(At),zo.removeClass(Lt),zo.addClass(Ot),qo.stop().animate({width:Yo.nw},e)}ce(),ee({guessIndex:Xo,time:e,keep:!0}),Ye&&En.nav&&Bn(e)}so=i||!0,ze.ok=!0,ze()}return ei=To.offset().left,h(),this},wo.setOptions=function(t){return o.extend(a,t),je(),this},wo.shuffle=function(){return qe&&I(qe)&&je(),this},wo.longPress={threshold:1,count:0,thumbSlideTime:20,progress:function(){this.inProgress||(this.count++,this.inProgress=this.count>this.threshold)},end:function(){this.inProgress&&(this.isEnded=!0)},reset:function(){this.count=0,this.inProgress=!1,this.isEnded=!1}},wo.destroy=function(){return wo.cancelFullScreen(),wo.stopAutoplay(),qe=wo.data=null,b(),De=[],ue(Jn),je.ok=!1,this},wo.playVideo=function(){var t=Oe,n=t.video,e=Xo;return"object"==typeof n&&t.videoReady&&(Je&&wo.fullScreen&&wo.cancelFullScreen(),$(function(){return!Tn.is()||e!==Xo},function(){e===Xo&&(t.$video=t.$video||o(L(gn)).append(D(n)),t.$video.appendTo(t[Jn]),Po.addClass(mt),Le=t.$video,C(),$o.blur(),Wo.blur(),de("loadvideo"))})),this},wo.stopVideo=function(){return _e(Le,!0,!0),this},wo.spliceByIndex=function(t,n){n.i=t+1,n.img&&o.ajax({url:n.img,type:"HEAD",success:function(){qe.splice(t,1,n),je()}})},To.on("mousemove",ke),Uo=it(Fo,{onStart:fe,onMove:function(t,n){xe(To,n.edge)},onTouchEnd:me,onEnd:function(t){var n;if(xe(To),n=(Rn&&!po||t.touch)&&a.arrows,(t.moved||n&&t.pos!==t.newPos&&!t.control)&&t.$target[0]!==Wo[0]){var e=w(t.newPos,Yo.w,a.margin,Ie);wo.show({index:e,time:Ze?eo:t.time,overPos:t.overPos,user:!0})}else t.aborted||t.control||Pe(t.startEvent,n)},timeLow:1,timeHigh:1,friction:2,select:"."+Jt+", ."+Jt+" *",$wrap:To,direction:"horizontal"}),Jo=it(No,{onStart:fe,onMove:function(t,n){xe(qo,n.edge)},onTouchEnd:me,onEnd:function(t){function n(){ee.l=t.newPos,ve(),pe(),Fn(t.newPos,!0),In()}if(t.moved)t.pos!==t.newPos?(ho=!0,tt(No,{time:t.time,pos:t.newPos,overPos:t.overPos,direction:a.navdir,onEnd:n}),Fn(t.newPos),io&&xe(qo,N(t.newPos,Jo.min,Jo.max,t.dir))):n();else{var e=t.$target.closest("."+Wt,No)[0];e&&Fe.call(e,t.startEvent)}},timeLow:.5,timeHigh:2,friction:5,$wrap:qo,direction:a.navdir}),Go=at(To,{shift:!0,onEnd:function(t,n){fe(),me(),wo.show({index:n,slow:t.altKey})}}),Zo=at(qo,{onEnd:function(t,n){fe(),me();var e=x(No)+.25*n;No.css(l(s(e,Jo.min,Jo.max),a.navdir)),io&&xe(qo,N(e,Jo.min,Jo.max,a.navdir)),Zo.prevent={"<":e>=Jo.max,">":e<=Jo.min},clearTimeout(Zo.t),Zo.t=setTimeout(function(){ee.l=e,Fn(e,!0)},Kn),Fn(e)}}),Po.hover(function(){setTimeout(function(){vo||Ce(!(po=!0))},0)},function(){po&&Ce(!(po=!1))}),A($o,function(t){J(t),Ee.call(this,t)},{onStart:function(){fe(),Uo.control=!0},onTouchEnd:me}),A(Do,function(t){J(t),"thumbs"===a.navtype?wo.show("<"):wo.showSlide("prev")}),A(Io,function(t){J(t),"thumbs"===a.navtype?wo.show(">"):wo.showSlide("next")}),$o.each(function(){U(this,function(t){Ee.call(this,t)}),Me(this)}),U(Ro,function(){e.hasClass(tn)?(wo.cancelFullScreen(),Fo.focus()):(wo.requestFullScreen(),Wo.focus())}),Me(Ro),o.each("load push pop shift unshift reverse sort splice".split(" "),function(t,n){wo[n]=function(){return qe=qe||[],"load"!==n?Array.prototype[n].apply(qe,arguments):arguments[0]&&"object"==typeof arguments[0]&&arguments[0].length&&(qe=W(arguments[0])),je(),wo}}),je()},o.fn.fotorama=function(n){return this.each(function(){var e=this,i=o(this),a=i.data(),r=a.fotorama;r?r.setOptions(n,!0):$(function(){return!M(e)},function(){a.urtext=i.html(),new o.Fotorama(i,o.extend({},ae,t.fotoramaDefaults,n,a))})})},o.Fotorama.instances=[],o.Fotorama.cache={},o.Fotorama.measures={},o=o||{},o.Fotorama=o.Fotorama||{},o.Fotorama.jst=o.Fotorama.jst||{},o.Fotorama.jst.dots=function(t){var n="";Sn.escape;return n+='<div class="fotorama__nav__frame fotorama__nav__frame--dot" tabindex="0" role="button" data-gallery-role="nav-frame" data-nav-type="thumb" aria-label>\r\n    <div class="fotorama__dot"></div>\r\n</div>'},o.Fotorama.jst.frameCaption=function(t){var n,e="";Sn.escape;return e+='<div class="fotorama__caption" aria-hidden="true">\r\n    <div class="fotorama__caption__wrap" id="'+(null==(n=t.labelledby)?"":n)+'">'+(null==(n=t.caption)?"":n)+"</div>\r\n</div>\r\n"},o.Fotorama.jst.style=function(t){var n,e="";Sn.escape;return e+=".fotorama"+(null==(n=t.s)?"":n)+" .fotorama__nav--thumbs .fotorama__nav__frame{\r\npadding:"+(null==(n=t.m)?"":n)+"px;\r\nheight:"+(null==(n=t.h)?"":n)+"px}\r\n.fotorama"+(null==(n=t.s)?"":n)+" .fotorama__thumb-border{\r\nheight:"+(null==(n=t.h)?"":n)+"px;\r\nborder-width:"+(null==(n=t.b)?"":n)+"px;\r\nmargin-top:"+(null==(n=t.m)?"":n)+"px}"},o.Fotorama.jst.thumb=function(t){var n="";Sn.escape;return n+='<div class="fotorama__nav__frame fotorama__nav__frame--thumb" tabindex="0" role="button" data-gallery-role="nav-frame" data-nav-type="thumb" aria-label>\r\n    <div class="fotorama__thumb">\r\n    </div>\r\n</div>'}}(window,document,location,"undefined"!=typeof jQuery&&jQuery);
\ No newline at end of file
+fotoramaVersion="4.6.4",function(a,b,c,d,e){"use strict";function Ba(a){var b="bez_"+d.makeArray(arguments).join("_").replace(".","p");if("function"!=typeof d.easing[b]){var c=function(a,b){var c=[null,null],d=[null,null],e=[null,null],f=function(f,g){return e[g]=3*a[g],d[g]=3*(b[g]-a[g])-e[g],c[g]=1-e[g]-d[g],f*(e[g]+f*(d[g]+f*c[g]))},g=function(a){return e[0]+a*(2*d[0]+3*c[0]*a)},h=function(a){for(var d,b=a,c=0;++c<14&&(d=f(b,0)-a,!(Math.abs(d)<.001));)b-=d/g(b);return b};return function(a){return f(h(a),1)}};d.easing[b]=function(b,d,e,f,g){return f*c([a[0],a[1]],[a[2],a[3]])(d/g)+e}}return b}function eb(){}function fb(a,b,c){return Math.max(isNaN(b)?-(1/0):b,Math.min(isNaN(c)?1/0:c,a))}function gb(a,b){return a.match(/ma/)&&a.match(/-?\d+(?!d)/g)[a.match(/3d/)?"vertical"===b?13:12:"vertical"===b?5:4]}function hb(a,b){return Ia?+gb(a.css("transform"),b):+a.css("vertical"===b?"top":"left").replace("px","")}function ib(a,b){var c={};if(Ia)switch(b){case"vertical":c.transform="translate3d(0, "+a+"px,0)";break;case"list":break;default:c.transform="translate3d("+a+"px,0,0)"}else"vertical"===b?c.top=a:c.left=a;return c}function jb(a){return{"transition-duration":a+"ms"}}function kb(a,b){return isNaN(a)?b:a}function lb(a,b){return kb(+String(a).replace(b||"px",""))}function mb(a){return/%$/.test(a)?lb(a,"%"):e}function nb(a,b){return kb(mb(a)/100*b,lb(a))}function ob(a){return(!isNaN(lb(a))||!isNaN(lb(a,"%")))&&a}function pb(a,b,c,d){return(a-(d||0))*(b+(c||0))}function qb(a,b,c,d){return-Math.round(a/(b+(c||0))-(d||0))}function rb(a){var b=a.data();if(!b.tEnd){var c=a[0],d={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",msTransition:"MSTransitionEnd",transition:"transitionend"};Rb(c,d[wa.prefixed("transition")],function(a){b.tProp&&a.propertyName.match(b.tProp)&&b.onEndFn()}),b.tEnd=!0}}function sb(a,b,c,d){var e,f=a.data();f&&(f.onEndFn=function(){e||(e=!0,clearTimeout(f.tT),c())},f.tProp=b,clearTimeout(f.tT),f.tT=setTimeout(function(){f.onEndFn()},1.5*d),rb(a))}function tb(a,b){var c=a.navdir||"horizontal";if(a.length){var d=a.data();Ia?(a.css(jb(0)),d.onEndFn=eb,clearTimeout(d.tT)):a.stop();var e=ub(b,function(){return hb(a,c)});return a.css(ib(e,c)),e}}function ub(){for(var a,b=0,c=arguments.length;b<c&&(a=b?arguments[b]():arguments[b],"number"!=typeof a);b++);return a}function vb(a,b){return Math.round(a+(b-a)/1.5)}function wb(){return wb.p=wb.p||("https:"===c.protocol?"https://":"http://"),wb.p}function xb(a){var c=b.createElement("a");return c.href=a,c}function yb(a,b){if("string"!=typeof a)return a;a=xb(a);var c,d;if(a.host.match(/youtube\.com/)&&a.search){if(c=a.search.split("v=")[1]){var e=c.indexOf("&");e!==-1&&(c=c.substring(0,e)),d="youtube"}}else a.host.match(/youtube\.com|youtu\.be/)?(c=a.pathname.replace(/^\/(embed\/|v\/)?/,"").replace(/\/.*/,""),d="youtube"):a.host.match(/vimeo\.com/)&&(d="vimeo",c=a.pathname.replace(/^\/(video\/)?/,"").replace(/\/.*/,""));return c&&d||!b||(c=a.href,d="custom"),!!c&&{id:c,type:d,s:a.search.replace(/^\?/,""),p:wb()}}function zb(a,b,c){var e,f,g=a.video;return"youtube"===g.type?(f=wb()+"img.youtube.com/vi/"+g.id+"/default.jpg",e=f.replace(/\/default.jpg$/,"/hqdefault.jpg"),a.thumbsReady=!0):"vimeo"===g.type?d.ajax({url:wb()+"vimeo.com/api/v2/video/"+g.id+".json",dataType:"jsonp",success:function(d){a.thumbsReady=!0,Ab(b,{img:d[0].thumbnail_large,thumb:d[0].thumbnail_small},a.i,c)}}):a.thumbsReady=!0,{img:e,thumb:f}}function Ab(a,b,c,e){for(var f=0,g=a.length;f<g;f++){var h=a[f];if(h.i===c&&h.thumbsReady){var i={videoReady:!0};i[Xa]=i[Za]=i[Ya]=!1,e.splice(f,1,d.extend({},h,i,b));break}}}function Bb(a){function c(a,b,c){var f=a.children("img").eq(0),g=a.attr("href"),h=a.attr("src"),i=f.attr("src"),j=b.video,k=!!c&&yb(g,j===!0);k?g=!1:k=j,e(a,f,d.extend(b,{video:k,img:b.img||g||h||i,thumb:b.thumb||i||h||g}))}function e(a,b,c){var e=c.thumb&&c.img!==c.thumb,f=lb(c.width||a.attr("width")),g=lb(c.height||a.attr("height"));d.extend(c,{width:f,height:g,thumbratio:Qb(c.thumbratio||lb(c.thumbwidth||b&&b.attr("width")||e||f)/lb(c.thumbheight||b&&b.attr("height")||e||g))})}var b=[];return a.children().each(function(){var a=d(this),f=Pb(d.extend(a.data(),{id:a.attr("id")}));if(a.is("a, img"))c(a,f,!0);else{if(a.is(":empty"))return;e(a,null,d.extend(f,{html:this,_html:a.html()}))}b.push(f)}),b}function Cb(a){return 0===a.offsetWidth&&0===a.offsetHeight}function Db(a){return!d.contains(b.documentElement,a)}function Eb(a,b,c,d){return Eb.i||(Eb.i=1,Eb.ii=[!0]),d=d||Eb.i,"undefined"==typeof Eb.ii[d]&&(Eb.ii[d]=!0),a()?b():Eb.ii[d]&&setTimeout(function(){Eb.ii[d]&&Eb(a,b,c,d)},c||100),Eb.i++}function Fb(a,b){var c=a.data(),d=c.measures;if(d&&(!c.l||c.l.W!==d.width||c.l.H!==d.height||c.l.r!==d.ratio||c.l.w!==b.w||c.l.h!==b.h)){var e=fb(b.h,0,d.height),f=e*d.ratio;$b.setRatio(a,f,e),c.l={W:d.width,H:d.height,r:d.ratio,w:b.w,h:b.h}}return!0}function Gb(a,b){var c=a[0];c.styleSheet?c.styleSheet.cssText=b:a.html(b)}function Hb(a,b,c,d){return b!==c&&("vertical"===d?a<=b?"top":a>=c?"bottom":"top bottom":a<=b?"left":a>=c?"right":"left right")}function Ib(a,b,c){c=c||{},a.each(function(){var f,a=d(this),e=a.data();e.clickOn||(e.clickOn=!0,d.extend(hc(a,{onStart:function(a){f=a,(c.onStart||eb).call(this,a)},onMove:c.onMove||eb,onTouchEnd:c.onTouchEnd||eb,onEnd:function(a){a.moved||b.call(this,f)}}),{noMove:!0}))})}function Jb(a,b){return'<div class="'+a+'">'+(b||"")+"</div>"}function Kb(a){return"."+a}function Lb(a){var b='<iframe src="'+a.p+a.type+".com/embed/"+a.id+'" frameborder="0" allowfullscreen></iframe>';return b}function Mb(a){for(var b=a.length;b;){var c=Math.floor(Math.random()*b--),d=a[b];a[b]=a[c],a[c]=d}return a}function Nb(a){return"[object Array]"==Object.prototype.toString.call(a)&&d.map(a,function(a){return d.extend({},a)})}function Ob(a,b,c){a.scrollLeft(b||0).scrollTop(c||0)}function Pb(a){if(a){var b={};return d.each(a,function(a,c){b[a.toLowerCase()]=c}),b}}function Qb(a){if(a){var b=+a;return isNaN(b)?(b=a.split("/"),+b[0]/+b[1]||e):b}}function Rb(a,b,c,d){b&&(a.addEventListener?a.addEventListener(b,c,!!d):a.attachEvent("on"+b,c))}function Sb(a,b){return a>b.max?a=b.max:a<b.min&&(a=b.min),a}function Tb(a,b,c,d,e,f,g){var h,i,j;return"horizontal"===g?(i=a.thumbwidth,j=f.width()):(i=a.thumbheight,j=f.height()),h=(i+a.margin)*(c+1)>=j-d?"horizontal"===g?-e.position().left:-e.position().top:(i+a.margin)*c<=Math.abs(d)?"horizontal"===g?-e.position().left+j-(i+a.margin):-e.position().top+j-(i+a.margin):d,h=Sb(h,b),h||0}function Ub(a){return!!a.getAttribute("disabled")}function Vb(a,b){return b?{disabled:a}:{tabindex:a*-1+"",disabled:a}}function Wb(a,b){Rb(a,"keyup",function(c){Ub(a)||13==c.keyCode&&b.call(a,c)})}function Xb(a,b){Rb(a,"focus",a.onfocusin=function(c){b.call(a,c)},!0)}function Yb(a,b){a.preventDefault?a.preventDefault():a.returnValue=!1,b&&a.stopPropagation&&a.stopPropagation()}function Zb(a){return a?">":"<"}function _b(a,b){var c=a.data(),e=Math.round(b.pos),f=function(){c&&c.sliding&&(c.sliding=!1),(b.onEnd||eb)()};"undefined"!=typeof b.overPos&&b.overPos!==b.pos&&(e=b.overPos);var g=d.extend(ib(e,b.direction),b.width&&{width:b.width},b.height&&{height:b.height});c&&c.sliding&&(c.sliding=!0),Ia?(a.css(d.extend(jb(b.time),g)),b.time>10?sb(a,"transform",f,b.time):f()):a.stop().animate(g,b.time,_a,f)}function ac(a,b,c,e,f,g){var h="undefined"!=typeof g;if(h||(f.push(arguments),Array.prototype.push.call(arguments,f.length),!(f.length>1))){a=a||d(a),b=b||d(b);var i=a[0],j=b[0],k="crossfade"===e.method,l=function(){if(!l.done){l.done=!0;var a=(h||f.shift())&&f.shift();a&&ac.apply(this,a),(e.onEnd||eb)(!!a)}},m=e.time/(g||1);c.removeClass(P+" "+O),a.stop().addClass(P),b.stop().addClass(O),k&&j&&a.fadeTo(0,0),a.fadeTo(k?m:0,1,k&&l),b.fadeTo(m,0,l),i&&k||j||l()}}function gc(a){var b=(a.touches||[])[0]||a;a._x=b.pageX||b.originalEvent.pageX,a._y=b.clientY||b.originalEvent.clientY,a._now=d.now()}function hc(a,c){function p(a){return i=d(a.target),f.checked=l=m=o=!1,g||f.flow||a.touches&&a.touches.length>1||a.which>1||bc&&bc.type!==a.type&&dc||(l=c.select&&i.is(c.select,e))?l:(k="touchstart"===a.type,m=i.is("a, a *",e),j=f.control,n=f.noMove||f.noSwipe||j?16:f.snap?0:4,gc(a),h=bc=a,cc=a.type.replace(/down|start/,"move").replace(/Down/,"Move"),(c.onStart||eb).call(e,a,{control:j,$target:i}),g=f.flow=!0,void(k&&!f.go||Yb(a)))}function q(a){if(a.touches&&a.touches.length>1||Na&&!a.isPrimary||cc!==a.type||!g)return g&&r(),void(c.onTouchEnd||eb)();gc(a);var b=Math.abs(a._x-h._x),d=Math.abs(a._y-h._y),i=b-d,j=(f.go||f.x||i>=0)&&!f.noSwipe,l=i<0;k&&!f.checked?(g=j)&&Yb(a):(Yb(a),(c.onMove||eb).call(e,a,{touch:k})),!o&&Math.sqrt(Math.pow(b,2)+Math.pow(d,2))>n&&(o=!0),f.checked=f.checked||j||l}function r(a){(c.onTouchEnd||eb)();var b=g;f.control=g=!1,b&&(f.flow=!1),!b||m&&!f.checked||(a&&Yb(a),dc=!0,clearTimeout(ec),ec=setTimeout(function(){dc=!1},1e3),(c.onEnd||eb).call(e,{moved:o,$target:i,control:j,touch:k,startEvent:h,aborted:!a||"MSPointerCancel"===a.type}))}function s(){f.flow||(f.flow=!0)}function t(){f.flow&&(f.flow=!1)}var g,h,i,j,k,l,m,n,o,e=a[0],f={};return Na?(Rb(e,"MSPointerDown",p),Rb(b,"MSPointerMove",q),Rb(b,"MSPointerCancel",r),Rb(b,"MSPointerUp",r)):(Rb(e,"touchstart",p),Rb(e,"touchmove",q),Rb(e,"touchend",r),Rb(b,"touchstart",s),Rb(b,"touchend",t),Rb(b,"touchcancel",t),Ca.on("scroll",t),a.on("mousedown pointerdown",p),Da.on("mousemove pointermove",q).on("mouseup pointerup",r)),fc=wa.touch?"a":"div",a.on("click",fc,function(a){f.checked&&Yb(a)}),f}function ic(a,b){function w(d,e){v=!0,g=h="vertical"===r?d._y:d._x,m=d._now,l=[[m,g]],i=j=f.noMove||e?0:tb(a,(b.getPos||eb)()),(b.onStart||eb).call(c,d)}function x(b,c){o=f.min,p=f.max,q=f.snap,r=f.direction||"horizontal",a.navdir=r,s=b.altKey,v=u=!1,t=c.control,t||e.sliding||w(b)}function y(d,e){f.noSwipe||(v||w(d),h="vertical"===r?d._y:d._x,l.push([d._now,h]),j=i-(g-h),k=Hb(j,o,p,r),j<=o?j=vb(j,o):j>=p&&(j=vb(j,p)),f.noMove||(a.css(ib(j,r)),u||(u=!0,e.touch||Na||a.addClass(ea)),(b.onMove||eb).call(c,d,{pos:j,edge:k})))}function z(e){if(!f.noSwipe||!e.moved){v||w(e.startEvent,!0),e.touch||Na||a.removeClass(ea),n=d.now();for(var k,m,t,x,y,z,A,B,D,g=n-Pa,u=null,C=Qa,E=b.friction,F=l.length-1;F>=0;F--){if(k=l[F][0],m=Math.abs(k-g),null===u||m<t)u=k,x=l[F][1];else if(u===g||m>t)break;t=m}A=fb(j,o,p);var G=x-h,H=G>=0,I=n-u,J=I>Pa,K=!J&&j!==i&&A===j;q&&(A=fb(Math[K?H?"floor":"ceil":"round"](j/q)*q,o,p),o=p=A),K&&(q||A===j)&&(D=-(G/I),C*=fb(Math.abs(D),b.timeLow,b.timeHigh),y=Math.round(j+D*C/E),q||(A=y),(!H&&y>p||H&&y<o)&&(z=H?o:p,B=y-z,q||(A=z),B=fb(A+.03*B,z-50,z+50),C=Math.abs((j-B)/(D/E)))),C*=s?10:1,(b.onEnd||eb).call(c,d.extend(e,{moved:e.moved||J&&q,pos:j,newPos:A,overPos:B,time:C,dir:r}))}}var g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,c=a[0],e=a.data(),f={};return f=d.extend(hc(b.$wrap,d.extend({},b,{onStart:x,onMove:y,onEnd:z})),f)}function jc(a,b){var e,f,g,c=a[0],h={prevent:{}};return Rb(c,Oa,function(a){var c=a.wheelDeltaY||-1*a.deltaY||0,i=a.wheelDeltaX||-1*a.deltaX||0,j=Math.abs(i)&&!Math.abs(c),k=Zb(i<0),l=f===k,m=d.now(),n=m-g<Pa;f=k,g=m,j&&h.ok&&(!h.prevent[k]||e)&&(Yb(a,!0),e&&l&&n||(b.shift&&(e=!0,clearTimeout(h.t),h.t=setTimeout(function(){e=!1},Ra)),(b.onEnd||eb)(a,b.shift?k:i)))}),h}function kc(){d.each(d.Fotorama.instances,function(a,b){b.index=a})}function lc(a){d.Fotorama.instances.push(a),kc()}function mc(a){d.Fotorama.instances.splice(a.index,1),kc()}var f="fotorama",g="fotorama__fullscreen",h=f+"__wrap",i=h+"--css2",j=h+"--css3",k=h+"--video",l=h+"--fade",m=h+"--slide",n=h+"--no-controls",o=h+"--no-shadows",p=h+"--pan-y",q=h+"--rtl",s=h+"--no-captions",t=h+"--toggle-arrows",u=f+"__stage",v=u+"__frame",w=v+"--video",x=u+"__shaft",y=f+"__grab",z=f+"__pointer",A=f+"__arr",B=A+"--disabled",C=A+"--prev",D=A+"--next",E=f+"__nav",F=E+"-wrap",G=E+"__shaft",H=F+"--vertical",I=F+"--list",J=F+"--horizontal",K=E+"--dots",L=E+"--thumbs",M=E+"__frame",N=f+"__fade",O=N+"-front",P=N+"-rear",Q=f+"__shadow",R=Q+"s",S=R+"--left",T=R+"--right",U=R+"--top",V=R+"--bottom",W=f+"__active",X=f+"__select",Y=f+"--hidden",Z=f+"--fullscreen",$=f+"__fullscreen-icon",_=f+"__error",aa=f+"__loading",ba=f+"__loaded",ca=ba+"--full",da=ba+"--img",ea=f+"__grabbing",fa=f+"__img",ga=fa+"--full",ha=f+"__thumb",ia=ha+"__arr--left",ja=ha+"__arr--right",ka=ha+"-border",la=f+"__html",ma=f+"-video-container",na=f+"__video",oa=na+"-play",pa=na+"-close",qa=f+"_horizontal_ratio",ra=f+"_vertical_ratio",sa=f+"__spinner",ta=sa+"--show",ua=d&&d.fn.jquery.split(".");if(!ua||ua[0]<1||1==ua[0]&&ua[1]<8)throw"Fotorama requires jQuery 1.8 or later and will not run without it.";var va={},wa=function(a,b,c){function y(a){i.cssText=a}function A(a,b){return typeof a===b}function B(a,b){return!!~(""+a).indexOf(b)}function C(a,b){for(var d in a){var e=a[d];if(!B(e,"-")&&i[e]!==c)return"pfx"!=b||e}return!1}function D(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:A(f,"function")?f.bind(d||b):f}return!1}function E(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+n.join(d+" ")+d).split(" ");return A(b,"string")||A(b,"undefined")?C(e,b):(e=(a+" "+o.join(d+" ")+d).split(" "),D(e,b,c))}var j,u,x,d="2.8.3",e={},f=b.documentElement,g="modernizr",h=b.createElement(g),i=h.style,l=({}.toString," -webkit- -moz- -o- -ms- ".split(" ")),m="Webkit Moz O ms",n=m.split(" "),o=m.toLowerCase().split(" "),p={},s=[],t=s.slice,v=function(a,c,d,e){var h,i,j,k,l=b.createElement("div"),m=b.body,n=m||b.createElement("body");if(parseInt(d,10))for(;d--;)j=b.createElement("div"),j.id=e?e[d]:g+(d+1),l.appendChild(j);return h=["&#173;",'<style id="s',g,'">',a,"</style>"].join(""),l.id=g,(m?l:n).innerHTML+=h,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=f.style.overflow,f.style.overflow="hidden",f.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),f.style.overflow=k),!!i},w={}.hasOwnProperty;x=A(w,"undefined")||A(w.call,"undefined")?function(a,b){return b in a&&A(a.constructor.prototype[b],"undefined")}:function(a,b){return w.call(a,b)},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if("function"!=typeof c)throw new TypeError;var d=t.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(t.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(t.call(arguments)))};return e}),p.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:v(["@media (",l.join("touch-enabled),("),g,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=9===a.offsetTop}),c},p.csstransforms3d=function(){var a=!!E("perspective");return a&&"webkitPerspective"in f.style&&v("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=9===b.offsetLeft&&3===b.offsetHeight}),a},p.csstransitions=function(){return E("transition")};for(var F in p)x(p,F)&&(u=F.toLowerCase(),e[u]=p[F](),s.push((e[u]?"":"no-")+u));return e.addTest=function(a,b){if("object"==typeof a)for(var d in a)x(a,d)&&e.addTest(d,a[d]);else{if(a=a.toLowerCase(),e[a]!==c)return e;b="function"==typeof b?b():b,"undefined"!=typeof enableClasses&&enableClasses&&(f.className+=" "+(b?"":"no-")+a),e[a]=b}return e},y(""),h=j=null,e._version=d,e._prefixes=l,e._domPrefixes=o,e._cssomPrefixes=n,e.testProp=function(a){return C([a])},e.testAllProps=E,e.testStyles=v,e.prefixed=function(a,b,c){return b?E(a,b,c):E(a,"pfx")},e}(a,b),xa={ok:!1,is:function(){return!1},request:function(){},cancel:function(){},event:"",prefix:""},ya="webkit moz o ms khtml".split(" ");if("undefined"!=typeof b.cancelFullScreen)xa.ok=!0;else for(var za=0,Aa=ya.length;za<Aa;za++)if(xa.prefix=ya[za],"undefined"!=typeof b[xa.prefix+"CancelFullScreen"]){xa.ok=!0;break}xa.ok&&(xa.event=xa.prefix+"fullscreenchange",xa.is=function(){switch(this.prefix){case"":return b.fullScreen;case"webkit":return b.webkitIsFullScreen;default:return b[this.prefix+"FullScreen"]}},xa.request=function(a){return""===this.prefix?a.requestFullScreen():a[this.prefix+"RequestFullScreen"]()},xa.cancel=function(a){return""===this.prefix?b.cancelFullScreen():b[this.prefix+"CancelFullScreen"]()});var Ea,Fa,Ca=d(a),Da=d(b),Ga="quirks"===c.hash.replace("#",""),Ha=wa.csstransforms3d,Ia=Ha&&!Ga,Ja=Ha||"CSS1Compat"===b.compatMode,Ka=xa.ok,La=navigator.userAgent.match(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i),Ma=!Ia||La,Na=navigator.msPointerEnabled,Oa="onwheel"in b.createElement("div")?"wheel":b.onmousewheel!==e?"mousewheel":"DOMMouseScroll",Pa=250,Qa=300,Ra=1400,Sa=5e3,Ta=2,Ua=64,Va=500,Wa=333,Xa="$stageFrame",Ya="$navDotFrame",Za="$navThumbFrame",$a="auto",_a=Ba([.1,0,.25,1]),ab=1200,bb=1,cb={width:null,minwidth:null,maxwidth:"100%",height:null,minheight:null,maxheight:null,ratio:null,margin:Ta,nav:"dots",navposition:"bottom",navwidth:null,thumbwidth:Ua,thumbheight:Ua,thumbmargin:Ta,thumbborderwidth:Ta,allowfullscreen:!1,transition:"slide",clicktransition:null,transitionduration:Qa,captions:!0,startindex:0,loop:!1,autoplay:!1,stopautoplayontouch:!0,keyboard:!1,arrows:!0,click:!0,swipe:!1,trackpad:!1,shuffle:!1,direction:"ltr",shadows:!0,showcaption:!0,navdir:"horizontal",navarrows:!0,navtype:"thumbs"},db={left:!0,right:!0,down:!0,up:!0,space:!1,home:!1,end:!1};Eb.stop=function(a){Eb.ii[a]=!1};var bc,cc,dc,ec,fc,$b=function(){function a(a,b,c){var d=b/c;d<=1?(a.parent().removeClass(qa),a.parent().addClass(ra)):(a.parent().removeClass(ra),a.parent().addClass(qa))}function b(a,b,c){var f=c;a.attr(f)||a.attr(f)===e||a.attr(f,b),a.find("["+f+"]").length&&a.find("["+f+"]").each(function(){d(this).attr(f,b)})}function c(a,b,c){var e,d=!1;return e=a.showCaption===c||a.showCaption===!0,!!b&&(a.caption&&e&&(d=!0),d)}return{setRatio:a,setThumbAttr:b,isExpectedCaption:c}}($b||{},jQuery);jQuery.Fotorama=function(c,r){function Yc(){d.each(ea,function(a,b){if(!b.i){b.i=ha++;var c=yb(b.video,!0);if(c){var d={};b.video=c,b.img||b.thumb?b.thumbsReady=!0:d=zb(b,ea,N),Ab(ea,{img:d.img,thumb:d.thumb},b.i,N)}}})}function Zc(a){return Dc[a]}function $c(){if(ya!==e)if("vertical"==r.navdir){var a=r.thumbwidth+r.thumbmargin;ya.css("left",a),Ha.css("right",a),vb.css("right",a),wa.css("width",wa.css("width")+a),Aa.css("max-width",wa.width()-a)}else ya.css("left",""),Ha.css("right",""),vb.css("right",""),wa.css("width",wa.css("width")+a),Aa.css("max-width","")}function _c(a){var j,b="keydown."+f,c=f+O,e="keydown."+c,h="keyup."+c,i="resize."+c+" orientationchange."+c;a?(Da.on(e,function(a){var b,c;bc&&27===a.keyCode?(b=!0,Vd(bc,!0,!0)):(N.fullScreen||r.keyboard&&!N.index)&&(27===a.keyCode?(b=!0,N.cancelFullScreen()):a.shiftKey&&32===a.keyCode&&Zc("space")||37===a.keyCode&&Zc("left")||38===a.keyCode&&Zc("up")&&d(":focus").attr("data-gallery-role")?(N.longPress.progress(),c="<"):32===a.keyCode&&Zc("space")||39===a.keyCode&&Zc("right")||40===a.keyCode&&Zc("down")&&d(":focus").attr("data-gallery-role")?(N.longPress.progress(),c=">"):36===a.keyCode&&Zc("home")?(N.longPress.progress(),c="<<"):35===a.keyCode&&Zc("end")&&(N.longPress.progress(),c=">>")),(b||c)&&Yb(a),j={index:c,slow:a.altKey,user:!0},c&&(N.longPress.inProgress?N.showWhileLongPress(j):N.show(j))}),a&&Da.on(h,function(a){N.longPress.inProgress&&N.showEndLongPress({user:!0}),N.longPress.reset()}),N.index||Da.off(b).on(b,"textarea, input, select",function(a){!Fa.hasClass(g)&&a.stopPropagation()}),Ca.on(i,N.resize)):(Da.off(e),Ca.off(i))}function ad(a){a!==ad.f&&(a?(c.addClass(f+" "+P).before(va).before(ua),lc(N)):(va.detach(),ua.detach(),c.html(qa.urtext).removeClass(P),mc(N)),_c(a),ad.f=a)}function bd(){ea=N.data=ea||Nb(r.data)||Bb(c),ra=N.size=ea.length,ee.ok&&r.shuffle&&Mb(ea),Yc(),cc=id(cc),ra&&ad(!0)}function cd(){var a=ra<2||bc;Hc.noMove=a||wc,Hc.noSwipe=a||!r.swipe,!Ac&&Aa.toggleClass(y,!r.click&&!Hc.noMove&&!Hc.noSwipe),Na&&wa.toggleClass(p,!Hc.noSwipe)}function dd(a){a===!0&&(a=""),r.autoplay=Math.max(+a||Sa,1.5*zc)}function ed(a){a.navarrows&&"thumbs"===a.nav?(rb.show(),sb.show()):(rb.hide(),sb.hide())}function fd(a,b){return Math.floor(wa.width()/(b.thumbwidth+b.thumbmargin))}function gd(){function b(b,c){a[b?"add":"remove"].push(c)}r.nav&&"dots"!==r.nav||(r.navdir="horizontal"),N.options=r=Pb(r),bb=fd(wa,r),wc="crossfade"===r.transition||"dissolve"===r.transition,qc=r.loop&&(ra>2||wc&&(!Ac||"slide"!==Ac)),zc=+r.transitionduration||Qa,Cc="rtl"===r.direction,Dc=d.extend({},r.keyboard&&db,r.keyboard),ed(r);var a={add:[],remove:[]};ra>1?(rc=r.nav,tc="top"===r.navposition,a.remove.push(X),La.toggle(r.arrows)):(rc=!1,La.hide()),Ad(),Cd(),Bd(),r.autoplay&&dd(r.autoplay),xc=lb(r.thumbwidth)||Ua,yc=lb(r.thumbheight)||Ua,Ic.ok=Kc.ok=r.trackpad&&!Ma,cd(),Kd(r,[Fc]),sc="thumbs"===rc,Oa.filter(":hidden")&&rc&&Oa.show(),sc?(td(ra,"navThumb"),_a=eb,Vc=Za,Gb(ua,d.Fotorama.jst.style({w:xc,h:yc,b:r.thumbborderwidth,m:r.thumbmargin,s:O,q:!Ja})),Ra.addClass(L).removeClass(K)):"dots"===rc?(td(ra,"navDot"),_a=cb,Vc=Ya,Ra.addClass(K).removeClass(L)):(Oa.hide(),rc=!1,Ra.removeClass(L+" "+K)),rc&&(tc?Oa.insertBefore(ya):Oa.insertAfter(ya),xd.nav=!1,xd(_a,Ta,"nav")),uc=r.allowfullscreen,uc?(vb.prependTo(ya),vc=Ka&&"native"===uc):(vb.detach(),vc=!1),b(wc,l),b(!wc,m),b(!r.captions,s),b(Cc,q),b(r.arrows,t),Bc=r.shadows&&!Ma,b(!Bc,o),wa.addClass(a.add.join(" ")).removeClass(a.remove.join(" ")),Ec=d.extend({},r),$c()}function hd(a){return a<0?(ra+a%ra)%ra:a>=ra?a%ra:a}function id(a){return fb(a,0,ra-1)}function jd(a){return qc?hd(a):id(a)}function kd(a){return!!(a>0||qc)&&a-1}function ld(a){return!!(a<ra-1||qc)&&a+1}function md(){Hc.min=qc?-(1/0):-pb(ra-1,Fc.w,r.margin,fc),Hc.max=qc?1/0:-pb(0,Fc.w,r.margin,fc),Hc.snap=Fc.w+r.margin}function nd(){var a="vertical"===r.navdir,b=a?Ta.height():Ta.width(),c=a?Fc.h:Fc.nw;Jc.min=Math.min(0,c-b),Jc.max=0,Jc.direction=r.navdir,Ta.toggleClass(y,!(Jc.noMove=Jc.min===Jc.max))}function od(a,b,c){if("number"==typeof a){a=new Array(a);var e=!0}return d.each(a,function(a,d){if(e&&(d=a),"number"==typeof d){var f=ea[hd(d)];if(f){var g="$"+b+"Frame",h=f[g];c.call(this,a,d,f,h,g,h&&h.data())}}})}function pd(a,b,c,d){(!Gc||"*"===Gc&&d===pc)&&(a=ob(r.width)||ob(a)||Va,b=ob(r.height)||ob(b)||Wa,N.resize({width:a,ratio:r.ratio||c||a/b},0,d!==pc&&"*"))}function qd(a,b,c,e){od(a,b,function(a,f,g,h,i,j){function s(a){var b=hd(f);Ld(a,{index:b,src:p,frame:ea[b]})}function t(){m.remove(),d.Fotorama.cache[p]="error",g.html&&"stage"===b||!q||q===p?(!p||g.html||k?"stage"===b&&(h.trigger("f:load").removeClass(aa+" "+_).addClass(ba),s("load"),pd()):(h.trigger("f:error").removeClass(aa).addClass(_),s("error")),j.state="error",!(ra>1&&ea[f]===g)||g.html||g.deleted||g.video||k||(g.deleted=!0,N.splice(f,1))):(g[o]=p=q,j.$full=null,qd([f],b,c,!0))}function u(){d.Fotorama.measures[p]=n.measures=d.Fotorama.measures[p]||{width:l.width,height:l.height,ratio:l.width/l.height},pd(n.measures.width,n.measures.height,n.measures.ratio,f),m.off("load error").addClass(""+(k?ga:fa)).attr("aria-hidden","false").prependTo(h),h.hasClass(v)&&!h.hasClass(ma)&&h.attr("href",m.attr("src")),Fb(m,(d.isFunction(c)?c():c)||Fc),d.Fotorama.cache[p]=j.state="loaded",setTimeout(function(){h.trigger("f:load").removeClass(aa+" "+_).addClass(ba+" "+(k?ca:da)),"stage"===b?s("load"):(g.thumbratio===$a||!g.thumbratio&&r.thumbratio===$a)&&(g.thumbratio=n.measures.ratio,ce())},0)}function w(){var a=10;Eb(function(){return!Tc||!a--&&!Ma},function(){u()})}if(h){var k=N.fullScreen&&!j.$full&&"stage"===b;if(!j.$img||e||k){var l=new Image,m=d(l),n=m.data();j[k?"$full":"$img"]=m;var o="stage"===b?k?"full":"img":"thumb",p=g[o],q=k?g.img:g["stage"===b?"thumb":"img"];if("navThumb"===b&&(h=j.$wrap),!p)return void t();d.Fotorama.cache[p]?!function a(){"error"===d.Fotorama.cache[p]?t():"loaded"===d.Fotorama.cache[p]?setTimeout(w,0):setTimeout(a,100)}():(d.Fotorama.cache[p]="*",m.on("load",w).on("error",t)),j.state="",l.src=p,j.data.caption&&(l.alt=j.data.caption||""),j.data.full&&d(l).data("original",j.data.full),$b.isExpectedCaption(g,r.showcaption)&&d(l).attr("aria-labelledby",g.labelledby)}}})}function rd(){var a=dc[Xa];a&&!a.data().state&&(Ub.addClass(ta),a.on("f:load f:error",function(){a.off("f:load f:error"),Ub.removeClass(ta)}))}function sd(a){Wb(a,_d),Xb(a,function(){setTimeout(function(){Ob(Ra)},0),Fd({time:zc,guessIndex:d(this).data().eq,minMax:Jc})})}function td(a,b){od(a,b,function(a,c,e,f,g,h){if(!f){f=e[g]=wa[g].clone(),h=f.data(),h.data=e;var i=f[0],j="labelledby"+d.now();"stage"===b?(e.html&&d('<div class="'+la+'"></div>').append(e._html?d(e.html).removeAttr("id").html(e._html):e.html).appendTo(f),e.id&&(j=e.id||j),e.labelledby=j,$b.isExpectedCaption(e,r.showcaption)&&d(d.Fotorama.jst.frameCaption({caption:e.caption,labelledby:j})).appendTo(f),e.video&&f.addClass(w).append(xb.clone()),Xb(i,function(){setTimeout(function(){Ob(ya)},0),Yd({index:h.eq,user:!0})}),Ba=Ba.add(f)):"navDot"===b?(sd(i),cb=cb.add(f)):"navThumb"===b&&(sd(i),h.$wrap=f.children(":first"),eb=eb.add(f),e.video&&h.$wrap.append(xb.clone()))}})}function ud(a,b){return a&&a.length&&Fb(a,b)}function vd(a){od(a,"stage",function(a,b,c,e,f,g){if(e){var h=hd(b);g.eq=h,Rc[Xa][h]=e.css(d.extend({left:wc?0:pb(b,Fc.w,r.margin,fc)},wc&&jb(0))),Db(e[0])&&(e.appendTo(Aa),Vd(c.$video)),ud(g.$img,Fc),ud(g.$full,Fc),!e.hasClass(v)||"false"===e.attr("aria-hidden")&&e.hasClass(W)||e.attr("aria-hidden","true")}})}function wd(a,b){var c,e;"thumbs"!==rc||isNaN(a)||(c=-a,e=-a+Fc.nw,"vertical"===r.navdir&&(a-=r.thumbheight,e=-a+Fc.h),eb.each(function(){var a=d(this),f=a.data(),g=f.eq,h=function(){return{h:yc,w:f.w}},i=h(),j="vertical"===r.navdir?f.t>e:f.l>e;i.w=f.w,f.l+f.w<c||j||ud(f.$img,i)||b&&qd([g],"navThumb",h)}))}function xd(a,b,c){if(!xd[c]){var e="nav"===c&&sc,f=0,g=0;b.append(a.filter(function(){for(var a,b=d(this),c=b.data(),e=0,f=ea.length;e<f;e++)if(c.data===ea[e]){a=!0,c.eq=e;break}return a||b.remove()&&!1}).sort(function(a,b){return d(a).data().eq-d(b).data().eq}).each(function(){var a=d(this),b=a.data();$b.setThumbAttr(a,b.data.caption,"aria-label")}).each(function(){if(e){var a=d(this),b=a.data(),c=Math.round(yc*b.data.thumbratio)||xc,h=Math.round(xc/b.data.thumbratio)||yc;b.t=g,b.h=h,b.l=f,b.w=c,a.css({width:c}),g+=h+r.thumbmargin,f+=c+r.thumbmargin}})),xd[c]=!0}}function yd(a){return a-Wc>Fc.w/3}function zd(a){return!(qc||cc+a&&cc-ra+a||bc)}function Ad(){var a=zd(0),b=zd(1);Ga.toggleClass(B,a).attr(Vb(a,!1)),Ha.toggleClass(B,b).attr(Vb(b,!1))}function Bd(){var a=!1,b=!1;if("thumbs"!==r.navtype||r.loop||(a=0==cc,b=cc==r.data.length-1),"slides"===r.navtype){var c=hb(Ta,r.navdir);a=c>=Jc.max,b=c<=Jc.min}rb.toggleClass(B,a).attr(Vb(a,!0)),sb.toggleClass(B,b).attr(Vb(b,!0))}function Cd(){Ic.ok&&(Ic.prevent={"<":zd(0),">":zd(1)})}function Dd(a){var c,d,e,f,b=a.data();sc?(c=b.l,d=b.t,e=b.w,f=b.h):(c=a.position().left,e=a.width());var g={c:c+e/2,min:-c+10*r.thumbmargin,max:-c+Fc.w-e-10*r.thumbmargin},h={c:d+f/2,min:-d+10*r.thumbmargin,max:-d+Fc.h-f-10*r.thumbmargin};return"vertical"===r.navdir?h:g}function Ed(a){var b=dc[Vc].data();_b(mb,{time:1.2*a,pos:"vertical"===r.navdir?b.t:b.l,width:b.w,height:b.h,direction:r.navdir})}function Fd(a){var d,e,f,g,h,i,j,k,b=ea[a.guessIndex][Vc],c=r.navtype;b&&("thumbs"===c?(d=Jc.min!==Jc.max,f=a.minMax||d&&Dd(dc[Vc]),g=d&&(a.keep&&Fd.t?Fd.l:fb((a.coo||Fc.nw/2)-Dd(b).c,f.min,f.max)),h=d&&(a.keep&&Fd.l?Fd.l:fb((a.coo||Fc.nw/2)-Dd(b).c,f.min,f.max)),i="vertical"===r.navdir?g:h,j=d&&fb(i,Jc.min,Jc.max)||0,e=1.1*a.time,_b(Ta,{time:e,pos:j,direction:r.navdir,onEnd:function(){wd(j,!0),Bd()}}),Ud(Ra,Hb(j,Jc.min,Jc.max,r.navdir)),Fd.l=i):(k=hb(Ta,r.navdir),e=1.11*a.time,j=Tb(r,Jc,a.guessIndex,k,b,Oa,r.navdir),_b(Ta,{time:e,pos:j,direction:r.navdir,onEnd:function(){wd(j,!0),Bd()}}),Ud(Ra,Hb(j,Jc.min,Jc.max,r.navdir))))}function Gd(){Hd(Vc),Qc[Vc].push(dc[Vc].addClass(W).attr("data-active",!0))}function Hd(a){for(var b=Qc[a];b.length;)b.shift().removeClass(W).attr("data-active",!1)}function Id(a){var b=Rc[a];d.each(ec,function(a,c){delete b[hd(c)]}),d.each(b,function(a,c){delete b[a],c.detach()})}function Jd(a){fc=gc=cc;var b=dc[Xa];b&&(Hd(Xa),Qc[Xa].push(b.addClass(W).attr("data-active",!0)),b.hasClass(v)&&b.attr("aria-hidden","false"),a||N.showStage.onEnd(!0),tb(Aa,0,!0),Id(Xa),vd(ec),md(),nd(),Wb(Aa[0],function(){c.hasClass(Z)||(N.requestFullScreen(),vb.focus())}))}function Kd(a,b){a&&d.each(b,function(b,c){c&&d.extend(c,{width:a.width||c.width,height:a.height,minwidth:a.minwidth,maxwidth:a.maxwidth,minheight:a.minheight,maxheight:a.maxheight,ratio:Qb(a.ratio)})})}function Ld(a,b){c.trigger(f+":"+a,[N,b])}function Md(){clearTimeout(Nd.t),Tc=1,r.stopautoplayontouch?N.stopAutoplay():Oc=!0}function Nd(){Tc&&(r.stopautoplayontouch||(Od(),Pd()),Nd.t=setTimeout(function(){Tc=0},Qa+Pa))}function Od(){Oc=!(!bc&&!Pc)}function Pd(){if(clearTimeout(Pd.t),Eb.stop(Pd.w),!r.autoplay||Oc)return void(N.autoplay&&(N.autoplay=!1,Ld("stopautoplay")));N.autoplay||(N.autoplay=!0,Ld("startautoplay"));var a=cc,b=dc[Xa].data();Pd.w=Eb(function(){return b.state||a!==cc},function(){Pd.t=setTimeout(function(){if(!Oc&&a===cc){var b=oc,c=ea[b][Xa].data();Pd.w=Eb(function(){return c.state||b!==oc},function(){Oc||b!==oc||N.show(qc?Zb(!Cc):oc)})}},r.autoplay)})}function Qd(a){var b;return"object"!=typeof a?(b=a,a={}):b=a.index,b=">"===b?gc+1:"<"===b?gc-1:"<<"===b?0:">>"===b?ra-1:b,b=isNaN(b)?e:b,b="undefined"==typeof b?cc||0:b}function Rd(a){N.activeIndex=cc=jd(a),kc=kd(cc),nc=ld(cc),oc=hd(cc+(Cc?-1:1)),ec=[cc,kc,nc],gc=qc?a:cc}function Sd(a){var b=Math.abs(hc-gc),c=ub(a.time,function(){return Math.min(zc*(1+(b-1)/12),2*zc)});return a.slow&&(c*=10),c}function Td(){N.fullScreen&&(N.fullScreen=!1,Ka&&xa.cancel(Q),Fa.removeClass(g),Ea.removeClass(g),c.removeClass(Z).insertAfter(va),Fc=d.extend({},Sc),Vd(bc,!0,!0),$d("x",!1),N.resize(),qd(ec,"stage"),Ob(Ca,Mc,Lc),Ld("fullscreenexit"))}function Ud(a,b){Bc&&(a.removeClass(S+" "+T),a.removeClass(U+" "+V),b&&!bc&&a.addClass(b.replace(/^|\s/g," "+R+"--")))}function Vd(a,b,c){b&&(wa.removeClass(k),bc=!1,cd()),a&&a!==bc&&(a.remove(),Ld("unloadvideo")),c&&(Od(),Pd())}function Wd(a){wa.toggleClass(n,a)}function Xd(a){if(!Hc.flow){var b=a?a.pageX:Xd.x,c=b&&!zd(yd(b))&&r.click;Xd.p!==c&&ya.toggleClass(z,c)&&(Xd.p=c,Xd.x=b)}}function Yd(a){clearTimeout(Yd.t),r.clicktransition&&r.clicktransition!==r.transition?setTimeout(function(){var b=r.transition;N.setOptions({transition:r.clicktransition}),Ac=b,Yd.t=setTimeout(function(){N.show(a)},10)},0):N.show(a)}function Zd(a,b){var e=a.target,f=d(e);f.hasClass(oa)?N.playVideo():e===wb?N.toggleFullScreen():bc?e===Rb&&Vd(bc,!0,!0):c.hasClass(Z)||N.requestFullScreen()}function $d(a,b){Hc[a]=Jc[a]=b}function _d(a){var b=d(this).data().eq;Yd("thumbs"===r.navtype?{index:b,slow:a.altKey,user:!0,coo:a._x-Ra.offset().left}:{index:b,slow:a.altKey,user:!0})}function ae(a){Yd({index:La.index(this)?">":"<",slow:a.altKey,user:!0})}function be(a){Xb(a,function(){setTimeout(function(){Ob(ya)},0),Wd(!1)})}function ce(){if(bd(),gd(),!ce.i){ce.i=!0;var a=r.startindex;cc=fc=gc=hc=pc=jd(a)||0}if(ra){if(de())return;bc&&Vd(bc,!0),ec=[],Id(Xa),ce.ok=!0,N.show({index:cc,time:0}),N.resize()}else N.destroy()}function de(){if(!de.f===Cc)return de.f=Cc,cc=ra-1-cc,N.reverse(),!0}function ee(){ee.ok&&(ee.ok=!1,Ld("ready"))}Ea=d("html"),Fa=d("body");var ea,ra,_a,bc,dc,ec,fc,gc,hc,kc,nc,oc,pc,qc,rc,sc,tc,uc,vc,wc,xc,yc,zc,Ac,Bc,Cc,Dc,Gc,Lc,Mc,Nc,Oc,Pc,Sc,Tc,Uc,Vc,N=this,O=d.now(),P=f+O,Q=c[0],ha=1,qa=c.data(),ua=d("<style></style>"),va=d(Jb(Y)),wa=c.find(Kb(h)),ya=wa.find(Kb(u)),Aa=(ya[0],c.find(Kb(x))),Ba=d(),Ga=c.find(Kb(C)),Ha=c.find(Kb(D)),La=c.find(Kb(A)),Oa=c.find(Kb(F)),Ra=Oa.find(Kb(E)),Ta=Ra.find(Kb(G)),cb=d(),eb=d(),mb=(Aa.data(),Ta.data(),c.find(Kb(ka))),rb=c.find(Kb(ia)),sb=c.find(Kb(ja)),vb=c.find(Kb($)),wb=vb[0],xb=d(Jb(oa)),Cb=c.find(Kb(pa)),Rb=Cb[0],Ub=c.find(Kb(sa)),cc=!1,Ec={},Fc={},Hc={},Ic={},Jc={},Kc={},Qc={},Rc={},Wc=0,Xc=[];wa[Xa]=d('<div class="'+v+'"></div>'),wa[Za]=d(d.Fotorama.jst.thumb()),wa[Ya]=d(d.Fotorama.jst.dots()),
+    Qc[Xa]=[],Qc[Za]=[],Qc[Ya]=[],Rc[Xa]={},wa.addClass(Ia?j:i),qa.fotorama=this,N.startAutoplay=function(a){return N.autoplay?this:(Oc=Pc=!1,dd(a||r.autoplay),Pd(),this)},N.stopAutoplay=function(){return N.autoplay&&(Oc=Pc=!0,Pd()),this},N.showSlide=function(a){var c,b=hb(Ta,r.navdir),d=550,e="horizontal"===r.navdir?r.thumbwidth:r.thumbheight,f=function(){Bd()};"next"===a&&(c=b-(e+r.margin)*bb),"prev"===a&&(c=b+(e+r.margin)*bb),c=Sb(c,Jc),wd(c,!0),_b(Ta,{time:d,pos:c,direction:r.navdir,onEnd:f})},N.showWhileLongPress=function(a){if(!N.longPress.singlePressInProgress){var b=Qd(a);Rd(b);var c=Sd(a)/50,d=dc;N.activeFrame=dc=ea[cc];var e=d===dc&&!a.user;return N.showNav(e,a,c),this}},N.showEndLongPress=function(a){if(!N.longPress.singlePressInProgress){var b=Qd(a);Rd(b);var c=Sd(a)/50,d=dc;N.activeFrame=dc=ea[cc];var e=d===dc&&!a.user;return N.showStage(e,a,c),Nc="undefined"!=typeof hc&&hc!==cc,hc=cc,this}},N.showStage=function(a,b,c){Vd(bc,dc.i!==ea[hd(fc)].i),td(ec,"stage"),vd(Ma?[gc]:[gc,kd(gc),ld(gc)]),$d("go",!0),a||Ld("show",{user:b.user,time:c}),Oc=!0;var d=b.overPos,e=N.showStage.onEnd=function(c){if(!e.ok){if(e.ok=!0,c||Jd(!0),a||Ld("showend",{user:b.user}),!c&&Ac&&Ac!==r.transition)return N.setOptions({transition:Ac}),void(Ac=!1);rd(),qd(ec,"stage"),$d("go",!1),Cd(),Xd(),Od(),Pd(),N.fullScreen?(dc[Xa].find("."+ga).attr("aria-hidden",!1),dc[Xa].find("."+fa).attr("aria-hidden",!0)):(dc[Xa].find("."+ga).attr("aria-hidden",!0),dc[Xa].find("."+fa).attr("aria-hidden",!1))}};if(wc){var f=dc[Xa],g=ea[hc]&&cc!==hc?ea[hc][Xa]:null;ac(f,g,Ba,{time:c,method:r.transition,onEnd:e},Xc)}else _b(Aa,{pos:-pb(gc,Fc.w,r.margin,fc),overPos:d,time:c,onEnd:e});Ad()},N.showNav=function(a,b,c){if(Bd(),rc){Gd();var d=id(cc+fb(gc-hc,-1,1));Fd({time:c,coo:d!==cc&&b.coo,guessIndex:"undefined"!=typeof b.coo?d:cc,keep:a}),sc&&Ed(c)}},N.show=function(a){N.longPress.singlePressInProgress=!0;var b=Qd(a);Rd(b);var c=Sd(a),d=dc;N.activeFrame=dc=ea[cc];var e=d===dc&&!a.user;return N.showStage(e,a,c),N.showNav(e,a,c),Nc="undefined"!=typeof hc&&hc!==cc,hc=cc,N.longPress.singlePressInProgress=!1,this},N.requestFullScreen=function(){if(uc&&!N.fullScreen){var b=d((N.activeFrame||{}).$stageFrame||{}).hasClass("fotorama-video-container");if(b)return;Lc=Ca.scrollTop(),Mc=Ca.scrollLeft(),Ob(Ca),$d("x",!0),Sc=d.extend({},Fc),c.addClass(Z).appendTo(Fa.addClass(g)),Ea.addClass(g),Vd(bc,!0,!0),N.fullScreen=!0,vc&&xa.request(Q),N.resize(),qd(ec,"stage"),rd(),Ld("fullscreenenter"),"ontouchstart"in a||vb.focus()}return this},N.cancelFullScreen=function(){return vc&&xa.is()?xa.cancel(b):Td(),this},N.toggleFullScreen=function(){return N[(N.fullScreen?"cancel":"request")+"FullScreen"]()},N.resize=function(b){if(!ea)return this;var c=arguments[1]||0,e=arguments[2];bb=fd(wa,r),Kd(N.fullScreen?{width:d(a).width(),maxwidth:null,minwidth:null,height:d(a).height(),maxheight:null,minheight:null}:Pb(b),[Fc,e||N.fullScreen||r]);var f=Fc.width,g=Fc.height,h=Fc.ratio,i=Ca.height()-(rc?Ra.height():0);if(ob(f)&&(wa.css({width:""}),wa.css({height:""}),ya.css({width:""}),ya.css({height:""}),Aa.css({width:""}),Aa.css({height:""}),Ra.css({width:""}),Ra.css({height:""}),wa.css({minWidth:Fc.minwidth||0,maxWidth:Fc.maxwidth||ab}),"dots"===rc&&Oa.hide(),f=Fc.W=Fc.w=wa.width(),Fc.nw=rc&&nb(r.navwidth,f)||f,Aa.css({width:Fc.w,marginLeft:(Fc.W-Fc.w)/2}),g=nb(g,i),g=g||h&&f/h)){if(f=Math.round(f),g=Fc.h=Math.round(fb(g,nb(Fc.minheight,i),nb(Fc.maxheight,i))),ya.css({width:f,height:g}),"vertical"!==r.navdir||N.fullscreen||Ra.width(r.thumbwidth+2*r.thumbmargin),"horizontal"!==r.navdir||N.fullscreen||Ra.height(r.thumbheight+2*r.thumbmargin),"dots"===rc&&(Ra.width(f).height("auto"),Oa.show()),"vertical"===r.navdir&&N.fullScreen&&ya.css("height",Ca.height()),"horizontal"===r.navdir&&N.fullScreen&&ya.css("height",Ca.height()-Ra.height()),rc){switch(r.navdir){case"vertical":Oa.removeClass(J),Oa.removeClass(I),Oa.addClass(H),Ra.stop().animate({height:Fc.h,width:r.thumbwidth},c);break;case"list":Oa.removeClass(H),Oa.removeClass(J),Oa.addClass(I);break;default:Oa.removeClass(H),Oa.removeClass(I),Oa.addClass(J),Ra.stop().animate({width:Fc.nw},c)}Jd(),Fd({guessIndex:cc,time:c,keep:!0}),sc&&xd.nav&&Ed(c)}Gc=e||!0,ee.ok=!0,ee()}return Wc=ya.offset().left,$c(),this},N.setOptions=function(a){return d.extend(r,a),ce(),this},N.shuffle=function(){return ea&&Mb(ea)&&ce(),this},N.longPress={threshold:1,count:0,thumbSlideTime:20,progress:function(){this.inProgress||(this.count++,this.inProgress=this.count>this.threshold)},end:function(){this.inProgress&&(this.isEnded=!0)},reset:function(){this.count=0,this.inProgress=!1,this.isEnded=!1}},N.destroy=function(){return N.cancelFullScreen(),N.stopAutoplay(),ea=N.data=null,ad(),ec=[],Id(Xa),ce.ok=!1,this},N.playVideo=function(){var a=dc,b=a.video,c=cc;return"object"==typeof b&&a.videoReady&&(vc&&N.fullScreen&&N.cancelFullScreen(),Eb(function(){return!xa.is()||c!==cc},function(){c===cc&&(a.$video=a.$video||d(Jb(na)).append(Lb(b)),a.$video.appendTo(a[Xa]),wa.addClass(k),bc=a.$video,cd(),La.blur(),vb.blur(),Ld("loadvideo"))})),this},N.stopVideo=function(){return Vd(bc,!0,!0),this},N.spliceByIndex=function(a,b){b.i=a+1,b.img&&d.ajax({url:b.img,type:"HEAD",success:function(){ea.splice(a,1,b),ce()}})},ya.on("mousemove",Xd),Hc=ic(Aa,{onStart:Md,onMove:function(a,b){Ud(ya,b.edge)},onTouchEnd:Nd,onEnd:function(a){var b;if(Ud(ya),b=(Na&&!Uc||a.touch)&&r.arrows,(a.moved||b&&a.pos!==a.newPos&&!a.control)&&a.$target[0]!==vb[0]){var c=qb(a.newPos,Fc.w,r.margin,fc);N.show({index:c,time:wc?zc:a.time,overPos:a.overPos,user:!0})}else a.aborted||a.control||Zd(a.startEvent,b)},timeLow:1,timeHigh:1,friction:2,select:"."+X+", ."+X+" *",$wrap:ya,direction:"horizontal"}),Jc=ic(Ta,{onStart:Md,onMove:function(a,b){Ud(Ra,b.edge)},onTouchEnd:Nd,onEnd:function(a){function b(){Fd.l=a.newPos,Od(),Pd(),wd(a.newPos,!0),Bd()}if(a.moved)a.pos!==a.newPos?(Oc=!0,_b(Ta,{time:a.time,pos:a.newPos,overPos:a.overPos,direction:r.navdir,onEnd:b}),wd(a.newPos),Bc&&Ud(Ra,Hb(a.newPos,Jc.min,Jc.max,a.dir))):b();else{var c=a.$target.closest("."+M,Ta)[0];c&&_d.call(c,a.startEvent)}},timeLow:.5,timeHigh:2,friction:5,$wrap:Ra,direction:r.navdir}),Ic=jc(ya,{shift:!0,onEnd:function(a,b){Md(),Nd(),N.show({index:b,slow:a.altKey})}}),Kc=jc(Ra,{onEnd:function(a,b){Md(),Nd();var c=tb(Ta)+.25*b;Ta.css(ib(fb(c,Jc.min,Jc.max),r.navdir)),Bc&&Ud(Ra,Hb(c,Jc.min,Jc.max,r.navdir)),Kc.prevent={"<":c>=Jc.max,">":c<=Jc.min},clearTimeout(Kc.t),Kc.t=setTimeout(function(){Fd.l=c,wd(c,!0)},Pa),wd(c)}}),wa.hover(function(){setTimeout(function(){Tc||Wd(!(Uc=!0))},0)},function(){Uc&&Wd(!(Uc=!1))}),Ib(La,function(a){Yb(a),ae.call(this,a)},{onStart:function(){Md(),Hc.control=!0},onTouchEnd:Nd}),Ib(rb,function(a){Yb(a),"thumbs"===r.navtype?N.show("<"):N.showSlide("prev")}),Ib(sb,function(a){Yb(a),"thumbs"===r.navtype?N.show(">"):N.showSlide("next")}),La.each(function(){Wb(this,function(a){ae.call(this,a)}),be(this)}),Wb(wb,function(){c.hasClass(Z)?(N.cancelFullScreen(),Aa.focus()):(N.requestFullScreen(),vb.focus())}),be(wb),d.each("load push pop shift unshift reverse sort splice".split(" "),function(a,b){N[b]=function(){return ea=ea||[],"load"!==b?Array.prototype[b].apply(ea,arguments):arguments[0]&&"object"==typeof arguments[0]&&arguments[0].length&&(ea=Nb(arguments[0])),ce(),N}}),ce()},d.fn.fotorama=function(b){return this.each(function(){var c=this,e=d(this),f=e.data(),g=f.fotorama;g?g.setOptions(b,!0):Eb(function(){return!Cb(c)},function(){f.urtext=e.html(),new d.Fotorama(e,d.extend({},cb,a.fotoramaDefaults,b,f))})})},d.Fotorama.instances=[],d.Fotorama.cache={},d.Fotorama.measures={},d=d||{},d.Fotorama=d.Fotorama||{},d.Fotorama.jst=d.Fotorama.jst||{},d.Fotorama.jst.dots=function(a){var c="";va.escape;return c+='<div class="fotorama__nav__frame fotorama__nav__frame--dot" tabindex="0" role="button" data-gallery-role="nav-frame" data-nav-type="thumb" aria-label>\r\n    <div class="fotorama__dot"></div>\r\n</div>'},d.Fotorama.jst.frameCaption=function(a){var b,c="";va.escape;return c+='<div class="fotorama__caption" aria-hidden="true">\r\n    <div class="fotorama__caption__wrap" id="'+(null==(b=a.labelledby)?"":b)+'">'+(null==(b=a.caption)?"":b)+"</div>\r\n</div>\r\n"},d.Fotorama.jst.style=function(a){var b,c="";va.escape;return c+=".fotorama"+(null==(b=a.s)?"":b)+" .fotorama__nav--thumbs .fotorama__nav__frame{\r\npadding:"+(null==(b=a.m)?"":b)+"px;\r\nheight:"+(null==(b=a.h)?"":b)+"px}\r\n.fotorama"+(null==(b=a.s)?"":b)+" .fotorama__thumb-border{\r\nheight:"+(null==(b=a.h)?"":b)+"px;\r\nborder-width:"+(null==(b=a.b)?"":b)+"px;\r\nmargin-top:"+(null==(b=a.m)?"":b)+"px}"},d.Fotorama.jst.thumb=function(a){var c="";va.escape;return c+='<div class="fotorama__nav__frame fotorama__nav__frame--thumb" tabindex="0" role="button" data-gallery-role="nav-frame" data-nav-type="thumb" aria-label>\r\n    <div class="fotorama__thumb">\r\n    </div>\r\n</div>'}}(window,document,location,"undefined"!=typeof jQuery&&jQuery);
\ No newline at end of file
diff --git a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/html5-schema.js b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/html5-schema.js
index a74a9f12fb2dfe1a0ea5e79b445608016c61462c..f224218f4f731511b8ba13f3ded06b5a73393f4d 100644
--- a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/html5-schema.js
+++ b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/html5-schema.js
@@ -46,7 +46,7 @@ define([
     };
 
     schema.flowContent = schema.blockContent.concat(schema.phrasingContent, ['style']);
-    schema.nonEmpty = ['td', 'th', 'iframe', 'video', 'audio', 'object', 'script'].concat(schema.shortEnded);
+    schema.nonEmpty = ['td', 'th', 'iframe', 'video', 'audio', 'object', 'script', 'i', 'em', 'span'].concat(schema.shortEnded);
 
     _.extend(schema, (function (phrasingContent, flowContent) {
         var validElements   = [],
diff --git a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js
index 4964e6bb14e703f3a0a11a84ab1af78c7e9cfe6e..66b72857d003397b8a756dc6aae9c0de70c58eeb 100755
--- a/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js
+++ b/lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js
@@ -101,6 +101,8 @@ define([
                 magentoPluginsOptions: magentoPluginsOptions,
                 doctype: '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
                 setup: function(ed){
+                    ed.onPreInit.add(self.onEditorPreInit.bind(self));
+
                     ed.onInit.add(self.onEditorInit.bind(self));
 
                     ed.onSubmit.add(function(ed, e) {
@@ -285,10 +287,18 @@ define([
             }
         },
 
-        onEditorInit: function (editor) {
+        /**
+         * Editor pre-initialise event handler.
+         */
+        onEditorPreInit: function (editor) {
             this.applySchema(editor);
         },
 
+        /**
+         * @deprecated
+         */
+        onEditorInit: function () {},
+
         onFormValidation: function() {
             if (tinyMCE.get(this.id)) {
                 $(this.id).value = tinyMCE.get(this.id).getContent();
diff --git a/lib/web/mage/dataPost.js b/lib/web/mage/dataPost.js
index e1c297ffcef4b9a6a3d64806d5f93eb57e938644..2d47929f57213c338c5b121310c544b3876331ec 100644
--- a/lib/web/mage/dataPost.js
+++ b/lib/web/mage/dataPost.js
@@ -2,50 +2,88 @@
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-/*jshint browser:true jquery:true*/
-/*global confirm:true*/
+
 define([
-    "jquery",
-    "mage/template",
-    "jquery/ui"
-], function($,mageTemplate){
-    
+    'jquery',
+    'mage/template',
+    'Magento_Ui/js/modal/confirm',
+    'jquery/ui'
+], function ($, mageTemplate, uiConfirm) {
+    'use strict';
+
     $.widget('mage.dataPost', {
         options: {
-            formTemplate: '<form action="<%- data.action %>" method="post">'
-                + '<% _.each(data.data, function(value, index) { %>'
-                    + '<input name="<%- index %>" value="<%- value %>">'
-                + '<% }) %></form>',
+            formTemplate: '<form action="<%- data.action %>" method="post">' +
+            '<% _.each(data.data, function(value, index) { %>' +
+            '<input name="<%- index %>" value="<%- value %>">' +
+            '<% }) %></form>',
             postTrigger: ['a[data-post]', 'button[data-post]', 'span[data-post]'],
             formKeyInputSelector: 'input[name="form_key"]'
         },
-        _create: function() {
+
+        /** @inheritdoc */
+        _create: function () {
             this._bind();
         },
-        _bind: function() {
+
+        /** @inheritdoc */
+        _bind: function () {
             var events = {};
-            $.each(this.options.postTrigger, function(index, value) {
+
+            $.each(this.options.postTrigger, function (index, value) {
                 events['click ' + value] = '_postDataAction';
             });
+
             this._on(events);
         },
-        _postDataAction: function(e) {
-            e.preventDefault();
+
+        /**
+         * Handler for click.
+         *
+         * @param {Object} e
+         * @private
+         */
+        _postDataAction: function (e) {
             var params = $(e.currentTarget).data('post');
+
+            e.preventDefault();
             this.postData(params);
         },
-        postData: function(params) {
-            var formKey = $(this.options.formKeyInputSelector).val();
+
+        /**
+         * Data post action.
+         *
+         * @param {Object} params
+         */
+        postData: function (params) {
+            var formKey = $(this.options.formKeyInputSelector).val(),
+                $form;
+
             if (formKey) {
-                params.data.form_key = formKey;
+                params.data['form_key'] = formKey;
             }
-            $(mageTemplate(this.options.formTemplate, {
+
+            $form = $(mageTemplate(this.options.formTemplate, {
                 data: params
-            })).appendTo('body').hide().submit();
+            }));
+
+            if (params.data.confirmation) {
+                uiConfirm({
+                    content: params.data.confirmationMessage,
+                    actions: {
+                        /** @inheritdoc */
+                        confirm: function () {
+                            $form.appendTo('body').hide().submit();
+                        }
+                    }
+                });
+            } else {
+                $form.appendTo('body').hide().submit();
+            }
         }
     });
-    
+
     $(document).dataPost();
 
     return $.mage.dataPost;
-});
\ No newline at end of file
+});
diff --git a/lib/web/mage/utils/misc.js b/lib/web/mage/utils/misc.js
index b3bc52b7164f5512057b624cdaff96a2cfca311a..c6440b8929395419053ab53961f5fcc231ab7eee 100644
--- a/lib/web/mage/utils/misc.js
+++ b/lib/web/mage/utils/misc.js
@@ -39,6 +39,7 @@ define([
         'EEE': 'ddd',
         'e': 'd',
         'yyyy': 'YYYY',
+        'yy': 'YY',
         'y': 'YYYY',
         'a': 'A'
     };
diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js
index 9fab793b70b6c042c573e38aef012f6294765c25..3041a177185cf1dfa5bda6e233a2c58a0282d0de 100644
--- a/lib/web/mage/validation.js
+++ b/lib/web/mage/validation.js
@@ -545,10 +545,10 @@
                 var pass = $.trim(v);
                 var result = pass.length >= passwordMinLength;
                 if (result == false) {
-                    validator.passwordErrorMessage = $.mage.__(
-                        "Minimum length of this field must be equal or greater than %1 symbols." +
-                        " Leading and trailing spaces will be ignored."
-                    ).replace('%1', passwordMinLength);
+                    /*eslint-disable max-len*/
+                    validator.passwordErrorMessage = $.mage.__('Minimum length of this field must be equal or greater than %1 symbols. Leading and trailing spaces will be ignored.').replace('%1', passwordMinLength);
+
+                    /*eslint-enable max-len*/
                     return result;
                 }
                 if (pass.match(/\d+/)) {
@@ -565,10 +565,11 @@
                 }
                 if (counter < passwordMinCharacterSets) {
                     result = false;
-                    validator.passwordErrorMessage = $.mage.__(
-                        "Minimum of different classes of characters in password is %1." +
-                        " Classes of characters: Lower Case, Upper Case, Digits, Special Characters."
-                    ).replace('%1', passwordMinCharacterSets);
+
+                    /*eslint-disable max-len*/
+                    validator.passwordErrorMessage = $.mage.__('Minimum of different classes of characters in password is %1. Classes of characters: Lower Case, Upper Case, Digits, Special Characters.').replace('%1', passwordMinCharacterSets);
+
+                    /*eslint-enable max-len*/
                 }
                 return result;
             }, function () {
@@ -984,7 +985,7 @@
 
                 return !!container.querySelectorAll(selector).length;
             },
-            'Please select one of the options.'
+            $.mage.__('Please select one of the options.')
         ],
         "less-than-equals-to": [
             function (value, element, params) {
@@ -1145,16 +1146,12 @@
                     if (name.match(reMax) && result) {
                         length = name.split('-')[2];
                         result = (v.length <= length);
-                        validator.validateMessage = $.mage.__(
-                            "Please enter less or equal than %1 symbols."
-                        ).replace('%1', length);
+                        validator.validateMessage = $.mage.__('Please enter less or equal than %1 symbols.').replace('%1', length);
                     }
                     if (name.match(reMin) && result && !$.mage.isEmpty(v)) {
                         length = name.split('-')[2];
                         result = v.length >= length;
-                        validator.validateMessage = $.mage.__(
-                            "Please enter more or equal than %1 symbols."
-                        ).replace('%1', length);
+                        validator.validateMessage = $.mage.__('Please enter more or equal than %1 symbols.').replace('%1', length);
                     }
                 });
                 return result;
diff --git a/lib/web/moment-timezone-with-data.js b/lib/web/moment-timezone-with-data.js
new file mode 100644
index 0000000000000000000000000000000000000000..6dfd9559f93d4c731872460f2ccc5009eca96130
--- /dev/null
+++ b/lib/web/moment-timezone-with-data.js
@@ -0,0 +1,7 @@
+//! moment-timezone.js
+//! version : 0.5.5
+//! author : Tim Wood
+//! license : MIT
+//! github.com/moment/moment-timezone
+!function(a,b){"use strict";"function"==typeof define&&define.amd?define(["moment"],b):"object"==typeof module&&module.exports?module.exports=b(require("moment")):b(a.moment)}(this,function(a){"use strict";function b(a){return a>96?a-87:a>64?a-29:a-48}function c(a){var c,d=0,e=a.split("."),f=e[0],g=e[1]||"",h=1,i=0,j=1;for(45===a.charCodeAt(0)&&(d=1,j=-1),d;d<f.length;d++)c=b(f.charCodeAt(d)),i=60*i+c;for(d=0;d<g.length;d++)h/=60,c=b(g.charCodeAt(d)),i+=c*h;return i*j}function d(a){for(var b=0;b<a.length;b++)a[b]=c(a[b])}function e(a,b){for(var c=0;c<b;c++)a[c]=Math.round((a[c-1]||0)+6e4*a[c]);a[b-1]=1/0}function f(a,b){var c,d=[];for(c=0;c<b.length;c++)d[c]=a[b[c]];return d}function g(a){var b=a.split("|"),c=b[2].split(" "),g=b[3].split(""),h=b[4].split(" ");return d(c),d(g),d(h),e(h,g.length),{name:b[0],abbrs:f(b[1].split(" "),g),offsets:f(c,g),untils:h,population:0|b[5]}}function h(a){a&&this._set(g(a))}function i(a){var b=a.toTimeString(),c=b.match(/\([a-z ]+\)/i);c&&c[0]?(c=c[0].match(/[A-Z]/g),c=c?c.join(""):void 0):(c=b.match(/[A-Z]{3,5}/g),c=c?c[0]:void 0),"GMT"===c&&(c=void 0),this.at=+a,this.abbr=c,this.offset=a.getTimezoneOffset()}function j(a){this.zone=a,this.offsetScore=0,this.abbrScore=0}function k(a,b){for(var c,d;d=6e4*((b.at-a.at)/12e4|0);)c=new i(new Date(a.at+d)),c.offset===a.offset?a=c:b=c;return a}function l(){var a,b,c,d=(new Date).getFullYear()-2,e=new i(new Date(d,0,1)),f=[e];for(c=1;c<48;c++)b=new i(new Date(d,c,1)),b.offset!==e.offset&&(a=k(e,b),f.push(a),f.push(new i(new Date(a.at+6e4)))),e=b;for(c=0;c<4;c++)f.push(new i(new Date(d+c,0,1))),f.push(new i(new Date(d+c,6,1)));return f}function m(a,b){return a.offsetScore!==b.offsetScore?a.offsetScore-b.offsetScore:a.abbrScore!==b.abbrScore?a.abbrScore-b.abbrScore:b.zone.population-a.zone.population}function n(a,b){var c,e;for(d(b),c=0;c<b.length;c++)e=b[c],I[e]=I[e]||{},I[e][a]=!0}function o(a){var b,c,d,e=a.length,f={},g=[];for(b=0;b<e;b++){d=I[a[b].offset]||{};for(c in d)d.hasOwnProperty(c)&&(f[c]=!0)}for(b in f)f.hasOwnProperty(b)&&g.push(H[b]);return g}function p(){try{var a=Intl.DateTimeFormat().resolvedOptions().timeZone;if(a){var b=H[r(a)];if(b)return b;z("Moment Timezone found "+a+" from the Intl api, but did not have that data loaded.")}}catch(c){}var d,e,f,g=l(),h=g.length,i=o(g),k=[];for(e=0;e<i.length;e++){for(d=new j(t(i[e]),h),f=0;f<h;f++)d.scoreOffsetAt(g[f]);k.push(d)}return k.sort(m),k.length>0?k[0].zone.name:void 0}function q(a){return D&&!a||(D=p()),D}function r(a){return(a||"").toLowerCase().replace(/\//g,"_")}function s(a){var b,c,d,e;for("string"==typeof a&&(a=[a]),b=0;b<a.length;b++)d=a[b].split("|"),c=d[0],e=r(c),F[e]=a[b],H[e]=c,d[5]&&n(e,d[2].split(" "))}function t(a,b){a=r(a);var c,d=F[a];return d instanceof h?d:"string"==typeof d?(d=new h(d),F[a]=d,d):G[a]&&b!==t&&(c=t(G[a],t))?(d=F[a]=new h,d._set(c),d.name=H[a],d):null}function u(){var a,b=[];for(a in H)H.hasOwnProperty(a)&&(F[a]||F[G[a]])&&H[a]&&b.push(H[a]);return b.sort()}function v(a){var b,c,d,e;for("string"==typeof a&&(a=[a]),b=0;b<a.length;b++)c=a[b].split("|"),d=r(c[0]),e=r(c[1]),G[d]=e,H[d]=c[0],G[e]=d,H[e]=c[1]}function w(a){s(a.zones),v(a.links),A.dataVersion=a.version}function x(a){return x.didShowError||(x.didShowError=!0,z("moment.tz.zoneExists('"+a+"') has been deprecated in favor of !moment.tz.zone('"+a+"')")),!!t(a)}function y(a){return!(!a._a||void 0!==a._tzm)}function z(a){"undefined"!=typeof console&&"function"==typeof console.error&&console.error(a)}function A(b){var c=Array.prototype.slice.call(arguments,0,-1),d=arguments[arguments.length-1],e=t(d),f=a.utc.apply(null,c);return e&&!a.isMoment(b)&&y(f)&&f.add(e.parse(f),"minutes"),f.tz(d),f}function B(a){return function(){return this._z?this._z.abbr(this):a.call(this)}}function C(a){return function(){return this._z=null,a.apply(this,arguments)}}if(void 0!==a.tz)return z("Moment Timezone "+a.tz.version+" was already loaded "+(a.tz.dataVersion?"with data from ":"without any data")+a.tz.dataVersion),a;var D,E="0.5.5",F={},G={},H={},I={},J=a.version.split("."),K=+J[0],L=+J[1];(K<2||2===K&&L<6)&&z("Moment Timezone requires Moment.js >= 2.6.0. You are using Moment.js "+a.version+". See momentjs.com"),h.prototype={_set:function(a){this.name=a.name,this.abbrs=a.abbrs,this.untils=a.untils,this.offsets=a.offsets,this.population=a.population},_index:function(a){var b,c=+a,d=this.untils;for(b=0;b<d.length;b++)if(c<d[b])return b},parse:function(a){var b,c,d,e,f=+a,g=this.offsets,h=this.untils,i=h.length-1;for(e=0;e<i;e++)if(b=g[e],c=g[e+1],d=g[e?e-1:e],b<c&&A.moveAmbiguousForward?b=c:b>d&&A.moveInvalidForward&&(b=d),f<h[e]-6e4*b)return g[e];return g[i]},abbr:function(a){return this.abbrs[this._index(a)]},offset:function(a){return this.offsets[this._index(a)]}},j.prototype.scoreOffsetAt=function(a){this.offsetScore+=Math.abs(this.zone.offset(a.at)-a.offset),this.zone.abbr(a.at).replace(/[^A-Z]/g,"")!==a.abbr&&this.abbrScore++},A.version=E,A.dataVersion="",A._zones=F,A._links=G,A._names=H,A.add=s,A.link=v,A.load=w,A.zone=t,A.zoneExists=x,A.guess=q,A.names=u,A.Zone=h,A.unpack=g,A.unpackBase60=c,A.needsOffset=y,A.moveInvalidForward=!0,A.moveAmbiguousForward=!1;var M=a.fn;a.tz=A,a.defaultZone=null,a.updateOffset=function(b,c){var d,e=a.defaultZone;void 0===b._z&&(e&&y(b)&&!b._isUTC&&(b._d=a.utc(b._a)._d,b.utc().add(e.parse(b),"minutes")),b._z=e),b._z&&(d=b._z.offset(b),Math.abs(d)<16&&(d/=60),void 0!==b.utcOffset?b.utcOffset(-d,c):b.zone(d,c))},M.tz=function(b){return b?(this._z=t(b),this._z?a.updateOffset(this):z("Moment Timezone has no data for "+b+". See http://momentjs.com/timezone/docs/#/data-loading/."),this):this._z?this._z.name:void 0},M.zoneName=B(M.zoneName),M.zoneAbbr=B(M.zoneAbbr),M.utc=C(M.utc),a.tz.setDefault=function(b){return(K<2||2===K&&L<9)&&z("Moment Timezone setDefault() requires Moment.js >= 2.9.0. You are using Moment.js "+a.version+"."),a.defaultZone=b?t(b):null,a};var N=a.momentProperties;return"[object Array]"===Object.prototype.toString.call(N)?(N.push("_z"),N.push("_a")):N&&(N._z=null),w({version:"2016f",zones:["Africa/Abidjan|LMT GMT|g.8 0|01|-2ldXH.Q|48e5","Africa/Accra|LMT GMT GHST|.Q 0 -k|012121212121212121212121212121212121212121212121|-26BbX.8 6tzX.8 MnE 1BAk MnE 1BAk MnE 1BAk MnE 1C0k MnE 1BAk MnE 1BAk MnE 1BAk MnE 1C0k MnE 1BAk MnE 1BAk MnE 1BAk MnE 1C0k MnE 1BAk MnE 1BAk MnE 1BAk MnE 1C0k MnE 1BAk MnE 1BAk MnE 1BAk MnE 1C0k MnE 1BAk MnE 1BAk MnE|41e5","Africa/Nairobi|LMT EAT BEAT BEAUT|-2r.g -30 -2u -2J|01231|-1F3Cr.g 3Dzr.g okMu MFXJ|47e5","Africa/Algiers|PMT WET WEST CET CEST|-9.l 0 -10 -10 -20|0121212121212121343431312123431213|-2nco9.l cNb9.l HA0 19A0 1iM0 11c0 1oo0 Wo0 1rc0 QM0 1EM0 UM0 DA0 Imo0 rd0 De0 9Xz0 1fb0 1ap0 16K0 2yo0 mEp0 hwL0 jxA0 11A0 dDd0 17b0 11B0 1cN0 2Dy0 1cN0 1fB0 1cL0|26e5","Africa/Lagos|LMT WAT|-d.A -10|01|-22y0d.A|17e6","Africa/Bissau|LMT WAT GMT|12.k 10 0|012|-2ldWV.E 2xonV.E|39e4","Africa/Maputo|LMT CAT|-2a.k -20|01|-2GJea.k|26e5","Africa/Cairo|EET EEST|-20 -30|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-1bIO0 vb0 1ip0 11z0 1iN0 1nz0 12p0 1pz0 10N0 1pz0 16p0 1jz0 s3d0 Vz0 1oN0 11b0 1oO0 10N0 1pz0 10N0 1pb0 10N0 1pb0 10N0 1pb0 10N0 1pz0 10N0 1pb0 10N0 1pb0 11d0 1oL0 11d0 1pb0 11d0 1oL0 11d0 1oL0 11d0 1oL0 11d0 1pb0 11d0 1oL0 11d0 1oL0 11d0 1oL0 11d0 1pb0 11d0 1oL0 11d0 1oL0 11d0 1oL0 11d0 1pb0 11d0 1oL0 11d0 1WL0 rd0 1Rz0 wp0 1pb0 11d0 1oL0 11d0 1oL0 11d0 1oL0 11d0 1pb0 11d0 1qL0 Xd0 1oL0 11d0 1oL0 11d0 1pb0 11d0 1oL0 11d0 1oL0 11d0 1ny0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 WL0 1qN0 Rb0 1wp0 On0 1zd0 Lz0 1EN0 Fb0 c10 8n0 8Nd0 gL0 e10 mn0|15e6","Africa/Casablanca|LMT WET WEST CET|u.k 0 -10 -10|0121212121212121213121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2gMnt.E 130Lt.E rb0 Dd0 dVb0 b6p0 TX0 EoB0 LL0 gnd0 rz0 43d0 AL0 1Nd0 XX0 1Cp0 pz0 dEp0 4mn0 SyN0 AL0 1Nd0 wn0 1FB0 Db0 1zd0 Lz0 1Nf0 wM0 co0 go0 1o00 s00 dA0 vc0 11A0 A00 e00 y00 11A0 uM0 e00 Dc0 11A0 s00 e00 IM0 WM0 mo0 gM0 LA0 WM0 jA0 e00 Rc0 11A0 e00 e00 U00 11A0 8o0 e00 11A0 11A0 5A0 e00 17c0 1fA0 1a00 1a00 1fA0 17c0 1io0 14o0 1lc0 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1lc0 14o0 1fA0|32e5","Africa/Ceuta|WET WEST CET CEST|0 -10 -10 -20|010101010101010101010232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-25KN0 11z0 drd0 18o0 3I00 17c0 1fA0 1a00 1io0 1a00 1y7p0 LL0 gnd0 rz0 43d0 AL0 1Nd0 XX0 1Cp0 pz0 dEp0 4VB0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|85e3","Africa/El_Aaiun|LMT WAT WET WEST|Q.M 10 0 -10|01232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-1rDz7.c 1GVA7.c 6L0 AL0 1Nd0 XX0 1Cp0 pz0 1cBB0 AL0 1Nd0 wn0 1FB0 Db0 1zd0 Lz0 1Nf0 wM0 co0 go0 1o00 s00 dA0 vc0 11A0 A00 e00 y00 11A0 uM0 e00 Dc0 11A0 s00 e00 IM0 WM0 mo0 gM0 LA0 WM0 jA0 e00 Rc0 11A0 e00 e00 U00 11A0 8o0 e00 11A0 11A0 5A0 e00 17c0 1fA0 1a00 1a00 1fA0 17c0 1io0 14o0 1lc0 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1lc0 14o0 1fA0|20e4","Africa/Johannesburg|SAST SAST SAST|-1u -20 -30|012121|-2GJdu 1Ajdu 1cL0 1cN0 1cL0|84e5","Africa/Khartoum|LMT CAT CAST EAT|-2a.8 -20 -30 -30|01212121212121212121212121212121213|-1yW2a.8 1zK0a.8 16L0 1iN0 17b0 1jd0 17b0 1ip0 17z0 1i10 17X0 1hB0 18n0 1hd0 19b0 1gp0 19z0 1iN0 17b0 1ip0 17z0 1i10 18n0 1hd0 18L0 1gN0 19b0 1gp0 19z0 1iN0 17z0 1i10 17X0 yGd0|51e5","Africa/Monrovia|MMT LRT GMT|H.8 I.u 0|012|-23Lzg.Q 29s01.m|11e5","Africa/Ndjamena|LMT WAT WAST|-10.c -10 -20|0121|-2le10.c 2J3c0.c Wn0|13e5","Africa/Tripoli|LMT CET CEST EET|-Q.I -10 -20 -20|012121213121212121212121213123123|-21JcQ.I 1hnBQ.I vx0 4iP0 xx0 4eN0 Bb0 7ip0 U0n0 A10 1db0 1cN0 1db0 1dd0 1db0 1eN0 1bb0 1e10 1cL0 1c10 1db0 1dd0 1db0 1cN0 1db0 1q10 fAn0 1ep0 1db0 AKq0 TA0 1o00|11e5","Africa/Tunis|PMT CET CEST|-9.l -10 -20|0121212121212121212121212121212121|-2nco9.l 18pa9.l 1qM0 DA0 3Tc0 11B0 1ze0 WM0 7z0 3d0 14L0 1cN0 1f90 1ar0 16J0 1gXB0 WM0 1rA0 11c0 nwo0 Ko0 1cM0 1cM0 1rA0 10M0 zuM0 10N0 1aN0 1qM0 WM0 1qM0 11A0 1o00|20e5","Africa/Windhoek|SWAT SAST SAST CAT WAT WAST|-1u -20 -30 -20 -10 -20|012134545454545454545454545454545454545454545454545454545454545454545454545454545454545454545|-2GJdu 1Ajdu 1cL0 1SqL0 9NA0 11D0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 11B0 1nX0 11B0|32e4","America/Adak|NST NWT NPT BST BDT AHST HST HDT|b0 a0 a0 b0 a0 a0 a0 90|012034343434343434343434343434343456767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676|-17SX0 8wW0 iB0 Qlb0 52O0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 cm0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|326","America/Anchorage|CAT CAWT CAPT AHST AHDT YST AKST AKDT|a0 90 90 a0 90 90 90 80|012034343434343434343434343434343456767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676|-17T00 8wX0 iA0 Qlb0 52O0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 cm0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|30e4","America/Port_of_Spain|LMT AST|46.4 40|01|-2kNvR.U|43e3","America/Araguaina|LMT BRT BRST|3c.M 30 20|0121212121212121212121212121212121212121212121212121|-2glwL.c HdKL.c 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 dMN0 Lz0 1zd0 Rb0 1wN0 Wn0 1tB0 Rb0 1tB0 WL0 1tB0 Rb0 1zd0 On0 1HB0 FX0 ny10 Lz0|14e4","America/Argentina/Buenos_Aires|CMT ART ARST ART ARST|4g.M 40 30 30 20|0121212121212121212121212121212121212121213434343434343234343|-20UHH.c pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wp0 Rb0 1wp0 TX0 g0p0 10M0 j3c0 uL0 1qN0 WL0","America/Argentina/Catamarca|CMT ART ARST ART ARST WART|4g.M 40 30 30 20 40|0121212121212121212121212121212121212121213434343454343235343|-20UHH.c pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wq0 Ra0 1wp0 TX0 g0p0 10M0 ako0 7B0 8zb0 uL0","America/Argentina/Cordoba|CMT ART ARST ART ARST WART|4g.M 40 30 30 20 40|0121212121212121212121212121212121212121213434343454343234343|-20UHH.c pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wq0 Ra0 1wp0 TX0 g0p0 10M0 j3c0 uL0 1qN0 WL0","America/Argentina/Jujuy|CMT ART ARST ART ARST WART WARST|4g.M 40 30 30 20 40 30|01212121212121212121212121212121212121212134343456543432343|-20UHH.c pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1ze0 TX0 1ld0 WK0 1wp0 TX0 g0p0 10M0 j3c0 uL0","America/Argentina/La_Rioja|CMT ART ARST ART ARST WART|4g.M 40 30 30 20 40|01212121212121212121212121212121212121212134343434534343235343|-20UHH.c pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Qn0 qO0 16n0 Rb0 1wp0 TX0 g0p0 10M0 ako0 7B0 8zb0 uL0","America/Argentina/Mendoza|CMT ART ARST ART ARST WART WARST|4g.M 40 30 30 20 40 30|0121212121212121212121212121212121212121213434345656543235343|-20UHH.c pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1u20 SL0 1vd0 Tb0 1wp0 TW0 g0p0 10M0 agM0 Op0 7TX0 uL0","America/Argentina/Rio_Gallegos|CMT ART ARST ART ARST WART|4g.M 40 30 30 20 40|0121212121212121212121212121212121212121213434343434343235343|-20UHH.c pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wp0 Rb0 1wp0 TX0 g0p0 10M0 ako0 7B0 8zb0 uL0","America/Argentina/Salta|CMT ART ARST ART ARST WART|4g.M 40 30 30 20 40|01212121212121212121212121212121212121212134343434543432343|-20UHH.c pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wq0 Ra0 1wp0 TX0 g0p0 10M0 j3c0 uL0","America/Argentina/San_Juan|CMT ART ARST ART ARST WART|4g.M 40 30 30 20 40|01212121212121212121212121212121212121212134343434534343235343|-20UHH.c pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Qn0 qO0 16n0 Rb0 1wp0 TX0 g0p0 10M0 ak00 m10 8lb0 uL0","America/Argentina/San_Luis|CMT ART ARST ART ARST WART WARST|4g.M 40 30 30 20 40 30|01212121212121212121212121212121212121212134343456536353465653|-20UHH.c pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 XX0 1q20 SL0 AN0 kin0 10M0 ak00 m10 8lb0 8L0 jd0 1qN0 WL0 1qN0","America/Argentina/Tucuman|CMT ART ARST ART ARST WART|4g.M 40 30 30 20 40|012121212121212121212121212121212121212121343434345434323534343|-20UHH.c pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wq0 Ra0 1wp0 TX0 g0p0 10M0 ako0 4N0 8BX0 uL0 1qN0 WL0","America/Argentina/Ushuaia|CMT ART ARST ART ARST WART|4g.M 40 30 30 20 40|0121212121212121212121212121212121212121213434343434343235343|-20UHH.c pKnH.c Mn0 1iN0 Tb0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 1C10 LX0 1C10 LX0 1C10 LX0 1C10 Mn0 MN0 2jz0 MN0 4lX0 u10 5Lb0 1pB0 Fnz0 u10 uL0 1vd0 SL0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 zvd0 Bz0 1tB0 TX0 1wp0 Rb0 1wp0 Rb0 1wp0 TX0 g0p0 10M0 ajA0 8p0 8zb0 uL0","America/Curacao|LMT ANT AST|4z.L 4u 40|012|-2kV7o.d 28KLS.d|15e4","America/Asuncion|AMT PYT PYT PYST|3O.E 40 30 30|012131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313|-1x589.k 1DKM9.k 3CL0 3Dd0 10L0 1pB0 10n0 1pB0 10n0 1pB0 1cL0 1dd0 1db0 1dd0 1cL0 1dd0 1cL0 1dd0 1cL0 1dd0 1db0 1dd0 1cL0 1dd0 1cL0 1dd0 1cL0 1dd0 1db0 1dd0 1cL0 1lB0 14n0 1dd0 1cL0 1fd0 WL0 1rd0 1aL0 1dB0 Xz0 1qp0 Xb0 1qN0 10L0 1rB0 TX0 1tB0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 1cL0 WN0 1qL0 11B0 1nX0 1ip0 WL0 1qN0 WL0 1qN0 WL0 1tB0 TX0 1tB0 TX0 1tB0 19X0 1a10 1fz0 1a10 1fz0 1cN0 17b0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1fB0 19X0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1fB0 19X0 1ip0 17b0 1ip0 17b0 1ip0|28e5","America/Atikokan|CST CDT CWT CPT EST|60 50 50 50 50|0101234|-25TQ0 1in0 Rnb0 3je0 8x30 iw0|28e2","America/Bahia|LMT BRT BRST|2y.4 30 20|01212121212121212121212121212121212121212121212121212121212121|-2glxp.U HdLp.U 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 1EN0 Lz0 1C10 IL0 1HB0 Db0 1HB0 On0 1zd0 On0 1zd0 Lz0 1zd0 Rb0 1wN0 Wn0 1tB0 Rb0 1tB0 WL0 1tB0 Rb0 1zd0 On0 1HB0 FX0 l5B0 Rb0|27e5","America/Bahia_Banderas|LMT MST CST PST MDT CDT|71 70 60 80 60 50|0121212131414141414141414141414141414152525252525252525252525252525252525252525252525252525252|-1UQF0 deL0 8lc0 17c0 10M0 1dd0 otX0 gmN0 P2N0 13Vd0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nW0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0|84e3","America/Barbados|LMT BMT AST ADT|3W.t 3W.t 40 30|01232323232|-1Q0I1.v jsM0 1ODC1.v IL0 1ip0 17b0 1ip0 17b0 1ld0 13b0|28e4","America/Belem|LMT BRT BRST|3d.U 30 20|012121212121212121212121212121|-2glwK.4 HdKK.4 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0|20e5","America/Belize|LMT CST CHDT CDT|5Q.M 60 5u 50|01212121212121212121212121212121212121212121212121213131|-2kBu7.c fPA7.c Onu 1zcu Rbu 1wou Rbu 1wou Rbu 1zcu Onu 1zcu Onu 1zcu Rbu 1wou Rbu 1wou Rbu 1wou Rbu 1zcu Onu 1zcu Onu 1zcu Rbu 1wou Rbu 1wou Rbu 1zcu Onu 1zcu Onu 1zcu Onu 1zcu Rbu 1wou Rbu 1wou Rbu 1zcu Onu 1zcu Onu 1zcu Rbu 1wou Rbu 1f0Mu qn0 lxB0 mn0|57e3","America/Blanc-Sablon|AST ADT AWT APT|40 30 30 30|010230|-25TS0 1in0 UGp0 8x50 iu0|11e2","America/Boa_Vista|LMT AMT AMST|42.E 40 30|0121212121212121212121212121212121|-2glvV.k HdKV.k 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 smp0 WL0 1tB0 2L0|62e2","America/Bogota|BMT COT COST|4U.g 50 40|0121|-2eb73.I 38yo3.I 2en0|90e5","America/Boise|PST PDT MST MWT MPT MDT|80 70 70 60 60 60|0101023425252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252|-261q0 1nX0 11B0 1nX0 8C10 JCL0 8x20 ix0 QwN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 Dd0 1Kn0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|21e4","America/Cambridge_Bay|-00 MST MWT MPT MDDT MDT CST CDT EST|0 70 60 60 50 60 60 50 50|0123141515151515151515151515151515151515151515678651515151515151515151515151515151515151515151515151515151515151515151515151|-21Jc0 RO90 8x20 ix0 LCL0 1fA0 zgO0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11A0 1nX0 2K0 WQ0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|15e2","America/Campo_Grande|LMT AMT AMST|3C.s 40 30|012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212|-2glwl.w HdLl.w 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 1EN0 Lz0 1C10 IL0 1HB0 Db0 1HB0 On0 1zd0 On0 1zd0 Lz0 1zd0 Rb0 1wN0 Wn0 1tB0 Rb0 1tB0 WL0 1tB0 Rb0 1zd0 On0 1HB0 FX0 1C10 Lz0 1Ip0 HX0 1zd0 On0 1HB0 IL0 1wp0 On0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 Rb0 1zd0 Lz0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1C10 Lz0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 Rb0 1wp0 On0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1C10 Lz0 1C10 Lz0 1C10 Lz0 1C10 On0 1zd0 Rb0 1wp0 On0 1C10 Lz0 1C10 On0 1zd0|77e4","America/Cancun|LMT CST EST EDT CDT|5L.4 60 50 40 50|0123232341414141414141414141414141414141412|-1UQG0 2q2o0 yLB0 1lb0 14p0 1lb0 14p0 Lz0 xB0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 Dd0|63e4","America/Caracas|CMT VET VET|4r.E 4u 40|01212|-2kV7w.k 28KM2.k 1IwOu kqo0|29e5","America/Cayenne|LMT GFT GFT|3t.k 40 30|012|-2mrwu.E 2gWou.E|58e3","America/Panama|CMT EST|5j.A 50|01|-2uduE.o|15e5","America/Chicago|CST CDT EST CWT CPT|60 50 50 50 50|01010101010101010101010101010101010102010101010103401010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-261s0 1nX0 11B0 1nX0 1wp0 TX0 WN0 1qL0 1cN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 11B0 1Hz0 14p0 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 RB0 8x30 iw0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|92e5","America/Chihuahua|LMT MST CST CDT MDT|74.k 70 60 50 60|0121212323241414141414141414141414141414141414141414141414141414141414141414141414141414141|-1UQF0 deL0 8lc0 17c0 10M0 1dd0 2zQN0 1lb0 14p0 1lb0 14q0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0|81e4","America/Costa_Rica|SJMT CST CDT|5A.d 60 50|0121212121|-1Xd6n.L 2lu0n.L Db0 1Kp0 Db0 pRB0 15b0 1kp0 mL0|12e5","America/Creston|MST PST|70 80|010|-29DR0 43B0|53e2","America/Cuiaba|LMT AMT AMST|3I.k 40 30|0121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212|-2glwf.E HdLf.E 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 1EN0 Lz0 1C10 IL0 1HB0 Db0 1HB0 On0 1zd0 On0 1zd0 Lz0 1zd0 Rb0 1wN0 Wn0 1tB0 Rb0 1tB0 WL0 1tB0 Rb0 1zd0 On0 1HB0 FX0 4a10 HX0 1zd0 On0 1HB0 IL0 1wp0 On0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 Rb0 1zd0 Lz0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1C10 Lz0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 Rb0 1wp0 On0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1C10 Lz0 1C10 Lz0 1C10 Lz0 1C10 On0 1zd0 Rb0 1wp0 On0 1C10 Lz0 1C10 On0 1zd0|54e4","America/Danmarkshavn|LMT WGT WGST GMT|1e.E 30 20 0|01212121212121212121212121212121213|-2a5WJ.k 2z5fJ.k 19U0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 DC0|8","America/Dawson|YST YDT YWT YPT YDDT PST PDT|90 80 80 80 70 80 70|0101023040565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565|-25TN0 1in0 1o10 13V0 Ser0 8x00 iz0 LCL0 1fA0 jrA0 fNd0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|13e2","America/Dawson_Creek|PST PDT PWT PPT MST|80 70 70 70 70|0102301010101010101010101010101010101010101010101010101014|-25TO0 1in0 UGp0 8x10 iy0 3NB0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 ML0|12e3","America/Denver|MST MDT MWT MPT|70 60 60 60|01010101023010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-261r0 1nX0 11B0 1nX0 11B0 1qL0 WN0 mn0 Ord0 8x20 ix0 LCN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|26e5","America/Detroit|LMT CST EST EWT EPT EDT|5w.b 60 50 40 40 40|01234252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252|-2Cgir.N peqr.N 156L0 8x40 iv0 6fd0 11z0 Jy10 SL0 dnB0 1cL0 s10 1Vz0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|37e5","America/Edmonton|LMT MST MDT MWT MPT|7x.Q 70 60 60 60|01212121212121341212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2yd4q.8 shdq.8 1in0 17d0 hz0 2dB0 1fz0 1a10 11z0 1qN0 WL0 1qN0 11z0 IGN0 8x20 ix0 3NB0 11z0 LFB0 1cL0 3Cp0 1cL0 66N0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|10e5","America/Eirunepe|LMT ACT ACST AMT|4D.s 50 40 40|0121212121212121212121212121212131|-2glvk.w HdLk.w 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 dPB0 On0 yTd0 d5X0|31e3","America/El_Salvador|LMT CST CDT|5U.M 60 50|012121|-1XiG3.c 2Fvc3.c WL0 1qN0 WL0|11e5","America/Tijuana|LMT MST PST PDT PWT PPT|7M.4 70 80 70 70 70|012123245232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-1UQE0 4PX0 8mM0 8lc0 SN0 1cL0 pHB0 83r0 zI0 5O10 1Rz0 cOP0 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 BUp0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 U10 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|20e5","America/Fort_Nelson|PST PDT PWT PPT MST|80 70 70 70 70|01023010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010104|-25TO0 1in0 UGp0 8x10 iy0 3NB0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0|39e2","America/Fort_Wayne|CST CDT CWT CPT EST EDT|60 50 50 50 50 40|010101023010101010101010101040454545454545454545454545454545454545454545454545454545454545454545454|-261s0 1nX0 11B0 1nX0 QI10 Db0 RB0 8x30 iw0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 5Tz0 1o10 qLb0 1cL0 1cN0 1cL0 1qhd0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0","America/Fortaleza|LMT BRT BRST|2y 30 20|0121212121212121212121212121212121212121|-2glxq HdLq 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 nsp0 WL0 1tB0 5z0 2mN0 On0|34e5","America/Glace_Bay|LMT AST ADT AWT APT|3X.M 40 30 30 30|012134121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2IsI0.c CwO0.c 1in0 UGp0 8x50 iu0 iq10 11z0 Jg10 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|19e3","America/Godthab|LMT WGT WGST|3q.U 30 20|0121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2a5Ux.4 2z5dx.4 19U0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|17e3","America/Goose_Bay|NST NDT NST NDT NWT NPT AST ADT ADDT|3u.Q 2u.Q 3u 2u 2u 2u 40 30 20|010232323232323245232323232323232323232323232323232323232326767676767676767676767676767676767676767676768676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676|-25TSt.8 1in0 DXb0 2HbX.8 WL0 1qN0 WL0 1qN0 WL0 1tB0 TX0 1tB0 WL0 1qN0 WL0 1qN0 7UHu itu 1tB0 WL0 1qN0 WL0 1qN0 WL0 1qN0 WL0 1tB0 WL0 1ld0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 S10 g0u 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14n1 1lb0 14p0 1nW0 11C0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zcX Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|76e2","America/Grand_Turk|KMT EST EDT AST|57.b 50 40 40|0121212121212121212121212121212121212121212121212121212121212121212121212123|-2l1uQ.N 2HHBQ.N 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|37e2","America/Guatemala|LMT CST CDT|62.4 60 50|0121212121|-24KhV.U 2efXV.U An0 mtd0 Nz0 ifB0 17b0 zDB0 11z0|13e5","America/Guayaquil|QMT ECT|5e 50|01|-1yVSK|27e5","America/Guyana|LMT GBGT GYT GYT GYT|3Q.E 3J 3J 30 40|01234|-2dvU7.k 24JzQ.k mlc0 Bxbf|80e4","America/Halifax|LMT AST ADT AWT APT|4e.o 40 30 30 30|0121212121212121212121212121212121212121212121212134121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2IsHJ.A xzzJ.A 1db0 3I30 1in0 3HX0 IL0 1E10 ML0 1yN0 Pb0 1Bd0 Mn0 1Bd0 Rz0 1w10 Xb0 1w10 LX0 1w10 Xb0 1w10 Lz0 1C10 Jz0 1E10 OL0 1yN0 Un0 1qp0 Xb0 1qp0 11X0 1w10 Lz0 1HB0 LX0 1C10 FX0 1w10 Xb0 1qp0 Xb0 1BB0 LX0 1td0 Xb0 1qp0 Xb0 Rf0 8x50 iu0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 3Qp0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 3Qp0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 6i10 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|39e4","America/Havana|HMT CST CDT|5t.A 50 40|012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-1Meuu.o 72zu.o ML0 sld0 An0 1Nd0 Db0 1Nd0 An0 6Ep0 An0 1Nd0 An0 JDd0 Mn0 1Ap0 On0 1fd0 11X0 1qN0 WL0 1wp0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 14n0 1ld0 14L0 1kN0 15b0 1kp0 1cL0 1cN0 1fz0 1a10 1fz0 1fB0 11z0 14p0 1nX0 11B0 1nX0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 14n0 1ld0 14n0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 1a10 1in0 1a10 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 17c0 1o00 11A0 1qM0 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 11A0 6i00 Rc0 1wo0 U00 1tA0 Rc0 1wo0 U00 1wo0 U00 1zc0 U00 1qM0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0|21e5","America/Hermosillo|LMT MST CST PST MDT|7n.Q 70 60 80 60|0121212131414141|-1UQF0 deL0 8lc0 17c0 10M0 1dd0 otX0 gmN0 P2N0 13Vd0 1lb0 14p0 1lb0 14p0 1lb0|64e4","America/Indiana/Knox|CST CDT CWT CPT EST|60 50 50 50 50|0101023010101010101010101010101010101040101010101010101010101010101010101010101010101010141010101010101010101010101010101010101010101010101010101010101010|-261s0 1nX0 11B0 1nX0 SgN0 8x30 iw0 3NB0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 1fz0 1cN0 1cL0 1cN0 11z0 1o10 11z0 1o10 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 3Cn0 8wp0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 z8o0 1o00 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0","America/Indiana/Marengo|CST CDT CWT CPT EST EDT|60 50 50 50 50 40|0101023010101010101010104545454545414545454545454545454545454545454545454545454545454545454545454545454|-261s0 1nX0 11B0 1nX0 SgN0 8x30 iw0 dyN0 11z0 6fd0 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 jrz0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1VA0 LA0 1BX0 1e6p0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0","America/Indiana/Petersburg|CST CDT CWT CPT EST EDT|60 50 50 50 50 40|01010230101010101010101010104010101010101010101010141014545454545454545454545454545454545454545454545454545454545454|-261s0 1nX0 11B0 1nX0 SgN0 8x30 iw0 njX0 WN0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 3Fb0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 19co0 1o00 Rd0 1zb0 Oo0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0","America/Indiana/Tell_City|CST CDT CWT CPT EST EDT|60 50 50 50 50 40|01010230101010101010101010101010454541010101010101010101010101010101010101010101010101010101010101010|-261s0 1nX0 11B0 1nX0 SgN0 8x30 iw0 1o10 11z0 g0p0 11z0 1o10 11z0 1qL0 WN0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 1fz0 1cN0 WL0 1qN0 1cL0 1cN0 1cL0 1cN0 caL0 1cL0 1cN0 1cL0 1qhd0 1o00 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0","America/Indiana/Vevay|CST CDT CWT CPT EST EDT|60 50 50 50 50 40|010102304545454545454545454545454545454545454545454545454545454545454545454545454|-261s0 1nX0 11B0 1nX0 SgN0 8x30 iw0 kPB0 Awn0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1lnd0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0","America/Indiana/Vincennes|CST CDT CWT CPT EST EDT|60 50 50 50 50 40|01010230101010101010101010101010454541014545454545454545454545454545454545454545454545454545454545454|-261s0 1nX0 11B0 1nX0 SgN0 8x30 iw0 1o10 11z0 g0p0 11z0 1o10 11z0 1qL0 WN0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 1fz0 1cN0 WL0 1qN0 1cL0 1cN0 1cL0 1cN0 caL0 1cL0 1cN0 1cL0 1qhd0 1o00 Rd0 1zb0 Oo0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0","America/Indiana/Winamac|CST CDT CWT CPT EST EDT|60 50 50 50 50 40|01010230101010101010101010101010101010454541054545454545454545454545454545454545454545454545454545454545454|-261s0 1nX0 11B0 1nX0 SgN0 8x30 iw0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 1fz0 1cN0 1cL0 1cN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 jrz0 1cL0 1cN0 1cL0 1qhd0 1o00 Rd0 1za0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0","America/Inuvik|-00 PST PDDT MST MDT|0 80 60 70 60|0121343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343|-FnA0 tWU0 1fA0 wPe0 2pz0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|35e2","America/Iqaluit|-00 EWT EPT EST EDDT EDT CST CDT|0 40 40 50 30 40 60 50|01234353535353535353535353535353535353535353567353535353535353535353535353535353535353535353535353535353535353535353535353|-16K00 7nX0 iv0 LCL0 1fA0 zgO0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11C0 1nX0 11A0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|67e2","America/Jamaica|KMT EST EDT|57.b 50 40|0121212121212121212121|-2l1uQ.N 2uM1Q.N 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0|94e4","America/Juneau|PST PWT PPT PDT YDT YST AKST AKDT|80 70 70 70 80 90 90 80|01203030303030303030303030403030356767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676|-17T20 8x10 iy0 Vo10 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cM0 1cM0 1cL0 1cN0 1fz0 1a10 1fz0 co0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|33e3","America/Kentucky/Louisville|CST CDT CWT CPT EST EDT|60 50 50 50 50 40|0101010102301010101010101010101010101454545454545414545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454|-261s0 1nX0 11B0 1nX0 3Fd0 Nb0 LPd0 11z0 RB0 8x30 iw0 Bb0 10N0 2bB0 8in0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 xz0 gso0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1VA0 LA0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0","America/Kentucky/Monticello|CST CDT CWT CPT EST EDT|60 50 50 50 50 40|0101023010101010101010101010101010101010101010101010101010101010101010101454545454545454545454545454545454545454545454545454545454545454545454545454|-261s0 1nX0 11B0 1nX0 SgN0 8x30 iw0 SWp0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11A0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0","America/La_Paz|CMT BOST BOT|4w.A 3w.A 40|012|-1x37r.o 13b0|19e5","America/Lima|LMT PET PEST|58.A 50 40|0121212121212121|-2tyGP.o 1bDzP.o zX0 1aN0 1cL0 1cN0 1cL0 1PrB0 zX0 1O10 zX0 6Gp0 zX0 98p0 zX0|11e6","America/Los_Angeles|PST PDT PWT PPT|80 70 70 70|010102301010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-261q0 1nX0 11B0 1nX0 SgN0 8x10 iy0 5Wp0 1Vb0 3dB0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|15e6","America/Maceio|LMT BRT BRST|2m.Q 30 20|012121212121212121212121212121212121212121|-2glxB.8 HdLB.8 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 dMN0 Lz0 8Q10 WL0 1tB0 5z0 2mN0 On0|93e4","America/Managua|MMT CST EST CDT|5J.c 60 50 50|0121313121213131|-1quie.M 1yAMe.M 4mn0 9Up0 Dz0 1K10 Dz0 s3F0 1KH0 DB0 9In0 k8p0 19X0 1o30 11y0|22e5","America/Manaus|LMT AMT AMST|40.4 40 30|01212121212121212121212121212121|-2glvX.U HdKX.U 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 dPB0 On0|19e5","America/Martinique|FFMT AST ADT|44.k 40 30|0121|-2mPTT.E 2LPbT.E 19X0|39e4","America/Matamoros|LMT CST CDT|6E 60 50|0121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-1UQG0 2FjC0 1nX0 i6p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 U10 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|45e4","America/Mazatlan|LMT MST CST PST MDT|75.E 70 60 80 60|0121212131414141414141414141414141414141414141414141414141414141414141414141414141414141414141|-1UQF0 deL0 8lc0 17c0 10M0 1dd0 otX0 gmN0 P2N0 13Vd0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0|44e4","America/Menominee|CST CDT CWT CPT EST|60 50 50 50 50|01010230101041010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-261s0 1nX0 11B0 1nX0 SgN0 8x30 iw0 1o10 11z0 LCN0 1fz0 6410 9Jb0 1cM0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|85e2","America/Merida|LMT CST EST CDT|5W.s 60 50 50|0121313131313131313131313131313131313131313131313131313131313131313131313131313131313131|-1UQG0 2q2o0 2hz0 wu30 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0|11e5","America/Metlakatla|PST PWT PPT PDT AKST AKDT|80 70 70 70 90 80|0120303030303030303030303030303030454545454545454545454545454545454545454545454|-17T20 8x10 iy0 Vo10 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1hU10 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|14e2","America/Mexico_City|LMT MST CST CDT CWT|6A.A 70 60 50 50|012121232324232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-1UQF0 deL0 8lc0 17c0 10M0 1dd0 gEn0 TX0 3xd0 Jb0 6zB0 SL0 e5d0 17b0 1Pff0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0|20e6","America/Miquelon|LMT AST PMST PMDT|3I.E 40 30 20|012323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-2mKkf.k 2LTAf.k gQ10 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|61e2","America/Moncton|EST AST ADT AWT APT|50 40 30 30 30|012121212121212121212134121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2IsH0 CwN0 1in0 zAo0 An0 1Nd0 An0 1Nd0 An0 1Nd0 An0 1Nd0 An0 1Nd0 An0 1K10 Lz0 1zB0 NX0 1u10 Wn0 S20 8x50 iu0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 3Cp0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14n1 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 ReX 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|64e3","America/Monterrey|LMT CST CDT|6F.g 60 50|0121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-1UQG0 2FjC0 1nX0 i6p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0|41e5","America/Montevideo|MMT UYT UYHST UYST UYT UYHST|3I.I 3u 30 20 30 2u|012121212121212121212121213434343434345454543453434343434343434343434343434343434343434|-20UIf.g 8jzJ.g 1cLu 1dcu 1cLu 1dcu 1cLu ircu 11zu 1o0u 11zu 1o0u 11zu 1qMu WLu 1qMu WLu 1qMu WLu 1qMu 11zu 1o0u 11zu NAu 11bu 2iMu zWu Dq10 19X0 pd0 jz0 cm10 19X0 1fB0 1on0 11d0 1oL0 1nB0 1fzu 1aou 1fzu 1aou 1fzu 3nAu Jb0 3MN0 1SLu 4jzu 2PB0 Lb0 3Dd0 1pb0 ixd0 An0 1MN0 An0 1wp0 On0 1wp0 Rb0 1zd0 On0 1wp0 Rb0 s8p0 1fB0 1ip0 11z0 1ld0 14n0 1o10 11z0 1o10 11z0 1o10 14n0 1ld0 14n0 1ld0 14n0 1o10 11z0 1o10 11z0 1o10 11z0|17e5","America/Toronto|EST EDT EWT EPT|50 40 40 40|01010101010101010101010101010101010101010101012301010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-25TR0 1in0 11Wu 1nzu 1fD0 WJ0 1wr0 Nb0 1Ap0 On0 1zd0 On0 1wp0 TX0 1tB0 TX0 1tB0 TX0 1tB0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 4kM0 8x40 iv0 1o10 11z0 1nX0 11z0 1o10 11z0 1o10 1qL0 11D0 1nX0 11B0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|65e5","America/Nassau|LMT EST EDT|59.u 50 40|012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2kNuO.u 26XdO.u 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|24e4","America/New_York|EST EDT EWT EPT|50 40 40 40|01010101010101010101010101010101010101010101010102301010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-261t0 1nX0 11B0 1nX0 11B0 1qL0 1a10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 RB0 8x40 iv0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|21e6","America/Nipigon|EST EDT EWT EPT|50 40 40 40|010123010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-25TR0 1in0 Rnb0 3je0 8x40 iv0 19yN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|16e2","America/Nome|NST NWT NPT BST BDT YST AKST AKDT|b0 a0 a0 b0 a0 90 90 80|012034343434343434343434343434343456767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676767676|-17SX0 8wW0 iB0 Qlb0 52O0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 cl0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|38e2","America/Noronha|LMT FNT FNST|29.E 20 10|0121212121212121212121212121212121212121|-2glxO.k HdKO.k 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 nsp0 WL0 1tB0 2L0 2pB0 On0|30e2","America/North_Dakota/Beulah|MST MDT MWT MPT CST CDT|70 60 60 60 60 50|010102301010101010101010101010101010101010101010101010101010101010101010101010101010101010101014545454545454545454545454545454545454545454545454545454|-261r0 1nX0 11B0 1nX0 SgN0 8x20 ix0 QwN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Oo0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0","America/North_Dakota/Center|MST MDT MWT MPT CST CDT|70 60 60 60 60 50|010102301010101010101010101010101010101010101010101010101014545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454|-261r0 1nX0 11B0 1nX0 SgN0 8x20 ix0 QwN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14o0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0","America/North_Dakota/New_Salem|MST MDT MWT MPT CST CDT|70 60 60 60 60 50|010102301010101010101010101010101010101010101010101010101010101010101010101010101454545454545454545454545454545454545454545454545454545454545454545454|-261r0 1nX0 11B0 1nX0 SgN0 8x20 ix0 QwN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14o0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0","America/Ojinaga|LMT MST CST CDT MDT|6V.E 70 60 50 60|0121212323241414141414141414141414141414141414141414141414141414141414141414141414141414141|-1UQF0 deL0 8lc0 17c0 10M0 1dd0 2zQN0 1lb0 14p0 1lb0 14q0 1lb0 14p0 1nX0 11B0 1nX0 1fB0 WL0 1fB0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 U10 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|23e3","America/Pangnirtung|-00 AST AWT APT ADDT ADT EDT EST CST CDT|0 40 30 30 20 30 40 50 60 50|012314151515151515151515151515151515167676767689767676767676767676767676767676767676767676767676767676767676767676767676767|-1XiM0 PnG0 8x50 iu0 LCL0 1fA0 zgO0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1o00 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11C0 1nX0 11A0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|14e2","America/Paramaribo|LMT PMT PMT NEGT SRT SRT|3E.E 3E.Q 3E.A 3u 3u 30|012345|-2nDUj.k Wqo0.c qanX.I 1dmLN.o lzc0|24e4","America/Phoenix|MST MDT MWT|70 60 60|01010202010|-261r0 1nX0 11B0 1nX0 SgN0 4Al1 Ap0 1db0 SWqX 1cL0|42e5","America/Port-au-Prince|PPMT EST EDT|4N 50 40|01212121212121212121212121212121212121212121|-28RHb 2FnMb 19X0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14q0 1o00 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 14o0 1o00 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 i6n0 1nX0 11B0 1nX0 d430 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|23e5","America/Rio_Branco|LMT ACT ACST AMT|4v.c 50 40 40|01212121212121212121212121212131|-2glvs.M HdLs.M 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 NBd0 d5X0|31e4","America/Porto_Velho|LMT AMT AMST|4f.A 40 30|012121212121212121212121212121|-2glvI.o HdKI.o 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0|37e4","America/Puerto_Rico|AST AWT APT|40 30 30|0120|-17lU0 7XT0 iu0|24e5","America/Rainy_River|CST CDT CWT CPT|60 50 50 50|010123010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-25TQ0 1in0 Rnb0 3je0 8x30 iw0 19yN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|842","America/Rankin_Inlet|-00 CST CDDT CDT EST|0 60 40 50 50|012131313131313131313131313131313131313131313431313131313131313131313131313131313131313131313131313131313131313131313131|-vDc0 keu0 1fA0 zgO0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|26e2","America/Recife|LMT BRT BRST|2j.A 30 20|0121212121212121212121212121212121212121|-2glxE.o HdLE.o 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 nsp0 WL0 1tB0 2L0 2pB0 On0|33e5","America/Regina|LMT MST MDT MWT MPT CST|6W.A 70 60 60 60 60|012121212121212121212121341212121212121212121212121215|-2AD51.o uHe1.o 1in0 s2L0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 66N0 1cL0 1cN0 19X0 1fB0 1cL0 1fB0 1cL0 1cN0 1cL0 M30 8x20 ix0 1ip0 1cL0 1ip0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 3NB0 1cL0 1cN0|19e4","America/Resolute|-00 CST CDDT CDT EST|0 60 40 50 50|012131313131313131313131313131313131313131313431313131313431313131313131313131313131313131313131313131313131313131313131|-SnA0 GWS0 1fA0 zgO0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|229","America/Santarem|LMT AMT AMST BRT|3C.M 40 30 30|0121212121212121212121212121213|-2glwl.c HdLl.c 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 qe10 xb0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 NBd0|21e4","America/Santiago|SMT CLT CLT CLST CLST|4G.K 50 40 40 30|010203131313131212421242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424|-2q2jh.e fJAh.e 5knG.K 1Vzh.e jRAG.K 1pbh.e 11d0 1oL0 11d0 1oL0 11d0 1oL0 11d0 1pb0 11d0 nHX0 op0 9Bz0 jb0 1oN0 ko0 Qeo0 WL0 1zd0 On0 1ip0 11z0 1o10 11z0 1qN0 WL0 1ld0 14n0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 1cL0 1cN0 11z0 1o10 11z0 1qN0 WL0 1fB0 19X0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1ip0 1fz0 1fB0 11z0 1qN0 WL0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1o10 19X0 1fB0 1nX0 G10 1EL0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Dd0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Dd0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Dd0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0|62e5","America/Santo_Domingo|SDMT EST EDT EHDT AST|4E 50 40 4u 40|01213131313131414|-1ttjk 1lJMk Mn0 6sp0 Lbu 1Cou yLu 1RAu wLu 1QMu xzu 1Q0u xXu 1PAu 13jB0 e00|29e5","America/Sao_Paulo|LMT BRT BRST|36.s 30 20|012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212|-2glwR.w HdKR.w 1cc0 1e10 1bX0 Ezd0 So0 1vA0 Mn0 1BB0 ML0 1BB0 zX0 pTd0 PX0 2ep0 nz0 1C10 zX0 1C10 LX0 1C10 Mn0 H210 Rb0 1tB0 IL0 1Fd0 FX0 1EN0 FX0 1HB0 Lz0 1EN0 Lz0 1C10 IL0 1HB0 Db0 1HB0 On0 1zd0 On0 1zd0 Lz0 1zd0 Rb0 1wN0 Wn0 1tB0 Rb0 1tB0 WL0 1tB0 Rb0 1zd0 On0 1HB0 FX0 1C10 Lz0 1Ip0 HX0 1zd0 On0 1HB0 IL0 1wp0 On0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 Rb0 1zd0 Lz0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1C10 Lz0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 Rb0 1wp0 On0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1C10 Lz0 1C10 Lz0 1C10 Lz0 1C10 On0 1zd0 Rb0 1wp0 On0 1C10 Lz0 1C10 On0 1zd0|20e6","America/Scoresbysund|LMT CGT CGST EGST EGT|1r.Q 20 10 0 10|0121343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434|-2a5Ww.8 2z5ew.8 1a00 1cK0 1cL0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|452","America/Sitka|PST PWT PPT PDT YST AKST AKDT|80 70 70 70 90 90 80|01203030303030303030303030303030345656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565|-17T20 8x10 iy0 Vo10 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 co0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|90e2","America/St_Johns|NST NDT NST NDT NWT NPT NDDT|3u.Q 2u.Q 3u 2u 2u 2u 1u|01010101010101010101010101010101010102323232323232324523232323232323232323232323232323232323232323232323232323232323232323232323232323232326232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-28oit.8 14L0 1nB0 1in0 1gm0 Dz0 1JB0 1cL0 1cN0 1cL0 1fB0 19X0 1fB0 19X0 1fB0 19X0 1fB0 19X0 1fB0 1cL0 1cN0 1cL0 1fB0 19X0 1fB0 19X0 1fB0 19X0 1fB0 19X0 1fB0 1cL0 1fB0 19X0 1fB0 19X0 10O0 eKX.8 19X0 1iq0 WL0 1qN0 WL0 1qN0 WL0 1tB0 TX0 1tB0 WL0 1qN0 WL0 1qN0 7UHu itu 1tB0 WL0 1qN0 WL0 1qN0 WL0 1qN0 WL0 1tB0 WL0 1ld0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14n1 1lb0 14p0 1nW0 11C0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zcX Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|11e4","America/Swift_Current|LMT MST MDT MWT MPT CST|7b.k 70 60 60 60 60|012134121212121212121215|-2AD4M.E uHdM.E 1in0 UGp0 8x20 ix0 1o10 17b0 1ip0 11z0 1o10 11z0 1o10 11z0 isN0 1cL0 3Cp0 1cL0 1cN0 11z0 1qN0 WL0 pMp0|16e3","America/Tegucigalpa|LMT CST CDT|5M.Q 60 50|01212121|-1WGGb.8 2ETcb.8 WL0 1qN0 WL0 GRd0 AL0|11e5","America/Thule|LMT AST ADT|4z.8 40 30|012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2a5To.Q 31NBo.Q 1cL0 1cN0 1cL0 1fB0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|656","America/Thunder_Bay|CST EST EWT EPT EDT|60 50 40 40 40|0123141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141414141|-2q5S0 1iaN0 8x40 iv0 XNB0 1cL0 1cN0 1fz0 1cN0 1cL0 3Cp0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|11e4","America/Vancouver|PST PDT PWT PPT|80 70 70 70|0102301010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-25TO0 1in0 UGp0 8x10 iy0 1o10 17b0 1ip0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|23e5","America/Whitehorse|YST YDT YWT YPT YDDT PST PDT|90 80 80 80 70 80 70|0101023040565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565|-25TN0 1in0 1o10 13V0 Ser0 8x00 iz0 LCL0 1fA0 3NA0 vrd0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|23e3","America/Winnipeg|CST CDT CWT CPT|60 50 50 50|010101023010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-2aIi0 WL0 3ND0 1in0 Jap0 Rb0 aCN0 8x30 iw0 1tB0 11z0 1ip0 11z0 1o10 11z0 1o10 11z0 1rd0 10L0 1op0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 1cL0 1cN0 11z0 6i10 WL0 6i10 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1a00 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1a00 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 14o0 1lc0 14o0 1o00 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 14o0 1o00 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 14o0 1lc0 14o0 1o00 11A0 1o00 11A0 1o00 14o0 1lc0 14o0 1lc0 14o0 1o00 11A0 1o00 11A0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|66e4","America/Yakutat|YST YWT YPT YDT AKST AKDT|90 80 80 80 90 80|01203030303030303030303030303030304545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454|-17T10 8x00 iz0 Vo10 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 cn0 10q0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|642","America/Yellowknife|-00 MST MWT MPT MDDT MDT|0 70 60 60 50 60|012314151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151515151|-1pdA0 hix0 8x20 ix0 LCL0 1fA0 zgO0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|19e3","Antarctica/Casey|-00 AWST CAST|0 -80 -b0|012121|-2q00 1DjS0 T90 40P0 KL0|10","Antarctica/Davis|-00 DAVT DAVT|0 -70 -50|01012121|-vyo0 iXt0 alj0 1D7v0 VB0 3Wn0 KN0|70","Antarctica/DumontDUrville|-00 PMT DDUT|0 -a0 -a0|0102|-U0o0 cfq0 bFm0|80","Antarctica/Macquarie|AEST AEDT -00 MIST|-a0 -b0 0 -b0|0102010101010101010101010101010101010101010101010101010101010101010101010101010101010101013|-29E80 19X0 4SL0 1ayy0 Lvs0 1cM0 1o00 Rc0 1wo0 Rc0 1wo0 U00 1wo0 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 11A0 1qM0 WM0 1qM0 Oo0 1zc0 Oo0 1zc0 Oo0 1wo0 WM0 1tA0 WM0 1tA0 U00 1tA0 U00 1tA0 11A0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 11A0 1o00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1cM0 1a00 1io0 1cM0 1cM0 1cM0 1cM0 1cM0|1","Antarctica/Mawson|-00 MAWT MAWT|0 -60 -50|012|-CEo0 2fyk0|60","Pacific/Auckland|NZMT NZST NZST NZDT|-bu -cu -c0 -d0|01020202020202020202020202023232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323|-1GCVu Lz0 1tB0 11zu 1o0u 11zu 1o0u 11zu 1o0u 14nu 1lcu 14nu 1lcu 1lbu 11Au 1nXu 11Au 1nXu 11Au 1nXu 11Au 1nXu 11Au 1qLu WMu 1qLu 11Au 1n1bu IM0 1C00 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1qM0 14o0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1io0 17c0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1io0 17c0 1io0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00|14e5","Antarctica/Palmer|-00 ARST ART ART ARST CLT CLST|0 30 40 30 20 40 30|0121212121234356565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656565656|-cao0 nD0 1vd0 SL0 1vd0 17z0 1cN0 1fz0 1cN0 1cL0 1cN0 asn0 Db0 jsN0 14N0 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 1cL0 1cN0 11z0 1o10 11z0 1qN0 WL0 1fB0 19X0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1ip0 1fz0 1fB0 11z0 1qN0 WL0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1o10 19X0 1fB0 1nX0 G10 1EL0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Dd0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Dd0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Dd0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0|40","Antarctica/Rothera|-00 ROTT|0 30|01|gOo0|130","Antarctica/Syowa|-00 SYOT|0 -30|01|-vs00|20","Antarctica/Troll|-00 UTC CEST|0 0 -20|01212121212121212121212121212121212121212121212121212121212121212121|1puo0 hd0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|40","Antarctica/Vostok|-00 VOST|0 -60|01|-tjA0|25","Europe/Oslo|CET CEST|-10 -20|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-2awM0 Qm0 W6o0 5pf0 WM0 1fA0 1cM0 1cM0 1cM0 1cM0 wJc0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1qM0 WM0 zpc0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|62e4","Asia/Riyadh|LMT AST|-36.Q -30|01|-TvD6.Q|57e5","Asia/Almaty|LMT +05 +06 +07|-57.M -50 -60 -70|012323232323232323232321232323232323232323232323232|-1Pc57.M eUo7.M 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0|15e5","Asia/Amman|LMT EET EEST|-2n.I -20 -30|0121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-1yW2n.I 1HiMn.I KL0 1oN0 11b0 1oN0 11b0 1pd0 1dz0 1cp0 11b0 1op0 11b0 fO10 1db0 1e10 1cL0 1cN0 1cL0 1cN0 1fz0 1pd0 10n0 1ld0 14n0 1hB0 15b0 1ip0 19X0 1cN0 1cL0 1cN0 17b0 1ld0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1So0 y00 1fc0 1dc0 1co0 1dc0 1cM0 1cM0 1cM0 1o00 11A0 1lc0 17c0 1cM0 1cM0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 4bX0 Dd0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|25e5","Asia/Anadyr|LMT ANAT ANAT ANAST ANAST ANAST ANAT|-bN.U -c0 -d0 -e0 -d0 -c0 -b0|01232414141414141414141561414141414141414141414141414141414141561|-1PcbN.U eUnN.U 23CL0 1db0 1cN0 1dc0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qN0 WM0|13e3","Asia/Aqtau|LMT +04 +05 +06|-3l.4 -40 -50 -60|012323232323232323232123232312121212121212121212|-1Pc3l.4 eUnl.4 24PX0 2pX0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0|15e4","Asia/Aqtobe|LMT +04 +05 +06|-3M.E -40 -50 -60|0123232323232323232321232323232323232323232323232|-1Pc3M.E eUnM.E 23CL0 3Db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0|27e4","Asia/Ashgabat|LMT ASHT ASHT ASHST ASHST TMT TMT|-3R.w -40 -50 -60 -50 -40 -50|012323232323232323232324156|-1Pc3R.w eUnR.w 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 ba0 xC0|41e4","Asia/Baghdad|BMT AST ADT|-2V.A -30 -40|012121212121212121212121212121212121212121212121212121|-26BeV.A 2ACnV.A 11b0 1cp0 1dz0 1dd0 1db0 1cN0 1cp0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1de0 1dc0 1dc0 1dc0 1cM0 1dc0 1cM0 1dc0 1cM0 1dc0 1dc0 1dc0 1cM0 1dc0 1cM0 1dc0 1cM0 1dc0 1dc0 1dc0 1cM0 1dc0 1cM0 1dc0 1cM0 1dc0 1dc0 1dc0 1cM0 1dc0 1cM0 1dc0 1cM0 1dc0|66e5","Asia/Qatar|LMT GST AST|-3q.8 -40 -30|012|-21Jfq.8 27BXq.8|96e4","Asia/Baku|LMT BAKT BAKT BAKST BAKST AZST AZT AZT AZST|-3j.o -30 -40 -50 -40 -40 -30 -40 -50|01232323232323232323232456578787878787878787878787878787878787878787|-1Pc3j.o 1jUoj.o WCL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 10K0 c30 1cM0 1cM0 8wq0 1o00 11z0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|27e5","Asia/Bangkok|BMT ICT|-6G.4 -70|01|-218SG.4|15e6","Asia/Barnaul|LMT +06 +07 +08|-5z -60 -70 -80|0123232323232323232323212323232321212121212121212121212121212121212|-21S5z pCnz 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 p90 LE0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3rd0","Asia/Beirut|EET EEST|-20 -30|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-21aq0 1on0 1410 1db0 19B0 1in0 1ip0 WL0 1lQp0 11b0 1oN0 11b0 1oN0 11b0 1pd0 11b0 1oN0 11b0 q6N0 En0 1oN0 11b0 1oN0 11b0 1oN0 11b0 1pd0 11b0 1oN0 11b0 1op0 11b0 dA10 17b0 1iN0 17b0 1iN0 17b0 1iN0 17b0 1vB0 SL0 1mp0 13z0 1iN0 17b0 1iN0 17b0 1jd0 12n0 1a10 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0|22e5","Asia/Bishkek|LMT FRUT FRUT FRUST FRUST KGT KGST KGT|-4W.o -50 -60 -70 -60 -50 -60 -60|01232323232323232323232456565656565656565656565656567|-1Pc4W.o eUnW.o 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 11c0 1tX0 17b0 1ip0 17b0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1cPu 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 T8u|87e4","Asia/Brunei|LMT BNT BNT|-7D.E -7u -80|012|-1KITD.E gDc9.E|42e4","Asia/Kolkata|HMT BURT IST IST|-5R.k -6u -5u -6u|01232|-18LFR.k 1unn.k HB0 7zX0|15e6","Asia/Chita|LMT YAKT YAKT YAKST YAKST YAKT IRKT|-7x.Q -80 -90 -a0 -90 -a0 -80|0123232323232323232323241232323232323232323232323232323232323232562|-21Q7x.Q pAnx.Q 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3re0|33e4","Asia/Choibalsan|LMT ULAT ULAT CHOST CHOT CHOT CHOST|-7C -70 -80 -a0 -90 -80 -90|0123434343434343434343434343434343434343434343456565656565656565656565656565656565656565656565|-2APHC 2UkoC cKn0 1da0 1dd0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 6hD0 11z0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 3Db0 h1f0 1cJ0 1cP0 1cJ0 1cP0 1fx0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1fx0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1fx0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1fx0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0|38e3","Asia/Shanghai|CST CDT|-80 -90|01010101010101010|-1c1I0 LX0 16p0 1jz0 1Myp0 Rb0 1o10 11z0 1o10 11z0 1qN0 11z0 1o10 11z0 1o10 11z0|23e6","Asia/Colombo|MMT IST IHST IST LKT LKT|-5j.w -5u -60 -6u -6u -60|01231451|-2zOtj.w 1rFbN.w 1zzu 7Apu 23dz0 11zu n3cu|22e5","Asia/Dhaka|HMT BURT IST DACT BDT BDST|-5R.k -6u -5u -60 -60 -70|01213454|-18LFR.k 1unn.k HB0 m6n0 LqMu 1x6n0 1i00|16e6","Asia/Damascus|LMT EET EEST|-2p.c -20 -30|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-21Jep.c Hep.c 17b0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1xRB0 11X0 1oN0 10L0 1pB0 11b0 1oN0 10L0 1mp0 13X0 1oN0 11b0 1pd0 11b0 1oN0 11b0 1oN0 11b0 1oN0 11b0 1pd0 11b0 1oN0 11b0 1oN0 11b0 1oN0 11b0 1pd0 11b0 1oN0 Nb0 1AN0 Nb0 bcp0 19X0 1gp0 19X0 3ld0 1xX0 Vd0 1Bz0 Sp0 1vX0 10p0 1dz0 1cN0 1cL0 1db0 1db0 1g10 1an0 1ap0 1db0 1fd0 1db0 1cN0 1db0 1dd0 1db0 1cp0 1dz0 1c10 1dX0 1cN0 1db0 1dd0 1db0 1cN0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1db0 1cN0 1db0 1cN0 19z0 1fB0 1qL0 11B0 1on0 Wp0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0|26e5","Asia/Dili|LMT TLT JST TLT WITA|-8m.k -80 -90 -90 -80|012343|-2le8m.k 1dnXm.k 8HA0 1ew00 Xld0|19e4","Asia/Dubai|LMT GST|-3F.c -40|01|-21JfF.c|39e5","Asia/Dushanbe|LMT DUST DUST DUSST DUSST TJT|-4z.c -50 -60 -70 -60 -50|0123232323232323232323245|-1Pc4z.c eUnz.c 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 14N0|76e4","Asia/Gaza|EET EET EEST IST IDT|-20 -30 -30 -20 -30|010101010102020202020202020202023434343434343434343434343430202020202020202020202020202020202020202020202020202020202020202020202020202020202020|-1c2q0 5Rb0 10r0 1px0 10N0 1pz0 16p0 1jB0 16p0 1jx0 pBd0 Vz0 1oN0 11b0 1oO0 10N0 1pz0 10N0 1pb0 10N0 1pb0 10N0 1pb0 10N0 1pz0 10N0 1pb0 10N0 1pb0 11d0 1oL0 dW0 hfB0 Db0 1fB0 Rb0 npB0 11z0 1C10 IL0 1s10 10n0 1o10 WL0 1zd0 On0 1ld0 11z0 1o10 14n0 1o10 14n0 1nd0 12n0 1nd0 Xz0 1q10 12n0 M10 C00 17c0 1io0 17c0 1io0 17c0 1o00 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 17c0 1io0 18N0 1bz0 19z0 1gp0 1610 1iL0 11z0 1o10 14o0 1lA1 SKX 1xd1 MKX 1AN0 1a00 1fA0 1cL0 1cN0 1nX0 1210 1nz0 1220 1ny0 1220 1qm0 1220 1ny0 1220 1ny0 1220 1ny0 1220 1ny0 1220 1ny0 1220 1qm0 1220 1ny0 1220 1ny0 1220 1ny0 1220 1ny0 1220 1qm0 1220 1ny0 1220 1ny0 1220 1ny0 1220 1ny0 1220 1ny0 1220 1qm0 1220 1ny0 1220 1ny0 1220 1ny0|18e5","Asia/Hebron|EET EET EEST IST IDT|-20 -30 -30 -20 -30|01010101010202020202020202020202343434343434343434343434343020202020202020202020202020202020202020202020202020202020202020202020202020202020202020|-1c2q0 5Rb0 10r0 1px0 10N0 1pz0 16p0 1jB0 16p0 1jx0 pBd0 Vz0 1oN0 11b0 1oO0 10N0 1pz0 10N0 1pb0 10N0 1pb0 10N0 1pb0 10N0 1pz0 10N0 1pb0 10N0 1pb0 11d0 1oL0 dW0 hfB0 Db0 1fB0 Rb0 npB0 11z0 1C10 IL0 1s10 10n0 1o10 WL0 1zd0 On0 1ld0 11z0 1o10 14n0 1o10 14n0 1nd0 12n0 1nd0 Xz0 1q10 12n0 M10 C00 17c0 1io0 17c0 1io0 17c0 1o00 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 17c0 1io0 18N0 1bz0 19z0 1gp0 1610 1iL0 12L0 1mN0 14o0 1lc0 Tb0 1xd1 MKX bB0 cn0 1cN0 1a00 1fA0 1cL0 1cN0 1nX0 1210 1nz0 1220 1ny0 1220 1qm0 1220 1ny0 1220 1ny0 1220 1ny0 1220 1ny0 1220 1ny0 1220 1qm0 1220 1ny0 1220 1ny0 1220 1ny0 1220 1ny0 1220 1qm0 1220 1ny0 1220 1ny0 1220 1ny0 1220 1ny0 1220 1ny0 1220 1qm0 1220 1ny0 1220 1ny0 1220 1ny0|25e4","Asia/Ho_Chi_Minh|LMT PLMT ICT IDT JST|-76.E -76.u -70 -80 -90|0123423232|-2yC76.E bK00.a 1h7b6.u 5lz0 18o0 3Oq0 k5b0 aW00 BAM0|90e5","Asia/Hong_Kong|LMT HKT HKST JST|-7A.G -80 -90 -90|0121312121212121212121212121212121212121212121212121212121212121212121|-2CFHA.G 1sEP6.G 1cL0 ylu 93X0 1qQu 1tX0 Rd0 1In0 NB0 1cL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1kL0 14N0 1nX0 U10 1tz0 U10 1wn0 Rd0 1wn0 U10 1tz0 U10 1tz0 U10 1tz0 U10 1wn0 Rd0 1wn0 Rd0 1wn0 U10 1tz0 U10 1tz0 17d0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 s10 1Vz0 1cN0 1cL0 1cN0 1cL0 6fd0 14n0|73e5","Asia/Hovd|LMT HOVT HOVT HOVST|-66.A -60 -70 -80|012323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-2APG6.A 2Uko6.A cKn0 1db0 1dd0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 6hD0 11z0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 kEp0 1cJ0 1cP0 1cJ0 1cP0 1fx0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1fx0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1fx0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1fx0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0|81e3","Asia/Irkutsk|IMT IRKT IRKT IRKST IRKST IRKT|-6V.5 -70 -80 -90 -80 -90|012323232323232323232324123232323232323232323232323232323232323252|-21zGV.5 pjXV.5 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|60e4","Europe/Istanbul|IMT EET EEST TRST TRT|-1U.U -20 -30 -40 -30|012121212121212121212121212121212121212121212121212121234343434342121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2ogNU.U dzzU.U 11b0 8tB0 1on0 1410 1db0 19B0 1in0 3Rd0 Un0 1oN0 11b0 zSp0 CL0 mN0 1Vz0 1gN0 1pz0 5Rd0 1fz0 1yp0 ML0 1kp0 17b0 1ip0 17b0 1fB0 19X0 1jB0 18L0 1ip0 17z0 qdd0 xX0 3S10 Tz0 dA10 11z0 1o10 11z0 1qN0 11z0 1ze0 11B0 WM0 1qO0 WI0 1nX0 1rB0 10L0 11B0 1in0 17d0 1in0 2pX0 19E0 1fU0 16Q0 1iI0 16Q0 1iI0 1Vd0 pb0 3Kp0 14o0 1df0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cL0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WO0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 Xc0 1qo0 WM0 1qM0 11A0 1o00 1200 1nA0 11A0 1tA0 U00 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|13e6","Asia/Jakarta|BMT JAVT WIB JST WIB WIB|-77.c -7k -7u -90 -80 -70|01232425|-1Q0Tk luM0 mPzO 8vWu 6kpu 4PXu xhcu|31e6","Asia/Jayapura|LMT WIT ACST|-9m.M -90 -9u|0121|-1uu9m.M sMMm.M L4nu|26e4","Asia/Jerusalem|JMT IST IDT IDDT|-2k.E -20 -30 -40|01212121212132121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-26Bek.E SyMk.E 5Rb0 10r0 1px0 10N0 1pz0 16p0 1jB0 16p0 1jx0 3LB0 Em0 or0 1cn0 1dB0 16n0 10O0 1ja0 1tC0 14o0 1cM0 1a00 11A0 1Na0 An0 1MP0 AJ0 1Kp0 LC0 1oo0 Wl0 EQN0 Db0 1fB0 Rb0 npB0 11z0 1C10 IL0 1s10 10n0 1o10 WL0 1zd0 On0 1ld0 11z0 1o10 14n0 1o10 14n0 1nd0 12n0 1nd0 Xz0 1q10 12n0 1hB0 1dX0 1ep0 1aL0 1eN0 17X0 1nf0 11z0 1tB0 19W0 1e10 17b0 1ep0 1gL0 18N0 1fz0 1eN0 17b0 1gq0 1gn0 19d0 1dz0 1c10 17X0 1hB0 1gn0 19d0 1dz0 1c10 17X0 1kp0 1dz0 1c10 1aL0 1eN0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0|81e4","Asia/Kabul|AFT AFT|-40 -4u|01|-10Qs0|46e5","Asia/Kamchatka|LMT PETT PETT PETST PETST|-ay.A -b0 -c0 -d0 -c0|01232323232323232323232412323232323232323232323232323232323232412|-1SLKy.A ivXy.A 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qN0 WM0|18e4","Asia/Karachi|LMT IST IST KART PKT PKST|-4s.c -5u -6u -50 -50 -60|012134545454|-2xoss.c 1qOKW.c 7zX0 eup0 LqMu 1fy00 1cL0 dK10 11b0 1610 1jX0|24e6","Asia/Urumqi|LMT XJT|-5O.k -60|01|-1GgtO.k|32e5","Asia/Kathmandu|LMT IST NPT|-5F.g -5u -5J|012|-21JhF.g 2EGMb.g|12e5","Asia/Khandyga|LMT YAKT YAKT YAKST YAKST VLAT VLAST VLAT YAKT|-92.d -80 -90 -a0 -90 -a0 -b0 -b0 -a0|01232323232323232323232412323232323232323232323232565656565656565782|-21Q92.d pAp2.d 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 qK0 yN0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 17V0 7zD0|66e2","Asia/Krasnoyarsk|LMT KRAT KRAT KRAST KRAST KRAT|-6b.q -60 -70 -80 -70 -80|012323232323232323232324123232323232323232323232323232323232323252|-21Hib.q prAb.q 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|10e5","Asia/Kuala_Lumpur|SMT MALT MALST MALT MALT JST MYT|-6T.p -70 -7k -7k -7u -90 -80|01234546|-2Bg6T.p 17anT.p 7hXE dM00 17bO 8Fyu 1so1u|71e5","Asia/Kuching|LMT BORT BORT BORTST JST MYT|-7l.k -7u -80 -8k -90 -80|01232323232323232425|-1KITl.k gDbP.k 6ynu AnE 1O0k AnE 1NAk AnE 1NAk AnE 1NAk AnE 1O0k AnE 1NAk AnE pAk 8Fz0 1so10|13e4","Asia/Macau|LMT MOT MOST CST|-7y.k -80 -90 -80|0121212121212121212121212121212121212121213|-2le7y.k 1XO34.k 1wn0 Rd0 1wn0 R9u 1wqu U10 1tz0 TVu 1tz0 17gu 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cJu 1cL0 1cN0 1fz0 1cN0 1cOu 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cJu 1cL0 1cN0 1fz0 1cN0 1cL0 KEp0|57e4","Asia/Magadan|LMT MAGT MAGT MAGST MAGST MAGT|-a3.c -a0 -b0 -c0 -b0 -c0|0123232323232323232323241232323232323232323232323232323232323232512|-1Pca3.c eUo3.c 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3Cq0|95e3","Asia/Makassar|LMT MMT WITA JST|-7V.A -7V.A -80 -90|01232|-21JjV.A vfc0 myLV.A 8ML0|15e5","Asia/Manila|PHT PHST JST|-80 -90 -90|010201010|-1kJI0 AL0 cK10 65X0 mXB0 vX0 VK10 1db0|24e6","Asia/Nicosia|LMT EET EEST|-2d.s -20 -30|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-1Vc2d.s 2a3cd.s 1cL0 1qp0 Xz0 19B0 19X0 1fB0 1db0 1cp0 1cL0 1fB0 19X0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1o30 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|32e4","Asia/Novokuznetsk|LMT +06 +07 +08|-5M.M -60 -70 -80|012323232323232323232321232323232323232323232323232323232323212|-1PctM.M eULM.M 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 2sp0 WM0|55e4","Asia/Novosibirsk|LMT +06 +07 +08|-5v.E -60 -70 -80|0123232323232323232323212323212121212121212121212121212121212121212|-21Qnv.E pAFv.E 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 ml0 Os0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 4eN0|15e5","Asia/Omsk|LMT OMST OMST OMSST OMSST OMST|-4R.u -50 -60 -70 -60 -70|012323232323232323232324123232323232323232323232323232323232323252|-224sR.u pMLR.u 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|12e5","Asia/Oral|LMT +04 +05 +06|-3p.o -40 -50 -60|01232323232323232121212121212121212121212121212|-1Pc3p.o eUnp.o 23CL0 3Db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1fA0 1cM0 1cM0 IM0 1EM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0|27e4","Asia/Pontianak|LMT PMT WIB JST WIB WITA WIB|-7h.k -7h.k -7u -90 -80 -80 -70|012324256|-2ua7h.k XE00 munL.k 8Rau 6kpu 4PXu xhcu Wqnu|23e4","Asia/Pyongyang|LMT KST JCST JST KST|-8n -8u -90 -90 -90|012341|-2um8n 97XR 12FXu jdA0 2Onc0|29e5","Asia/Qyzylorda|LMT +04 +05 +06|-4l.Q -40 -50 -60|0123232323232323232323232323232323232323232323|-1Pc4l.Q eUol.Q 23CL0 3Db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 3ao0 1EM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0|73e4","Asia/Rangoon|RMT BURT JST MMT|-6o.E -6u -90 -6u|0123|-21Jio.E SmnS.E 7j9u|48e5","Asia/Sakhalin|LMT JCST JST SAKT SAKST SAKST SAKT|-9u.M -90 -90 -b0 -c0 -b0 -a0|01234343434343434343434356343434343435656565656565656565656565656363|-2AGVu.M 1iaMu.M je00 1qFa0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o10 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3rd0|58e4","Asia/Samarkand|LMT SAMT SAMT SAMST TAST UZST UZT|-4r.R -40 -50 -60 -60 -60 -50|01234323232323232323232356|-1Pc4r.R eUor.R 23CL0 1db0 1cM0 1dc0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 11x0 bf0|36e4","Asia/Seoul|LMT KST JCST JST KST KDT KDT|-8r.Q -8u -90 -90 -90 -9u -a0|01234151515151515146464|-2um8r.Q 97XV.Q 12FXu jjA0 kKo0 2I0u OL0 1FB0 Rb0 1qN0 TX0 1tB0 TX0 1tB0 TX0 1tB0 TX0 2ap0 12FBu 11A0 1o00 11A0|23e6","Asia/Singapore|SMT MALT MALST MALT MALT JST SGT SGT|-6T.p -70 -7k -7k -7u -90 -7u -80|012345467|-2Bg6T.p 17anT.p 7hXE dM00 17bO 8Fyu Mspu DTA0|56e5","Asia/Srednekolymsk|LMT MAGT MAGT MAGST MAGST MAGT SRET|-ae.Q -a0 -b0 -c0 -b0 -c0 -b0|012323232323232323232324123232323232323232323232323232323232323256|-1Pcae.Q eUoe.Q 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|35e2","Asia/Taipei|JWST JST CST CDT|-80 -90 -80 -90|01232323232323232323232323232323232323232|-1iw80 joM0 1yo0 Tz0 1ip0 1jX0 1cN0 11b0 1oN0 11b0 1oN0 11b0 1oN0 11b0 10N0 1BX0 10p0 1pz0 10p0 1pz0 10p0 1db0 1dd0 1db0 1cN0 1db0 1cN0 1db0 1cN0 1db0 1BB0 ML0 1Bd0 ML0 uq10 1db0 1cN0 1db0 97B0 AL0|74e5","Asia/Tashkent|LMT TAST TAST TASST TASST UZST UZT|-4B.b -50 -60 -70 -60 -60 -50|01232323232323232323232456|-1Pc4B.b eUnB.b 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 11y0 bf0|23e5","Asia/Tbilisi|TBMT TBIT TBIT TBIST TBIST GEST GET GET GEST|-2X.b -30 -40 -50 -40 -40 -30 -40 -50|0123232323232323232323245656565787878787878787878567|-1Pc2X.b 1jUnX.b WCL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 3y0 19f0 1cK0 1cL0 1cN0 1cL0 1cN0 1cL0 1cM0 1cL0 1fB0 3Nz0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 An0 Os0 WM0|11e5","Asia/Tehran|LMT TMT IRST IRST IRDT IRDT|-3p.I -3p.I -3u -40 -50 -4u|01234325252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252|-2btDp.I 1d3c0 1huLT.I TXu 1pz0 sN0 vAu 1cL0 1dB0 1en0 pNB0 UL0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 64p0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0|14e6","Asia/Thimphu|LMT IST BTT|-5W.A -5u -60|012|-Su5W.A 1BGMs.A|79e3","Asia/Tokyo|JCST JST JDT|-90 -90 -a0|0121212121|-1iw90 pKq0 QL0 1lB0 13X0 1zB0 NX0 1zB0 NX0|38e6","Asia/Tomsk|LMT +06 +07 +08|-5D.P -60 -70 -80|0123232323232323232323212323232323232323232323212121212121212121212|-21NhD.P pxzD.P 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 co0 1bB0 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3Qp0|10e5","Asia/Ulaanbaatar|LMT ULAT ULAT ULAST|-77.w -70 -80 -90|012323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-2APH7.w 2Uko7.w cKn0 1db0 1dd0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 6hD0 11z0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 kEp0 1cJ0 1cP0 1cJ0 1cP0 1fx0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1fx0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1fx0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1fx0 1cP0 1cJ0 1cP0 1cJ0 1cP0 1cJ0|12e5","Asia/Ust-Nera|LMT YAKT YAKT MAGST MAGT MAGST MAGT MAGT VLAT VLAT|-9w.S -80 -90 -c0 -b0 -b0 -a0 -c0 -b0 -a0|0123434343434343434343456434343434343434343434343434343434343434789|-21Q9w.S pApw.S 23CL0 1d90 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 17V0 7zD0|65e2","Asia/Vladivostok|LMT VLAT VLAT VLAST VLAST VLAT|-8L.v -90 -a0 -b0 -a0 -b0|012323232323232323232324123232323232323232323232323232323232323252|-1SJIL.v itXL.v 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|60e4","Asia/Yakutsk|LMT YAKT YAKT YAKST YAKST YAKT|-8C.W -80 -90 -a0 -90 -a0|012323232323232323232324123232323232323232323232323232323232323252|-21Q8C.W pAoC.W 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|28e4","Asia/Yekaterinburg|LMT PMT SVET SVET SVEST SVEST YEKT YEKST YEKT|-42.x -3J.5 -40 -50 -60 -50 -50 -60 -60|0123434343434343434343435267676767676767676767676767676767676767686|-2ag42.x 7mQh.s qBvJ.5 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|14e5","Asia/Yerevan|LMT YERT YERT YERST YERST AMST AMT AMT AMST|-2W -30 -40 -50 -40 -40 -30 -40 -50|0123232323232323232323245656565657878787878787878787878787878787|-1Pc2W 1jUnW WCL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1am0 2r0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 3Fb0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|13e5","Atlantic/Azores|HMT AZOT AZOST AZOMT AZOT AZOST WET|1S.w 20 10 0 10 0 0|01212121212121212121212121212121212121212121232123212321232121212121212121212121212121212121212121454545454545454545454545454545456545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454|-2ldW5.s aPX5.s Sp0 LX0 1vc0 Tc0 1uM0 SM0 1vc0 Tc0 1vc0 SM0 1vc0 6600 1co0 3E00 17c0 1fA0 1a00 1io0 1a00 1io0 17c0 3I00 17c0 1cM0 1cM0 3Fc0 1cM0 1a00 1fA0 1io0 17c0 1cM0 1cM0 1a00 1fA0 1io0 1qM0 Dc0 1tA0 1cM0 1dc0 1400 gL0 IM0 s10 U00 dX0 Rc0 pd0 Rc0 gL0 Oo0 pd0 Rc0 gL0 Oo0 pd0 14o0 1cM0 1cP0 1cM0 1cM0 1cM0 1cM0 1cM0 3Co0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 qIl0 1cM0 1fA0 1cM0 1cM0 1cN0 1cL0 1cN0 1cM0 1cM0 1cM0 1cM0 1cN0 1cL0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cL0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|25e4","Atlantic/Bermuda|LMT AST ADT|4j.i 40 30|0121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-1BnRE.G 1LTbE.G 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0|65e3","Atlantic/Canary|LMT CANT WET WEST|11.A 10 0 -10|01232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-1UtaW.o XPAW.o 1lAK0 1a10 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|54e4","Atlantic/Cape_Verde|LMT CVT CVST CVT|1y.4 20 10 10|01213|-2xomp.U 1qOMp.U 7zX0 1djf0|50e4","Atlantic/Faroe|LMT WET WEST|r.4 0 -10|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2uSnw.U 2Wgow.U 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|49e3","Atlantic/Madeira|FMT MADT MADST MADMT WET WEST|17.A 10 0 -10 0 -10|01212121212121212121212121212121212121212121232123212321232121212121212121212121212121212121212121454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454|-2ldWQ.o aPWQ.o Sp0 LX0 1vc0 Tc0 1uM0 SM0 1vc0 Tc0 1vc0 SM0 1vc0 6600 1co0 3E00 17c0 1fA0 1a00 1io0 1a00 1io0 17c0 3I00 17c0 1cM0 1cM0 3Fc0 1cM0 1a00 1fA0 1io0 17c0 1cM0 1cM0 1a00 1fA0 1io0 1qM0 Dc0 1tA0 1cM0 1dc0 1400 gL0 IM0 s10 U00 dX0 Rc0 pd0 Rc0 gL0 Oo0 pd0 Rc0 gL0 Oo0 pd0 14o0 1cM0 1cP0 1cM0 1cM0 1cM0 1cM0 1cM0 3Co0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 qIl0 1cM0 1fA0 1cM0 1cM0 1cN0 1cL0 1cN0 1cM0 1cM0 1cM0 1cM0 1cN0 1cL0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|27e4","Atlantic/Reykjavik|LMT IST ISST GMT|1s 10 0 0|012121212121212121212121212121212121212121212121212121212121212121213|-2uWmw mfaw 1Bd0 ML0 1LB0 Cn0 1LB0 3fX0 C10 HrX0 1cO0 LB0 1EL0 LA0 1C00 Oo0 1wo0 Rc0 1wo0 Rc0 1wo0 Rc0 1zc0 Oo0 1zc0 14o0 1lc0 14o0 1lc0 14o0 1o00 11A0 1lc0 14o0 1o00 14o0 1lc0 14o0 1lc0 14o0 1lc0 14o0 1lc0 14o0 1o00 14o0 1lc0 14o0 1lc0 14o0 1lc0 14o0 1lc0 14o0 1lc0 14o0 1o00 14o0 1lc0 14o0 1lc0 14o0 1lc0 14o0 1lc0 14o0 1o00 14o0|12e4","Atlantic/South_Georgia|GST|20|0||30","Atlantic/Stanley|SMT FKT FKST FKT FKST|3P.o 40 30 30 20|0121212121212134343212121212121212121212121212121212121212121212121212|-2kJw8.A 12bA8.A 19X0 1fB0 19X0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1fB0 Cn0 1Cc10 WL0 1qL0 U10 1tz0 U10 1qM0 WN0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1tz0 U10 1tz0 WN0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1tz0 WN0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qL0 WN0 1qN0 U10 1wn0 Rd0 1wn0 U10 1tz0 U10 1tz0 U10 1tz0 U10 1tz0 U10 1wn0 U10 1tz0 U10 1tz0 U10|21e2","Australia/Sydney|AEST AEDT|-a0 -b0|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|-293lX xcX 10jd0 yL0 1cN0 1cL0 1fB0 19X0 17c10 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 14o0 1o00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 U00 1qM0 WM0 1tA0 WM0 1tA0 U00 1tA0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 11A0 1o00 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 14o0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0|40e5","Australia/Adelaide|ACST ACDT|-9u -au|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|-293lt xcX 10jd0 yL0 1cN0 1cL0 1fB0 19X0 17c10 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 U00 1qM0 WM0 1tA0 WM0 1tA0 U00 1tA0 U00 1tA0 Oo0 1zc0 WM0 1qM0 Rc0 1zc0 U00 1tA0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 14o0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0|11e5","Australia/Brisbane|AEST AEDT|-a0 -b0|01010101010101010|-293lX xcX 10jd0 yL0 1cN0 1cL0 1fB0 19X0 17c10 LA0 H1A0 Oo0 1zc0 Oo0 1zc0 Oo0|20e5","Australia/Broken_Hill|ACST ACDT|-9u -au|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|-293lt xcX 10jd0 yL0 1cN0 1cL0 1fB0 19X0 17c10 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 14o0 1o00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 U00 1qM0 WM0 1tA0 WM0 1tA0 U00 1tA0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 14o0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0|18e3","Australia/Currie|AEST AEDT|-a0 -b0|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|-29E80 19X0 10jd0 yL0 1cN0 1cL0 1fB0 19X0 17c10 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 11A0 1qM0 WM0 1qM0 Oo0 1zc0 Oo0 1zc0 Oo0 1wo0 WM0 1tA0 WM0 1tA0 U00 1tA0 U00 1tA0 11A0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 11A0 1o00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1cM0 1a00 1io0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0|746","Australia/Darwin|ACST ACDT|-9u -au|010101010|-293lt xcX 10jd0 yL0 1cN0 1cL0 1fB0 19X0|12e4","Australia/Eucla|ACWST ACWDT|-8J -9J|0101010101010101010|-293kI xcX 10jd0 yL0 1cN0 1cL0 1gSp0 Oo0 l5A0 Oo0 iJA0 G00 zU00 IM0 1qM0 11A0 1o00 11A0|368","Australia/Hobart|AEST AEDT|-a0 -b0|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|-29E80 19X0 10jd0 yL0 1cN0 1cL0 1fB0 19X0 VfB0 1cM0 1o00 Rc0 1wo0 Rc0 1wo0 U00 1wo0 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 11A0 1qM0 WM0 1qM0 Oo0 1zc0 Oo0 1zc0 Oo0 1wo0 WM0 1tA0 WM0 1tA0 U00 1tA0 U00 1tA0 11A0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 11A0 1o00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1cM0 1a00 1io0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0|21e4","Australia/Lord_Howe|AEST LHST LHDT LHDT|-a0 -au -bu -b0|0121212121313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313|raC0 1zdu Rb0 1zd0 On0 1zd0 On0 1zd0 On0 1zd0 TXu 1qMu WLu 1tAu WLu 1tAu TXu 1tAu Onu 1zcu Onu 1zcu Onu 1zcu Rbu 1zcu Onu 1zcu Onu 1zcu 11zu 1o0u 11zu 1o0u 11zu 1o0u 11zu 1qMu WLu 11Au 1nXu 1qMu 11zu 1o0u 11zu 1o0u 11zu 1qMu WLu 1qMu 11zu 1o0u WLu 1qMu 14nu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1fzu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu|347","Australia/Lindeman|AEST AEDT|-a0 -b0|010101010101010101010|-293lX xcX 10jd0 yL0 1cN0 1cL0 1fB0 19X0 17c10 LA0 H1A0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0|10","Australia/Melbourne|AEST AEDT|-a0 -b0|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101|-293lX xcX 10jd0 yL0 1cN0 1cL0 1fB0 19X0 17c10 LA0 1C00 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 U00 1qM0 WM0 1qM0 11A0 1tA0 U00 1tA0 U00 1tA0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 11A0 1o00 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 14o0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0|39e5","Australia/Perth|AWST AWDT|-80 -90|0101010101010101010|-293jX xcX 10jd0 yL0 1cN0 1cL0 1gSp0 Oo0 l5A0 Oo0 iJA0 G00 zU00 IM0 1qM0 11A0 1o00 11A0|18e5","CET|CET CEST|-10 -20|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-2aFe0 11d0 1iO0 11A0 1o00 11A0 Qrc0 6i00 WM0 1fA0 1cM0 1cM0 1cM0 16M0 1gMM0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00","CST6CDT|CST CDT CWT CPT|60 50 50 50|010102301010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-261s0 1nX0 11B0 1nX0 SgN0 8x30 iw0 QwN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0","Pacific/Easter|EMT EAST EASST EAST EASST|7h.s 70 60 60 50|0121212121212121212121212121234343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434|-1uSgG.w 1s4IG.w WL0 1zd0 On0 1ip0 11z0 1o10 11z0 1qN0 WL0 1ld0 14n0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 WL0 1qN0 1cL0 1cN0 11z0 1o10 11z0 1qN0 WL0 1fB0 19X0 1qN0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1ip0 1fz0 1fB0 11z0 1qN0 WL0 1qN0 WL0 1qN0 WL0 1qN0 11z0 1o10 11z0 1o10 11z0 1qN0 WL0 1qN0 17b0 1ip0 11z0 1o10 19X0 1fB0 1nX0 G10 1EL0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Dd0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Dd0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Dd0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1Nb0 Ap0|30e2","EET|EET EEST|-20 -30|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|hDB0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00","EST|EST|50|0|","EST5EDT|EST EDT EWT EPT|50 40 40 40|010102301010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-261t0 1nX0 11B0 1nX0 SgN0 8x40 iv0 QwN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0","Europe/Dublin|DMT IST GMT BST IST|p.l -y.D 0 -10 -10|01232323232324242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242|-2ax9y.D Rc0 1fzy.D 14M0 1fc0 1g00 1co0 1dc0 1co0 1oo0 1400 1dc0 19A0 1io0 1io0 WM0 1o00 14o0 1o00 17c0 1io0 17c0 1fA0 1a00 1lc0 17c0 1io0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1cM0 1io0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1a00 1io0 1qM0 Dc0 g5X0 14p0 1wn0 17d0 1io0 11A0 1o00 17c0 1fA0 1a00 1fA0 1cM0 1fA0 1a00 17c0 1fA0 1a00 1io0 17c0 1lc0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1a00 1a00 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1tA0 IM0 90o0 U00 1tA0 U00 1tA0 U00 1tA0 U00 1tA0 WM0 1qM0 WM0 1qM0 WM0 1tA0 U00 1tA0 U00 1tA0 11z0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 14o0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|12e5","Etc/GMT+0|GMT|0|0|","Etc/GMT+1|GMT+1|10|0|","Etc/GMT+10|GMT+10|a0|0|","Etc/GMT+11|GMT+11|b0|0|","Etc/GMT+12|GMT+12|c0|0|","Etc/GMT+2|GMT+2|20|0|","Etc/GMT+3|GMT+3|30|0|","Etc/GMT+4|GMT+4|40|0|","Etc/GMT+5|GMT+5|50|0|","Etc/GMT+6|GMT+6|60|0|","Etc/GMT+7|GMT+7|70|0|","Etc/GMT+8|GMT+8|80|0|","Etc/GMT+9|GMT+9|90|0|","Etc/GMT-1|GMT-1|-10|0|","Etc/GMT-10|GMT-10|-a0|0|","Etc/GMT-11|GMT-11|-b0|0|","Etc/GMT-12|GMT-12|-c0|0|","Etc/GMT-13|GMT-13|-d0|0|","Etc/GMT-14|GMT-14|-e0|0|","Etc/GMT-2|GMT-2|-20|0|","Etc/GMT-3|GMT-3|-30|0|","Etc/GMT-4|GMT-4|-40|0|","Etc/GMT-5|GMT-5|-50|0|","Etc/GMT-6|GMT-6|-60|0|","Etc/GMT-7|GMT-7|-70|0|","Etc/GMT-8|GMT-8|-80|0|","Etc/GMT-9|GMT-9|-90|0|","Etc/UCT|UCT|0|0|","Etc/UTC|UTC|0|0|","Europe/Amsterdam|AMT NST NEST NET CEST CET|-j.w -1j.w -1k -k -20 -10|010101010101010101010101010101010101010101012323234545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545|-2aFcj.w 11b0 1iP0 11A0 1io0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1co0 1io0 1yo0 Pc0 1a00 1fA0 1Bc0 Mo0 1tc0 Uo0 1tA0 U00 1uo0 W00 1s00 VA0 1so0 Vc0 1sM0 UM0 1wo0 Rc0 1u00 Wo0 1rA0 W00 1s00 VA0 1sM0 UM0 1w00 fV0 BCX.w 1tA0 U00 1u00 Wo0 1sm0 601k WM0 1fA0 1cM0 1cM0 1cM0 16M0 1gMM0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|16e5","Europe/Andorra|WET CET CEST|0 -10 -20|012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-UBA0 1xIN0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|79e3","Europe/Astrakhan|LMT +03 +04 +05|-3c.c -30 -40 -50|012323232323232323212121212121212121212121212121212121212121212|-1Pcrc.c eUMc.c 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1fA0 1cM0 3Co0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3rd0","Europe/Athens|AMT EET EEST CEST CET|-1y.Q -20 -30 -20 -10|012123434121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2a61x.Q CNbx.Q mn0 kU10 9b0 3Es0 Xa0 1fb0 1dd0 k3X0 Nz0 SCp0 1vc0 SO0 1cM0 1a00 1ao0 1fc0 1a10 1fG0 1cg0 1dX0 1bX0 1cQ0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|35e5","Europe/London|GMT BST BDST|0 -10 -20|0101010101010101010101010101010101010101010101010121212121210101210101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-2axa0 Rc0 1fA0 14M0 1fc0 1g00 1co0 1dc0 1co0 1oo0 1400 1dc0 19A0 1io0 1io0 WM0 1o00 14o0 1o00 17c0 1io0 17c0 1fA0 1a00 1lc0 17c0 1io0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1cM0 1io0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1a00 1io0 1qM0 Dc0 2Rz0 Dc0 1zc0 Oo0 1zc0 Rc0 1wo0 17c0 1iM0 FA0 xB0 1fA0 1a00 14o0 bb0 LA0 xB0 Rc0 1wo0 11A0 1o00 17c0 1fA0 1a00 1fA0 1cM0 1fA0 1a00 17c0 1fA0 1a00 1io0 17c0 1lc0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1a00 1a00 1qM0 WM0 1qM0 11A0 1o00 WM0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1tA0 IM0 90o0 U00 1tA0 U00 1tA0 U00 1tA0 U00 1tA0 WM0 1qM0 WM0 1qM0 WM0 1tA0 U00 1tA0 U00 1tA0 11z0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 14o0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|10e6","Europe/Belgrade|CET CEST|-10 -20|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-19RC0 3IP0 WM0 1fA0 1cM0 1cM0 1rc0 Qo0 1vmo0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|12e5","Europe/Berlin|CET CEST CEMT|-10 -20 -30|01010101010101210101210101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-2aFe0 11d0 1iO0 11A0 1o00 11A0 Qrc0 6i00 WM0 1fA0 1cM0 1cM0 1cM0 kL0 Nc0 m10 WM0 1ao0 1cp0 dX0 jz0 Dd0 1io0 17c0 1fA0 1a00 1ehA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|41e5","Europe/Prague|CET CEST|-10 -20|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-2aFe0 11d0 1iO0 11A0 1o00 11A0 Qrc0 6i00 WM0 1fA0 1cM0 16M0 1lc0 1tA0 17A0 11c0 1io0 17c0 1io0 17c0 1fc0 1ao0 1bNc0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|13e5","Europe/Brussels|WET CET CEST WEST|0 -10 -20 -10|0121212103030303030303030303030303030303030303030303212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2ehc0 3zX0 11c0 1iO0 11A0 1o00 11A0 my0 Ic0 1qM0 Rc0 1EM0 UM0 1u00 10o0 1io0 1io0 17c0 1a00 1fA0 1cM0 1cM0 1io0 17c0 1fA0 1a00 1io0 1a30 1io0 17c0 1fA0 1a00 1io0 17c0 1cM0 1cM0 1a00 1io0 1cM0 1cM0 1a00 1fA0 1io0 17c0 1cM0 1cM0 1a00 1fA0 1io0 1qM0 Dc0 y00 5Wn0 WM0 1fA0 1cM0 16M0 1iM0 16M0 1C00 Uo0 1eeo0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|21e5","Europe/Bucharest|BMT EET EEST|-1I.o -20 -30|0121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-1xApI.o 20LI.o RA0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1Axc0 On0 1fA0 1a10 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cK0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cL0 1cN0 1cL0 1fB0 1nX0 11E0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|19e5","Europe/Budapest|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-2aFe0 11d0 1iO0 11A0 1ip0 17b0 1op0 1tb0 Q2m0 3Ne0 WM0 1fA0 1cM0 1cM0 1oJ0 1dc0 1030 1fA0 1cM0 1cM0 1cM0 1cM0 1fA0 1a00 1iM0 1fA0 8Ha0 Rb0 1wN0 Rb0 1BB0 Lz0 1C20 LB0 SNX0 1a10 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|17e5","Europe/Zurich|CET CEST|-10 -20|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-19Lc0 11A0 1o00 11A0 1xG10 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|38e4","Europe/Chisinau|CMT BMT EET EEST CEST CET MSK MSD|-1T -1I.o -20 -30 -20 -10 -30 -40|012323232323232323234545467676767676767676767323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232|-26jdT wGMa.A 20LI.o RA0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 27A0 2en0 39g0 WM0 1fA0 1cM0 V90 1t7z0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 gL0 WO0 1cM0 1cM0 1cK0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1nX0 11D0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|67e4","Europe/Copenhagen|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-2azC0 Tz0 VuO0 60q0 WM0 1fA0 1cM0 1cM0 1cM0 S00 1HA0 Nc0 1C00 Dc0 1Nc0 Ao0 1h5A0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|12e5","Europe/Gibraltar|GMT BST BDST CET CEST|0 -10 -20 -10 -20|010101010101010101010101010101010101010101010101012121212121010121010101010101010101034343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343|-2axa0 Rc0 1fA0 14M0 1fc0 1g00 1co0 1dc0 1co0 1oo0 1400 1dc0 19A0 1io0 1io0 WM0 1o00 14o0 1o00 17c0 1io0 17c0 1fA0 1a00 1lc0 17c0 1io0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1cM0 1io0 17c0 1fA0 1a00 1io0 17c0 1io0 17c0 1fA0 1a00 1io0 1qM0 Dc0 2Rz0 Dc0 1zc0 Oo0 1zc0 Rc0 1wo0 17c0 1iM0 FA0 xB0 1fA0 1a00 14o0 bb0 LA0 xB0 Rc0 1wo0 11A0 1o00 17c0 1fA0 1a00 1fA0 1cM0 1fA0 1a00 17c0 1fA0 1a00 1io0 17c0 1lc0 17c0 1fA0 10Jz0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|30e3","Europe/Helsinki|HMT EET EEST|-1D.N -20 -30|0121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-1WuND.N OULD.N 1dA0 1xGq0 1cM0 1cM0 1cM0 1cN0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|12e5","Europe/Kaliningrad|CET CEST CET CEST MSK MSD EEST EET FET|-10 -20 -20 -30 -30 -40 -30 -20 -30|0101010101010232454545454545454546767676767676767676767676767676767676767676787|-2aFe0 11d0 1iO0 11A0 1o00 11A0 Qrc0 6i00 WM0 1fA0 1cM0 1cM0 Am0 Lb0 1en0 op0 1pNz0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|44e4","Europe/Kiev|KMT EET MSK CEST CET MSD EEST|-22.4 -20 -30 -20 -10 -40 -30|0123434252525252525252525256161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161|-1Pc22.4 eUo2.4 rnz0 2Hg0 WM0 1fA0 da0 1v4m0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 Db0 3220 1cK0 1cL0 1cN0 1cL0 1cN0 1cL0 1cQ0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|34e5","Europe/Kirov|LMT +03 +04 +05|-3i.M -30 -40 -50|01232323232323232321212121212121212121212121212121212121212121|-22WNi.M qHai.M 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1fA0 1cM0 3Co0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|48e4","Europe/Lisbon|LMT WET WEST WEMT CET CEST|A.J 0 -10 -20 -10 -20|012121212121212121212121212121212121212121212321232123212321212121212121212121212121212121212121214121212121212121212121212121212124545454212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2ldXn.f aPWn.f Sp0 LX0 1vc0 Tc0 1uM0 SM0 1vc0 Tc0 1vc0 SM0 1vc0 6600 1co0 3E00 17c0 1fA0 1a00 1io0 1a00 1io0 17c0 3I00 17c0 1cM0 1cM0 3Fc0 1cM0 1a00 1fA0 1io0 17c0 1cM0 1cM0 1a00 1fA0 1io0 1qM0 Dc0 1tA0 1cM0 1dc0 1400 gL0 IM0 s10 U00 dX0 Rc0 pd0 Rc0 gL0 Oo0 pd0 Rc0 gL0 Oo0 pd0 14o0 1cM0 1cP0 1cM0 1cM0 1cM0 1cM0 1cM0 3Co0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 pvy0 1cM0 1cM0 1fA0 1cM0 1cM0 1cN0 1cL0 1cN0 1cM0 1cM0 1cM0 1cM0 1cN0 1cL0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|27e5","Europe/Luxembourg|LMT CET CEST WET WEST WEST WET|-o.A -10 -20 0 -10 -20 -10|0121212134343434343434343434343434343434343434343434565651212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2DG0o.A t6mo.A TB0 1nX0 Up0 1o20 11A0 rW0 CM0 1qP0 R90 1EO0 UK0 1u20 10m0 1ip0 1in0 17e0 19W0 1fB0 1db0 1cp0 1in0 17d0 1fz0 1a10 1in0 1a10 1in0 17f0 1fA0 1a00 1io0 17c0 1cM0 1cM0 1a00 1io0 1cM0 1cM0 1a00 1fA0 1io0 17c0 1cM0 1cM0 1a00 1fA0 1io0 1qM0 Dc0 vA0 60L0 WM0 1fA0 1cM0 17c0 1io0 16M0 1C00 Uo0 1eeo0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|54e4","Europe/Madrid|WET WEST WEMT CET CEST|0 -10 -20 -10 -20|01010101010101010101010121212121234343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343|-28dd0 11A0 1go0 19A0 1co0 1dA0 b1A0 18o0 3I00 17c0 1fA0 1a00 1io0 1a00 1io0 17c0 iyo0 Rc0 18o0 1hc0 1io0 1a00 14o0 5aL0 MM0 1vc0 17A0 1i00 1bc0 1eo0 17d0 1in0 17A0 6hA0 10N0 XIL0 1a10 1in0 17d0 19X0 1cN0 1fz0 1a10 1fX0 1cp0 1cO0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|62e5","Europe/Malta|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-2as10 M00 1cM0 1cM0 14o0 1o00 WM0 1qM0 17c0 1cM0 M3A0 5M20 WM0 1fA0 1cM0 1cM0 1cM0 16m0 1de0 1lc0 14m0 1lc0 WO0 1qM0 GTW0 On0 1C10 Lz0 1C10 Lz0 1EN0 Lz0 1C10 Lz0 1zd0 Oo0 1C00 On0 1cp0 1cM0 1lA0 Xc0 1qq0 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1o10 11z0 1iN0 19z0 1fB0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|42e4","Europe/Minsk|MMT EET MSK CEST CET MSD EEST FET|-1O -20 -30 -20 -10 -40 -30 -30|012343432525252525252525252616161616161616161616161616161616161616172|-1Pc1O eUnO qNX0 3gQ0 WM0 1fA0 1cM0 Al0 1tsn0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 3Fc0 1cN0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hy0|19e5","Europe/Monaco|PMT WET WEST WEMT CET CEST|-9.l 0 -10 -20 -10 -20|01212121212121212121212121212121212121212121212121232323232345454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454|-2nco9.l cNb9.l HA0 19A0 1iM0 11c0 1oo0 Wo0 1rc0 QM0 1EM0 UM0 1u00 10o0 1io0 1wo0 Rc0 1a00 1fA0 1cM0 1cM0 1io0 17c0 1fA0 1a00 1io0 1a00 1io0 17c0 1fA0 1a00 1io0 17c0 1cM0 1cM0 1a00 1io0 1cM0 1cM0 1a00 1fA0 1io0 17c0 1cM0 1cM0 1a00 1fA0 1io0 1qM0 Df0 2RV0 11z0 11B0 1ze0 WM0 1fA0 1cM0 1fa0 1aq0 16M0 1ekn0 1cL0 1fC0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|38e3","Europe/Moscow|MMT MMT MST MDST MSD MSK MSM EET EEST MSK|-2u.h -2v.j -3v.j -4v.j -40 -30 -50 -20 -30 -40|012132345464575454545454545454545458754545454545454545454545454545454545454595|-2ag2u.h 2pyW.W 1bA0 11X0 GN0 1Hb0 c20 imv.j 3DA0 dz0 15A0 c10 2q10 iM10 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|16e6","Europe/Paris|PMT WET WEST CEST CET WEMT|-9.l 0 -10 -20 -10 -20|0121212121212121212121212121212121212121212121212123434352543434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434|-2nco8.l cNb8.l HA0 19A0 1iM0 11c0 1oo0 Wo0 1rc0 QM0 1EM0 UM0 1u00 10o0 1io0 1wo0 Rc0 1a00 1fA0 1cM0 1cM0 1io0 17c0 1fA0 1a00 1io0 1a00 1io0 17c0 1fA0 1a00 1io0 17c0 1cM0 1cM0 1a00 1io0 1cM0 1cM0 1a00 1fA0 1io0 17c0 1cM0 1cM0 1a00 1fA0 1io0 1qM0 Df0 Ik0 5M30 WM0 1fA0 1cM0 Vx0 hB0 1aq0 16M0 1ekn0 1cL0 1fC0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|11e6","Europe/Riga|RMT LST EET MSK CEST CET MSD EEST|-1A.y -2A.y -20 -30 -20 -10 -40 -30|010102345454536363636363636363727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272|-25TzA.y 11A0 1iM0 ko0 gWm0 yDXA.y 2bX0 3fE0 WM0 1fA0 1cM0 1cM0 4m0 1sLy0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cN0 1o00 11A0 1o00 11A0 1qM0 3oo0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|64e4","Europe/Rome|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-2as10 M00 1cM0 1cM0 14o0 1o00 WM0 1qM0 17c0 1cM0 M3A0 5M20 WM0 1fA0 1cM0 16K0 1iO0 16m0 1de0 1lc0 14m0 1lc0 WO0 1qM0 GTW0 On0 1C10 Lz0 1C10 Lz0 1EN0 Lz0 1C10 Lz0 1zd0 Oo0 1C00 On0 1C10 Lz0 1zd0 On0 1C10 LA0 1C00 LA0 1zc0 Oo0 1C00 Oo0 1zc0 Oo0 1fC0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|39e5","Europe/Samara|LMT SAMT SAMT KUYT KUYST MSD MSK EEST SAMST SAMST|-3k.k -30 -40 -40 -50 -40 -30 -30 -50 -40|012343434343434343435656712828282828282828282828282828282828282912|-22WNk.k qHak.k bcn0 1Qqo0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1cM0 1cN0 8o0 14m0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qN0 WM0|12e5","Europe/Simferopol|SMT EET MSK CEST CET MSD EEST MSK|-2g -20 -30 -20 -10 -40 -30 -40|012343432525252525252525252161616525252616161616161616161616161616161616172|-1Pc2g eUog rEn0 2qs0 WM0 1fA0 1cM0 3V0 1u0L0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1Q00 4eL0 1cL0 1cN0 1cL0 1cN0 dX0 WL0 1cN0 1cL0 1fB0 1o30 11B0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11z0 1nW0|33e4","Europe/Sofia|EET CET CEST EEST|-20 -10 -20 -30|01212103030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030|-168L0 WM0 1fA0 1cM0 1cM0 1cN0 1mKH0 1dd0 1fb0 1ap0 1fb0 1a20 1fy0 1a30 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cK0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 1nX0 11E0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|12e5","Europe/Stockholm|CET CEST|-10 -20|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-2azC0 TB0 2yDe0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|15e5","Europe/Tallinn|TMT CET CEST EET MSK MSD EEST|-1D -10 -20 -20 -30 -40 -30|012103421212454545454545454546363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363|-26oND teD 11A0 1Ta0 4rXl KSLD 2FX0 2Jg0 WM0 1fA0 1cM0 18J0 1sTX0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o10 11A0 1qM0 5QM0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|41e4","Europe/Tirane|LMT CET CEST|-1j.k -10 -20|01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2glBj.k 14pcj.k 5LC0 WM0 4M0 1fCK0 10n0 1op0 11z0 1pd0 11z0 1qN0 WL0 1qp0 Xb0 1qp0 Xb0 1qp0 11z0 1lB0 11z0 1qN0 11z0 1iN0 16n0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|42e4","Europe/Ulyanovsk|LMT +03 +04 +05 +02|-3d.A -30 -40 -50 -20|01232323232323232321214121212121212121212121212121212121212121212|-22WNd.A qHad.A 23CL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 2pB0 1cM0 1fA0 2pB0 IM0 rX0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0 3rd0","Europe/Uzhgorod|CET CEST MSK MSD EET EEST|-10 -20 -30 -40 -20 -30|010101023232323232323232320454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454|-1cqL0 6i00 WM0 1fA0 1cM0 1ml0 1Cp0 1r3W0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1Q00 1Nf0 2pw0 1cL0 1cN0 1cL0 1cN0 1cL0 1cQ0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|11e4","Europe/Vienna|CET CEST|-10 -20|0101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-2aFe0 11d0 1iO0 11A0 1o00 11A0 3KM0 14o0 LA00 6i00 WM0 1fA0 1cM0 1cM0 1cM0 400 2qM0 1a00 1cM0 1cM0 1io0 17c0 1gHa0 19X0 1cP0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|18e5","Europe/Vilnius|WMT KMT CET EET MSK CEST MSD EEST|-1o -1z.A -10 -20 -30 -20 -40 -30|012324525254646464646464646473737373737373737352537373737373737373737373737373737373737373737373737373737373737373737373|-293do 6ILM.o 1Ooz.A zz0 Mfd0 29W0 3is0 WM0 1fA0 1cM0 LV0 1tgL0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11B0 1o00 11A0 1qM0 8io0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|54e4","Europe/Volgograd|LMT TSAT STAT STAT VOLT VOLST VOLST VOLT MSD MSK MSK|-2V.E -30 -30 -40 -40 -50 -40 -30 -40 -30 -40|0123454545454545454676767489898989898989898989898989898989898989a9|-21IqV.E cLXV.E cEM0 1gqn0 Lco0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1cM0 1cM0 1fA0 1cM0 2pz0 1cN0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 8Hz0|10e5","Europe/Warsaw|WMT CET CEST EET EEST|-1o -10 -20 -20 -30|012121234312121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121|-2ctdo 1LXo 11d0 1iO0 11A0 1o00 11A0 1on0 11A0 6zy0 HWP0 5IM0 WM0 1fA0 1cM0 1dz0 1mL0 1en0 15B0 1aq0 1nA0 11A0 1io0 17c0 1fA0 1a00 iDX0 LA0 1cM0 1cM0 1C00 Oo0 1cM0 1cM0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1C00 LA0 uso0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cN0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|17e5","Europe/Zaporozhye|CUT EET MSK CEST CET MSD EEST|-2k -20 -30 -20 -10 -40 -30|01234342525252525252525252526161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161|-1Pc2k eUok rdb0 2RE0 WM0 1fA0 8m0 1v9a0 1db0 1cN0 1db0 1cN0 1db0 1dd0 1cO0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cK0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cQ0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|77e4","HST|HST|a0|0|","Indian/Chagos|LMT IOT IOT|-4N.E -50 -60|012|-2xosN.E 3AGLN.E|30e2","Indian/Christmas|CXT|-70|0||21e2","Indian/Cocos|CCT|-6u|0||596","Indian/Kerguelen|-00 TFT|0 -50|01|-MG00|130","Indian/Mahe|LMT SCT|-3F.M -40|01|-2yO3F.M|79e3","Indian/Maldives|MMT MVT|-4S -50|01|-olgS|35e4","Indian/Mauritius|LMT MUT MUST|-3O -40 -50|012121|-2xorO 34unO 14L0 12kr0 11z0|15e4","Indian/Reunion|LMT RET|-3F.Q -40|01|-2mDDF.Q|84e4","Pacific/Kwajalein|MHT KWAT MHT|-b0 c0 -c0|012|-AX0 W9X0|14e3","MET|MET MEST|-10 -20|01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-2aFe0 11d0 1iO0 11A0 1o00 11A0 Qrc0 6i00 WM0 1fA0 1cM0 1cM0 1cM0 16M0 1gMM0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00","MST|MST|70|0|","MST7MDT|MST MDT MWT MPT|70 60 60 60|010102301010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-261r0 1nX0 11B0 1nX0 SgN0 8x20 ix0 QwN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0","Pacific/Chatham|CHAST CHAST CHADT|-cf -cJ -dJ|012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212|-WqAf 1adef IM0 1C00 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1qM0 14o0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1io0 17c0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1lc0 14o0 1lc0 14o0 1lc0 17c0 1io0 17c0 1io0 17c0 1io0 17c0 1io0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00|600","PST8PDT|PST PDT PWT PPT|80 70 70 70|010102301010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-261q0 1nX0 11B0 1nX0 SgN0 8x10 iy0 QwN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1cN0 1cL0 1cN0 1cL0 s10 1Vz0 LB0 1BX0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1fz0 1a10 1fz0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0","Pacific/Apia|LMT WSST SST SDT WSDT WSST|bq.U bu b0 a0 -e0 -d0|01232345454545454545454545454545454545454545454545454545454|-2nDMx.4 1yW03.4 2rRbu 1ff0 1a00 CI0 AQ0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1io0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00|37e3","Pacific/Bougainville|PGT JST BST|-a0 -90 -b0|0102|-16Wy0 7CN0 2MQp0|18e4","Pacific/Chuuk|CHUT|-a0|0||49e3","Pacific/Efate|LMT VUT VUST|-bd.g -b0 -c0|0121212121212121212121|-2l9nd.g 2Szcd.g 1cL0 1oN0 10L0 1fB0 19X0 1fB0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1cN0 1cL0 1fB0 Lz0 1Nd0 An0|66e3","Pacific/Enderbury|PHOT PHOT PHOT|c0 b0 -d0|012|nIc0 B8n0|1","Pacific/Fakaofo|TKT TKT|b0 -d0|01|1Gfn0|483","Pacific/Fiji|LMT FJT FJST|-bT.I -c0 -d0|0121212121212121212121212121212121212121212121212121212121212121|-2bUzT.I 3m8NT.I LA0 1EM0 IM0 nJc0 LA0 1o00 Rc0 1wo0 Ao0 1Nc0 Ao0 1Q00 xz0 1SN0 uM0 1SM0 uM0 1VA0 s00 1VA0 uM0 1SM0 uM0 1SM0 uM0 1SM0 uM0 1VA0 s00 1VA0 s00 1VA0 uM0 1SM0 uM0 1SM0 uM0 1SM0 uM0 1VA0 s00 1VA0 uM0 1SM0 uM0 1SM0 uM0 1SM0 uM0 1VA0 s00 1VA0 s00 1VA0 uM0 1SM0 uM0 1SM0 uM0 1SM0 uM0|88e4","Pacific/Funafuti|TVT|-c0|0||45e2","Pacific/Galapagos|LMT ECT GALT|5W.o 50 60|012|-1yVS1.A 2dTz1.A|25e3","Pacific/Gambier|LMT GAMT|8X.M 90|01|-2jof0.c|125","Pacific/Guadalcanal|LMT SBT|-aD.M -b0|01|-2joyD.M|11e4","Pacific/Guam|GST ChST|-a0 -a0|01|1fpq0|17e4","Pacific/Honolulu|HST HDT HST|au 9u a0|010102|-1thLu 8x0 lef0 8Pz0 46p0|37e4","Pacific/Kiritimati|LINT LINT LINT|aE a0 -e0|012|nIaE B8nk|51e2","Pacific/Kosrae|KOST KOST|-b0 -c0|010|-AX0 1bdz0|66e2","Pacific/Majuro|MHT MHT|-b0 -c0|01|-AX0|28e3","Pacific/Marquesas|LMT MART|9i 9u|01|-2joeG|86e2","Pacific/Pago_Pago|LMT NST BST SST|bm.M b0 b0 b0|0123|-2nDMB.c 2gVzB.c EyM0|37e2","Pacific/Nauru|LMT NRT JST NRT|-b7.E -bu -90 -c0|01213|-1Xdn7.E PvzB.E 5RCu 1ouJu|10e3","Pacific/Niue|NUT NUT NUT|bk bu b0|012|-KfME 17y0a|12e2","Pacific/Norfolk|NMT NFT NFST NFT|-bc -bu -cu -b0|01213|-Kgbc W01G On0 1COp0|25e4","Pacific/Noumea|LMT NCT NCST|-b5.M -b0 -c0|01212121|-2l9n5.M 2EqM5.M xX0 1PB0 yn0 HeP0 Ao0|98e3","Pacific/Palau|PWT|-90|0||21e3","Pacific/Pitcairn|PNT PST|8u 80|01|18Vku|56","Pacific/Pohnpei|PONT|-b0|0||34e3","Pacific/Port_Moresby|PGT|-a0|0||25e4","Pacific/Rarotonga|CKT CKHST CKT|au 9u a0|012121212121212121212121212|lyWu IL0 1zcu Onu 1zcu Onu 1zcu Rbu 1zcu Onu 1zcu Onu 1zcu Onu 1zcu Onu 1zcu Onu 1zcu Rbu 1zcu Onu 1zcu Onu 1zcu Onu|13e3","Pacific/Tahiti|LMT TAHT|9W.g a0|01|-2joe1.I|18e4","Pacific/Tarawa|GILT|-c0|0||29e3","Pacific/Tongatapu|TOT TOT TOST|-ck -d0 -e0|01212121|-1aB0k 2n5dk 15A0 1wo0 xz0 1Q10 xz0|75e3","Pacific/Wake|WAKT|-c0|0||16e3","Pacific/Wallis|WFT|-c0|0||94","WET|WET WEST|0 -10|010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|hDB0 1a00 1fA0 1cM0 1cM0 1cM0 1fA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00"],
+    links:["Africa/Abidjan|Africa/Bamako","Africa/Abidjan|Africa/Banjul","Africa/Abidjan|Africa/Conakry","Africa/Abidjan|Africa/Dakar","Africa/Abidjan|Africa/Freetown","Africa/Abidjan|Africa/Lome","Africa/Abidjan|Africa/Nouakchott","Africa/Abidjan|Africa/Ouagadougou","Africa/Abidjan|Africa/Sao_Tome","Africa/Abidjan|Africa/Timbuktu","Africa/Abidjan|Atlantic/St_Helena","Africa/Cairo|Egypt","Africa/Johannesburg|Africa/Maseru","Africa/Johannesburg|Africa/Mbabane","Africa/Khartoum|Africa/Juba","Africa/Lagos|Africa/Bangui","Africa/Lagos|Africa/Brazzaville","Africa/Lagos|Africa/Douala","Africa/Lagos|Africa/Kinshasa","Africa/Lagos|Africa/Libreville","Africa/Lagos|Africa/Luanda","Africa/Lagos|Africa/Malabo","Africa/Lagos|Africa/Niamey","Africa/Lagos|Africa/Porto-Novo","Africa/Maputo|Africa/Blantyre","Africa/Maputo|Africa/Bujumbura","Africa/Maputo|Africa/Gaborone","Africa/Maputo|Africa/Harare","Africa/Maputo|Africa/Kigali","Africa/Maputo|Africa/Lubumbashi","Africa/Maputo|Africa/Lusaka","Africa/Nairobi|Africa/Addis_Ababa","Africa/Nairobi|Africa/Asmara","Africa/Nairobi|Africa/Asmera","Africa/Nairobi|Africa/Dar_es_Salaam","Africa/Nairobi|Africa/Djibouti","Africa/Nairobi|Africa/Kampala","Africa/Nairobi|Africa/Mogadishu","Africa/Nairobi|Indian/Antananarivo","Africa/Nairobi|Indian/Comoro","Africa/Nairobi|Indian/Mayotte","Africa/Tripoli|Libya","America/Adak|America/Atka","America/Adak|US/Aleutian","America/Anchorage|US/Alaska","America/Argentina/Buenos_Aires|America/Buenos_Aires","America/Argentina/Catamarca|America/Argentina/ComodRivadavia","America/Argentina/Catamarca|America/Catamarca","America/Argentina/Cordoba|America/Cordoba","America/Argentina/Cordoba|America/Rosario","America/Argentina/Jujuy|America/Jujuy","America/Argentina/Mendoza|America/Mendoza","America/Atikokan|America/Coral_Harbour","America/Chicago|US/Central","America/Curacao|America/Aruba","America/Curacao|America/Kralendijk","America/Curacao|America/Lower_Princes","America/Denver|America/Shiprock","America/Denver|Navajo","America/Denver|US/Mountain","America/Detroit|US/Michigan","America/Edmonton|Canada/Mountain","America/Fort_Wayne|America/Indiana/Indianapolis","America/Fort_Wayne|America/Indianapolis","America/Fort_Wayne|US/East-Indiana","America/Halifax|Canada/Atlantic","America/Havana|Cuba","America/Indiana/Knox|America/Knox_IN","America/Indiana/Knox|US/Indiana-Starke","America/Jamaica|Jamaica","America/Kentucky/Louisville|America/Louisville","America/Los_Angeles|US/Pacific","America/Los_Angeles|US/Pacific-New","America/Manaus|Brazil/West","America/Mazatlan|Mexico/BajaSur","America/Mexico_City|Mexico/General","America/New_York|US/Eastern","America/Noronha|Brazil/DeNoronha","America/Panama|America/Cayman","America/Phoenix|US/Arizona","America/Port_of_Spain|America/Anguilla","America/Port_of_Spain|America/Antigua","America/Port_of_Spain|America/Dominica","America/Port_of_Spain|America/Grenada","America/Port_of_Spain|America/Guadeloupe","America/Port_of_Spain|America/Marigot","America/Port_of_Spain|America/Montserrat","America/Port_of_Spain|America/St_Barthelemy","America/Port_of_Spain|America/St_Kitts","America/Port_of_Spain|America/St_Lucia","America/Port_of_Spain|America/St_Thomas","America/Port_of_Spain|America/St_Vincent","America/Port_of_Spain|America/Tortola","America/Port_of_Spain|America/Virgin","America/Regina|Canada/East-Saskatchewan","America/Regina|Canada/Saskatchewan","America/Rio_Branco|America/Porto_Acre","America/Rio_Branco|Brazil/Acre","America/Santiago|Chile/Continental","America/Sao_Paulo|Brazil/East","America/St_Johns|Canada/Newfoundland","America/Tijuana|America/Ensenada","America/Tijuana|America/Santa_Isabel","America/Tijuana|Mexico/BajaNorte","America/Toronto|America/Montreal","America/Toronto|Canada/Eastern","America/Vancouver|Canada/Pacific","America/Whitehorse|Canada/Yukon","America/Winnipeg|Canada/Central","Asia/Ashgabat|Asia/Ashkhabad","Asia/Bangkok|Asia/Phnom_Penh","Asia/Bangkok|Asia/Vientiane","Asia/Dhaka|Asia/Dacca","Asia/Dubai|Asia/Muscat","Asia/Ho_Chi_Minh|Asia/Saigon","Asia/Hong_Kong|Hongkong","Asia/Jerusalem|Asia/Tel_Aviv","Asia/Jerusalem|Israel","Asia/Kathmandu|Asia/Katmandu","Asia/Kolkata|Asia/Calcutta","Asia/Macau|Asia/Macao","Asia/Makassar|Asia/Ujung_Pandang","Asia/Nicosia|Europe/Nicosia","Asia/Qatar|Asia/Bahrain","Asia/Riyadh|Asia/Aden","Asia/Riyadh|Asia/Kuwait","Asia/Seoul|ROK","Asia/Shanghai|Asia/Chongqing","Asia/Shanghai|Asia/Chungking","Asia/Shanghai|Asia/Harbin","Asia/Shanghai|PRC","Asia/Singapore|Singapore","Asia/Taipei|ROC","Asia/Tehran|Iran","Asia/Thimphu|Asia/Thimbu","Asia/Tokyo|Japan","Asia/Ulaanbaatar|Asia/Ulan_Bator","Asia/Urumqi|Asia/Kashgar","Atlantic/Faroe|Atlantic/Faeroe","Atlantic/Reykjavik|Iceland","Australia/Adelaide|Australia/South","Australia/Brisbane|Australia/Queensland","Australia/Broken_Hill|Australia/Yancowinna","Australia/Darwin|Australia/North","Australia/Hobart|Australia/Tasmania","Australia/Lord_Howe|Australia/LHI","Australia/Melbourne|Australia/Victoria","Australia/Perth|Australia/West","Australia/Sydney|Australia/ACT","Australia/Sydney|Australia/Canberra","Australia/Sydney|Australia/NSW","Etc/GMT+0|Etc/GMT","Etc/GMT+0|Etc/GMT-0","Etc/GMT+0|Etc/GMT0","Etc/GMT+0|Etc/Greenwich","Etc/GMT+0|GMT","Etc/GMT+0|GMT+0","Etc/GMT+0|GMT-0","Etc/GMT+0|GMT0","Etc/GMT+0|Greenwich","Etc/UCT|UCT","Etc/UTC|Etc/Universal","Etc/UTC|Etc/Zulu","Etc/UTC|UTC","Etc/UTC|Universal","Etc/UTC|Zulu","Europe/Belgrade|Europe/Ljubljana","Europe/Belgrade|Europe/Podgorica","Europe/Belgrade|Europe/Sarajevo","Europe/Belgrade|Europe/Skopje","Europe/Belgrade|Europe/Zagreb","Europe/Chisinau|Europe/Tiraspol","Europe/Dublin|Eire","Europe/Helsinki|Europe/Mariehamn","Europe/Istanbul|Asia/Istanbul","Europe/Istanbul|Turkey","Europe/Lisbon|Portugal","Europe/London|Europe/Belfast","Europe/London|Europe/Guernsey","Europe/London|Europe/Isle_of_Man","Europe/London|Europe/Jersey","Europe/London|GB","Europe/London|GB-Eire","Europe/Moscow|W-SU","Europe/Oslo|Arctic/Longyearbyen","Europe/Oslo|Atlantic/Jan_Mayen","Europe/Prague|Europe/Bratislava","Europe/Rome|Europe/San_Marino","Europe/Rome|Europe/Vatican","Europe/Warsaw|Poland","Europe/Zurich|Europe/Busingen","Europe/Zurich|Europe/Vaduz","Pacific/Auckland|Antarctica/McMurdo","Pacific/Auckland|Antarctica/South_Pole","Pacific/Auckland|NZ","Pacific/Chatham|NZ-CHAT","Pacific/Chuuk|Pacific/Truk","Pacific/Chuuk|Pacific/Yap","Pacific/Easter|Chile/EasterIsland","Pacific/Guam|Pacific/Saipan","Pacific/Honolulu|Pacific/Johnston","Pacific/Honolulu|US/Hawaii","Pacific/Kwajalein|Kwajalein","Pacific/Pago_Pago|Pacific/Midway","Pacific/Pago_Pago|Pacific/Samoa","Pacific/Pago_Pago|US/Samoa","Pacific/Pohnpei|Pacific/Ponape"]}),a});
diff --git a/setup/performance-toolkit/profiles/ce/attributeSets.xml b/setup/performance-toolkit/profiles/ce/attributeSets.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0db403e9969c079da00562f119233d24ea208a6b
--- /dev/null
+++ b/setup/performance-toolkit/profiles/ce/attributeSets.xml
@@ -0,0 +1,132 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<attribute_sets> <!-- Content of Attribute Sets -->
+    <attribute_set>
+        <name>Attribute Set 1</name>
+        <attributes>
+            <attribute>
+                <is_required>1</is_required>
+                <is_visible_on_front>1</is_visible_on_front>
+                <is_visible_in_advanced_search>1</is_visible_in_advanced_search>
+                <attribute_code>mycolor</attribute_code>
+                <backend_type></backend_type>
+                <is_searchable>1</is_searchable>
+                <is_filterable>1</is_filterable>
+                <is_filterable_in_search>1</is_filterable_in_search>
+                <frontend_label>my color</frontend_label>
+                <frontend_input>select</frontend_input>
+                <default_value>my yellow</default_value>
+                <options>
+                    <option>
+                        <label>my green</label>
+                        <value>my green</value>
+                    </option>
+                    <option>
+                        <label>my red</label>
+                        <value>my red</value>
+                    </option>
+                    <option>
+                        <label>my yellow</label>
+                        <value>my yellow</value>
+                    </option>
+                </options>
+            </attribute>
+            <attribute>
+                <is_required>1</is_required>
+                <is_visible_on_front>1</is_visible_on_front>
+                <is_visible_in_advanced_search>1</is_visible_in_advanced_search>
+                <attribute_code>mysize</attribute_code>
+                <backend_type></backend_type>
+                <is_searchable>1</is_searchable>
+                <is_filterable>1</is_filterable>
+                <is_filterable_in_search>1</is_filterable_in_search>
+                <frontend_label>my size</frontend_label>
+                <frontend_input>select</frontend_input>
+                <default_value>my large</default_value>
+                <options>
+                    <option>
+                        <label>my small</label>
+                        <value>my small</value>
+                    </option>
+                    <option>
+                        <label>my medium</label>
+                        <value>my medium</value>
+                    </option>
+                    <option>
+                        <label>my large</label>
+                        <value>my large</value>
+                    </option>
+                </options>
+            </attribute>
+        </attributes>
+    </attribute_set>
+    <attribute_set>
+        <name>Attribute Set 2</name>
+        <attributes>
+            <attribute>
+                <is_required>1</is_required>
+                <is_visible_on_front>1</is_visible_on_front>
+                <is_visible_in_advanced_search>1</is_visible_in_advanced_search>
+                <attribute_code>attributeset2attribute1</attribute_code>
+                <backend_type></backend_type>
+                <is_searchable>1</is_searchable>
+                <is_filterable>1</is_filterable>
+                <is_filterable_in_search>1</is_filterable_in_search>
+                <frontend_label>Attribute Set 2 - Attribute 1</frontend_label>
+                <frontend_input>select</frontend_input>
+                <default_value>attributeset2attribute1option1</default_value>
+                <options>
+                    <option>
+                        <label>Attribute Set 2 - Attribute 1 - Option a</label>
+                        <value>attributeset2attribute1option1</value>
+                    </option>
+                    <option>
+                        <label>Attribute Set 2 - Attribute 1 - Option b</label>
+                        <value>attributeset2attribute1option2</value>
+                    </option>
+                    <option>
+                        <label>Attribute Set 2 - Attribute 1 - Option c</label>
+                        <value>attributeset2attribute1option3</value>
+                    </option>
+                </options>
+            </attribute>
+        </attributes>
+    </attribute_set>
+    <attribute_set>
+        <name>Attribute Set 3</name>
+        <attributes>
+            <attribute>
+                <is_required>1</is_required>
+                <is_visible_on_front>1</is_visible_on_front>
+                <is_visible_in_advanced_search>1</is_visible_in_advanced_search>
+                <attribute_code>attributeset3attribute1</attribute_code>
+                <backend_type></backend_type>
+                <is_searchable>1</is_searchable>
+                <is_filterable>1</is_filterable>
+                <is_filterable_in_search>1</is_filterable_in_search>
+                <frontend_label>Attribute Set 3 - Attribute 1</frontend_label>
+                <frontend_input>select</frontend_input>
+                <default_value>attributeset3attribute1option1</default_value>
+                <options>
+                    <option>
+                        <label>Attribute Set 3 - Attribute 1 - Option a</label>
+                        <value>attributeset3attribute1option1</value>
+                    </option>
+                    <option>
+                        <label>Attribute Set 3 - Attribute 1 - Option b</label>
+                        <value>attributeset3attribute1option2</value>
+                    </option>
+                    <option>
+                        <label>Attribute Set 3 - Attribute 1 - Option c</label>
+                        <value>attributeset3attribute1option3</value>
+                    </option>
+                </options>
+            </attribute>
+        </attributes>
+    </attribute_set>
+</attribute_sets>
\ No newline at end of file
diff --git a/setup/performance-toolkit/profiles/ce/extra_large.xml b/setup/performance-toolkit/profiles/ce/extra_large.xml
index 41561e54f787b417ec5be855e607a2436b1d0abe..c9bf96ad4f4cab4cb8a6c1aacbe6e89a673e842c 100644
--- a/setup/performance-toolkit/profiles/ce/extra_large.xml
+++ b/setup/performance-toolkit/profiles/ce/extra_large.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
 -->
-<config>
+<config xmlns:xi="http://www.w3.org/2001/XInclude">
     <profile>
         <websites>5</websites> <!-- Number of websites to generate -->
         <store_groups>5</store_groups> <!--Number of stores-->
@@ -68,5 +68,8 @@
                 <set_scheduled>true</set_scheduled>
             </indexer>
         </indexers>
+        <xi:include href="searchTerms.xml" />
+        <xi:include href="searchConfig.xml" />
+        <xi:include href="attributeSets.xml" />
     </profile>
 </config>
diff --git a/setup/performance-toolkit/profiles/ce/large.xml b/setup/performance-toolkit/profiles/ce/large.xml
index ec521527a438406cf08b0211944347612bca5743..07e7ac33023b17d5d626986b76d84e88b3f7314b 100644
--- a/setup/performance-toolkit/profiles/ce/large.xml
+++ b/setup/performance-toolkit/profiles/ce/large.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
 -->
-<config>
+<config xmlns:xi="http://www.w3.org/2001/XInclude">
     <profile>
         <websites>3</websites> <!-- Number of websites to generate -->
         <store_groups>3</store_groups> <!--Number of stores-->
@@ -68,5 +68,8 @@
                 <set_scheduled>true</set_scheduled>
             </indexer>
         </indexers>
+        <xi:include href="searchTerms.xml" />
+        <xi:include href="searchConfig.xml" />
+        <xi:include href="attributeSets.xml" />
     </profile>
 </config>
diff --git a/setup/performance-toolkit/profiles/ce/medium.xml b/setup/performance-toolkit/profiles/ce/medium.xml
index d2125b0586b1244553277c5cafdbe30e7bb5020a..6b1b289e823bab41a6d637350037b64c39e96935 100644
--- a/setup/performance-toolkit/profiles/ce/medium.xml
+++ b/setup/performance-toolkit/profiles/ce/medium.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
 -->
-<config>
+<config xmlns:xi="http://www.w3.org/2001/XInclude">
     <profile>
         <websites>1</websites> <!-- Number of websites to generate -->
         <store_groups>2</store_groups> <!--Number of stores-->
@@ -68,5 +68,8 @@
                 <set_scheduled>false</set_scheduled>
             </indexer>
         </indexers>
+        <xi:include href="searchTerms.xml" />
+        <xi:include href="searchConfig.xml" />
+        <xi:include href="attributeSets.xml" />
     </profile>
 </config>
diff --git a/setup/performance-toolkit/profiles/ce/searchConfig.xml b/setup/performance-toolkit/profiles/ce/searchConfig.xml
new file mode 100644
index 0000000000000000000000000000000000000000..55c2caea2482c271af5cc2aa97e243fea9c6f6e3
--- /dev/null
+++ b/setup/performance-toolkit/profiles/ce/searchConfig.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<search_config> <!-- Search configuration for Simple/Configurable products -->
+    <max_amount_of_words_description>200</max_amount_of_words_description>
+    <max_amount_of_words_short_description>20</max_amount_of_words_short_description>
+    <min_amount_of_words_description>20</min_amount_of_words_description>
+    <min_amount_of_words_short_description>5</min_amount_of_words_short_description>
+</search_config>
diff --git a/setup/performance-toolkit/profiles/ce/searchTerms.xml b/setup/performance-toolkit/profiles/ce/searchTerms.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b5713ac4644f661a586564827283c6b7c973b51e
--- /dev/null
+++ b/setup/performance-toolkit/profiles/ce/searchTerms.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<search_terms> <!-- Content of Search Terms -->
+    <search_term>
+        <term>iphone 6</term>
+        <count>50</count>
+    </search_term>
+    <search_term>
+        <term>galaxy s3</term>
+        <count>100</count>
+    </search_term>
+</search_terms>
\ No newline at end of file
diff --git a/setup/performance-toolkit/profiles/ce/small.xml b/setup/performance-toolkit/profiles/ce/small.xml
index d935a90299b6063d1b06d995647044c9d0a5b23d..4f9b436666f8c743c0fd0058c6fc747944506c9d 100644
--- a/setup/performance-toolkit/profiles/ce/small.xml
+++ b/setup/performance-toolkit/profiles/ce/small.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
 -->
-<config>
+<config xmlns:xi="http://www.w3.org/2001/XInclude">
     <profile>
         <websites>1</websites> <!-- Number of websites to generate -->
         <store_groups>1</store_groups> <!--Number of stores-->
@@ -68,5 +68,8 @@
                 <set_scheduled>false</set_scheduled>
             </indexer>
         </indexers>
+        <xi:include href="searchTerms.xml" />
+        <xi:include href="searchConfig.xml" />
+        <xi:include href="attributeSets.xml" />
     </profile>
 </config>
diff --git a/setup/pub/angular-clickout/angular-clickout.js b/setup/pub/angular-clickout/angular-clickout.js
new file mode 100755
index 0000000000000000000000000000000000000000..36317edc7a4ea3108c6097f0fbc8df2f5291b051
--- /dev/null
+++ b/setup/pub/angular-clickout/angular-clickout.js
@@ -0,0 +1,25 @@
+/*! Angular clickout v1.0.2 | © 2014 Greg Bergé | License MIT */
+(function (window, angular, undefined) { 'use strict';
+
+  /**
+   * Click out directive.
+   * Execute an angular expression when we click out of the current element.
+   */
+
+  angular.module('clickOut', [])
+  .directive('clickOut', ['$window', '$parse', function ($window, $parse) {
+    return {
+      restrict: 'A',
+      link: function (scope, element, attrs) {
+        var clickOutHandler = $parse(attrs.clickOut);
+
+        angular.element($window).on('click', function (event) {
+          if (element[0].contains(event.target)) return;
+          clickOutHandler(scope, {$event: event});
+          scope.$apply();
+        });
+      }
+    };
+  }]);
+
+}(window, window.angular));
diff --git a/setup/pub/angular-clickout/angular-clickout.min.js.map b/setup/pub/angular-clickout/angular-clickout.min.js.map
new file mode 100755
index 0000000000000000000000000000000000000000..70c6dfb1c9e4f66f1368393ce0bbdc8afa710dfc
--- /dev/null
+++ b/setup/pub/angular-clickout/angular-clickout.min.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"angular-clickout.min.js","sources":["angular-clickout.js"],"names":["window","angular","undefined","module","directive","$window","$parse","restrict","link","scope","element","attrs","clickOutHandler","clickOut","on","event","contains","target","$event","$apply"],"mappings":";CACC,SAAUA,EAAQC,EAASC,GAAa,YAOvCD,GAAQE,OAAO,eACdC,UAAU,YAAa,UAAW,SAAU,SAAUC,EAASC,GAC9D,OACEC,SAAU,IACVC,KAAM,SAAUC,EAAOC,EAASC,GAC9B,GAAIC,GAAkBN,EAAOK,EAAME,SAEnCZ,GAAQS,QAAQL,GAASS,GAAG,QAAS,SAAUC,GACzCL,EAAQ,GAAGM,SAASD,EAAME,UAC9BL,EAAgBH,GAAQS,OAAQH,IAChCN,EAAMU,kBAMdnB,OAAQA,OAAOC"}
\ No newline at end of file
diff --git a/setup/pub/angular-sanitize/angular-sanitize.js b/setup/pub/angular-sanitize/angular-sanitize.js
new file mode 100644
index 0000000000000000000000000000000000000000..b7ec2820dd7feb99a854a89399630484e0e60018
--- /dev/null
+++ b/setup/pub/angular-sanitize/angular-sanitize.js
@@ -0,0 +1,618 @@
+/**
+ * @license AngularJS v1.2.14
+ * (c) 2010-2014 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+(function(window, angular, undefined) {'use strict';
+
+    var $sanitizeMinErr = angular.$$minErr('$sanitize');
+
+    /**
+     * @ngdoc module
+     * @name ngSanitize
+     * @description
+     *
+     * # ngSanitize
+     *
+     * The `ngSanitize` module provides functionality to sanitize HTML.
+     *
+     *
+     * <div doc-module-components="ngSanitize"></div>
+     *
+     * See {@link ngSanitize.$sanitize `$sanitize`} for usage.
+     */
+
+    /*
+     * HTML Parser By Misko Hevery (misko@hevery.com)
+     * based on:  HTML Parser By John Resig (ejohn.org)
+     * Original code by Erik Arvidsson, Mozilla Public License
+     * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
+     *
+     * // Use like so:
+     * htmlParser(htmlString, {
+     *     start: function(tag, attrs, unary) {},
+     *     end: function(tag) {},
+     *     chars: function(text) {},
+     *     comment: function(text) {}
+     * });
+     *
+     */
+
+
+    /**
+     * @ngdoc service
+     * @name $sanitize
+     * @function
+     *
+     * @description
+     *   The input is sanitized by parsing the html into tokens. All safe tokens (from a whitelist) are
+     *   then serialized back to properly escaped html string. This means that no unsafe input can make
+     *   it into the returned string, however, since our parser is more strict than a typical browser
+     *   parser, it's possible that some obscure input, which would be recognized as valid HTML by a
+     *   browser, won't make it through the sanitizer.
+     *   The whitelist is configured using the functions `aHrefSanitizationWhitelist` and
+     *   `imgSrcSanitizationWhitelist` of {@link ng.$compileProvider `$compileProvider`}.
+     *
+     * @param {string} html Html input.
+     * @returns {string} Sanitized html.
+     *
+     * @example
+     <example module="ngSanitize" deps="angular-sanitize.js">
+     <file name="index.html">
+     <script>
+     function Ctrl($scope, $sce) {
+         $scope.snippet =
+           '<p style="color:blue">an html\n' +
+           '<em onmouseover="this.textContent=\'PWN3D!\'">click here</em>\n' +
+           'snippet</p>';
+         $scope.deliberatelyTrustDangerousSnippet = function() {
+           return $sce.trustAsHtml($scope.snippet);
+         };
+       }
+     </script>
+     <div ng-controller="Ctrl">
+     Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
+     <table>
+     <tr>
+     <td>Directive</td>
+     <td>How</td>
+     <td>Source</td>
+     <td>Rendered</td>
+     </tr>
+     <tr id="bind-html-with-sanitize">
+     <td>ng-bind-html</td>
+     <td>Automatically uses $sanitize</td>
+     <td><pre>&lt;div ng-bind-html="snippet"&gt;<br/>&lt;/div&gt;</pre></td>
+     <td><div ng-bind-html="snippet"></div></td>
+     </tr>
+     <tr id="bind-html-with-trust">
+     <td>ng-bind-html</td>
+     <td>Bypass $sanitize by explicitly trusting the dangerous value</td>
+     <td>
+     <pre>&lt;div ng-bind-html="deliberatelyTrustDangerousSnippet()"&gt;
+     &lt;/div&gt;</pre>
+     </td>
+     <td><div ng-bind-html="deliberatelyTrustDangerousSnippet()"></div></td>
+     </tr>
+     <tr id="bind-default">
+     <td>ng-bind</td>
+     <td>Automatically escapes</td>
+     <td><pre>&lt;div ng-bind="snippet"&gt;<br/>&lt;/div&gt;</pre></td>
+     <td><div ng-bind="snippet"></div></td>
+     </tr>
+     </table>
+     </div>
+     </file>
+     <file name="protractor.js" type="protractor">
+     it('should sanitize the html snippet by default', function() {
+       expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()).
+         toBe('<p>an html\n<em>click here</em>\nsnippet</p>');
+     });
+     it('should inline raw snippet if bound to a trusted value', function() {
+       expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).
+         toBe("<p style=\"color:blue\">an html\n" +
+              "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
+              "snippet</p>");
+     });
+     it('should escape snippet without any filter', function() {
+       expect(element(by.css('#bind-default div')).getInnerHtml()).
+         toBe("&lt;p style=\"color:blue\"&gt;an html\n" +
+              "&lt;em onmouseover=\"this.textContent='PWN3D!'\"&gt;click here&lt;/em&gt;\n" +
+              "snippet&lt;/p&gt;");
+     });
+     it('should update', function() {
+       element(by.model('snippet')).clear();
+       element(by.model('snippet')).sendKeys('new <b onclick="alert(1)">text</b>');
+       expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()).
+         toBe('new <b>text</b>');
+       expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).toBe(
+         'new <b onclick="alert(1)">text</b>');
+       expect(element(by.css('#bind-default div')).getInnerHtml()).toBe(
+         "new &lt;b onclick=\"alert(1)\"&gt;text&lt;/b&gt;");
+     });
+     </file>
+     </example>
+     */
+    function $SanitizeProvider() {
+        this.$get = ['$$sanitizeUri', function($$sanitizeUri) {
+            return function(html) {
+                var buf = [];
+                htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) {
+                    return !/^unsafe/.test($$sanitizeUri(uri, isImage));
+                }));
+                return buf.join('');
+            };
+        }];
+    }
+
+    function sanitizeText(chars) {
+        var buf = [];
+        var writer = htmlSanitizeWriter(buf, angular.noop);
+        writer.chars(chars);
+        return buf.join('');
+    }
+
+
+// Regular Expressions for parsing tags and attributes
+    var START_TAG_REGEXP =
+            /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,
+        END_TAG_REGEXP = /^<\s*\/\s*([\w:-]+)[^>]*>/,
+        ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,
+        BEGIN_TAG_REGEXP = /^</,
+        BEGING_END_TAGE_REGEXP = /^<\s*\//,
+        COMMENT_REGEXP = /<!--(.*?)-->/g,
+        DOCTYPE_REGEXP = /<!DOCTYPE([^>]*?)>/i,
+        CDATA_REGEXP = /<!\[CDATA\[(.*?)]]>/g,
+        // Match everything outside of normal chars and " (quote character)
+        NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g;
+
+
+// Good source of info about elements and attributes
+// http://dev.w3.org/html5/spec/Overview.html#semantics
+// http://simon.html5.org/html-elements
+
+// Safe Void Elements - HTML5
+// http://dev.w3.org/html5/spec/Overview.html#void-elements
+    var voidElements = makeMap("area,br,col,hr,img,wbr");
+
+// Elements that you can, intentionally, leave open (and which close themselves)
+// http://dev.w3.org/html5/spec/Overview.html#optional-tags
+    var optionalEndTagBlockElements = makeMap("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"),
+        optionalEndTagInlineElements = makeMap("rp,rt"),
+        optionalEndTagElements = angular.extend({},
+            optionalEndTagInlineElements,
+            optionalEndTagBlockElements);
+
+// Safe Block Elements - HTML5
+    var blockElements = angular.extend({}, optionalEndTagBlockElements, makeMap("address,article," +
+        "aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5," +
+        "h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul"));
+
+// Inline Elements - HTML5
+    var inlineElements = angular.extend({}, optionalEndTagInlineElements, makeMap("a,abbr,acronym,b," +
+        "bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s," +
+        "samp,small,span,strike,strong,sub,sup,time,tt,u,var"));
+
+
+// Special Elements (can contain anything)
+    var specialElements = makeMap("script,style");
+
+    var validElements = angular.extend({},
+        voidElements,
+        blockElements,
+        inlineElements,
+        optionalEndTagElements);
+
+//Attributes that have href and hence need to be sanitized
+    var uriAttrs = makeMap("background,cite,href,longdesc,src,usemap");
+    var validAttrs = angular.extend({}, uriAttrs, makeMap(
+        'abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,'+
+        'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,'+
+        'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,'+
+        'scope,scrolling,shape,size,span,start,summary,target,title,type,'+
+        'valign,value,vspace,width'));
+
+    function makeMap(str) {
+        var obj = {}, items = str.split(','), i;
+        for (i = 0; i < items.length; i++) obj[items[i]] = true;
+        return obj;
+    }
+
+
+    /**
+     * @example
+     * htmlParser(htmlString, {
+ *     start: function(tag, attrs, unary) {},
+ *     end: function(tag) {},
+ *     chars: function(text) {},
+ *     comment: function(text) {}
+ * });
+     *
+     * @param {string} html string
+     * @param {object} handler
+     */
+    function htmlParser( html, handler ) {
+        var index, chars, match, stack = [], last = html;
+        stack.last = function() { return stack[ stack.length - 1 ]; };
+
+        while ( html ) {
+            chars = true;
+
+            // Make sure we're not in a script or style element
+            if ( !stack.last() || !specialElements[ stack.last() ] ) {
+
+                // Comment
+                if ( html.indexOf("<!--") === 0 ) {
+                    // comments containing -- are not allowed unless they terminate the comment
+                    index = html.indexOf("--", 4);
+
+                    if ( index >= 0 && html.lastIndexOf("-->", index) === index) {
+                        if (handler.comment) handler.comment( html.substring( 4, index ) );
+                        html = html.substring( index + 3 );
+                        chars = false;
+                    }
+                    // DOCTYPE
+                } else if ( DOCTYPE_REGEXP.test(html) ) {
+                    match = html.match( DOCTYPE_REGEXP );
+
+                    if ( match ) {
+                        html = html.replace( match[0] , '');
+                        chars = false;
+                    }
+                    // end tag
+                } else if ( BEGING_END_TAGE_REGEXP.test(html) ) {
+                    match = html.match( END_TAG_REGEXP );
+
+                    if ( match ) {
+                        html = html.substring( match[0].length );
+                        match[0].replace( END_TAG_REGEXP, parseEndTag );
+                        chars = false;
+                    }
+
+                    // start tag
+                } else if ( BEGIN_TAG_REGEXP.test(html) ) {
+                    match = html.match( START_TAG_REGEXP );
+
+                    if ( match ) {
+                        html = html.substring( match[0].length );
+                        match[0].replace( START_TAG_REGEXP, parseStartTag );
+                        chars = false;
+                    }
+                }
+
+                if ( chars ) {
+                    index = html.indexOf("<");
+
+                    var text = index < 0 ? html : html.substring( 0, index );
+                    html = index < 0 ? "" : html.substring( index );
+
+                    if (handler.chars) handler.chars( decodeEntities(text) );
+                }
+
+            } else {
+                html = html.replace(new RegExp("(.*)<\\s*\\/\\s*" + stack.last() + "[^>]*>", 'i'),
+                    function(all, text){
+                        text = text.replace(COMMENT_REGEXP, "$1").replace(CDATA_REGEXP, "$1");
+
+                        if (handler.chars) handler.chars( decodeEntities(text) );
+
+                        return "";
+                    });
+
+                parseEndTag( "", stack.last() );
+            }
+
+            if ( html == last ) {
+                throw $sanitizeMinErr('badparse', "The sanitizer was unable to parse the following block " +
+                    "of html: {0}", html);
+            }
+            last = html;
+        }
+
+        // Clean up any remaining tags
+        parseEndTag();
+
+        function parseStartTag( tag, tagName, rest, unary ) {
+            tagName = angular.lowercase(tagName);
+            if ( blockElements[ tagName ] ) {
+                while ( stack.last() && inlineElements[ stack.last() ] ) {
+                    parseEndTag( "", stack.last() );
+                }
+            }
+
+            if ( optionalEndTagElements[ tagName ] && stack.last() == tagName ) {
+                parseEndTag( "", tagName );
+            }
+
+            unary = voidElements[ tagName ] || !!unary;
+
+            if ( !unary )
+                stack.push( tagName );
+
+            var attrs = {};
+
+            rest.replace(ATTR_REGEXP,
+                function(match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) {
+                    var value = doubleQuotedValue
+                        || singleQuotedValue
+                        || unquotedValue
+                        || '';
+
+                    attrs[name] = decodeEntities(value);
+                });
+            if (handler.start) handler.start( tagName, attrs, unary );
+        }
+
+        function parseEndTag( tag, tagName ) {
+            var pos = 0, i;
+            tagName = angular.lowercase(tagName);
+            if ( tagName )
+            // Find the closest opened tag of the same type
+                for ( pos = stack.length - 1; pos >= 0; pos-- )
+                    if ( stack[ pos ] == tagName )
+                        break;
+
+            if ( pos >= 0 ) {
+                // Close all the open elements, up the stack
+                for ( i = stack.length - 1; i >= pos; i-- )
+                    if (handler.end) handler.end( stack[ i ] );
+
+                // Remove the open elements from the stack
+                stack.length = pos;
+            }
+        }
+    }
+
+    var hiddenPre=document.createElement("pre");
+    var spaceRe = /^(\s*)([\s\S]*?)(\s*)$/;
+    /**
+     * decodes all entities into regular string
+     * @param value
+     * @returns {string} A string with decoded entities.
+     */
+    function decodeEntities(value) {
+        if (!value) { return ''; }
+
+        // Note: IE8 does not preserve spaces at the start/end of innerHTML
+        // so we must capture them and reattach them afterward
+        var parts = spaceRe.exec(value);
+        var spaceBefore = parts[1];
+        var spaceAfter = parts[3];
+        var content = parts[2];
+        if (content) {
+            hiddenPre.innerHTML=content.replace(/</g,"&lt;");
+            // innerText depends on styling as it doesn't display hidden elements.
+            // Therefore, it's better to use textContent not to cause unnecessary
+            // reflows. However, IE<9 don't support textContent so the innerText
+            // fallback is necessary.
+            content = 'textContent' in hiddenPre ?
+                hiddenPre.textContent : hiddenPre.innerText;
+        }
+        return spaceBefore + content + spaceAfter;
+    }
+
+    /**
+     * Escapes all potentially dangerous characters, so that the
+     * resulting string can be safely inserted into attribute or
+     * element text.
+     * @param value
+     * @returns {string} escaped text
+     */
+    function encodeEntities(value) {
+        return value.
+        replace(/&/g, '&amp;').
+        replace(NON_ALPHANUMERIC_REGEXP, function(value){
+            return '&#' + value.charCodeAt(0) + ';';
+        }).
+        replace(/</g, '&lt;').
+        replace(/>/g, '&gt;');
+    }
+
+    /**
+     * create an HTML/XML writer which writes to buffer
+     * @param {Array} buf use buf.jain('') to get out sanitized html string
+     * @returns {object} in the form of {
+ *     start: function(tag, attrs, unary) {},
+ *     end: function(tag) {},
+ *     chars: function(text) {},
+ *     comment: function(text) {}
+ * }
+     */
+    function htmlSanitizeWriter(buf, uriValidator){
+        var ignore = false;
+        var out = angular.bind(buf, buf.push);
+        return {
+            start: function(tag, attrs, unary){
+                tag = angular.lowercase(tag);
+                if (!ignore && specialElements[tag]) {
+                    ignore = tag;
+                }
+                if (!ignore && validElements[tag] === true) {
+                    out('<');
+                    out(tag);
+                    angular.forEach(attrs, function(value, key){
+                        var lkey=angular.lowercase(key);
+                        var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background');
+                        if (validAttrs[lkey] === true &&
+                            (uriAttrs[lkey] !== true || uriValidator(value, isImage))) {
+                            out(' ');
+                            out(key);
+                            out('="');
+                            out(encodeEntities(value));
+                            out('"');
+                        }
+                    });
+                    out(unary ? '/>' : '>');
+                }
+            },
+            end: function(tag){
+                tag = angular.lowercase(tag);
+                if (!ignore && validElements[tag] === true) {
+                    out('</');
+                    out(tag);
+                    out('>');
+                }
+                if (tag == ignore) {
+                    ignore = false;
+                }
+            },
+            chars: function(chars){
+                if (!ignore) {
+                    out(encodeEntities(chars));
+                }
+            }
+        };
+    }
+
+
+// define ngSanitize module and register $sanitize service
+    angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider);
+
+    /* global sanitizeText: false */
+
+    /**
+     * @ngdoc filter
+     * @name linky
+     * @function
+     *
+     * @description
+     * Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and
+     * plain email address links.
+     *
+     * Requires the {@link ngSanitize `ngSanitize`} module to be installed.
+     *
+     * @param {string} text Input text.
+     * @param {string} target Window (_blank|_self|_parent|_top) or named frame to open links in.
+     * @returns {string} Html-linkified text.
+     *
+     * @usage
+     <span ng-bind-html="linky_expression | linky"></span>
+     *
+     * @example
+     <example module="ngSanitize" deps="angular-sanitize.js">
+     <file name="index.html">
+     <script>
+     function Ctrl($scope) {
+           $scope.snippet =
+             'Pretty text with some links:\n'+
+             'http://angularjs.org/,\n'+
+             'mailto:us@somewhere.org,\n'+
+             'another@somewhere.org,\n'+
+             'and one more: ftp://127.0.0.1/.';
+           $scope.snippetWithTarget = 'http://angularjs.org/';
+         }
+     </script>
+     <div ng-controller="Ctrl">
+     Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
+     <table>
+     <tr>
+     <td>Filter</td>
+     <td>Source</td>
+     <td>Rendered</td>
+     </tr>
+     <tr id="linky-filter">
+     <td>linky filter</td>
+     <td>
+     <pre>&lt;div ng-bind-html="snippet | linky"&gt;<br>&lt;/div&gt;</pre>
+     </td>
+     <td>
+     <div ng-bind-html="snippet | linky"></div>
+     </td>
+     </tr>
+     <tr id="linky-target">
+     <td>linky target</td>
+     <td>
+     <pre>&lt;div ng-bind-html="snippetWithTarget | linky:'_blank'"&gt;<br>&lt;/div&gt;</pre>
+     </td>
+     <td>
+     <div ng-bind-html="snippetWithTarget | linky:'_blank'"></div>
+     </td>
+     </tr>
+     <tr id="escaped-html">
+     <td>no filter</td>
+     <td><pre>&lt;div ng-bind="snippet"&gt;<br>&lt;/div&gt;</pre></td>
+     <td><div ng-bind="snippet"></div></td>
+     </tr>
+     </table>
+     </file>
+     <file name="protractor.js" type="protractor">
+     it('should linkify the snippet with urls', function() {
+         expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
+             toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' +
+                  'another@somewhere.org, and one more: ftp://127.0.0.1/.');
+         expect(element.all(by.css('#linky-filter a')).count()).toEqual(4);
+       });
+     it('should not linkify snippet without the linky filter', function() {
+         expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()).
+             toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' +
+                  'another@somewhere.org, and one more: ftp://127.0.0.1/.');
+         expect(element.all(by.css('#escaped-html a')).count()).toEqual(0);
+       });
+     it('should update', function() {
+         element(by.model('snippet')).clear();
+         element(by.model('snippet')).sendKeys('new http://link.');
+         expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
+             toBe('new http://link.');
+         expect(element.all(by.css('#linky-filter a')).count()).toEqual(1);
+         expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText())
+             .toBe('new http://link.');
+       });
+     it('should work with the target property', function() {
+        expect(element(by.id('linky-target')).
+            element(by.binding("snippetWithTarget | linky:'_blank'")).getText()).
+            toBe('http://angularjs.org/');
+        expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank');
+       });
+     </file>
+     </example>
+     */
+    angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
+        var LINKY_URL_REGEXP =
+                /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>]/,
+            MAILTO_REGEXP = /^mailto:/;
+
+        return function(text, target) {
+            if (!text) return text;
+            var match;
+            var raw = text;
+            var html = [];
+            var url;
+            var i;
+            while ((match = raw.match(LINKY_URL_REGEXP))) {
+                // We can not end in these as they are sometimes found at the end of the sentence
+                url = match[0];
+                // if we did not match ftp/http/mailto then assume mailto
+                if (match[2] == match[3]) url = 'mailto:' + url;
+                i = match.index;
+                addText(raw.substr(0, i));
+                addLink(url, match[0].replace(MAILTO_REGEXP, ''));
+                raw = raw.substring(i + match[0].length);
+            }
+            addText(raw);
+            return $sanitize(html.join(''));
+
+            function addText(text) {
+                if (!text) {
+                    return;
+                }
+                html.push(sanitizeText(text));
+            }
+
+            function addLink(url, text) {
+                html.push('<a ');
+                if (angular.isDefined(target)) {
+                    html.push('target="');
+                    html.push(target);
+                    html.push('" ');
+                }
+                html.push('href="');
+                html.push(url);
+                html.push('">');
+                addText(text);
+                html.push('</a>');
+            }
+        };
+    }]);
+
+
+})(window, window.angular);
\ No newline at end of file
diff --git a/setup/pub/angular-sanitize/angular-sanitize.min.js.map b/setup/pub/angular-sanitize/angular-sanitize.min.js.map
new file mode 100644
index 0000000000000000000000000000000000000000..0c993a6ed2afb7d117a86c855187e8d016ed37f8
--- /dev/null
+++ b/setup/pub/angular-sanitize/angular-sanitize.min.js.map
@@ -0,0 +1,8 @@
+{
+"version":3,
+"file":"angular-sanitize.min.js",
+"lineCount":13,
+"mappings":"A;;;;;aAKC,SAAQ,CAACA,CAAD,CAASC,CAAT,CAAkBC,CAAlB,CAA6B,CAiJtCC,QAASA,EAAY,CAACC,CAAD,CAAQ,CAC3B,IAAIC,EAAM,EACGC,EAAAC,CAAmBF,CAAnBE,CAAwBN,CAAAO,KAAxBD,CACbH,MAAA,CAAaA,CAAb,CACA,OAAOC,EAAAI,KAAA,CAAS,EAAT,CAJoB,CAmE7BC,QAASA,EAAO,CAACC,CAAD,CAAM,CAAA,IAChBC,EAAM,EAAIC,EAAAA,CAAQF,CAAAG,MAAA,CAAU,GAAV,CAAtB,KAAsCC,CACtC,KAAKA,CAAL,CAAS,CAAT,CAAYA,CAAZ,CAAgBF,CAAAG,OAAhB,CAA8BD,CAAA,EAA9B,CAAmCH,CAAA,CAAIC,CAAA,CAAME,CAAN,CAAJ,CAAA,CAAgB,CAAA,CACnD,OAAOH,EAHa,CAmBtBK,QAASA,EAAU,CAAEC,CAAF,CAAQC,CAAR,CAAkB,CAiFnCC,QAASA,EAAa,CAAEC,CAAF,CAAOC,CAAP,CAAgBC,CAAhB,CAAsBC,CAAtB,CAA8B,CAClDF,CAAA,CAAUrB,CAAAwB,UAAA,CAAkBH,CAAlB,CACV,IAAKI,CAAA,CAAeJ,CAAf,CAAL,CACE,IAAA,CAAQK,CAAAC,KAAA,EAAR,EAAwBC,CAAA,CAAgBF,CAAAC,KAAA,EAAhB,CAAxB,CAAA,CACEE,CAAA,CAAa,EAAb,CAAiBH,CAAAC,KAAA,EAAjB,CAICG,EAAA,CAAwBT,CAAxB,CAAL,EAA0CK,CAAAC,KAAA,EAA1C,EAA0DN,CAA1D,EACEQ,CAAA,CAAa,EAAb,CAAiBR,CAAjB,CAKF,EAFAE,CAEA,CAFQQ,CAAA,CAAcV,CAAd,CAER,EAFmC,CAAC,CAACE,CAErC,GACEG,CAAAM,KAAA,CAAYX,CAAZ,CAEF,KAAIY,EAAQ,EAEZX,EAAAY,QAAA,CAAaC,CAAb,CACE,QAAQ,CAACC,CAAD,CAAQC,CAAR,CAAcC,CAAd,CAAiCC,CAAjC,CAAoDC,CAApD,CAAmE,CAMzEP,CAAA,CAAMI,CAAN,CAAA,CAAcI,CAAA,CALFH,CAKE,EAJTC,CAIS,EAHTC,CAGS,EAFT,EAES,CAN2D,CAD7E,CASItB,EAAAwB,MAAJ,EAAmBxB,CAAAwB,MAAA,CAAerB,CAAf,CAAwBY,CAAxB,CAA+BV,CAA/B,CA5B+B,CA+BpDM,QAASA,EAAW,CAAET,CAAF,CAAOC,CAAP,CAAiB,CAAA,IAC/BsB,EAAM,CADyB,CACtB7B,CAEb,IADAO,CACA,CADUrB,CAAAwB,UAAA,CAAkBH,CAAlB,CACV,CAEE,IAAMsB,CAAN,CAAYjB,CAAAX,OAAZ,CAA2B,CAA3B,CAAqC,CAArC,EAA8B4B,CAA9B,EACOjB,CAAA,CAAOiB,CAAP,CADP,EACuBtB,CADvB,CAAwCsB,CAAA,EAAxC;AAIF,GAAY,CAAZ,EAAKA,CAAL,CAAgB,CAEd,IAAM7B,CAAN,CAAUY,CAAAX,OAAV,CAAyB,CAAzB,CAA4BD,CAA5B,EAAiC6B,CAAjC,CAAsC7B,CAAA,EAAtC,CACMI,CAAA0B,IAAJ,EAAiB1B,CAAA0B,IAAA,CAAalB,CAAA,CAAOZ,CAAP,CAAb,CAGnBY,EAAAX,OAAA,CAAe4B,CAND,CATmB,CAhHF,IAC/BE,CAD+B,CACxB1C,CADwB,CACVuB,EAAQ,EADE,CACEC,EAAOV,CAG5C,KAFAS,CAAAC,KAEA,CAFamB,QAAQ,EAAG,CAAE,MAAOpB,EAAA,CAAOA,CAAAX,OAAP,CAAsB,CAAtB,CAAT,CAExB,CAAQE,CAAR,CAAA,CAAe,CACbd,CAAA,CAAQ,CAAA,CAGR,IAAMuB,CAAAC,KAAA,EAAN,EAAuBoB,CAAA,CAAiBrB,CAAAC,KAAA,EAAjB,CAAvB,CAmDEV,CASA,CATOA,CAAAiB,QAAA,CAAiBc,MAAJ,CAAW,kBAAX,CAAgCtB,CAAAC,KAAA,EAAhC,CAA+C,QAA/C,CAAyD,GAAzD,CAAb,CACL,QAAQ,CAACsB,CAAD,CAAMC,CAAN,CAAW,CACjBA,CAAA,CAAOA,CAAAhB,QAAA,CAAaiB,CAAb,CAA6B,IAA7B,CAAAjB,QAAA,CAA2CkB,CAA3C,CAAyD,IAAzD,CAEHlC,EAAAf,MAAJ,EAAmBe,CAAAf,MAAA,CAAesC,CAAA,CAAeS,CAAf,CAAf,CAEnB,OAAO,EALU,CADd,CASP,CAAArB,CAAA,CAAa,EAAb,CAAiBH,CAAAC,KAAA,EAAjB,CA5DF,KAAyD,CAGvD,GAA8B,CAA9B,GAAKV,CAAAoC,QAAA,CAAa,SAAb,CAAL,CAEER,CAEA,CAFQ5B,CAAAoC,QAAA,CAAa,IAAb,CAAmB,CAAnB,CAER,CAAc,CAAd,EAAKR,CAAL,EAAmB5B,CAAAqC,YAAA,CAAiB,QAAjB,CAAwBT,CAAxB,CAAnB,GAAsDA,CAAtD,GACM3B,CAAAqC,QAEJ,EAFqBrC,CAAAqC,QAAA,CAAiBtC,CAAAuC,UAAA,CAAgB,CAAhB,CAAmBX,CAAnB,CAAjB,CAErB,CADA5B,CACA,CADOA,CAAAuC,UAAA,CAAgBX,CAAhB,CAAwB,CAAxB,CACP,CAAA1C,CAAA,CAAQ,CAAA,CAHV,CAJF,KAUO,IAAKsD,CAAAC,KAAA,CAAoBzC,CAApB,CAAL,CAGL,IAFAmB,CAEA,CAFQnB,CAAAmB,MAAA,CAAYqB,CAAZ,CAER,CACExC,CACA;AADOA,CAAAiB,QAAA,CAAcE,CAAA,CAAM,CAAN,CAAd,CAAyB,EAAzB,CACP,CAAAjC,CAAA,CAAQ,CAAA,CAFV,CAHK,IAQA,IAAKwD,CAAAD,KAAA,CAA4BzC,CAA5B,CAAL,CAGL,IAFAmB,CAEA,CAFQnB,CAAAmB,MAAA,CAAYwB,CAAZ,CAER,CACE3C,CAEA,CAFOA,CAAAuC,UAAA,CAAgBpB,CAAA,CAAM,CAAN,CAAArB,OAAhB,CAEP,CADAqB,CAAA,CAAM,CAAN,CAAAF,QAAA,CAAkB0B,CAAlB,CAAkC/B,CAAlC,CACA,CAAA1B,CAAA,CAAQ,CAAA,CAHV,CAHK,IAUK0D,EAAAH,KAAA,CAAsBzC,CAAtB,CAAL,GACLmB,CADK,CACGnB,CAAAmB,MAAA,CAAY0B,CAAZ,CADH,IAIH7C,CAEA,CAFOA,CAAAuC,UAAA,CAAgBpB,CAAA,CAAM,CAAN,CAAArB,OAAhB,CAEP,CADAqB,CAAA,CAAM,CAAN,CAAAF,QAAA,CAAkB4B,CAAlB,CAAoC3C,CAApC,CACA,CAAAhB,CAAA,CAAQ,CAAA,CANL,CAUFA,EAAL,GACE0C,CAKA,CALQ5B,CAAAoC,QAAA,CAAa,GAAb,CAKR,CAHIH,CAGJ,CAHmB,CAAR,CAAAL,CAAA,CAAY5B,CAAZ,CAAmBA,CAAAuC,UAAA,CAAgB,CAAhB,CAAmBX,CAAnB,CAG9B,CAFA5B,CAEA,CAFe,CAAR,CAAA4B,CAAA,CAAY,EAAZ,CAAiB5B,CAAAuC,UAAA,CAAgBX,CAAhB,CAExB,CAAI3B,CAAAf,MAAJ,EAAmBe,CAAAf,MAAA,CAAesC,CAAA,CAAeS,CAAf,CAAf,CANrB,CAzCuD,CA+DzD,GAAKjC,CAAL,EAAaU,CAAb,CACE,KAAMoC,EAAA,CAAgB,UAAhB,CAC4C9C,CAD5C,CAAN,CAGFU,CAAA,CAAOV,CAvEM,CA2EfY,CAAA,EA/EmC,CA2IrCY,QAASA,EAAc,CAACuB,CAAD,CAAQ,CAC7B,GAAI,CAACA,CAAL,CAAc,MAAO,EAIrB,KAAIC,EAAQC,CAAAC,KAAA,CAAaH,CAAb,CACRI,EAAAA,CAAcH,CAAA,CAAM,CAAN,CAClB,KAAII,EAAaJ,CAAA,CAAM,CAAN,CAEjB,IADIK,CACJ,CADcL,CAAA,CAAM,CAAN,CACd,CACEM,CAAAC,UAKA,CALoBF,CAAApC,QAAA,CAAgB,IAAhB,CAAqB,MAArB,CAKpB,CAAAoC,CAAA,CAAU,aAAA,EAAiBC,EAAjB,CACRA,CAAAE,YADQ,CACgBF,CAAAG,UAE5B,OAAON,EAAP,CAAqBE,CAArB,CAA+BD,CAlBF,CA4B/BM,QAASA,EAAc,CAACX,CAAD,CAAQ,CAC7B,MAAOA,EAAA9B,QAAA,CACG,IADH;AACS,OADT,CAAAA,QAAA,CAEG0C,CAFH,CAE4B,QAAQ,CAACZ,CAAD,CAAO,CAC9C,MAAO,IAAP,CAAcA,CAAAa,WAAA,CAAiB,CAAjB,CAAd,CAAoC,GADU,CAF3C,CAAA3C,QAAA,CAKG,IALH,CAKS,MALT,CAAAA,QAAA,CAMG,IANH,CAMS,MANT,CADsB,CAoB/B7B,QAASA,EAAkB,CAACD,CAAD,CAAM0E,CAAN,CAAmB,CAC5C,IAAIC,EAAS,CAAA,CAAb,CACIC,EAAMhF,CAAAiF,KAAA,CAAa7E,CAAb,CAAkBA,CAAA4B,KAAlB,CACV,OAAO,OACEU,QAAQ,CAACtB,CAAD,CAAMa,CAAN,CAAaV,CAAb,CAAmB,CAChCH,CAAA,CAAMpB,CAAAwB,UAAA,CAAkBJ,CAAlB,CACD2D,EAAAA,CAAL,EAAehC,CAAA,CAAgB3B,CAAhB,CAAf,GACE2D,CADF,CACW3D,CADX,CAGK2D,EAAL,EAAsC,CAAA,CAAtC,GAAeG,CAAA,CAAc9D,CAAd,CAAf,GACE4D,CAAA,CAAI,GAAJ,CAcA,CAbAA,CAAA,CAAI5D,CAAJ,CAaA,CAZApB,CAAAmF,QAAA,CAAgBlD,CAAhB,CAAuB,QAAQ,CAAC+B,CAAD,CAAQoB,CAAR,CAAY,CACzC,IAAIC,EAAKrF,CAAAwB,UAAA,CAAkB4D,CAAlB,CAAT,CACIE,EAAmB,KAAnBA,GAAWlE,CAAXkE,EAAqC,KAArCA,GAA4BD,CAA5BC,EAAyD,YAAzDA,GAAgDD,CAC3B,EAAA,CAAzB,GAAIE,CAAA,CAAWF,CAAX,CAAJ,EACsB,CAAA,CADtB,GACGG,CAAA,CAASH,CAAT,CADH,EAC8B,CAAAP,CAAA,CAAad,CAAb,CAAoBsB,CAApB,CAD9B,GAEEN,CAAA,CAAI,GAAJ,CAIA,CAHAA,CAAA,CAAII,CAAJ,CAGA,CAFAJ,CAAA,CAAI,IAAJ,CAEA,CADAA,CAAA,CAAIL,CAAA,CAAeX,CAAf,CAAJ,CACA,CAAAgB,CAAA,CAAI,GAAJ,CANF,CAHyC,CAA3C,CAYA,CAAAA,CAAA,CAAIzD,CAAA,CAAQ,IAAR,CAAe,GAAnB,CAfF,CALgC,CAD7B,KAwBAqB,QAAQ,CAACxB,CAAD,CAAK,CACdA,CAAA,CAAMpB,CAAAwB,UAAA,CAAkBJ,CAAlB,CACD2D,EAAL,EAAsC,CAAA,CAAtC,GAAeG,CAAA,CAAc9D,CAAd,CAAf,GACE4D,CAAA,CAAI,IAAJ,CAEA,CADAA,CAAA,CAAI5D,CAAJ,CACA,CAAA4D,CAAA,CAAI,GAAJ,CAHF,CAKI5D,EAAJ,EAAW2D,CAAX,GACEA,CADF,CACW,CAAA,CADX,CAPc,CAxBb,OAmCE5E,QAAQ,CAACA,CAAD,CAAO,CACb4E,CAAL;AACEC,CAAA,CAAIL,CAAA,CAAexE,CAAf,CAAJ,CAFgB,CAnCjB,CAHqC,CAha9C,IAAI4D,EAAkB/D,CAAAyF,SAAA,CAAiB,WAAjB,CAAtB,CAwJI3B,EACG,4FAzJP,CA0JEF,EAAiB,2BA1JnB,CA2JEzB,EAAc,yEA3JhB,CA4JE0B,EAAmB,IA5JrB,CA6JEF,EAAyB,SA7J3B,CA8JER,EAAiB,qBA9JnB,CA+JEM,EAAiB,qBA/JnB,CAgKEL,EAAe,yBAhKjB,CAkKEwB,EAA0B,gBAlK5B,CA2KI7C,EAAetB,CAAA,CAAQ,wBAAR,CAIfiF,EAAAA,CAA8BjF,CAAA,CAAQ,gDAAR,CAC9BkF,EAAAA,CAA+BlF,CAAA,CAAQ,OAAR,CADnC,KAEIqB,EAAyB9B,CAAA4F,OAAA,CAAe,EAAf,CACeD,CADf,CAEeD,CAFf,CAF7B,CAOIjE,EAAgBzB,CAAA4F,OAAA,CAAe,EAAf,CAAmBF,CAAnB,CAAgDjF,CAAA,CAAQ,4KAAR,CAAhD,CAPpB;AAYImB,EAAiB5B,CAAA4F,OAAA,CAAe,EAAf,CAAmBD,CAAnB,CAAiDlF,CAAA,CAAQ,2JAAR,CAAjD,CAZrB,CAkBIsC,EAAkBtC,CAAA,CAAQ,cAAR,CAlBtB,CAoBIyE,EAAgBlF,CAAA4F,OAAA,CAAe,EAAf,CACe7D,CADf,CAEeN,CAFf,CAGeG,CAHf,CAIeE,CAJf,CApBpB,CA2BI0D,EAAW/E,CAAA,CAAQ,0CAAR,CA3Bf,CA4BI8E,EAAavF,CAAA4F,OAAA,CAAe,EAAf,CAAmBJ,CAAnB,CAA6B/E,CAAA,CAC1C,ySAD0C,CAA7B,CA5BjB;AA0LI8D,EAAUsB,QAAAC,cAAA,CAAuB,KAAvB,CA1Ld,CA2LI5B,EAAU,wBAsGdlE,EAAA+F,OAAA,CAAe,YAAf,CAA6B,EAA7B,CAAAC,SAAA,CAA0C,WAA1C,CA7UAC,QAA0B,EAAG,CAC3B,IAAAC,KAAA,CAAY,CAAC,eAAD,CAAkB,QAAQ,CAACC,CAAD,CAAgB,CACpD,MAAO,SAAQ,CAAClF,CAAD,CAAO,CACpB,IAAIb,EAAM,EACVY,EAAA,CAAWC,CAAX,CAAiBZ,CAAA,CAAmBD,CAAnB,CAAwB,QAAQ,CAACgG,CAAD,CAAMd,CAAN,CAAe,CAC9D,MAAO,CAAC,SAAA5B,KAAA,CAAeyC,CAAA,CAAcC,CAAd,CAAmBd,CAAnB,CAAf,CADsD,CAA/C,CAAjB,CAGA,OAAOlF,EAAAI,KAAA,CAAS,EAAT,CALa,CAD8B,CAA1C,CADe,CA6U7B,CAuGAR,EAAA+F,OAAA,CAAe,YAAf,CAAAM,OAAA,CAAoC,OAApC,CAA6C,CAAC,WAAD,CAAc,QAAQ,CAACC,CAAD,CAAY,CAAA,IACzEC,EACE,mEAFuE,CAGzEC,EAAgB,UAEpB,OAAO,SAAQ,CAACtD,CAAD,CAAOuD,CAAP,CAAe,CAoB5BC,QAASA,EAAO,CAACxD,CAAD,CAAO,CAChBA,CAAL,EAGAjC,CAAAe,KAAA,CAAU9B,CAAA,CAAagD,CAAb,CAAV,CAJqB,CAOvByD,QAASA,EAAO,CAACC,CAAD,CAAM1D,CAAN,CAAY,CAC1BjC,CAAAe,KAAA,CAAU,KAAV,CACIhC,EAAA6G,UAAA,CAAkBJ,CAAlB,CAAJ;CACExF,CAAAe,KAAA,CAAU,UAAV,CAEA,CADAf,CAAAe,KAAA,CAAUyE,CAAV,CACA,CAAAxF,CAAAe,KAAA,CAAU,IAAV,CAHF,CAKAf,EAAAe,KAAA,CAAU,QAAV,CACAf,EAAAe,KAAA,CAAU4E,CAAV,CACA3F,EAAAe,KAAA,CAAU,IAAV,CACA0E,EAAA,CAAQxD,CAAR,CACAjC,EAAAe,KAAA,CAAU,MAAV,CAX0B,CA1B5B,GAAI,CAACkB,CAAL,CAAW,MAAOA,EAMlB,KALA,IAAId,CAAJ,CACI0E,EAAM5D,CADV,CAEIjC,EAAO,EAFX,CAGI2F,CAHJ,CAII9F,CACJ,CAAQsB,CAAR,CAAgB0E,CAAA1E,MAAA,CAAUmE,CAAV,CAAhB,CAAA,CAEEK,CAMA,CANMxE,CAAA,CAAM,CAAN,CAMN,CAJIA,CAAA,CAAM,CAAN,CAIJ,EAJgBA,CAAA,CAAM,CAAN,CAIhB,GAJ0BwE,CAI1B,CAJgC,SAIhC,CAJ4CA,CAI5C,EAHA9F,CAGA,CAHIsB,CAAAS,MAGJ,CAFA6D,CAAA,CAAQI,CAAAC,OAAA,CAAW,CAAX,CAAcjG,CAAd,CAAR,CAEA,CADA6F,CAAA,CAAQC,CAAR,CAAaxE,CAAA,CAAM,CAAN,CAAAF,QAAA,CAAiBsE,CAAjB,CAAgC,EAAhC,CAAb,CACA,CAAAM,CAAA,CAAMA,CAAAtD,UAAA,CAAc1C,CAAd,CAAkBsB,CAAA,CAAM,CAAN,CAAArB,OAAlB,CAER2F,EAAA,CAAQI,CAAR,CACA,OAAOR,EAAA,CAAUrF,CAAAT,KAAA,CAAU,EAAV,CAAV,CAlBqB,CAL+C,CAAlC,CAA7C,CAzjBsC,CAArC,CAAA,CA0mBET,MA1mBF,CA0mBUA,MAAAC,QA1mBV;",
+"sources":["angular-sanitize.js"],
+"names":["window","angular","undefined","sanitizeText","chars","buf","htmlSanitizeWriter","writer","noop","join","makeMap","str","obj","items","split","i","length","htmlParser","html","handler","parseStartTag","tag","tagName","rest","unary","lowercase","blockElements","stack","last","inlineElements","parseEndTag","optionalEndTagElements","voidElements","push","attrs","replace","ATTR_REGEXP","match","name","doubleQuotedValue","singleQuotedValue","unquotedValue","decodeEntities","start","pos","end","index","stack.last","specialElements","RegExp","all","text","COMMENT_REGEXP","CDATA_REGEXP","indexOf","lastIndexOf","comment","substring","DOCTYPE_REGEXP","test","BEGING_END_TAGE_REGEXP","END_TAG_REGEXP","BEGIN_TAG_REGEXP","START_TAG_REGEXP","$sanitizeMinErr","value","parts","spaceRe","exec","spaceBefore","spaceAfter","content","hiddenPre","innerHTML","textContent","innerText","encodeEntities","NON_ALPHANUMERIC_REGEXP","charCodeAt","uriValidator","ignore","out","bind","validElements","forEach","key","lkey","isImage","validAttrs","uriAttrs","$$minErr","optionalEndTagBlockElements","optionalEndTagInlineElements","extend","document","createElement","module","provider","$SanitizeProvider","$get","$$sanitizeUri","uri","filter","$sanitize","LINKY_URL_REGEXP","MAILTO_REGEXP","target","addText","addLink","url","isDefined","raw","substr"]
+}
\ No newline at end of file
diff --git a/setup/src/Magento/Setup/Console/Command/GenerateFixturesCommand.php b/setup/src/Magento/Setup/Console/Command/GenerateFixturesCommand.php
index d91a1633ef03848eb1a73a123b9e5f87d6f253d4..f70c36cec65dcd5fb868f12b7144fb46e58c3a7c 100644
--- a/setup/src/Magento/Setup/Console/Command/GenerateFixturesCommand.php
+++ b/setup/src/Magento/Setup/Console/Command/GenerateFixturesCommand.php
@@ -78,7 +78,12 @@ class GenerateFixturesCommand extends Command
             $output->writeln('<info>Generating profile with following params:</info>');
 
             foreach ($fixtureModel->getParamLabels() as $configKey => $label) {
-                $output->writeln('<info> |- ' . $label . ': ' . $fixtureModel->getValue($configKey) . '</info>');
+                $output->writeln(
+                    '<info> |- ' . $label . ': ' . (is_array($fixtureModel->getValue($configKey)) === true
+                        ? sizeof(
+                            $fixtureModel->getValue($configKey)[array_keys($fixtureModel->getValue($configKey))[0]]
+                        ) : $fixtureModel->getValue($configKey)) . '</info>'
+                );
             }
 
             /** @var $config \Magento\Indexer\Model\Config */
diff --git a/setup/src/Magento/Setup/Fixtures/AttributeSetsFixture.php b/setup/src/Magento/Setup/Fixtures/AttributeSetsFixture.php
new file mode 100644
index 0000000000000000000000000000000000000000..5617eca9a0e7e24694c151d508ed09a4cd547999
--- /dev/null
+++ b/setup/src/Magento/Setup/Fixtures/AttributeSetsFixture.php
@@ -0,0 +1,122 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Fixtures;
+
+/**
+ * Class AttributeSetFixture
+ */
+class AttributeSetsFixture extends Fixture
+{
+    /**
+     * @var int
+     */
+    protected $priority = 25;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute()
+    {
+        $attributeSets = $this->fixtureModel->getValue('attribute_sets', null);
+        if ($attributeSets === null) {
+            return;
+        }
+        $this->fixtureModel->resetObjectManager();
+        /** @var \Magento\Catalog\Api\AttributeSetManagementInterface $attributeSetManagement */
+        $attributeSetManagement = $this->fixtureModel->getObjectManager()->create(
+            \Magento\Catalog\Api\AttributeSetManagementInterface::class
+        );
+        /** @var \Magento\Catalog\Api\ProductAttributeGroupRepositoryInterface $attributeGroupRepository */
+        $attributeGroupRepository = $this->fixtureModel->getObjectManager()->create(
+            \Magento\Catalog\Api\ProductAttributeGroupRepositoryInterface::class
+        );
+
+        foreach ($attributeSets['attribute_set'] as $attributeSetData) {
+            //Create Attribute Set
+            /** @var \Magento\Eav\Api\Data\AttributeSetInterfaceFactory $attributeSetFactory */
+            $attributeSetFactory = $this->fixtureModel->getObjectManager()->create(
+                \Magento\Eav\Api\Data\AttributeSetInterfaceFactory::class
+            );
+            $attributeSet = $attributeSetFactory->create();
+            $attributeSet->setAttributeSetName($attributeSetData['name']);
+            $attributeSet->setEntityTypeId(\Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE);
+
+            $result = $attributeSetManagement->create($attributeSet, 4);
+            $attributeSetId = $result->getAttributeSetId();
+
+            //Create Attribute Group
+            /** @var \Magento\Eav\Api\Data\AttributeGroupInterfaceFactory $attributeGroupFactory */
+            $attributeGroupFactory = $this->fixtureModel->getObjectManager()->create(
+                \Magento\Eav\Api\Data\AttributeGroupInterfaceFactory::class
+            );
+            $attributeGroup = $attributeGroupFactory->create();
+            $attributeGroup->setAttributeGroupName($result->getAttributeSetName() . ' - Group');
+            $attributeGroup->setAttributeSetId($attributeSetId);
+            $attributeGroupRepository->save($attributeGroup);
+            $attributeGroupId = $attributeGroup->getAttributeGroupId();
+
+            /** @var \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository */
+            $attributeRepository = $this->fixtureModel->getObjectManager()->create(
+                \Magento\Catalog\Api\ProductAttributeRepositoryInterface::class
+            );
+            /** @var \Magento\Catalog\Api\ProductAttributeManagementInterface $attributeManagementManagement */
+            $attributeManagement = $this->fixtureModel->getObjectManager()->create(
+                \Magento\Catalog\Api\ProductAttributeManagementInterface::class
+            );
+
+            $attributesData = array_key_exists(0, $attributeSetData['attributes']['attribute'])
+                ? $attributeSetData['attributes']['attribute'] : [$attributeSetData['attributes']['attribute']];
+            foreach ($attributesData as $attributeData) {
+                //Create Attribute
+                /** @var  \Magento\Catalog\Api\Data\ProductAttributeInterfaceFactory $attributeFactory */
+                $attributeFactory = $this->fixtureModel->getObjectManager()->create(
+                    \Magento\Catalog\Api\Data\ProductAttributeInterfaceFactory::class
+                );
+
+                $optionsData = array_key_exists(0, $attributeData['options']['option'])
+                    ? $attributeData['options']['option'] : [$attributeData['options']['option']];
+                $options = [];
+                foreach ($optionsData as $optionData) {
+                    /** @var \Magento\Eav\Api\Data\AttributeOptionInterfaceFactory $optionFactory */
+                    $optionFactory = $this->fixtureModel->getObjectManager()->create(
+                        \Magento\Eav\Api\Data\AttributeOptionInterfaceFactory::class
+                    );
+                    $option = $optionFactory->create(['data' => $optionData]);
+                    $options[] = $option;
+                }
+
+                $attribute = $attributeFactory->create(['data' => $attributeData]);
+                $attribute->setOptions($options);
+
+                $result = $attributeRepository->save($attribute);
+                $attributeId = $result->getAttributeId();
+
+                //Associate Attribute to Attribute Set
+                $sortOrder = 3;
+                $attributeManagement->assign($attributeSetId, $attributeGroupId, $attributeId, $sortOrder);
+            }
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getActionTitle()
+    {
+        return 'Generating attribute sets';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function introduceParamLabels()
+    {
+        return [
+            'attribute_sets' => 'Attribute Sets'
+        ];
+    }
+}
diff --git a/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php b/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php
index 5142efc2da6614cfd6253b02cf7a30b69fc07663..2340de71cf78363ed00fd9248577e7479b6dc012 100644
--- a/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php
+++ b/setup/src/Magento/Setup/Fixtures/ConfigurableProductsFixture.php
@@ -6,19 +6,25 @@
 
 namespace Magento\Setup\Fixtures;
 
-use Magento\Setup\Model\Complex\Generator;
+use Magento\Setup\Model\DataGenerator;
 use Magento\Setup\Model\Complex\Pattern;
+use Magento\Setup\Model\Complex\Generator;
 
 /**
  * Class ConfigurableProductsFixture
  */
-class ConfigurableProductsFixture extends Fixture
+class ConfigurableProductsFixture extends SimpleProductsFixture
 {
     /**
      * @var int
      */
     protected $priority = 50;
 
+    /**
+     * @var array
+     */
+    protected $searchConfig;
+
     //@codingStandardsIgnoreStart
     /**
      * Get CSV template headers
@@ -31,6 +37,7 @@ class ConfigurableProductsFixture extends Fixture
             'sku',
             'store_view_code',
             'attribute_set_code',
+            'additional_attributes',
             'product_type',
             'categories',
             'product_websites',
@@ -137,22 +144,38 @@ class ConfigurableProductsFixture extends Fixture
     }
 
     /**
-     * @param callable $productCategory
-     * @param callable $productWebsite
-     * @param string $variation
+     * @param Closure|mixed $productCategoryClosure
+     * @param Closure|mixed $productWebsiteClosure
+     * @param Closure|mixed $shortDescriptionClosure
+     * @param Closure|mixed $descriptionClosure
+     * @param Closure|mixed $priceClosure
+     * @param Closure|mixed $attributeSetClosure
+     * @param Closure|mixed $additionalAttributesClosure
+     * @param string $variationClosure
      * @param string $suffix
      * @return array
      * @SuppressWarnings(PHPMD)
      */
-    private function generateConfigurableProduct($productCategory, $productWebsite, $variation, $suffix)
+    private function generateConfigurableProduct(
+        $productCategoryClosure,
+        $productWebsiteClosure,
+        $shortDescriptionClosure,
+        $descriptionClosure,
+        $priceClosure,
+        $attributeSetClosure,
+        $additionalAttributesClosure,
+        $variationClosure,
+        $suffix
+    )
     {
         return [
             'sku' => 'Configurable Product %s' . $suffix,
             'store_view_code' => '',
-            'attribute_set_code' => 'Default',
+            'attribute_set_code' => $attributeSetClosure,
+            'additional_attributes' => $additionalAttributesClosure,
             'product_type' => 'configurable',
-            'categories' => $productCategory,
-            'product_websites' => $productWebsite,
+            'categories' => $productCategoryClosure,
+            'product_websites' => $productWebsiteClosure,
             'color' => '',
             'configurable_variation' => '',
             'cost' => '',
@@ -162,7 +185,7 @@ class ConfigurableProductsFixture extends Fixture
             'custom_design_from' => '',
             'custom_design_to' => '',
             'custom_layout_update' => '',
-            'description' => '<p>Configurable product description %s</p>',
+            'description' => $descriptionClosure,
             'enable_googlecheckout' => '1',
             'gallery' => '',
             'gift_message_available' => '',
@@ -184,12 +207,12 @@ class ConfigurableProductsFixture extends Fixture
             'news_to_date' => '',
             'options_container' => 'Block after Info Column',
             'page_layout' => '',
-            'price' => '10',
+            'price' => $priceClosure,
             'quantity_and_stock_status' => 'In Stock',
             'related_tgtr_position_behavior' => '',
             'related_tgtr_position_limit' => '',
             'required_options' => '1',
-            'short_description' => '',
+            'short_description' => $shortDescriptionClosure,
             'small_image' => '',
             'small_image_label' => '',
             'special_from_date' => '',
@@ -244,32 +267,51 @@ class ConfigurableProductsFixture extends Fixture
             '_media_label' => '',
             '_media_position' => '',
             '_media_is_disabled' => '',
-            'configurable_variations' => $variation,
+            'configurable_variations' => $variationClosure,
         ];
     }
 
     /**
      * Get CSV template rows
      *
-     * @param Closure|mixed $productCategory
-     * @param Closure|mixed $productWebsite
+     * @param Closure|mixed $productCategoryClosure
+     * @param Closure|mixed $productWebsiteClosure
+     * @param Closure|mixed $shortDescriptionClosure
+     * @param Closure|mixed $descriptionClosure
+     * @param Closure|mixed $priceClosure
+     * @param Closure|mixed $attributeSetClosure
+     * @param Closure|mixed $additionalAttributesClosure
+     * @param Closure|mixed $variationClosure
+     * @param int $optionsNumber
+     * @param string $suffix
      *
      * @SuppressWarnings(PHPMD)
      *
      * @return array
      */
-    protected function getRows($productCategory, $productWebsite, $optionsNumber, $suffix = '')
+    protected function getRows(
+        $productCategoryClosure,
+        $productWebsiteClosure,
+        $shortDescriptionClosure,
+        $descriptionClosure,
+        $priceClosure,
+        $attributeSetClosure,
+        $additionalAttributesClosure,
+        $variationClosure,
+        $optionsNumber,
+        $suffix = ''
+    )
     {
         $data = [];
-        $variation = [];
         for ($i = 1; $i <= $optionsNumber; $i++) {
             $productData = [
                 'sku' => "Configurable Product %s-option {$i}{$suffix}",
                 'store_view_code' => '',
-                'attribute_set_code' => 'Default',
+                'attribute_set_code' => $attributeSetClosure,
+                'additional_attributes' => $additionalAttributesClosure,
                 'product_type' => 'simple',
-                'categories' => $productCategory,
-                'product_websites' => $productWebsite,
+                'categories' => $productCategoryClosure,
+                'product_websites' => $productWebsiteClosure,
                 'color' => '',
                 'configurable_variation' => "option {$i}",
                 'cost' => '',
@@ -279,7 +321,7 @@ class ConfigurableProductsFixture extends Fixture
                 'custom_design_from' => '',
                 'custom_design_to' => '',
                 'custom_layout_update' => '',
-                'description' => '<p>Configurable product description %s</p>',
+                'description' => $descriptionClosure,
                 'enable_googlecheckout' => '1',
                 'gallery' => '',
                 'gift_message_available' => '',
@@ -301,12 +343,12 @@ class ConfigurableProductsFixture extends Fixture
                 'news_to_date' => '',
                 'options_container' => 'Block after Info Column',
                 'page_layout' => '',
-                'price' => function () { return mt_rand(1, 1000) / 10; },
+                'price' => $priceClosure,
                 'quantity_and_stock_status' => 'In Stock',
                 'related_tgtr_position_behavior' => '',
                 'related_tgtr_position_limit' => '',
                 'required_options' => '0',
-                'short_description' => '',
+                'short_description' => $shortDescriptionClosure,
                 'small_image' => '',
                 'small_image_label' => '',
                 'special_from_date' => '',
@@ -366,21 +408,18 @@ class ConfigurableProductsFixture extends Fixture
                 '_media_position' => '',
                 '_media_is_disabled' => '',
             ];
-
-            $variation[] = implode(
-                ',',
-                [
-                    'sku=' . $productData['sku'],
-                    'configurable_variation=' . $productData['configurable_variation'],
-                ]
-            );
             $data[] = $productData;
         }
 
         $data[] = $this->generateConfigurableProduct(
-            $productCategory,
-            $productWebsite,
-            implode('|', $variation),
+            $productCategoryClosure,
+            $productWebsiteClosure,
+            $shortDescriptionClosure,
+            $descriptionClosure,
+            $priceClosure,
+            $attributeSetClosure,
+            $additionalAttributesClosure,
+            $variationClosure,
             $suffix
         );
         return $data;
@@ -388,26 +427,141 @@ class ConfigurableProductsFixture extends Fixture
 
     /**
      * {@inheritdoc}
+     * @SuppressWarnings(PHPMD)
      */
     public function execute()
     {
-        $configurableCount = $this->fixtureModel->getValue('configurable_products', 0);
-        if (!$configurableCount) {
+        $configurableProductsCount = $this->fixtureModel->getValue('configurable_products', 0);
+        if (!$configurableProductsCount) {
             return;
         }
-        $this->fixtureModel->resetObjectManager();
+        $simpleProductsCount = $this->fixtureModel->getValue('simple_products', 0);
+        $maxAmountOfWordsDescription = $this->getSearchConfigValue('max_amount_of_words_description');
+        $maxAmountOfWordsShortDescription = $this->getSearchConfigValue('max_amount_of_words_short_description');
+        $minAmountOfWordsDescription = $this->getSearchConfigValue('min_amount_of_words_description');
+        $minAmountOfWordsShortDescription = $this->getSearchConfigValue('min_amount_of_words_short_description');
 
+        $attributes = $this->getAttributes();
+        $searchTerms = $this->getSearchTerms();
+        $this->fixtureModel->resetObjectManager();
         $result = $this->getCategoriesAndWebsites();
-
+        $variationCount = $this->fixtureModel->getValue('configurable_products_variation', 3);
         $result = array_values($result);
+        $dataGenerator = new DataGenerator(realpath(__DIR__ . '/' . 'dictionary.csv'));
 
-        $productWebsite = function ($index) use ($result) {
+        $productWebsiteClosure = function ($index) use ($result) {
             return $result[$index % count($result)][0];
         };
-        $productCategory = function ($index) use ($result) {
+        $productCategoryClosure = function ($index) use ($result) {
             return $result[$index % count($result)][2] . '/' . $result[$index % count($result)][1];
         };
-
+        $shortDescriptionClosure = function ($index)
+        use (
+            $searchTerms,
+            $simpleProductsCount,
+            $configurableProductsCount,
+            $dataGenerator,
+            $maxAmountOfWordsShortDescription,
+            $minAmountOfWordsShortDescription
+        )
+        {
+            $count = $searchTerms === null
+                ? 0
+                : round(
+                    $searchTerms[$index % count($searchTerms)]['count'] * (
+                        $configurableProductsCount / ($simpleProductsCount + $configurableProductsCount)
+                    )
+                );
+            mt_srand($index);
+            return $dataGenerator->generate(
+                $minAmountOfWordsShortDescription,
+                $maxAmountOfWordsShortDescription,
+                'shortDescription-' . $index
+            ) . ($index <= ($count * count($searchTerms)) ? ' '
+                . $searchTerms[$index % count($searchTerms)]['term'] : '');
+        };
+        $descriptionClosure = function ($index)
+        use (
+            $searchTerms,
+            $simpleProductsCount,
+            $configurableProductsCount,
+            $dataGenerator,
+            $maxAmountOfWordsDescription,
+            $minAmountOfWordsDescription
+        )
+        {
+            $count = $searchTerms === null
+                ? 0
+                : round(
+                    $searchTerms[$index % count($searchTerms)]['count'] * (
+                        $configurableProductsCount / ($simpleProductsCount + $configurableProductsCount)
+                    )
+                );
+            mt_srand($index);
+            return $dataGenerator->generate(
+                $minAmountOfWordsDescription,
+                $maxAmountOfWordsDescription,
+                'description-' . $index
+            ) . ($index <= ($count * count($searchTerms))
+                ? ' ' . $searchTerms[$index % count($searchTerms)]['term'] : '');
+        };
+        $priceClosure = function($index) {
+            mt_srand($index);
+            switch (mt_rand(0,3)) {
+                case 0: return 9.99;
+                case 1: return 5;
+                case 2: return 1;
+                case 3: return mt_rand(1,10000)/10;
+            }
+        };
+        $attributeSetClosure = function($index) use ($attributes, $result) {
+            mt_srand($index);
+            $attributeSet =  (count(array_keys($attributes)) > (($index - 1) % count($result))
+                ? array_keys($attributes)[mt_rand(0, count(array_keys($attributes)) - 1)] : 'Default');
+            return $attributeSet;
+        };
+        $variationClosure = function($index, $variationIndex) use ($attributes, $result, $variationCount) {
+            mt_srand($index);
+            $attributeSetCode = (count(array_keys($attributes)) > (($index - 1) % count($result))
+                ? array_keys($attributes)[mt_rand(0, count(array_keys($attributes)) - 1)] : 'Default');
+            $skus = [];
+            for ($i=1; $i <= $variationCount; $i++) {
+                $skus[] = 'sku=Configurable Product ' . $index . '-option ' . $i;
+            }
+            $values = [];
+            if ($attributeSetCode == 'Default') {
+                for ($i=1; $i <= $variationCount; $i++) {
+                    $values[] =  'configurable_variation=option ' . $i;
+                }
+            } else {
+                for ($i=$variationCount; $i > 0; $i--) {
+                    $attributeValues = '';
+                    foreach ($attributes[$attributeSetCode] as $attribute) {
+                        $attributeValues = $attributeValues . $attribute['name'] . "=" .
+                            $attribute['values'][($variationIndex - $i) % count($attribute['values'])] . ",";
+                    }
+                    $values [] = $attributeValues;
+                }
+            }
+            $variations = [];
+            for ($i=0; $i < $variationCount; $i++) {
+                $variations[] = trim(implode(",",[$skus[$i],$values[$i]]), ",");
+            }
+            return implode("|",$variations);
+        };
+        $additionalAttributesClosure = function($index, $variationIndex) use ($attributes, $result) {
+            $attributeValues = '';
+            mt_srand($index);
+            $attributeSetCode = (count(array_keys($attributes)) > (($index - 1) % count($result))
+                ? array_keys($attributes)[mt_rand(0, count(array_keys($attributes)) - 1)] : 'Default');
+            if ($attributeSetCode !== 'Default' ) {
+                foreach ($attributes[$attributeSetCode] as $attribute) {
+                    $attributeValues = $attributeValues . $attribute['name'] . "=" .
+                        $attribute['values'][$variationIndex %  count($attribute['values'])] . ",";
+                }
+            }
+            return trim($attributeValues, ",");
+        };
         /**
          * Create configurable products
          */
@@ -415,9 +569,15 @@ class ConfigurableProductsFixture extends Fixture
         $pattern->setHeaders($this->getHeaders());
         $pattern->setRowsSet(
             $this->getRows(
-                $productCategory,
-                $productWebsite,
-                $this->fixtureModel->getValue('configurable_products_variation', 3)
+                $productCategoryClosure,
+                $productWebsiteClosure,
+                $shortDescriptionClosure,
+                $descriptionClosure,
+                $priceClosure,
+                $attributeSetClosure,
+                $additionalAttributesClosure,
+                $variationClosure,
+                $variationCount
             )
         );
 
@@ -435,7 +595,7 @@ class ConfigurableProductsFixture extends Fixture
 
         $source = $this->fixtureModel->getObjectManager()->create(
             Generator::class,
-            ['rowPattern' => $pattern, 'count' => $configurableCount]
+            ['rowPattern' => $pattern, 'count' => $configurableProductsCount]
         );
         // it is not obvious, but the validateSource() will actually save import queue data to DB
         if (!$import->validateSource($source)) {
@@ -467,9 +627,10 @@ class ConfigurableProductsFixture extends Fixture
     }
 
     /**
+     * @override
      * @return array
      */
-    private function getCategoriesAndWebsites()
+    protected function getCategoriesAndWebsites()
     {
         /** @var \Magento\Store\Model\StoreManager $storeManager */
         $storeManager = $this->fixtureModel->getObjectManager()->get(\Magento\Store\Model\StoreManager::class);
diff --git a/setup/src/Magento/Setup/Fixtures/FixtureModel.php b/setup/src/Magento/Setup/Fixtures/FixtureModel.php
index 118b29cb4306bb6e05580eea3bc0da207a72835d..44173a32c3e771ec2c43480a73c380ad2a2691ab 100644
--- a/setup/src/Magento/Setup/Fixtures/FixtureModel.php
+++ b/setup/src/Magento/Setup/Fixtures/FixtureModel.php
@@ -206,7 +206,9 @@ class FixtureModel
         if (!is_readable($filename)) {
             throw new \Exception("Profile configuration file `{$filename}` is not readable or does not exists.");
         }
-        $this->config = $this->fileParser->load($filename)->xmlToArray();
+        $this->fileParser->getDom()->load($filename);
+        $this->fileParser->getDom()->xinclude();
+        $this->config = $this->fileParser->xmlToArray();
     }
 
     /**
diff --git a/setup/src/Magento/Setup/Fixtures/SimpleProductsFixture.php b/setup/src/Magento/Setup/Fixtures/SimpleProductsFixture.php
index 6de4eaf91529fb3bc12cffe4d78aba238bc2fc05..fbb28d35269b177762410e8da7560612dd64db9c 100644
--- a/setup/src/Magento/Setup/Fixtures/SimpleProductsFixture.php
+++ b/setup/src/Magento/Setup/Fixtures/SimpleProductsFixture.php
@@ -6,6 +6,7 @@
 
 namespace Magento\Setup\Fixtures;
 
+use Magento\Setup\Model\DataGenerator;
 use Magento\Setup\Model\Generator;
 
 /**
@@ -18,8 +19,14 @@ class SimpleProductsFixture extends Fixture
      */
     protected $priority = 30;
 
+    /**
+     * @var array
+     */
+    protected $searchConfig;
+
     /**
      * {@inheritdoc}
+     * @SuppressWarnings(PHPMD)
      */
     public function execute()
     {
@@ -27,48 +34,16 @@ class SimpleProductsFixture extends Fixture
         if (!$simpleProductsCount) {
             return;
         }
+        $configurableProductsCount = $this->fixtureModel->getValue('configurable_products', 0);
+        $maxAmountOfWordsDescription = $this->getSearchConfigValue('max_amount_of_words_description');
+        $maxAmountOfWordsShortDescription = $this->getSearchConfigValue('max_amount_of_words_short_description');
+        $minAmountOfWordsDescription = $this->getSearchConfigValue('min_amount_of_words_description');
+        $minAmountOfWordsShortDescription = $this->getSearchConfigValue('min_amount_of_words_short_description');
+        $searchTerms = $this->getSearchTerms();
+        $attributes = $this->getAttributes();
         $this->fixtureModel->resetObjectManager();
-
-        /** @var \Magento\Store\Model\StoreManager $storeManager */
-        $storeManager = $this->fixtureModel->getObjectManager()->create(\Magento\Store\Model\StoreManager::class);
-        /** @var $category \Magento\Catalog\Model\Category */
-        $category = $this->fixtureModel->getObjectManager()->get(\Magento\Catalog\Model\Category::class);
-
-        $result = [];
-        //Get all websites
-        $websites = $storeManager->getWebsites();
-        foreach ($websites as $website) {
-            $websiteCode = $website->getCode();
-            //Get all groups
-            $websiteGroups = $website->getGroups();
-            foreach ($websiteGroups as $websiteGroup) {
-                $websiteGroupRootCategory = $websiteGroup->getRootCategoryId();
-                $category->load($websiteGroupRootCategory);
-                $categoryResource = $category->getResource();
-                //Get all categories
-                $resultsCategories = $categoryResource->getAllChildren($category);
-                foreach ($resultsCategories as $resultsCategory) {
-                    $category->load($resultsCategory);
-                    $structure = explode('/', $category->getPath());
-                    $pathSize  = count($structure);
-                    if ($pathSize > 1) {
-                        $path = [];
-                        for ($i = 0; $i < $pathSize; $i++) {
-                            $path[] = $category->load($structure[$i])->getName();
-                        }
-                        array_shift($path);
-                        $resultsCategoryName = implode('/', $path);
-                    } else {
-                        $resultsCategoryName = $category->getName();
-                    }
-                    //Deleted root categories
-                    if (trim($resultsCategoryName) != '') {
-                        $result[$resultsCategory] = [$websiteCode, $resultsCategoryName];
-                    }
-                }
-            }
-        }
-        $result = array_values($result);
+        $result = $this->getCategoriesAndWebsites();
+        $dataGenerator = new DataGenerator(realpath(__DIR__ . '/' . 'dictionary.csv'));
 
         $productWebsite = function ($index) use ($result) {
             return $result[$index % count($result)][0];
@@ -76,10 +51,92 @@ class SimpleProductsFixture extends Fixture
         $productCategory = function ($index) use ($result) {
             return $result[$index % count($result)][1];
         };
-
-        $generator = new Generator(
-            $this->getPattern($productWebsite, $productCategory),
-            $simpleProductsCount
+        $shortDescription = function ($index) use (
+            $searchTerms,
+            $simpleProductsCount,
+            $configurableProductsCount,
+            $dataGenerator,
+            $maxAmountOfWordsShortDescription,
+            $minAmountOfWordsShortDescription
+        ) {
+            $count = $searchTerms === null
+                ? 0
+                : round(
+                    $searchTerms[$index % count($searchTerms)]['count'] * (
+                        $simpleProductsCount / ($simpleProductsCount + $configurableProductsCount)
+                    )
+                );
+            return $dataGenerator->generate(
+                $minAmountOfWordsShortDescription,
+                $maxAmountOfWordsShortDescription
+            ) . ($index <= ($count * count($searchTerms)) ? ' '
+                . $searchTerms[$index % count($searchTerms)]['term'] : '');
+        };
+        $description = function ($index) use (
+            $searchTerms,
+            $simpleProductsCount,
+            $configurableProductsCount,
+            $dataGenerator,
+            $maxAmountOfWordsDescription,
+            $minAmountOfWordsDescription
+        ) {
+            $count = $searchTerms === null
+                ? 0
+                : round(
+                    $searchTerms[$index % count($searchTerms)]['count'] * (
+                        $simpleProductsCount / ($simpleProductsCount + $configurableProductsCount)
+                    )
+                );
+            return $dataGenerator->generate(
+                $minAmountOfWordsDescription,
+                $maxAmountOfWordsDescription
+            ) . ($index <= ($count * count($searchTerms)) ? ' '
+                . $searchTerms[$index % count($searchTerms)]['term'] : '');
+        };
+        $price = function () {
+            switch (mt_rand(0, 3)) {
+                case 0:
+                    return 9.99;
+                case 1:
+                    return 5;
+                case 2:
+                    return 1;
+                case 3:
+                    return mt_rand(1, 10000)/10;
+            }
+        };
+        $attributeSet = function ($index) use ($attributes, $result) {
+            mt_srand($index);
+            return (count(array_keys($attributes)) > (($index - 1) % count($result))
+                ? array_keys($attributes)[mt_rand(0, count(array_keys($attributes)) - 1)] : 'Default');
+        };
+        $additionalAttributes = function ($index) use ($attributes, $result) {
+            $attributeValues = '';
+            mt_srand($index);
+            $attributeSetCode = (count(array_keys($attributes)) > (($index - 1) % count($result))
+                ? array_keys($attributes)[mt_rand(0, count(array_keys($attributes)) - 1)] : 'Default');
+            if ($attributeSetCode !== 'Default') {
+                foreach ($attributes[$attributeSetCode] as $attribute) {
+                    $attributeValues = $attributeValues . $attribute['name'] . "=" .
+                        $attribute['values'][mt_rand(0, count($attribute['values']) - 1)] . ",";
+                }
+            }
+            return trim($attributeValues, ",");
+        };
+        $generator = $this->fixtureModel->getObjectManager()->create(
+            Generator::class,
+            [
+                'rowPattern' => $this->getPattern(
+                    $productWebsite,
+                    $productCategory,
+                    $shortDescription,
+                    $description,
+                    $price,
+                    $attributeSet,
+                    $additionalAttributes
+                ),
+                'limit' => $simpleProductsCount
+            ]
         );
         /** @var \Magento\ImportExport\Model\Import $import */
         $import = $this->fixtureModel->getObjectManager()->create(
@@ -93,9 +150,13 @@ class SimpleProductsFixture extends Fixture
             ]
         );
         // it is not obvious, but the validateSource() will actually save import queue data to DB
-        $import->validateSource($generator);
+        if (!$import->validateSource($generator)) {
+            throw new \Exception($import->getFormatedLogTrace());
+        }
         // this converts import queue into actual entities
-        $import->importSource();
+        if (!$import->importSource()) {
+            throw new \Exception($import->getFormatedLogTrace());
+        }
     }
 
     /**
@@ -103,21 +164,34 @@ class SimpleProductsFixture extends Fixture
      *
      * @param Closure|int|string $productWebsiteClosure
      * @param Closure|int|string $productCategoryClosure
+     * @param Closure|int|string $shortDescriptionClosure
+     * @param Closure|int|string $descriptionClosure
+     * @param Closure|int|string $priceClosure
+     * @param Closure|int|string $attributeSetClosure
+     * @param Closure|int|string $additionalAttributesClosure
      * @return array
      */
-    protected function getPattern($productWebsiteClosure, $productCategoryClosure)
-    {
+    protected function getPattern(
+        $productWebsiteClosure,
+        $productCategoryClosure,
+        $shortDescriptionClosure,
+        $descriptionClosure,
+        $priceClosure,
+        $attributeSetClosure,
+        $additionalAttributesClosure
+    ) {
         return [
-            'attribute_set_code'    => 'Default',
+            'attribute_set_code'    => $attributeSetClosure,
+            'additional_attributes' => $additionalAttributesClosure,
             'product_type'             => \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE,
             'product_websites' => $productWebsiteClosure,
             'categories'         => $productCategoryClosure,
             'name'              => 'Simple Product %s',
-            'short_description' => 'Short simple product description %s',
+            'short_description' => $shortDescriptionClosure,
             'weight'            => 1,
-            'description'       => 'Full simple product Description %s',
+            'description'       => $descriptionClosure,
             'sku'               => 'product_dynamic_%s',
-            'price'             => 10,
+            'price'             => $priceClosure,
             'visibility'        => 'Catalog, Search',
             'product_online'            => \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED,
             'tax_class_name'      => 'Taxable Goods',
@@ -155,4 +229,112 @@ class SimpleProductsFixture extends Fixture
             'simple_products' => 'Simple products'
         ];
     }
+
+    /**
+     * @return array
+     */
+    protected function getAttributes()
+    {
+        $attributeSets = $this->fixtureModel->getValue('attribute_sets', null);
+        $attributes = [];
+
+        if ($attributeSets !== null && array_key_exists('attribute_set', $attributeSets)) {
+            foreach ($attributeSets['attribute_set'] as $attributeSet) {
+                $attributesData = array_key_exists(0, $attributeSet['attributes']['attribute'])
+                    ? $attributeSet['attributes']['attribute'] : [$attributeSet['attributes']['attribute']];
+                foreach ($attributesData as $attributeData) {
+                    $values = [];
+                    $optionsData = array_key_exists(0, $attributeData['options']['option'])
+                        ? $attributeData['options']['option'] : [$attributeData['options']['option']];
+                    foreach ($optionsData as $optionData) {
+                        $values[] = $optionData['label'];
+                    }
+                    $attributes[$attributeSet['name']][] =
+                        ['name' => $attributeData['attribute_code'], 'values' => $values];
+                }
+            }
+        }
+        return $attributes;
+    }
+
+    /**
+     * @return array
+     */
+    protected function getCategoriesAndWebsites()
+    {
+        /** @var \Magento\Store\Model\StoreManager $storeManager */
+        $storeManager = $this->fixtureModel->getObjectManager()->create(\Magento\Store\Model\StoreManager::class);
+        /** @var $category \Magento\Catalog\Model\Category */
+        $category = $this->fixtureModel->getObjectManager()->get(\Magento\Catalog\Model\Category::class);
+
+        $result = [];
+        //Get all websites
+        $websites = $storeManager->getWebsites();
+        foreach ($websites as $website) {
+            $websiteCode = $website->getCode();
+            //Get all groups
+            $websiteGroups = $website->getGroups();
+            foreach ($websiteGroups as $websiteGroup) {
+                $websiteGroupRootCategory = $websiteGroup->getRootCategoryId();
+                $category->load($websiteGroupRootCategory);
+                $categoryResource = $category->getResource();
+                //Get all categories
+                $resultsCategories = $categoryResource->getAllChildren($category);
+                foreach ($resultsCategories as $resultsCategory) {
+                    $category->load($resultsCategory);
+                    $structure = explode('/', $category->getPath());
+                    $pathSize  = count($structure);
+                    if ($pathSize > 1) {
+                        $path = [];
+                        for ($i = 0; $i < $pathSize; $i++) {
+                            $path[] = $category->load($structure[$i])->getName();
+                        }
+                        array_shift($path);
+                        $resultsCategoryName = implode('/', $path);
+                    } else {
+                        $resultsCategoryName = $category->getName();
+                    }
+                    //Deleted root categories
+                    if (trim($resultsCategoryName) != '') {
+                        $result[$resultsCategory] = [$websiteCode, $resultsCategoryName];
+                    }
+                }
+            }
+        }
+        return array_values($result);
+    }
+
+    /**
+     * @return array
+     */
+    protected function getSearchConfig()
+    {
+        if (!$this->searchConfig) {
+            $this->searchConfig = $this->fixtureModel->getValue('search_config', null);
+        }
+        return $this->searchConfig;
+    }
+
+    /**
+     * @param string $name
+     * @return int|mixed
+     */
+    protected function getSearchConfigValue($name)
+    {
+        return $this->getSearchConfig() === null
+            ? 0 : ($this->getSearchConfig()[$name] === null ? 0: $this->getSearchConfig()[$name]);
+    }
+
+    /**
+     * @return array
+     */
+    protected function getSearchTerms()
+    {
+        $searchTerms = $this->fixtureModel->getValue('search_terms', null);
+        if ($searchTerms !== null) {
+            $searchTerms = array_key_exists(0, $searchTerms['search_term'])
+                ? $searchTerms['search_term'] : [$searchTerms['search_term']];
+        }
+        return $searchTerms;
+    }
 }
diff --git a/setup/src/Magento/Setup/Fixtures/dictionary.csv b/setup/src/Magento/Setup/Fixtures/dictionary.csv
new file mode 100644
index 0000000000000000000000000000000000000000..c839b7c46f51c25b1cda3afe4bfb7466e4ef082e
--- /dev/null
+++ b/setup/src/Magento/Setup/Fixtures/dictionary.csv
@@ -0,0 +1,7373 @@
+the
+of
+and
+a
+in
+to
+it
+is
+to
+was
+I
+for
+that
+you
+he
+be
+with
+on
+by
+at
+have
+are
+not
+this
+but
+had
+they
+his
+from
+she
+that
+which
+or
+we
+an
+were
+as
+do
+been
+their
+has
+would
+there
+what
+will
+all
+if
+can
+her
+said
+who
+one
+so
+up
+as
+them
+some
+when
+could
+him
+into
+its
+then
+two
+out
+time
+my
+about
+did
+your
+now
+me
+no
+other
+only
+just
+more
+these
+also
+people
+know
+any
+first
+see
+very
+new
+may
+well
+should
+like
+than
+how
+get
+way
+one
+our
+made
+got
+after
+think
+between
+many
+years
+er
+those
+go
+being
+because
+down
+yeah
+three
+good
+back
+make
+such
+on
+there
+through
+year
+over
+must
+still
+even
+take
+too
+more
+here
+own
+come
+last
+does
+oh
+say
+no
+going
+work
+where
+erm
+us
+government
+same
+man
+might
+day
+yes
+however
+put
+world
+over
+another
+in
+want
+as
+life
+most
+against
+again
+never
+under
+old
+much
+something
+Mr
+why
+each
+while
+house
+part
+number
+found
+off
+different
+went
+really
+thought
+came
+used
+children
+always
+four
+where
+without
+give
+few
+within
+about
+system
+local
+place
+great
+during
+although
+small
+before
+look
+next
+when
+case
+end
+things
+social
+most
+find
+group
+quite
+mean
+five
+party
+every
+company
+women
+says
+important
+took
+much
+men
+information
+both
+national
+often
+seen
+given
+school
+fact
+money
+told
+away
+high
+point
+night
+state
+business
+second
+British
+need
+taken
+done
+right
+having
+thing
+looked
+London
+area
+perhaps
+head
+water
+right
+family
+long
+hand
+like
+already
+possible
+nothing
+yet
+large
+left
+side
+asked
+set
+whether
+days
+mm
+home
+called
+John
+development
+week
+use
+country
+power
+later
+almost
+young
+council
+himself
+far
+both
+use
+room
+together
+tell
+little
+political
+before
+able
+become
+six
+general
+service
+eyes
+members
+since
+times
+problem
+anything
+market
+towards
+court
+public
+others
+face
+full
+doing
+war
+car
+felt
+police
+keep
+held
+problems
+road
+probably
+help
+interest
+available
+law
+best
+form
+looking
+early
+making
+today
+mother
+saw
+knew
+education
+work
+actually
+policy
+ever
+so
+at least
+office
+am
+research
+feel
+big
+body
+door
+let
+Britain
+name
+person
+services
+months
+report
+question
+using
+health
+turned
+lot
+million
+main
+though
+words
+enough
+child
+less
+book
+period
+until
+several
+sure
+father
+level
+control
+known
+society
+major
+seemed
+around
+began
+itself
+themselves
+minister
+economic
+wanted
+upon
+areas
+after
+therefore
+woman
+England
+city
+community
+only
+including
+centre
+gave
+job
+among
+position
+effect
+likely
+real
+clear
+staff
+black
+kind
+read
+provide
+particular
+became
+line
+moment
+international
+action
+special
+difficult
+certain
+particularly
+either
+open
+management
+taking
+across
+idea
+further
+whole
+age
+process
+act
+around
+evidence
+view
+better
+off
+mind
+sense
+rather
+seems
+believe
+morning
+third
+else
+half
+white
+death
+sometimes
+thus
+brought
+getting
+ten
+shall
+try
+behind
+heard
+table
+change
+support
+back
+sort
+Mrs
+whose
+industry
+ago
+free
+care
+order
+century
+range
+European
+gone
+yesterday
+training
+working
+ask
+street
+home
+word
+groups
+history
+central
+all
+study
+usually
+remember
+trade
+hundred
+programme
+food
+committee
+air
+hours
+experience
+rate
+hands
+indeed
+sir
+language
+land
+result
+course
+someone
+everything
+certainly
+based
+team
+section
+leave
+trying
+coming
+similar
+once
+minutes
+authority
+human
+changes
+little
+cases
+common
+role
+Europe
+necessary
+nature
+class
+reason
+long
+saying
+town
+show
+subject
+voice
+companies
+since
+simply
+especially
+department
+single
+short
+personal
+pay
+value
+member
+started
+run
+patients
+paper
+private
+seven
+UK
+eight
+systems
+herself
+practice
+wife
+price
+type
+seem
+figure
+former
+lost
+right
+need
+matter
+decision
+bank
+countries
+until
+makes
+union
+terms
+financial
+needed
+south
+university
+club
+president
+friend
+parents
+quality
+cos
+building
+north
+stage
+meeting
+foreign
+soon
+strong
+situation
+comes
+late
+bed
+recent
+date
+low
+US
+concerned
+girl
+hard
+American
+David
+according to
+twenty
+higher
+tax
+production
+various
+understand
+led
+bring
+schools
+ground
+conditions
+secretary
+weeks
+clearly
+bad
+art
+start
+include
+poor
+hospital
+friends
+decided
+shown
+music
+month
+English
+tried
+game
+1990
+May
+anyone
+wrong
+ways
+chapter
+followed
+cost
+play
+present
+love
+issue
+goes
+described
+award
+Mr.
+king
+royal
+results
+workers
+April
+expected
+amount
+students
+despite
+knowledge
+June
+moved
+news
+light
+March
+approach
+cut
+basis
+hair
+required
+further
+paid
+series
+better
+before
+field
+allowed
+easy
+kept
+questions
+natural
+live
+future
+rest
+project
+greater
+feet
+meet
+simple
+died
+for
+happened
+added
+manager
+computer
+security
+near
+met
+evening
+means
+round
+carried
+hear
+bit
+heart
+forward
+sent
+above
+attention
+labour
+story
+structure
+move
+agreed
+nine
+letter
+individual
+force
+studies
+movement
+account
+per
+call
+board
+success
+1989
+French
+following
+considered
+current
+everyone
+fire
+agreement
+please
+boy
+capital
+stood
+analysis
+whatever
+population
+modern
+theory
+books
+stop
+legal
+Scotland
+material
+son
+received
+model
+chance
+environment
+finally
+performance
+sea
+rights
+growth
+authorities
+provided
+nice
+whom
+produced
+relationship
+talk
+turn
+built
+final
+east
+1991
+talking
+fine
+worked
+west
+parties
+size
+record
+red
+close
+property
+myself
+example
+space
+giving
+normal
+nor
+reached
+buy
+serious
+quickly
+Peter
+along
+plan
+behaviour
+France
+recently
+term
+previous
+couple
+included
+pounds
+anyway
+cup
+treatment
+energy
+total
+thank
+director
+prime
+levels
+significant
+issues
+sat
+income
+top
+choice
+costs
+design
+pressure
+scheme
+July
+change
+a bit
+list
+suddenly
+continue
+technology
+hall
+takes
+ones
+details
+happy
+consider
+won
+defence
+following
+parts
+loss
+industrial
+activities
+throughout
+spent
+outside
+teachers
+generally
+opened
+floor
+round
+activity
+hope
+points
+association
+nearly
+United
+allow
+rates
+sun
+army
+sorry
+wall
+hotel
+forces
+contract
+dead
+Paul
+stay
+reported
+as well
+hour
+difference
+meant
+summer
+county
+specific
+numbers
+wide
+appropriate
+husband
+top
+played
+relations
+Dr
+figures
+chairman
+set
+lower
+product
+colour
+ideas
+George
+St
+look
+arms
+obviously
+unless
+produce
+changed
+season
+developed
+unit
+appear
+investment
+test
+basic
+write
+village
+reasons
+military
+original
+successful
+garden
+effects
+aware
+yourself
+exactly
+help
+suppose
+showed
+style
+employment
+passed
+appeared
+page
+hold
+suggested
+Germany
+continued
+October
+offered
+products
+popular
+science
+New
+window
+expect
+beyond
+resources
+rules
+professional
+announced
+economy
+picture
+okay
+needs
+doctor
+maybe
+events
+direct
+gives
+advice
+running
+circumstances
+sales
+risk
+interests
+September
+dark
+event
+thousand
+involved
+written
+park
+1988
+returned
+ensure
+America
+fish
+wish
+opportunity
+commission
+1992
+oil
+sound
+ready
+lines
+shop
+looks
+James
+immediately
+worth
+college
+press
+January
+fell
+blood
+goods
+playing
+carry
+less
+film
+prices
+useful
+conference
+operation
+follows
+extent
+designed
+application
+station
+television
+access
+Richard
+response
+degree
+majority
+effective
+established
+wrote
+region
+green
+York
+ah
+western
+traditional
+easily
+cold
+shows
+offer
+though
+statement
+Scottish
+published
+forms
+German
+down
+accept
+miles
+independent
+election
+support
+importance
+lady
+site
+jobs
+needs
+plans
+earth
+earlier
+title
+parliament
+standards
+leaving
+interesting
+houses
+planning
+considerable
+girls
+involved
+Ireland
+increase
+species
+stopped
+concern
+public
+means
+caused
+raised
+through
+glass
+physical
+thought
+Michael
+eye
+left
+heavy
+walked
+daughter
+existing
+competition
+speak
+responsible
+up to
+river
+follow
+software
+complete
+above
+November
+December
+purpose
+mouth
+medical
+responsibility
+Sunday
+Wales
+leader
+tomorrow
+piece
+thirty
+lay
+officer
+task
+blue
+answer
+stand
+thinking
+extra
+highly
+places
+arm
+eventually
+campaign
+ability
+appeal
+whole
+Charles
+skills
+opposition
+remained
+pattern
+method
+miss
+hot
+lead
+source
+bought
+baby
+lack
+once
+bill
+division
+remain
+surface
+older
+charge
+methods
+trouble
+fully
+equipment
+moving
+suggest
+disease
+officers
+past
+peace
+male
+slightly
+demand
+failed
+wants
+attempt
+types
+Christmas
+hit
+post
+policies
+hardly
+ii
+arrived
+compared
+below
+otherwise
+windows
+West
+deal
+directly
+interested
+sale
+like
+firm
+status
+happen
+box
+even if
+teacher
+radio
+provision
+variety
+show
+ran
+sector
+return
+factors
+essential
+direction
+beautiful
+civil
+base
+waiting
+caught
+sit
+develop
+character
+safety
+placed
+past
+completely
+tea
+introduced
+killed
+love
+mum
+context
+fifty
+primary
+animals
+culture
+Oxford
+brother
+obvious
+weight
+discussion
+created
+1987
+future
+other
+start
+States
+none
+sold
+let's
+machine
+afternoon
+knows
+environmental
+fair
+William
+February
+provides
+wait
+league
+trees
+positive
+organisation
+win
+condition
+families
+argument
+Saturday
+learn
+up
+normally
+claimed
+truth
+senior
+kitchen
+works
+add
+lived
+library
+minute
+believed
+enough
+transport
+share
+principle
+create
+agree
+born
+players
+cash
+exchange
+rule
+budget
+turn
+pupils
+nuclear
+sitting
+version
+English
+best
+features
+duty
+annual
+balance
+front
+send
+boys
+presence
+protection
+dog
+courses
+individuals
+matters
+media
+avoid
+influence
+presented
+speaker
+stone
+relevant
+apply
+August
+explain
+deep
+Robert
+1986
+achieved
+slowly
+relatively
+shares
+letters
+finished
+survey
+huge
+accepted
+covered
+review
+Smith
+closed
+form
+marriage
+commercial
+aid
+lives
+collection
+living
+speech
+Africa
+regional
+differences
+benefit
+apparently
+effort
+gets
+executive
+later
+latter
+function
+failure
+return
+chair
+reference
+horse
+becomes
+attack
+reports
+practical
+queen
+subjects
+career
+bar
+official
+text
+appears
+separate
+student
+names
+sell
+holiday
+larger
+cells
+open
+progress
+early
+states
+helped
+visit
+smiled
+stock
+memory
+merely
+studio
+key
+putting
+eat
+opinion
+understanding
+regular
+decisions
+chief
+drawn
+firms
+remains
+facilities
+values
+district
+cars
+due
+mhm
+begin
+managed
+receive
+corner
+image
+edge
+sister
+politics
+expression
+instead
+impact
+quarter
+forced
+inside
+views
+scale
+plant
+race
+ball
+gold
+join
+Henry
+spend
+voice
+alone
+additional
+benefits
+1985
+trust
+for instance
+largely
+advantage
+associated
+increased
+standing
+dad
+foot
+somebody
+pain
+gas
+clothes
+smaller
+aspects
+active
+affairs
+possibly
+increase
+railway
+ended
+feeling
+network
+leaders
+nevertheless
+cause
+half
+powerful
+step
+complex
+joined
+plants
+standard
+holding
+carefully
+length
+mind
+rise
+strength
+crime
+hard
+wind
+Mary
+possibility
+becoming
+damage
+records
+reduce
+examples
+mainly
+credit
+winter
+impossible
+insurance
+explained
+units
+currently
+forest
+formed
+somewhere
+earlier
+beginning
+regarded
+fall
+confidence
+discussed
+speed
+legislation
+mentioned
+along
+pulled
+spoke
+debate
+intended
+bodies
+message
+middle
+plus
+supply
+100
+skin
+Edward
+stuff
+providing
+entirely
+front
+domestic
+require
+proved
+expressed
+treated
+match
+solution
+previously
+tonight
+patient
+actual
+difficulties
+farm
+united
+far
+build
+reach
+proposals
+extremely
+choose
+ministers
+technical
+fresh
+ordinary
+scene
+materials
+museum
+Thomas
+move
+article
+prevent
+achieve
+customers
+includes
+powers
+band
+items
+justice
+play
+animal
+internal
+suggests
+excellent
+face
+rich
+assessment
+save
+phone
+fairly
+football
+watched
+telephone
+steps
+decide
+South
+traffic
+watch
+coffee
+deal
+sources
+past
+buildings
+increasingly
+relief
+distance
+introduction
+forty
+administration
+no
+safe
+applied
+sight
+Mark
+island
+potential
+banks
+housing
+meaning
+existence
+claim
+northern
+enjoy
+reduced
+twelve
+equally
+in front of
+walk
+very
+apart from
+watching
+cultural
+famous
+latest
+users
+TV
+cabinet
+legs
+institutions
+Japan
+measures
+reality
+proper
+video
+worse
+lose
+argued
+train
+spirit
+programmes
+accounts
+trial
+target
+fear
+joint
+doubt
+formal
+unemployment
+prison
+accident
+concept
+limited
+elements
+strange
+served
+papers
+discovered
+conservative
+rock
+cover
+usual
+tree
+smile
+unable
+warm
+surely
+organization
+battle
+proportion
+difficulty
+sides
+refused
+weekend
+construction
+picked
+distribution
+dinner
+wine
+while
+works
+obtained
+exercise
+writing
+asking
+showing
+ahead
+rural
+lovely
+applications
+twice
+factor
+path
+games
+funds
+whereas
+nobody
+shape
+initial
+substantial
+referred
+tend
+seat
+improve
+onto
+thanks
+aircraft
+light
+contact
+quiet
+rain
+background
+identified
+contrast
+officials
+strategy
+average
+master
+forget
+leading
+soft
+reasonable
+seeing
+pound
+grounds
+raise
+immediate
+communication
+client
+Paris
+star
+fourth
+suitable
+determined
+ought
+detail
+everybody
+noted
+equal
+imagine
+appointed
+manner
+homes
+classes
+freedom
+operations
+detailed
+keeping
+selection
+requirements
+pair
+draw
+walls
+talks
+working
+call
+danger
+attitude
+user
+overall
+offer
+female
+relationships
+Edinburgh
+note
+afraid
+pick
+charges
+democratic
+elections
+entered
+courts
+growing
+goal
+straight
+techniques
+sufficient
+middle
+agency
+scientific
+eastern
+crisis
+rose
+correct
+removed
+prince
+theatre
+Irish
+laid
+act
+expensive
+markets
+sign
+educational
+capacity
+telling
+happens
+absolutely
+patterns
+whilst
+managers
+purposes
+employees
+1984
+totally
+opportunities
+cause
+break
+will
+procedure
+feeling
+output
+mental
+frequently
+bridge
+dangerous
+either
+fingers
+recognition
+largest
+turning
+arrangements
+sites
+profits
+quick
+absence
+sentence
+beside
+pass
+fields
+critical
+pointed
+prove
+listen
+inc
+recorded
+cost
+signed
+hill
+dropped
+card
+tour
+understood
+notes
+track
+1983
+partly
+replaced
+increased
+weather
+principles
+seriously
+familiar
+related
+package
+elsewhere
+teaching
+bottom
+necessarily
+commitment
+player
+double
+birds
+properly
+1993
+Jack
+threat
+notice
+unlikely
+admitted
+1981
+replied
+silence
+route
+file
+liked
+supported
+issued
+perfect
+victory
+discuss
+widely
+occur
+second
+violence
+efforts
+element
+neck
+carrying
+conflict
+pieces
+Darlington
+under
+profit
+reaction
+colleagues
+historical
+standard
+end
+Friday
+finance
+hope
+rooms
+projects
+closely
+fund
+daily
+below
+cell
+Liverpool
+Tom
+southern
+expenditure
+increasing
+discipline
+completed
+occurred
+individual
+spring
+audience
+lead
+thousands
+grow
+conversation
+tiny
+congress
+emphasis
+finding
+exist
+check
+alone
+consideration
+speaking
+learning
+defined
+seek
+1979
+appearance
+maintain
+option
+dry
+bright
+urban
+pictures
+estate
+debt
+youth
+neither
+affected
+married
+feature
+payment
+exhibition
+liberal
+supposed
+assembly
+reform
+empty
+boat
+suffered
+bus
+hell
+remembered
+driver
+lunch
+flowers
+heat
+processes
+upper
+volume
+share
+captain
+murder
+North
+fifteen
+represented
+meetings
+contribution
+drugs
+die
+feelings
+outside
+Ian
+arts
+leg
+serve
+dealing
+writing
+curriculum
+bag
+sought
+apparent
+branch
+beginning
+noticed
+procedures
+models
+Martin
+enter
+revealed
+institute
+establish
+object
+occasion
+waste
+facts
+membership
+requires
+shook
+Monday
+claims
+control
+prepared
+younger
+faith
+shops
+challenge
+answer
+Russian
+moral
+pleasure
+orders
+Alan
+heads
+bloody
+careful
+filled
+Corp
+literature
+birth
+1980
+leading
+code
+centres
+broke
+prepared
+that
+professor
+1982
+aye
+wood
+gentleman
+flight
+entry
+pretty
+attractive
+wild
+investigation
+crown
+protect
+nodded
+greatest
+subject to
+functions
+encourage
+belief
+care
+developments
+description
+tradition
+Japanese
+thin
+adopted
+vital
+document
+conclusion
+hoped
+Italy
+enjoyed
+engineering
+coal
+transfer
+address
+breath
+along with
+Ltd
+alternative
+total
+schemes
+copy
+desire
+search
+effectively
+organisations
+demands
+pushed
+visit
+etc
+planning
+farmers
+ancient
+released
+opening
+lips
+iii
+treaty
+newspaper
+aim
+drug
+identify
+engine
+Manchester
+USA
+tests
+owner
+sky
+Tony
+wearing
+depends
+elderly
+ministry
+Australia
+busy
+inside
+anybody
+reading
+external
+capable
+marketing
+streets
+partner
+respect
+shot
+institution
+generation
+acid
+realised
+chosen
+wider
+his
+narrow
+horses
+broad
+ordered
+wonderful
+key
+contained
+laughed
+bringing
+clients
+typical
+drink
+Stephen
+employed
+atmosphere
+slow
+wondered
+clean
+actions
+entire
+troops
+Leeds
+vote
+definition
+welfare
+reduction
+row
+walking
+laws
+visitors
+release
+meanwhile
+confirmed
+examination
+doors
+leadership
+attitudes
+East
+enable
+beneath
+journey
+milk
+stated
+hence
+IBM
+machines
+affect
+grey
+screen
+criticism
+surprise
+reading
+nineteen
+stories
+billion
+constant
+teeth
+brain
+explanation
+brief
+signs
+married
+highest
+cover
+starting
+knowing
+claim
+creation
+castle
+governments
+goals
+intention
+India
+vast
+flat
+guide
+drive
+surprised
+easier
+ideal
+shut
+readers
+run
+Bill
+magazine
+bound
+terrible
+thoughts
+kinds
+academic
+worry
+minor
+seats
+customer
+significance
+measure
+pleased
+unfortunately
+o'clock
+revolution
+attempts
+noise
+charged
+rare
+biggest
+rather than
+somewhat
+sections
+stared
+seeking
+paying
+meeting
+encouraged
+thick
+Jones
+loved
+metal
+grand
+plenty
+note
+phase
+coast
+injury
+China
+granted
+motion
+observed
+technique
+ill
+drew
+potential
+factory
+lying
+severe
+mine
+lights
+wonder
+Harry
+spread
+contains
+strongly
+offers
+afterwards
+committed
+tape
+shoulder
+bear
+corporate
+obtain
+kill
+that is
+worst
+learned
+settlement
+ooh
+grew
+represent
+rapidly
+tall
+hole
+living
+adult
+iron
+amongst
+faced
+negative
+afford
+lots
+index
+permanent
+beat
+trip
+contain
+fundamental
+doctors
+desk
+ourselves
+sport
+unions
+implications
+fashion
+content
+similarly
+elected
+proposed
+judge
+pool
+inflation
+brown
+Brian
+originally
+funny
+via
+practices
+somehow
+payments
+odd
+Andrew
+pension
+pay
+crucial
+fit
+inner
+appointment
+used
+flow
+launched
+Chris
+independence
+Spain
+objects
+setting
+little
+least
+colours
+palace
+perfectly
+combination
+contracts
+criminal
+consequences
+pages
+contemporary
+UN
+talked
+session
+sharp
+structures
+planned
+drive
+Wednesday
+Kingdom
+falling
+sample
+virtually
+fast
+sick
+movements
+dogs
+Anne
+Yorkshire
+Roman
+accommodation
+nation
+temperature
+massive
+societies
+consumer
+cities
+offices
+documents
+valley
+indicated
+breakfast
+stayed
+kids
+display
+named
+bedroom
+sports
+aspect
+unique
+Steve
+sixty
+author
+lane
+objectives
+secondary
+wear
+republic
+agent
+interpretation
+assistance
+directors
+badly
+alright
+parliamentary
+African
+Joe
+unknown
+industries
+assets
+selling
+moreover
+Northern
+nose
+Jim
+Russia
+subsequent
+place
+describe
+declared
+gallery
+allowing
+ship
+other than
+visited
+cross
+grown
+crowd
+recognised
+interview
+broken
+Simon
+argue
+BBC
+naturally
+thinking
+general
+Mike
+meal
+catch
+representatives
+proceedings
+tears
+alive
+involving
+shoulders
+employers
+begun
+departments
+vision
+yours
+unix
+beauty
+guilty
+proposal
+impression
+square
+angry
+regulations
+regions
+vehicle
+Jane
+democracy
+sequence
+offering
+Graham
+enormous
+invited
+cancer
+sheet
+struck
+Glasgow
+rarely
+involve
+involvement
+improvement
+ninety
+motor
+shock
+tone
+significantly
+contact
+manufacturing
+close
+seconds
+dress
+assumed
+well
+quietly
+grass
+nations
+provisions
+communities
+roof
+yellow
+indicate
+distinction
+present
+statements
+comments
+allows
+late
+pollution
+fruit
+acting
+involves
+unusual
+assume
+towns
+lucky
+fuel
+spot
+properties
+touch
+fall
+Major
+bottle
+except
+anywhere
+net
+buying
+long-term
+soil
+sum
+stages
+decline
+missed
+reader
+extensive
+manage
+calling
+talk
+heavily
+containing
+plate
+advertising
+revenue
+remaining
+glad
+diet
+agricultural
+artist
+plastic
+artists
+gently
+Bob
+alright
+location
+ring
+ice
+operate
+lies
+candidates
+Italian
+pull
+passage
+principal
+cope
+linked
+tired
+periods
+firmly
+occasionally
+identity
+persons
+limited
+warned
+efficient
+runs
+hundreds
+maintenance
+divided
+unlike
+establishment
+channel
+producing
+fight
+happening
+song
+map
+expert
+formation
+comfortable
+border
+constitution
+weapons
+emergency
+Chinese
+waited
+continues
+arranged
+link
+Wilson
+spokesman
+extended
+rail
+Philip
+candidate
+believes
+funding
+promised
+positions
+mostly
+household
+remove
+performed
+cat
+sleep
+abroad
+teams
+mountain
+program
+countryside
+stars
+victim
+studied
+relative
+criteria
+conventional
+parish
+framework
+willing
+strike
+cheap
+ref
+sudden
+approval
+concentration
+partners
+autumn
+maintained
+warning
+cards
+roads
+approved
+lake
+starts
+determine
+liability
+editor
+realise
+thinks
+helping
+longer
+proposed
+voluntary
+settled
+grant
+characters
+valuable
+situations
+deputy
+walk
+regularly
+occasions
+trading
+rejected
+agriculture
+premises
+dramatic
+fill
+theme
+silver
+golden
+duties
+friendly
+arguments
+accused
+driving
+losses
+error
+reflected
+dream
+shortly
+wealth
+working
+temporary
+federal
+stress
+painting
+request
+initially
+reflect
+lifted
+eighty
+hello
+pub
+recovery
+loan
+electricity
+1980s
+chest
+Margaret
+refer
+taught
+silent
+Brown
+beach
+Indian
+eleven
+answered
+learning
+recession
+focus
+facing
+video-taped
+height
+clubs
+item
+characteristics
+emerged
+options
+matter
+hurt
+forgotten
+worried
+bread
+admit
+chief
+specifically
+owners
+Lewis
+statutory
+mirror
+agents
+writer
+deeply
+Welsh
+foundation
+struggle
+1978
+parent
+dependent
+mistake
+reputation
+Frank
+eggs
+decade
+steel
+gain
+leads
+publication
+resistance
+offence
+incident
+Thursday
+prefer
+stations
+denied
+examine
+lifespan
+wages
+tasks
+gained
+acquired
+outcome
+claims
+travel
+competitive
+marked
+panel
+resolution
+wished
+dear
+efficiency
+demanded
+flat
+yards
+subsequently
+gradually
+businesses
+chancellor
+chain
+specialist
+1977
+dressed
+tells
+negotiations
+relating
+supporters
+armed
+radical
+sleep
+representation
+agencies
+theories
+outside
+shoes
+threatened
+spending
+keen
+drove
+gardens
+acceptable
+notion
+initiative
+stairs
+Cambridge
+advance
+leaves
+recognise
+worker
+essentially
+empire
+shared
+sensitive
+uses
+clause
+attached
+Taylor
+living
+fallen
+Belfast
+fighting
+dear
+controlled
+sugar
+Elizabeth
+block
+global
+delivery
+changing
+Lee
+computers
+ages
+meat
+mass
+emotional
+brothers
+bird
+expansion
+islands
+healthy
+Middlesbrough
+aside
+attend
+secret
+store
+1976
+break
+writers
+self
+rising
+travel
+bigger
+alternative
+rapid
+instructions
+wet
+adequate
+weak
+licence
+fixed
+soldiers
+examined
+aimed
+owned
+average
+awareness
+centuries
+images
+drama
+notice
+Tuesday
+handed
+furniture
+gate
+scientists
+administrative
+sees
+pocket
+wooden
+uncle
+remarkable
+co-operation
+creating
+Adam
+Luke
+newspapers
+currency
+comprehensive
+intelligence
+charity
+fifth
+links
+hoping
+respond
+surprising
+extension
+solid
+survive
+growing
+apart
+restaurant
+churches
+precisely
+pale
+skill
+close
+connection
+mass
+dealt
+brilliant
+maximum
+losing
+depend
+200
+experienced
+across
+introduce
+philosophy
+convention
+gun
+films
+sons
+eh
+communications
+regime
+miss
+attended
+suffer
+copies
+councils
+round
+partnership
+inquiry
+Sarah
+residents
+absolute
+firm
+French
+corporation
+arrested
+reports
+minority
+arrival
+in addition to
+listening
+taste
+sad
+gap
+plane
+scope
+experiences
+coat
+command
+consequence
+left
+fun
+Birmingham
+tory
+golf
+electronic
+behind
+visual
+retirement
+replace
+rise
+darkness
+fault
+directed
+complete
+1970s
+enemy
+comment
+electric
+priority
+metres
+database
+Tim
+pure
+Spanish
+Nigel
+rough
+core
+circle
+result
+literary
+bay
+championship
+guests
+1975
+insisted
+mere
+bits
+successfully
+limit
+imposed
+continuing
+Rome
+sounds
+abuse
+categories
+languages
+tower
+Thatcher
+anger
+accompanied
+category
+collected
+present
+need
+comparison
+supreme
+supplied
+chemical
+fans
+greatly
+sweet
+wedding
+teaching
+represents
+duke
+mark
+personnel
+genuine
+adults
+mail
+politicians
+occurs
+exciting
+written
+returning
+promotion
+longer
+preparation
+defendant
+presumably
+DNA
+derived
+Washington
+paintings
+fitted
+mothers
+affair
+stupid
+cricket
+advanced
+tank
+arise
+photographs
+point
+disappeared
+expectations
+findings
+illness
+citizens
+mood
+faces
+tension
+Commons
+ladies
+briefly
+stones
+mixture
+classical
+arrangement
+extreme
+Williams
+nineteenth
+discover
+favourite
+shot
+causing
+yard
+begins
+socialist
+judgment
+landscape
+fail
+feels
+consumption
+mill
+1974
+informed
+birthday
+widespread
+consent
+confident
+acts
+Gloucester
+sake
+estimated
+requirement
+catholic
+experts
+Israel
+numerous
+throat
+permission
+ignored
+guidance
+moments
+brings
+costs
+module
+opposite
+respectively
+altogether
+input
+presentation
+everywhere
+distinct
+statistics
+repeated
+tough
+earnings
+saved
+finger
+branches
+fishing
+components
+truly
+drink
+turns
+luck
+boss
+exists
+champion
+MP
+answers
+tools
+cycle
+recommended
+intervention
+mile
+Scott
+whenever
+AIDS
+promote
+helpful
+prospect
+definitely
+Johnson
+organised
+controls
+Ben
+express
+Iraq
+nurse
+frame
+perform
+cottage
+wave
+adding
+proud
+by
+winner
+solicitor
+neighbours
+pilot
+calls
+mad
+alliance
+given
+straight
+survival
+winning
+votes
+primarily
+attacks
+compensation
+Sam
+destroyed
+camp
+hat
+territory
+symptoms
+prior to
+ownership
+wage
+concluded
+discussions
+developing
+cream
+achievement
+drawing
+entrance
+basically
+poverty
+disabled
+extend
+fast
+suggestion
+consistent
+shareholders
+degrees
+mention
+anxious
+fewer
+delivered
+dark
+transferred
+employee
+throw
+assumption
+inevitably
+nervous
+profession
+awful
+cool
+hang
+threw
+vehicles
+stable
+realized
+suit
+hills
+prize
+drop
+constitutional
+perspective
+Neil
+satisfied
+bid
+aunt
+festival
+constantly
+conscious
+developing
+connected
+concerning
+savings
+reasonably
+concentrate
+pace
+novel
+operating
+breach
+purchase
+crossed
+Asia
+chances
+depth
+calls
+strategic
+thrown
+bills
+Jean
+Ken
+reply
+ha
+Ruth
+treat
+green
+sheep
+dominant
+phrase
+push
+eating
+now that
+conducted
+employer
+ears
+contents
+touched
+prepare
+sounded
+Moscow
+theoretical
+setting
+soul
+wore
+study
+1960s
+outstanding
+benefit
+vary
+jacket
+except
+holy
+processing
+sand
+clinical
+prisoners
+dispute
+shadow
+minimum
+organizations
+plaintiff
+snow
+cried
+fit
+driven
+Joseph
+port
+recognized
+servants
+limits
+pink
+et al
+sound
+hearing
+measured
+dance
+eighteen
+sorts
+Patrick
+trained
+stomach
+slight
+fought
+points
+storage
+breaking
+impressive
+honest
+provided
+dismissed
+glanced
+related
+cast
+crew
+defeat
+hold
+gift
+enthusiasm
+princess
+press
+spending
+advantages
+reaching
+articles
+resulted
+files
+hung
+cuts
+residential
+extraordinary
+visible
+shouted
+reducing
+experiments
+tables
+finish
+tendency
+conduct
+objective
+report
+ring
+hospitals
+mechanism
+seventy
+exception
+poetry
+inspector
+1973
+covering
+stepped
+accurate
+percent
+victims
+approached
+distant
+alongside
+airport
+furthermore
+considerably
+pressed
+missing
+origin
+salt
+personality
+fight
+Canada
+arrive
+fly
+Greek
+receiving
+still
+rocks
+fees
+fee
+complicated
+ends
+musical
+stands
+moon
+chamber
+puts
+turnover
+attacked
+ultimately
+routine
+observation
+precise
+plain
+gentle
+watch
+staring
+since
+leisure
+economics
+device
+broken
+mortgage
+live
+leaves
+confusion
+cut
+finds
+instruments
+secondly
+Bush
+certificate
+ear
+remote
+satisfaction
+responsibilities
+ratio
+coach
+fears
+sentences
+holder
+shopping
+possession
+selected
+Bristol
+sets
+smoke
+rugby
+songs
+clock
+summary
+implementation
+protein
+housing
+escape
+wing
+fixed
+helps
+poll
+Arthur
+scored
+chose
+column
+holidays
+contributions
+architecture
+Nick
+approximately
+disaster
+minds
+Keith
+marks
+trust
+neither
+monetary
+mountains
+White
+discovery
+collect
+spoken
+steam
+smooth
+silly
+childhood
+teach
+Kong
+unity
+staying
+climate
+percentage
+villages
+attracted
+Americans
+designs
+secure
+cutting
+iv
+Hong
+last
+taxes
+tennis
+peak
+relation
+readily
+evaluation
+frequency
+Andy
+shirt
+cake
+nights
+bishop
+test
+pretty
+Charlie
+deliberately
+round
+determination
+applies
+automatically
+standing
+rent
+psychological
+violent
+medicine
+boards
+protest
+Anna
+unemployed
+final
+being
+Rose
+reforms
+inevitable
+junior
+signal
+building
+till
+welcome
+fat
+roles
+headquarters
+sensible
+visits
+manufacturers
+restrictions
+samples
+Pacific
+improved
+Berlin
+grateful
+strategies
+score
+tended
+expense
+loans
+addressed
+mode
+structural
+dozen
+pride
+newly
+founded
+variation
+aged
+rely
+investors
+infection
+dominated
+combined
+survived
+Helen
+string
+Lucy
+experiment
+fourteen
+undertaken
+committees
+buyer
+agreements
+participation
+welcome
+match
+complaints
+ships
+critics
+guitar
+camera
+laboratory
+waves
+landlord
+rang
+hate
+demonstrated
+bomb
+engaged
+knife
+so-called
+modules
+pleasant
+headed
+surgery
+universities
+millions
+concepts
+proof
+marry
+Maggie
+operating
+pressures
+lives
+sixteen
+repeat
+host
+Dave
+pitch
+attempted
+assess
+penalty
+tail
+boxes
+holes
+deep
+contribute
+passing
+reveal
+cleared
+thereby
+acceptance
+1972
+anxiety
+above
+Newcastle
+formula
+personally
+Howard
+mission
+deaf
+relatives
+imagination
+apple
+dirty
+rid
+abandoned
+appreciate
+continuous
+describes
+suffering
+circuit
+stronger
+responses
+excitement
+approaches
+supply
+plan
+Zealand
+tested
+disk
+holds
+replacement
+instrument
+universe
+memories
+overseas
+expertise
+causes
+solicitors
+comfort
+sergeant
+trend
+treasury
+entitled
+sounds
+acquisition
+opening
+tickets
+bath
+delighted
+sending
+increasing
+confirm
+loose
+state
+targets
+occasional
+paragraph
+writes
+evident
+Kent
+desperate
+handle
+fellow
+blind
+occupied
+overcome
+dust
+burden
+psychology
+relate
+drivers
+surprisingly
+1970
+Matthew
+cheese
+consciousness
+considering
+universal
+Gordon
+aha
+square
+succeeded
+knees
+1971
+boots
+smell
+closer
+mummy
+slipped
+component
+regulation
+Roger
+attempt
+locked
+keeps
+wheel
+classic
+MPs
+cattle
+consists
+touch
+illustrated
+platform
+shift
+draft
+purely
+load
+influenced
+passengers
+recommendations
+preparing
+solutions
+Alexander
+injuries
+tenant
+commonly
+Victoria
+leather
+gathered
+zone
+sufficiently
+like
+Laura
+squad
+recall
+steady
+retain
+checked
+existed
+attract
+conservation
+flesh
+pack
+publicity
+rose
+mean
+variations
+split
+sixth
+edition
+concerns
+tied
+summit
+engineers
+Terry
+listed
+judges
+researchers
+equivalent
+assist
+upstairs
+hers
+Francis
+located
+nurses
+fear
+mark
+suggesting
+whispered
+serving
+intellectual
+influence
+stream
+generated
+consequently
+San
+authors
+wondering
+judgement
+experience
+Victorian
+egg
+supplies
+level
+produces
+councillor
+roots
+taxation
+bathroom
+ultimate
+awarded
+stick
+glasses
+raising
+qualities
+layer
+lost
+creative
+medieval
+risks
+assumptions
+displayed
+dreams
+Germans
+accounting
+curve
+drawing
+backed
+adopt
+colleges
+guard
+evolution
+sign
+aims
+sharply
+constructed
+advised
+softly
+settle
+decades
+completion
+linguistic
+ignore
+convinced
+Colin
+judicial
+photograph
+sophisticated
+Alice
+asleep
+paused
+amounts
+poem
+recording
+carbon
+Durham
+possibilities
+good
+explains
+equation
+NHS
+vulnerable
+raw
+net
+deaths
+babies
+illegal
+outer
+topic
+medium
+till
+promise
+tends
+hopes
+angle
+interviews
+ban
+feed
+potentially
+machinery
+tongue
+coalition
+travelling
+define
+consultation
+reception
+pulling
+Nicholas
+integration
+revolutionary
+quoted
+compare
+surrounded
+bitter
+attempting
+guess
+improvements
+climbed
+cathedral
+heaven
+wanting
+painted
+Australian
+changing
+grammar
+jumped
+Ulster
+Gulf
+native
+imperial
+persuade
+voices
+conclusions
+laughing
+lift
+1968
+Gary
+boundaries
+favour
+guy
+studying
+Jimmy
+beliefs
+undoubtedly
+wings
+retained
+joy
+bone
+informal
+demonstrate
+Douglas
+regard
+clear
+calculated
+flexible
+meals
+announcement
+lawyers
+ruled
+account
+sheets
+tunnel
+exercise
+bars
+carpet
+quantity
+catalogue
+reminded
+shrugged
+notably
+Anthony
+schedule
+petrol
+investigate
+hotels
+buried
+once more
+journal
+nowhere
+considerations
+concentrated
+collective
+destruction
+frequent
+versions
+offences
+agenda
+clever
+experimental
+plays
+Kate
+listened
+La
+texts
+plates
+deficit
+transition
+Norman
+spiritual
+intense
+indication
+flew
+pushing
+rational
+hanging
+entitled
+excluded
+knocked
+professionals
+tight
+composition
+indicates
+conservatives
+Kevin
+interaction
+ceiling
+guidelines
+cold
+roughly
+Governor
+qualifications
+ethnic
+me
+argues
+Dublin
+inches
+opera
+pupil
+cheaper
+generous
+prominent
+inadequate
+accordingly
+welcomed
+instruction
+logical
+passion
+drawings
+exposure
+departure
+blame
+racing
+mixed
+historic
+guest
+Mrs.
+pipe
+modest
+Dutch
+lessons
+hero
+Lloyd
+sectors
+Diana
+barely
+logic
+Essex
+acute
+harm
+representing
+discourse
+voted
+electrical
+hearing
+consumers
+jury
+Grant
+weekly
+acted
+delay
+valid
+wherever
+representative
+transaction
+bowl
+increases
+contributed
+Christopher
+record
+leaned
+lesson
+lit
+admission
+stores
+awards
+automatic
+timber
+trousers
+vote
+habit
+Oliver
+arrange
+red
+matches
+punishment
+bones
+cross
+deny
+rubbish
+hide
+mortality
+complex
+pc
+earl
+explore
+urged
+occupation
+storm
+darling
+keys
+customs
+profile
+gross
+depression
+classroom
+glance
+mystery
+mutual
+reliable
+wholly
+entering
+bare
+liable
+facility
+stressed
+stuck
+realize
+engineer
+smiling
+confined
+province
+registration
+males
+laughter
+humour
+resource
+multiple
+Albert
+ruling
+silk
+waters
+Rachel
+paint
+cotton
+Atlantic
+identification
+claiming
+sole
+coverage
+arising
+Owen
+honour
+poet
+prospects
+travelled
+divisions
+posts
+avoided
+in case
+charter
+managing
+pregnant
+obligation
+win
+adds
+formally
+flying
+Latin
+nearby
+Egypt
+exact
+directions
+curious
+bother
+participants
+lawyer
+resignation
+bearing
+sets
+pointing
+tool
+damages
+speakers
+fate
+daddy
+devices
+phenomenon
+strain
+substance
+bags
+wire
+Wood
+underlying
+responded
+enjoying
+visitor
+joining
+uncertainty
+but
+drop
+submitted
+flower
+Ford
+California
+perception
+identical
+farming
+letting
+audit
+satisfactory
+Billy
+ticket
+lists
+preference
+Great
+thirteen
+Van
+secret
+pop
+album
+federation
+learnt
+deliver
+Westminster
+chemicals
+farmer
+variables
+male
+assault
+marginal
+leave
+namely
+fed
+distinctive
+kingdom
+assessed
+refuse
+electoral
+urgent
+allowance
+observations
+libraries
+Lawrence
+reflects
+force
+sympathy
+running
+falls
+publishing
+recovered
+stability
+canal
+funeral
+singing
+titles
+beds
+sessions
+restricted
+Sheffield
+Nottingham
+expecting
+clothing
+drinks
+disposal
+failing
+joke
+focus
+succeed
+Maria
+typically
+official
+conversion
+presidential
+generations
+mayor
+sharing
+Clare
+worth
+transactions
+era
+policeman
+Fred
+gaze
+controversial
+count
+proceed
+Young
+folk
+fabric
+oral
+horror
+Kelly
+everyday
+emperor
+viewed
+sing
+belt
+fortune
+demand
+doubt
+crash
+encouraging
+interpreted
+Louis
+organic
+maintaining
+removal
+female
+routes
+continued
+trials
+enables
+print
+laugh
+bent
+expected
+connections
+magistrates
+errors
+statistical
+resolved
+desirable
+recognize
+Stuart
+thoroughly
+injured
+van
+blocks
+prosecution
+register
+trends
+preferred
+reckon
+innocent
+ideology
+belong
+improved
+past
+corridor
+exclusive
+tale
+pairs
+prayer
+collapse
+lease
+talent
+gains
+separated
+marked
+experienced
+persuaded
+sighed
+butter
+suggestions
+Russell
+unexpected
+foods
+picking
+banking
+sciences
+superb
+contacts
+operated
+alarm
+go
+Poland
+gene
+daughters
+sheer
+guardian
+count
+cloud
+disappointed
+Bernard
+format
+scenes
+frightened
+hardware
+traditionally
+gastric
+genes
+effectiveness
+full-time
+intend
+concentrations
+defend
+strict
+fighting
+creatures
+closer
+Swindon
+capitalist
+Walker
+addition
+chocolate
+emerge
+Hugh
+hidden
+likes
+Susan
+Stewart
+reactions
+lands
+establishing
+swept
+anniversary
+permitted
+export
+1967
+justify
+tissue
+Davies
+bet
+specified
+romantic
+garage
+conviction
+declined
+resigned
+Clarke
+advise
+scientist
+root
+asset
+warmth
+bulk
+bands
+knee
+minimum
+humans
+references
+any
+associations
+muscles
+withdrawal
+registered
+distributed
+regarding
+exposed
+declaration
+graphics
+reluctant
+actor
+switched
+sisters
+winners
+eighteenth
+chemistry
+rest
+justified
+stop
+converted
+boundary
+suspect
+magnificent
+stretched
+convenient
+friendship
+established
+recover
+destroy
+Jackson
+mess
+correspondent
+navy
+dollar
+craft
+reflection
+chicken
+plans
+tin
+Miller
+curtains
+gesture
+tourist
+diary
+protected
+ocean
+discussing
+practitioners
+bloody
+entertainment
+nearest
+mechanisms
+closed
+expenses
+uncertain
+artificial
+democrats
+damaged
+composed
+heating
+diplomatic
+drinking
+discrimination
+rows
+bench
+councillors
+acquire
+installed
+guns
+killing
+Microsoft
+blow
+salary
+Baker
+tip
+1950s
+physically
+estates
+tremendous
+marine
+ease
+institutional
+mechanical
+retail
+resist
+mixed
+literally
+chapel
+distinguish
+wildlife
+Rivers
+Iran
+tories
+doubts
+formerly
+priorities
+reserves
+publications
+commented
+gender
+passenger
+Sussex
+strictly
+boats
+causes
+pen
+chapters
+cheque
+required
+testing
+carriage
+weapon
+generate
+Clinton
+asks
+earn
+supporting
+mentally
+judge
+messages
+females
+biological
+applying
+implies
+known
+Emily
+rolled
+tube
+functional
+accidents
+flexibility
+chairs
+Phil
+styles
+cap
+straightforward
+moves
+wise
+fired
+organized
+inspection
+Derek
+mathematics
+heritage
+superior
+1969
+specially
+finance
+cloth
+sociology
+desperately
+fiction
+equity
+satisfy
+Lords
+shell
+Wright
+lad
+whereby
+forests
+suit
+pursue
+digital
+increases
+tenants
+refers
+voters
+piano
+productivity
+part-time
+lightly
+assistant
+Commander
+address
+situated
+restoration
+outlined
+imports
+comment
+stolen
+Harris
+clerk
+cinema
+Ann
+covers
+capitalism
+spectacular
+shapes
+controversy
+Marx
+gates
+escaped
+Robin
+continuing
+trains
+ensuring
+colonel
+confused
+grants
+remarks
+bonds
+wives
+computing
+constraints
+solve
+aggressive
+availability
+unfair
+sadly
+invasion
+tracks
+compete
+closure
+spare
+painful
+earned
+venture
+topics
+wonder
+equivalent
+grade
+Korea
+pot
+emotions
+washed
+escape
+abstract
+Eric
+murmured
+stake
+lift
+states
+breeding
+securities
+asian
+mud
+Joan
+estimates
+cheek
+stored
+correctly
+refugees
+Moore
+obligations
+spirits
+unhappy
+Ross
+networks
+beaten
+snapped
+initiatives
+understanding
+alter
+shame
+pensions
+oxygen
+therapy
+associated
+courage
+discretion
+dates
+deposits
+hopefully
+exports
+legislative
+Eliot
+ward
+monthly
+deciding
+describing
+assuming
+opposed
+Alex
+searching
+intelligent
+impose
+explicit
+jurisdiction
+designer
+tie
+fellow
+quantities
+fleet
+Barry
+seller
+RAF
+borough
+stand
+flats
+virtue
+constituency
+complained
+coloured
+midnight
+taxi
+engines
+railways
+display
+just
+ridiculous
+Caroline
+debts
+comparable
+amazing
+acknowledged
+appeal
+wars
+successive
+refusal
+incorporated
+creature
+secured
+economies
+isolation
+Leicester
+succession
+signals
+working-class
+physics
+feared
+concert
+tonnes
+realistic
+hungry
+launch
+Evans
+resort
+burst
+sort
+back
+Walter
+gear
+Shakespeare
+surveys
+volunteers
+stick
+separation
+la
+demonstration
+fails
+conception
+decent
+discount
+unnecessary
+prevented
+flying
+worn
+dictionary
+twentieth
+fat
+random
+retired
+local
+origins
+packed
+achieving
+heading
+forever
+influential
+masters
+channels
+harbour
+producers
+duration
+Thames
+cable
+1945
+desert
+terrace
+assured
+allocation
+check
+diseases
+merchant
+constable
+Vietnam
+Dean
+recalled
+lifetime
+chips
+Ray
+genetic
+complaint
+near
+visiting
+explaining
+order
+marvellous
+Malcolm
+Morgan
+restored
+earliest
+enabled
+release
+Cardiff
+assurance
+bottles
+brick
+essence
+autonomy
+giant
+requiring
+hunting
+consensus
+differ
+vegetables
+junction
+workshop
+measure
+purchaser
+secure
+attendance
+necessity
+bottom
+demanding
+skilled
+shaking
+subtle
+select
+attack
+questioned
+sooner
+producer
+planet
+elegant
+amendment
+hopes
+carries
+recommend
+lesser
+farms
+parallel
+limitations
+locally
+Marie
+tragedy
+instance
+cousin
+collections
+backwards
+grain
+resulting
+fraud
+swung
+landed
+quarters
+liberation
+seventeen
+referring
+interior
+bike
+suspended
+officially
+journalists
+nasty
+movie
+suppliers
+dealer
+shows
+soldier
+intensive
+kit
+witness
+delight
+symbol
+forum
+casual
+tropical
+shorter
+Allen
+crimes
+printed
+miners
+feeding
+relax
+pass
+manufacturer
+chip
+crazy
+forming
+kissed
+swimming
+happily
+copper
+arguing
+shots
+landing
+nursery
+entries
+preliminary
+besides
+arises
+partial
+households
+damp
+wool
+1964
+servant
+Pakistan
+attending
+Guy
+plot
+muscle
+beings
+inch
+simultaneously
+concrete
+Roy
+roll
+bell
+neighbour
+reign
+analysed
+tide
+expand
+alleged
+guilt
+rank
+introducing
+transfer
+uses
+ceremony
+Morris
+separately
+opinions
+enquiry
+grinned
+lover
+slept
+choices
+assistant
+severely
+finest
+poured
+vertical
+Easter
+upset
+hey
+allegations
+IRA
+justification
+detective
+programs
+throwing
+strike
+ate
+appendix
+Jenny
+districts
+commonwealth
+dealers
+delicate
+forms
+advisers
+lonely
+dull
+mouse
+Pat
+occupational
+pity
+behave
+complexity
+youngsters
+riding
+weakness
+excessive
+Clark
+progressive
+captured
+stance
+undertake
+exceptional
+faster
+Iraqi
+remind
+counter
+Greece
+triumph
+remarked
+continental
+striking
+integrated
+pit
+encountered
+implemented
+sizes
+directive
+participate
+safely
+lowest
+lighting
+villa
+okay
+downstairs
+portrait
+alternatively
+edges
+focused
+bye
+residence
+panic
+label
+aims
+magazines
+neat
+combined
+transformation
+theft
+lecture
+incidence
+scores
+radiation
+perceived
+spread
+firstly
+interface
+doctrine
+shouting
+affecting
+ours
+excuse
+accepting
+risen
+Lancashire
+approach
+deposit
+pond
+substantially
+innovation
+diagnosis
+gifts
+allocated
+regard
+remainder
+speculation
+approaching
+dialogue
+estimate
+wash
+supervision
+dying
+exclusively
+happiness
+politically
+timing
+chronic
+Geoffrey
+peasants
+tightly
+characteristic
+accuracy
+compulsory
+wrapped
+interim
+objective
+Benjamin
+walking
+infant
+Bruce
+judged
+splendid
+ride
+divorce
+magic
+Cleveland
+bond
+review
+short-term
+ambulance
+brave
+investigations
+systematic
+Green
+seized
+cry
+laugh
+advanced
+obliged
+opens
+eaten
+relevance
+1930s
+careers
+Liz
+withdrawn
+Barbara
+no
+payable
+handsome
+fun
+Ms
+instances
+governors
+horrible
+measurement
+employ
+primitive
+steadily
+switch
+fascinating
+Brazil
+ideological
+pile
+mounted
+metropolitan
+alternatives
+dollars
+north-east
+explosion
+starting
+glory
+scarcely
+Harriet
+surrounding
+coup
+domain
+fence
+threatening
+dragged
+breast
+habits
+mine
+hierarchy
+grip
+socialism
+enquiries
+particles
+Sweden
+choosing
+colleague
+monitoring
+Midlands
+restore
+printer
+imagined
+doorway
+prisoner
+juice
+classification
+estimated
+equilibrium
+solely
+with regard to
+serves
+peaceful
+observer
+explanations
+circles
+rescue
+maps
+hated
+observe
+Hughes
+premier
+mate
+hypothesis
+1966
+ride
+companion
+liver
+factories
+buyers
+reward
+controlling
+satellite
+loyalty
+operational
+pardon
+improving
+jump
+potatoes
+intervals
+technological
+near
+fortunately
+hostile
+advisory
+cook
+precious
+opponents
+peasant
+insist
+geography
+button
+consistently
+cultures
+seeds
+monopoly
+accessible
+tournament
+moves
+excited
+determined
+owed
+pockets
+belonged
+Hollywood
+dining
+switch
+traditions
+compromise
+intensity
+chaos
+obtaining
+Mexico
+King
+combine
+altered
+nonsense
+clouds
+themes
+suspicion
+ranks
+disorder
+stocks
+Kuwait
+1965
+2000
+consultant
+collapsed
+purchased
+impressed
+half
+Catherine
+provincial
+sterling
+performances
+instantly
+Bell
+constitute
+arrest
+dose
+exercises
+issue
+competitors
+spectrum
+dangers
+allies
+travellers
+plc
+kid
+disc
+Donald
+nowadays
+Surrey
+cheeks
+endless
+isolated
+dimension
+twin
+bedrooms
+clean
+columns
+privilege
+post-war
+volumes
+broadcasting
+commerce
+historians
+train
+geographical
+oak
+actors
+step
+like
+dynamic
+freely
+checking
+equipped
+inspired
+density
+1994
+forthcoming
+HIV
+boring
+handled
+poems
+recording
+unfortunate
+banned
+Karen
+own
+suspected
+boom
+tribunal
+kicked
+possessed
+Jonathan
+broadly
+publicly
+attributed
+definite
+challenged
+extending
+cooking
+pause
+strip
+predicted
+super
+barrier
+pregnancy
+loud
+menu
+preserved
+Avenue
+restaurants
+acres
+prompted
+senses
+essay
+lip
+recruitment
+defendants
+presents
+guarantee
+invest
+cats
+maximum
+notable
+upwards
+arose
+cry
+fierce
+detected
+indirect
+German
+witnesses
+patch
+sensitivity
+Le
+mistakes
+receiver
+crops
+chin
+wheels
+rice
+Dec
+forgot
+illustrate
+reveals
+Freud
+limit
+chap
+Campbell
+races
+awkward
+Turkey
+implied
+climb
+widow
+varied
+slid
+stopping
+rope
+steep
+neutral
+Oxfordshire
+finish
+debut
+seed
+challenge
+promoted
+delegation
+hitherto
+artistic
+muttered
+adoption
+architect
+dear
+Kenneth
+portfolio
+continent
+transformed
+couples
+probability
+content
+Robinson
+struggling
+mild
+counties
+wish
+mention
+fitness
+tackle
+dish
+statute
+invariably
+Charlotte
+prey
+view
+consultants
+gather
+arriving
+corners
+delegates
+Holland
+archbishop
+Sue
+withdraw
+replacing
+Milton
+meaning
+mature
+differently
+chart
+technologies
+woods
+possess
+cab
+grace
+toilet
+grabbed
+prevention
+equality
+wishes
+bases
+operator
+regardless
+harsh
+colonial
+ambitious
+exploration
+lords
+investigated
+collecting
+Switzerland
+shadows
+Corbett
+evil
+Johnny
+dramatically
+Marshall
+indicating
+orchestra
+lock
+inhabitants
+defeated
+disappointment
+magnetic
+washing
+fibre
+correspondence
+verbal
+legitimate
+requested
+emotion
+odds
+workforce
+vessels
+brass
+pursued
+ph
+balls
+adviser
+faint
+handling
+appointments
+grandfather
+motivation
+sympathetic
+publishers
+peoples
+socially
+investments
+rhythm
+variable
+Chelsea
+memorial
+well-known
+empirical
+roses
+ceased
+fluid
+descriptions
+incidents
+DC
+dismissal
+appreciated
+communicate
+rushed
+bronze
+wisdom
+Daniel
+supper
+adventure
+tribute
+seeks
+promise
+head
+ye
+1960
+crop
+beef
+suited
+exercised
+respects
+terror
+circulation
+identifying
+achievements
+fool
+intentions
+proportions
+lads
+directory
+Brighton
+inn
+promoting
+flag
+separate
+Roberts
+Ward
+Dennis
+clay
+Cook
+Norway
+attraction
+ends
+disability
+championships
+vague
+virus
+shift
+ranging
+competence
+examining
+inform
+spaces
+goodness
+gang
+favourite
+preserve
+remembering
+naval
+molecules
+hearts
+trapped
+actively
+leaf
+Brussels
+distress
+resolve
+custody
+packages
+drinking
+operators
+myth
+gain
+voting
+Mick
+returns
+tourists
+encouragement
+lacking
+seldom
+processor
+sums
+integrity
+acknowledge
+shortage
+depressed
+rightly
+Louise
+remarkably
+repair
+shoot
+electronics
+wishing
+Kinnock
+imprisonment
+kings
+waved
+shared
+shocked
+uniform
+added
+reject
+implement
+pays
+hesitated
+seventh
+magic
+mid
+populations
+worthwhile
+filling
+crystal
+fraction
+qualified
+Newton
+Sally
+server
+Nato
+specimens
+kiss
+reflecting
+shower
+missing
+roll
+sword
+varieties
+clinic
+imply
+ie
+rivals
+Julia
+breakdown
+Anderson
+scales
+fan
+operates
+blank
+whoever
+scandal
+oldest
+smart
+favourable
+filter
+interviewed
+absent
+mining
+gentlemen
+enemies
+champions
+Duncan
+exclusion
+boot
+locations
+Hamilton
+transmission
+custom
+tanks
+tries
+Gloucestershire
+publisher
+beating
+evidently
+Netherlands
+Polish
+lively
+exceptions
+Emma
+appeals
+Israeli
+mobility
+reviewed
+buses
+conclude
+mix
+shore
+commissioner
+absorbed
+Norwich
+dawn
+developed
+guards
+incomes
+parking
+vendor
+wishes
+republics
+loads
+barriers
+translation
+evenings
+Hungary
+lectures
+stimulus
+conflicts
+remains
+margin
+question
+bothered
+neighbourhood
+tourism
+meanings
+FA
+desktop
+reportedly
+risk
+zero
+demonstrations
+dividend
+opponent
+wake
+stiff
+rejection
+flavour
+relates
+borrow
+emissions
+representative
+Midland
+thereafter
+enthusiastic
+observers
+cited
+quid
+fortnight
+dreadful
+guarantee
+reduced
+rigid
+killer
+ending
+trick
+successor
+execution
+influences
+temperatures
+mines
+drank
+coastal
+greeted
+nightmare
+peculiar
+corruption
+tray
+speaks
+cupboard
+creates
+Jordan
+Aberdeen
+harder
+burned
+appearing
+Swiss
+rabbit
+environments
+comedy
+referendum
+bureau
+avoiding
+just about
+matrix
+honestly
+profound
+journalist
+extended
+Julie
+tapes
+suspension
+delayed
+eager
+comply
+selected
+skirt
+matched
+feminist
+Davis
+Canadian
+closing
+acts
+grief
+relaxed
+insight
+deck
+sensation
+placing
+sequences
+temple
+parks
+tactics
+verdict
+adapted
+enhance
+corresponding
+strings
+accurately
+running
+pray
+accent
+envelope
+interference
+grandmother
+examinations
+phone
+planned
+shelf
+deemed
+waist
+waste
+onwards
+applicable
+futures
+sauce
+immense
+purchase
+breathing
+allied
+Norfolk
+contest
+expects
+supports
+km
+blacks
+decision-making
+coins
+genuinely
+accounted
+expressing
+assessing
+dance
+scheduled
+adjustment
+charge
+winds
+meets
+practically
+merger
+comparative
+permit
+celebrate
+vessel
+belonging
+affection
+outline
+albeit
+Lily
+leaning
+lounge
+raises
+Cheltenham
+workshops
+refusing
+shallow
+dishes
+monitor
+propose
+blamed
+dioxide
+kind
+broader
+handling
+bastard
+uncomfortable
+affects
+proposition
+representations
+conservation
+ya
+makers
+Yugoslavia
+Fox
+citizen
+forcing
+productive
+woke
+bored
+beneficial
+slip
+campaigns
+handful
+aged
+collar
+curtain
+diversity
+hint
+Thompson
+disappear
+charming
+bonus
+secrets
+interrupted
+specialists
+accommodate
+frustration
+recommendation
+meantime
+coffin
+daily
+condemned
+minimal
+mobile
+academy
+testing
+independently
+appealed
+museums
+cruel
+faces
+murdered
+on board
+Turkish
+aim
+Will
+territories
+pressing
+Churchill
+commit
+verse
+research
+orange
+interval
+threats
+passive
+suspicious
+forgive
+liberty
+ghost
+rear
+believing
+correlation
+measurements
+1963
+investigating
+shade
+layers
+bias
+overwhelming
+certainty
+Sunderland
+cow
+commissioned
+trusts
+maturity
+resulting
+fatal
+surrounding
+crying
+planted
+symbolic
+isle
+historian
+enabling
+removing
+slope
+excuse
+angel
+nearby
+rats
+straw
+1962
+surfaces
+gods
+foundations
+honours
+Belgium
+disputes
+insects
+inspiration
+draw
+presenting
+registered
+pavement
+telephone
+reserve
+keeper
+dimensions
+predict
+neighbouring
+validity
+breeze
+ugly
+expanded
+lasted
+irrelevant
+complain
+shelter
+patient
+driving
+wealthy
+upset
+hostility
+profitable
+rod
+fled
+compact
+lamp
+shifted
+supplier
+crossing
+phenomena
+IT
+measuring
+horizon
+rival
+making
+clergy
+marble
+pensioners
+fragments
+loyal
+Alison
+Stanley
+conscience
+sixties
+Hill
+saving
+tune
+moderate
+1961
+soup
+paths
+struggled
+popularity
+score
+singer
+distinguished
+climbing
+kick
+Betty
+characteristic
+interior
+episode
+oven
+basket
+noble
+forwards
+consisted
+crowds
+positively
+pole
+burning
+pet
+insufficient
+evil
+mysterious
+jet
+eligible
+behalf
+passes
+nails
+collaboration
+lorry
+nest
+varying
+enforcement
+Spencer
+Denmark
+make-up
+molecular
+managerial
+raid
+ambition
+middle-class
+brand
+migration
+embassy
+neatly
+looks
+worship
+Olympic
+devised
+exclude
+organ
+favoured
+linear
+Samuel
+cared
+manor
+detect
+interpret
+Kennedy
+substances
+crude
+fantasy
+counselling
+abilities
+treating
+blew
+embarrassment
+executed
+implication
+Ron
+printed
+prospective
+importantly
+Preston
+continually
+Barnes
+executives
+catching
+forehead
+Ali
+diverse
+parental
+elaborate
+furious
+definitions
+appreciation
+fiscal
+Kim
+commitments
+sculpture
+runs
+striker
+beans
+brush
+soccer
+spell
+reductions
+contrary
+soap
+dated
+stretch
+publish
+russians
+pig
+stroke
+ladder
+Greater
+burning
+expressions
+useless
+nerve
+pence
+Gabriel
+rumours
+relied
+Edwards
+semantic
+inherent
+embarrassed
+1948
+specification
+despair
+yep
+name
+serum
+Maxwell
+Dick
+apartment
+Vienna
+deliberate
+stranger
+philosophical
+criterion
+trap
+pubs
+utterly
+link
+frowned
+awake
+bureaucracy
+nonetheless
+sunshine
+bloke
+partially
+remedy
+battery
+variable
+within
+forth
+barn
+ties
+settlements
+installation
+crashed
+negotiate
+Somerset
+nursing
+dignity
+promising
+minus
+criticised
+sacred
+analyse
+senate
+incentive
+unpleasant
+varied
+selective
+qualified
+Devon
+powder
+clauses
+expectation
+tender
+inclined
+funded
+alleged
+hidden
+ridge
+exhibitions
+lengths
+Joyce
+posed
+explicitly
+symbols
+exploitation
+receives
+1950
+intermediate
+Isabel
+blocked
+trophy
+launch
+spotted
+manufacture
+diesel
+masses
+protective
+paint
+budgets
+Lisa
+grows
+fortunate
+deserve
+lap
+concerns
+varies
+compliance
+defensive
+damage
+objections
+qualify
+featured
+suite
+salmon
+reach
+requests
+objection
+devoted
+thesis
+repeatedly
+blow
+palm
+Austria
+Rover
+parked
+Carter
+Guinness
+temporarily
+Land
+south-east
+chains
+worthy
+ozone
+pursuit
+valued
+divine
+react
+deals
+head
+phoned
+carrier
+jeans
+feedback
+dancing
+tales
+rally
+grant
+performing
+rush
+handicap
+consisting
+counted
+qualification
+guaranteed
+negligence
+continuity
+lend
+offers
+educated
+stuck
+surplus
+swallowed
+eagle
+printing
+land
+Willie
+novels
+driving
+dependence
+1st
+eighth
+Craig
+organise
+Cornwall
+orange
+diameter
+1939
+toward
+auction
+eating
+Max
+invisible
+determining
+construct
+faculty
+offenders
+occurring
+Pete
+charm
+Don
+suffering
+contempt
+Wimbledon
+reinforced
+specify
+misery
+dropping
+breasts
+overall
+Sara
+jewellery
+bacteria
+sin
+comparisons
+privatisation
+owe
+squadron
+grave
+codes
+circular
+misleading
+centred
+sunlight
+lowered
+invested
+mathematical
+proteins
+sanctions
+aggression
+caution
+loch
+reply
+direct
+subjected
+inappropriate
+diagram
+terribly
+St
+human
+liquid
+solar
+angles
+sorted
+persistent
+poles
+laying
+inherited
+phrases
+doubtful
+calcium
+shake
+ingredients
+Sophie
+admits
+black
+BR
+monster
+flames
+allowances
+sustain
+needle
+telecommunications
+sphere
+revenues
+guessed
+bowel
+doubled
+prints
+rangers
+accountants
+screaming
+legend
+petition
+predominantly
+manual
+lies
+premium
+photo
+surroundings
+spots
+gravel
+19th
+architectural
+bold
+Maastricht
+inheritance
+Harvey
+knock
+blues
+beyond
+Day
+emergence
+beautifully
+deeper
+intact
+cooperation
+convince
+incredible
+sound
+devoted
+conduct
+united
+celebration
+abruptly
+considers
+flights
+explored
+loves
+blue
+Derby
+restriction
+prior
+submit
+gaining
+Santa
+morality
+tragic
+musicians
+invite
+Ipswich
+selling
+script
+coupled
+tap
+remark
+consist
+respectable
+pint
+optimistic
+humanity
+layout
+openly
+breed
+policemen
+Scots
+invented
+linking
+convincing
+Harold
+guide
+vocabulary
+Rob
+unacceptable
+competent
+Carrie
+spatial
+ignoring
+applicant
+swiftly
+easier
+painter
+decisive
+traders
+pretend
+bargaining
+depended
+modes
+preventing
+rage
+respective
+elite
+permanently
+seemingly
+bunch
+carers
+fathers
+engagement
+liquid
+Canterbury
+binding
+fires
+sentenced
+rebels
+founder
+ballet
+erosion
+Gould
+syndrome
+relieved
+nursing
+harmony
+Coventry
+protested
+hut
+sits
+stops
+Lamont
+bore
+instructed
+fertility
+toxic
+testament
+1957
+sickness
+stretch
+Bath
+lemon
+practise
+mix
+faster
+integral
+select
+redundant
+handle
+throne
+conceived
+polytechnic
+nerves
+belongs
+privately
+burn
+gravity
+labelled
+Alfred
+bishops
+basin
+rings
+holders
+swing
+flood
+Christie
+evolved
+sovereignty
+then
+applicants
+cows
+lion
+Virginia
+trail
+smoking
+trading
+Murray
+boxing
+amateur
+probable
+scrutiny
+tempted
+borders
+pan
+fix
+hydrogen
+accountability
+consulted
+echo
+sponsorship
+fame
+El
+lakes
+protests
+patience
+documentation
+Geoff
+backing
+search
+Mozart
+silently
+passing
+seasons
+recipe
+fetch
+auditors
+territorial
+specified
+abandon
+bombs
+Los
+mineral
+horizontal
+lined
+Robyn
+booked
+du
+cleaning
+bear
+old-fashioned
+inland
+youngest
+envisaged
+floors
+thrust
+likewise
+strengthen
+penny
+wake
+Bradford
+overseas
+consult
+cognitive
+Ralph
+dock
+reaches
+disturbed
+communists
+slim
+synthesis
+contexts
+revival
+Reading
+regulatory
+hurried
+defender
+dry
+miserable
+walks
+debates
+dancing
+isolated
+venue
+Hampshire
+resident
+rounds
+deals
+packet
+likelihood
+remaining
+induced
+guys
+temper
+comparatively
+calculations
+protecting
+holdings
+corn
+1947
+Yeltsin
+fusion
+Marxist
+conferences
+creditors
+questionnaire
+gothic
+scared
+willingness
+civilian
+shelves
+reporting
+precision
+divide
+Phillips
+overnight
+Intel
+Linda
+deputies
+Indians
+Trevor
+Juliet
+Watson
+conventions
+modified
+instant
+praise
+Des
+coin
+blown
+hiding
+galleries
+1940
+Constance
+outlook
+incurred
+adverse
+subsidiary
+tiles
+seventeenth
+Korean
+emphasised
+Eddie
+bile
+1959
+fancy
+accounting
+leaflet
+headmaster
+crack
+heels
+truck
+engage
+reporter
+plays
+Steven
+calm
+initiated
+brigade
+Dorothy
+unconscious
+convicted
+illustration
+trustees
+sustained
+alike
+End
+ideally
+entity
+tons
+sang
+telegraph
+negotiation
+opposite
+smell
+aesthetic
+wiped
+concentrating
+anonymous
+trace
+usage
+orthodox
+fulfil
+polite
+girlfriend
+lovers
+translated
+static
+intent
+cancelled
+inside
+unaware
+presidency
+corps
+assigned
+appearances
+exploit
+margins
+worldwide
+cups
+solved
+panels
+halt
+EEC
+Suffolk
+developers
+fantastic
+Lancaster
+seminar
+fashionable
+criticisms
+Cooper
+motorway
+zones
+foolish
+intake
+advances
+receipt
+rule
+regiment
+trades
+manual
+backs
+duck
+causal
+convey
+Tommy
+wee
+cleaning
+fond
+compatible
+Southampton
+inclusion
+Herbert
+finding
+lengthy
+two-thirds
+tent
+shed
+implicit
+cameras
+dare
+abolition
+Romania
+pigs
+lace
+dedicated
+cuts
+perceptions
+ft
+counts
+earning
+kiss
+confirmation
+dual
+confronted
+twenty-five
+mistress
+assignment
+propaganda
+toys
+Arsenal
+Eleanor
+critic
+curiosity
+republican
+pipes
+reduces
+shooting
+cheerful
+reporting
+plea
+distinguished
+subjective
+pie
+priests
+returns
+tel
+labels
+width
+relaxation
+advertisement
+white
+smoke
+pencil
+legally
+following
+lacked
+surviving
+disadvantage
+ruling
+forward
+sleeping
+owl
+adequately
+reproduction
+rewards
+architects
+rear
+Shelley
+exotic
+ambassador
+1914
+camps
+displays
+passages
+gazed
+timetable
+salad
+purple
+cautious
+visiting
+Turner
+aggregate
+ignorance
+anticipated
+Parker
+redundancy
+array
+penalties
+renaissance
+theology
+try
+warn
+process
+ethical
+major
+proving
+plain
+protestant
+grid
+tenth
+takeover
+canvas
+Ted
+skull
+highlighted
+jokes
+beat
+pools
+twins
+borne
+criticized
+chemical
+omitted
+revision
+sincerely
+prizes
+salvation
+teenage
+responding
+indicators
+repairs
+amnesty
+comparing
+large-scale
+yield
+Claire
+photography
+disastrous
+thumb
+dying
+jointly
+kilometres
+scholars
+ace
+lump
+delicious
+confidential
+clash
+market
+underground
+Blanche
+armed
+destination
+witnessed
+parameters
+costly
+restraint
+bit
+1958
+shaped
+rode
+tips
+prosperity
+diamond
+fury
+instinct
+reserved
+valuation
+contacted
+subsidies
+Hunt
+collector
+Darwin
+sponsored
+compound
+strengths
+sank
+defences
+lifestyle
+prejudice
+announce
+apparatus
+dot
+shoe
+blanket
+wound
+Christine
+hunger
+cabin
+photographer
+stay
+preservation
+calendar
+assessments
+colony
+Katherine
+thorough
+medal
+trips
+washing
+eliminate
+breathe
+actress
+provinces
+helicopter
+mist
+clue
+dominance
+relaxed
+analysts
+searched
+grin
+Czechoslovakia
+hitting
+inability
+portion
+restrict
+Gray
+conspiracy
+Nicholson
+mercy
+log
+autonomous
+intends
+solidarity
+jail
+genius
+1920s
+pilots
+incorporate
+atomic
+blade
+frozen
+1956
+colourful
+discharge
+injured
+mask
+provided that
+Trent
+ease
+draws
+retire
+supposed
+ml
+angrily
+sigh
+stamp
+adjust
+ferry
+concessions
+majesty
+Gilbert
+pylori
+uniform
+adjusted
+ashamed
+admired
+alpha
+referee
+1944
+Lebanon
+respondents
+Collins
+rested
+reconstruction
+flown
+individually
+jaw
+submission
+efficiently
+bitterly
+glorious
+pour
+illustrates
+Angeles
+amid
+convert
+wicked
+provoked
+Chapman
+elbow
+videos
+coherent
+annually
+le
+rising
+disciplines
+cliff
+boyfriend
+novel
+controls
+sweat
+depths
+Claudia
+cave
+balanced
+strikes
+stretching
+pains
+Close
+Tokyo
+Portugal
+racism
+priced
+delightful
+evaluate
+arbitrary
+Chicago
+Richards
+signature
+reversed
+heroes
+clarity
+hit
+screamed
+adjacent
+lid
+psychiatric
+comprising
+honey
+temptation
+beam
+immigration
+recordings
+worrying
+weird
+practitioner
+unchanged
+calculation
+tutor
+politician
+rolling
+Athens
+expedition
+electorate
+evolutionary
+scattered
+abolished
+researcher
+ports
+Chester
+dilemma
+Carl
+loaded
+IMF
+flung
+intimate
+fever
+parallel
+tight
+miracle
+including
+lawn
+biology
+Lothian
+failures
+breaks
+Angela
+shy
+appraisal
+sporting
+wines
+cleaned
+disciplinary
+occurrence
+smile
+formidable
+lexical
+graduates
+fined
+cooking
+privacy
+needles
+Reagan
+Black
+Ed
+sink
+march
+equations
+grim
+narrative
+HP
+charts
+polls
+Paula
+express
+OK
+limbs
+decorated
+high
+addressing
+proceeds
+pact
+Madame
+Merseyside
+revenge
+vice-president
+far from
+proceeded
+airline
+minerals
+killing
+accused
+double
+gradual
+descent
+mount
+homeless
+courtesy
+enhanced
+supermarket
+Blake
+Cheshire
+interfere
+organisers
+managing
+monitoring
+coming
+rat
+supporting
+Marcus
+trace
+approve
+delays
+pm
+Reynolds
+please
+yo
+programming
+training
+renewed
+Hull
+invention
+writings
+back
+excess
+planes
+legacy
+challenges
+gaps
+dug
+Jason
+interpretations
+smallest
+pulse
+analyses
+Ashley
+rubber
+retired
+specimen
+outdoor
+shooting
+chosen
+embarrassing
+wrist
+atoms
+Hereford
+smoking
+incidentally
+preferred
+renewal
+Japanese
+vanished
+hook
+loudly
+bride
+Annie
+interactions
+bizarre
+gospel
+realm
+mainland
+knit
+appalling
+exchanges
+surgeon
+crews
+orientation
+twisted
+occupy
+flame
+hatred
+exceed
+Maurice
+laboratories
+reviews
+Bosnia
+agreed
+Butler
+utility
+conversations
+imaginative
+pursuing
+flour
+accepted
+wartime
+governing
+Reid
+object
+cutting
+indirectly
+governed
+palestinian
+vocational
+von
+modification
+slopes
+allegedly
+parade
+free
+aluminium
+Al
+movies
+biscuits
+motive
+register
+merchants
+hip
+print
+rabbits
+remedies
+stress
+trainer
+welcome
+wound
+Geneva
+configuration
+boost
+puzzled
+encounter
+axis
+no matter how
+Clive
+worldwide
+Arnold
+Allan
+lamb
+laser
+vegetation
+reluctance
+jazz
+databases
+strengthened
+protocol
+enjoyment
+organisational
+knitting
+census
+calculate
+handicapped
+mucosa
+theirs
+1951
+advertisements
+eldest
+Carol
+1936
+eventual
+husbands
+fur
+followers
+wasted
+pump
+lifting
+practised
+yacht
+toes
+stimulate
+speeches
+1953
+traced
+ensured
+arrow
+journals
+weekends
+spontaneous
+appoint
+1949
+binding
+superintendent
+vivid
+corporations
+organisms
+celebrated
+mice
+motives
+torn
+tie
+dies
+1954
+waiting
+classified
+organs
+lack
+worlds
+nineteenth-century
+faithful
+shield
+withdrew
+reckoned
+north-west
+rolling
+missiles
+noisy
+hire
+organising
+quote
+sofa
+reminder
+Venice
+ministerial
+A
+daylight
+injection
+graph
+exchanged
+prayers
+boost
+preparations
+borrowing
+innovative
+strongest
+audiences
+disclosure
+confrontation
+constitutes
+burnt
+liaison
+armies
+strangely
+wounds
+Hewlett-Packard
+controlled
+Newman
+cease
+incentives
+extends
+Mitchell
+echoed
+facilitate
+resentment
+shout
+cage
+gloves
+1990s
+exploring
+saving
+Leonard
+crossing
+choir
+Gibson
+exit
+Sydney
+assumes
+woodland
+fog
+underneath
+promises
+Ellen
+nationalism
+Kenya
+commentators
+Ferguson
+metals
+reasoning
+acids
+hunt
+pop
+1946
+dirt
+Texas
+Keynes
+conceptual
+aiming
+stating
+technically
+heading
+economically
+constituted
+Union
+maker
+blowing
+touching
+tours
+erected
+ambitions
+spare
+chorus
+Bond
+bladder
+settings
+dividends
+18th
+Gaulle
+unusually
+phases
+adapt
+colitis
+exploded
+Nelson
+civic
+bells
+gall
+Macdonald
+unwilling
+retreat
+booklet
+enforce
+defining
+goodbye
+meaningful
+Gregory
+pine
+borrowed
+bow
+disturbing
\ No newline at end of file
diff --git a/setup/src/Magento/Setup/Model/Complex/Pattern.php b/setup/src/Magento/Setup/Model/Complex/Pattern.php
index ee1356ff4d174ea03ad144d2db8b2b6a2ed951d7..a6569b3657de9373b4d459650087a9b177ef5658 100644
--- a/setup/src/Magento/Setup/Model/Complex/Pattern.php
+++ b/setup/src/Magento/Setup/Model/Complex/Pattern.php
@@ -104,7 +104,7 @@ class Pattern
         foreach ($this->getHeaders() as $key) {
             if (isset($row[$key])) {
                 if (is_callable($row[$key])) {
-                    $row[$key] = call_user_func($row[$key], $index);
+                    $row[$key] = call_user_func($row[$key], $index, $generatorKey);
                 } else {
                     $row[$key] = str_replace('%s', $index, $row[$key]);
                 }
diff --git a/setup/src/Magento/Setup/Model/DataGenerator.php b/setup/src/Magento/Setup/Model/DataGenerator.php
new file mode 100644
index 0000000000000000000000000000000000000000..7ea52bdb26aea5067d98726c52aab00ad8366d6b
--- /dev/null
+++ b/setup/src/Magento/Setup/Model/DataGenerator.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+/**
+ * A custom adapter that allows generating arbitrary descriptions
+ */
+namespace Magento\Setup\Model;
+
+class DataGenerator
+{
+    /**
+     * Location for dictionary file.
+     *
+     * @var string
+     */
+    private $dictionaryFile;
+
+    /**
+     * Dictionary data.
+     *
+     * @var array
+     */
+    private $dictionaryData;
+
+    /**
+     * Map of generated values
+     *
+     * @var array
+     */
+    private $generatedValues;
+
+    /**
+     * DataGenerator constructor.
+     *
+     * @param string $dictionaryFile
+     */
+    public function __construct($dictionaryFile)
+    {
+        $this->dictionaryFile = $dictionaryFile;
+        $this->readData();
+        $this->generatedValues = [];
+    }
+
+    /**
+     * Read data from file.
+     *
+     * @return void
+     */
+    protected function readData()
+    {
+        $f = fopen($this->dictionaryFile, 'r');
+        while (!feof($f) && is_array($line = fgetcsv($f))) {
+            $this->dictionaryData[] = $line[0];
+        }
+    }
+
+    /**
+     * Generate string of random word data.
+     *
+     * @param int $minAmountOfWords
+     * @param int $maxAmountOfWords
+     * @param string|null $key
+     * @return string
+     */
+    public function generate($minAmountOfWords, $maxAmountOfWords, $key = null)
+    {
+        $numberOfWords = mt_rand($minAmountOfWords, $maxAmountOfWords);
+        $result = '';
+
+        if ($key === null || !array_key_exists($key, $this->generatedValues)) {
+            for ($i = 0; $i < $numberOfWords; $i++) {
+                $result .= ' ' . $this->dictionaryData[mt_rand(0, count($this->dictionaryData) - 1)];
+            }
+            $result = trim($result);
+
+            if ($key !== null) {
+                $this->generatedValues[$key] = $result;
+            }
+        } else {
+            $result = $this->generatedValues[$key];
+        }
+        return $result;
+    }
+}
diff --git a/setup/src/Magento/Setup/Module/I18n/Context.php b/setup/src/Magento/Setup/Module/I18n/Context.php
index 9db97153972cbccc96a13f8380d17c27b4e186f5..a2137e3d9bd00851431e45f6a1629f157415ecb1 100644
--- a/setup/src/Magento/Setup/Module/I18n/Context.php
+++ b/setup/src/Magento/Setup/Module/I18n/Context.php
@@ -93,7 +93,7 @@ class Context
      *
      * @param string $type
      * @param array $value
-     * @return string
+     * @return string|null
      * @throws \InvalidArgumentException
      */
     public function buildPathToLocaleDirectoryByContext($type, $value)
@@ -111,6 +111,7 @@ class Context
             default:
                 throw new \InvalidArgumentException(sprintf('Invalid context given: "%s".', $type));
         }
-        return $path . '/' . self::LOCALE_DIRECTORY . '/';
+
+        return (null === $path) ? null : $path . '/' . self::LOCALE_DIRECTORY . '/';
     }
 }
diff --git a/setup/src/Magento/Setup/Module/I18n/Pack/Writer/File/AbstractFile.php b/setup/src/Magento/Setup/Module/I18n/Pack/Writer/File/AbstractFile.php
index 00a1361c3c76170f8fef3b844f36be5f15e4ef6b..2495a9209e2358da9346ad79690a5de5d344d211 100644
--- a/setup/src/Magento/Setup/Module/I18n/Pack/Writer/File/AbstractFile.php
+++ b/setup/src/Magento/Setup/Module/I18n/Pack/Writer/File/AbstractFile.php
@@ -121,6 +121,11 @@ abstract class AbstractFile implements WriterInterface
                 } catch (\InvalidArgumentException $e) {
                     throw new \InvalidArgumentException($e->getMessage() . ' Row #' . ($key + 1) . '.');
                 }
+
+                if (null === $path) {
+                    continue;
+                }
+
                 $filename = $path . $this->_locale . '.' . $this->_getFileExtension();
                 $files[$filename][$phrase->getPhrase()] = $phrase;
             }
diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/AttributeSetsFixtureTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/AttributeSetsFixtureTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..674f444fbde10666b75aa5dadfef3719e3177152
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/AttributeSetsFixtureTest.php
@@ -0,0 +1,288 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Fixtures;
+
+use \Magento\Setup\Fixtures\AttributeSetsFixture;
+
+/**
+ * @SuppressWarnings(PHPMD)
+ */
+class AttributeSetsFixtureTest extends \PHPUnit_Framework_TestCase
+{
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Fixtures\FixtureModel
+     */
+    private $fixtureModelMock;
+
+    /**
+     * @var \Magento\Setup\Fixtures\AttributeSetsFixture
+     */
+    private $model;
+
+    public function setUp()
+    {
+        $this->fixtureModelMock = $this->getMockBuilder(\Magento\Setup\Fixtures\FixtureModel::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->model = new AttributeSetsFixture($this->fixtureModelMock);
+    }
+
+    public function testExecute()
+    {
+        $attributeSets = [
+            'attribute_set' => [
+                [
+                    'name' => 'attribute set name',
+                    'attributes' => [
+                        'attribute' => [
+                            [
+                                'is_required' => 1,
+                                'is_visible_on_front' => 1,
+                                'is_visible_in_advanced_search' => 1,
+                                'is_filterable' => 1,
+                                'is_filterable_in_search' => 1,
+                                'default_value' => 'yellow1',
+                                'attribute_code' => 'mycolor',
+                                'is_searchable' => '1',
+                                'frontend_label' => 'mycolor',
+                                'frontend_input' => 'select',
+                                'options' => [
+                                    'option' => [
+                                        [
+                                            'label' => 'yellow1',
+                                            'value' => ''
+                                        ]
+                                    ]
+                                ]
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ];
+        $attributeSet = $attributeSets['attribute_set'][0];
+
+        // Mock Attribute Sets
+        $attributeSetMock = $this->getMockBuilder(\Magento\Eav\Api\Data\AttributeSetInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $attributeSetMock->expects($this->once())
+            ->method('setAttributeSetName')
+            ->with("attribute set name");
+        $attributeSetMock->expects($this->once())
+            ->method('setEntityTypeId')
+            ->with(\Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE);
+        $attributeSetMock->expects($this->any())
+            ->method('getAttributeSetName')
+            ->willReturn($attributeSet['name']);
+
+        $attributeSetFactoryMock = $this->getMockBuilder(\Magento\Eav\Api\Data\AttributeSetInterfaceFactory::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $attributeSetFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($attributeSetMock);
+
+        $attributeSetManagementMock = $this->getMockBuilder(\Magento\Catalog\Api\AttributeSetManagementInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $attributeSetManagementMock->expects($this->once())
+            ->method('create')
+            ->with($attributeSetMock, '4')
+            ->willReturn($attributeSetMock);
+
+        //Mock Attribute Groups
+        $attributeGroupMock = $this->getMockBuilder(\Magento\Eav\Api\Data\AttributeGroupInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $attributeGroupMock->expects($this->once())
+            ->method('setAttributeGroupName')
+            ->with($attributeSetMock->getAttributeSetName() . ' - Group');
+        $attributeGroupMock->expects($this->once())
+            ->method('setAttributeSetId')
+            ->with($attributeSetMock->getAttributeSetId());
+
+        $attributeGroupFactoryMock = $this->getMockBuilder(\Magento\Eav\Api\Data\AttributeGroupInterfaceFactory::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $attributeGroupFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($attributeGroupMock);
+
+        $productAttributeGroupRepoMock = $this->getMockBuilder(
+            \Magento\Catalog\Api\ProductAttributeGroupRepositoryInterface::class
+        )
+            ->disableOriginalConstructor()
+            ->getMock();
+        $productAttributeGroupRepoMock->expects($this->once())
+            ->method('save')
+            ->with($attributeGroupMock)
+            ->willReturn($attributeGroupMock);
+
+        // Mock Attributes
+        $attributeMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductAttributeInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $attributeFactoryMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductAttributeInterfaceFactory::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $attributeFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($attributeMock);
+
+        //Mock Attribute Options
+        $optionMock = $this->getMockBuilder(\Magento\Eav\Api\Data\AttributeOptionInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $optionFactoryMock = $this->getMockBuilder(\Magento\Eav\Api\Data\AttributeOptionInterfaceFactory::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $optionFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($optionMock);
+
+        $productAttributeRepoMock = $this->getMockBuilder(
+            \Magento\Catalog\Api\ProductAttributeRepositoryInterface::class
+        )
+            ->disableOriginalConstructor()
+            ->getMock();
+        $productAttributeRepoMock->expects($this->once())
+            ->method('save')
+            ->with($attributeMock)
+            ->willReturn($attributeMock);
+
+        $productAttributeManagementMock = $this->getMockBuilder(
+            \Magento\Catalog\Api\ProductAttributeManagementInterface::class
+        )
+            ->disableOriginalConstructor()
+            ->getMock();
+        $productAttributeManagementMock->expects($this->once())
+            ->method('assign')
+            ->willReturn($attributeMock->getAttributeId());
+
+        $objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManager\ObjectManager::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $objectManagerMock->expects($this->at(0))
+            ->method('create')
+            ->willReturn($attributeSetManagementMock);
+        $objectManagerMock->expects($this->at(1))
+            ->method('create')
+            ->willReturn($productAttributeGroupRepoMock);
+        $objectManagerMock->expects($this->at(2))
+            ->method('create')
+            ->willReturn($attributeSetFactoryMock);
+        $objectManagerMock->expects($this->at(3))
+            ->method('create')
+            ->willReturn($attributeGroupFactoryMock);
+        $objectManagerMock->expects($this->at(4))
+            ->method('create')
+            ->willReturn($productAttributeRepoMock);
+        $objectManagerMock->expects($this->at(5))
+            ->method('create')
+            ->willReturn($productAttributeManagementMock);
+        $objectManagerMock->expects($this->at(6))
+            ->method('create')
+            ->willReturn($attributeFactoryMock);
+        $objectManagerMock->expects($this->at(7))
+            ->method('create')
+            ->willReturn($optionFactoryMock);
+
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->willReturn($attributeSets);
+
+        $this->fixtureModelMock
+            ->expects($this->any())
+            ->method('getObjectManager')
+            ->will($this->returnValue($objectManagerMock));
+
+        $this->model->execute();
+    }
+
+    public function testNoFixtureConfigValue()
+    {
+        $attributeSetManagementMock = $this->getMockBuilder(\Magento\Catalog\Api\AttributeSetManagementInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $attributeSetManagementMock->expects($this->never())->method('create');
+
+        $productAttributeGroupRepoMock = $this->getMockBuilder(
+            \Magento\Catalog\Api\ProductAttributeGroupRepositoryInterface::class
+        )
+            ->disableOriginalConstructor()
+            ->getMock();
+        $productAttributeGroupRepoMock->expects($this->never())->method('save');
+
+        $productAttributeRepoMock = $this->getMockBuilder(
+            \Magento\Catalog\Api\ProductAttributeRepositoryInterface::class
+        )
+            ->disableOriginalConstructor()
+            ->getMock();
+        $productAttributeRepoMock->expects($this->never())->method('save');
+
+        $productAttributeManagementMock = $this->getMockBuilder(
+            \Magento\Catalog\Api\ProductAttributeManagementInterface::class
+        )
+            ->disableOriginalConstructor()
+            ->getMock();
+        $productAttributeManagementMock->expects($this->never())->method('assign');
+
+        $objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManager\ObjectManager::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $objectManagerMock->expects($this->never())
+            ->method('create')
+            ->with($this->equalTo(\Magento\Catalog\Api\AttributeSetManagementInterface::class))
+            ->willReturn($attributeSetManagementMock);
+        $objectManagerMock->expects($this->never())
+            ->method('create')
+            ->with($this->equalTo(\Magento\Catalog\Api\ProductAttributeGroupRepositoryInterface::class))
+            ->willReturn($productAttributeGroupRepoMock);
+        $objectManagerMock->expects($this->never())
+            ->method('create')
+            ->with($this->equalTo(\Magento\Catalog\Api\ProductAttributeRepositoryInterface::class))
+            ->willReturn($productAttributeRepoMock);
+        $objectManagerMock->expects($this->never())
+            ->method('create')
+            ->with($this->equalTo(\Magento\Catalog\Api\ProductAttributeManagementInterface::class))
+            ->willReturn($productAttributeManagementMock);
+
+        $this->fixtureModelMock
+            ->expects($this->never())
+            ->method('getObjectManager')
+            ->will($this->returnValue($objectManagerMock));
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->willReturn(null);
+
+        $this->model->execute();
+    }
+
+    public function testGetActionTitle()
+    {
+        $this->assertSame('Generating attribute sets', $this->model->getActionTitle());
+    }
+
+    public function testIntroduceParamLabels()
+    {
+        $this->assertSame([
+            'attribute_sets' => 'Attribute Sets'
+        ], $this->model->introduceParamLabels());
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/ConfigurableProductsFixtureTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/ConfigurableProductsFixtureTest.php
index 7e89f7d807ed8704156fcffd5252185c0a2e0e54..7f2676c53e232ef152b9ad23a990b40f891e7115 100644
--- a/setup/src/Magento/Setup/Test/Unit/Fixtures/ConfigurableProductsFixtureTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/ConfigurableProductsFixtureTest.php
@@ -23,16 +23,25 @@ class ConfigurableProductsFixtureTest extends \PHPUnit_Framework_TestCase
 
     public function setUp()
     {
-        $this->fixtureModelMock = $this->getMock(\Magento\Setup\Fixtures\FixtureModel::class, [], [], '', false);
+        $this->fixtureModelMock = $this->getMockBuilder(\Magento\Setup\Fixtures\FixtureModel::class)
+            ->disableOriginalConstructor()
+            ->getMock();
 
         $this->model = new ConfigurableProductsFixture($this->fixtureModelMock);
     }
 
+    /**
+     * @SuppressWarnings(PHPMD)
+     */
     public function testExecute()
     {
-        $importMock = $this->getMock(\Magento\ImportExport\Model\Import::class, [], [], '', false);
+        $importMock = $this->getMockBuilder(\Magento\ImportExport\Model\Import::class)
+            ->disableOriginalConstructor()
+            ->getMock();
 
-        $contextMock = $this->getMock(\Magento\Framework\Model\ResourceModel\Db\Context::class, [], [], '', false);
+        $contextMock = $this->getMockBuilder(\Magento\Framework\Model\ResourceModel\Db\Context::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $abstractDbMock = $this->getMockForAbstractClass(
             \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
             [$contextMock],
@@ -46,7 +55,9 @@ class ConfigurableProductsFixtureTest extends \PHPUnit_Framework_TestCase
             ->method('getAllChildren')
             ->will($this->returnValue([1]));
 
-        $categoryMock = $this->getMock(\Magento\Catalog\Model\Category::class, [], [], '', false);
+        $categoryMock = $this->getMockBuilder(\Magento\Catalog\Model\Category::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $categoryMock->expects($this->once())
             ->method('getResource')
             ->will($this->returnValue($abstractDbMock));
@@ -60,12 +71,16 @@ class ConfigurableProductsFixtureTest extends \PHPUnit_Framework_TestCase
             ->method('load')
             ->willReturnSelf();
 
-        $storeMock = $this->getMock(\Magento\Store\Model\Store::class, [], [], '', false);
+        $storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $storeMock->expects($this->once())
             ->method('getRootCategoryId')
             ->will($this->returnValue([2]));
 
-        $websiteMock = $this->getMock(\Magento\Store\Model\Website::class, [], [], '', false);
+        $websiteMock = $this->getMockBuilder(\Magento\Store\Model\Website::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $websiteMock->expects($this->once())
             ->method('getCode')
             ->will($this->returnValue('website_code'));
@@ -73,15 +88,18 @@ class ConfigurableProductsFixtureTest extends \PHPUnit_Framework_TestCase
             ->method('getGroups')
             ->will($this->returnValue([$storeMock]));
 
-        $storeManagerMock = $this->getMock(\Magento\Store\Model\StoreManager::class, [], [], '', false);
+        $storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManager::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $storeManagerMock->expects($this->once())
             ->method('getWebsites')
             ->will($this->returnValue([$websiteMock]));
 
         $source = $this->getMockBuilder(Generator::class)->disableOriginalConstructor()->getMock();
 
-        $objectManagerMock = $this->getMock(\Magento\Framework\ObjectManager\ObjectManager::class, [], [], '', false);
-
+        $objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManager\ObjectManager::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $objectManagerMock->expects($this->at(0))
             ->method('get')
             ->with(\Magento\Store\Model\StoreManager::class)
@@ -103,14 +121,61 @@ class ConfigurableProductsFixtureTest extends \PHPUnit_Framework_TestCase
         $importMock->expects($this->once())->method('validateSource')->with($source)->willReturn(1);
         $importMock->expects($this->once())->method('importSource')->willReturn(1);
 
+        $valuesMap = [
+            ['configurable_products', 0, 1],
+            ['simple_products', 0, 1],
+            ['search_terms', null, ['search_term' =>[['term' => 'iphone 6', 'count' => '1']]]],
+            ['configurable_products_variation', 3, 1],
+            [
+                'search_config',
+                null,
+                [
+                    'max_amount_of_words_description' => '200',
+                    'max_amount_of_words_short_description' => '20',
+                    'min_amount_of_words_description' => '20',
+                    'min_amount_of_words_short_description' => '5'
+                ]
+            ],
+            ['attribute_sets',
+                null,
+                [
+                    'attribute_set' => [
+                        [
+                            'name' => 'attribute set name',
+                            'attributes' => [
+                                'attribute' => [
+                                    [
+                                        'is_required' => 1,
+                                        'is_visible_on_front' => 1,
+                                        'is_visible_in_advanced_search' => 1,
+                                        'is_filterable' => 1,
+                                        'is_filterable_in_search' => 1,
+                                        'default_value' => 'yellow1',
+                                        'attribute_code' => 'mycolor',
+                                        'is_searchable' => '1',
+                                        'frontend_label' => 'mycolor',
+                                        'frontend_input' => 'select',
+                                        'options' => [
+                                            'option' => [
+                                                [
+                                                    'label' => 'yellow1',
+                                                    'value' => ''
+                                                ]
+                                            ]
+                                        ]
+                                    ]
+                                ]
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ];
+
         $this->fixtureModelMock
             ->expects($this->any())
             ->method('getValue')
-            ->willReturnMap([
-                ['configurable_products', 0, 1],
-                ['configurable_products_variation', 3, 1],
-            ]);
-
+            ->will($this->returnValueMap($valuesMap));
         $this->fixtureModelMock
             ->expects($this->atLeastOnce())
             ->method('getObjectManager')
@@ -121,11 +186,15 @@ class ConfigurableProductsFixtureTest extends \PHPUnit_Framework_TestCase
 
     public function testNoFixtureConfigValue()
     {
-        $importMock = $this->getMock(\Magento\ImportExport\Model\Import::class, [], [], '', false);
+        $importMock = $this->getMockBuilder(\Magento\ImportExport\Model\Import::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $importMock->expects($this->never())->method('validateSource');
         $importMock->expects($this->never())->method('importSource');
 
-        $objectManagerMock = $this->getMock(\Magento\Framework\ObjectManager\ObjectManager::class, [], [], '', false);
+        $objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManager\ObjectManager::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $objectManagerMock->expects($this->never())
             ->method('create')
             ->with($this->equalTo(\Magento\ImportExport\Model\Import::class))
@@ -151,7 +220,7 @@ class ConfigurableProductsFixtureTest extends \PHPUnit_Framework_TestCase
     public function testIntroduceParamLabels()
     {
         $this->assertSame([
-            'configurable_products' => 'Configurable products',
+            'configurable_products' => 'Configurable products'
         ], $this->model->introduceParamLabels());
     }
 }
diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/FixtureModelTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/FixtureModelTest.php
index ee1369bd15d5a46f084a504fdfedbf61eb53f8bc..32b00312880dee07e0f172f97df4668596088abd 100644
--- a/setup/src/Magento/Setup/Test/Unit/Fixtures/FixtureModelTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/FixtureModelTest.php
@@ -55,11 +55,19 @@ class FixtureModelTest extends \PHPUnit_Framework_TestCase
             false
         );
 
-        $fileParserMock = $this->getMock(\Magento\Framework\Xml\Parser::class, ['load', 'xmlToArray'], [], '', false);
-        $fileParserMock->expects($this->once())->method('xmlToArray')->willReturn(
+        $fileParserMock = $this->getMock(\Magento\Framework\Xml\Parser::class, ['getDom', 'xmlToArray'], [], '', false);
+        $fileParserMock->expects($this->exactly(2))->method('xmlToArray')->willReturn(
             ['config' => [ 'profile' => ['some_key' => 'some_value']]]
         );
-        $fileParserMock->expects($this->once())->method('load')->with('config.file')->willReturn($fileParserMock);
+
+        $domMock = $this->getMock(\DOMDocument::class, ['load', 'xinclude'], [], '', false);
+        $domMock->expects($this->once())->method('load')->with('config.file')->willReturn(
+            $fileParserMock->xmlToArray()
+        );
+        $domMock->expects($this->once())->method('xinclude');
+
+        $fileParserMock->expects($this->exactly(2))->method('getDom')->willReturn($domMock);
+
         $this->model = new FixtureModel($reindexCommandMock, $fileParserMock);
         $this->model->loadConfig('config.file');
         $this->assertSame('some_value', $this->model->getValue('some_key'));
diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/SimpleProductsFixtureTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/SimpleProductsFixtureTest.php
index 913b2a1e3f02048ac4c61b894e287791ce421207..5e24863483992ce4ada367846fc9c3350a5082b7 100644
--- a/setup/src/Magento/Setup/Test/Unit/Fixtures/SimpleProductsFixtureTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/SimpleProductsFixtureTest.php
@@ -22,19 +22,28 @@ class SimpleProductsFixtureTest extends \PHPUnit_Framework_TestCase
 
     public function setUp()
     {
-        $this->fixtureModelMock = $this->getMock(\Magento\Setup\Fixtures\FixtureModel::class, [], [], '', false);
+        $this->fixtureModelMock = $this->getMockBuilder(\Magento\Setup\Fixtures\FixtureModel::class)
+            ->disableOriginalConstructor()
+            ->getMock();
 
         $this->model = new SimpleProductsFixture($this->fixtureModelMock);
     }
 
+    /**
+     * @SuppressWarnings(PHPMD)
+     */
     public function testExecute()
     {
-        $storeMock = $this->getMock(\Magento\Store\Model\Store::class, [], [], '', false);
+        $storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $storeMock->expects($this->once())
             ->method('getRootCategoryId')
             ->willReturn(1);
 
-        $websiteMock = $this->getMock(\Magento\Store\Model\Website::class, [], [], '', false);
+        $websiteMock = $this->getMockBuilder(\Magento\Store\Model\Website::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $websiteMock->expects($this->once())
             ->method('getCode')
             ->willReturn('website_code');
@@ -42,14 +51,24 @@ class SimpleProductsFixtureTest extends \PHPUnit_Framework_TestCase
             ->method('getGroups')
             ->willReturn([$storeMock]);
 
-        $storeManagerMock = $this->getMock(\Magento\Store\Model\StoreManager::class, [], [], '', false);
+        $storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManager::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $storeManagerMock->expects($this->once())
             ->method('getWebsites')
             ->willReturn([$websiteMock]);
 
-        $importMock = $this->getMock(\Magento\ImportExport\Model\Import::class, [], [], '', false);
+        $source = $this->getMockBuilder(\Magento\Setup\Model\Generator::class)->disableOriginalConstructor()->getMock();
+
+        $importMock = $this->getMockBuilder(\Magento\ImportExport\Model\Import::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $importMock->expects($this->once())->method('validateSource')->with($source)->willReturn(1);
+        $importMock->expects($this->once())->method('importSource')->willReturn(1);
 
-        $contextMock = $this->getMock(\Magento\Framework\Model\ResourceModel\Db\Context::class, [], [], '', false);
+        $contextMock = $this->getMockBuilder(\Magento\Framework\Model\ResourceModel\Db\Context::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $abstractDbMock = $this->getMockForAbstractClass(
             \Magento\Framework\Model\ResourceModel\Db\AbstractDb::class,
             [$contextMock],
@@ -63,7 +82,9 @@ class SimpleProductsFixtureTest extends \PHPUnit_Framework_TestCase
             ->method('getAllChildren')
             ->will($this->returnValue([1]));
 
-        $categoryMock = $this->getMock(\Magento\Catalog\Model\Category::class, [], [], '', false);
+        $categoryMock = $this->getMockBuilder(\Magento\Catalog\Model\Category::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $categoryMock->expects($this->once())
             ->method('getResource')
             ->willReturn($abstractDbMock);
@@ -77,35 +98,81 @@ class SimpleProductsFixtureTest extends \PHPUnit_Framework_TestCase
             ->method('getName')
             ->willReturn('category_name');
 
-        $valueMap = [
-            [
-                \Magento\ImportExport\Model\Import::class,
-                [
-                    'data' => [
-                        'entity' => 'catalog_product',
-                        'behavior' => 'append',
-                        'validation_strategy' => 'validation-stop-on-errors'
-                    ]
-                ],
-                $importMock
-            ],
-            [\Magento\Store\Model\StoreManager::class, [], $storeManagerMock]
-        ];
-
-        $objectManagerMock = $this->getMock(\Magento\Framework\ObjectManager\ObjectManager::class, [], [], '', false);
-        $objectManagerMock->expects($this->exactly(2))
+        $objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManager\ObjectManager::class)
+            ->disableOriginalConstructor()
+            ->getMock();
+        $objectManagerMock->expects($this->at(0))
             ->method('create')
-            ->will($this->returnValueMap($valueMap));
-        $objectManagerMock->expects($this->once())
+            ->with(\Magento\Store\Model\StoreManager::class)
+            ->willReturn($storeManagerMock);
+        $objectManagerMock->expects($this->at(1))
             ->method('get')
             ->willReturn($categoryMock);
+        $objectManagerMock->expects($this->at(2))
+            ->method('create')
+            ->with(\Magento\Setup\Model\Generator::class)
+            ->willReturn($source);
+        $objectManagerMock->expects($this->at(3))
+            ->method('create')
+            ->with(\Magento\ImportExport\Model\Import::class)
+            ->willReturn($importMock);
 
+        $valuesMap = [
+            ['simple_products', 0, 1],
+            ['configurable_products', 0, 1],
+            ['search_terms', null, ['search_term' =>[['term' => 'iphone 6', 'count' => '1']]]],
+            [
+                'search_config',
+                null,
+                [
+                    'max_amount_of_words_description' => '200',
+                    'max_amount_of_words_short_description' => '20',
+                    'min_amount_of_words_description' => '20',
+                    'min_amount_of_words_short_description' => '5'
+                ]
+            ],
+            [
+                'attribute_sets',
+                null,
+                [
+                    'attribute_set' => [
+                        [
+                            'name' => 'attribute set name',
+                            'attributes' => [
+                                'attribute' => [
+                                    [
+                                        'is_required' => 1,
+                                        'is_visible_on_front' => 1,
+                                        'is_visible_in_advanced_search' => 1,
+                                        'is_filterable' => 1,
+                                        'is_filterable_in_search' => 1,
+                                        'default_value' => 'yellow1',
+                                        'attribute_code' => 'mycolor',
+                                        'is_searchable' => '1',
+                                        'frontend_label' => 'mycolor',
+                                        'frontend_input' => 'select',
+                                        'options' => [
+                                            'option' => [
+                                                [
+                                                    'label' => 'yellow1',
+                                                    'value' => ''
+                                                ]
+                                            ]
+                                        ]
+                                    ]
+                                ]
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ];
         $this->fixtureModelMock
-            ->expects($this->once())
+            ->expects($this->any())
             ->method('getValue')
-            ->willReturn(1);
+            ->will($this->returnValueMap($valuesMap));
         $this->fixtureModelMock
-            ->expects($this->exactly(3))
+            ->expects($this->any())
             ->method('getObjectManager')
             ->willReturn($objectManagerMock);
 
@@ -114,11 +181,15 @@ class SimpleProductsFixtureTest extends \PHPUnit_Framework_TestCase
 
     public function testNoFixtureConfigValue()
     {
-        $importMock = $this->getMock(\Magento\ImportExport\Model\Import::class, [], [], '', false);
+        $importMock = $this->getMockBuilder(\Magento\ImportExport\Model\Import::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $importMock->expects($this->never())->method('validateSource');
         $importMock->expects($this->never())->method('importSource');
 
-        $objectManagerMock = $this->getMock(\Magento\Framework\ObjectManager\ObjectManager::class, [], [], '', false);
+        $objectManagerMock = $this->getMockBuilder(\Magento\Framework\ObjectManager\ObjectManager::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $objectManagerMock->expects($this->never())
             ->method('create')
             ->with($this->equalTo(\Magento\ImportExport\Model\Import::class))
@@ -129,7 +200,7 @@ class SimpleProductsFixtureTest extends \PHPUnit_Framework_TestCase
             ->method('getObjectManager')
             ->will($this->returnValue($objectManagerMock));
         $this->fixtureModelMock
-            ->expects($this->once())
+            ->expects($this->any())
             ->method('getValue')
             ->willReturn(false);
 
diff --git a/setup/src/Magento/Setup/Test/Unit/Model/Complex/PatternTest.php b/setup/src/Magento/Setup/Test/Unit/Model/Complex/PatternTest.php
index 4adac2b0fb0edadf4a22d36f4fcd6f44d5357e35..0123fcd8ca032a79ff0b4ff5616747d8fb517bc7 100644
--- a/setup/src/Magento/Setup/Test/Unit/Model/Complex/PatternTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Model/Complex/PatternTest.php
@@ -42,8 +42,8 @@ class PatternTest extends \PHPUnit_Framework_TestCase
                     [
                         'id' => '%s',
                         'name' => 'Static',
-                        'calculated' => function ($index) {
-                            return $index * 10;
+                        'calculated' => function ($index, $generatedKey) {
+                            return $index * 10 + $generatedKey;
                         },
                     ],
                     [
@@ -53,7 +53,7 @@ class PatternTest extends \PHPUnit_Framework_TestCase
                         'name' => 'yyy %s'
                     ],
                 ],
-                'ecpectedCount'      => 3,
+                'expectedCount'      => 3,
                 'expectedRowsResult' => [
                     ['id' => '1', 'name' => 'Static', 'calculated' => 10],
                     ['id' => '',  'name' => 'xxx 1',  'calculated' => ''],
@@ -68,7 +68,7 @@ class PatternTest extends \PHPUnit_Framework_TestCase
                         'calculated' => 'calc %s',
                     ],
                 ],
-                'ecpectedCount' => 1,
+                'expectedCount' => 1,
                 'expectedRowsResult' => [
                     ['id' => '1', 'name' => 'Dynamic 1', 'calculated' => 'calc 1'],
                 ],
diff --git a/setup/src/Magento/Setup/Test/Unit/Model/DataGeneratorTest.php b/setup/src/Magento/Setup/Test/Unit/Model/DataGeneratorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..65f92488c1a62fc62a4f36be3d8140ffe118eecd
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Model/DataGeneratorTest.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Model;
+
+use Magento\Setup\Model\DataGenerator;
+
+class DataGeneratorTest extends \PHPUnit_Framework_TestCase
+{
+
+    const PATH_TO_CSV_FILE = '/_files/dictionary.csv';
+
+    /**
+     * @test
+     *
+     * @return void
+     */
+    public function testGenerate()
+    {
+        $data = file(__DIR__ . self::PATH_TO_CSV_FILE);
+        $wordCount = count($data);
+        $model = new DataGenerator(__DIR__ . self::PATH_TO_CSV_FILE);
+        $result = $model->generate($wordCount, $wordCount);
+
+        $found = false;
+        foreach ($data as $word) {
+            $found = (strpos($result, $word[0]) !== false) || $found;
+        }
+        $this->assertTrue($found);
+        $this->assertEquals($wordCount, count(explode(" ", $result)));
+    }
+
+    public function testGenerateWithKey()
+    {
+        $key = 'generate-test';
+
+        $data = file(__DIR__ . self::PATH_TO_CSV_FILE);
+        $wordCount = mt_rand(1, count($data));
+        $model = new DataGenerator(__DIR__ . self::PATH_TO_CSV_FILE);
+        $result = $model->generate($wordCount, $wordCount, $key);
+
+        $foundResult = $model->generate($wordCount, $wordCount, $key);
+
+        $this->assertEquals($wordCount, count(explode(" ", $result)));
+        $this->assertEquals($result, $foundResult);
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Model/_files/dictionary.csv b/setup/src/Magento/Setup/Test/Unit/Model/_files/dictionary.csv
new file mode 100644
index 0000000000000000000000000000000000000000..da9dfd0f0ca08670a550cbfcd2af61526f9eede1
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Model/_files/dictionary.csv
@@ -0,0 +1,5 @@
+one
+two
+three
+four
+five
\ No newline at end of file
diff --git a/setup/src/Magento/Setup/Test/Unit/Module/I18n/ContextTest.php b/setup/src/Magento/Setup/Test/Unit/Module/I18n/ContextTest.php
index fa9f915de9e8cb70484d38d8c141c12e9431fe21..9bcac1e73ccee1ce8960018231d308f0b3e2ae25 100644
--- a/setup/src/Magento/Setup/Test/Unit/Module/I18n/ContextTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Module/I18n/ContextTest.php
@@ -41,7 +41,7 @@ class ContextTest extends \PHPUnit_Framework_TestCase
     {
         $this->componentRegistrar->expects($this->any())
             ->method('getPaths')
-            ->will($this->returnValueMap($pathValues));
+            ->willReturnMap($pathValues);
         $this->context = new Context($this->componentRegistrar);
         $this->assertEquals($context, $this->context->getContextByPath($path));
     }
@@ -108,10 +108,8 @@ class ContextTest extends \PHPUnit_Framework_TestCase
             $paths[$module[1]] = $module[2];
         }
         $this->componentRegistrar->expects($this->any())
-            ->method('getPaths')
-            ->with(ComponentRegistrar::MODULE)
-            ->willReturn($paths);
-        $this->componentRegistrar->expects($this->any())->method('getPath')->will($this->returnValueMap($registrar));
+            ->method('getPath')
+            ->willReturnMap($registrar);
         $this->context = new Context($this->componentRegistrar);
         $this->assertEquals($path, $this->context->buildPathToLocaleDirectoryByContext($context[0], $context[1]));
     }
@@ -127,7 +125,22 @@ class ContextTest extends \PHPUnit_Framework_TestCase
                 [Context::CONTEXT_TYPE_MODULE, 'Magento_Module'],
                 [[ComponentRegistrar::MODULE, 'Magento_Module', BP . '/app/code/Magento/Module']]
             ],
-            ['/i18n/', [Context::CONTEXT_TYPE_THEME, 'theme/test.phtml'], []],
+            [
+                BP . '/app/design/frontend/Magento/luma/i18n/',
+                [Context::CONTEXT_TYPE_THEME, 'frontend/Magento/luma'],
+                [[ComponentRegistrar::THEME, 'frontend/Magento/luma', BP . '/app/design/frontend/Magento/luma']]
+            ],
+
+            [
+                null,
+                [Context::CONTEXT_TYPE_MODULE, 'Unregistered_Module'],
+                [[ComponentRegistrar::MODULE, 'Unregistered_Module', null]]
+            ],
+            [
+                null,
+                [Context::CONTEXT_TYPE_THEME, 'frontend/Magento/unregistered'],
+                [[ComponentRegistrar::THEME, 'frontend/Magento/unregistered', null]]
+            ],
             [BP . '/lib/web/i18n/', [Context::CONTEXT_TYPE_LIB, 'lib/web/module/test.phtml'], []],
         ];
     }
@@ -138,10 +151,8 @@ class ContextTest extends \PHPUnit_Framework_TestCase
      */
     public function testBuildPathToLocaleDirectoryByContextWithInvalidType()
     {
-        $this->componentRegistrar->expects($this->any())
-            ->method('getPaths')
-            ->with(ComponentRegistrar::MODULE)
-            ->willReturn(['module' => '/path/to/module']);
+        $this->componentRegistrar->expects($this->never())
+            ->method('getPath');
         $this->context = new Context($this->componentRegistrar);
         $this->context->buildPathToLocaleDirectoryByContext('invalid_type', 'Magento_Module');
     }
diff --git a/setup/src/Magento/Setup/Test/Unit/Module/I18n/Pack/Writer/File/CsvTest.php b/setup/src/Magento/Setup/Test/Unit/Module/I18n/Pack/Writer/File/CsvTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b97f27ba714e4dcebe015022c895d9f0d7b2a3dc
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Module/I18n/Pack/Writer/File/CsvTest.php
@@ -0,0 +1,209 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Setup\Test\Unit\Module\I18n\Pack\Writer\File;
+
+use Magento\Setup\Module\I18n\Context;
+use Magento\Setup\Module\I18n\Locale;
+use Magento\Setup\Module\I18n\Dictionary;
+use Magento\Setup\Module\I18n\Factory;
+use Magento\Setup\Module\I18n\Dictionary\Phrase;
+use Magento\Setup\Module\I18n\Pack\Writer\File\Csv;
+use Magento\Setup\Module\I18n\Dictionary\WriterInterface;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
+
+require_once __DIR__ . '/_files/ioMock.php';
+
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class CsvTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $contextMock;
+
+    /**
+     * @var Locale|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $localeMock;
+
+    /**
+     * @var Dictionary|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $dictionaryMock;
+
+    /**
+     * @var Phrase|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $phraseMock;
+
+    /**
+     * @var Factory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $factoryMock;
+
+    /**
+     * @var Csv|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $object;
+
+    /**
+     * @return void
+     */
+    protected function setUp()
+    {
+        /** @var ObjectManagerHelper $objectManagerHelper */
+        $objectManagerHelper = new ObjectManagerHelper($this);
+
+        $this->contextMock = $this->getMock(Context::class, [], [], '', false, false);
+        $this->localeMock = $this->getMock(Locale::class, [], [], '', false, false);
+        $this->dictionaryMock = $this->getMock(Dictionary::class, [], [], '', false, false);
+        $this->phraseMock = $this->getMock(Phrase::class, [], [], '', false, false);
+        $this->factoryMock = $this->getMock(Factory::class, [], [], '', false, false);
+
+        $constructorArguments = $objectManagerHelper->getConstructArguments(
+            Csv::class,
+            [
+                'context' => $this->contextMock,
+                'factory' => $this->factoryMock
+            ]
+        );
+        $this->object = $objectManagerHelper->getObject(Csv::class, $constructorArguments);
+    }
+
+    /**
+     * @param string $contextType
+     * @param array $contextValue
+     * @dataProvider writeDictionaryWithRuntimeExceptionDataProvider
+     * @expectedException \RuntimeException
+     * @return void
+     */
+    public function testWriteDictionaryWithRuntimeException($contextType, $contextValue)
+    {
+        $this->configureGeneralPhrasesMock($contextType, $contextValue);
+
+        $this->object->writeDictionary($this->dictionaryMock, $this->localeMock);
+    }
+
+    /**
+     * @return array
+     */
+    public function writeDictionaryWithRuntimeExceptionDataProvider()
+    {
+        return [
+            ['', []],
+            ['module', []],
+            ['', ['Magento_Module']]
+        ];
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     * @expectedExceptionMessage Some error. Row #1.
+     * @return void
+     */
+    public function testWriteDictionaryWithInvalidArgumentException()
+    {
+        $contextType = 'module';
+        $contextValue = 'Magento_Module';
+
+        $this->configureGeneralPhrasesMock($contextType, [$contextValue]);
+
+        $this->contextMock->expects($this->once())
+            ->method('buildPathToLocaleDirectoryByContext')
+            ->with($contextType, $contextValue)
+            ->willThrowException(new \InvalidArgumentException('Some error.'));
+
+        $this->object->writeDictionary($this->dictionaryMock, $this->localeMock);
+    }
+
+    /**
+     * @return void
+     */
+    public function testWriteDictionaryWherePathIsNull()
+    {
+        $contextType = 'module';
+        $contextValue = 'Magento_Module';
+
+        $this->configureGeneralPhrasesMock($contextType, [$contextValue]);
+
+        $this->contextMock->expects($this->once())
+            ->method('buildPathToLocaleDirectoryByContext')
+            ->with($contextType, $contextValue)
+            ->willReturn(null);
+
+        $this->phraseMock->expects($this->never())
+            ->method('setContextType');
+        $this->phraseMock->expects($this->never())
+            ->method('setContextValue');
+
+        $this->object->writeDictionary($this->dictionaryMock, $this->localeMock);
+    }
+
+    /**
+     * @return void
+     */
+    public function testWriteDictionary()
+    {
+        $contextType = 'module';
+        $contextValue = 'Magento_Module';
+        $path = '/some/path/';
+        $phrase = 'Phrase';
+        $locale = 'en_EN';
+        $file = $path . $locale . '.' . Csv::FILE_EXTENSION;
+
+        $this->configureGeneralPhrasesMock($contextType, [$contextValue]);
+
+        $this->phraseMock->expects($this->once())
+            ->method('getPhrase')
+            ->willReturn($phrase);
+        $this->phraseMock->expects($this->once())
+            ->method('setContextType')
+            ->with(null);
+        $this->phraseMock->expects($this->once())
+            ->method('setContextValue')
+            ->with(null);
+        $this->localeMock->expects($this->once())
+            ->method('__toString')
+            ->willReturn($locale);
+
+        $this->contextMock->expects($this->once())
+            ->method('buildPathToLocaleDirectoryByContext')
+            ->with($contextType, $contextValue)
+            ->willReturn($path);
+
+        $writerMock = $this->getMockForAbstractClass(WriterInterface::class);
+        $writerMock->expects($this->once())
+            ->method('write')
+            ->with($this->phraseMock);
+        $this->factoryMock->expects($this->once())
+            ->method('createDictionaryWriter')
+            ->with($file)
+            ->willReturn($writerMock);
+
+        $this->object->writeDictionary($this->dictionaryMock, $this->localeMock);
+    }
+
+    /**
+     * @param string $contextType
+     * @param array $contextValue
+     * @return void
+     */
+    private function configureGeneralPhrasesMock($contextType, $contextValue)
+    {
+        $this->phraseMock->expects($this->any())
+            ->method('getContextType')
+            ->willReturn($contextType);
+        $this->phraseMock->expects($this->any())
+            ->method('getContextValue')
+            ->willReturn($contextValue);
+
+        $this->dictionaryMock->expects($this->once())
+            ->method('getPhrases')
+            ->willReturn([$this->phraseMock]);
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Module/I18n/Pack/Writer/File/_files/ioMock.php b/setup/src/Magento/Setup/Test/Unit/Module/I18n/Pack/Writer/File/_files/ioMock.php
new file mode 100644
index 0000000000000000000000000000000000000000..154a62232b16a7df83ecdded83d57ca3ededdbb3
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Module/I18n/Pack/Writer/File/_files/ioMock.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Setup\Module\I18n\Pack\Writer\File;
+
+/**
+ * Mock is_dir function
+ *
+ * @see \Magento\Setup\Module\I18n\Pack\Writer\File\AbstractFile
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+function is_dir($path)
+{
+    return false;
+}
+
+/**
+ * Mock mkdir function
+ *
+ * @see \Magento\Setup\Module\I18n\Pack\Writer\File\AbstractFile
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+function mkdir($pathname, $mode = 0777, $recursive = false, $context = null)
+{
+    return true;
+}
+
+/**
+ * Mock chmod function
+ *
+ * @see \Magento\Setup\Module\I18n\Pack\Writer\File\AbstractFile
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+ */
+function chmod($filename, $mode)
+{
+    return true;
+}