diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php
index 630e51d3c244aaa1e63550285d7d91cc62cd2d3d..6e1154ff4c4d58ad95d8be6eadde211be84e165c 100644
--- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php
+++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php
@@ -569,6 +569,7 @@ class BundlePanel extends AbstractModifier
                     'arguments' => [
                         'data' => [
                             'config' => [
+                                'component' => 'Magento_Bundle/js/components/bundle-option-qty',
                                 'formElement' => Form\Element\Input::NAME,
                                 'componentType' => Form\Field::NAME,
                                 'dataType' => Form\Element\DataType\Number::NAME,
@@ -577,8 +578,12 @@ class BundlePanel extends AbstractModifier
                                 'value' => '1',
                                 'sortOrder' => 100,
                                 'validation' => [
+                                    'required-entry' => true,
                                     'validate-number' => true,
                                 ],
+                                'imports' => [
+                                    'isInteger' => '${ $.provider }:${ $.parentScope }.selection_qty_is_integer'
+                                ],
                             ],
                         ],
                     ],
diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php
index 008bb7b6a608672d7ff2d9a90405b44c8692b3c3..8fcf53f8950074ca94352639d5bf161898c8a1a5 100644
--- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php
+++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/Composite.php
@@ -88,6 +88,8 @@ class Composite extends AbstractModifier
 
     /**
      * {@inheritdoc}
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
      */
     public function modifyData(array $data)
     {
@@ -103,6 +105,12 @@ class Composite extends AbstractModifier
                 /** @var \Magento\Bundle\Api\Data\LinkInterface $productLink */
                 foreach ($option->getProductLinks() as $productLink) {
                     $linkedProduct = $this->productRepository->get($productLink->getSku());
+                    $integerQty = 1;
+                    if ($linkedProduct->getExtensionAttributes()->getStockItem()) {
+                        if ($linkedProduct->getExtensionAttributes()->getStockItem()->getIsQtyDecimal()) {
+                            $integerQty = 0;
+                        }
+                    }
                     $selections[] = [
                         'selection_id' => $productLink->getId(),
                         'option_id' => $productLink->getOptionId(),
@@ -112,8 +120,9 @@ class Composite extends AbstractModifier
                         'is_default' => ($productLink->getIsDefault()) ? '1' : '0',
                         'selection_price_value' => $productLink->getPrice(),
                         'selection_price_type' => $productLink->getPriceType(),
-                        'selection_qty' => $productLink->getQty(),
+                        'selection_qty' => (bool)$integerQty ? (int)$productLink->getQty() : $productLink->getQty(),
                         'selection_can_change_qty' => $productLink->getCanChangeQuantity(),
+                        'selection_qty_is_integer' => (bool)$integerQty,
                         'position' => $productLink->getPosition(),
                     ];
                 }
diff --git a/app/code/Magento/Bundle/view/adminhtml/templates/product/edit/bundle/option/selection.phtml b/app/code/Magento/Bundle/view/adminhtml/templates/product/edit/bundle/option/selection.phtml
index 11d43466c394218199d6dbab618c9b72a078c6ec..5dbeebea8f3e9679ea2f6c9ee5889c9f6d65108b 100644
--- a/app/code/Magento/Bundle/view/adminhtml/templates/product/edit/bundle/option/selection.phtml
+++ b/app/code/Magento/Bundle/view/adminhtml/templates/product/edit/bundle/option/selection.phtml
@@ -164,7 +164,7 @@ Bundle.Selection.prototype = {
         if (data.can_read_price != undefined && !data.can_read_price) {
             data.selection_price_value = '';
         } else {
-            data.selection_price_value = Number(data.selection_price_value).toFixed(2);
+            data.selection_price_value = Number(Math.round(data.selection_price_value + "e+2") + "e-2").toFixed(2);
         }
 
         data.index = this.itemsCount++;
diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js
new file mode 100644
index 0000000000000000000000000000000000000000..a52d4e8a4683bc1a6c2745a528fe1a12b7f092cb
--- /dev/null
+++ b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-option-qty.js
@@ -0,0 +1,26 @@
+/**
+ * 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: {
+            valueUpdate: 'input',
+            isInteger: true
+        },
+
+        /**
+         * update event
+         */
+        onUpdate: function () {
+            this.validation['validate-number'] = true;
+            this.validation['validate-digits'] = this.isInteger;
+            this.validate();
+        }
+    });
+});
diff --git a/app/code/Magento/Catalog/view/base/web/js/price-utils.js b/app/code/Magento/Catalog/view/base/web/js/price-utils.js
index f97e01f14117009660556a343d0504436c668f6d..0291d82845368d0282f0f9b5c8879a0d2383c46d 100644
--- a/app/code/Magento/Catalog/view/base/web/js/price-utils.js
+++ b/app/code/Magento/Catalog/view/base/web/js/price-utils.js
@@ -43,7 +43,7 @@ define([
             pattern = format.pattern || '%s',
             s = '',
             i, pad,
-            j, re, r;
+            j, re, r, am;
 
         if (isShowSign === undefined || isShowSign === true) {
             s = amount < 0 ? '-' : (isShowSign ? '+' : '');
@@ -52,7 +52,9 @@ define([
         }
         pattern = pattern.indexOf('{sign}') < 0 ? s + pattern : pattern.replace('{sign}', s);
 
-        i = parseInt(amount = Math.abs(+amount || 0).toFixed(precision), 10) + '';
+        // we're avoiding the usage of to fixed, and using round instead with the e representation to address
+        // numbers like 1.005 = 1.01. Using ToFixed to only provide trailig zeroes in case we have a whole number
+        i = parseInt(amount = Number(Math.round(Math.abs(+amount || 0) + 'e+' + precision) + ('e-' + precision)) , 10) + '';
         pad = (i.length < integerRequired) ? (integerRequired - i.length) : 0;
 
         i = stringPad('0', pad) + i;
@@ -63,9 +65,12 @@ define([
         // replace(/-/, 0) is only for fixing Safari bug which appears
         // when Math.abs(0).toFixed() executed on '0' number.
         // Result is '0.-0' :(
+
+
+        am = Number(Math.round(Math.abs(amount - i) + 'e+' + precision) + ('e-' + precision));
         r = (j ? i.substr(0, j) + groupSymbol : '') +
             i.substr(j).replace(re, '$1' + groupSymbol) +
-            (precision ? decimalSymbol + Math.abs(amount - i).toFixed(precision).replace(/-/, 0).slice(2) : '');
+            (precision ? decimalSymbol + am.toFixed(2).replace(/-/, 0).slice(2) : '');
 
         return pattern.replace('%s', r).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
     }
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/configurable.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/configurable.js
index e2a89cba9519f31f7d4e78505d363e6a9d58b261..b138e1243e89412ffa8ac426bd732307bda6483f 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/configurable.js
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/configurable.js
@@ -214,7 +214,7 @@ Product.Config.prototype = {
             }
         }
 
-        var roundedPrice = (Math.round(price*100)/100).toString();
+        var roundedPrice = Number(Math.round(price + "e+2") + "e-2").toString();
 
         if (this.prices && this.prices[roundedPrice]) {
             str+= this.prices[roundedPrice];
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js
index f05e524439af5a9b3917807eaabd43a11524918a..878b0459fb0e96638fb7103b862442ec009b74e6 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js
@@ -124,7 +124,7 @@ define([
                 },
                 name: product.name || product.sku,
                 options: options,
-                price: parseFloat(product.price.replace(/[^\d.]+/g, '')).toFixed(4),
+                price: parseFloat(Math.round(product.price.replace(/[^\d.]+/g, '') + "e+4") + "e-4").toFixed(4),
                 productId: productId,
                 productUrl: this.buildProductUrl(productId),
                 quantity: product.quantity || null,
diff --git a/app/code/Magento/Quote/etc/fieldset.xml b/app/code/Magento/Quote/etc/fieldset.xml
index acb860fa1733d1be7c919a602fe7c4e10388f10c..36f0b2d1331052660a6a9dac02e23fefc755fb8f 100644
--- a/app/code/Magento/Quote/etc/fieldset.xml
+++ b/app/code/Magento/Quote/etc/fieldset.xml
@@ -247,6 +247,9 @@
             <field name="row_total">
                 <aspect name="to_order_item" />
             </field>
+            <field name="base_price">
+                <aspect name="to_order_item" />
+            </field>
             <field name="base_original_price">
                 <aspect name="to_order_item" />
             </field>
diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Shipping.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Shipping.php
index a5cbd3431b33765263d3fd6e5b9bee27ea9b42ea..0a2596029de8a2f480b9ee6a37e12097cb8188dd 100644
--- a/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Shipping.php
+++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Total/Shipping.php
@@ -17,6 +17,13 @@ class Shipping extends AbstractTotal
      */
     protected $priceCurrency;
 
+    /**
+     * Tax config
+     *
+     * @var \Magento\Tax\Model\Config
+     */
+    private $taxConfig;
+
     /**
      * @param PriceCurrencyInterface $priceCurrency
      * @param array $data
@@ -37,62 +44,64 @@ class Shipping extends AbstractTotal
     public function collect(\Magento\Sales\Model\Order\Creditmemo $creditmemo)
     {
         $order = $creditmemo->getOrder();
-        $allowedAmount = $order->getShippingAmount() - $order->getShippingRefunded();
-        $baseAllowedAmount = $order->getBaseShippingAmount() - $order->getBaseShippingRefunded();
 
+        // amounts without tax
         $orderShippingAmount = $order->getShippingAmount();
         $orderBaseShippingAmount = $order->getBaseShippingAmount();
+        $allowedAmount = $orderShippingAmount - $order->getShippingRefunded();
+        $baseAllowedAmount = $orderBaseShippingAmount - $order->getBaseShippingRefunded();
+
+        // amounts including tax
         $orderShippingInclTax = $order->getShippingInclTax();
         $orderBaseShippingInclTax = $order->getBaseShippingInclTax();
+        $allowedTaxAmount = $order->getShippingTaxAmount() - $order->getShippingTaxRefunded();
+        $baseAllowedTaxAmount = $order->getBaseShippingTaxAmount() - $order->getBaseShippingTaxRefunded();
+        $allowedAmountInclTax = $allowedAmount + $allowedTaxAmount;
+        $baseAllowedAmountInclTax = $baseAllowedAmount + $baseAllowedTaxAmount;
 
+        // for the credit memo
         $shippingAmount = $baseShippingAmount = $shippingInclTax = $baseShippingInclTax = 0;
 
-        /**
-         * Check if shipping amount was specified (from invoice or another source).
-         * Using has magic method to allow setting 0 as shipping amount.
-         */
+        // Check if the desired shipping amount to refund was specified (from invoice or another source).
         if ($creditmemo->hasBaseShippingAmount()) {
-            $baseShippingAmount = $this->priceCurrency->round($creditmemo->getBaseShippingAmount());
-            /*
-             * Rounded allowed shipping refund amount is the highest acceptable shipping refund amount.
-             * Shipping refund amount shouldn't cause errors, if it doesn't exceed that limit.
-             * Note: ($x < $y + 0.0001) means ($x <= $y) for floats
-             */
-            if ($baseShippingAmount < $this->priceCurrency->round($baseAllowedAmount) + 0.0001) {
+            // For the conditional logic, we will either use amounts that always include tax -OR- never include tax.
+            // The logic uses the 'base' currency to be consistent with what the user (admin) provided as input.
+            $useAmountsWithTax = $this->isSuppliedShippingAmountInclTax($order);
+
+            // Since the user (admin) supplied 'desiredAmount' it already has tax -OR- does not include tax
+            $desiredAmount = $this->priceCurrency->round($creditmemo->getBaseShippingAmount());
+            $maxAllowedAmount = ($useAmountsWithTax ? $baseAllowedAmountInclTax : $baseAllowedAmount);
+            $originalTotalAmount = ($useAmountsWithTax ? $orderBaseShippingInclTax : $orderBaseShippingAmount);
+
+            // Note: ($x < $y + 0.0001) means ($x <= $y) for floats
+            if ($desiredAmount < $this->priceCurrency->round($maxAllowedAmount) + 0.0001) {
+                // since the admin is returning less than the allowed amount, compute the ratio being returned
                 $ratio = 0;
-                if ($orderBaseShippingAmount > 0) {
-                    $ratio = $baseShippingAmount / $orderBaseShippingAmount;
+                if ($originalTotalAmount > 0) {
+                    $ratio = $desiredAmount / $originalTotalAmount;
                 }
-                /*
-                 * Shipping refund amount should be equated to allowed refund amount,
-                 * if it exceeds that limit.
-                 * Note: ($x > $y - 0.0001) means ($x >= $y) for floats
-                 */
-                if ($baseShippingAmount > $baseAllowedAmount - 0.0001) {
+                // capture amounts without tax
+                // Note: ($x > $y - 0.0001) means ($x >= $y) for floats
+                if ($desiredAmount > $maxAllowedAmount - 0.0001) {
                     $shippingAmount = $allowedAmount;
                     $baseShippingAmount = $baseAllowedAmount;
                 } else {
                     $shippingAmount = $this->priceCurrency->round($orderShippingAmount * $ratio);
+                    $baseShippingAmount = $this->priceCurrency->round($orderBaseShippingAmount * $ratio);
                 }
                 $shippingInclTax = $this->priceCurrency->round($orderShippingInclTax * $ratio);
                 $baseShippingInclTax = $this->priceCurrency->round($orderBaseShippingInclTax * $ratio);
             } else {
-                $baseAllowedAmount = $order->getBaseCurrency()->format($baseAllowedAmount, null, false);
+                $maxAllowedAmount = $order->getBaseCurrency()->format($maxAllowedAmount, null, false);
                 throw new \Magento\Framework\Exception\LocalizedException(
-                    __('Maximum shipping amount allowed to refund is: %1', $baseAllowedAmount)
+                    __('Maximum shipping amount allowed to refund is: %1', $maxAllowedAmount)
                 );
             }
         } else {
             $shippingAmount = $allowedAmount;
             $baseShippingAmount = $baseAllowedAmount;
-
-            $allowedTaxAmount = $order->getShippingTaxAmount() - $order->getShippingTaxRefunded();
-            $baseAllowedTaxAmount = $order->getBaseShippingTaxAmount() - $order->getBaseShippingTaxRefunded();
-
-            $shippingInclTax = $this->priceCurrency->round($allowedAmount + $allowedTaxAmount);
-            $baseShippingInclTax = $this->priceCurrency->round(
-                $baseAllowedAmount + $baseAllowedTaxAmount
-            );
+            $shippingInclTax = $this->priceCurrency->round($allowedAmountInclTax);
+            $baseShippingInclTax = $this->priceCurrency->round($baseAllowedAmountInclTax);
         }
 
         $creditmemo->setShippingAmount($shippingAmount);
@@ -104,4 +113,32 @@ class Shipping extends AbstractTotal
         $creditmemo->setBaseGrandTotal($creditmemo->getBaseGrandTotal() + $baseShippingAmount);
         return $this;
     }
+
+    /**
+     * Returns whether the user specified a shipping amount that already includes tax
+     *
+     * @param \Magento\Sales\Model\Order $order
+     * @return bool
+     */
+    private function isSuppliedShippingAmountInclTax($order)
+    {
+        // returns true if we are only displaying shipping including tax, otherwise returns false
+        return $this->getTaxConfig()->displaySalesShippingInclTax($order->getStoreId());
+    }
+
+    /**
+     * Get the Tax Config.
+     * In a future release, will become a constructor parameter.
+     *
+     * @return \Magento\Tax\Model\Config
+     *
+     * @deprecated
+     */
+    private function getTaxConfig()
+    {
+        if ($this->taxConfig === null) {
+            $this->taxConfig = \Magento\Framework\App\ObjectManager::getInstance()->get('Magento\Tax\Model\Config');
+        }
+        return $this->taxConfig;
+    }
 }
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/ShippingTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/ShippingTest.php
index 54391701b8c38874d392615d246463877a0b3b37..52624f64592926cadf61ae75ed7d05a6c18149e3 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/ShippingTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Creditmemo/Total/ShippingTest.php
@@ -15,6 +15,11 @@ class ShippingTest extends \PHPUnit_Framework_TestCase
      */
     protected $creditmemoMock;
 
+    /**
+     * @var \Magento\Tax\Model\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $taxConfig;
+
     /**
      * @var \Magento\Sales\Model\Order\Creditmemo\Total\Shipping
      */
@@ -51,16 +56,24 @@ class ShippingTest extends \PHPUnit_Framework_TestCase
                 }
             );
 
+        $this->taxConfig = $this->getMock('Magento\Tax\Model\Config', [], [], '', false);
+
         $this->shippingCollector = $objectManager->getObject(
             'Magento\Sales\Model\Order\Creditmemo\Total\Shipping',
             [
                 'priceCurrency' => $priceCurrencyMock,
             ]
         );
+
+        // needed until 'taxConfig' becomes part of the constructor for shippingCollector
+        $reflection = new \ReflectionClass(get_class($this->shippingCollector));
+        $reflectionProperty = $reflection->getProperty('taxConfig');
+        $reflectionProperty->setAccessible(true);
+        $reflectionProperty->setValue($this->shippingCollector, $this->taxConfig);
     }
 
     /**
-     * Test the case where shipping amount specified is greater than shipping amount allowed
+     * situation: The admin user specified a desired shipping refund that is greater than the amount allowed
      *
      * @expectedException \Magento\Framework\Exception\LocalizedException
      * @expectedExceptionMessage Maximum shipping amount allowed to refund is: 5
@@ -70,7 +83,10 @@ class ShippingTest extends \PHPUnit_Framework_TestCase
         $orderShippingAmount = 10;
         $orderShippingRefunded = 5;
         $allowedShippingAmount = $orderShippingAmount - $orderShippingRefunded;
-        $creditmemoShippingAmount = 6;
+        $desiredRefundAmount = $allowedShippingAmount + 1; // force amount to be larger than what is allowed
+
+        $this->taxConfig->expects($this->any())->method('displaySalesShippingInclTax')->willReturn(false);
+
         $currencyMock = $this->getMockBuilder('Magento\Directory\Model\Currency')
             ->disableOriginalConstructor()
             ->getMock();
@@ -78,6 +94,7 @@ class ShippingTest extends \PHPUnit_Framework_TestCase
             ->method('format')
             ->with($allowedShippingAmount, null, false)
             ->willReturn($allowedShippingAmount);
+
         $order = new \Magento\Framework\DataObject(
             [
                 'base_shipping_amount' => $orderShippingAmount,
@@ -89,18 +106,22 @@ class ShippingTest extends \PHPUnit_Framework_TestCase
         $this->creditmemoMock->expects($this->once())
             ->method('getOrder')
             ->willReturn($order);
-
         $this->creditmemoMock->expects($this->once())
             ->method('hasBaseShippingAmount')
             ->willReturn(true);
         $this->creditmemoMock->expects($this->once())
             ->method('getBaseShippingAmount')
-            ->willReturn($creditmemoShippingAmount);
-
+            ->willReturn($desiredRefundAmount);
 
+        //expect to have an exception thrown
         $this->shippingCollector->collect($this->creditmemoMock);
     }
 
+    /**
+     * situation: The admin user did *not* specify any desired refund amount
+     *
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
     public function testCollectNoSpecifiedShippingAmount()
     {
         $orderShippingAmount = 10;
@@ -122,6 +143,8 @@ class ShippingTest extends \PHPUnit_Framework_TestCase
         $expectedGrandTotal = $grandTotalBefore + $allowedShippingAmount;
         $expectedBaseGrandTtoal = $baseGrandTotalBefore + $baseAllowedShippingAmount;
 
+        $this->taxConfig->expects($this->any())->method('displaySalesShippingInclTax')->willReturn(false);
+
         $order = new \Magento\Framework\DataObject(
             [
                 'shipping_amount' => $orderShippingAmount,
@@ -140,11 +163,9 @@ class ShippingTest extends \PHPUnit_Framework_TestCase
         $this->creditmemoMock->expects($this->once())
             ->method('getOrder')
             ->willReturn($order);
-
         $this->creditmemoMock->expects($this->once())
             ->method('hasBaseShippingAmount')
             ->willReturn(false);
-
         $this->creditmemoMock->expects($this->once())
             ->method('getGrandTotal')
             ->willReturn($grandTotalBefore);
@@ -196,8 +217,8 @@ class ShippingTest extends \PHPUnit_Framework_TestCase
         $orderShippingInclTax = $orderShippingAmount + $shippingTaxAmount;
         $baseOrderShippingInclTax = $baseOrderShippingAmount + $baseShippingTaxAmount;
 
-        //refund half
-        $creditmemoBaseShippingAmount = $ratio * $baseOrderShippingAmount;
+        //determine expected partial refund amounts
+        $desiredRefundAmount = $baseOrderShippingAmount * $ratio;
 
         $expectedShippingAmount = $orderShippingAmount * $ratio;
         $expectedShippingAmountInclTax = $orderShippingInclTax * $ratio;
@@ -209,6 +230,8 @@ class ShippingTest extends \PHPUnit_Framework_TestCase
         $expectedGrandTotal = $grandTotalBefore + $expectedShippingAmount;
         $expectedBaseGrandTtoal = $baseGrandTotalBefore + $expectedBaseShippingAmount;
 
+        $this->taxConfig->expects($this->any())->method('displaySalesShippingInclTax')->willReturn(false);
+
         $order = new \Magento\Framework\DataObject(
             [
                 'shipping_amount' => $orderShippingAmount,
@@ -223,14 +246,12 @@ class ShippingTest extends \PHPUnit_Framework_TestCase
         $this->creditmemoMock->expects($this->once())
             ->method('getOrder')
             ->willReturn($order);
-
         $this->creditmemoMock->expects($this->once())
             ->method('hasBaseShippingAmount')
             ->willReturn(true);
         $this->creditmemoMock->expects($this->once())
             ->method('getBaseShippingAmount')
-            ->willReturn($creditmemoBaseShippingAmount);
-
+            ->willReturn($desiredRefundAmount);
         $this->creditmemoMock->expects($this->once())
             ->method('getGrandTotal')
             ->willReturn($grandTotalBefore);
@@ -267,6 +288,9 @@ class ShippingTest extends \PHPUnit_Framework_TestCase
         $this->shippingCollector->collect($this->creditmemoMock);
     }
 
+    /**
+     * @return array
+     */
     public function collectWithSpecifiedShippingAmountDataProvider()
     {
         return [
@@ -274,4 +298,102 @@ class ShippingTest extends \PHPUnit_Framework_TestCase
             'quarter' => [0.25],
         ];
     }
+
+    /**
+     * situation: The admin user specified the desired refund amount that has taxes embedded within it
+     *
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function testCollectUsingTaxInclShippingAmount()
+    {
+        $this->taxConfig->expects($this->any())->method('displaySalesShippingInclTax')->willReturn(true);
+
+        $orderShippingAmount = 15;
+        $shippingTaxAmount = 3;
+        $orderShippingInclTax = $orderShippingAmount + $shippingTaxAmount;
+        $orderShippingAmountRefunded = 5;
+        $shippingTaxRefunded = 1;
+        $refundedInclTax = $orderShippingAmountRefunded + $shippingTaxRefunded;
+
+        $currencyMultiple = 2;
+        $baseOrderShippingAmount = $orderShippingAmount * $currencyMultiple;
+        $baseShippingTaxAmount = $shippingTaxAmount * $currencyMultiple;
+        $baseOrderShippingInclTax = $orderShippingInclTax * $currencyMultiple;
+        $baseOrderShippingAmountRefunded = $orderShippingAmountRefunded * $currencyMultiple;
+        $baseShippingTaxRefunded = $shippingTaxRefunded * $currencyMultiple;
+        $baseRefundedInclTax = $refundedInclTax * $currencyMultiple;
+
+        //determine expected amounts
+        $desiredRefundAmount = $baseOrderShippingInclTax - $baseRefundedInclTax;
+
+        $expectedShippingAmount = $orderShippingAmount - $orderShippingAmountRefunded;
+        $expectedShippingAmountInclTax = $orderShippingInclTax - $refundedInclTax;
+
+        $expectedBaseShippingAmount = $expectedShippingAmount * $currencyMultiple;
+        $expectedBaseShippingAmountInclTax = $expectedShippingAmountInclTax * $currencyMultiple;
+
+        $grandTotalBefore = 100;
+        $baseGrandTotalBefore = 200;
+        $expectedGrandTotal = $grandTotalBefore + $expectedShippingAmount;
+        $expectedBaseGrandTtoal = $baseGrandTotalBefore + $expectedBaseShippingAmount;
+
+        $order = new \Magento\Framework\DataObject(
+            [
+                'shipping_amount' => $orderShippingAmount,
+                'base_shipping_amount' => $baseOrderShippingAmount,
+                'shipping_refunded' => $orderShippingAmountRefunded,
+                'base_shipping_refunded' => $baseOrderShippingAmountRefunded,
+                'shipping_incl_tax' => $orderShippingInclTax,
+                'base_shipping_incl_tax' => $baseOrderShippingInclTax,
+                'shipping_tax_amount' => $shippingTaxAmount,
+                'shipping_tax_refunded' => $shippingTaxRefunded,
+                'base_shipping_tax_amount' => $baseShippingTaxAmount,
+                'base_shipping_tax_refunded' => $baseShippingTaxRefunded,
+            ]
+        );
+
+        $this->creditmemoMock->expects($this->once())
+            ->method('getOrder')
+            ->willReturn($order);
+        $this->creditmemoMock->expects($this->once())
+            ->method('hasBaseShippingAmount')
+            ->willReturn(true);
+        $this->creditmemoMock->expects($this->once())
+            ->method('getBaseShippingAmount')
+            ->willReturn($desiredRefundAmount);
+        $this->creditmemoMock->expects($this->once())
+            ->method('getGrandTotal')
+            ->willReturn($grandTotalBefore);
+        $this->creditmemoMock->expects($this->once())
+            ->method('getBaseGrandTotal')
+            ->willReturn($baseGrandTotalBefore);
+
+        //verify
+        $this->creditmemoMock->expects($this->once())
+            ->method('setShippingAmount')
+            ->with($expectedShippingAmount)
+            ->willReturnSelf();
+        $this->creditmemoMock->expects($this->once())
+            ->method('setBaseShippingAmount')
+            ->with($expectedBaseShippingAmount)
+            ->willReturnSelf();
+        $this->creditmemoMock->expects($this->once())
+            ->method('setShippingInclTax')
+            ->with($expectedShippingAmountInclTax)
+            ->willReturnSelf();
+        $this->creditmemoMock->expects($this->once())
+            ->method('setBaseShippingInclTax')
+            ->with($expectedBaseShippingAmountInclTax)
+            ->willReturnSelf();
+        $this->creditmemoMock->expects($this->once())
+            ->method('setGrandTotal')
+            ->with($expectedGrandTotal)
+            ->willReturnSelf();
+        $this->creditmemoMock->expects($this->once())
+            ->method('setBaseGrandTotal')
+            ->with($expectedBaseGrandTtoal)
+            ->willReturnSelf();
+
+        $this->shippingCollector->collect($this->creditmemoMock);
+    }
 }
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 bec36e6206eddcf7c1344d2626f0e5ca1e8c2a5e..6e5eca5d94be422e1efad40d7e69a59042e0a446 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
@@ -539,7 +539,7 @@ define([
                             if (this._isSummarizePrice()) {
                                 productPrice += this.productPriceBase[productId];
                             }
-                            productPrice = parseFloat(productPrice);
+                            productPrice = parseFloat(Math.round(productPrice + "e+2") + "e-2");
                             priceColl.innerHTML = this.currencySymbol + productPrice.toFixed(2);
                             // and set checkbox checked
                             grid.setCheckboxChecked(checkbox, true);
diff --git a/app/code/Magento/Shipping/view/adminhtml/web/order/packaging.js b/app/code/Magento/Shipping/view/adminhtml/web/order/packaging.js
index 645e43bfb869ee4c137ea15578f813beaabf72d9..1e6c9a4465049127168a4ed5b7ffb348c534ba4f 100644
--- a/app/code/Magento/Shipping/view/adminhtml/web/order/packaging.js
+++ b/app/code/Magento/Shipping/view/adminhtml/web/order/packaging.js
@@ -728,7 +728,7 @@ Packaging.prototype = {
                             item.remove();
                         } else if (qtyValue > packedQty) {
                             /* fix float number precision */
-                            qty.value = Number((qtyValue - packedQty).toFixed(4));
+                            qty.value = Number(Number(Math.round((qtyValue - packedQty) + "e+4") + "e-4").toFixed(4));
                         }
                     }
                 }
@@ -786,8 +786,8 @@ Packaging.prototype = {
             containerCustomsValue.value = parseFloat(containerCustomsValue.value) + itemCustomsValue * qtyValue;
             this.packages[packageId]['items'][itemId]['customs_value'] = itemCustomsValue;
         }.bind(this));
