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 8b079d1fd5d15fecb0a8a63ec7e1c7d9e27d29a7..ab46c78c6f6e74f62a8c798c4c2b039b2eaf4876 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
@@ -4,18 +4,19 @@
  */
 /*jshint browser:true jquery:true*/
 /*global alert*/
-define([], function() {
+define([], function () {
     /**
-     * @param addressData
+     * @param {Object} addressData
      * Returns new address object
      */
     return function (addressData) {
         var identifier = Date.now();
+
         return {
             email: addressData.email,
             countryId: (addressData.country_id) ? addressData.country_id : window.checkoutConfig.defaultCountryId,
-            regionId: (addressData.region && addressData.region.region_id)
-                ? addressData.region.region_id
+            regionId: (addressData.region && addressData.region.region_id) ?
+                addressData.region.region_id
                 : window.checkoutConfig.defaultRegionId,
             regionCode: (addressData.region) ? addressData.region.region_code : null,
             region: (addressData.region) ? addressData.region.region : null,
@@ -33,25 +34,26 @@ define([], function() {
             suffix: addressData.suffix,
             vatId: addressData.vat_id,
             saveInAddressBook: addressData.save_in_address_book,
-            isDefaultShipping: function() {
+            customAttributes: addressData.custom_attributes,
+            isDefaultShipping: function () {
                 return addressData.default_shipping;
             },
-            isDefaultBilling: function() {
+            isDefaultBilling: function () {
                 return addressData.default_billing;
             },
-            getType: function() {
+            getType: function () {
                 return 'new-customer-address';
             },
-            getKey: function() {
+            getKey: function () {
                 return this.getType();
             },
-            getCacheKey: function() {
+            getCacheKey: function () {
                 return this.getType() + identifier;
             },
-            isEditable: function() {
+            isEditable: function () {
                 return true;
             },
-            canUseForBilling: function() {
+            canUseForBilling: function () {
                 return true;
             }
         }
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/quote.js b/app/code/Magento/Checkout/view/frontend/web/js/model/quote.js
index eb950d1e6f9a3d7d484c2379026a1cfd3a03d809..6f86ecedd1af3f5f85909c338ccd00e6cf390dc2 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/model/quote.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/quote.js
@@ -44,7 +44,7 @@ define(
                 return totals;
             },
             setTotals: function(totalsData) {
-                if (_.isObject(totalsData.extension_attributes)) {
+                if (_.isObject(totalsData) && _.isObject(totalsData.extension_attributes)) {
                     _.each(totalsData.extension_attributes, function(element, index) {
                         totalsData[index] = element;
                     });
diff --git a/app/code/Magento/Customer/Model/Address.php b/app/code/Magento/Customer/Model/Address.php
index 54eeaf09f1ff76ef87522cccb5f2cc3d77107281..0d7638a37196a9062f05cc34e7ef9b2d983176c6 100644
--- a/app/code/Magento/Customer/Model/Address.php
+++ b/app/code/Magento/Customer/Model/Address.php
@@ -47,6 +47,11 @@ class Address extends \Magento\Customer\Model\Address\AbstractAddress
      */
     protected $indexerRegistry;
 
+    /**
+     * @var \Magento\Customer\Model\Address\CustomAttributeListInterface
+     */
+    private $attributeList;
+
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
@@ -347,4 +352,27 @@ class Address extends \Magento\Customer\Model\Address\AbstractAddress
         $indexer = $this->indexerRegistry->get(Customer::CUSTOMER_GRID_INDEXER_ID);
         $indexer->reindexRow($this->getCustomerId());
     }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getCustomAttributesCodes()
+    {
+        return array_keys($this->getAttributeList()->getAttributes());
+    }
+
+    /**
+     * Get new AttributeList dependency for application code.
+     * @return \Magento\Customer\Model\Address\CustomAttributeListInterface
+     * @deprecated
+     */
+    private function getAttributeList()
+    {
+        if (!$this->attributeList) {
+            $this->attributeList = \Magento\Framework\App\ObjectManager::getInstance()->get(
+                \Magento\Customer\Model\Address\CustomAttributeListInterface::class
+            );
+        }
+        return $this->attributeList;
+    }
 }
diff --git a/app/code/Magento/Customer/Model/Address/AbstractAddress.php b/app/code/Magento/Customer/Model/Address/AbstractAddress.php
index 6855eb242e6e5f1e9b476a175dadc841d2b9fbf6..1851f858b992f2acfdd8285aeaca897682b24792 100644
--- a/app/code/Magento/Customer/Model/Address/AbstractAddress.php
+++ b/app/code/Magento/Customer/Model/Address/AbstractAddress.php
@@ -263,7 +263,7 @@ class AbstractAddress extends AbstractExtensibleModel implements AddressModelInt
     {
         if (is_array($key)) {
             $key = $this->_implodeArrayField($key);
-        } elseif (is_array($value) && $this->isAddressMultilineAttribute($key)) {
+        } elseif (is_array($value) && !empty($value) && $this->isAddressMultilineAttribute($key)) {
             $value = $this->_implodeArrayValues($value);
         }
         return parent::setData($key, $value);
diff --git a/app/code/Magento/Customer/Model/Address/CustomAttributeList.php b/app/code/Magento/Customer/Model/Address/CustomAttributeList.php
new file mode 100644
index 0000000000000000000000000000000000000000..f83b37c2a814debcc5d6b0c1ccd6a429cb3a755a
--- /dev/null
+++ b/app/code/Magento/Customer/Model/Address/CustomAttributeList.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Customer\Model\Address;
+
+class CustomAttributeList implements CustomAttributeListInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getAttributes()
+    {
+        return [];
+    }
+}
diff --git a/app/code/Magento/Customer/Model/Address/CustomAttributeListInterface.php b/app/code/Magento/Customer/Model/Address/CustomAttributeListInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..c04cfe16f49183e0e27ab8362068b75a83951d3c
--- /dev/null
+++ b/app/code/Magento/Customer/Model/Address/CustomAttributeListInterface.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Customer\Model\Address;
+
+interface CustomAttributeListInterface
+{
+    /**
+     * Retrieve list of customer addresses custom attributes
+     *
+     * @return array
+     */
+    public function getAttributes();
+}
diff --git a/app/code/Magento/Customer/etc/di.xml b/app/code/Magento/Customer/etc/di.xml
index 647ec87efca25a1e583df18d3d469f586996b2c2..1e5f0ce0677ecf699b12b540bb9805d8129d053e 100644
--- a/app/code/Magento/Customer/etc/di.xml
+++ b/app/code/Magento/Customer/etc/di.xml
@@ -49,6 +49,8 @@
                 type="Magento\Customer\Model\EmailNotification" />
     <preference for="Magento\Customer\Api\CustomerNameGenerationInterface"
                 type="Magento\Customer\Helper\View" />
+    <preference for="Magento\Customer\Model\Address\CustomAttributeListInterface"
+                type="Magento\Customer\Model\Address\CustomAttributeList" />
     <type name="Magento\Customer\Model\Session">
         <arguments>
             <argument name="configShare" xsi:type="object">Magento\Customer\Model\Config\Share\Proxy</argument>
diff --git a/app/code/Magento/Customer/view/frontend/web/js/model/customer/address.js b/app/code/Magento/Customer/view/frontend/web/js/model/customer/address.js
index e81016145c705e9d99d86265fb6f0dfd284f9d19..30fbef98fd39ab15db1c7971e3e86ad82e367253 100644
--- a/app/code/Magento/Customer/view/frontend/web/js/model/customer/address.js
+++ b/app/code/Magento/Customer/view/frontend/web/js/model/customer/address.js
@@ -32,6 +32,7 @@ define([], function() {
             vatId: addressData.vat_id,
             sameAsBilling: addressData.same_as_billing,
             saveInAddressBook: addressData.save_in_address_book,
+            customAttributes: addressData.custom_attributes,
             isDefaultShipping: function() {
                 return addressData.default_shipping;
             },
diff --git a/app/code/Magento/Quote/Model/Quote/Item/Compare.php b/app/code/Magento/Quote/Model/Quote/Item/Compare.php
index f61dc25660c9d1dd68b132aaceedc0fd7356315e..10bb712025462fc11f99c2f55206c6cf10f8b854 100644
--- a/app/code/Magento/Quote/Model/Quote/Item/Compare.php
+++ b/app/code/Magento/Quote/Model/Quote/Item/Compare.php
@@ -23,6 +23,9 @@ class Compare
         if (is_string($value) && is_array(@unserialize($value))) {
             $value = @unserialize($value);
             unset($value['qty'], $value['uenc']);
+            $value = array_filter($value, function ($optionValue) {
+                return !empty($optionValue);
+            });
         }
         return $value;
     }
diff --git a/app/code/Magento/Quote/Model/QuoteManagement.php b/app/code/Magento/Quote/Model/QuoteManagement.php
index d8aedf4a8b986a45e237e460e127ba4d5060a8a0..f69e299b4542e7669d9bc23df733d9bd8b63b242 100644
--- a/app/code/Magento/Quote/Model/QuoteManagement.php
+++ b/app/code/Magento/Quote/Model/QuoteManagement.php
@@ -21,6 +21,8 @@ use Magento\Sales\Api\Data\OrderInterfaceFactory as OrderFactory;
 use Magento\Sales\Api\OrderManagementInterface as OrderManagement;
 use Magento\Store\Model\StoreManagerInterface;
 use Magento\Quote\Model\Quote\Address;
+use Magento\Framework\App\ObjectManager;
+use Magento\Quote\Model\QuoteIdMaskFactory;
 
 /**
  * Class QuoteManagement
@@ -130,6 +132,11 @@ class QuoteManagement implements \Magento\Quote\Api\CartManagementInterface
      */
     protected $quoteFactory;
 
+    /**
+     * @var QuoteIdMaskFactory
+     */
+    private $quoteIdMaskFactory;
+
     /**
      * @param EventManager $eventManager
      * @param QuoteValidator $quoteValidator
@@ -262,6 +269,12 @@ class QuoteManagement implements \Magento\Quote\Api\CartManagementInterface
 
         $quote->setCustomer($customer);
         $quote->setCustomerIsGuest(0);
+        $quoteIdMaskFactory = $this->getQuoteIdMaskFactory();
+        /** @var \Magento\Quote\Model\QuoteIdMask $quoteIdMask */
+        $quoteIdMask = $quoteIdMaskFactory->create()->load($cartId, 'quote_id');
+        if ($quoteIdMask->getId()) {
+            $quoteIdMask->delete();
+        }
         $this->quoteRepository->save($quote);
         return true;
 
@@ -547,4 +560,16 @@ class QuoteManagement implements \Magento\Quote\Api\CartManagementInterface
             $shipping->setIsDefaultBilling(true);
         }
     }
+
+    /**
+     * @return QuoteIdMaskFactory
+     * @deprecated
+     */
+    private function getQuoteIdMaskFactory()
+    {
+        if (!$this->quoteIdMaskFactory) {
+            $this->quoteIdMaskFactory = ObjectManager::getInstance()->get(QuoteIdMaskFactory::class);
+        }
+        return $this->quoteIdMaskFactory;
+    }
 }
diff --git a/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/CompareTest.php b/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/CompareTest.php
index a22d10aee9318aed5d07fa70768e8ecfa90ca940..07f9987a902522b5701c6fdab888274f664d2073 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/CompareTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/CompareTest.php
@@ -187,4 +187,31 @@ class CompareTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue([]));
         $this->assertFalse($this->helper->compare($this->itemMock, $this->comparedMock));
     }
+
+    /**
+     * Verify that compare ignores empty options.
+     */
+    public function testCompareWithEmptyValues()
+    {
+        $this->itemMock->expects($this->any())
+            ->method('getProductId')
+            ->will($this->returnValue(1));
+        $this->comparedMock->expects($this->any())
+            ->method('getProductId')
+            ->will($this->returnValue(1));
+
+        $this->itemMock->expects($this->once())->method('getOptions')->willReturn([
+            $this->getOptionMock('option-1', serialize([
+                'non-empty-option' => 'test',
+                'empty_option' => ''
+            ]))
+        ]);
+        $this->comparedMock->expects($this->once())->method('getOptions')->willReturn([
+            $this->getOptionMock('option-1', serialize([
+                'non-empty-option' => 'test'
+            ]))
+        ]);
+        
+        $this->assertTrue($this->helper->compare($this->itemMock, $this->comparedMock));
+    }
 }
diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php
index cd2a56b3b9d7b414b24530e17dbf409dfcf2fe14..2664e7ef21ad76da3bfd6b844caf42d8bbdb8900 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php
@@ -124,7 +124,7 @@ class QuoteManagementTest extends \PHPUnit_Framework_TestCase
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
-    protected $quoteFactoryMock;
+    private $quoteIdMock;
 
     /**
      * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
@@ -238,7 +238,6 @@ class QuoteManagementTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->quoteFactoryMock = $this->getMock('\Magento\Quote\Model\QuoteFactory', ['create'], [], '', false);
-
         $this->model = $objectManager->getObject(
             '\Magento\Quote\Model\QuoteManagement',
             [
@@ -264,6 +263,12 @@ class QuoteManagementTest extends \PHPUnit_Framework_TestCase
                 'quoteFactory' => $this->quoteFactoryMock
             ]
         );
+
+        // Set the new dependency
+        $this->quoteIdMock = $this->getMock('Magento\Quote\Model\QuoteIdMask', [], [], '', false);
+        $quoteIdFactoryMock = $this->getMock(\Magento\Quote\Model\QuoteIdMaskFactory::class, ['create'], [], '', false);
+        $this->setPropertyValue($this->model, 'quoteIdMaskFactory', $quoteIdFactoryMock);
+
     }
 
     public function testCreateEmptyCartAnonymous()
@@ -508,6 +513,13 @@ class QuoteManagementTest extends \PHPUnit_Framework_TestCase
         $customerId = 455;
         $storeId = 5;
 
+        $this->getPropertyValue($this->model, 'quoteIdMaskFactory')
+            ->expects($this->once())
+            ->method('create')
+            ->willReturn($this->quoteIdMock);
+        $this->quoteIdMock->expects($this->once())->method('load')->with($cartId, 'quote_id')->willReturnSelf();
+        $this->quoteIdMock->expects($this->once())->method('getId')->willReturn(10);
+        $this->quoteIdMock->expects($this->once())->method('delete');
         $quoteMock = $this->getMock(
             '\Magento\Quote\Model\Quote',
             ['getCustomerId', 'setCustomer', 'setCustomerIsGuest'],
@@ -739,7 +751,7 @@ class QuoteManagementTest extends \PHPUnit_Framework_TestCase
         $this->checkoutSessionMock->expects($this->once())->method('setLastOrderId')->with($orderId);
         $this->checkoutSessionMock->expects($this->once())->method('setLastRealOrderId')->with($orderIncrementId);
         $this->checkoutSessionMock->expects($this->once())->method('setLastOrderStatus')->with($orderStatus);
- 
+
         $this->assertEquals($orderId, $service->placeOrder($cartId));
     }
 
@@ -935,7 +947,7 @@ class QuoteManagementTest extends \PHPUnit_Framework_TestCase
         $order = $this->getMock(
             'Magento\Sales\Model\Order',
             ['setShippingAddress', 'getAddressesCollection', 'getAddresses', 'getBillingAddress', 'addAddresses',
-            'setBillingAddress', 'setAddresses', 'setPayment', 'setItems', 'setQuoteId'],
+                'setBillingAddress', 'setAddresses', 'setPayment', 'setItems', 'setQuoteId'],
             [],
             '',
             false
@@ -979,4 +991,37 @@ class QuoteManagementTest extends \PHPUnit_Framework_TestCase
             ->willReturn($cartMock);
         $this->assertEquals($cartMock, $this->model->getCartForCustomer($customerId));
     }
+
+    /**
+     * Get any object property value.
+     *
+     * @param $object
+     * @param $property
+     * @return mixed
+     */
+    protected function getPropertyValue($object, $property)
+    {
+        $reflection = new \ReflectionClass(get_class($object));
+        $reflectionProperty = $reflection->getProperty($property);
+        $reflectionProperty->setAccessible(true);
+
+        return $reflectionProperty->getValue($object);
+    }
+
+    /**
+     * Set object property value.
+     *
+     * @param $object
+     * @param $property
+     * @param $value
+     */
+    protected function setPropertyValue(&$object, $property, $value)
+    {
+        $reflection = new \ReflectionClass(get_class($object));
+        $reflectionProperty = $reflection->getProperty($property);
+        $reflectionProperty->setAccessible(true);
+        $reflectionProperty->setValue($object, $value);
+
+        return $object;
+    }
 }
diff --git a/app/code/Magento/SalesRule/view/frontend/web/js/action/set-coupon-code.js b/app/code/Magento/SalesRule/view/frontend/web/js/action/set-coupon-code.js
index b636a613d622ffe50570117408c6be86b414df0a..606fe4013ea762c5460c49202907463d7c7952f2 100644
--- a/app/code/Magento/SalesRule/view/frontend/web/js/action/set-coupon-code.js
+++ b/app/code/Magento/SalesRule/view/frontend/web/js/action/set-coupon-code.js
@@ -13,26 +13,24 @@ define(
         'jquery',
         'Magento_Checkout/js/model/quote',
         'Magento_Checkout/js/model/resource-url-manager',
-        'Magento_Checkout/js/model/payment-service',
         'Magento_Checkout/js/model/error-processor',
         'Magento_SalesRule/js/model/payment/discount-messages',
         'mage/storage',
-        'Magento_Checkout/js/action/get-totals',
         'mage/translate',
-        'Magento_Checkout/js/model/payment/method-list'
+        'Magento_Checkout/js/action/get-payment-information',
+        'Magento_Checkout/js/model/totals'
     ],
     function (
         ko,
         $,
         quote,
         urlManager,
-        paymentService,
         errorProcessor,
         messageContainer,
         storage,
-        getTotalsAction,
         $t,
-        paymentMethodList
+        getPaymentInformationAction,
+        totals
     ) {
         'use strict';
         return function (couponCode, isApplied, isLoading) {
@@ -49,11 +47,10 @@ define(
                         var deferred = $.Deferred();
                         isLoading(false);
                         isApplied(true);
-                        getTotalsAction([], deferred);
-                        $.when(deferred).done(function() {
-                            paymentService.setPaymentMethods(
-                                paymentMethodList()
-                            );
+                        totals.isLoading(true);
+                        getPaymentInformationAction(deferred);
+                        $.when(deferred).done(function () {
+                            totals.isLoading(false);
                         });
                         messageContainer.addSuccessMessage({'message': message});
                     }
@@ -61,6 +58,7 @@ define(
             ).fail(
                 function (response) {
                     isLoading(false);
+                    totals.isLoading(false);
                     errorProcessor.process(response, messageContainer);
                 }
             );
diff --git a/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestCartManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestCartManagementTest.php
index c67470fd69ae592503f7b18dba7eee920ba133a1..a201724eaaa6824e9c0500b2108699be44e33285 100644
--- a/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestCartManagementTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Quote/Api/GuestCartManagementTest.php
@@ -70,9 +70,9 @@ class GuestCartManagementTest extends WebapiAbstract
         $quote = $this->objectManager->create('Magento\Quote\Model\Quote')->load('test01', 'reserved_order_id');
         $cartId = $quote->getId();
         /** @var \Magento\Quote\Model\QuoteIdMask $quoteIdMask */
-        $quoteIdMask = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
-            ->create('Magento\Quote\Model\QuoteIdMaskFactory')
-            ->create();
+        $quoteIdMaskFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
+            ->create('Magento\Quote\Model\QuoteIdMaskFactory');
+        $quoteIdMask = $quoteIdMaskFactory->create();
         $quoteIdMask->load($cartId, 'quote_id');
         //Use masked cart Id
         $cartId = $quoteIdMask->getMaskedId();
@@ -110,6 +110,7 @@ class GuestCartManagementTest extends WebapiAbstract
         $this->assertEquals($customer->getId(), $quote->getCustomerId());
         $this->assertEquals($customer->getFirstname(), $quote->getCustomerFirstname());
         $this->assertEquals($customer->getLastname(), $quote->getCustomerLastname());
+        $this->assertNull($quoteIdMaskFactory->create()->load($cartId, 'masked_id')->getId());
     }
 
     /**