-        containerWeight.value = parseFloat(parseFloat(containerWeight.value).toFixed(4));
-        containerCustomsValue.value = parseFloat(containerCustomsValue.value).toFixed(2);
+        containerWeight.value = parseFloat(parseFloat(Math.round(containerWeight.value + "e+4") + "e-4").toFixed(4));
+        containerCustomsValue.value = parseFloat(Math.round(containerCustomsValue.value + "e+2") + "e-2").toFixed(2);
         if (containerCustomsValue.value == 0) {
             containerCustomsValue.value = '';
         }
diff --git a/app/code/Magento/Tax/Model/Sales/Order/TaxManagement.php b/app/code/Magento/Tax/Model/Sales/Order/TaxManagement.php
index b49e43108e40bd270bb01b4e9b508d0e7406a7d3..e8700e714951c823abbc23c309299d11235a8b15 100644
--- a/app/code/Magento/Tax/Model/Sales/Order/TaxManagement.php
+++ b/app/code/Magento/Tax/Model/Sales/Order/TaxManagement.php
@@ -66,18 +66,27 @@ class TaxManagement implements \Magento\Tax\Api\OrderTaxManagementInterface
      *
      * @param TaxDetailsDataObjectFactory $appliedTaxDataObjectFactory
      * @param array $itemAppliedTax
+     * @param AppliedTax $existingAppliedTax
      * @return AppliedTax
      */
     protected function convertToAppliedTaxDataObject(
         TaxDetailsDataObjectFactory $appliedTaxDataObjectFactory,
-        $itemAppliedTax
+        $itemAppliedTax,
+        AppliedTax $existingAppliedTax = null
     ) {
+        // if there is an existingAppliedTax, include its amount and baseAmount
+        $amount = $baseAmount = 0;
+        if ($existingAppliedTax !== null) {
+            $amount = $existingAppliedTax->getAmount();
+            $baseAmount = $existingAppliedTax->getBaseAmount();
+        }
+
         return $appliedTaxDataObjectFactory->create()
             ->setCode($itemAppliedTax['code'])
             ->setTitle($itemAppliedTax['title'])
             ->setPercent($itemAppliedTax['tax_percent'])
-            ->setAmount($itemAppliedTax['real_amount'])
-            ->setBaseAmount($itemAppliedTax['real_base_amount']);
+            ->setAmount($itemAppliedTax['real_amount'] + $amount)
+            ->setBaseAmount($itemAppliedTax['real_base_amount'] + $baseAmount);
     }
 
     /**
@@ -141,46 +150,39 @@ class TaxManagement implements \Magento\Tax\Api\OrderTaxManagementInterface
         $orderItemAppliedTaxes = $this->orderItemTaxFactory->create()->getTaxItemsByOrderId($orderId);
         $itemsData = [];
         foreach ($orderItemAppliedTaxes as $itemAppliedTax) {
+            $key = $itemId = $associatedItemId = null;
+
             //group applied taxes by item
             if (isset($itemAppliedTax['item_id'])) {
                 //The taxable is a product
+                //Note: the associatedItemId is null
                 $itemId = $itemAppliedTax['item_id'];
-                if (!isset($itemsData[$itemId])) {
-                    $itemsData[$itemId] = [
-                        Item::KEY_ITEM_ID => $itemAppliedTax['item_id'],
-                        Item::KEY_TYPE => $itemAppliedTax['taxable_item_type'],
-                        Item::KEY_ASSOCIATED_ITEM_ID => null,
-                    ];
-                }
-                $itemsData[$itemId]['applied_taxes'][$itemAppliedTax['code']] =
-                    $this->convertToAppliedTaxDataObject($this->appliedTaxDataObjectFactory, $itemAppliedTax);
+                $key = $itemId;
             } elseif (isset($itemAppliedTax['associated_item_id'])) {
-                //The taxable is associated with a product, e.g., weee, gift wrapping etc.
-                $itemId = $itemAppliedTax['associated_item_id'];
-                $key = $itemAppliedTax['taxable_item_type'] . $itemId;
-                if (!isset($itemsData[$key])) {
-                    $itemsData[$key] = [
-                        Item::KEY_ITEM_ID => null,
-                        Item::KEY_TYPE => $itemAppliedTax['taxable_item_type'],
-                        Item::KEY_ASSOCIATED_ITEM_ID => $itemId,
-                    ];
-                }
-                $itemsData[$key]['applied_taxes'][$itemAppliedTax['code']] =
-                    $this->convertToAppliedTaxDataObject($this->appliedTaxDataObjectFactory, $itemAppliedTax);
+                //The taxable is associated with a product, e.g., weee, gift wrapping, etc.
+                //Note: the itemId is null
+                $associatedItemId = $itemAppliedTax['associated_item_id'];
+                $key = $itemAppliedTax['taxable_item_type'] . $associatedItemId;
             } else {
                 //The taxable is not associated with a product, e.g., shipping
-                //Use item type as key
+                //Use item type as key.  Both the itemId and associatedItemId are null
                 $key = $itemAppliedTax['taxable_item_type'];
-                if (!isset($itemsData[$key])) {
-                    $itemsData[$key] = [
-                        Item::KEY_TYPE => $itemAppliedTax['taxable_item_type'],
-                        Item::KEY_ITEM_ID => null,
-                        Item::KEY_ASSOCIATED_ITEM_ID => null,
-                    ];
-                }
-                $itemsData[$key][Item::KEY_APPLIED_TAXES][$itemAppliedTax['code']] =
-                    $this->convertToAppliedTaxDataObject($this->appliedTaxDataObjectFactory, $itemAppliedTax);
             }
+
+            // create the itemsData entry
+            if (!isset($itemsData[$key])) {
+                $itemsData[$key] = [
+                    Item::KEY_TYPE => $itemAppliedTax['taxable_item_type'],
+                    Item::KEY_ITEM_ID => $itemId,                       // might be null
+                    Item::KEY_ASSOCIATED_ITEM_ID => $associatedItemId,  // might be null
+                ];
+            }
+            $current = null;
+            if (isset($itemsData[$key][Item::KEY_APPLIED_TAXES][$itemAppliedTax['code']])) {
+                $current = $itemsData[$key][Item::KEY_APPLIED_TAXES][$itemAppliedTax['code']];
+            }
+            $itemsData[$key][Item::KEY_APPLIED_TAXES][$itemAppliedTax['code']] =
+                $this->convertToAppliedTaxDataObject($this->appliedTaxDataObjectFactory, $itemAppliedTax, $current);
         }
 
         $items = [];
diff --git a/app/code/Magento/Tax/Test/Unit/Model/Quote/GrandTotalDetailsPluginTest.php b/app/code/Magento/Tax/Test/Unit/Model/Quote/GrandTotalDetailsPluginTest.php
index 1870806dd4262d5359598a0049e57535989a5aac..bc241592f9184625ca86b1d21b03a17809f43c9b 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/Quote/GrandTotalDetailsPluginTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/Quote/GrandTotalDetailsPluginTest.php
@@ -63,10 +63,12 @@ class GrandTotalDetailsPluginTest extends \PHPUnit_Framework_TestCase
 
         $this->detailsFactoryMock = $this->getMockBuilder('\Magento\Tax\Api\Data\GrandTotalDetailsInterfaceFactory')
             ->disableOriginalConstructor()
+            ->setMethods(['create'])
             ->getMock();
 
         $this->ratesFactoryMock = $this->getMockBuilder('\Magento\Tax\Api\Data\GrandTotalRatesInterfaceFactory')
             ->disableOriginalConstructor()
+            ->setMethods(['create'])
             ->getMock();
 
         $this->taxConfigMock = $this->getMockBuilder('\Magento\Tax\Model\Config')
@@ -154,7 +156,6 @@ class GrandTotalDetailsPluginTest extends \PHPUnit_Framework_TestCase
         ];
         $taxAmount = 10;
 
-
         $taxRateMock = $this->setupTaxRateFactoryMock($taxRate);
 
         $taxDetailsMock = $this->setupTaxDetails(
@@ -190,7 +191,6 @@ class GrandTotalDetailsPluginTest extends \PHPUnit_Framework_TestCase
             ->with([$taxDetailsMock])
             ->willReturnSelf();
 
-
         $taxSegmentMock = $this->getMockBuilder('\Magento\Quote\Model\Cart\TotalSegment')
             ->disableOriginalConstructor()
             ->getMock();
diff --git a/app/code/Magento/Tax/Test/Unit/Model/Sales/Order/TaxManagementTest.php b/app/code/Magento/Tax/Test/Unit/Model/Sales/Order/TaxManagementTest.php
index cd7198e336ddc22d5b3e9dd2bd2ce9a184f698f5..4c78af20608ac9e6cc14933eb884d2521be0924f 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/Sales/Order/TaxManagementTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/Sales/Order/TaxManagementTest.php
@@ -26,36 +26,6 @@ class TaxManagementTest extends \PHPUnit_Framework_TestCase
      */
     private $taxItemResourceMock;
 
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    private $taxItemFactoryMock;
-
-    /**
-     * @var  \PHPUnit_Framework_MockObject_MockObject
-     */
-    private $orderFactoryMock;
-
-    /**
-     * @var  \PHPUnit_Framework_MockObject_MockObject
-     */
-    private $appliedTaxDataObjectFactoryMock;
-
-    /**
-     * @var  \PHPUnit_Framework_MockObject_MockObject
-     */
-    private $itemDataObjectFactoryMock;
-
-    /**
-     * @var \Magento\Tax\Api\Data\OrderTaxDetailsItemInterface
-     */
-    protected $itemDataObject;
-
-    /**
-     * @var  \PHPUnit_Framework_MockObject_MockObject
-     */
-    private $orderTaxDetailsDataObjectFactoryMock;
-
     /**
      * @var \Magento\Tax\Api\Data\OrderTaxDetailsAppliedTaxInterface
      */
@@ -68,85 +38,85 @@ class TaxManagementTest extends \PHPUnit_Framework_TestCase
 
     public function setUp()
     {
-        $this->orderMock = $this->getMock('Magento\Sales\Model\Order', [], [], '', false);
-        $this->orderFactoryMock = $this->getMock('Magento\Sales\Model\OrderFactory', ['create'], [], '', false);
-        $this->taxItemResourceMock = $this->getMock(
-            'Magento\Sales\Model\ResourceModel\Order\Tax\Item',
-            [],
-            [],
-            '',
-            false
-        );
-        $this->taxItemFactoryMock = $this->getMock(
-            'Magento\Sales\Model\ResourceModel\Order\Tax\ItemFactory',
-            ['create'],
-            [],
-            '',
-            false
-        );
+        $this->orderMock = $this->getMock('Magento\Sales\Model\Order', ['load'], [], '', false);
 
-        $objectManager = new ObjectManager($this);
         $methods = ['create'];
+        $orderFactoryMock = $this->getMock('Magento\Sales\Model\OrderFactory', $methods, [], '', false);
+        $orderFactoryMock->expects($this->atLeastOnce())
+            ->method('create')
+            ->will($this->returnValue($this->orderMock));
+
+        $className = 'Magento\Sales\Model\ResourceModel\Order\Tax\Item';
+        $this->taxItemResourceMock = $this->getMock($className, ['getTaxItemsByOrderId'], [], '', false);
+
+        $className = 'Magento\Sales\Model\ResourceModel\Order\Tax\ItemFactory';
+        $taxItemFactoryMock = $this->getMock($className, $methods, [], '', false);
+        $taxItemFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($this->taxItemResourceMock);
+
+        $objectManager = new ObjectManager($this);
         $this->appliedTaxDataObject = $objectManager->getObject('Magento\Tax\Model\Sales\Order\Tax');
-        $this->appliedTaxDataObjectFactoryMock
-            = $this->getMock('Magento\Tax\Api\Data\OrderTaxDetailsAppliedTaxInterfaceFactory', $methods, [], '', false);
-        $this->appliedTaxDataObjectFactoryMock->expects($this->any())
+
+        $className = 'Magento\Tax\Api\Data\OrderTaxDetailsAppliedTaxInterfaceFactory';
+        $appliedTaxDataObjectFactoryMock = $this->getMock($className, $methods, [], '', false);
+        $appliedTaxDataObjectFactoryMock->expects($this->any())
             ->method('create')
             ->willReturn($this->appliedTaxDataObject);
 
-        $this->itemDataObject = $objectManager->getObject('Magento\Sales\Model\Order\Tax\Item');
-        $this->itemDataObjectFactoryMock =
-            $this->getMock('Magento\Tax\Api\Data\OrderTaxDetailsItemInterfaceFactory', $methods, [], '', false);
-        $this->itemDataObjectFactoryMock->expects($this->atLeastOnce())
-            ->method('create')->willReturn($this->itemDataObject);
+        $itemDataObject = $objectManager->getObject('Magento\Sales\Model\Order\Tax\Item');
+
+        $className = 'Magento\Tax\Api\Data\OrderTaxDetailsItemInterfaceFactory';
+        $itemDataObjectFactoryMock = $this->getMock($className, $methods, [], '', false);
+        $itemDataObjectFactoryMock->expects($this->atLeastOnce())
+            ->method('create')
+            ->willReturn($itemDataObject);
 
         $this->orderTaxDetailsDataObject = $objectManager->getObject('Magento\Tax\Model\Sales\Order\Details');
-        $this->orderTaxDetailsDataObjectFactoryMock =
-            $this->getMock('Magento\Tax\Api\Data\OrderTaxDetailsInterfaceFactory', $methods, [], '', false);
-        $this->orderTaxDetailsDataObjectFactoryMock->expects($this->any())
+
+        $className = 'Magento\Tax\Api\Data\OrderTaxDetailsInterfaceFactory';
+        $orderTaxDetailsDataObjectFactoryMock = $this->getMock($className, $methods, [], '', false);
+        $orderTaxDetailsDataObjectFactoryMock->expects($this->any())
             ->method('create')
             ->willReturn($this->orderTaxDetailsDataObject);
 
         $this->taxManagement = $objectManager->getObject(
             'Magento\Tax\Model\Sales\Order\TaxManagement',
             [
-                'orderFactory' => $this->orderFactoryMock,
-                'orderItemTaxFactory' => $this->taxItemFactoryMock,
-                'appliedTaxDataObjectFactory' => $this->appliedTaxDataObjectFactoryMock,
-                'itemDataObjectFactory' => $this->itemDataObjectFactoryMock,
-                'orderTaxDetailsDataObjectFactory' => $this->orderTaxDetailsDataObjectFactoryMock
+                'orderFactory' => $orderFactoryMock,
+                'orderItemTaxFactory' => $taxItemFactoryMock,
+                'orderTaxDetailsDataObjectFactory' => $orderTaxDetailsDataObjectFactoryMock,
+                'itemDataObjectFactory' => $itemDataObjectFactoryMock,
+                'appliedTaxDataObjectFactory' => $appliedTaxDataObjectFactoryMock
             ]
         );
     }
 
     /**
      * @param array $orderItemAppliedTaxes
+     * @param array $expected
      * @return void
      * @dataProvider getOrderTaxDetailsDataProvider
      */
-    public function testGetOrderTaxDetails($orderItemAppliedTaxes)
+    public function testGetOrderTaxDetails($orderItemAppliedTaxes, $expected)
     {
         $orderId = 1;
-        $data = $orderItemAppliedTaxes[0];
-
-        $this->orderFactoryMock->expects($this->atLeastOnce())
-            ->method('create')
-            ->will($this->returnValue($this->orderMock));
         $this->orderMock->expects($this->once())
             ->method('load')
             ->with($orderId)
             ->will($this->returnSelf());
-        $this->taxItemFactoryMock->expects($this->once())->method('create')->willReturn($this->taxItemResourceMock);
         $this->taxItemResourceMock->expects($this->once())
             ->method('getTaxItemsByOrderId')
             ->with($orderId)
             ->will($this->returnValue($orderItemAppliedTaxes));
+
         $this->assertEquals($this->orderTaxDetailsDataObject, $this->taxManagement->getOrderTaxDetails($orderId));
-        $this->assertEquals($data['code'], $this->appliedTaxDataObject->getCode());
-        $this->assertEquals($data['title'], $this->appliedTaxDataObject->getTitle());
-        $this->assertEquals($data['tax_percent'], $this->appliedTaxDataObject->getPercent());
-        $this->assertEquals($data['real_amount'], $this->appliedTaxDataObject->getAmount());
-        $this->assertEquals($data['real_base_amount'], $this->appliedTaxDataObject->getBaseAmount());
+
+        $this->assertEquals($expected['code'], $this->appliedTaxDataObject->getCode());
+        $this->assertEquals($expected['title'], $this->appliedTaxDataObject->getTitle());
+        $this->assertEquals($expected['tax_percent'], $this->appliedTaxDataObject->getPercent());
+        $this->assertEquals($expected['real_amount'], $this->appliedTaxDataObject->getAmount());
+        $this->assertEquals($expected['real_base_amount'], $this->appliedTaxDataObject->getBaseAmount());
     }
 
     /**
@@ -155,7 +125,7 @@ class TaxManagementTest extends \PHPUnit_Framework_TestCase
      */
     public function getOrderTaxDetailsDataProvider()
     {
-        return [
+        $data = [
             'one_item' => [
                 'orderItemAppliedTaxes' => [
                     [
@@ -169,8 +139,16 @@ class TaxManagementTest extends \PHPUnit_Framework_TestCase
                         'real_base_amount' => '12.3779',
                     ],
                 ],
+                'expected' => [
+                    'code' => 'US-CA-*-Rate 1',
+                    'title' => 'US-CA-*-Rate 1',
+                    'tax_percent' => '8.25',
+                    'real_amount' => '6.1889',
+                    'real_base_amount' => '12.3779',
+                ],
             ],
-            'wee_item' => [
+
+            'weee_item' => [
                 'orderItemAppliedTaxes' => [
                     [
                         'item_id' => null,
@@ -183,7 +161,15 @@ class TaxManagementTest extends \PHPUnit_Framework_TestCase
                         'real_base_amount' => '1.7979',
                     ],
                 ],
+                'expected' => [
+                    'code' => 'SanJose City Tax',
+                    'title' => 'SanJose City Tax',
+                    'tax_percent' => '6',
+                    'real_amount' => '0.9011',
+                    'real_base_amount' => '1.7979',
+                ],
             ],
+
             'shipping' => [
                 'orderItemAppliedTaxes' => [
                     [
@@ -197,7 +183,48 @@ class TaxManagementTest extends \PHPUnit_Framework_TestCase
                         'real_base_amount' => '5.21',
                     ],
                 ],
+                'expected' => [
+                    'code' => 'Shipping',
+                    'title' => 'Shipping',
+                    'tax_percent' => '21',
+                    'real_amount' => '2.6',
+                    'real_base_amount' => '5.21',
+                ],
+            ],
+
+            'canadian_weee' => [
+                'orderItemAppliedTaxes' => [
+                    [
+                        'item_id' => null,
+                        'taxable_item_type' => 'weee',
+                        'associated_item_id' => 69,
+                        'code' => 'GST',
+                        'title' => 'GST',
+                        'tax_percent' => '5',
+                        'real_amount' => '2.10',
+                        'real_base_amount' => '4.10',
+                    ],
+                    [
+                        'item_id' => null,
+                        'taxable_item_type' => 'weee',
+                        'associated_item_id' => 69,
+                        'code' => 'GST',
+                        'title' => 'GST',
+                        'tax_percent' => '5',
+                        'real_amount' => '1.15',
+                        'real_base_amount' => '3.10',
+                    ],
+                ],
+                'expected' => [
+                    'code' => 'GST',
+                    'title' => 'GST',
+                    'tax_percent' => '5',
+                    'real_amount' => '3.25',
+                    'real_base_amount' => '7.20',
+                ],
             ],
         ];
+
+        return $data;
     }
 }
diff --git a/app/code/Magento/Weee/Model/Tax.php b/app/code/Magento/Weee/Model/Tax.php
index d3de2f754ca00c37e76e58190bdf41b7232b5187..5a6d4ff73225725ade29f47599bd5130a62da49e 100644
--- a/app/code/Magento/Weee/Model/Tax.php
+++ b/app/code/Magento/Weee/Model/Tax.php
@@ -345,7 +345,7 @@ class Tax extends \Magento\Framework\Model\AbstractModel
 
                 $one = new \Magento\Framework\DataObject();
                 $one->setName(
-                    __($attribute['label_value']) ? __($attribute['label_value']) : __($attribute['frontend_label'])
+                    $attribute['label_value'] ? __($attribute['label_value']) : __($attribute['frontend_label'])
                 )
                     ->setAmount($amount)
                     ->setTaxAmount($taxAmount)
diff --git a/app/code/Magento/Weee/Test/Unit/Model/TaxTest.php b/app/code/Magento/Weee/Test/Unit/Model/TaxTest.php
index b0ccb5e1890e940d897499aa1a8a703e89bdacdf..7d8b375821f73fb90b76fab024743d370c8e9d3b 100644
--- a/app/code/Magento/Weee/Test/Unit/Model/TaxTest.php
+++ b/app/code/Magento/Weee/Test/Unit/Model/TaxTest.php
@@ -16,6 +16,7 @@ class TaxTest extends \PHPUnit_Framework_TestCase
      * @var \Magento\Weee\Model\Tax
      */
     protected $model;
+
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
@@ -93,7 +94,6 @@ class TaxTest extends \PHPUnit_Framework_TestCase
     {
         $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
 
-
         $className = '\Magento\Framework\Model\Context';
         $this->context = $this->getMock($className, [], [], '', false);
 
@@ -158,10 +158,14 @@ class TaxTest extends \PHPUnit_Framework_TestCase
             ]
         );
     }
+
     /**
      * test GetProductWeeeAttributes
+     * @dataProvider getProductWeeeAttributesDataProvider
+     * @param array $weeeTaxCalculationsByEntity
+     * @param array $expectedFptLabel
      */
-    public function testGetProductWeeeAttributes()
+    public function testGetProductWeeeAttributes($weeeTaxCalculationsByEntity, $expectedFptLabel)
     {
         $product = $this->getMock('\Magento\Catalog\Model\Product', [], [], '', false);
         $website = $this->getMock('\Magento\Store\Model\Website', [], [], '', false);
@@ -233,11 +237,7 @@ class TaxTest extends \PHPUnit_Framework_TestCase
         $this->resource->expects($this->any())
             ->method('fetchWeeeTaxCalculationsByEntity')
             ->willReturn([
-                0 => [
-                    'weee_value' => 1,
-                    'label_value' => 'fpt_label',
-                    'attribute_code' => 'fpt_code',
-                    ]
+                0 => $weeeTaxCalculationsByEntity
             ]);
 
         $result = $this->model->getProductWeeeAttributes($product, null, null, null, true);
@@ -246,6 +246,34 @@ class TaxTest extends \PHPUnit_Framework_TestCase
         $obj = $result[0];
         $this->assertEquals(1, $obj->getAmount());
         $this->assertEquals(0.25, $obj->getTaxAmount());
-        $this->assertEquals('fpt_code', $obj->getCode());
+        $this->assertEquals($weeeTaxCalculationsByEntity['attribute_code'], $obj->getCode());
+        $this->assertEquals(__($expectedFptLabel), $obj->getName());
+    }
+
+    /**
+     * @return array
+     */
+    public function getProductWeeeAttributesDataProvider()
+    {
+        return [
+            'store_label_defined' => [
+                'weeeTaxCalculationsByEntity' => [
+                    'weee_value' => 1,
+                    'label_value' => 'fpt_label',
+                    'frontend_label' => 'fpt_label_frontend',
+                    'attribute_code' => 'fpt_code',
+                ],
+                'expectedFptLabel' => 'fpt_label'
+            ],
+            'store_label_not_defined' => [
+                'weeeTaxCalculationsByEntity' => [
+                    'weee_value' => 1,
+                    'label_value' => '',
+                    'frontend_label' => 'fpt_label_frontend',
+                    'attribute_code' => 'fpt_code',
+                ],
+                'expectedFptLabel' => 'fpt_label_frontend'
+            ]
+        ];
     }
 }
diff --git a/app/code/Magento/Weee/Ui/DataProvider/Product/Form/Modifier/Weee.php b/app/code/Magento/Weee/Ui/DataProvider/Product/Form/Modifier/Weee.php
index 1285fbe3b0b8c8183cb38b79d7407494ec47880f..197a4d03cc231f271c33ede15730082a302bb80a 100644
--- a/app/code/Magento/Weee/Ui/DataProvider/Product/Form/Modifier/Weee.php
+++ b/app/code/Magento/Weee/Ui/DataProvider/Product/Form/Modifier/Weee.php
@@ -217,9 +217,6 @@ class Weee extends AbstractModifier
                                                 ],
                                                 'caption' => '*',
                                                 'visible' => true,
-                                                'validation' => [
-                                                    'required-entry' => true
-                                                ],
                                             ],
                                         ],
                                     ],
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/_files/discount_10percent.php b/dev/tests/integration/testsuite/Magento/Checkout/_files/discount_10percent.php
index aadfdc9825f541fb408fbeffe7758ddf60b6e836..6741c685a3c7824ba7b5e90f7aca2ea4b9ad72ca 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/_files/discount_10percent.php
+++ b/dev/tests/integration/testsuite/Magento/Checkout/_files/discount_10percent.php
@@ -7,8 +7,11 @@
  */
 
 $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+/** @var \Magento\SalesRule\Model\RuleFactory $salesRule */
+$salesRuleFactory = $objectManager->get('Magento\SalesRule\Model\RuleFactory');
+
 /** @var \Magento\SalesRule\Model\Rule $salesRule */
-$salesRule = $objectManager->create('Magento\SalesRule\Model\Rule');
+$salesRule = $salesRuleFactory->create();
 
 $data = [
     'name' => 'Test Coupon',
@@ -27,5 +30,6 @@ $data = [
 ];
 
 $salesRule->loadPost($data)->setUseAutoGeneration(false)->save();
+$objectManager->get('Magento\Framework\Registry')->unregister('Magento/Checkout/_file/discount_10percent');
 $objectManager->get('Magento\Framework\Registry')
-    ->register('Magento/Checkout/_file/discount_10percent', $salesRule->getRuleId(), true);
+    ->register('Magento/Checkout/_file/discount_10percent', $salesRule->getRuleId());
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/_files/discount_10percent_generalusers.php b/dev/tests/integration/testsuite/Magento/Checkout/_files/discount_10percent_generalusers.php
index e89c11ac5a2f2e565885a0d1491ddb2a74b9db4f..697d15ea5e1e6711a0d765cc7ed8a1f087edf849 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/_files/discount_10percent_generalusers.php
+++ b/dev/tests/integration/testsuite/Magento/Checkout/_files/discount_10percent_generalusers.php
@@ -28,5 +28,6 @@ $data = [
 ];
 
 $salesRule->loadPost($data)->setUseAutoGeneration(false)->save();
+$objectManager->get('Magento\Framework\Registry')->unregister('Magento/Checkout/_file/discount_10percent_generalusers');
 $objectManager->get('Magento\Framework\Registry')
-    ->register('Magento/Checkout/_file/discount_10percent_generalusers', $salesRule->getRuleId(), true);
+    ->register('Magento/Checkout/_file/discount_10percent_generalusers', $salesRule->getRuleId());
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/_files/discount_10percent_generalusers_rollback.php b/dev/tests/integration/testsuite/Magento/Checkout/_files/discount_10percent_generalusers_rollback.php
index a6f462f767443532421f66b9e8d144335469233e..d935c7b7f3b5149fa0771be075269b4359e859f1 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/_files/discount_10percent_generalusers_rollback.php
+++ b/dev/tests/integration/testsuite/Magento/Checkout/_files/discount_10percent_generalusers_rollback.php
@@ -8,5 +8,8 @@
 
 /** @var \Magento\SalesRule\Model\Rule $salesRule */
 $salesRule = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\SalesRule\Model\Rule');
-$salesRule->load('Test Coupon for General', 'name');
+/** @var int $salesRuleId */
+$salesRuleId = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry')
+    ->registry('Magento/Checkout/_file/discount_10percent_generalusers');
+$salesRule->load($salesRuleId);
 $salesRule->delete();
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/_files/discount_10percent_rollback.php b/dev/tests/integration/testsuite/Magento/Checkout/_files/discount_10percent_rollback.php
index 53c90ee1778f1eb0c67b16c1af81e4a87f9cb47f..d27c7a86de5125fe2b716ceb191314487870228c 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/_files/discount_10percent_rollback.php
+++ b/dev/tests/integration/testsuite/Magento/Checkout/_files/discount_10percent_rollback.php
@@ -8,5 +8,8 @@
 
 /** @var \Magento\SalesRule\Model\Rule $salesRule */
 $salesRule = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\SalesRule\Model\Rule');
-$salesRule->load('Test Coupon', 'name');
+/** @var int $salesRuleId */
+$salesRuleId = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry')
+    ->registry('Magento/Checkout/_file/discount_10percent');
+$salesRule->load($salesRuleId);
 $salesRule->delete();
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_coupon_saved.php b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_coupon_saved.php
index c35b5769fc9d3596f1d8429dd099233e28c7117d..54993e76f98fe32e93da770acc5d76d38dcdfee1 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_coupon_saved.php
+++ b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_coupon_saved.php
@@ -13,7 +13,8 @@ require __DIR__ . '/../../Checkout/_files/discount_10percent.php';
 require 'quote_with_address_saved.php';
 
 $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-$salesRule = $objectManager->create('Magento\SalesRule\Model\Rule');
+$salesRuleFactory = $objectManager->get('Magento\SalesRule\Model\RuleFactory');
+$salesRule = $salesRuleFactory->create();
 $salesRuleId = $objectManager->get('Magento\Framework\Registry')
     ->registry('Magento/Checkout/_file/discount_10percent');
 $salesRule->load($salesRuleId);