diff --git a/app/code/Magento/Captcha/Model/Cart/ConfigPlugin.php b/app/code/Magento/Captcha/Model/Cart/ConfigPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..73046749a66bfae1f68a81376c9d2963ba995ae9
--- /dev/null
+++ b/app/code/Magento/Captcha/Model/Cart/ConfigPlugin.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Captcha\Model\Cart;
+
+class ConfigPlugin
+{
+    /**
+     * @var \Magento\Captcha\Model\Checkout\ConfigProvider
+     */
+    protected $configProvider;
+
+    /**
+     * @param \Magento\Captcha\Model\Checkout\ConfigProvider $configProvider
+     */
+    public function __construct(
+        \Magento\Captcha\Model\Checkout\ConfigProvider $configProvider
+    ) {
+        $this->configProvider = $configProvider;
+    }
+
+    /**
+     * @param \Magento\Checkout\Block\Cart\Sidebar $subject
+     * @param array $result
+     * @return array
+     *
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function afterGetConfig(\Magento\Checkout\Block\Cart\Sidebar $subject, array $result)
+    {
+        return array_merge_recursive($result, $this->configProvider->getConfig());
+    }
+}
diff --git a/app/code/Magento/Captcha/Model/Checkout/Plugin/Validation.php b/app/code/Magento/Captcha/Model/Checkout/Plugin/Validation.php
deleted file mode 100644
index eac1d7a74421e4994531d7cc71858d5690609fed..0000000000000000000000000000000000000000
--- a/app/code/Magento/Captcha/Model/Checkout/Plugin/Validation.php
+++ /dev/null
@@ -1,60 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Captcha\Model\Checkout\Plugin;
-
-use Magento\Framework\Exception\NoSuchEntityException;
-use Magento\Framework\Exception\InputException;
-
-class Validation
-{
-    /**
-     * @var \Magento\Captcha\Helper\Data
-     */
-    protected $captchaHelper;
-
-    /**
-     * @var array
-     */
-    protected $formIds;
-
-    /**
-     * @param \Magento\Captcha\Helper\Data $captchaHelper
-     * @param array $formIds
-     */
-    public function __construct(
-        \Magento\Captcha\Helper\Data $captchaHelper,
-        array $formIds
-    ) {
-        $this->captchaHelper = $captchaHelper;
-        $this->formIds = $formIds;
-    }
-
-    /**
-     * @param \Magento\Quote\Model\AddressAdditionalDataProcessor $subject
-     * @param \Magento\Quote\Api\Data\AddressAdditionalDataInterface $additionalData
-     * @throws \Magento\Framework\Exception\NoSuchEntityException
-     * @throws \Magento\Framework\Exception\InputException
-     * @return void
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
-     */
-    public function beforeProcess(
-        \Magento\Quote\Model\AddressAdditionalDataProcessor $subject,
-        \Magento\Quote\Api\Data\AddressAdditionalDataInterface $additionalData
-    ) {
-        $formId = $additionalData->getExtensionAttributes()->getCaptchaFormId();
-        $captchaText = $additionalData->getExtensionAttributes()->getCaptchaString();
-
-        if ($formId !== null && !in_array($formId, $this->formIds)) {
-            throw new NoSuchEntityException(__('Provided form does not exist'));
-        }
-        $captchaModel = $this->captchaHelper->getCaptcha($formId);
-        if ($captchaModel->isRequired()) {
-            if (!$captchaModel->isCorrect($captchaText)) {
-                throw new InputException(__('Incorrect CAPTCHA'));
-            }
-        }
-    }
-}
diff --git a/app/code/Magento/Captcha/Model/Customer/Plugin/AjaxLogin.php b/app/code/Magento/Captcha/Model/Customer/Plugin/AjaxLogin.php
index 39edd79861db2de45bc2f3c508c17afb9f3b3cd6..65cb2d8612abd20e6c3cf8a380de5a00f69cdd0c 100644
--- a/app/code/Magento/Captcha/Model/Customer/Plugin/AjaxLogin.php
+++ b/app/code/Magento/Captcha/Model/Customer/Plugin/AjaxLogin.php
@@ -26,53 +26,67 @@ class AjaxLogin
      */
     protected $resultJsonFactory;
 
+    /**
+     * @var array
+     */
+    protected $formIds;
+
     /**
      * @param CaptchaHelper $helper
      * @param SessionManagerInterface $sessionManager
      * @param JsonFactory $resultJsonFactory
+     * @param array $formIds
      */
     public function __construct(
         CaptchaHelper $helper,
         SessionManagerInterface $sessionManager,
-        JsonFactory $resultJsonFactory
+        JsonFactory $resultJsonFactory,
+        array $formIds
     ) {
         $this->helper = $helper;
         $this->sessionManager = $sessionManager;
         $this->resultJsonFactory = $resultJsonFactory;
+        $this->formIds = $formIds;
     }
 
     /**
      * @param \Magento\Customer\Controller\Ajax\Login $subject
      * @param callable $proceed
-     * @return \Magento\Framework\Controller\ResultInterface
+     * @return $this
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
      * @throws \Zend_Json_Exception
+     * @SuppressWarnings(PHPMD.NPathComplexity)
      */
     public function aroundExecute(
         \Magento\Customer\Controller\Ajax\Login $subject,
         \Closure $proceed
     ) {
-        $loginFormId = 'user_login';
+        $captchaFormIdField = 'captcha_form_id';
         $captchaInputName = 'captcha_string';
 
         /** @var \Magento\Framework\App\RequestInterface $request */
         $request = $subject->getRequest();
 
-        /** @var \Magento\Captcha\Model\ModelInterface $captchaModel */
-        $captchaModel = $this->helper->getCaptcha($loginFormId);
-
         $loginParams = \Zend_Json::decode($request->getContent());
         $username = isset($loginParams['username']) ? $loginParams['username'] : null;
-        $captchaString = isset($loginParams[$captchaInputName])
-            ? $loginParams[$captchaInputName]
-            : null;
+        $captchaString = isset($loginParams[$captchaInputName]) ? $loginParams[$captchaInputName] : null;
+        $loginFormId = isset($loginParams[$captchaFormIdField]) ? $loginParams[$captchaFormIdField] : null;
 
-        if ($captchaModel->isRequired($username)) {
-            $captchaModel->logAttempt($username);
-            if (!$captchaModel->isCorrect($captchaString)) {
-                $this->sessionManager->setUsername($username);
-                /** @var \Magento\Framework\Controller\Result\Json $resultJson */
+        foreach ($this->formIds as $formId) {
+            $captchaModel = $this->helper->getCaptcha($formId);
+            if ($captchaModel->isRequired($username) && !in_array($loginFormId, $this->formIds)) {
                 $resultJson = $this->resultJsonFactory->create();
-                return $resultJson->setData(['errors' => true, 'message' => __('Incorrect CAPTCHA')]);
+                return $resultJson->setData(['errors' => true, 'message' => __('Provided form does not exist')]);
+            }
+
+            if ($formId == $loginFormId) {
+                $captchaModel->logAttempt($username);
+                if (!$captchaModel->isCorrect($captchaString)) {
+                    $this->sessionManager->setUsername($username);
+                    /** @var \Magento\Framework\Controller\Result\Json $resultJson */
+                    $resultJson = $this->resultJsonFactory->create();
+                    return $resultJson->setData(['errors' => true, 'message' => __('Incorrect CAPTCHA')]);
+                }
             }
         }
         return $proceed();
diff --git a/app/code/Magento/Captcha/Test/Unit/Controller/Refresh/IndexTest.php b/app/code/Magento/Captcha/Test/Unit/Controller/Refresh/IndexTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..fd47b19ea9038c553c8183b13066421b94236cfa
--- /dev/null
+++ b/app/code/Magento/Captcha/Test/Unit/Controller/Refresh/IndexTest.php
@@ -0,0 +1,122 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Captcha\Test\Unit\Controller\Refresh;
+
+class IndexTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $captchaHelperMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $captchaMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $requestMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $responseMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $contextMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $viewMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $layoutMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $flagMock;
+
+    /**
+     * @var \Magento\Captcha\Controller\Refresh\Index
+     */
+    protected $model;
+
+    protected function setUp()
+    {
+        $this->captchaHelperMock = $this->getMock('Magento\Captcha\Helper\Data', [], [], '', false);
+        $this->captchaMock = $this->getMock('Magento\Captcha\Model\DefaultModel', [], [], '', false);
+        $this->requestMock = $this->getMock('Magento\Framework\App\Request\Http', [], [], '', false);
+        $this->responseMock = $this->getMock('Magento\Framework\App\Response\Http', [], [], '', false);
+        $this->contextMock = $this->getMock('Magento\Framework\App\Action\Context', [], [], '', false);
+        $this->viewMock = $this->getMock('Magento\Framework\App\ViewInterface');
+        $this->layoutMock = $this->getMock('Magento\Framework\View\LayoutInterface');
+        $this->flagMock = $this->getMock('Magento\Framework\App\ActionFlag', [], [], '', false);
+
+        $this->contextMock->expects($this->any())->method('getRequest')->will($this->returnValue($this->requestMock));
+        $this->contextMock->expects($this->any())->method('getView')->will($this->returnValue($this->viewMock));
+        $this->contextMock->expects($this->any())->method('getResponse')->will($this->returnValue($this->responseMock));
+        $this->contextMock->expects($this->any())->method('getActionFlag')->will($this->returnValue($this->flagMock));
+        $this->viewMock->expects($this->any())->method('getLayout')->will($this->returnValue($this->layoutMock));
+
+        $this->model = new \Magento\Captcha\Controller\Refresh\Index($this->contextMock, $this->captchaHelperMock);
+    }
+
+    /**
+     * @dataProvider executeDataProvider
+     * @param int $formId
+     * @param int $callsNumber
+     */
+    public function testExecute($formId, $callsNumber)
+    {
+        $content = ['formId' => $formId];
+
+        $blockMethods = ['setFormId', 'setIsAjax', 'toHtml'];
+        $blockMock = $this->getMock('Magento\Captcha\Block\Captcha', $blockMethods, [], '', false);
+
+        $this->requestMock->expects($this->any())->method('getPost')->with('formId')->will($this->returnValue($formId));
+        $this->requestMock->expects($this->exactly($callsNumber))->method('getContent')
+            ->will($this->returnValue(json_encode($content)));
+        $this->captchaHelperMock->expects($this->any())->method('getCaptcha')->with($formId)
+            ->will($this->returnValue($this->captchaMock));
+        $this->captchaMock->expects($this->once())->method('generate');
+        $this->captchaMock->expects($this->once())->method('getBlockName')->will($this->returnValue('block'));
+        $this->captchaMock->expects($this->once())->method('getImgSrc')->will($this->returnValue('source'));
+        $this->layoutMock->expects($this->once())->method('createBlock')->with('block')
+            ->will($this->returnValue($blockMock));
+        $blockMock->expects($this->any())->method('setFormId')->with($formId)->will($this->returnValue($blockMock));
+        $blockMock->expects($this->any())->method('setIsAjax')->with(true)->will($this->returnValue($blockMock));
+        $blockMock->expects($this->once())->method('toHtml');
+        $this->responseMock->expects($this->once())->method('representJson')->with(json_encode(['imgSrc' => 'source']));
+        $this->flagMock->expects($this->once())->method('set')->with('', 'no-postDispatch', true);
+
+        $this->model->execute();
+    }
+
+    /**
+     * @return array
+     */
+    public function executeDataProvider()
+    {
+        return [
+            [
+                'formId' => null,
+                'callsNumber' => 1,
+            ],
+            [
+                'formId' => 1,
+                'callsNumber' => 0,
+            ]
+        ];
+    }
+}
diff --git a/app/code/Magento/Captcha/Test/Unit/Model/Checkout/ConfigProviderTest.php b/app/code/Magento/Captcha/Test/Unit/Model/Checkout/ConfigProviderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..addc768e6c571efc38a2fa613195b6d6b791a5eb
--- /dev/null
+++ b/app/code/Magento/Captcha/Test/Unit/Model/Checkout/ConfigProviderTest.php
@@ -0,0 +1,121 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Captcha\Test\Unit\Model\Checkout;
+
+class ConfigProviderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManagerMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $captchaHelperMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $captchaMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeMock;
+
+    /**
+     * @var integer
+     */
+    protected $formId = 1;
+
+    /**
+     * @var \Magento\Captcha\Model\Checkout\ConfigProvider
+     */
+    protected $model;
+
+    protected function setUp()
+    {
+        $this->storeManagerMock = $this->getMock('Magento\Store\Model\StoreManagerInterface');
+        $this->captchaHelperMock = $this->getMock('Magento\Captcha\Helper\Data', [], [], '', false);
+        $this->captchaMock = $this->getMock('Magento\Captcha\Model\DefaultModel', [], [], '', false);
+        $this->storeMock = $this->getMock('Magento\Store\Model\Store', [], [], '', false);
+        $formIds = [$this->formId];
+
+        $this->model = new \Magento\Captcha\Model\Checkout\ConfigProvider(
+            $this->storeManagerMock,
+            $this->captchaHelperMock,
+            $formIds
+        );
+    }
+
+    /**
+     * @dataProvider getConfigDataProvider
+     * @param bool $isRequired
+     * @param integer $captchaGenerations
+     * @param array $expectedConfig
+     */
+    public function testGetConfig($isRequired, $captchaGenerations, $expectedConfig)
+    {
+        $this->captchaHelperMock->expects($this->any())->method('getCaptcha')->with($this->formId)
+            ->will($this->returnValue($this->captchaMock));
+
+        $this->captchaMock->expects($this->any())->method('isCaseSensitive')->will($this->returnValue(1));
+        $this->captchaMock->expects($this->any())->method('getHeight')->will($this->returnValue('12px'));
+        $this->captchaMock->expects($this->any())->method('isRequired')->will($this->returnValue($isRequired));
+
+        $this->captchaMock->expects($this->exactly($captchaGenerations))->method('generate');
+        $this->captchaMock->expects($this->exactly($captchaGenerations))->method('getImgSrc')
+            ->will($this->returnValue('source'));
+
+        $this->storeManagerMock->expects($this->any())->method('getStore')->will($this->returnValue($this->storeMock));
+        $this->storeMock->expects($this->once())->method('isCurrentlySecure')->will($this->returnValue(true));
+        $this->storeMock->expects($this->once())->method('getUrl')->with('captcha/refresh', ['_secure' => true])
+            ->will($this->returnValue('https://magento.com/captcha'));
+
+        $config = $this->model->getConfig();
+        $this->assertEquals($config, $expectedConfig);
+    }
+
+    /**
+     * @return array
+     */
+    public function getConfigDataProvider()
+    {
+        return [
+            [
+                'isRequired' => true,
+                'captchaGenerations' => 1,
+                'expectedConfig' => [
+                    'captcha' => [
+                        $this->formId => [
+                            'isCaseSensitive' => true,
+                            'imageHeight' => '12px',
+                            'imageSrc' => 'source',
+                            'refreshUrl' => 'https://magento.com/captcha',
+                            'isRequired' => true
+                        ],
+                    ],
+                ],
+            ],
+            [
+                'isRequired' => false,
+                'captchaGenerations' => 0,
+                'expectedConfig' => [
+                    'captcha' => [
+                        $this->formId => [
+                            'isCaseSensitive' => true,
+                            'imageHeight' => '12px',
+                            'imageSrc' => '',
+                            'refreshUrl' => 'https://magento.com/captcha',
+                            'isRequired' => false
+                        ],
+                    ],
+                ],
+            ],
+        ];
+    }
+}
diff --git a/app/code/Magento/Captcha/Test/Unit/Model/Customer/Plugin/AjaxLoginTest.php b/app/code/Magento/Captcha/Test/Unit/Model/Customer/Plugin/AjaxLoginTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7a79969f8ef4f17c760547f7b7496821b18e9fec
--- /dev/null
+++ b/app/code/Magento/Captcha/Test/Unit/Model/Customer/Plugin/AjaxLoginTest.php
@@ -0,0 +1,173 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Captcha\Test\Unit\Model\Customer\Plugin;
+
+class AjaxLoginTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $sessionManagerMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $captchaHelperMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $jsonFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $captchaMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultJsonMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $requestMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $loginControllerMock;
+
+    /**
+     * @var array
+     */
+    protected $formIds;
+
+    /**
+     * @var \Magento\Captcha\Model\Customer\Plugin\AjaxLogin
+     */
+    protected $model;
+
+    protected function setUp()
+    {
+        $this->sessionManagerMock = $this->getMock('Magento\Checkout\Model\Session', ['setUsername'], [], '', false);
+        $this->captchaHelperMock = $this->getMock('Magento\Captcha\Helper\Data', [], [], '', false);
+        $this->captchaMock = $this->getMock('Magento\Captcha\Model\DefaultModel', [], [], '', false);
+        $this->jsonFactoryMock = $this->getMock(
+            'Magento\Framework\Controller\Result\JsonFactory',
+            ['create'],
+            [],
+            '',
+            false
+        );
+        $this->resultJsonMock = $this->getMock('Magento\Framework\Controller\Result\Json', [], [], '', false);
+        $this->requestMock = $this->getMock('Magento\Framework\App\Request\Http', [], [], '', false);
+        $this->loginControllerMock = $this->getMock('Magento\Customer\Controller\Ajax\Login', [], [], '', false);
+
+        $this->loginControllerMock->expects($this->any())->method('getRequest')
+            ->will($this->returnValue($this->requestMock));
+        $this->captchaHelperMock->expects($this->once())->method('getCaptcha')
+            ->with('user_login')->will($this->returnValue($this->captchaMock));
+        $this->formIds = ['user_login'];
+
+        $this->model = new \Magento\Captcha\Model\Customer\Plugin\AjaxLogin(
+            $this->captchaHelperMock,
+            $this->sessionManagerMock,
+            $this->jsonFactoryMock,
+            $this->formIds
+        );
+    }
+
+    public function testAroundExecute()
+    {
+        $username = 'name';
+        $captchaString = 'string';
+        $requestContent = json_encode([
+            'username' => $username,
+            'captcha_string' => $captchaString,
+            'captcha_form_id' => $this->formIds[0]
+        ]);
+
+        $this->requestMock->expects($this->once())->method('getContent')->will($this->returnValue($requestContent));
+        $this->captchaMock->expects($this->once())->method('isRequired')->with($username)
+            ->will($this->returnValue(true));
+        $this->captchaMock->expects($this->once())->method('logAttempt')->with($username);
+        $this->captchaMock->expects($this->once())->method('isCorrect')->with($captchaString)
+            ->will($this->returnValue(true));
+
+        $closure = function () {
+            return 'result';
+        };
+        $this->assertEquals('result', $this->model->aroundExecute($this->loginControllerMock, $closure));
+    }
+
+    public function testAroundExecuteIncorrectCaptcha()
+    {
+        $username = 'name';
+        $captchaString = 'string';
+        $requestContent = json_encode([
+            'username' => $username,
+            'captcha_string' => $captchaString,
+            'captcha_form_id' => $this->formIds[0]
+        ]);
+
+        $this->requestMock->expects($this->once())->method('getContent')->will($this->returnValue($requestContent));
+        $this->captchaMock->expects($this->once())->method('isRequired')->with($username)
+            ->will($this->returnValue(true));
+        $this->captchaMock->expects($this->once())->method('logAttempt')->with($username);
+        $this->captchaMock->expects($this->once())->method('isCorrect')
+            ->with($captchaString)->will($this->returnValue(false));
+
+        $this->sessionManagerMock->expects($this->once())->method('setUsername')->with($username);
+        $this->jsonFactoryMock->expects($this->once())->method('create')
+            ->will($this->returnValue($this->resultJsonMock));
+
+        $this->resultJsonMock->expects($this->once())->method('setData')
+            ->with(['errors' => true, 'message' => __('Incorrect CAPTCHA')])->will($this->returnValue('response'));
+
+        $closure = function () {
+        };
+        $this->assertEquals('response', $this->model->aroundExecute($this->loginControllerMock, $closure));
+    }
+
+    /**
+     * @dataProvider aroundExecuteCaptchaIsNotRequired
+     * @param string $username
+     * @param array $requestContent
+     */
+    public function testAroundExecuteCaptchaIsNotRequired($username, $requestContent)
+    {
+        $this->requestMock->expects($this->once())->method('getContent')->will($this->returnValue($requestContent));
+
+        $this->captchaMock->expects($this->once())->method('isRequired')->with($username)
+            ->will($this->returnValue(false));
+        $this->captchaMock->expects($this->never())->method('logAttempt')->with($username);
+        $this->captchaMock->expects($this->never())->method('isCorrect');
+
+        $closure = function () {
+            return 'result';
+        };
+        $this->assertEquals('result', $this->model->aroundExecute($this->loginControllerMock, $closure));
+    }
+
+    /**
+     * @return array
+     */
+    public function aroundExecuteCaptchaIsNotRequired()
+    {
+        return [
+            [
+                'username' => 'name',
+                'requestContent' => json_encode(['username' => 'name', 'captcha_string' => 'string']),
+            ],
+            [
+                'username' => null,
+                'requestContent' => json_encode(['captcha_string' => 'string']),
+            ],
+        ];
+    }
+}
diff --git a/app/code/Magento/Captcha/composer.json b/app/code/Magento/Captcha/composer.json
index 987ef790dfd28fc18a1e0a87488a86213f350154..a52065c0e94a4ddbcde9e27a053311b619e9519d 100644
--- a/app/code/Magento/Captcha/composer.json
+++ b/app/code/Magento/Captcha/composer.json
@@ -6,7 +6,6 @@
         "magento/module-store": "0.74.0-beta15",
         "magento/module-customer": "0.74.0-beta15",
         "magento/module-checkout": "0.74.0-beta15",
-        "magento/module-quote": "0.74.0-beta15",
         "magento/module-backend": "0.74.0-beta15",
         "magento/framework": "0.74.0-beta15",
         "magento/magento-composer-installer": "*"
diff --git a/app/code/Magento/Captcha/etc/di.xml b/app/code/Magento/Captcha/etc/di.xml
index 2f150515f4ef38c3d2b14eb746aac1409d422dc6..6dfdcd70b2222544e04939b7eb1aa4404dd07083 100644
--- a/app/code/Magento/Captcha/etc/di.xml
+++ b/app/code/Magento/Captcha/etc/di.xml
@@ -19,16 +19,15 @@
     <type name="Magento\Customer\Controller\Ajax\Login">
         <plugin name="configurable_product" type="Magento\Captcha\Model\Customer\Plugin\AjaxLogin" sortOrder="50" />
     </type>
-    <type name="Magento\Quote\Model\AddressAdditionalDataProcessor">
-        <plugin name="captcha_validation" type="\Magento\Captcha\Model\Checkout\Plugin\Validation" />
-    </type>
-    <type name="Magento\Captcha\Model\Checkout\Plugin\Validation">
+    <type name="Magento\Captcha\Model\Customer\Plugin\AjaxLogin">
         <arguments>
             <argument name="formIds" xsi:type="array">
                 <item name="user_login" xsi:type="string">user_login</item>
                 <item name="guest_checkout" xsi:type="string">guest_checkout</item>
-                <item name="register_during_checkout" xsi:type="string">register_during_checkout</item>
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Checkout\Block\Cart\Sidebar">
+        <plugin name="login_captcha" type="\Magento\Captcha\Model\Cart\ConfigPlugin" sortOrder="50" />
+    </type>
 </config>
diff --git a/app/code/Magento/Captcha/etc/extension_attributes.xml b/app/code/Magento/Captcha/etc/extension_attributes.xml
deleted file mode 100644
index e99af65250102d4db36964850c3ee1d602f08b99..0000000000000000000000000000000000000000
--- a/app/code/Magento/Captcha/etc/extension_attributes.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0"?>
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Api/etc/extension_attributes.xsd">
-    <extension_attributes for="Magento\Quote\Api\Data\AddressAdditionalDataInterface">
-        <attribute code="captcha_string" type="string" />
-        <attribute code="captcha_form_id" type="string" />
-    </extension_attributes>
-</config>
-
-
diff --git a/app/code/Magento/Captcha/etc/frontend/di.xml b/app/code/Magento/Captcha/etc/frontend/di.xml
index 4807eb77b726076246107bddfc1acbac299d83a6..a768ffac2f67e372ed36af36133105b7ca909f54 100644
--- a/app/code/Magento/Captcha/etc/frontend/di.xml
+++ b/app/code/Magento/Captcha/etc/frontend/di.xml
@@ -18,7 +18,6 @@
             <argument name="formIds" xsi:type="array">
                 <item name="user_login" xsi:type="string">user_login</item>
                 <item name="guest_checkout" xsi:type="string">guest_checkout</item>
-                <item name="register_during_checkout" xsi:type="string">register_during_checkout</item>
             </argument>
         </arguments>
     </type>
diff --git a/app/code/Magento/Captcha/view/frontend/layout/checkout_onepage_index.xml b/app/code/Magento/Captcha/view/frontend/layout/checkout_onepage_index.xml
index 3154d7f81876805131083c4912ab3e0fbf93cc87..d7d6fc551c5ff3f777effb8a6cf3b573c60113a1 100644
--- a/app/code/Magento/Captcha/view/frontend/layout/checkout_onepage_index.xml
+++ b/app/code/Magento/Captcha/view/frontend/layout/checkout_onepage_index.xml
@@ -5,7 +5,7 @@
  * See COPYING.txt for license details.
  */
 -->
-<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
     <body>
         <referenceBlock name="checkout.root">
             <arguments>
@@ -13,30 +13,59 @@
                     <item name="components" xsi:type="array">
                         <item name="checkout" xsi:type="array">
                             <item name="children" xsi:type="array">
+                                <item name="authentication" xsi:type="array">
+                                    <item name="children" xsi:type="array">
+                                        <item name="captcha" xsi:type="array">
+                                            <item name="component" xsi:type="string">Magento_Captcha/js/view/checkout/loginCaptcha</item>
+                                            <item name="displayArea" xsi:type="string">additional-login-form-fields</item>
+                                            <item name="formId" xsi:type="string">user_login</item>
+                                            <item name="configSource" xsi:type="string">checkoutConfig</item>
+                                        </item>
+                                    </item>
+                                </item>
                                 <item name="steps" xsi:type="array">
                                     <item name="children" xsi:type="array">
-                                        <item name="authentication" xsi:type="array">
+                                        <item name="shipping-step" xsi:type="array">
                                             <item name="children" xsi:type="array">
-                                                <item name="captcha" xsi:type="array">
-                                                    <item name="component" xsi:type="string">Magento_Captcha/js/view/checkout/loginCaptcha</item>
-                                                    <item name="displayArea" xsi:type="string">additional-login-form-fields</item>
-                                                    <item name="formId" xsi:type="string">user_login</item>
+                                                <item name="shippingAddress" xsi:type="array">
+                                                    <item name="children" xsi:type="array">
+                                                        <item name="customer-email" xsi:type="array">
+                                                            <item name="children" xsi:type="array">
+                                                                <item name="additional-login-form-fields" xsi:type="array">
+                                                                    <item name="children" xsi:type="array">
+                                                                        <item name="captcha" xsi:type="array">
+                                                                            <item name="component" xsi:type="string">Magento_Captcha/js/view/checkout/loginCaptcha</item>
+                                                                            <item name="displayArea" xsi:type="string">additional-login-form-fields</item>
+                                                                            <item name="formId" xsi:type="string">guest_checkout</item>
+                                                                            <item name="configSource" xsi:type="string">checkoutConfig</item>
+                                                                        </item>
+                                                                    </item>
+                                                                </item>
+                                                            </item>
+                                                        </item>
+                                                    </item>
                                                 </item>
                                             </item>
                                         </item>
-                                        <item name="billingAddress" xsi:type="array">
+                                        <item name="billing-step" xsi:type="array">
                                             <item name="children" xsi:type="array">
-                                                <item name="captcha_guest_checkout" xsi:type="array">
-                                                    <item name="component" xsi:type="string">Magento_Captcha/js/view/checkout/guestCaptcha</item>
-                                                    <item name="displayArea" xsi:type="string">additional-fieldsets</item>
-                                                    <item name="formId" xsi:type="string">guest_checkout</item>
-                                                    <item name="dataScope" xsi:type="string">additionalAddressData</item>
-                                                </item>
-                                                <item name="captcha_register_during_checkout" xsi:type="array">
-                                                    <item name="component" xsi:type="string">Magento_Captcha/js/view/checkout/registerCaptcha</item>
-                                                    <item name="displayArea" xsi:type="string">additional-fieldsets</item>
-                                                    <item name="formId" xsi:type="string">register_during_checkout</item>
-                                                    <item name="dataScope" xsi:type="string">additionalAddressData</item>
+                                                <item name="payment" xsi:type="array">
+                                                    <item name="children" xsi:type="array">
+                                                        <item name="customer-email" xsi:type="array">
+                                                            <item name="children" xsi:type="array">
+                                                                <item name="additional-login-form-fields" xsi:type="array">
+                                                                    <item name="children" xsi:type="array">
+                                                                        <item name="captcha" xsi:type="array">
+                                                                            <item name="component" xsi:type="string">Magento_Captcha/js/view/checkout/loginCaptcha</item>
+                                                                            <item name="displayArea" xsi:type="string">additional-login-form-fields</item>
+                                                                            <item name="formId" xsi:type="string">guest_checkout</item>
+                                                                            <item name="configSource" xsi:type="string">checkoutConfig</item>
+                                                                        </item>
+                                                                    </item>
+                                                                </item>
+                                                            </item>
+                                                        </item>
+                                                    </item>
                                                 </item>
                                             </item>
                                         </item>
@@ -49,4 +78,4 @@
             </arguments>
         </referenceBlock>
     </body>
-</page>
\ No newline at end of file
+</page>
diff --git a/app/code/Magento/Captcha/view/frontend/layout/default.xml b/app/code/Magento/Captcha/view/frontend/layout/default.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9e0bf3cc751c5c0b9fad96ea62e3da31b26ed320
--- /dev/null
+++ b/app/code/Magento/Captcha/view/frontend/layout/default.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+    <body>
+        <referenceBlock name="minicart">
+            <arguments>
+                <argument name="jsLayout" xsi:type="array">
+                    <item name="components" xsi:type="array">
+                        <item name="minicart_content" xsi:type="array">
+                            <item name="children" xsi:type="array">
+                                <item name="sign-in-popup" xsi:type="array">
+                                    <item name="children" xsi:type="array">
+                                        <item name="captcha" xsi:type="array">
+                                            <item name="component" xsi:type="string">Magento_Captcha/js/view/checkout/loginCaptcha</item>
+                                            <item name="displayArea" xsi:type="string">additional-login-form-fields</item>
+                                            <item name="formId" xsi:type="string">user_login</item>
+                                            <item name="configSource" xsi:type="string">checkout</item>
+                                        </item>
+                                    </item>
+                                </item>
+                            </item>
+                        </item>
+                    </item>
+                </argument>
+            </arguments>
+        </referenceBlock>
+    </body>
+</page>
diff --git a/app/code/Magento/Captcha/view/frontend/web/js/action/refresh.js b/app/code/Magento/Captcha/view/frontend/web/js/action/refresh.js
index cc8b2119827216883b9330c5717d5cbf1d460337..b11ae9b1f144aee227da25267b86dd7cc7ed1681 100644
--- a/app/code/Magento/Captcha/view/frontend/web/js/action/refresh.js
+++ b/app/code/Magento/Captcha/view/frontend/web/js/action/refresh.js
@@ -9,9 +9,10 @@ define(
     function(storage) {
         "use strict";
         return function(refreshUrl, formId, imageSource) {
-            storage.post(
+            return storage.post(
                 refreshUrl,
-                JSON.stringify({'formId': formId})
+                JSON.stringify({'formId': formId}),
+                false
             ).done(
                 function (response) {
                     if (response.imgSrc) {
diff --git a/app/code/Magento/Captcha/view/frontend/web/js/model/captcha.js b/app/code/Magento/Captcha/view/frontend/web/js/model/captcha.js
index a8abae3cc8de7638c7c6414df11a646935e3e715..6a720a8cdeb91879729ecc3ca4aa85f3e497f3bd 100644
--- a/app/code/Magento/Captcha/view/frontend/web/js/model/captcha.js
+++ b/app/code/Magento/Captcha/view/frontend/web/js/model/captcha.js
@@ -6,10 +6,11 @@
 /*global alert*/
 define(
     [
+        'jquery',
         'ko',
         'Magento_Captcha/js/action/refresh'
     ],
-    function(ko, refreshAction) {
+    function($, ko, refreshAction) {
         return function (captchaData) {
             return {
                 formId: captchaData.formId,
@@ -20,6 +21,7 @@ define(
                 isCaseSensitive: captchaData.isCaseSensitive,
                 imageHeight: captchaData.imageHeight,
                 refreshUrl: captchaData.refreshUrl,
+                isLoading: ko.observable(false),
 
                 getFormId: function () {
                     return this.formId;
@@ -70,7 +72,14 @@ define(
                     this.captchaValue(value);
                 },
                 refresh: function() {
-                    refreshAction(this.getRefreshUrl(), this.getFormId(), this.getImageSource());
+                    var refresh,
+                        self = this;
+                    this.isLoading(true);
+
+                    refresh = refreshAction(this.getRefreshUrl(), this.getFormId(), this.getImageSource());
+                    $.when(refresh).done(function() {
+                        self.isLoading(false);
+                    });
                 }
             };
         }
diff --git a/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/defaultCaptcha.js b/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/defaultCaptcha.js
index 5039e6a56a4d254c1f3763c3ead7d62efc481f81..ddb4a6f84ae57bf22a0c9396a5843658813f0785 100644
--- a/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/defaultCaptcha.js
+++ b/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/defaultCaptcha.js
@@ -7,15 +7,14 @@
 define(
     [
         'jquery',
-        'ko',
         'uiComponent',
-        'Magento_Customer/js/model/customer',
         'Magento_Captcha/js/model/captcha',
         'Magento_Captcha/js/model/captchaList'
     ],
-    function ($, ko, Component, customer, Captcha, captchaList) {
-        "use strict";
-        var captchaConfig = window.checkoutConfig.captcha;
+    function ($, Component, Captcha, captchaList) {
+        'use strict';
+        var captchaConfig;
+
         return Component.extend({
             defaults: {
                 template: 'Magento_Captcha/checkout/captcha'
@@ -26,11 +25,16 @@ define(
                 return this.currentCaptcha.getCaptchaValue();
             },
             initialize: function() {
+                this._super();
+                captchaConfig = window[this.configSource]['captcha'];
+
                 $.each(captchaConfig, function(formId, captchaData) {
                     captchaData.formId = formId;
                     captchaList.add(Captcha(captchaData));
                 });
-                this._super();
+            },
+            getIsLoading: function() {
+                return this.currentCaptcha.isLoading
             },
             getCurrentCaptcha: function() {
                 return this.currentCaptcha;
diff --git a/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/guestCaptcha.js b/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/guestCaptcha.js
deleted file mode 100644
index eb7e9c806e64bd94da1086bf4e92af253ce8027a..0000000000000000000000000000000000000000
--- a/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/guestCaptcha.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*browser:true jquery:true*/
-/*global define*/
-define(
-    [
-        'Magento_Captcha/js/view/checkout/defaultCaptcha',
-        'Magento_Checkout/js/model/quote',
-        'Magento_Captcha/js/model/captchaList',
-        'Magento_Checkout/js/action/select-shipping-address',
-        'Magento_Checkout/js/action/select-billing-address',
-        'Magento_Checkout/js/model/step-navigator'
-    ],
-    function (defaultCaptcha, quote, captchaList, selectShippingAddress, selectBillingAddress, navigator) {
-        "use strict";
-        return defaultCaptcha.extend({
-            initialize: function() {
-                this._super();
-                var self = this;
-                var currentCaptcha = captchaList.getCaptchaByFormId(this.formId);
-                if (currentCaptcha != null) {
-                    this.setCurrentCaptcha(currentCaptcha);
-                    quote.getCheckoutMethod().subscribe(function(method) {
-                        if (method == 'guest') {
-                            self.setIsVisible(true);
-                            var callback = function(isSuccessful) {
-                                if (!isSuccessful) {
-                                    currentCaptcha.setCaptchaValue(null);
-                                    currentCaptcha.refresh();
-                                    navigator.goToStep('billingAddress');
-                                }
-                            };
-                            selectShippingAddress.setActionCallback(callback);
-                            selectBillingAddress.setActionCallback(callback);
-                        } else {
-                            self.setIsVisible(false);
-                        }
-                    });
-                }
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/loginCaptcha.js b/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/loginCaptcha.js
index e042e96e850e6558926cd6612a8a9d7526635c77..75f7c4f0071dc96da86f13112f3d8c04190e6a02 100644
--- a/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/loginCaptcha.js
+++ b/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/loginCaptcha.js
@@ -7,26 +7,25 @@
 define(
     [
         'Magento_Captcha/js/view/checkout/defaultCaptcha',
-        'Magento_Customer/js/model/customer',
-        'Magento_Captcha/js/model/captchaList'
+        'Magento_Captcha/js/model/captchaList',
+        'Magento_Customer/js/action/login'
     ],
-    function (defaultCaptcha, customer, captchaList) {
-        "use strict";
+    function (defaultCaptcha, captchaList, loginAction) {
+        'use strict';
         return defaultCaptcha.extend({
             initialize: function() {
                 this._super();
-                var currentCaptcha = captchaList.getCaptchaByFormId(this.formId);
+                var currentCaptcha = captchaList.getCaptchaByFormId(this.formId),
+                    self = this;
+
                 if (currentCaptcha != null) {
                     currentCaptcha.setIsVisible(true);
                     this.setCurrentCaptcha(currentCaptcha);
-                    this.updateCaptchaOnFailedLogin();
-                }
-            },
-            updateCaptchaOnFailedLogin: function () {
-                if (this.formId == 'user_login') {
-                    var self = this;
-                    customer.getFailedLoginAttempts().subscribe(function() {
-                        self.refresh();
+
+                    loginAction.registerLoginCallback(function(loginData) {
+                        if (loginData.captcha_form_id && loginData.captcha_form_id == self.formId) {
+                            self.refresh();
+                        }
                     });
                 }
             }
diff --git a/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/registerCaptcha.js b/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/registerCaptcha.js
deleted file mode 100644
index ea284b5fe562483669319af1c308409d4e137358..0000000000000000000000000000000000000000
--- a/app/code/Magento/Captcha/view/frontend/web/js/view/checkout/registerCaptcha.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*browser:true jquery:true*/
-/*global define*/
-define(
-    [
-        'Magento_Captcha/js/view/checkout/defaultCaptcha',
-        'Magento_Checkout/js/model/quote',
-        'Magento_Captcha/js/model/captchaList',
-        'Magento_Checkout/js/action/select-shipping-address',
-        'Magento_Checkout/js/action/select-billing-address',
-        'Magento_Checkout/js/model/step-navigator'
-    ],
-    function (defaultCaptcha, quote, captchaList, selectShippingAddress, selectBillingAddress, navigator) {
-        "use strict";
-        return defaultCaptcha.extend({
-            initialize: function() {
-                this._super();
-                var self = this;
-                var currentCaptcha = captchaList.getCaptchaByFormId(this.formId);
-                if (currentCaptcha != null) {
-                    this.setCurrentCaptcha(currentCaptcha);
-                    quote.getCheckoutMethod().subscribe(function(method) {
-                        if (method == 'register') {
-                            self.setIsVisible(true);
-                            var callback = function(isSuccessful) {
-                                if (!isSuccessful) {
-                                    currentCaptcha.setCaptchaValue(null);
-                                    currentCaptcha.refresh();
-                                    navigator.goToStep('billingAddress');
-                                }
-                            };
-                            selectShippingAddress.setActionCallback(callback);
-                            selectBillingAddress.setActionCallback(callback);
-                        } else {
-                            self.setIsVisible(false);
-                        }
-                    });
-                }
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Captcha/view/frontend/web/template/checkout/captcha.html b/app/code/Magento/Captcha/view/frontend/web/template/checkout/captcha.html
index fd345b82386446b5553ef81f3ce56b5e1c70f158..3b294d904b2cbe877dd80763986aa7fa66ecf89b 100644
--- a/app/code/Magento/Captcha/view/frontend/web/template/checkout/captcha.html
+++ b/app/code/Magento/Captcha/view/frontend/web/template/checkout/captcha.html
@@ -5,7 +5,7 @@
  */
 -->
 <!-- ko if: (isRequired() && getIsVisible())-->
-<div class="field captcha required">
+<div class="field captcha required" data-bind="blockLoader: getIsLoading()">
     <label data-bind="attr: {for: 'captcha_' + formId}" class="label"><span data-bind="text: $t('Please type the letters below')"></span></label>
     <div class="control captcha">
         <input name="captcha_string" type="text" class="input-text required-entry" data-bind="value: captchaValue(), attr: {id: 'captcha_' + formId, 'data-scope': dataScope}" />
diff --git a/app/code/Magento/Catalog/Test/Unit/Helper/Product/ConfigurationPoolTest.php b/app/code/Magento/Catalog/Test/Unit/Helper/Product/ConfigurationPoolTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..5b0f7dd0f9340b1c33eb6b1ec0d41b749243e620
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Unit/Helper/Product/ConfigurationPoolTest.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Catalog\Test\Unit\Helper\Product;
+
+class ConfigurationPoolTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var array
+     */
+    protected $instancesType;
+
+    /**
+     * @var \Magento\Catalog\Helper\Product\ConfigurationPool
+     */
+    protected $model;
+
+    protected function setUp()
+    {
+        $this->instancesType = ['simple' => 'simple', 'default' => 'default'];
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManagerInterface');
+        $this->model = new \Magento\Catalog\Helper\Product\ConfigurationPool($objectManagerMock, $this->instancesType);
+    }
+
+    /**
+     * @dataProvider getByProductTypeDataProvider
+     * @param string $productType
+     * @param string $expectedResult
+     */
+    public function testGetByProductType($productType, $expectedResult)
+    {
+        $this->assertEquals($expectedResult, $this->model->getByProductType($productType));
+    }
+
+    /**
+     * @return array
+     */
+    public function getByProductTypeDataProvider()
+    {
+        return [
+            [
+                'productType' => 'simple',
+                'expectedResult' => 'simple'
+            ],
+            [
+                'productType' => 'custom',
+                'expectedResult' => 'default'
+            ],
+        ];
+    }
+}
diff --git a/app/code/Magento/Checkout/Api/Data/PaymentDetailsInterface.php b/app/code/Magento/Checkout/Api/Data/PaymentDetailsInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..ea68c7aa5d85f7b00d7d3c96431c509e8b30388f
--- /dev/null
+++ b/app/code/Magento/Checkout/Api/Data/PaymentDetailsInterface.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Api\Data;
+
+interface PaymentDetailsInterface
+{
+    /**#@+
+     * Constants defined for keys of array, makes typos less likely
+     */
+    const PAYMENT_METHODS = 'payment_methods';
+
+    const TOTALS = 'totals';
+
+    /**#@-*/
+
+    /**
+     * @return \Magento\Quote\Api\Data\PaymentMethodInterface[]
+     */
+    public function getPaymentMethods();
+
+    /**
+     * @param \Magento\Quote\Api\Data\PaymentMethodInterface[] $paymentMethods
+     * @return $this
+     */
+    public function setPaymentMethods($paymentMethods);
+
+    /**
+     * @return \Magento\Quote\Api\Data\TotalsInterface
+     */
+    public function getTotals();
+
+    /**
+     * @param \Magento\Quote\Api\Data\TotalsInterface $totals
+     * @return $this
+     */
+    public function setTotals($totals);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Checkout\Api\Data\PaymentDetailsExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Checkout\Api\Data\PaymentDetailsExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Checkout\Api\Data\PaymentDetailsExtensionInterface $extensionAttributes
+    );
+}
diff --git a/app/code/Magento/Checkout/Api/Data/ShippingInformationInterface.php b/app/code/Magento/Checkout/Api/Data/ShippingInformationInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..9b2b3710eb3ae4b521e96712312a2f2718cc53e6
--- /dev/null
+++ b/app/code/Magento/Checkout/Api/Data/ShippingInformationInterface.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Api\Data;
+
+interface ShippingInformationInterface extends \Magento\Framework\Api\CustomAttributesDataInterface
+{
+    /**#@+
+     * Constants defined for keys of array, makes typos less likely
+     */
+    const SHIPPING_ADDRESS = 'shipping_address';
+
+    const SHIPPING_METHOD_CODE = 'shipping_method_code';
+
+    const SHIPPING_CARRIER_CODE = 'shipping_carrier_code';
+
+    /**#@-*/
+
+    /**
+     * Returns shipping address
+     *
+     * @return \Magento\Quote\Api\Data\AddressInterface
+     */
+    public function getShippingAddress();
+
+    /**
+     * Set shipping address
+     *
+     * @param \Magento\Quote\Api\Data\AddressInterface $address
+     * @return $this
+     */
+    public function setShippingAddress(\Magento\Quote\Api\Data\AddressInterface $address);
+
+    /**
+     * Returns shipping method code
+     *
+     * @return string
+     */
+    public function getShippingMethodCode();
+
+    /**
+     * Set shipping method code
+     *
+     * @param string $code
+     * @return $this
+     */
+    public function setShippingMethodCode($code);
+
+    /**
+     * Returns carrier code
+     *
+     * @return string
+     */
+    public function getShippingCarrierCode();
+
+    /**
+     * Set carrier code
+     *
+     * @param string $code
+     * @return $this
+     */
+    public function setShippingCarrierCode($code);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Checkout\Api\Data\ShippingInformationExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Checkout\Api\Data\ShippingInformationExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Checkout\Api\Data\ShippingInformationExtensionInterface $extensionAttributes
+    );
+}
diff --git a/app/code/Magento/Checkout/Api/GuestPaymentInformationManagementInterface.php b/app/code/Magento/Checkout/Api/GuestPaymentInformationManagementInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..7a2b178aa6691c64a9e00618c30f8717006a0220
--- /dev/null
+++ b/app/code/Magento/Checkout/Api/GuestPaymentInformationManagementInterface.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Api;
+
+interface GuestPaymentInformationManagementInterface
+{
+    /**
+     * Set payment information and place order for a specified cart.
+     *
+     * @param string $cartId
+     * @param string $email
+     * @param \Magento\Quote\Api\Data\PaymentInterface $paymentMethod
+     * @param \Magento\Quote\Api\Data\AddressInterface $billingAddress
+     * @throws \Magento\Framework\Exception\CouldNotSaveException
+     * @return int Order ID.
+     */
+    public function savePaymentInformationAndPlaceOrder(
+        $cartId,
+        $email,
+        \Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
+        \Magento\Quote\Api\Data\AddressInterface $billingAddress
+    );
+
+    /**
+     * Set payment information for a specified cart.
+     *
+     * @param string $cartId
+     * @param string $email
+     * @param \Magento\Quote\Api\Data\PaymentInterface $paymentMethod
+     * @param \Magento\Quote\Api\Data\AddressInterface $billingAddress
+     * @throws \Magento\Framework\Exception\CouldNotSaveException
+     * @return int Order ID.
+     */
+    public function savePaymentInformation(
+        $cartId,
+        $email,
+        \Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
+        \Magento\Quote\Api\Data\AddressInterface $billingAddress
+    );
+}
diff --git a/app/code/Magento/Checkout/Api/GuestShippingInformationManagementInterface.php b/app/code/Magento/Checkout/Api/GuestShippingInformationManagementInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..c52ee4a7766b8b8dfa6e6b55b76a16a4d2e8a786
--- /dev/null
+++ b/app/code/Magento/Checkout/Api/GuestShippingInformationManagementInterface.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Api;
+
+interface GuestShippingInformationManagementInterface
+{
+    /**
+     * @param string $cartId
+     * @param \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
+     * @return \Magento\Checkout\Api\Data\PaymentDetailsInterface
+     */
+    public function saveAddressInformation(
+        $cartId,
+        \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
+    );
+}
diff --git a/app/code/Magento/Checkout/Api/PaymentInformationManagementInterface.php b/app/code/Magento/Checkout/Api/PaymentInformationManagementInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..bac301c7ab3695bc691aa74e5b9b764a366427a1
--- /dev/null
+++ b/app/code/Magento/Checkout/Api/PaymentInformationManagementInterface.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Api;
+
+interface PaymentInformationManagementInterface
+{
+    /**
+     * Set payment information and place order for a specified cart.
+     *
+     * @param int $cartId
+     * @param \Magento\Quote\Api\Data\PaymentInterface $paymentMethod
+     * @param \Magento\Quote\Api\Data\AddressInterface $billingAddress
+     * @throws \Magento\Framework\Exception\CouldNotSaveException
+     * @return int Order ID.
+     */
+    public function savePaymentInformationAndPlaceOrder(
+        $cartId,
+        \Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
+        \Magento\Quote\Api\Data\AddressInterface $billingAddress
+    );
+
+    /**
+     * Set payment information for a specified cart.
+     *
+     * @param int $cartId
+     * @param \Magento\Quote\Api\Data\PaymentInterface $paymentMethod
+     * @param \Magento\Quote\Api\Data\AddressInterface $billingAddress
+     * @throws \Magento\Framework\Exception\CouldNotSaveException
+     * @return int Order ID.
+     */
+    public function savePaymentInformation(
+        $cartId,
+        \Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
+        \Magento\Quote\Api\Data\AddressInterface $billingAddress
+    );
+}
diff --git a/app/code/Magento/Checkout/Api/ShippingInformationManagementInterface.php b/app/code/Magento/Checkout/Api/ShippingInformationManagementInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..4f39b764b35b9c3b7bbedbaf4914b7c6a732d77f
--- /dev/null
+++ b/app/code/Magento/Checkout/Api/ShippingInformationManagementInterface.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Api;
+
+interface ShippingInformationManagementInterface
+{
+    /**
+     * @param int $cartId
+     * @param \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
+     * @return \Magento\Checkout\Api\Data\PaymentDetailsInterface
+     */
+    public function saveAddressInformation(
+        $cartId,
+        \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
+    );
+}
diff --git a/app/code/Magento/Checkout/Block/Cart/Sidebar.php b/app/code/Magento/Checkout/Block/Cart/Sidebar.php
index 593f1bd35806d975c41fba9806a6586c538a2950..a754a3c6582c58f3a1dcd4ec8f90f234a2ffaeff 100644
--- a/app/code/Magento/Checkout/Block/Cart/Sidebar.php
+++ b/app/code/Magento/Checkout/Block/Cart/Sidebar.php
@@ -52,6 +52,25 @@ class Sidebar extends AbstractCart
         $this->imageView = $imageView;
     }
 
+    /**
+     * Returns minicart config
+     *
+     * @return array
+     */
+    public function getConfig()
+    {
+        return [
+            'shoppingCartUrl' => $this->getShoppingCartUrl(),
+            'checkoutUrl' => $this->getCheckoutUrl(),
+            'updateItemQtyUrl' => $this->getUpdateItemQtyUrl(),
+            'removeItemUrl' => $this->getRemoveItemUrl(),
+            'imageTemplate' => $this->getImageHtmlTemplate(),
+            'customerRegisterUrl' => $this->getCustomerRegisterUrlUrl(),
+            'customerForgotPasswordUrl' => $this->getCustomerForgotPasswordUrl(),
+            'baseUrl' => $this->getBaseUrl()
+        ];
+    }
+
     /**
      * @return string
      */
@@ -139,4 +158,34 @@ class Sidebar extends AbstractCart
     {
         return $this->getLayout()->getBlock('checkout.cart.minicart.totals')->toHtml();
     }
+
+    /**
+     * Get customer register url
+     *
+     * @return string
+     */
+    public function getCustomerRegisterUrlUrl()
+    {
+        return $this->getUrl('customer/account/create');
+    }
+
+    /**
+     * Get customer forgot password url
+     *
+     * @return string
+     */
+    public function getCustomerForgotPasswordUrl()
+    {
+        return $this->getUrl('customer/account/forgotpassword');
+    }
+
+    /**
+     * Return base url.
+     *
+     * @return string
+     */
+    public function getBaseUrl()
+    {
+        return $this->_storeManager->getStore()->getBaseUrl();
+    }
 }
diff --git a/app/code/Magento/Checkout/Block/Checkout/AttributeMerger.php b/app/code/Magento/Checkout/Block/Checkout/AttributeMerger.php
index 224079faff6ff237b82ffa3ddf482d83d486a62f..32609252f0552023241063773f18a2f61c82fe02 100644
--- a/app/code/Magento/Checkout/Block/Checkout/AttributeMerger.php
+++ b/app/code/Magento/Checkout/Block/Checkout/AttributeMerger.php
@@ -125,6 +125,9 @@ class AttributeMerger
                 'elementTmpl' => isset($additionalConfig['config']['elementTmpl'])
                     ? $additionalConfig['config']['elementTmpl']
                     : $elementTemplate,
+                'tooltip' => isset($additionalConfig['config']['tooltip'])
+                    ? $additionalConfig['config']['tooltip']
+                    : null
             ],
             'dataScope' => $dataScopePrefix . '.' . $attributeCode,
             'label' => $attributeConfig['label'],
@@ -141,7 +144,7 @@ class AttributeMerger
 
         $defaultValue = $this->getDefaultValue($attributeCode);
         if (null !== $defaultValue) {
-            $element['default'] = $defaultValue;
+            $element['value'] = $defaultValue;
         }
         return $element;
     }
diff --git a/app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php b/app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php
index 9f5ffc3f6ef6dca215aaa6c100d57d4b4009dc8b..20332513a009f078db5fc7cd3468894ccaaac593 100644
--- a/app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php
+++ b/app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php
@@ -60,26 +60,29 @@ class LayoutProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcesso
         }
 
         // The following code is a workaround for custom address attributes
-        if (isset($jsLayout['components']['checkout']['children']['steps']['children']['billingAddress']
-            ['children']['billing-address-fieldset']['children']
+        if (isset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
+            ['payment']['children']
         )) {
-            $fields = $jsLayout['components']['checkout']['children']['steps']['children']['billingAddress']
-            ['children']['billing-address-fieldset']['children'];
-            $jsLayout['components']['checkout']['children']['steps']['children']['billingAddress']
-            ['children']['billing-address-fieldset']['children'] = $this->merger->merge(
-                $elements,
-                'checkoutProvider',
-                'billingAddress',
-                $fields
-            );
+            $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
+                    )
+                );
         }
-        if (isset($jsLayout['components']['checkout']['children']['steps']['children']['shippingAddress']
-            ['children']['shipping-address-fieldset']['children']
+
+        if (isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
+            ['children']['shippingAddress']['children']['shipping-address-fieldset']['children']
         )) {
-            $fields = $jsLayout['components']['checkout']['children']['steps']['children']['shippingAddress']
-            ['children']['shipping-address-fieldset']['children'];
-            $jsLayout['components']['checkout']['children']['steps']['children']['shippingAddress']
-            ['children']['shipping-address-fieldset']['children'] = $this->merger->merge(
+            $fields = $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
+            ['children']['shippingAddress']['children']['shipping-address-fieldset']['children'];
+            $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
+            ['children']['shippingAddress']['children']['shipping-address-fieldset']['children'] = $this->merger->merge(
                 $elements,
                 'checkoutProvider',
                 'shippingAddress',
@@ -88,4 +91,90 @@ class LayoutProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcesso
         }
         return $jsLayout;
     }
+
+    /**
+     * Inject billing address component into every payment component
+     *
+     * @param array $configuration list of payment components
+     * @param array $elements attributes that must be displayed in address form
+     * @return array
+     */
+    private function processPaymentConfiguration(array &$configuration, array $elements)
+    {
+        $output = [];
+        foreach ($configuration as $paymentGroup => $groupConfig) {
+            foreach ($groupConfig['methods'] as $paymentCode => $paymentComponent) {
+                if (empty($paymentComponent['isBillingAddressRequired'])) {
+                    continue;
+                }
+                $output[$paymentCode . '-form'] = [
+                    'component' => 'Magento_Checkout/js/view/billing-address',
+                    'displayArea' => 'billing-address-form-' . $paymentCode,
+                    'provider' => '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' => [
+                                            'validate-select' => 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',
+                                            ],
+                                        ],
+                                    ],
+                                ]
+                            ),
+                        ],
+                    ],
+                ];
+            }
+            unset($configuration[$paymentGroup]['methods']);
+        }
+
+        return $output;
+    }
 }
diff --git a/app/code/Magento/Checkout/Block/Checkout/TotalsProcessor.php b/app/code/Magento/Checkout/Block/Checkout/TotalsProcessor.php
new file mode 100644
index 0000000000000000000000000000000000000000..af5a8a51dd456490a1e1f66329cb1f83f94cc088
--- /dev/null
+++ b/app/code/Magento/Checkout/Block/Checkout/TotalsProcessor.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Block\Checkout;
+
+use Magento\Framework\App\Config\ScopeConfigInterface;
+
+class TotalsProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcessorInterface
+{
+    /**
+     * Core store config
+     *
+     * @var ScopeConfigInterface
+     */
+    protected $scopeConfig;
+
+    /**
+     * @param ScopeConfigInterface $scopeConfig
+     */
+    public function __construct(
+        ScopeConfigInterface $scopeConfig
+    ) {
+        $this->scopeConfig = $scopeConfig;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function process($jsLayout)
+    {
+        $configData = $this->scopeConfig->getValue('sales/totals_sort');
+        $totals = $jsLayout['components']['checkout']['children']['summary']['children']['totals']['children'];
+        foreach ($totals as $code => &$total) {
+            //convert JS naming style to config naming style
+            $code = str_replace('-', '_', $code);
+            if (array_key_exists($code, $configData)) {
+                $total['sortOrder'] = $configData[$code];
+            }
+        }
+        $jsLayout['components']['checkout']['children']['summary']['children']['totals']['children'] = $totals;
+
+        return array_merge_recursive($jsLayout, $totals);
+    }
+}
diff --git a/app/code/Magento/Checkout/Controller/Onepage/Index.php b/app/code/Magento/Checkout/Controller/Onepage/Index.php
index 991511fc02267a4d6a250fb78576b0feaa08ad14..7fa9fa794c5fb5ab4441324cc716e26bec15c987 100644
--- a/app/code/Magento/Checkout/Controller/Onepage/Index.php
+++ b/app/code/Magento/Checkout/Controller/Onepage/Index.php
@@ -15,11 +15,19 @@ class Index extends \Magento\Checkout\Controller\Onepage
      */
     public function execute()
     {
-        if (!$this->_objectManager->get('Magento\Checkout\Helper\Data')->canOnepageCheckout()) {
+        $checkoutHelper = $this->_objectManager->get('Magento\Checkout\Helper\Data');
+        if (!$checkoutHelper->canOnepageCheckout()) {
             $this->messageManager->addError(__('One-page checkout is turned off.'));
             return $this->resultRedirectFactory->create()->setPath('checkout/cart');
         }
+
         $quote = $this->getOnepage()->getQuote();
+
+        if (!$this->_customerSession->isLoggedIn() && !$checkoutHelper->isAllowedGuestCheckout($quote)) {
+            $this->messageManager->addError(__('Guest checkout is disabled.'));
+            return $this->resultRedirectFactory->create()->setPath('checkout/cart');
+        }
+
         if (!$quote->hasItems() || $quote->getHasError() || !$quote->validateMinimumAmount()) {
             return $this->resultRedirectFactory->create()->setPath('checkout/cart');
         }
diff --git a/app/code/Magento/Checkout/CustomerData/Cart.php b/app/code/Magento/Checkout/CustomerData/Cart.php
index ae306dc9439a26fedb5282ced36980fd55476887..55fd454db8aeb8d42bb6674d6ad0336f9e45c1ff 100644
--- a/app/code/Magento/Checkout/CustomerData/Cart.php
+++ b/app/code/Magento/Checkout/CustomerData/Cart.php
@@ -94,6 +94,7 @@ class Cart extends \Magento\Framework\Object implements SectionSourceInterface
             'possible_onepage_checkout' => $this->isPossibleOnepageCheckout(),
             'items' => $this->getRecentItems(),
             'extra_actions' => $this->layout->createBlock('Magento\Catalog\Block\ShortcutButtons')->toHtml(),
+            'isGuestCheckoutAllowed' => $this->isGuestCheckoutAllowed(),
         ];
     }
 
@@ -173,4 +174,14 @@ class Cart extends \Magento\Framework\Object implements SectionSourceInterface
         }
         return $this->getQuote()->getAllVisibleItems();
     }
+
+    /**
+     * Check if guest checkout is allowed
+     *
+     * @return bool
+     */
+    public function isGuestCheckoutAllowed()
+    {
+        return $this->checkoutHelper->isAllowedGuestCheckout($this->checkoutSession->getQuote());
+    }
 }
diff --git a/app/code/Magento/Checkout/Model/Cart/ImageProvider.php b/app/code/Magento/Checkout/Model/Cart/ImageProvider.php
new file mode 100644
index 0000000000000000000000000000000000000000..f49b267b88a8ea7441b817fdb5a9fe42fe13b187
--- /dev/null
+++ b/app/code/Magento/Checkout/Model/Cart/ImageProvider.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Model\Cart;
+
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class ImageProvider
+{
+    /**
+     * @var \Magento\Quote\Api\CartItemRepositoryInterface
+     */
+    protected $itemRepository;
+
+    /**
+     * @var \Magento\Checkout\CustomerData\ItemPoolInterface
+     */
+    protected $itemPool;
+
+    /**
+     * @param \Magento\Quote\Api\CartItemRepositoryInterface $itemRepository
+     * @param \Magento\Checkout\CustomerData\ItemPoolInterface $itemPool
+     */
+    public function __construct(
+        \Magento\Quote\Api\CartItemRepositoryInterface $itemRepository,
+        \Magento\Checkout\CustomerData\ItemPoolInterface $itemPool
+    ) {
+        $this->itemRepository = $itemRepository;
+        $this->itemPool = $itemPool;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getImages($cartId)
+    {
+        $itemData = [];
+
+        /** @see code/Magento/Catalog/Helper/Product.php */
+        $items = $this->itemRepository->getList($cartId);
+        /** @var \Magento\Quote\Model\Quote\Item $cartItem */
+        foreach ($items as $cartItem) {
+            $allData = $this->itemPool->getItemData($cartItem);
+            $itemData[$cartItem->getItemId()] = $allData['product_image'];
+        }
+        return $itemData;
+    }
+}
diff --git a/app/code/Magento/Checkout/Model/DefaultConfigProvider.php b/app/code/Magento/Checkout/Model/DefaultConfigProvider.php
index 08de243b3a16294460af5e94807652592114ab90..21911aec850fcdc82c6163d2684fc10869fa8421 100644
--- a/app/code/Magento/Checkout/Model/DefaultConfigProvider.php
+++ b/app/code/Magento/Checkout/Model/DefaultConfigProvider.php
@@ -6,7 +6,6 @@
 namespace Magento\Checkout\Model;
 
 use Magento\Checkout\Helper\Data as CheckoutHelper;
-use Magento\Checkout\Model\Type\Onepage as OnepageCheckout;
 use Magento\Checkout\Model\Session as CheckoutSession;
 use Magento\Customer\Api\CustomerRepositoryInterface as CustomerRepository;
 use Magento\Customer\Model\Context as CustomerContext;
@@ -23,6 +22,9 @@ use Magento\Catalog\Helper\Product\ConfigurationPool;
 use Magento\Quote\Model\QuoteIdMaskFactory;
 use Magento\Framework\Locale\FormatInterface as LocaleFormat;
 use Magento\Framework\UrlInterface;
+use Magento\Quote\Api\CartTotalRepositoryInterface;
+use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Store\Model\ScopeInterface;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -120,6 +122,53 @@ class DefaultConfigProvider implements ConfigProviderInterface
      */
     protected $viewConfig;
 
+    /**
+     * @var \Magento\Directory\Model\Country\Postcode\ConfigInterface
+     */
+    protected $postCodesConfig;
+
+    /**
+     * @var \Magento\Directory\Helper\Data
+     */
+    protected $directoryHelper;
+
+    /**
+     * @var Cart\ImageProvider
+     */
+    protected $imageProvider;
+
+    /**
+     * @var CartTotalRepositoryInterface
+     */
+    protected $cartTotalRepository;
+
+    /**
+     * Shipping method data factory.
+     *
+     * @var \Magento\Quote\Api\Data\EstimateAddressInterfaceFactory
+     */
+    protected $estimatedAddressFactory;
+
+    /**
+     * @var ScopeConfigInterface
+     */
+    protected $scopeConfig;
+
+    /**
+     * @var \Magento\Shipping\Model\Config
+     */
+    protected $shippingMethodConfig;
+
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * @var \Magento\Quote\Api\PaymentMethodManagementInterface
+     */
+    protected $paymentMethodManagement;
+
     /**
      * @param CheckoutHelper $checkoutHelper
      * @param Session $checkoutSession
@@ -139,6 +188,15 @@ class DefaultConfigProvider implements ConfigProviderInterface
      * @param FormKey $formKey
      * @param \Magento\Catalog\Helper\Image $imageHelper
      * @param \Magento\Framework\View\ConfigInterface $viewConfig
+     * @param \Magento\Directory\Model\Country\Postcode\ConfigInterface $postCodesConfig
+     * @param Cart\ImageProvider $imageProvider
+     * @param \Magento\Directory\Helper\Data $directoryHelper
+     * @param CartTotalRepositoryInterface $cartTotalRepository
+     * @param \Magento\Quote\Api\Data\EstimateAddressInterfaceFactory $estimatedAddressFactory
+     * @param ScopeConfigInterface $scopeConfig
+     * @param \Magento\Shipping\Model\Config $shippingMethodConfig
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     * @param \Magento\Quote\Api\PaymentMethodManagementInterface $paymentMethodManagement
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function __construct(
@@ -159,7 +217,16 @@ class DefaultConfigProvider implements ConfigProviderInterface
         \Magento\Customer\Model\Address\Config $addressConfig,
         FormKey $formKey,
         \Magento\Catalog\Helper\Image $imageHelper,
-        \Magento\Framework\View\ConfigInterface $viewConfig
+        \Magento\Framework\View\ConfigInterface $viewConfig,
+        \Magento\Directory\Model\Country\Postcode\ConfigInterface $postCodesConfig,
+        Cart\ImageProvider $imageProvider,
+        \Magento\Directory\Helper\Data $directoryHelper,
+        CartTotalRepositoryInterface $cartTotalRepository,
+        \Magento\Quote\Api\Data\EstimateAddressInterfaceFactory $estimatedAddressFactory,
+        ScopeConfigInterface $scopeConfig,
+        \Magento\Shipping\Model\Config $shippingMethodConfig,
+        \Magento\Store\Model\StoreManagerInterface $storeManager,
+        \Magento\Quote\Api\PaymentMethodManagementInterface $paymentMethodManagement
     ) {
         $this->checkoutHelper = $checkoutHelper;
         $this->checkoutSession = $checkoutSession;
@@ -179,6 +246,15 @@ class DefaultConfigProvider implements ConfigProviderInterface
         $this->formKey = $formKey;
         $this->imageHelper = $imageHelper;
         $this->viewConfig = $viewConfig;
+        $this->postCodesConfig = $postCodesConfig;
+        $this->imageProvider = $imageProvider;
+        $this->directoryHelper = $directoryHelper;
+        $this->cartTotalRepository = $cartTotalRepository;
+        $this->estimatedAddressFactory = $estimatedAddressFactory;
+        $this->scopeConfig = $scopeConfig;
+        $this->shippingMethodConfig = $shippingMethodConfig;
+        $this->storeManager = $storeManager;
+        $this->paymentMethodManagement = $paymentMethodManagement;
     }
 
     /**
@@ -186,6 +262,7 @@ class DefaultConfigProvider implements ConfigProviderInterface
      */
     public function getConfig()
     {
+        $quoteId = $this->checkoutSession->getQuote()->getId();
         return [
             'formKey' => $this->formKey->getFormKey(),
             'customerData' => $this->getCustomerData(),
@@ -207,10 +284,72 @@ class DefaultConfigProvider implements ConfigProviderInterface
             'basePriceFormat' => $this->localeFormat->getPriceFormat(
                 null,
                 $this->currencyManager->getDefaultCurrency()
-            )
+            ),
+            'postCodes' => $this->postCodesConfig->getPostCodes(),
+            'imageData' => $this->imageProvider->getImages($quoteId),
+            'countryData' => $this->getCountryData(),
+            'totalsData' => $this->getTotalsData(),
+            'shippingRates' => $this->getDefaultShippingRates(),
+            'shippingPolicy' => [
+                'isEnabled' => $this->scopeConfig->isSetFlag(
+                    'shipping/shipping_policy/enable_shipping_policy',
+                    ScopeInterface::SCOPE_STORE
+                ),
+                'shippingPolicyContent' => nl2br(
+                    $this->scopeConfig->getValue(
+                        'shipping/shipping_policy/shipping_policy_content',
+                        ScopeInterface::SCOPE_STORE
+                    )
+                )
+            ],
+            'activeCarriers' => $this->getActiveCarriers(),
+            'originCountryCode' => $this->getOriginCountryCode(),
+            'paymentMethods' => $this->getPaymentMethods()
         ];
     }
 
+    /**
+     * Get default shipping rates
+     *
+     * @return array
+     */
+    private function getDefaultShippingRates()
+    {
+        $output = [];
+        $addressKey = null;
+        if ($this->checkoutSession->getQuote()->getId()) {
+            $quote = $this->quoteRepository->get($this->checkoutSession->getQuote()->getId());
+            /** @var \Magento\Quote\Api\Data\EstimateAddressInterface $estimatedAddress */
+            $estimatedAddress = $this->estimatedAddressFactory->create();
+
+            $address = $quote->getShippingAddress();
+            if ($address &&
+                ($address->getCountryId()
+                    || $address->getPostcode()
+                    || $address->getRegion()
+                    || $address->getRegionId()
+                )
+            ) {
+                $estimatedAddress->setCountryId($address->getCountryId());
+                $estimatedAddress->setPostcode($address->getPostcode());
+                $estimatedAddress->setRegion($address->getRegion());
+                $estimatedAddress->setRegionId($address->getRegionId());
+            } else {
+                $estimatedAddress->setCountryId($this->directoryHelper->getDefaultCountry());
+            }
+            $rates = $this->shippingMethodManager->estimateByAddress($quote->getId(), $estimatedAddress);
+            foreach ($rates as $rate) {
+                $output[] = $rate->__toArray();
+            }
+
+            if ($address->getCustomerAddressId()) {
+                $addressKey = 'customer-address' . $address->getCustomerAddressId();
+            }
+        };
+        return ['key' => $addressKey, 'data' => $output];
+
+    }
+
     /**
      * Retrieve customer data
      *
@@ -270,13 +409,6 @@ class DefaultConfigProvider implements ConfigProviderInterface
         $quoteData = [];
         if ($this->checkoutSession->getQuote()->getId()) {
             $quote = $this->quoteRepository->get($this->checkoutSession->getQuote()->getId());
-            // the following condition is a legacy logic left here for compatibility
-            if (!$quote->getCustomer()->getId()) {
-                $this->quoteRepository->save($this->checkoutSession->getQuote()->setCheckoutMethod('guest'));
-            } else {
-                $this->quoteRepository->save($this->checkoutSession->getQuote()->setCheckoutMethod(null));
-            }
-
             $quoteData = $quote->toArray();
             $quoteData['is_virtual'] = $quote->getIsVirtual();
 
@@ -357,22 +489,21 @@ class DefaultConfigProvider implements ConfigProviderInterface
     /**
      * Retrieve selected shipping method
      *
-     * @return string
+     * @return array|null
      */
     private function getSelectedShippingMethod()
     {
-        // Shipping method ID contains carrier code and shipping method code
-        $shippingMethodId = '';
+        $shippingMethodData = null;
         try {
             $quoteId = $this->checkoutSession->getQuote()->getId();
             $shippingMethod = $this->shippingMethodManager->get($quoteId);
             if ($shippingMethod) {
-                $shippingMethodId = $shippingMethod->getCarrierCode() . '_' . $shippingMethod->getMethodCode();
+                $shippingMethodData = $shippingMethod->__toArray();
             }
         } catch (\Exception $exception) {
-            $shippingMethodId = '';
+            $shippingMethodData = null;
         }
-        return $shippingMethodId;
+        return $shippingMethodData;
     }
 
     /**
@@ -434,4 +565,97 @@ class DefaultConfigProvider implements ConfigProviderInterface
     {
         return $this->checkoutSession->getQuote()->getStore()->getBaseUrl(UrlInterface::URL_TYPE_STATIC);
     }
+
+    /**
+     * Return countries data
+     * @return array
+     */
+    private function getCountryData()
+    {
+        $country = [];
+        $regionsData = $this->directoryHelper->getRegionData();
+        foreach ($this->directoryHelper->getCountryCollection() as $code => $data) {
+            $country[$code]['name'] = $data->getName();
+            if (array_key_exists($code, $regionsData)) {
+                foreach ($regionsData[$code] as $key => $region) {
+                    $country[$code]['regions'][$key]['code'] = $region['code'];
+                    $country[$code]['regions'][$key]['name'] = $region['name'];
+                }
+            }
+
+        }
+        return $country;
+    }
+
+    /**
+     * Return quote totals data
+     * @return array
+     */
+    private function getTotalsData()
+    {
+        /** @var \Magento\Quote\Api\Data\TotalsInterface $totals */
+        $totals = $this->cartTotalRepository->get($this->checkoutSession->getQuote()->getId());
+        $items = [];
+        /** @var  \Magento\Quote\Model\Cart\Totals\Item $item */
+        foreach ($totals->getItems() as $item) {
+            $items[] = $item->__toArray();
+        }
+        $totalSegmentsData = [];
+        /** @var \Magento\Quote\Model\Cart\TotalSegment $totalSegment */
+        foreach ($totals->getTotalSegments() as $totalSegment) {
+            $totalSegmentsData[] = $totalSegment->toArray();
+        }
+        $totals->setItems($items);
+        $totals->setTotalSegments($totalSegmentsData);
+        $totalsArray = $totals->toArray();
+        if (is_object($totals->getExtensionAttributes())) {
+            $totalsArray['extension_attributes'] = $totals->getExtensionAttributes()->__toArray();
+        }
+        return $totalsArray;
+    }
+
+    /**
+     * Returns active carriers codes
+     * @return array
+     */
+    private function getActiveCarriers()
+    {
+        $activeCarriers = [];
+        foreach ($this->shippingMethodConfig->getActiveCarriers() as $carrier) {
+            $activeCarriers[] = $carrier->getCarrierCode();
+        }
+        return $activeCarriers;
+    }
+
+    /**
+     * Returns origin country code
+     * @return string
+     */
+    private function getOriginCountryCode()
+    {
+        return $this->scopeConfig->getValue(
+            \Magento\Shipping\Model\Config::XML_PATH_ORIGIN_COUNTRY_ID,
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+            $this->storeManager->getStore()
+        );
+    }
+
+    /**
+     * Returns array of payment methods
+     * @return array
+     */
+    private function getPaymentMethods()
+    {
+        $paymentMethods = [];
+        $quote = $this->checkoutSession->getQuote();
+        if ($quote->getIsVirtual()) {
+            foreach ($this->paymentMethodManagement->getList($quote->getId()) as $paymentMethod) {
+                $paymentMethods[] = [
+                    'code' => $paymentMethod->getCode(),
+                    'title' => $paymentMethod->getTitle()
+                ];
+            }
+        }
+        return $paymentMethods;
+    }
 }
diff --git a/app/code/Magento/Checkout/Model/GuestPaymentInformationManagement.php b/app/code/Magento/Checkout/Model/GuestPaymentInformationManagement.php
new file mode 100644
index 0000000000000000000000000000000000000000..75e2539835e50cad7c7ff97d185044196423bf5d
--- /dev/null
+++ b/app/code/Magento/Checkout/Model/GuestPaymentInformationManagement.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Checkout\Model;
+
+class GuestPaymentInformationManagement implements \Magento\Checkout\Api\GuestPaymentInformationManagementInterface
+{
+
+    /**
+     * @var \Magento\Quote\Api\GuestBillingAddressManagementInterface
+     */
+    protected $billingAddressManagement;
+
+    /**
+     * @var \Magento\Quote\Api\GuestPaymentMethodManagementInterface
+     */
+    protected $paymentMethodManagement;
+
+    /**
+     * @var \Magento\Quote\Api\GuestCartManagementInterface
+     */
+    protected $cartManagement;
+
+    /**
+     * @param \Magento\Quote\Api\GuestBillingAddressManagementInterface $billingAddressManagement
+     * @param \Magento\Quote\Api\GuestPaymentMethodManagementInterface $paymentMethodManagement
+     * @param \Magento\Quote\Api\GuestCartManagementInterface $cartManagement
+     */
+    public function __construct(
+        \Magento\Quote\Api\GuestBillingAddressManagementInterface $billingAddressManagement,
+        \Magento\Quote\Api\GuestPaymentMethodManagementInterface $paymentMethodManagement,
+        \Magento\Quote\Api\GuestCartManagementInterface $cartManagement
+    ) {
+        $this->billingAddressManagement = $billingAddressManagement;
+        $this->paymentMethodManagement = $paymentMethodManagement;
+        $this->cartManagement = $cartManagement;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function savePaymentInformationAndPlaceOrder(
+        $cartId,
+        $email,
+        \Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
+        \Magento\Quote\Api\Data\AddressInterface $billingAddress
+    ) {
+        $this->savePaymentInformation($cartId, $email, $paymentMethod, $billingAddress);
+        return $this->cartManagement->placeOrder($cartId);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function savePaymentInformation(
+        $cartId,
+        $email,
+        \Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
+        \Magento\Quote\Api\Data\AddressInterface $billingAddress
+    ) {
+        $billingAddress->setEmail($email);
+        $this->billingAddressManagement->assign($cartId, $billingAddress);
+        $this->paymentMethodManagement->set($cartId, $paymentMethod);
+        return true;
+    }
+}
diff --git a/app/code/Magento/Checkout/Model/GuestShippingInformationManagement.php b/app/code/Magento/Checkout/Model/GuestShippingInformationManagement.php
new file mode 100644
index 0000000000000000000000000000000000000000..475bc915bf90ce15e48972dcc03979a02abc3a55
--- /dev/null
+++ b/app/code/Magento/Checkout/Model/GuestShippingInformationManagement.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Model;
+
+class GuestShippingInformationManagement implements \Magento\Checkout\Api\GuestShippingInformationManagementInterface
+{
+    /**
+     * @var \Magento\Quote\Model\QuoteIdMaskFactory
+     */
+    protected $quoteIdMaskFactory;
+
+    /**
+     * @var ShippingInformationManagement
+     */
+    protected $shippingInformationManagement;
+
+    /**
+     * @param \Magento\Quote\Model\QuoteIdMaskFactory $quoteIdMaskFactory
+     * @param ShippingInformationManagement $shippingInformationManagement
+     */
+    public function __construct(
+        \Magento\Quote\Model\QuoteIdMaskFactory $quoteIdMaskFactory,
+        \Magento\Checkout\Model\ShippingInformationManagement $shippingInformationManagement
+    ) {
+        $this->quoteIdMaskFactory = $quoteIdMaskFactory;
+        $this->shippingInformationManagement = $shippingInformationManagement;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function saveAddressInformation(
+        $cartId,
+        \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
+    ) {
+        /** @var $quoteIdMask \Magento\Quote\Model\QuoteIdMask */
+        $quoteIdMask = $this->quoteIdMaskFactory->create()->load($cartId, 'masked_id');
+        return $this->shippingInformationManagement->saveAddressInformation(
+            $quoteIdMask->getQuoteId(),
+            $addressInformation
+        );
+    }
+}
diff --git a/app/code/Magento/Checkout/Model/PaymentDetails.php b/app/code/Magento/Checkout/Model/PaymentDetails.php
new file mode 100644
index 0000000000000000000000000000000000000000..add196487ae989ccc195e557ee3c6f5e3de7177e
--- /dev/null
+++ b/app/code/Magento/Checkout/Model/PaymentDetails.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Model;
+
+/**
+ * @codeCoverageIgnoreStart
+ */
+class PaymentDetails extends \Magento\Framework\Model\AbstractExtensibleModel implements
+    \Magento\Checkout\Api\Data\PaymentDetailsInterface
+{
+    /**
+     * @{inheritdoc}
+     */
+    public function getPaymentMethods()
+    {
+        return $this->getData(self::PAYMENT_METHODS);
+    }
+
+    /**
+     * @{inheritdoc}
+     */
+    public function setPaymentMethods($paymentMethods)
+    {
+        return $this->setData(self::PAYMENT_METHODS, $paymentMethods);
+    }
+
+    /**
+     * @{inheritdoc}
+     */
+    public function getTotals()
+    {
+        return $this->getData(self::TOTALS);
+    }
+
+    /**
+     * @{inheritdoc}
+     */
+    public function setTotals($totals)
+    {
+        return $this->setData(self::TOTALS, $totals);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Checkout\Api\Data\PaymentDetailsExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Checkout\Api\Data\PaymentDetailsExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Checkout\Api\Data\PaymentDetailsExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
+}
diff --git a/app/code/Magento/Checkout/Model/PaymentInformationManagement.php b/app/code/Magento/Checkout/Model/PaymentInformationManagement.php
new file mode 100644
index 0000000000000000000000000000000000000000..ff4b973c6298e3b95265a2d121aa51bac501804f
--- /dev/null
+++ b/app/code/Magento/Checkout/Model/PaymentInformationManagement.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Checkout\Model;
+
+class PaymentInformationManagement implements \Magento\Checkout\Api\PaymentInformationManagementInterface
+{
+
+    /**
+     * @var \Magento\Quote\Api\BillingAddressManagementInterface
+     */
+    protected $billingAddressManagement;
+
+    /**
+     * @var \Magento\Quote\Api\PaymentMethodManagementInterface
+     */
+    protected $paymentMethodManagement;
+
+    /**
+     * @var \Magento\Quote\Api\CartManagementInterface
+     */
+    protected $cartManagement;
+
+    /**
+     * @param \Magento\Quote\Api\BillingAddressManagementInterface $billingAddressManagement
+     * @param \Magento\Quote\Api\PaymentMethodManagementInterface $paymentMethodManagement
+     * @param \Magento\Quote\Api\CartManagementInterface $cartManagement
+     */
+    public function __construct(
+        \Magento\Quote\Api\BillingAddressManagementInterface $billingAddressManagement,
+        \Magento\Quote\Api\PaymentMethodManagementInterface $paymentMethodManagement,
+        \Magento\Quote\Api\CartManagementInterface $cartManagement
+    ) {
+        $this->billingAddressManagement = $billingAddressManagement;
+        $this->paymentMethodManagement = $paymentMethodManagement;
+        $this->cartManagement = $cartManagement;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function savePaymentInformationAndPlaceOrder(
+        $cartId,
+        \Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
+        \Magento\Quote\Api\Data\AddressInterface $billingAddress
+    ) {
+        $this->savePaymentInformation($cartId, $paymentMethod, $billingAddress);
+        return $this->cartManagement->placeOrder($cartId);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function savePaymentInformation(
+        $cartId,
+        \Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
+        \Magento\Quote\Api\Data\AddressInterface $billingAddress
+    ) {
+        $this->billingAddressManagement->assign($cartId, $billingAddress);
+        $this->paymentMethodManagement->set($cartId, $paymentMethod);
+        return true;
+    }
+}
diff --git a/app/code/Magento/Checkout/Model/ShippingInformation.php b/app/code/Magento/Checkout/Model/ShippingInformation.php
new file mode 100644
index 0000000000000000000000000000000000000000..44d024c7171f587514efb03446cd2480f6b29364
--- /dev/null
+++ b/app/code/Magento/Checkout/Model/ShippingInformation.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Model;
+
+use Magento\Framework\Model\AbstractExtensibleModel;
+use Magento\Checkout\Api\Data\ShippingInformationInterface;
+
+/**
+ * @codeCoverageIgnoreStart
+ */
+class ShippingInformation extends AbstractExtensibleModel implements ShippingInformationInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getShippingAddress()
+    {
+        return $this->getData(self::SHIPPING_ADDRESS);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setShippingAddress(\Magento\Quote\Api\Data\AddressInterface $address)
+    {
+        return $this->setData(self::SHIPPING_ADDRESS, $address);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getShippingMethodCode()
+    {
+        return $this->getData(self::SHIPPING_METHOD_CODE);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setShippingMethodCode($code)
+    {
+        return $this->setData(self::SHIPPING_METHOD_CODE, $code);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getShippingCarrierCode()
+    {
+        return $this->getData(self::SHIPPING_CARRIER_CODE);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setShippingCarrierCode($code)
+    {
+        return $this->setData(self::SHIPPING_CARRIER_CODE, $code);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setExtensionAttributes(
+        \Magento\Checkout\Api\Data\ShippingInformationExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
+}
diff --git a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php
new file mode 100644
index 0000000000000000000000000000000000000000..4cf21372af8943caf46bafa3812898e5715c57d0
--- /dev/null
+++ b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php
@@ -0,0 +1,178 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Checkout\Model;
+
+use Magento\Framework\Exception\InputException;
+use Magento\Framework\Exception\StateException;
+use Magento\Framework\Exception\NoSuchEntityException;
+use Psr\Log\LoggerInterface as Logger;
+use \Magento\Quote\Model\QuoteAddressValidator;
+
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class ShippingInformationManagement implements \Magento\Checkout\Api\ShippingInformationManagementInterface
+{
+    /**
+     * @var \Magento\Quote\Api\PaymentMethodManagementInterface
+     */
+    protected $paymentMethodManagement;
+
+    /**
+     * @var PaymentDetailsFactory
+     */
+    protected $paymentDetailsFactory;
+
+    /**
+     * @var \Magento\Quote\Api\CartTotalRepositoryInterface
+     */
+    protected $cartTotalsRepository;
+
+    /**
+     * Quote repository.
+     *
+     * @var \Magento\Quote\Model\QuoteRepository
+     */
+    protected $quoteRepository;
+
+    /**
+     * Logger.
+     *
+     * @var Logger
+     */
+    protected $logger;
+
+    /**
+     * Validator.
+     *
+     * @var QuoteAddressValidator
+     */
+    protected $addressValidator;
+
+    /**
+     * @var \Magento\Customer\Api\AddressRepositoryInterface
+     */
+    protected $addressRepository;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface
+     */
+    protected $scopeConfig;
+
+    /**
+     * @param \Magento\Quote\Api\PaymentMethodManagementInterface $paymentMethodManagement
+     * @param \Magento\Checkout\Model\PaymentDetailsFactory $paymentDetailsFactory
+     * @param \Magento\Quote\Api\CartTotalRepositoryInterface $cartTotalsRepository
+     * @param \Magento\Quote\Model\QuoteRepository $quoteRepository
+     * @param \Magento\Quote\Model\QuoteAddressValidator $addressValidator
+     * @param Logger $logger
+     * @param \Magento\Customer\Api\AddressRepositoryInterface $addressRepository
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     */
+    public function __construct(
+        \Magento\Quote\Api\PaymentMethodManagementInterface $paymentMethodManagement,
+        \Magento\Checkout\Model\PaymentDetailsFactory $paymentDetailsFactory,
+        \Magento\Quote\Api\CartTotalRepositoryInterface $cartTotalsRepository,
+        \Magento\Quote\Model\QuoteRepository $quoteRepository,
+        QuoteAddressValidator $addressValidator,
+        Logger $logger,
+        \Magento\Customer\Api\AddressRepositoryInterface $addressRepository,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+    ) {
+        $this->paymentMethodManagement = $paymentMethodManagement;
+        $this->paymentDetailsFactory = $paymentDetailsFactory;
+        $this->cartTotalsRepository = $cartTotalsRepository;
+        $this->quoteRepository = $quoteRepository;
+        $this->addressValidator = $addressValidator;
+        $this->logger = $logger;
+        $this->addressRepository = $addressRepository;
+        $this->scopeConfig = $scopeConfig;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     */
+    public function saveAddressInformation(
+        $cartId,
+        \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
+    ) {
+        $address = $addressInformation->getShippingAddress();
+        $carrierCode = $addressInformation->getShippingCarrierCode();
+        $methodCode = $addressInformation->getShippingMethodCode();
+
+        /** @var \Magento\Quote\Model\Quote $quote */
+        $quote = $this->quoteRepository->getActive($cartId);
+        if ($quote->isVirtual()) {
+            throw new NoSuchEntityException(
+                __('Cart contains virtual product(s) only. Shipping address is not applicable.')
+            );
+        }
+
+        if (0 == $quote->getItemsCount()) {
+            throw new InputException(__('Shipping method is not applicable for empty cart'));
+        }
+
+        $saveInAddressBook = $address->getSaveInAddressBook() ? 1 : 0;
+        $sameAsBilling = $address->getSameAsBilling() ? 1 : 0;
+        $customerAddressId = $address->getCustomerAddressId();
+        $this->addressValidator->validate($address);
+        $quote->setShippingAddress($address);
+        $address = $quote->getShippingAddress();
+
+        if ($customerAddressId) {
+            $addressData = $this->addressRepository->getById($customerAddressId);
+            $address = $quote->getShippingAddress()->importCustomerAddressData($addressData);
+        }
+        $address->setSameAsBilling($sameAsBilling);
+        $address->setSaveInAddressBook($saveInAddressBook);
+        $address->setCollectShippingRates(true);
+
+        if (!$address->getCountryId()) {
+            throw new StateException(__('Shipping address is not set'));
+        }
+
+        $address->setShippingMethod($carrierCode . '_' . $methodCode);
+
+        try {
+            $address->save();
+            $address->collectTotals();
+        } catch (\Exception $e) {
+            $this->logger->critical($e);
+            throw new InputException(__('Unable to save address. Please, check input data.'));
+        }
+
+        if (!$address->getShippingRateByCode($address->getShippingMethod())) {
+            throw new NoSuchEntityException(
+                __('Carrier with such method not found: %1, %2', $carrierCode, $methodCode)
+            );
+        }
+
+        if (!$quote->validateMinimumAmount($quote->getIsMultiShipping())) {
+            throw new InputException($this->scopeConfig->getValue(
+                'sales/minimum_order/error_message',
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+                $quote->getStoreId()
+            ));
+        }
+
+        try {
+            $address->save();
+            $quote->collectTotals();
+            $this->quoteRepository->save($quote);
+        } catch (\Exception $e) {
+            $this->logger->critical($e);
+            throw new InputException(__('Unable to save shipping information. Please, check input data.'));
+        }
+
+        /** @var \Magento\Checkout\Api\Data\PaymentDetailsInterface $paymentDetails */
+        $paymentDetails = $this->paymentDetailsFactory->create();
+        $paymentDetails->setPaymentMethods($this->paymentMethodManagement->getList($cartId));
+        $paymentDetails->setTotals($this->cartTotalsRepository->get($cartId));
+        return $paymentDetails;
+    }
+}
diff --git a/app/code/Magento/Checkout/Test/Unit/Controller/Onepage/IndexTest.php b/app/code/Magento/Checkout/Test/Unit/Controller/Onepage/IndexTest.php
index f3a3f246ec1ee9acff0150dd74735d03a4be9dc5..5159d70026cbc5c902e6adc3c3b80d21e22ea64e 100644
--- a/app/code/Magento/Checkout/Test/Unit/Controller/Onepage/IndexTest.php
+++ b/app/code/Magento/Checkout/Test/Unit/Controller/Onepage/IndexTest.php
@@ -188,6 +188,7 @@ class IndexTest extends \PHPUnit_Framework_TestCase
         $this->basicStub($this->quoteMock, 'hasItems')->willReturn(true);
         $this->basicStub($this->quoteMock, 'getHasError')->willReturn(false);
         $this->basicStub($this->quoteMock, 'validateMinimumAmount')->willReturn(true);
+        $this->basicStub($this->sessionMock, 'isLoggedIn')->willReturn(true);
 
         //Expected outcomes
         $this->sessionMock->expects($this->once())->method('regenerateId');
diff --git a/app/code/Magento/Checkout/Test/Unit/Model/Cart/ImageProviderTest.php b/app/code/Magento/Checkout/Test/Unit/Model/Cart/ImageProviderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..29b91231adb10d532df997da73c74117859b5098
--- /dev/null
+++ b/app/code/Magento/Checkout/Test/Unit/Model/Cart/ImageProviderTest.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Checkout\Test\Unit\Model\Cart;
+
+class ImageProviderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Checkout\Model\Cart\ImageProvider
+     */
+    public $model;
+
+    /**
+     * @var \PHPUnit_Framework_Mockobject_Mockobject | \Magento\Quote\Api\CartItemRepositoryInterface
+     */
+    protected $itemRepositoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_Mockobject_Mockobject | \Magento\Checkout\CustomerData\ItemPoolInterface
+     */
+    protected $itemPoolMock;
+
+    protected function setUp()
+    {
+        $this->itemRepositoryMock = $this->getMock('Magento\Quote\Api\CartItemRepositoryInterface', [], [], '', false);
+        $this->itemPoolMock = $this->getMock('Magento\Checkout\CustomerData\ItemPoolInterface', [], [], '', false);
+        $this->model = new \Magento\Checkout\Model\Cart\ImageProvider(
+            $this->itemRepositoryMock,
+            $this->itemPoolMock
+        );
+    }
+
+    public function testGetImages()
+    {
+        $cartId = 42;
+        $itemId = 74;
+        $itemData = ['product_image' => 'Magento.png', 'random' => '3.1415926535'];
+        $itemMock = $this->getMock('Magento\Quote\Model\Quote\Item', [], [], '', false);
+        $itemMock->expects($this->once())->method('getItemId')->willReturn($itemId);
+
+        $expectedResult = [$itemId => $itemData['product_image']];
+
+        $this->itemRepositoryMock->expects($this->once())->method('getList')->with($cartId)->willReturn([$itemMock]);
+        $this->itemPoolMock->expects($this->once())->method('getItemData')->with($itemMock)->willReturn($itemData);
+
+        $this->assertEquals($expectedResult, $this->model->getImages($cartId));
+    }
+}
diff --git a/app/code/Magento/Checkout/etc/di.xml b/app/code/Magento/Checkout/etc/di.xml
index 42d589f77e2dc1d49c5bcfdb09b5f65c3fd331f3..085ff442d7f75790df42f626a68a4cc886154fb4 100644
--- a/app/code/Magento/Checkout/etc/di.xml
+++ b/app/code/Magento/Checkout/etc/di.xml
@@ -16,4 +16,10 @@
             <argument name="storage" xsi:type="object">Magento\Checkout\Model\Session\Storage</argument>
         </arguments>
     </type>
+    <preference for="Magento\Checkout\Api\GuestShippingInformationManagementInterface" type="Magento\Checkout\Model\GuestShippingInformationManagement" />
+    <preference for="Magento\Checkout\Api\ShippingInformationManagementInterface" type="Magento\Checkout\Model\ShippingInformationManagement" />
+    <preference for="Magento\Checkout\Api\Data\ShippingInformationInterface" type="Magento\Checkout\Model\ShippingInformation" />
+    <preference for="Magento\Checkout\Api\Data\PaymentDetailsInterface" type="Magento\Checkout\Model\PaymentDetails" />
+    <preference for="Magento\Checkout\Api\GuestPaymentInformationManagementInterface" type="Magento\Checkout\Model\GuestPaymentInformationManagement" />
+    <preference for="Magento\Checkout\Api\PaymentInformationManagementInterface" type="Magento\Checkout\Model\PaymentInformationManagement" />
 </config>
diff --git a/app/code/Magento/Checkout/etc/frontend/di.xml b/app/code/Magento/Checkout/etc/frontend/di.xml
index 3399782763bea132a2c807f956f6323ce84016c7..20f146cc353ce63add45e00f3fc083c28cdb2768 100644
--- a/app/code/Magento/Checkout/etc/frontend/di.xml
+++ b/app/code/Magento/Checkout/etc/frontend/di.xml
@@ -43,6 +43,7 @@
         <arguments>
             <argument name="layoutProcessors" xsi:type="array">
                 <item name="addressFormAttributes" xsi:type="object">Magento\Checkout\Block\Checkout\LayoutProcessor</item>
+                <item name="totalsSortOrder" xsi:type="object">Magento\Checkout\Block\Checkout\TotalsProcessor</item>
             </argument>
         </arguments>
     </type>
diff --git a/app/code/Magento/Checkout/etc/webapi.xml b/app/code/Magento/Checkout/etc/webapi.xml
new file mode 100644
index 0000000000000000000000000000000000000000..28598faec5913a1a3d30af16084b9a2ac0d64bf0
--- /dev/null
+++ b/app/code/Magento/Checkout/etc/webapi.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:noNamespaceSchemaLocation="../../../../../app/code/Magento/Webapi/etc/webapi.xsd">
+
+    <!-- Managing shipping guest information -->
+    <route url="/V1/carts/:cartId/shipping-information" method="POST">
+        <service class="Magento\Checkout\Api\GuestShippingInformationManagementInterface" method="saveAddressInformation"/>
+        <resources>
+            <resource ref="anonymous" />
+        </resources>
+    </route>
+
+    <!-- Managing My shipping information -->
+    <route url="/V1/carts/mine/shipping-information" method="POST">
+        <service class="Magento\Checkout\Api\ShippingInformationManagementInterface" method="saveAddressInformation"/>
+        <resources>
+            <resource ref="self" />
+        </resources>
+        <data>
+            <parameter name="cartId" force="true">%cart_id%</parameter>
+        </data>
+    </route>
+    <!-- Guest place order with payment information saving -->
+    <route url="/V1/guest-carts/:cartId/payment-information" method="POST">
+        <service class="Magento\Checkout\Api\GuestPaymentInformationManagementInterface" method="savePaymentInformationAndPlaceOrder"/>
+        <resources>
+            <resource ref="anonymous" />
+        </resources>
+    </route>
+    <!-- My place order with payment information saving -->
+    <route url="/V1/carts/mine/payment-information" method="POST">
+        <service class="Magento\Checkout\Api\PaymentInformationManagementInterface" method="savePaymentInformationAndPlaceOrder"/>
+        <resources>
+            <resource ref="self" />
+        </resources>
+        <data>
+            <parameter name="cartId" force="true">%cart_id%</parameter>
+        </data>
+    </route>
+
+    <!-- Managing payment guest information -->
+    <route url="/V1/guest-carts/:cartId/set-payment-information" method="POST">
+        <service class="Magento\Checkout\Api\GuestPaymentInformationManagementInterface" method="savePaymentInformation"/>
+        <resources>
+            <resource ref="anonymous" />
+        </resources>
+    </route>
+    <!-- Managing My shipping information -->
+    <route url="/V1/carts/mine/set-payment-information" method="POST">
+        <service class="Magento\Checkout\Api\PaymentInformationManagementInterface" method="savePaymentInformation"/>
+        <resources>
+            <resource ref="self" />
+        </resources>
+        <data>
+            <parameter name="cartId" force="true">%cart_id%</parameter>
+        </data>
+    </route>
+</routes>
diff --git a/app/code/Magento/Checkout/view/frontend/layout/checkout_onepage_index.xml b/app/code/Magento/Checkout/view/frontend/layout/checkout_onepage_index.xml
index 5db66984f7812e8bd62978befb585a2eaa8434f9..a40e65477410eef2cfebf8e9c39203ed88070605 100644
--- a/app/code/Magento/Checkout/view/frontend/layout/checkout_onepage_index.xml
+++ b/app/code/Magento/Checkout/view/frontend/layout/checkout_onepage_index.xml
@@ -23,155 +23,233 @@
                         </item>
                         <item name="components" xsi:type="array">
                             <item name="checkout" xsi:type="array">
-                                <item name="component" xsi:type="string">Magento_Checkout/js/view/onepage</item>
+                                <item name="component" xsi:type="string">uiComponent</item>
+                                <item name="config" xsi:type="array">
+                                    <item name="template" xsi:type="string">Magento_Checkout/onepage</item>
+                                </item>
                                 <item name="children" xsi:type="array">
-                                    <item name="progress" xsi:type="array">
-                                        <item name="component" xsi:type="string">Magento_Checkout/js/view/progress</item>
-                                        <item name="displayArea" xsi:type="string">progress</item>
+                                    <item name="errors" xsi:type="array">
+                                        <item name="sortOrder" xsi:type="string">0</item>
+                                        <item name="component" xsi:type="string">Magento_Ui/js/view/messages</item>
+                                        <item name="displayArea" xsi:type="string">messages</item>
+                                    </item>
+                                    <item name="authentication" xsi:type="array">
+                                        <item name="sortOrder" xsi:type="string">1</item>
+                                        <item name="component" xsi:type="string">Magento_Checkout/js/view/authentication</item>
+                                        <item name="displayArea" xsi:type="string">authentication</item>
                                         <item name="children" xsi:type="array">
-                                            <item name="shipping" xsi:type="array">
-                                                <item name="component" xsi:type="string">Magento_Tax/js/view/checkout/shipping_method/price</item>
-                                                <item name="displayArea" xsi:type="string">shipping</item>
-                                            </item>
+                                        <!--Additional authentication fields-->
                                         </item>
                                     </item>
-                                    <item name="errors" xsi:type="array">
+                                    <item name="progressBar" xsi:type="array">
                                         <item name="sortOrder" xsi:type="string">0</item>
-                                        <item name="component" xsi:type="string">Magento_Ui/js/view/errors</item>
-                                        <item name="displayArea" xsi:type="string">errors</item>
+                                        <item name="component" xsi:type="string">Magento_Checkout/js/view/progress-bar</item>
+                                        <item name="displayArea" xsi:type="string">progressBar</item>
                                     </item>
                                     <item name="steps" xsi:type="array">
                                         <item name="component" xsi:type="string">uiComponent</item>
                                         <item name="displayArea" xsi:type="string">steps</item>
                                         <item name="children" xsi:type="array">
-                                            <item name="authentication" xsi:type="array">
-                                                <item name="component" xsi:type="string">Magento_Checkout/js/view/authentication</item>
+                                            <item name="shipping-step" xsi:type="array">
+                                                <item name="component" xsi:type="string">uiComponent</item>
                                                 <item name="sortOrder" xsi:type="string">1</item>
                                                 <item name="children" xsi:type="array">
-                                                    <item name="before" xsi:type="array">
+                                                    <item name="step-config" xsi:type="array">
                                                         <item name="component" xsi:type="string">uiComponent</item>
-                                                        <item name="displayArea" xsi:type="string">before</item>
                                                         <item name="children" xsi:type="array">
-                                                            <!-- merge additional data before authentication here -->
+                                                            <item name="shipping-rates-validation" xsi:type="array">
+                                                                <item name="children" xsi:type="array">
+                                                                    <!--Step configuration components-->
+                                                                </item>
+                                                            </item>
                                                         </item>
                                                     </item>
-                                                </item>
-                                            </item>
-                                            <item name="billingAddress" xsi:type="array">
-                                                <item name="component" xsi:type="string">Magento_Checkout/js/view/billing-address</item>
-                                                <item name="provider" xsi:type="string">checkoutProvider</item>
-                                                <item name="sortOrder" xsi:type="string">2</item>
-                                                <item name="children" xsi:type="array">
-                                                    <item name="billing-address-fieldset" xsi:type="array">
-                                                        <item name="component" xsi:type="string">uiComponent</item>
-                                                        <item name="displayArea" xsi:type="string">additional-fieldsets</item>
-                                                        <item name="children" xsi:type="array">
-                                                            <!-- The following items override configuration of corresponding address attributes -->
-                                                            <item name="region" xsi:type="array">
-                                                                <!-- Make region attribute invisible on frontend. Corresponding input element is created by region_id field -->
-                                                                <item name="visible" xsi:type="boolean">false</item>
-                                                            </item>
-                                                            <item name="region_id" xsi:type="array">
-                                                                <item name="component" xsi:type="string">Magento_Ui/js/form/element/region</item>
-                                                                <item name="config" xsi:type="array">
-                                                                    <item name="template" xsi:type="string">ui/form/field</item>
-                                                                    <item name="elementTmpl" xsi:type="string">ui/form/element/select</item>
-                                                                    <item name="customEntry" xsi:type="string">billingAddress.region</item>
-                                                                </item>
-                                                                <item name="validation" xsi:type="array">
-                                                                    <item name="validate-select" xsi:type="string">true</item>
-                                                                </item>
-                                                                <!-- Value of region_id field is filtered by the value of county_id attribute -->
-                                                                <item name="filterBy" xsi:type="array">
-                                                                    <item name="target" xsi:type="string">${ $.provider }:${ $.parentScope }.country_id</item>
-                                                                    <item name="field" xsi:type="string">country_id</item>
+                                                    <item name="shippingAddress" xsi:type="array">
+                                                        <item name="config" xsi:type="array">
+                                                            <item name="deps" xsi:type="string">checkout.steps.shipping-step.step-config</item>
+                                                            <item name="popUpForm" xsi:type="array">
+                                                                <item name="element" xsi:type="string">#opc-new-shipping-address</item>
+                                                                <item name="options" xsi:type="array">
+                                                                    <item name="type" xsi:type="string">popup</item>
+                                                                    <item name="responsive" xsi:type="boolean">true</item>
+                                                                    <item name="innerScroll" xsi:type="boolean">true</item>
+                                                                    <item name="title" xsi:type="string">Shipping Address</item>
+                                                                    <item name="trigger" xsi:type="string">opc-new-shipping-address</item>
+                                                                    <item name="buttons" xsi:type="array">
+                                                                        <item name="save" xsi:type="array">
+                                                                            <item name="text" xsi:type="string">Save Address</item>
+                                                                            <item name="class" xsi:type="string">action primary action-save-address</item>
+                                                                        </item>
+                                                                        <item name="cancel" xsi:type="array">
+                                                                            <item name="text" xsi:type="string">Cancel</item>
+                                                                            <item name="class" xsi:type="string">action secondary action-hide-popup</item>
+                                                                        </item>
+                                                                    </item>
                                                                 </item>
                                                             </item>
-                                                            <item name="postcode" xsi:type="array">
-                                                                <!-- post-code field has custom UI component -->
-                                                                <item name="component" xsi:type="string">Magento_Ui/js/form/element/post-code</item>
-                                                                <item name="validation" xsi:type="array">
-                                                                    <item name="required-entry" xsi:type="string">true</item>
+                                                        </item>
+                                                        <item name="component" xsi:type="string">Magento_Checkout/js/view/shipping</item>
+                                                        <item name="provider" xsi:type="string">checkoutProvider</item>
+                                                        <item name="sortOrder" xsi:type="string">1</item>
+                                                        <item name="children" xsi:type="array">
+                                                            <item name="customer-email" xsi:type="array">
+                                                                <item name="component" xsi:type="string">Magento_Customer/js/view/customer-email</item>
+                                                                <item name="displayArea" xsi:type="string">customer-email</item>
+                                                                <item name="tooltip" xsi:type="array">
+                                                                    <item name="description" xsi:type="string">We'll send your order confirmation here.</item>
+                                                                </item>
+                                                                <item name="children" xsi:type="array">
+                                                                    <item name="before-login-form" xsi:type="array">
+                                                                        <item name="component" xsi:type="string">uiComponent</item>
+                                                                        <item name="displayArea" xsi:type="string">before-login-form</item>
+                                                                        <item name="children" xsi:type="array">
+                                                                            <!-- before login form fields -->
+                                                                        </item>
+                                                                    </item>
+                                                                    <item name="additional-login-form-fields" xsi:type="array">
+                                                                        <item name="component" xsi:type="string">uiComponent</item>
+                                                                        <item name="displayArea" xsi:type="string">additional-login-form-fields</item>
+                                                                        <item name="children" xsi:type="array">
+                                                                            <!-- additional login form fields -->
+                                                                        </item>
+                                                                    </item>
                                                                 </item>
                                                             </item>
-                                                            <item name="company" xsi:type="array">
-                                                                <item name="validation" xsi:type="array">
-                                                                    <item name="min_text_length" xsi:type="number">0</item>
+                                                            <item name="before-form" xsi:type="array">
+                                                                <item name="component" xsi:type="string">uiComponent</item>
+                                                                <item name="displayArea" xsi:type="string">before-form</item>
+                                                                <item name="children" xsi:type="array">
+                                                                    <!-- before form fields -->
                                                                 </item>
                                                             </item>
-                                                            <item name="fax" xsi:type="array">
-                                                                <item name="validation" xsi:type="array">
-                                                                    <item name="min_text_length" xsi:type="number">0</item>
+                                                            <item name="before-fields" xsi:type="array">
+                                                                <item name="component" xsi:type="string">uiComponent</item>
+                                                                <item name="displayArea" xsi:type="string">before-fields</item>
+                                                                <item name="children" xsi:type="array">
+                                                                    <!-- before fields -->
                                                                 </item>
                                                             </item>
-                                                            <item name="country_id" xsi:type="array">
-                                                                <item name="sortOrder" xsi:type="string">115</item>
+                                                            <item name="address-list" xsi:type="array">
+                                                                <item name="component" xsi:type="string">Magento_Checkout/js/view/shipping-address/list</item>
+                                                                <item name="displayArea" xsi:type="string">address-list</item>
                                                             </item>
-                                                            <!-- The following items describe fields that are not directly related to address but must be shown in address form -->
-                                                            <item name="email" xsi:type="array">
-                                                                <item name="component" xsi:type="string">Magento_Ui/js/form/element/abstract</item>
-                                                                <item name="config" xsi:type="array">
-                                                                    <item name="template" xsi:type="string">ui/form/field</item>
-                                                                    <item name="elementTmpl" xsi:type="string">ui/form/element/email</item>
-                                                                    <item name="customScope" xsi:type="string">customerDetails</item>
+                                                            <item name="address-list-additional-addresses" xsi:type="array">
+                                                                <item name="component" xsi:type="string">uiComponent</item>
+                                                                <item name="displayArea" xsi:type="string">address-list-additional-addresses</item>
+                                                                <item name="children" xsi:type="array">
+                                                                    <!-- address-list-additional-addresses -->
                                                                 </item>
-                                                                <item name="label" xsi:type="string">Email</item>
-                                                                <item name="dataScope" xsi:type="string">customerDetails.email</item>
-                                                                <item name="provider" xsi:type="string">checkoutProvider</item>
-                                                                <item name="sortOrder" xsi:type="string">45</item>
-                                                                <item name="validation" xsi:type="array">
-                                                                    <item name="required-entry" xsi:type="boolean">true</item>
-                                                                    <item name="validate-email" xsi:type="boolean">true</item>
+                                                              </item>
+                                                            <item name="before-shipping-method-form" xsi:type="array">
+                                                                <item name="component" xsi:type="string">uiComponent</item>
+                                                                <item name="displayArea" xsi:type="string">before-shipping-method-form</item>
+                                                                <item name="children" xsi:type="array">
+                                                                    <!-- address-list-additional-addresses -->
                                                                 </item>
                                                             </item>
-                                                            <item name="save_in_address_book" xsi:type="array">
-                                                                <item name="component" xsi:type="string">Magento_Ui/js/form/element/abstract</item>
-                                                                <item name="config" xsi:type="array">
-                                                                    <item name="template" xsi:type="string">ui/form/field</item>
-                                                                    <item name="elementTmpl" xsi:type="string">ui/form/element/checkbox</item>
+                                                            <item name="shipping-address-fieldset" xsi:type="array">
+                                                                <item name="component" xsi:type="string">uiComponent</item>
+                                                                <item name="displayArea" xsi:type="string">additional-fieldsets</item>
+                                                                <item name="children" xsi:type="array">
+                                                                     <!-- The following items override configuration of corresponding address attributes -->
+                                                                    <item name="region" xsi:type="array">
+                                                                        <!-- Make region attribute invisible on frontend. Corresponding input element is created by region_id field -->
+                                                                        <item name="visible" xsi:type="boolean">false</item>
+                                                                    </item>
+                                                                    <item name="region_id" xsi:type="array">
+                                                                        <item name="component" xsi:type="string">Magento_Ui/js/form/element/region</item>
+                                                                        <item name="config" xsi:type="array">
+                                                                            <item name="template" xsi:type="string">ui/form/field</item>
+                                                                            <item name="elementTmpl" xsi:type="string">ui/form/element/select</item>
+                                                                            <item name="customEntry" xsi:type="string">shippingAddress.region</item>
+                                                                        </item>
+                                                                        <item name="validation" xsi:type="array">
+                                                                            <item name="validate-select" xsi:type="string">true</item>
+                                                                        </item>
+                                                                        <!-- Value of region_id field is filtered by the value of county_id attribute -->
+                                                                        <item name="filterBy" xsi:type="array">
+                                                                            <item name="target" xsi:type="string"><![CDATA[${ $.provider }:${ $.parentScope }.country_id]]></item>
+                                                                            <item name="field" xsi:type="string">country_id</item>
+                                                                        </item>
+                                                                    </item>
+                                                                    <item name="postcode" xsi:type="array">
+                                                                        <!-- post-code field has custom UI component -->
+                                                                        <item name="component" xsi:type="string">Magento_Ui/js/form/element/post-code</item>
+                                                                        <item name="validation" xsi:type="array">
+                                                                            <item name="required-entry" xsi:type="string">true</item>
+                                                                        </item>
+                                                                    </item>
+                                                                    <item name="company" xsi:type="array">
+                                                                        <item name="validation" xsi:type="array">
+                                                                            <item name="min_text_length" xsi:type="number">0</item>
+                                                                        </item>
+                                                                    </item>
+                                                                    <item name="fax" xsi:type="array">
+                                                                        <item name="validation" xsi:type="array">
+                                                                            <item name="min_text_length" xsi:type="number">0</item>
+                                                                        </item>
+                                                                    </item>
+                                                                    <item name="country_id" xsi:type="array">
+                                                                        <item name="sortOrder" xsi:type="string">115</item>
+                                                                    </item>
+                                                                    <item name="telephone" xsi:type="array">
+                                                                        <item name="config" xsi:type="array">
+                                                                            <item name="tooltip" xsi:type="array">
+                                                                                <item name="description" xsi:type="string">For delivery Questions</item>
+                                                                            </item>
+                                                                        </item>
+                                                                    </item>
                                                                 </item>
-                                                                <item name="description" xsi:type="string">Save in address book</item>
-                                                                <item name="provider" xsi:type="string">checkoutProvider</item>
-                                                                <item name="dataScope" xsi:type="string">billingAddress.save_in_address_book</item>
                                                             </item>
                                                         </item>
                                                     </item>
-                                                    <item name="billing-address-choice" xsi:type="array">
-                                                        <item name="component" xsi:type="string">uiComponent</item>
-                                                        <item name="displayArea" xsi:type="string">additional-field-choice</item>
-                                                        <item name="children" xsi:type="array">
-                                                            <!-- this region for different choice -->
-                                                        </item>
-                                                    </item>
                                                 </item>
                                             </item>
-                                            <item name="shippingAddress" xsi:type="array">
-                                                <item name="component" xsi:type="string">Magento_Checkout/js/view/shipping-address</item>
-                                                <item name="provider" xsi:type="string">checkoutProvider</item>
-                                                <item name="sortOrder" xsi:type="string">3</item>
+                                            <item name="billing-step" xsi:type="array">
+                                                <item name="component" xsi:type="string">uiComponent</item>
+                                                <item name="sortOrder" xsi:type="string">2</item>
                                                 <item name="children" xsi:type="array">
-                                                    <item name="before-fields" xsi:type="array">
-                                                        <item name="component" xsi:type="string">uiComponent</item>
-                                                        <item name="displayArea" xsi:type="string">before-fields</item>
-                                                        <item name="children" xsi:type="array">
-                                                            <!-- before fields -->
+                                                    <item name="payment" xsi:type="array">
+                                                        <item name="component" xsi:type="string">Magento_Checkout/js/view/payment</item>
+                                                        <item name="config" xsi:type="array">
+                                                            <item name="title" xsi:type="string">Payment</item>
                                                         </item>
-                                                    </item>
-                                                    <item name="shipping-address-fieldset" xsi:type="array">
-                                                        <item name="component" xsi:type="string">uiComponent</item>
-                                                        <item name="displayArea" xsi:type="string">additional-fieldsets</item>
                                                         <item name="children" xsi:type="array">
-                                                            <!-- The following items override configuration of corresponding address attributes -->
-                                                            <item name="region" xsi:type="array">
-                                                                <!-- Make region attribute invisible on frontend. Corresponding input element is created by region_id field -->
-                                                                <item name="visible" xsi:type="boolean">false</item>
+                                                            <item name="renders" xsi:type="array">
+                                                                <item name="component" xsi:type="string">uiComponent</item>
+                                                                <item name="children" xsi:type="array">
+                                                                    <!-- merge payment method renders here -->
+                                                                </item>
                                                             </item>
-                                                            <item name="region_id" xsi:type="array">
-                                                                <item name="component" xsi:type="string">Magento_Ui/js/form/element/region</item>
-                                                                <item name="config" xsi:type="array">
-                                                                    <item name="template" xsi:type="string">ui/form/field</item>
-                                                                    <item name="elementTmpl" xsi:type="string">ui/form/element/select</item>
-                                                                    <item name="customEntry" xsi:type="string">shippingAddress.region</item>
+                                                            <item name="customer-email" xsi:type="array">
+                                                                <item name="component" xsi:type="string">Magento_Customer/js/view/customer-email</item>
+                                                                <item name="displayArea" xsi:type="string">customer-email</item>
+                                                                <item name="tooltip" xsi:type="array">
+                                                                    <item name="description" xsi:type="string">(You can create an account to track your order after checkout)</item>
+                                                                </item>
+                                                                <item name="children" xsi:type="array">
+                                                                    <item name="before-login-form" xsi:type="array">
+                                                                        <item name="component" xsi:type="string">uiComponent</item>
+                                                                        <item name="displayArea" xsi:type="string">before-login-form</item>
+                                                                        <item name="children" xsi:type="array">
+                                                                            <!-- before login form fields -->
+                                                                        </item>
+                                                                    </item>
+                                                                    <item name="additional-login-form-fields" xsi:type="array">
+                                                                        <item name="component" xsi:type="string">uiComponent</item>
+                                                                        <item name="displayArea" xsi:type="string">additional-login-form-fields</item>
+                                                                        <item name="children" xsi:type="array">
+                                                                            <!-- additional login form fields -->
+                                                                        </item>
+                                                                    </item>
+                                                                </item>
+                                                            </item>
+                                                            <!-- TODO: add billing address form -->
+                                                            <item name="beforeMethods" xsi:type="array">
+                                                                <item name="component" xsi:type="string">uiComponent</item>
+                                                                <item name="displayArea" xsi:type="string">beforeMethods</item>
+                                                                <item name="children" xsi:type="array">
+                                                                    <!-- merge additional data before payment methods here -->
                                                                 </item>
                                                                 <item name="validation" xsi:type="array">
                                                                     <item name="validate-select" xsi:type="string">true</item>
@@ -182,135 +260,107 @@
                                                                     <item name="field" xsi:type="string">country_id</item>
                                                                 </item>
                                                             </item>
-                                                            <item name="postcode" xsi:type="array">
-                                                                <!-- post-code field has custom UI component -->
-                                                                <item name="component" xsi:type="string">Magento_Ui/js/form/element/post-code</item>
-                                                                <item name="validation" xsi:type="array">
-                                                                    <item name="required-entry" xsi:type="string">true</item>
-                                                                </item>
-                                                            </item>
-                                                            <item name="company" xsi:type="array">
-                                                                <item name="validation" xsi:type="array">
-                                                                    <item name="min_text_length" xsi:type="number">0</item>
+                                                            <item name="payments-list" xsi:type="array">
+                                                                <item name="component" xsi:type="string">Magento_Checkout/js/view/payment/list</item>
+                                                                <item name="displayArea" xsi:type="string">payment-methods-list</item>
+                                                                <item name="config" xsi:type="array">
+                                                                    <item name="deps" xsi:type="string">checkout.steps.billing-step.payment.renders</item>
                                                                 </item>
                                                             </item>
-                                                            <item name="fax" xsi:type="array">
-                                                                <item name="validation" xsi:type="array">
-                                                                    <item name="min_text_length" xsi:type="number">0</item>
+                                                            <!-- merge your payment methods here -->
+                                                            <item name="afterMethods" xsi:type="array">
+                                                                <item name="component" xsi:type="string">uiComponent</item>
+                                                                <item name="displayArea" xsi:type="string">afterMethods</item>
+                                                                <item name="children" xsi:type="array">
+                                                                    <!-- merge additional data after payment methods here -->
                                                                 </item>
                                                             </item>
-                                                            <item name="country_id" xsi:type="array">
-                                                                <item name="sortOrder" xsi:type="string">115</item>
-                                                            </item>
-                                                            <item name="save_in_address_book" xsi:type="array">
-                                                                <item name="component" xsi:type="string">Magento_Ui/js/form/element/abstract</item>
-                                                                <item name="config" xsi:type="array">
-                                                                    <item name="template" xsi:type="string">ui/form/field</item>
-                                                                    <item name="elementTmpl" xsi:type="string">ui/form/element/checkbox</item>
-                                                                </item>
-                                                                <item name="description" xsi:type="string">Save in address book</item>
-                                                                <item name="provider" xsi:type="string">checkoutProvider</item>
-                                                                <item name="dataScope" xsi:type="string">shippingAddress.save_in_address_book</item>
-                                                            </item>
                                                         </item>
                                                     </item>
                                                 </item>
                                             </item>
-                                            <item name="shipping" xsi:type="array">
-                                                <item name="component" xsi:type="string">Magento_Checkout/js/view/shipping-method</item>
-                                                <item name="sortOrder" xsi:type="string">4</item>
-                                                <item name="additional" xsi:type="array">
-                                                    <!-- merge your shipping methods here -->
+                                        </item>
+                                    </item>
+                                    <item name="summary" xsi:type="array">
+                                        <item name="component" xsi:type="string">Magento_Checkout/js/view/summary</item>
+                                        <item name="displayArea" xsi:type="string">summary</item>
+                                        <item name="config" xsi:type="array">
+                                            <item name="template" xsi:type="string">Magento_Checkout/summary</item>
+                                        </item>
+                                        <item name="children" xsi:type="array">
+                                            <item name="totals" xsi:type="array">
+                                                <item name="component" xsi:type="string">uiComponent</item>
+                                                <item name="displayArea" xsi:type="string">totals</item>
+                                                <item name="config" xsi:type="array">
+                                                    <item name="template" xsi:type="string">Magento_Checkout/summary/totals</item>
                                                 </item>
                                                 <item name="children" xsi:type="array">
-                                                    <item name="afterSelect" xsi:type="array">
-                                                        <item name="component" xsi:type="string">uiComponent</item>
-                                                        <item name="displayArea" xsi:type="string">afterSelect</item>
-                                                        <item name="children" xsi:type="array">
-                                                            <!-- merge additional data after shipping methods here -->
+                                                    <!-- sort order for this totals is configured on admin panel-->
+                                                    <!-- Stores->Configuration->SALES->Sales->General->Checkout Totals Sort Order -->
+                                                    <item name="subtotal" xsi:type="array">
+                                                        <item name="component"  xsi:type="string">Magento_Checkout/js/view/summary/subtotal</item>
+                                                        <item name="config" xsi:type="array">
+                                                            <item name="title" xsi:type="string">Cart Subtotal</item>
                                                         </item>
                                                     </item>
-                                                </item>
-                                            </item>
-                                            <item name="payment" xsi:type="array">
-                                                <item name="component" xsi:type="string">Magento_Checkout/js/view/payment</item>
-                                                <item name="sortOrder" xsi:type="string">5</item>
-                                                <item name="children" xsi:type="array">
-                                                    <item name="beforeMethods" xsi:type="array">
-                                                        <item name="component" xsi:type="string">uiComponent</item>
-                                                        <item name="displayArea" xsi:type="string">beforeMethods</item>
-                                                        <item name="children" xsi:type="array">
-                                                            <!-- merge additional data before payment methods here -->
+                                                    <item name="shipping" xsi:type="array">
+                                                        <item name="component"  xsi:type="string">Magento_Checkout/js/view/summary/shipping</item>
+                                                        <item name="config" xsi:type="array">
+                                                            <item name="title" xsi:type="string">Shipping</item>
+                                                            <item name="notCalculatedMessage" xsi:type="string">Not yet calculated</item>
                                                         </item>
                                                     </item>
-                                                    <!-- merge your payment methods here -->
-                                                    <item name="afterMethods" xsi:type="array">
-                                                        <item name="component" xsi:type="string">uiComponent</item>
-                                                        <item name="displayArea" xsi:type="string">afterMethods</item>
-                                                        <item name="children" xsi:type="array">
-                                                            <!-- merge additional data after payment methods here -->
+                                                    <item name="grand-total" xsi:type="array">
+                                                        <item name="component"  xsi:type="string">Magento_Checkout/js/view/summary/grand-total</item>
+                                                        <item name="config" xsi:type="array">
+                                                            <item name="title" xsi:type="string">Order Total</item>
                                                         </item>
                                                     </item>
                                                 </item>
                                             </item>
-                                            <item name="review" xsi:type="array">
-                                                <item name="component" xsi:type="string">Magento_Checkout/js/view/review</item>
-                                                <item name="sortOrder" xsi:type="string">6</item>
+                                            <item name="itemsBefore" xsi:type="array">
+                                                <item name="component" xsi:type="string">uiComponent</item>
                                                 <item name="children" xsi:type="array">
-                                                    <item name="columns" xsi:type="array">
-                                                        <item name="component" xsi:type="string">Magento_Checkout/js/view/columns</item>
-                                                        <item name="children" xsi:type="array">
-                                                            <item name="name" xsi:type="array"><item name="component" xsi:type="string">Magento_Checkout/js/view/review/item/columns/name</item></item>
-                                                            <item name="price" xsi:type="array"><item name="component" xsi:type="string">Magento_Checkout/js/view/review/item/columns/price</item></item>
-                                                            <item name="qty" xsi:type="array"><item name="component" xsi:type="string">Magento_Checkout/js/view/review/item/columns/qty</item></item>
-                                                            <item name="subtotal" xsi:type="array"><item name="component" xsi:type="string">Magento_Checkout/js/view/review/item/columns/subtotal</item></item>
-                                                        </item>
-                                                    </item>
-                                                    <item name="itemsBefore" xsi:type="array">
-                                                        <item name="component" xsi:type="string">Magento_Checkout/js/view/itemsBefore</item>
-                                                        <item name="children" xsi:type="array">
-                                                            <!-- merge your components here -->
-                                                        </item>
-                                                    </item>
-                                                    <item name="itemsAfter" xsi:type="array">
-                                                        <item name="component" xsi:type="string">Magento_Checkout/js/view/itemsAfter</item>
-                                                        <item name="children" xsi:type="array">
-                                                            <!-- merge your components here -->
-                                                        </item>
-                                                    </item>
-                                                    <item name="beforePlaceOrder" xsi:type="array">
-                                                        <item name="component" xsi:type="string">Magento_Checkout/js/view/beforePlaceOrder</item>
-                                                        <item name="children" xsi:type="array">
-                                                            <!-- merge your components here -->
-                                                        </item>
-                                                    </item>
-                                                    <item name="totals" xsi:type="array">
-                                                        <item name="component" xsi:type="string">Magento_Checkout/js/view/totals</item>
+                                                    <!-- merge your components here -->
+                                                </item>
+                                            </item>
+                                            <item name="cart_items" xsi:type="array">
+                                                <item name="component" xsi:type="string">Magento_Checkout/js/view/summary/cart-items</item>
+                                                <item name="children" xsi:type="array">
+                                                    <item name="details" xsi:type="array">
+                                                        <item name="component" xsi:type="string">Magento_Checkout/js/view/summary/item/details</item>
                                                         <item name="children" xsi:type="array">
-                                                            <item name="subtotal" xsi:type="array">
-                                                                <item name="component"  xsi:type="string">Magento_Checkout/js/view/subtotal</item>
-                                                            </item>
-                                                            <item name="discount" xsi:type="array">
-                                                                <item name="component"  xsi:type="string">Magento_Checkout/js/view/discount</item>
+                                                            <item name="thumbnail" xsi:type="array">
+                                                                <item name="component" xsi:type="string">Magento_Checkout/js/view/summary/item/details/thumbnail</item>
+                                                                <item name="displayArea" xsi:type="string">before_details</item>
                                                             </item>
-                                                        </item>
-                                                    </item>
-                                                    <item name="actions" xsi:type="array">
-                                                        <item name="component" xsi:type="string">Magento_Checkout/js/view/review/actions</item>
-                                                        <item name="children" xsi:type="array">
-                                                            <item name="@default" xsi:type="array">
-                                                                <item name="component" xsi:type="string">Magento_Checkout/js/view/review/actions/default</item>
-                                                                <item name="config" xsi:type="array">
-                                                                    <item name="isDefault" xsi:type="boolean">true</item>
-                                                                </item>
+                                                            <item name="subtotal" xsi:type="array">
+                                                                <item name="component" xsi:type="string">Magento_Checkout/js/view/summary/item/details/subtotal</item>
+                                                                <item name="displayArea" xsi:type="string">after_details</item>
                                                             </item>
-                                                            <!-- merge your components here -->
                                                         </item>
                                                     </item>
+
+                                                </item>
+                                            </item>
+                                            <item name="itemsAfter" xsi:type="array">
+                                                <item name="component" xsi:type="string">uiComponent</item>
+                                                <item name="children" xsi:type="array">
+                                                    <!-- merge your components here -->
                                                 </item>
                                             </item>
                                         </item>
                                     </item>
+                                    <item name="shipping-information" xsi:type="array">
+                                        <item name="component" xsi:type="string">Magento_Checkout/js/view/shipping-information</item>
+                                        <item name="displayArea" xsi:type="string">shipping-information</item>
+                                        <item name="children" xsi:type="array">
+                                            <item name="ship-to" xsi:type="array">
+                                                <item name="component" xsi:type="string">Magento_Checkout/js/view/shipping-information/list</item>
+                                                <item name="displayArea" xsi:type="string">ship-to</item>
+                                            </item>
+                                        </item>
+                                    </item>
                                 </item>
                             </item>
                             <item name="checkoutProvider" xsi:type="array">
@@ -321,5 +371,6 @@
                 </arguments>
             </block>
         </referenceContainer>
+        <remove name="page.messages" />
     </body>
 </page>
diff --git a/app/code/Magento/Checkout/view/frontend/layout/default.xml b/app/code/Magento/Checkout/view/frontend/layout/default.xml
index 2ac27890ca18a2a79b604c647abe24eb95f14625..da1007040f6a19ab02d2f794b2df8ac4e93df719 100644
--- a/app/code/Magento/Checkout/view/frontend/layout/default.xml
+++ b/app/code/Magento/Checkout/view/frontend/layout/default.xml
@@ -51,6 +51,19 @@
                                             <item name="displayArea" xsi:type="string">promotion</item>
                                         </item>
                                     </item>
+                                    <item name="sign-in-popup" xsi:type="array">
+                                        <item name="component" xsi:type="string">Magento_Checkout/js/view/cart/authentication</item>
+                                        <item name="config" xsi:type="array">
+                                            <item name="displayArea" xsi:type="string">sign-in-popup</item>
+                                            <item name="template" xsi:type="string">Magento_Checkout/cart/authentication</item>
+                                        </item>
+                                        <item name="children" xsi:type="array">
+                                            <item name="messages" xsi:type="array">
+                                                <item name="component" xsi:type="string">Magento_Ui/js/view/messages</item>
+                                                <item name="displayArea" xsi:type="string">messages</item>
+                                            </item>
+                                        </item>
+                                    </item>
                                 </item>
                             </item>
                         </item>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml
index d515d34169278ca83c7d361c5e43fcd51f9840ae..6d08bcb4bbf500ef2f823c46e8074640099f07d6 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml
@@ -42,18 +42,15 @@
         </div>
     <?php endif ?>
     <script>
-        window.checkout = {
-            shoppingCartUrl: '<?=$block->getShoppingCartUrl()?>',
-            checkoutUrl: '<?=$block->getCheckoutUrl()?>',
-            updateItemQtyUrl: '<?=$block->getUpdateItemQtyUrl()?>',
-            removeItemUrl: '<?=$block->getRemoveItemUrl()?>',
-            imageTemplate: '<?= $block->getImageHtmlTemplate()?>'
-        };
+        window.checkout = <?php echo \Zend_Json::encode($block->getConfig()); ?>;
     </script>
     <script type="text/x-magento-init">
     {
         "[data-block='minicart']": {
             "Magento_Ui/js/core/app": <?php echo $block->getJsLayout();?>
+        },
+        "*": {
+            "Magento_Ui/js/block-loader": "<?php echo $block->getViewFileUrl('images/loader-1.gif'); ?>"
         }
     }
     </script>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/onepage.phtml b/app/code/Magento/Checkout/view/frontend/templates/onepage.phtml
index 7e8fe0c43edb0dd18ac6ac63ceae182267a1de08..1f05ef68ff3a41b882e7342dc6c271ea2a9eb670 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/onepage.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/onepage.phtml
@@ -4,7 +4,7 @@
  * See COPYING.txt for license details.
  */
 ?>
-    <div id="checkout" data-bind="scope:'checkout'">
+    <div id="checkout" data-bind="scope:'checkout'" class="checkout-container">
         <!-- ko template: getTemplate() --><!-- /ko -->
         <script type="text/x-magento-init">
             {
@@ -20,8 +20,13 @@
             window.customerData = window.checkoutConfig.customerData;
         </script>
         <script>
-            require(['mage/url', 'Magento_Checkout/js/model/step-loader'], function(url, loader) {
+            require([
+                'mage/url',
+                'Magento_Checkout/js/model/step-loader',
+                'Magento_Ui/js/block-loader'
+            ], function(url, loader, blockLoader) {
                 loader.registerLoader();
+                blockLoader("<?php echo $block->getViewFileUrl('images/loader-1.gif'); ?>");
                 return url.setBaseUrl('<?php echo $block->getBaseUrl();?>');
             })
         </script>
diff --git a/app/code/Magento/Checkout/view/frontend/templates/onepage/link.phtml b/app/code/Magento/Checkout/view/frontend/templates/onepage/link.phtml
index 25d144d746d4a42020cce13217abb4b831e90d81..72b8a5bf5023ad578385467538fdb88299bce81e 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/onepage/link.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/onepage/link.phtml
@@ -5,18 +5,14 @@
  */
 
 // @codingStandardsIgnoreFile
-
-/**
- * @deprecated
- * @removeCandidate
- */
 ?>
 <?php if ($block->isPossibleOnepageCheckout()):?>
     <button type="button"
+            data-role="proceed-to-checkout"
             title="<?php echo __('Proceed to Checkout') ?>"
+            data-mage-init='{"Magento_Checkout/js/proceed-to-checkout":{}}'
             class="action primary checkout<?php echo($block->isDisabled()) ? ' disabled' : ''; ?>"
-            <?php if ($block->isDisabled()):?>disabled="disabled"<?php endif; ?>
-            onclick="window.location='<?php echo $block->getCheckoutUrl() ?>';">
-                <span><?php echo __('Proceed to Checkout') ?></span>
+            <?php if ($block->isDisabled()):?>disabled="disabled"<?php endif; ?>>
+        <span><?php echo __('Proceed to Checkout') ?></span>
     </button>
 <?php endif?>
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/create-billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/action/create-billing-address.js
new file mode 100644
index 0000000000000000000000000000000000000000..a48f92659f46a3f0d2d8bb76d5cb2920182643be
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/action/create-billing-address.js
@@ -0,0 +1,17 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [
+        'Magento_Checkout/js/model/address-converter'
+    ],
+    function(addressConverter) {
+        "use strict";
+        return function(addressData) {
+            var address = addressConverter.formAddressDataToQuoteAddress(addressData);
+            return address;
+        };
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/create-shipping-address.js b/app/code/Magento/Checkout/view/frontend/web/js/action/create-shipping-address.js
new file mode 100644
index 0000000000000000000000000000000000000000..d4225a3166057fabbcc83ebf01530ffae7601167
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/action/create-shipping-address.js
@@ -0,0 +1,30 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [
+        'Magento_Customer/js/model/address-list',
+        'Magento_Checkout/js/model/address-converter'
+    ],
+    function(addressList, addressConverter) {
+        "use strict";
+        return function(addressData) {
+            var address = addressConverter.formAddressDataToQuoteAddress(addressData);
+            var isAddressUpdated = addressList().some(function(currentAddress, index, addresses) {
+                if (currentAddress.getKey() == address.getKey()) {
+                    addresses[index] = address;
+                    return true;
+                }
+                return false;
+            });
+            if (!isAddressUpdated) {
+                addressList.push(address);
+            } else {
+                addressList.valueHasMutated();
+            }
+            return address;
+        };
+    }
+);
\ No newline at end of file
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/get-totals.js b/app/code/Magento/Checkout/view/frontend/web/js/action/get-totals.js
new file mode 100644
index 0000000000000000000000000000000000000000..57524a7cb404576bc19da11b30b54452833f5ab9
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/action/get-totals.js
@@ -0,0 +1,47 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+/*global define,alert*/
+define(
+    [
+        'jquery',
+        '../model/quote',
+        'Magento_Checkout/js/model/resource-url-manager',
+        'Magento_Ui/js/model/messageList',
+        'mage/storage',
+        'Magento_Checkout/js/model/totals'
+    ],
+    function ($, quote, resourceUrlManager, messageList, storage, totals) {
+        "use strict";
+        return function (callbacks, deferred) {
+            deferred = deferred || $.Deferred();
+            totals.isLoading(true);
+            return storage.get(
+                resourceUrlManager.getUrlForCartTotals(quote),
+                false
+            ).done(
+                function (response) {
+                    totals.isLoading(false);
+                    var proceed = true;
+                    $.each(callbacks, function(index, callback) {
+                        proceed = proceed && callback();
+                    });
+                    if (proceed) {
+                        quote.setTotals(response);
+                        deferred.resolve();
+                    }
+                }
+            ).error(
+                function (response) {
+                    totals.isLoading(false);
+                    var error = JSON.parse(response.responseText);
+                    messageList.addErrorMessage(error);
+                    deferred.reject();
+                }
+            );
+
+        };
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/place-order.js b/app/code/Magento/Checkout/view/frontend/web/js/action/place-order.js
index ee6bf6d67d3396bf764b2f39ac1c275ab464b1f5..eabe01078de5e0bbeb9a788c30c21f6e313977ec 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/action/place-order.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/action/place-order.js
@@ -2,48 +2,56 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-/*global define*/
 define(
     [
-        '../model/quote',
-        '../model/url-builder',
-        '../model/payment-service',
+        'Magento_Checkout/js/model/quote',
+        'Magento_Checkout/js/model/url-builder',
         'mage/storage',
         'mage/url',
-        'Magento_Ui/js/model/errorlist',
+        'Magento_Ui/js/model/messageList',
         'Magento_Customer/js/model/customer',
         'underscore'
     ],
-    function(quote, urlBuilder, paymentService, storage, url, errorList, customer, _) {
-        "use strict";
-        return function(customParams, callback) {
-            var payload;
-            customParams = customParams || {
-                cartId: quote.getQuoteId(),
-                paymentMethod: paymentService.getSelectedPaymentData()
-            };
+    function (quote, urlBuilder, storage, url, messageList, customer, _) {
+        'use strict';
+
+        return function (paymentData, redirectOnSuccess) {
+            var serviceUrl, payload;
+
+            redirectOnSuccess = redirectOnSuccess === false ? false : true;
             /**
              * Checkout for guest and registered customer.
              */
-            var serviceUrl;
-            if (quote.getCheckoutMethod()() === 'guest') {
-                serviceUrl =  urlBuilder.createUrl('/guest-carts/:quoteId/order', {quoteId: quote.getQuoteId()});
+            if (!customer.isLoggedIn()) {
+                serviceUrl = urlBuilder.createUrl('/guest-carts/:quoteId/payment-information', {
+                    quoteId: quote.getQuoteId()
+                });
+                payload = {
+                    cartId: quote.getQuoteId(),
+                    email: quote.guestEmail,
+                    paymentMethod: paymentData,
+                    billingAddress: quote.billingAddress()
+                };
             } else {
-                serviceUrl = urlBuilder.createUrl('/carts/mine/order', {});
+                serviceUrl = urlBuilder.createUrl('/carts/mine/payment-information', {});
+                payload = {
+                    cartId: quote.getQuoteId(),
+                    paymentMethod: paymentData,
+                    billingAddress: quote.billingAddress()
+                };
             }
-            payload = customParams;
-            storage.put(
+            storage.post(
                 serviceUrl, JSON.stringify(payload)
             ).done(
-                function() {
-                    if (!_.isFunction(callback) || callback()) {
+                function () {
+                    if (redirectOnSuccess) {
                         window.location.replace(url.build('checkout/onepage/success/'));
                     }
                 }
             ).fail(
-                function(response) {
+                function (response) {
                     var error = JSON.parse(response.responseText);
-                    errorList.add(error);
+                    messageList.addErrorMessage(error);
                 }
             );
         };
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/select-billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/action/select-billing-address.js
index 635f6797f40750b26511d8c686c4227b7420b433..da290fc1aa214d38d38deb8ca5b68805e66962f5 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/action/select-billing-address.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/action/select-billing-address.js
@@ -2,88 +2,15 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-/*jshint browser:true*/
-/*global define, alert*/
+/*global define*/
 define(
     [
-        '../model/quote',
-        '../model/addresslist',
-        '../model/step-navigator',
-        './select-shipping-address',
-        'uiRegistry',
-        '../model/url-builder',
-        'mage/storage',
-        '../model/payment-service',
-        'underscore'
+        '../model/quote'
     ],
-    function (quote, addressList, navigator, selectShippingAddress, registry, urlBuilder, storage, paymentService, _) {
+    function(quote) {
         "use strict";
-        var actionCallback;
-        var result = function (billingAddress, useForShipping, additionalData) {
-            var copyBillingToShipping = function() {
-                var shippingAddressSource = registry.get('checkoutProvider'),
-                    shippingAddress = shippingAddressSource.get('shippingAddress');
-                for (var property in billingAddress) {
-                    if (billingAddress.hasOwnProperty(property) && shippingAddress.hasOwnProperty(property)) {
-                        if (typeof billingAddress[property] === 'string') {
-                            shippingAddressSource.set('shippingAddress.' + property, billingAddress[property]);
-                        } else {
-                            shippingAddressSource.set('shippingAddress.' + property, _.clone(billingAddress[property]));
-                        }
-                    }
-                }
-            };
-            additionalData = additionalData || {};
-            quote.setBillingAddress(billingAddress);
-            if (useForShipping() === '1' && !quote.isVirtual()) {
-                if (!billingAddress.customerAddressId) {
-                    copyBillingToShipping();
-                }
-                selectShippingAddress(billingAddress, useForShipping, additionalData);
-            } else if (quote.isVirtual()) {
-                var serviceUrl;
-                if (quote.getCheckoutMethod()() === 'guest') {
-                    serviceUrl = urlBuilder.createUrl('/guest-carts/:quoteId/addresses', {quoteId: quote.getQuoteId()});
-                } else {
-                    serviceUrl = urlBuilder.createUrl('/carts/mine/addresses', {});
-                }
-                storage.post(
-                    serviceUrl,
-                    JSON.stringify({
-                        billingAddress: quote.getBillingAddress()(),
-                        additionalData: {extensionAttributes : additionalData},
-                        checkoutMethod: quote.getCheckoutMethod()()
-                    })
-                ).done(
-                    function (result) {
-                        paymentService.setPaymentMethods(result.payment_methods);
-                        quote.setFormattedBillingAddress(result.formatted_billing_address);
-                        quote.setTotals(result.totals);
-                        navigator.setCurrent('billingAddress').goNext();
-                        if (typeof actionCallback == 'function') {
-                            actionCallback(true);
-                        }
-                    }
-                ).fail(
-                    function (response) {
-                        var error = JSON.parse(response.responseText);
-                        errorList.add(error);
-                        quote.setBillingAddress(null);
-                        if (typeof actionCallback == 'function') {
-                            actionCallback(false);
-                        }
-                    }
-                );
-            } else {
-                navigator.setCurrent('billingAddress').goNext();
-                if (addressList.isBillingSameAsShipping) {
-                    copyBillingToShipping();
-                }
-            }
+        return function(billingAddress) {
+            quote.billingAddress(billingAddress);
         };
-        result.setActionCallback = function (value) {
-            actionCallback = value;
-        };
-        return result;
     }
 );
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js b/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js
index f0fe5a55aa3af0016a1a4e78dd15d7ae66295400..c6d9c56528efb47d0364a769b3a0a56d7d2d0016 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js
@@ -5,96 +5,12 @@
 /*global define*/
 define(
     [
-        '../model/quote',
-        '../model/url-builder',
-        '../model/step-navigator',
-        '../model/payment-service',
-        'Magento_Ui/js/model/errorlist',
-        'mage/storage',
-        'underscore'
+        '../model/quote'
     ],
-    function(quote, urlBuilder, navigator, service, errorList, storage, _) {
-        "use strict";
-        return function (methodData, methodInfo, callbacks) {
-            var paymentMethodData = {
-                "cartId": quote.getQuoteId(),
-                "paymentMethod": methodData
-            };
-
-            var shippingMethodCode = quote.getSelectedShippingMethod()().slice(0).split("_"),
-                shippingMethodData = {
-                    "shippingCarrierCode" : shippingMethodCode.shift(),
-                    "shippingMethodCode" : shippingMethodCode.join('_')
-                },
-                serviceUrl;
-            if (quote.getCheckoutMethod()() === 'guest') {
-                serviceUrl = urlBuilder.createUrl('/guest-carts/:quoteId/collect-totals', {quoteId: quote.getQuoteId()});
-            } else {
-                serviceUrl = urlBuilder.createUrl('/carts/mine/collect-totals', {});
-            }
-
-            if (quote.isVirtual()) {
-                return storage.put(
-                    serviceUrl,
-                    JSON.stringify(paymentMethodData)
-                ).done(
-                    function (response) {
-                        var proceed = true;
-                        _.each(callbacks, function(callback) {
-                            proceed = proceed && callback();
-                        });
-                        if (proceed) {
-                            quote.setPaymentMethod(methodData.method);
-                            service.setSelectedPaymentData(methodData);
-                            service.setSelectedPaymentInfo(methodInfo);
-                            quote.setTotals(response);
-                            navigator.setCurrent('paymentMethod').goNext();
-                        }
-                    }
-                ).error(
-                    function (response) {
-                        var error = JSON.parse(response.responseText);
-                        errorList.add(error);
-                        quote.setPaymentMethod(null);
-                    }
-                );
-            } else {
-                if (!_.isEmpty(quote.getShippingCustomOptions()())) {
-                    shippingMethodData = _.extend(
-                        shippingMethodData,
-                        {
-                            additionalData: {
-                                extension_attributes: quote.getShippingCustomOptions()()
-                            }
-                        }
-                    );
-                }
-                return storage.put(
-                    serviceUrl,
-                    JSON.stringify(_.extend(paymentMethodData, shippingMethodData))
-                ).done(
-                    function (response) {
-                        var proceed = true;
-                        _.each(callbacks, function(callback) {
-                            proceed = proceed && callback();
-                        });
-                        if (proceed) {
-                            quote.setPaymentMethod(methodData.method);
-                            //set the totals before setting PaymentData
-                            quote.setTotals(response);
-                            service.setSelectedPaymentData(methodData);
-                            service.setSelectedPaymentInfo(methodInfo);
-                            navigator.setCurrent('paymentMethod').goNext();
-                        }
-                    }
-                ).error(
-                    function (response) {
-                        var error = JSON.parse(response.responseText);
-                        errorList.add(error);
-                        quote.setPaymentMethod(null);
-                    }
-                );
-            }
-        };
+    function(quote) {
+        'use strict';
+        return function (paymentMethod) {
+            quote.paymentMethod(paymentMethod);
+        }
     }
 );
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/select-shipping-address.js b/app/code/Magento/Checkout/view/frontend/web/js/action/select-shipping-address.js
index c9f87d1594b7aa201bee919e37ba79ca4c3d21a6..5247cef00fb03ac61bf36e29f7e6655fee7605cd 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/action/select-shipping-address.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/action/select-shipping-address.js
@@ -4,69 +4,16 @@
  */
 /*global define*/
 define(
-    [
-        '../model/quote',
-        '../model/addresslist',
-        '../model/url-builder',
-        '../model/step-navigator',
-        '../model/shipping-service',
-        '../model/payment-service',
-        'mage/storage',
-        'Magento_Ui/js/model/errorlist'
+    ['../model/quote',
+     'Magento_Checkout/js/model/shipping-rate-service'
     ],
-    function(quote, addressList, urlBuilder, navigator, shippingService, paymentService, storage, errorList) {
+    function(quote, shippingRateService) {
         "use strict";
-        var actionCallback;
-        var result = function(shippingAddress, sameAsBilling, additionalData) {
-            var serviceUrl;
-            if (quote.getCheckoutMethod()() === 'guest') {
-                serviceUrl = urlBuilder.createUrl('/guest-carts/:quoteId/addresses', {quoteId: quote.getQuoteId()});
-            } else {
-                serviceUrl =  urlBuilder.createUrl('/carts/mine/addresses', {});
-            }
-
-            errorList.clear();
-            additionalData = additionalData || {};
-            shippingAddress['same_as_billing'] = (sameAsBilling) ? 1 : 0;
-            quote.setShippingAddress(shippingAddress);
-
-            storage.post(
-                serviceUrl,
-                JSON.stringify({
-                    shippingAddress: quote.getShippingAddress()(),
-                    billingAddress: quote.getBillingAddress()(),
-                    additionalData: {extensionAttributes : additionalData},
-                    checkoutMethod: quote.getCheckoutMethod()()
-                })
-            ).done(
-                function(result) {
-                    shippingService.setShippingRates(result.shipping_methods);
-                    paymentService.setPaymentMethods(result.payment_methods);
-                    quote.setFormattedBillingAddress(result.formatted_billing_address);
-                    quote.setFormattedShippingAddress(result.formatted_shipping_address);
-                    quote.setTotals(result.totals);
-                    navigator.setCurrent('shippingAddress').goNext();
-                    if (typeof actionCallback == 'function') {
-                        actionCallback(true);
-                    }
-                }
-            ).fail(
-                function(response) {
-                    var error = JSON.parse(response.responseText);
-                    errorList.add(error);
-                    quote.setShippingAddress(null);
-                    quote.setBillingAddress(null);
-                    quote.setFormattedBillingAddress(null);
-                    quote.setFormattedShippingAddress(null);
-                    if (typeof actionCallback == 'function') {
-                        actionCallback(false);
-                    }
-                }
-            );
+        quote.shippingAddress.subscribe(function () {
+            shippingRateService.getRates(quote.shippingAddress())
+        });
+        return function(shippingAddress) {
+            quote.shippingAddress(shippingAddress);
         };
-        result.setActionCallback = function (value) {
-            actionCallback = value;
-        };
-        return result;
     }
 );
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/select-shipping-method.js b/app/code/Magento/Checkout/view/frontend/web/js/action/select-shipping-method.js
index f00e2e86670c8e145fc67b33ec8a3fe7f1bcbf47..30f629cfc09e52343b5fe41343c8229f3e0e9abf 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/action/select-shipping-method.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/action/select-shipping-method.js
@@ -5,36 +5,12 @@
 /*global define,alert*/
 define(
     [
-        '../model/quote',
-        '../model/url-builder',
-        '../model/step-navigator',
-        'Magento_Checkout/js/model/shipping-service',
-        'mage/translate',
-        'ko'
+        '../model/quote'
     ],
-    function (quote, urlBuilder, navigator, shippingService, $t, ko) {
+    function (quote) {
         "use strict";
-        return function (code, customOptions, callbacks) {
-            if (!code) {
-                alert($t('Please specify a shipping method'));
-                return;
-            }
-
-            var proceed = true;
-            _.each(callbacks, function (callback) {
-                proceed = proceed && callback();
-            });
-
-            if (proceed) {
-                var shippingMethodCode = code.split("_"),
-                    shippingRate = shippingService.getRateByCode(shippingMethodCode)[0];
-
-                quote.setShippingMethod(shippingMethodCode);
-                quote.setSelectedShippingMethod(code);
-                quote.setShippingCustomOptions(customOptions);
-                quote.setCollectedTotals('shipping', shippingRate.amount);
-                navigator.setCurrent('shippingMethod').goNext();
-            }
-        };
+        return function (shippingMethod) {
+            quote.shippingMethod(shippingMethod)
+        }
     }
 );
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/set-payment-information.js b/app/code/Magento/Checkout/view/frontend/web/js/action/set-payment-information.js
new file mode 100644
index 0000000000000000000000000000000000000000..4f1167970a41e3af06ac108be3e60aa44d63ad20
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/action/set-payment-information.js
@@ -0,0 +1,56 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define(
+    [
+        'Magento_Checkout/js/model/quote',
+        'Magento_Checkout/js/model/url-builder',
+        'mage/storage',
+        'Magento_Ui/js/model/messageList',
+        'Magento_Customer/js/model/customer'
+    ],
+    function (quote, urlBuilder, storage, messageList, customer) {
+        'use strict';
+
+        return function () {
+            var serviceUrl,
+                payload,
+                paymentData = quote.paymentMethod();
+
+            /**
+             * Checkout for guest and registered customer.
+             */
+            if (!customer.isLoggedIn()) {
+                serviceUrl = urlBuilder.createUrl('/guest-carts/:quoteId/set-payment-information', {
+                    quoteId: quote.getQuoteId()
+                });
+                payload = {
+                    cartId: quote.getQuoteId(),
+                    email: quote.guestEmail,
+                    paymentMethod: paymentData,
+                    billingAddress: quote.billingAddress()
+                };
+            } else {
+                serviceUrl = urlBuilder.createUrl('/carts/mine/set-payment-information', {});
+                payload = {
+                    cartId: quote.getQuoteId(),
+                    paymentMethod: paymentData,
+                    billingAddress: quote.billingAddress()
+                };
+            }
+            return storage.post(
+                serviceUrl, JSON.stringify(payload)
+            ).done(
+                function () {
+                    //do nothing
+                }
+            ).fail(
+                function (response) {
+                    var error = JSON.parse(response.responseText);
+                    messageList.addErrorMessage(error);
+                }
+            );
+        };
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/set-shipping-information.js b/app/code/Magento/Checkout/view/frontend/web/js/action/set-shipping-information.js
new file mode 100644
index 0000000000000000000000000000000000000000..918f5201012f1eb933940b8a10e817b3a67387b4
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/action/set-shipping-information.js
@@ -0,0 +1,17 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define,alert*/
+define(
+    [
+        '../model/quote',
+        'Magento_Checkout/js/model/shipping-save-processor'
+    ],
+    function (quote, shippingSaveProcessor) {
+        'use strict';
+        return function () {
+            return shippingSaveProcessor.saveShippingInformation(quote.shippingAddress().getType());
+        }
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js b/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js
new file mode 100644
index 0000000000000000000000000000000000000000..896f38b9648aa27bee9050378c445d6a7e664ce5
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js
@@ -0,0 +1,85 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define(
+    [
+        'jquery',
+        'Magento_Checkout/js/model/new-customer-address',
+        'mage/utils/objects'
+    ],
+    function($, address, mageUtils) {
+        'use strict';
+        var countryData = window.checkoutConfig.countryData;
+
+        return {
+            /**
+             * Convert address form data to Address object
+             * @param {Object} formData
+             * @returns {Object}
+             */
+            formAddressDataToQuoteAddress: function(formData) {
+                // clone address form data to new object
+                var addressData = $.extend(true, {}, formData),
+                    region;
+
+                if (mageUtils.isObject(addressData.street)) {
+                    addressData.street = this.objectToArray(addressData.street);
+                }
+
+                addressData.region = {
+                    region_id: null,
+                    region_code: null,
+                    region: null
+                };
+
+                if (addressData.region_id) {
+                    region = countryData[addressData.country_id]['regions'][addressData.region_id];
+                    if (region) {
+                        addressData.region.region_id = addressData['region_id'];
+                        addressData.region.region_code = region['code'];
+                        addressData.region.region = region['name'];
+                    }
+                }
+                delete addressData.region_id;
+
+                return address(addressData);
+            },
+
+            formDataProviderToFlatData: function(formProviderData, formIndex) {
+                var addressData = {};
+                $.each(formProviderData, function(path, value) {
+                    var pathComponents = path.split('.');
+                    pathComponents.splice(pathComponents.indexOf(formIndex), 1);
+                    pathComponents.reverse();
+                    var dataObject = {};
+                    $.each(pathComponents, function(index, pathPart) {
+                        if (index == 0) {
+                            dataObject[pathPart] = value;
+                        } else {
+                            var parent = {};
+                            parent[pathPart] = dataObject;
+                            dataObject = parent;
+                        }
+                    });
+                    $.extend(true, addressData, dataObject);
+                });
+                return addressData;
+            },
+
+            /**
+             * Convert object to array
+             * @param {Object} object
+             * @returns {Array}
+             */
+            objectToArray: function (object) {
+                var convertedArray = [];
+                $.each(object, function (key) {
+                    return object[key].length ? convertedArray.push(object[key]) : false;
+                });
+
+                return convertedArray.slice(0);
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/addresslist.js b/app/code/Magento/Checkout/view/frontend/web/js/model/addresslist.js
deleted file mode 100644
index 62bc28d2527638c59a8f629f09448279187a74d4..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/js/model/addresslist.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*jshint browser:true*/
-/*global define*/
-define(['jquery'], function($) {
-    "use strict";
-    var addresses = [];
-    return {
-        add: function (address) {
-            addresses.push(address);
-        },
-        getAddressById: function(id) {
-            var address = null;
-            $.each(addresses, function(key, item) {
-                if (id === item.customerAddressId) {
-                    address = item;
-                    return false;
-                }
-            });
-            return address;
-        },
-        getAddresses: function() {
-            return addresses.slice(0);
-        },
-        isBillingSameAsShipping: false
-    };
-});
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/cart/authentication-popup.js b/app/code/Magento/Checkout/view/frontend/web/js/model/cart/authentication-popup.js
new file mode 100644
index 0000000000000000000000000000000000000000..e448a1c30b07da31ae1f26aaecb0477bade09b65
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/cart/authentication-popup.js
@@ -0,0 +1,37 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(
+    [
+        'jquery',
+        'Magento_Ui/js/modal/modal'
+    ],
+    function ($, modal) {
+        'use strict';
+        return {
+            modalWindow: null,
+
+            /** Create popUp window for provided element */
+            createPopUp: function(element) {
+                this.modalWindow = element;
+                var options = {
+                    'type': 'popup',
+                    'modalClass': 'popup-authentication',
+                    'responsive': true,
+                    'innerScroll': true,
+                    'trigger': '.proceed-to-checkout',
+                    'buttons': []
+                };
+                modal(options, $(this.modalWindow));
+            },
+
+            /** Show login popup window */
+            showModal: function() {
+                $(this.modalWindow).modal('openModal');
+            }
+        }
+    }
+);
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
new file mode 100644
index 0000000000000000000000000000000000000000..7f64f87e3e4c6cb7308f6a441faed2e13a74589a
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/new-customer-address.js
@@ -0,0 +1,58 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define([], function() {
+    /**
+     * @param addressData
+     * Returns new address object
+     */
+    return function (addressData) {
+        var identifier = Date.now();
+        return {
+            email: addressData.email,
+            countryId: addressData.country_id,
+            regionId: (addressData.region) ? addressData.region.region_id : null,
+            regionCode: (addressData.region) ? addressData.region.region_code : null,
+            region: (addressData.region) ? addressData.region.region : null,
+            customerId: addressData.customer_id,
+            street: addressData.street,
+            company: addressData.company,
+            telephone: addressData.telephone,
+            fax: addressData.fax,
+            postcode: addressData.postcode,
+            city: addressData.city,
+            firstname: addressData.firstname,
+            lastname: addressData.lastname,
+            middlename: addressData.middlename,
+            prefix: addressData.prefix,
+            suffix: addressData.suffix,
+            vatId: addressData.vat_id,
+            sameAsBilling: addressData.same_as_billing,
+            saveInAddressBook: addressData.save_in_address_book,
+            isDefaultShipping: function() {
+                return addressData.default_shipping;
+            },
+            isDefaultBilling: function() {
+                return addressData.default_billing;
+            },
+            getType: function() {
+                return 'new-customer-address'
+            },
+            getKey: function() {
+                return this.getType();
+            },
+            getCacheKey: function() {
+                return this.getType() + identifier;
+            },
+            isEditable: function() {
+                return true;
+            },
+            canUseForBilling: function() {
+                return true;
+            }
+        }
+    }
+});
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/payment-service.js b/app/code/Magento/Checkout/view/frontend/web/js/model/payment-service.js
index 9b6fc75a216c506964c20ee938f60ee1677de823..77841ad3b0632b0d155c7618039ea15fdc5776e9 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/model/payment-service.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/payment-service.js
@@ -2,67 +2,72 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-/*jshint browser:true jquery:true*/
-/*global alert*/
 define(
     [
-        'ko',
-        'jquery',
-        'Magento_Checkout/js/model/quote'
+        'underscore',
+        'Magento_Checkout/js/model/quote',
+        'Magento_Checkout/js/model/payment/method-list',
+        'Magento_Checkout/js/action/select-payment-method'
     ],
-    function (ko, $, quote) {
+    function (_, quote, methodList, selectPaymentMethod) {
+        'use strict';
+        var freeMethodCode = 'free';
+
         return {
-            paymentMethods: ko.observableArray([]),
-            availablePaymentMethods: ko.observableArray([]),
-            selectedPaymentData: ko.observableArray(),
-            selectedPaymentInfo: ko.observableArray([]),
-            setPaymentMethods: function(methods) {
-                this.paymentMethods(methods);
+            isFreeAvailable: false,
+            /**
+             * Populate the list of payment methods
+             * @param {Array} methods
+             */
+            setPaymentMethods: function (methods) {
+                var self = this,
+                    freeMethod,
+                    filteredMethods,
+                    methodIsAvailable;
+
+                freeMethod = _.find(methods, function (method) {
+                    return method.method === freeMethodCode;
+                });
+                this.isFreeAvailable = freeMethod ? true : false;
+
+                if (self.isFreeAvailable && freeMethod && quote.totals().grand_total <= 0) {
+                    methods.splice(0, methods.length, freeMethod);
+                    selectPaymentMethod(freeMethod);
+                }
+                filteredMethods = _.without(methods, freeMethod);
+
+                if (filteredMethods.length === 1) {
+                    selectPaymentMethod(filteredMethods[0]);
+                } else if (quote.paymentMethod()) {
+                    methodIsAvailable = methods.some(function (item) {
+                        return item.method === quote.paymentMethod().method;
+                    });
+                    //Unset selected payment method if not available
+                    if (!methodIsAvailable) {
+                        selectPaymentMethod(null);
+                    }
+                }
+                methodList(methods);
             },
+            /**
+             * Get the list of available payment methods.
+             * @returns {Array}
+             */
             getAvailablePaymentMethods: function () {
                 var methods = [],
                     self = this;
-                $.each(this.paymentMethods(), function (key, method) {
-                    if (self.isFreeMethodActive() && (
-                        quote.getCalculatedTotal() <= 0 && method['code'] == 'free'
-                        || quote.getCalculatedTotal() > 0 && method['code'] != 'free'
-                        ) || !self.isFreeMethodActive()
+                _.each(methodList(), function (method) {
+                    if (self.isFreeAvailable && (
+                        quote.totals().grand_total <= 0 && method.method === freeMethodCode ||
+                        quote.totals().grand_total > 0 && method.method !== freeMethodCode
+                        ) || !self.isFreeAvailable
                     ) {
                         methods.push(method);
                     }
                 });
+
                 return methods;
-            },
-            isFreeMethodActive: function () {
-                var isAvailable = false;
-                $.each(this.paymentMethods(), function (key, method) {
-                    if (method['code'] == 'free') {
-                        isAvailable = true;
-                    }
-                });
-                return isAvailable;
-            },
-            setSelectedPaymentData: function(data) {
-                this.selectedPaymentData(data);
-            },
-            getSelectedPaymentData: function () {
-                return this.selectedPaymentData();
-            },
-            setSelectedPaymentInfo: function(data) {
-                this.selectedPaymentInfo(data);
-            },
-            getSelectedPaymentInfo: function () {
-                return this.selectedPaymentInfo();
-            },
-            getTitleByCode: function(code) {
-                var methodTitle = '';
-                $.each(this.getAvailablePaymentMethods(), function (key, entity) {
-                    if (entity['code'] == code) {
-                        methodTitle = entity['title'];
-                    }
-                });
-                return methodTitle;
             }
-        }
+        };
     }
 );
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/payment/method-converter.js b/app/code/Magento/Checkout/view/frontend/web/js/model/payment/method-converter.js
new file mode 100644
index 0000000000000000000000000000000000000000..794f7d9a38b01fc043414adb8fdb2714f0aeac42
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/payment/method-converter.js
@@ -0,0 +1,23 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define(
+    [
+        'underscore'
+    ],
+    function (_) {
+        'use strict';
+
+        return function (methods) {
+            _.each(methods, function(method) {
+                if (method.hasOwnProperty('code')) {
+                    method.method = method.code;
+                    delete method.code;
+                }
+            });
+
+            return methods;
+        };
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/payment/method-list.js b/app/code/Magento/Checkout/view/frontend/web/js/model/payment/method-list.js
new file mode 100644
index 0000000000000000000000000000000000000000..9b234d7572c8efdfafc4c71456491edfb811b71d
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/payment/method-list.js
@@ -0,0 +1,13 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define(
+    [
+        'ko'
+    ],
+    function(ko) {
+        'use strict';
+        return ko.observableArray([]);
+    }
+);
diff --git a/app/code/Magento/Payment/view/frontend/web/js/view/payment/free-method.js b/app/code/Magento/Checkout/view/frontend/web/js/model/payment/renderer-list.js
similarity index 51%
rename from app/code/Magento/Payment/view/frontend/web/js/view/payment/free-method.js
rename to app/code/Magento/Checkout/view/frontend/web/js/model/payment/renderer-list.js
index 44285074df09ad9fa0d14f8f94a69c8c8782ba11..1966d296a9ef06c2df54a5c22c6cbe1364e74655 100644
--- a/app/code/Magento/Payment/view/frontend/web/js/view/payment/free-method.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/payment/renderer-list.js
@@ -2,14 +2,13 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-/*browser:true*/
 /*global define*/
 define(
     [
-        'Magento_Checkout/js/view/payment/method-info'
+        'ko'
     ],
-    function (method) {
-        return method.extend({
-        });
+    function(ko) {
+        'use strict';
+        return ko.observableArray([]);
     }
 );
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/postcode-validator.js b/app/code/Magento/Checkout/view/frontend/web/js/model/postcode-validator.js
new file mode 100644
index 0000000000000000000000000000000000000000..1cc970630a39c7c4509450c921c98cab0886db7f
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/postcode-validator.js
@@ -0,0 +1,30 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(['mageUtils'], function (utils) {
+    'use strict';
+    return {
+        validatedPostCodeExample: [],
+        validate: function(postCode, countryId) {
+            var patterns = window.checkoutConfig.postCodes[countryId];
+            this.validatedPostCodeExample = [];
+
+            if (!utils.isEmpty(postCode) && !utils.isEmpty(patterns)) {
+                for (var pattern in patterns) {
+                    if (patterns.hasOwnProperty(pattern)) {
+                        this.validatedPostCodeExample.push(patterns[pattern]['example']);
+                        var regex = new RegExp(patterns[pattern]['pattern']);
+                        if (regex.test(postCode)) {
+                            return true;
+                        }
+                    }
+                }
+                return false;
+            }
+            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 650a8b053f7a2c14d07cce94e578e3b1dde6c48f..2ba260a0495c1bd483b291d90988a68cffc48f8d 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
@@ -2,11 +2,10 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-/*jshint browser:true jquery:true*/
-/*global alert*/
 define(
     ['ko'],
-    function(ko) {
+    function (ko) {
+        'use strict';
         var billingAddress = ko.observable(null);
         var shippingAddress = ko.observable(null);
         var shippingMethod = ko.observable(null);
@@ -14,15 +13,21 @@ define(
         var quoteData = window.checkoutConfig.quoteData;
         var basePriceFormat = window.checkoutConfig.basePriceFormat;
         var priceFormat = window.checkoutConfig.priceFormat;
-        var selectedShippingMethod = ko.observable(window.checkoutConfig.selectedShippingMethod);
         var storeCode = window.checkoutConfig.storeCode;
-        var totals = ko.observable({});
-        var checkoutMethod = ko.observable(null);
+        var totalsData = window.checkoutConfig.totalsData;
+        var totals = ko.observable(totalsData);
         var shippingCustomOptions = ko.observable(null);
         var formattedShippingAddress = ko.observable(null);
         var formattedBillingAddress = ko.observable(null);
         var collectedTotals = ko.observable({});
         return {
+            totals: totals,
+            shippingAddress: shippingAddress,
+            shippingMethod: shippingMethod,
+            billingAddress: billingAddress,
+            paymentMethod: paymentMethod,
+            guestEmail: null,
+
             getQuoteId: function() {
                 return quoteData.entity_id;
             },
@@ -39,7 +44,7 @@ define(
                 return window.checkoutConfig.quoteItemData;
             },
             getTotals: function() {
-                return totals
+                return totals;
             },
             setTotals: function(totalsData) {
                 if (_.isObject(totalsData.extension_attributes)) {
@@ -50,18 +55,6 @@ define(
                 totals(totalsData);
                 this.setCollectedTotals('subtotal_with_discount', parseFloat(totalsData.subtotal_with_discount));
             },
-            setBillingAddress: function (address) {
-                billingAddress(address);
-            },
-            getBillingAddress: function() {
-                return billingAddress;
-            },
-            setShippingAddress: function (address) {
-                shippingAddress(address);
-            },
-            getShippingAddress: function() {
-                return shippingAddress;
-            },
             setFormattedBillingAddress: function (address) {
                 formattedBillingAddress(address);
             },
@@ -80,27 +73,9 @@ define(
             getPaymentMethod: function() {
                 return paymentMethod;
             },
-            setShippingMethod: function(shippingMethodCode) {
-                shippingMethod(shippingMethodCode);
-            },
-            getShippingMethod: function() {
-                return shippingMethod;
-            },
-            getSelectedShippingMethod: function() {
-                return selectedShippingMethod;
-            },
-            setSelectedShippingMethod: function(shippingMethod) {
-                selectedShippingMethod(shippingMethod);
-            },
             getStoreCode: function() {
                 return storeCode;
             },
-            getCheckoutMethod: function() {
-                return checkoutMethod;
-            },
-            setCheckoutMethod: function(method) {
-                checkoutMethod(method);
-            },
             setShippingCustomOptions: function(customOptions) {
                 shippingCustomOptions(customOptions);
             },
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/resource-url-manager.js b/app/code/Magento/Checkout/view/frontend/web/js/model/resource-url-manager.js
new file mode 100644
index 0000000000000000000000000000000000000000..b84e16a80bff26af12a7698631259f901cc5dd4f
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/resource-url-manager.js
@@ -0,0 +1,90 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(
+    [
+        'Magento_Customer/js/model/customer',
+        'Magento_Checkout/js/model/url-builder',
+        'mageUtils'
+    ],
+    function(customer, urlBuilder, utils) {
+        "use strict";
+        return {
+            getUrlForEstimationShippingMethodsForNewAddress: function(quote) {
+                var params = (this.getCheckoutMethod() == 'guest') ? {quoteId: quote.getQuoteId()} : {};
+                var urls = {
+                    'guest': '/guest-carts/:quoteId/estimate-shipping-methods',
+                    'customer': '/carts/mine/estimate-shipping-methods'
+                };
+                return this.getUrl(urls, params);
+            },
+
+            getUrlForEstimationShippingMethodsByAddressId: function(quote) {
+                var params = (this.getCheckoutMethod() == 'guest') ? {quoteId: quote.getQuoteId()} : {};
+                var urls = {
+                    'default': '/carts/mine/estimate-shipping-methods-by-address-id'
+                };
+                return this.getUrl(urls, params);
+            },
+
+            getApplyCouponUrl: function(couponCode, quoteId) {
+                var params = (this.getCheckoutMethod() == 'guest') ? {quoteId: quoteId} : {};
+                var urls = {
+                    'guest': '/guest-carts/' + quoteId + '/coupons/' + couponCode,
+                    'customer': '/carts/mine/coupons/' + couponCode
+                };
+                return this.getUrl(urls, params);
+            },
+
+            getCancelCouponUrl: function(quoteId) {
+                var params = (this.getCheckoutMethod() == 'guest') ? {quoteId: quoteId} : {};
+                var urls = {
+                    'guest': '/guest-carts/' + quoteId + '/coupons/',
+                    'customer': '/carts/mine/coupons/'
+                };
+                return this.getUrl(urls, params);
+            },
+
+            getUrlForCartTotals: function(quote) {
+                var params = (this.getCheckoutMethod() == 'guest') ? {quoteId: quote.getQuoteId()} : {};
+                var urls = {
+                    'guest': '/guest-carts/:quoteId/totals',
+                    'customer': '/carts/mine/totals'
+                };
+                return this.getUrl(urls, params);
+            },
+
+            getUrlForSetShippingInformation: function(quote) {
+                var params = (this.getCheckoutMethod() == 'guest') ? {cartId: quote.getQuoteId()} : {};
+                var urls = {
+                    'guest': '/carts/:cartId/shipping-information',
+                    'customer': '/carts/mine/shipping-information'
+                };
+                return this.getUrl(urls, params);
+            },
+
+            /** Get url for service */
+            getUrl: function(urls, urlParams) {
+                var url;
+
+                if (utils.isEmpty(urls)) {
+                    return 'Provided service call does not exist.';
+                }
+
+                if (!utils.isEmpty(urls['default'])) {
+                    url = urls['default'];
+                } else {
+                    url = urls[this.getCheckoutMethod()];
+                }
+                return urlBuilder.createUrl(url, urlParams);
+            },
+
+            getCheckoutMethod: function() {
+                return customer.isLoggedIn() ? 'customer' : 'guest';
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-address/form-popup-state.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-address/form-popup-state.js
new file mode 100644
index 0000000000000000000000000000000000000000..d23e82ca703bab7e787a5f47b0027612b4111998
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-address/form-popup-state.js
@@ -0,0 +1,16 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [
+        'ko'
+    ],
+    function(ko) {
+        'use strict';
+        return {
+            isVisible: ko.observable(false)
+        };
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-processor/customer-address.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-processor/customer-address.js
new file mode 100644
index 0000000000000000000000000000000000000000..068891a5286964d5dedb4b8812669e45a6f3b5ca
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-processor/customer-address.js
@@ -0,0 +1,51 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [
+        'Magento_Checkout/js/model/resource-url-manager',
+        'Magento_Checkout/js/model/quote',
+        'mage/storage',
+        'Magento_Checkout/js/model/shipping-service',
+        'Magento_Checkout/js/model/shipping-rate-registry',
+        'Magento_Ui/js/model/messageList'
+    ],
+    function (resourceUrlManager, quote, storage, shippingService, rateRegistry, messageList) {
+        "use strict";
+        return {
+            getRates: function(address) {
+                var cache = rateRegistry.get(address.getKey());
+                if (cache) {
+                    shippingService.setShippingRates(cache);
+                } else {
+                    shippingService.isLoading(true);
+                    storage.post(
+                        resourceUrlManager.getUrlForEstimationShippingMethodsByAddressId(),
+                        JSON.stringify({
+                            addressId: address.customerAddressId
+                        }),
+                        false
+                    ).done(
+                        function(result) {
+                            rateRegistry.set(address.getKey(), result);
+                            shippingService.setShippingRates(result);
+                        }
+
+                    ).fail(
+                        function(response) {
+                            var error = JSON.parse(response.responseText);
+                            messageList.addErrorMessage(error);
+                            shippingService.setShippingRates([])
+                        }
+                    ).always(
+                        function () {
+                            shippingService.isLoading(false);
+                        }
+                    );
+                }
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-processor/new-address.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-processor/new-address.js
new file mode 100644
index 0000000000000000000000000000000000000000..db5052ca0c39f44ddf2ed115ac1d7d94631f2c34
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-processor/new-address.js
@@ -0,0 +1,61 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define(
+    [
+        'Magento_Checkout/js/model/resource-url-manager',
+        'Magento_Checkout/js/model/quote',
+        'mage/storage',
+        'Magento_Checkout/js/model/shipping-service',
+        'Magento_Checkout/js/model/shipping-rate-registry',
+        'Magento_Ui/js/model/messageList'
+    ],
+    function (resourceUrlManager, quote, storage, shippingService, rateRegistry, messageList) {
+        'use strict';
+
+        return {
+            /**
+             * Get shipping rates for specified address.
+             * @param {Object} address
+             */
+            getRates: function (address) {
+                var cache = rateRegistry.get(address.getCacheKey()),
+                    serviceUrl = resourceUrlManager.getUrlForEstimationShippingMethodsForNewAddress(quote),
+                    payload = JSON.stringify({
+                            address: {
+                                country_id: address.countryId,
+                                region_id: address.regionId,
+                                region: address.region,
+                                postcode: address.postcode
+                            }
+                        }
+                    );
+
+                if (cache) {
+                    shippingService.setShippingRates(cache);
+                } else {
+                    shippingService.isLoading(true);
+                    storage.post(
+                        serviceUrl, payload, false
+                    ).done(
+                        function (result) {
+                            rateRegistry.set(address.getCacheKey(), result);
+                            shippingService.setShippingRates(result);
+                        }
+                    ).fail(
+                        function (response) {
+                            var error = JSON.parse(response.responseText);
+                            messageList.addErrorMessage(error);
+                            shippingService.setShippingRates([]);
+                        }
+                    ).always(
+                        function () {
+                            shippingService.isLoading(false);
+                        }
+                    );
+                }
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-registry.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-registry.js
new file mode 100644
index 0000000000000000000000000000000000000000..e5bd1104b1714d89fa4db7bc2893e604e3ea633a
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-registry.js
@@ -0,0 +1,23 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [],
+    function() {
+        "use strict";
+        var cache = [];
+        return {
+            get: function(addressKey) {
+                if (cache[addressKey]) {
+                    return cache[addressKey];
+                }
+                return false;
+            },
+            set: function(addressKey, data) {
+                cache[addressKey] = data;
+            }
+        };
+    }
+);
\ No newline at end of file
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-service.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-service.js
new file mode 100644
index 0000000000000000000000000000000000000000..68bc173215923fff08510790811e5270f4ef5328
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-service.js
@@ -0,0 +1,34 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true*/
+/*global define*/
+define(
+    [
+        'Magento_Checkout/js/model/shipping-rate-processor/new-address',
+        'Magento_Checkout/js/model/shipping-rate-processor/customer-address'
+    ],
+    function(defaultProcessor, customerAddressProcessor) {
+        "use strict";
+        var processors = [];
+        processors['default'] =  defaultProcessor;
+        processors['customer-address'] = customerAddressProcessor;
+
+        return {
+            registerProcessor: function(type, processor) {
+                processors[type] = processor;
+            },
+            getRates: function (address) {
+                var type = address.getType();
+                var rates = [];
+                if (processors[type]) {
+                    rates = processors[type].getRates(address);
+                } else {
+                    rates = processors['default'].getRates(address);
+                }
+                return rates;
+            }
+        }
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validation-rules.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validation-rules.js
new file mode 100644
index 0000000000000000000000000000000000000000..e6eafeee848e544635b8bb1b97ac345b76b52854
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validation-rules.js
@@ -0,0 +1,35 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    ['jquery'],
+    function ($) {
+        "use strict";
+        var ratesRules = {};
+        var checkoutConfig = window.checkoutConfig;
+        return {
+            registerRules: function(carrier, rules) {
+                if (checkoutConfig.activeCarriers.indexOf(carrier) != -1) {
+                    ratesRules[carrier] = rules.getRules();
+                }
+            },
+            getRules: function() {
+                return ratesRules;
+            },
+            getObservableFields: function() {
+                var self = this;
+                var observableFields = [];
+                $.each(self.getRules(), function(carrier, fields) {
+                    $.each(fields, function(field, rules) {
+                        if (observableFields.indexOf(field) == -1) {
+                            observableFields.push(field);
+                        }
+                    });
+                });
+                return observableFields;
+            }
+        };
+    }
+);
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
new file mode 100644
index 0000000000000000000000000000000000000000..7bd072008705968c57080a089666f07968355fb8
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js
@@ -0,0 +1,122 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [
+        'jquery',
+        'ko',
+        './shipping-rates-validation-rules',
+        '../model/address-converter',
+        '../action/select-shipping-address',
+        './postcode-validator',
+        'mage/translate'
+    ],
+    function ($, ko, shippingRatesValidationRules, addressConverter, selectShippingAddress, postcodeValidator, $t) {
+        'use strict';
+        var checkoutConfig = window.checkoutConfig;
+        var validators = [];
+        var observedElements = [];
+        var postcodeElement = null;
+
+        return {
+            validateAddressTimeout: 0,
+            validateDelay: 2000,
+
+            registerValidator: function(carrier, validator) {
+                if (checkoutConfig.activeCarriers.indexOf(carrier) != -1) {
+                    validators.push(validator);
+                }
+            },
+
+            validateAddressData: function(address) {
+                return validators.some(function(validator) {
+                    return validator.validate(address);
+                });
+            },
+
+            bindChangeHandlers: function(elements) {
+                var self = this;
+                var observableFields = shippingRatesValidationRules.getObservableFields();
+                $.each(elements, function(index, elem) {
+                    if (elem && observableFields.indexOf(elem.index) != -1) {
+                        if (elem.index !== 'postcode') {
+                            self.bindHandler(elem);
+                        }
+                    }
+
+                    if (elem.index === 'postcode') {
+                        self.bindHandler(elem);
+                        postcodeElement = elem;
+                    }
+                });
+            },
+
+            bindHandler: function(element) {
+                var self = this;
+                if (element.component.indexOf('/group') != -1) {
+                    $.each(element.elems(), function(index, elem) {
+                        self.bindHandler(elem);
+                    });
+                } else {
+                    element.on('value', function() {
+                        clearTimeout(self.validateAddressTimeout);
+                        self.validateAddressTimeout = setTimeout(function() {
+                            if (self.postcodeValidation()) {
+                                self.validateFields();
+                            }
+                        }, self.validateDelay);
+                    });
+                    observedElements.push(element);
+                }
+            },
+
+            postcodeValidation: function() {
+                if (postcodeElement == null || postcodeElement.value() == null) {
+                    return true;
+                }
+
+                var countryId = $('select[name="shippingAddress[country_id]"]').val();
+                var validationResult = postcodeValidator.validate(postcodeElement.value(), countryId);
+
+                postcodeElement.error(null);
+                if (!validationResult) {
+                    var errorMessage = $t('Invalid Zip/Postal code for current country!');
+                    if (postcodeValidator.validatedPostCodeExample.length) {
+                        errorMessage += $t(' Example: ') + postcodeValidator.validatedPostCodeExample.join('; ');
+                    }
+                    postcodeElement.error(errorMessage);
+                }
+                return validationResult;
+            },
+
+            /**
+             * Convert form data to quote address and validate fields for shipping rates
+             */
+            validateFields: function() {
+                var addressFlat = addressConverter.formDataProviderToFlatData(
+                    this.collectObservedData(),
+                    'shippingAddress'
+                );
+                if (this.validateAddressData(addressFlat)) {
+                    var address = addressConverter.formAddressDataToQuoteAddress(addressFlat);
+                    selectShippingAddress(address);
+                }
+            },
+
+            /**
+             * Collect observed fields data to object
+             *
+             * @returns {*}
+             */
+            collectObservedData: function() {
+                var observedValues = {};
+                $.each(observedElements, function(index, field) {
+                    observedValues[field.dataScope] = field.value();
+                });
+                return observedValues;
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-save-processor.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-save-processor.js
new file mode 100644
index 0000000000000000000000000000000000000000..8789ad0ccb38841da2fa7c900e1bee380fbc19e7
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-save-processor.js
@@ -0,0 +1,31 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true*/
+/*global define*/
+define(
+    [
+        'Magento_Checkout/js/model/shipping-save-processor/default'
+    ],
+    function(defaultProcessor) {
+        'use strict';
+        var processors = [];
+        processors['default'] =  defaultProcessor;
+
+        return {
+            registerProcessor: function(type, processor) {
+                processors[type] = processor;
+            },
+            saveShippingInformation: function (type) {
+                var rates = [];
+                if (processors[type]) {
+                    rates = processors[type].saveShippingInformation();
+                } else {
+                    rates = processors['default'].saveShippingInformation();
+                }
+                return rates;
+            }
+        }
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-save-processor/default.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-save-processor/default.js
new file mode 100644
index 0000000000000000000000000000000000000000..7233d429dc0691907a04b174452db883dbdc24df
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-save-processor/default.js
@@ -0,0 +1,46 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define,alert*/
+define(
+    [
+        'ko',
+        'Magento_Checkout/js/model/quote',
+        'Magento_Checkout/js/model/resource-url-manager',
+        'mage/storage',
+        'Magento_Checkout/js/model/payment-service',
+        'Magento_Checkout/js/model/payment/method-converter',
+        'Magento_Ui/js/model/messageList'
+    ],
+    function (ko, quote, resourceUrlManager, storage, paymentService, methodConverter, messageList) {
+        'use strict';
+
+        return {
+            saveShippingInformation: function() {
+                var payload = {
+                    addressInformation: {
+                        shipping_address: quote.shippingAddress(),
+                        shipping_method_code: quote.shippingMethod().method_code,
+                        shipping_carrier_code: quote.shippingMethod().carrier_code
+                    }
+                };
+
+                return storage.post(
+                    resourceUrlManager.getUrlForSetShippingInformation(quote),
+                    JSON.stringify(payload)
+                ).done(
+                    function (response) {
+                        quote.setTotals(response.totals);
+                        paymentService.setPaymentMethods(methodConverter(response.payment_methods));
+                    }
+                ).fail(
+                    function (response) {
+                        var error = JSON.parse(response.responseText);
+                        messageList.addErrorMessage(error);
+                    }
+                );
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-service.js b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-service.js
index 8bb0366111a7aa7002bf81a1932cbea8ec1582de..f03da90e2fade9119bbfb16dbcced239f13572c8 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-service.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/shipping-service.js
@@ -4,46 +4,63 @@
  */
 /*global define*/
 define(
-    ['ko', 'jquery'],
-    function (ko, $) {
+    [
+        'ko',
+        'Magento_Checkout/js/action/select-shipping-method',
+        'Magento_Checkout/js/model/quote',
+        'jquery'
+    ],
+    function (ko, selectShippingMethodAction, quote, $) {
         "use strict";
-        var rates = ko.observable([]);
+        var shippingRates = ko.observableArray([]);
         return {
-            shippingRates: ko.observableArray([]),
+            isLoading: ko.observable(false),
+            /**
+             * Set shipping rates
+             *
+             * @param ratesData
+             */
             setShippingRates: function(ratesData) {
-                var self = this;
-                rates(ratesData);
-                self.shippingRates([]);
-                $.each(ratesData, function (key, entity) {
-                    var rateEntity = {};
-                    rateEntity.items = [];
-                    if (!ratesData.hasOwnProperty(entity.carrier_code)) {
-                        rateEntity['carrier_code'] = entity.carrier_code;
-                        rateEntity['carrier_title'] = entity.carrier_title;
-                    }
-                    rateEntity.items.push(entity);
-                    self.shippingRates.push(rateEntity);
-                });
+                shippingRates(ratesData);
+                shippingRates.valueHasMutated();
 
+                if (ratesData.length == 1) {
+                    //set shipping rate if we have only one available shipping rate
+                    selectShippingMethodAction(ratesData[0]);
+                } else if(quote.shippingMethod()) {
+                    var rateIsAvailable = ratesData.some(function (rate) {
+                        if (rate.carrier_code == quote.shippingMethod().carrier_code
+                            && rate.method_code == quote.shippingMethod().method_code) {
+                            return true;
+                        }
+                        return false;
+                    });
+                    //Unset selected shipping shipping method if not available
+                    if (!rateIsAvailable) {
+                        selectShippingMethodAction(null);
+                    }
+                }
             },
+
+            /**
+             * Get shipping rates
+             *
+             * @returns {*}
+             */
             getSippingRates: function() {
-                return this.shippingRates;
+                return shippingRates;
             },
-            getTitleByCode: function(methodCodeParts) {
-                var shippingMethodTitle = '', shippingMethodCode, carrierCode, methodCode;
-                if (!methodCodeParts) {
-                    return shippingMethodTitle;
-                }
-                shippingMethodCode = methodCodeParts.slice(0);
-                carrierCode = shippingMethodCode.shift();
-                methodCode = shippingMethodCode.join('_');
-                $.each(rates(), function (key, entity) {
-                    if (entity['carrier_code'] === carrierCode && entity['method_code'] === methodCode) {
-                        shippingMethodTitle = entity['carrier_title'] + " - " + entity['method_title'];
-                    }
-                });
-                return shippingMethodTitle;
+
+            /**
+             * Get shipping method title
+             *
+             * @param shippingMethod
+             * @returns {string}
+             */
+            getTitleByCode: function(shippingMethod) {
+                return shippingMethod ? shippingMethod.carrier_title + " - " + shippingMethod.method_title : '';
             },
+
             getRateByCode : function(methodCodeParts) {
                 var shippingRates = [],
                     shippingMethodCode = methodCodeParts.slice(0),
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/step-navigator.js b/app/code/Magento/Checkout/view/frontend/web/js/model/step-navigator.js
index 44a48fa893285ea45161b23c6a402466921a1f06..0ce40c7999a80c32cfdb08b3c0ece8a261df3bdb 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/model/step-navigator.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/step-navigator.js
@@ -7,198 +7,89 @@
 define(
     [
         'jquery',
-        'ko',
-        'Magento_Customer/js/model/customer',
-        'Magento_Ui/js/model/errorlist'
+        'ko'
     ],
-    function($, ko, customer, errorList) {
-        var customerIsLoggedIn = customer.isLoggedIn()();
-        var defaultStepClass = 'section';
-        var allowedStepClass = 'allow';
-        var activeStepClass = 'active';
+    function($, ko) {
+        var steps = ko.observableArray();
+
         return {
-            currentStep: null,
-            steps: [
-                {
-                    name: 'authentication',
-                    isVisible: ko.observable(!customerIsLoggedIn),
-                    isEnabled: true,
-                    number: ko.observable(1),
-                    classAttributes: ko.observable(defaultStepClass)
-                },
-                {
-                    name: 'billingAddress',
-                    isVisible: ko.observable(customerIsLoggedIn),
-                    isEnabled: true,
-                    number: ko.observable(2),
-                    classAttributes: ko.observable(defaultStepClass)
-                },
-                {
-                    name: 'shippingAddress',
-                    isVisible: ko.observable(false),
-                    isEnabled: true,
-                    number: ko.observable(3),
-                    classAttributes: ko.observable(defaultStepClass)
-                },
-                {
-                    name: 'shippingMethod',
-                    isVisible: ko.observable(false),
-                    isEnabled: true,
-                    number: ko.observable(4),
-                    classAttributes: ko.observable(defaultStepClass)
-                },
-                {
-                    name: 'paymentMethod',
-                    isVisible: ko.observable(false),
-                    isEnabled: true,
-                    number: ko.observable(5),
-                    classAttributes: ko.observable(defaultStepClass)
-                },
-                {
-                    name: 'review',
-                    isVisible: ko.observable(false),
-                    isEnabled: true,
-                    number: ko.observable(6),
-                    classAttributes: ko.observable(defaultStepClass)
-                }
-            ],
-            setCurrent: function(step) {
-                this.currentStep = step;
-                return this;
-            },
-            getCurrentStep: function() {
-                if (!this.currentStep) {
-                    alert('Current step not set.');
-                    return;
-                }
-                var self = this;
-                var currentStep = null;
-                $.each(this.steps, function(key, step) {
-                    if (self.currentStep == step.name) {
-                        currentStep = step;
-                    }
+            steps: steps,
+            stepCodes: [],
+            registerStep: function(code, title, isVisible, sortOrder) {
+                steps.push({
+                    code: code,
+                    title : title,
+                    isVisible: isVisible,
+                    sortOrder: sortOrder
                 });
-                return currentStep;
-            },
-            goNext: function() {
-                var currentStep = this.getCurrentStep();
-                var nextStepOrder = currentStep.number() + 1;
-                var nextStep = null;
-                $.each(this.steps, function(key, item) {
-                    if (nextStepOrder == item.number()) {
-                        nextStep = item;
-                        return false;
+                this.stepCodes.push(code);
+            },
+
+            sortItems: function(itemOne, itemTwo) {
+                return itemOne.sortOrder > itemTwo.sortOrder ? 1 : -1
+            },
+
+            getActiveItemIndex: function() {
+                var activeIndex = 0;
+                steps.sort(this.sortItems).forEach(function(element, index) {
+                    if (element.isVisible()) {
+                        activeIndex = index;
                     }
                 });
-                if (nextStep) {
-                    this.toStep(nextStep.name);
-                }
-            },
-            goBack: function() {
-                var currentStep = this.getCurrentStep();
-                var prevStepOrder = currentStep.number() - 1;
-                var previousStep = null;
-                $.each(this.steps, function(key, item) {
-                    if (prevStepOrder == item.number()) {
-                        previousStep = item;
-                        return false;
-                    }
-                });
-                if (previousStep) {
-                    this.toStep(previousStep.name);
-                }
-            },
-            getStepClassAttributes: function(name) {
-                return this.findStepByName(name).classAttributes;
-            },
-            setStepClassAttributes: function(name) {
-                var stepClass = defaultStepClass;
-                var step = this.findStepByName(name);
-                if (step.isVisible()) {
-                    stepClass += ' ' + activeStepClass;
-                }
-                if (this.isStepAvailable(step.name)) {
-                    stepClass += ' ' + allowedStepClass;
-                }
-                step.classAttributes(stepClass);
-            },
-            updateStepsClassAttributes: function() {
-                var self = this;
-                $.each(this.steps, function(key, step) {
-                    var stepClass = defaultStepClass;
-                    if (step.isVisible()) {
-                        stepClass += ' ' + activeStepClass;
-                    }
-                    if (self.isStepAvailable(step.name)) {
-                        stepClass += ' ' + allowedStepClass;
+                return activeIndex;
+            },
+
+            isProcessed: function(code) {
+                var activeItemIndex = this.getActiveItemIndex();
+                var sortedItems = steps.sort(this.sortItems);
+                var requestedItemIndex = -1;
+                sortedItems.forEach(function(element, index) {
+                    if (element.code == code) {
+                        requestedItemIndex = index;
                     }
-                    step.classAttributes(stepClass);
                 });
+                return activeItemIndex > requestedItemIndex;
             },
-            isStepAvailable: function(name) {
-                var visibleStep = this.getCurrentVisibleStep();
-                var step = this.findStepByName(name);
-                return (step.number() < visibleStep.number());
-            },
-            goToStep: function(name) {
-                if (this.isStepAvailable(name)) {
-                    this.toStep(name);
-                }
-            },
-            toStep: function(name) {
-                if (name) {
-                    $.each(this.steps, function(key, step) {
-                        step.isVisible(false);
-                    });
-                    this.findStepByName(name).isVisible(true);
-                    this.updateStepsClassAttributes();
-                    errorList.clear();
+
+            navigateTo: function(step) {
+                var sortedItems = steps.sort(this.sortItems);
+                if (!this.isProcessed(step.code)) {
+                    return;
                 }
-            },
-            findStepByName: function(name) {
-                var step = null;
-                $.each(this.steps, function(key, currentStep) {
-                    if (name == currentStep.name) {
-                        step = currentStep;
-                        return false;
+                sortedItems.forEach(function(element) {
+                    if (element.code == step.code) {
+                        element.isVisible(true);
+                    } else {
+                        element.isVisible(false);
                     }
+
                 });
-                return step;
             },
-            isStepVisible: function(step) {
-                this.setStepClassAttributes(step);
-                return this.findStepByName(step).isVisible;
-            },
-            setStepVisible: function(step, flag) {
-                this.findStepByName(step).isVisible(flag);
-            },
-            getCurrentVisibleStep: function() {
-                var step = null;
-                $.each(this.steps, function(key, currentStep) {
-                    if (currentStep.isVisible()) {
-                        step = currentStep;
-                        return false;
+
+            next: function() {
+                var activeIndex = 0;
+                steps.sort(this.sortItems).forEach(function(element, index) {
+                    if (element.isVisible()) {
+                        element.isVisible(false);
+                        activeIndex = index;
                     }
                 });
-                return step;
-            },
-            setStepEnabled: function(step, flag) {
-                this.findStepByName(step).isEnabled = flag;
-                this.refreshStepsNumbers();
+                if (steps().length > activeIndex + 1) {
+                    steps()[activeIndex + 1].isVisible(true);
+                }
             },
-            refreshStepsNumbers: function() {
-                var numb = 1;
-                $.each(this.steps, function(key, item) {
-                    if (item.isEnabled) {
-                        item.number(numb);
-                        numb++;
-                    } else {
-                        item.number(null);
+
+            back: function() {
+                var activeIndex = 0;
+                steps.sort(this.sortItems).forEach(function(element, index) {
+                    if (element.isVisible()) {
+                        element.isVisible(false);
+                        activeIndex = index;
                     }
                 });
-            },
-            getStepNumber: function(name) {
-                return this.findStepByName(name).number;
+                if (steps()[activeIndex - 1]) {
+                    steps()[activeIndex - 1].isVisible(true);
+                }
             }
         };
     }
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js b/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js
new file mode 100644
index 0000000000000000000000000000000000000000..f32c0d2c15f3c40a2ea1468ac5c13d0e4b74da90
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/model/totals.js
@@ -0,0 +1,37 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(
+    [
+        'ko',
+        'Magento_Checkout/js/model/quote'
+    ],
+    function(ko, quote) {
+
+        return {
+            totals: quote.totals,
+            isLoading: ko.observable(false),
+            getItems: function() {
+                if (!this.totals() || !this.totals().items) {
+                    return [];
+                }
+                return this.totals().items;
+            },
+            getSegment: function(code) {
+                if (!this.totals()) {
+                    return null;
+                }
+                for (var i in this.totals().total_segments) {
+                    var total = this.totals().total_segments[i];
+                    if (total.code == code) {
+                        return total;
+                    }
+                }
+                return null;
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/proceed-to-checkout.js b/app/code/Magento/Checkout/view/frontend/web/js/proceed-to-checkout.js
new file mode 100644
index 0000000000000000000000000000000000000000..87794967ddff9501e2fba69a01fa8644decf056c
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/proceed-to-checkout.js
@@ -0,0 +1,27 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+define([
+        'jquery',
+        'Magento_Checkout/js/model/cart/authentication-popup',
+        'Magento_Customer/js/customer-data'
+    ],
+    function($, authenticationPopup, customerData) {
+        return function (config, element) {
+            $(element).click(function(event) {
+                event.preventDefault();
+                var cart = customerData.get('cart'),
+                    customer = customerData.get('customer');
+
+                if (customer() == false && !cart().isGuestCheckoutAllowed) {
+                    authenticationPopup.showModal();
+                    return false;
+                }
+                location.href = window.checkout.checkoutUrl;
+            });
+
+        };
+    }
+);
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 2455c3932eabaeee72ba2ec5997a0ed9a35b5732..5f93022da11a9089f3ef90ebef20ef2057529a56 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js
@@ -6,9 +6,11 @@
 /*global confirm:true*/
 define([
     "jquery",
+    'Magento_Checkout/js/model/cart/authentication-popup',
+    'Magento_Customer/js/customer-data',
     "jquery/ui",
     "mage/decorate"
-], function($){
+], function($, authenticationPopup, customerData){
 
     $.widget('mage.sidebar', {
         options: {
@@ -32,6 +34,13 @@ define([
             });
 
             $(this.options.button.checkout).on('click', $.proxy(function() {
+                var cart = customerData.get('cart'),
+                    customer = customerData.get('customer');
+
+                if (customer() == false && !cart().isGuestCheckoutAllowed) {
+                    authenticationPopup.showModal();
+                    return false;
+                }
                 location.href = this.options.url.checkout;
             }, this));
 
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/authentication.js b/app/code/Magento/Checkout/view/frontend/web/js/view/authentication.js
index 44018161f3eeabaf1969bd9e06558db266b13fd7..b921592e718ca5fc134113209f8a39e2624f68d3 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/authentication.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/authentication.js
@@ -6,66 +6,43 @@
 /*global alert*/
 define(
     [
-        "jquery",
-        'ko',
+        'jquery',
         'Magento_Ui/js/form/form',
         'Magento_Customer/js/action/login',
         'Magento_Customer/js/model/customer',
-        'Magento_Checkout/js/model/step-navigator',
-        '../model/quote',
         'mage/validation'
     ],
-    function($, ko, Component, login, customer, navigator, quote) {
-        "use strict";
-        var stepName = 'authentication';
+    function($, Component, loginAction, customer) {
+        'use strict';
+        var checkoutConfig = window.checkoutConfig;
+
         return Component.extend({
-            stepNumber: navigator.getStepNumber(stepName),
-            isGuestCheckoutAllowed: window.checkoutConfig.isGuestCheckoutAllowed,
-            isCustomerLoginRequired: window.checkoutConfig.isCustomerLoginRequired,
-            registerUrl: window.checkoutConfig.registerUrl,
-            forgotPasswordUrl: window.checkoutConfig.forgotPasswordUrl,
-            username: '',
-            password: '',
-            isVisible: navigator.isStepVisible(stepName),
+            isGuestCheckoutAllowed: checkoutConfig.isGuestCheckoutAllowed,
+            isCustomerLoginRequired: checkoutConfig.isCustomerLoginRequired,
+            registerUrl: checkoutConfig.registerUrl,
+            forgotPasswordUrl: checkoutConfig.forgotPasswordUrl,
             defaults: {
                 template: 'Magento_Checkout/authentication'
             },
+
+            /** Is login form enabled for current customer */
+            isActive: function() {
+                return !customer.isLoggedIn();
+            },
+
+            /** Provide login action */
             login: function(loginForm) {
-                var loginData = {};
-                var formDataArray = $(loginForm).serializeArray();
-                var loginFormSelector = 'form[data-role=login]';
+                var loginData = {},
+                    formDataArray = $(loginForm).serializeArray();
+
                 formDataArray.forEach(function (entry) {
                     loginData[entry.name] = entry.value;
                 });
-                if($(loginFormSelector).validation() && $(loginFormSelector).validation('isValid')) {
-                    login(loginData);
-                }
-            },
-            stepClassAttributes: function() {
-                return navigator.getStepClassAttributes(stepName);
-            },
-            isActive: function() {
-                if (customer.isLoggedIn()()) {
-                    navigator.setStepEnabled(stepName, false);
-                }
-                return !customer.isLoggedIn()();
-            },
-            isChecked: function() {
-                if (!isGuestCheckoutAllowed) {
-                    return 'register';
-                }
-                return false;
-            },
-            setCheckoutMethod: function() {
-                quote.setCheckoutMethod('guest');
-                $('[name="customerDetails.password"]').hide();
-                $('[name="customerDetails.confirm_password"]').hide();
-                $('[name*=".save_in_address_book"]').hide();
-                navigator.setCurrent('authentication').goNext();
-            },
-            navigateToCurrentStep: function() {
-                if (!navigator.isStepVisible(stepName)()) {
-                    navigator.goToStep(stepName);
+
+                if($(loginForm).validation()
+                    && $(loginForm).validation('isValid')
+                ) {
+                    loginAction(loginData);
                 }
             }
         });
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/beforePlaceOrder.js b/app/code/Magento/Checkout/view/frontend/web/js/view/beforePlaceOrder.js
index b84bed5619b32ec51ddd662dee71f4c65926f0c7..8424c7a9161db3a2eaefb81515920bc1d8202b9f 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/beforePlaceOrder.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/beforePlaceOrder.js
@@ -9,7 +9,6 @@ define(
         "use strict";
         return Component.extend({
             defaults: {
-                template: 'Magento_Checkout/review/iterator',
                 displayArea: 'beforePlaceOrder'
             }
         });
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 ebb20378def25789c4011acbd530a9b6e62da8ee..2ca86001d726002b81df9f2c6adc83bac7443080 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
@@ -6,127 +6,112 @@
 /*global define*/
 define(
     [
-        "jquery",
-        'Magento_Ui/js/form/form',
         'ko',
+        'Magento_Ui/js/form/form',
         'Magento_Customer/js/model/customer',
-        '../action/select-billing-address',
-        '../model/step-navigator',
-        '../model/quote',
-        '../model/addresslist'
+        'Magento_Customer/js/model/address-list',
+        'Magento_Checkout/js/model/quote',
+        'Magento_Checkout/js/action/create-billing-address',
+        'Magento_Checkout/js/action/select-billing-address',
+        'mage/translate'
     ],
-    function ($, Component, ko, customer, selectBillingAddress, navigator, quote, addressList) {
+    function (ko, Component, customer, addressList, quote, createBillingAddress, selectBillingAddress, $t) {
         "use strict";
-        var stepName = 'billingAddress';
-        var newAddressSelected = ko.observable(false);
-        var billingFormSelector = '#co-billing-form';
+
+        var newAddressOption = {
+            getAddressInline: function() {
+                return $t('New Address');
+            },
+            customerAddressId: null
+        };
+        var addressOptions = addressList().filter(function(address, index, addresses) {
+            return address.getType() == 'customer-address';
+        });
+        addressOptions.push(newAddressOption);
 
         return Component.extend({
             defaults: {
                 template: 'Magento_Checkout/billing-address'
             },
+
             initObservable: function () {
-                this._super().observe('useForShipping');
+                this._super()
+                    .observe({
+                        selectedAddress: null,
+                        isAddressDetailsVisible: quote.shippingAddress() != null,
+                        isAddressFormVisible: !customer.isLoggedIn() || addressOptions.length == 1,
+                        isAddressSameAsShipping: false
+                    });
+                quote.billingAddress.subscribe(function(newAddress) {
+                    this.isAddressSameAsShipping(newAddress == quote.shippingAddress() && !quote.isVirtual());
+                    this.isAddressDetailsVisible(true);
+                }, this);
                 return this;
             },
-            stepClassAttributes: function() {
-                return navigator.getStepClassAttributes(stepName);
-            },
-            stepNumber: navigator.getStepNumber(stepName),
-            billingAddresses: function() {
-                var newAddress = {
-                        getAddressInline: function() {
-                            return $.mage.__('New address');
-                        },
-                        customerAddressId: null
-                    },
-                    addresses = addressList.getAddresses();
-                addresses.push(newAddress);
-                return addresses;
-            },
-            selectedBillingAddressId: ko.observable(
-                addressList.getAddresses().length ? addressList.getAddresses()[0].customerAddressId : null
-            ),
-            isVisible: navigator.isStepVisible(stepName),
-            useForShipping: "1",
-            quoteIsVirtual: quote.isVirtual(),
-            billingAddressesOptionsText: function(item) {
-                return item.getAddressInline();
+
+            canUseShippingAddress: ko.computed(function(){
+                return !quote.isVirtual() && quote.shippingAddress()
+                    && quote.shippingAddress().canUseForBilling();
+            }),
+
+            saveInAddressBook: true,
+
+            currentBillingAddress: quote.billingAddress,
+
+            addressOptions: addressOptions,
+
+            customerHasAddresses: addressOptions.length > 1,
+
+            addressOptionsText: function(address) {
+                return address.getAddressInline();
             },
-            checkUseForShipping: function(useForShipping) {
-                var additionalData = {};
-                if (useForShipping() instanceof Object) {
-                    additionalData = useForShipping().getAdditionalData();
-                    useForShipping('1');
+
+            useShippingAddress: function () {
+                if (this.isAddressSameAsShipping()) {
+                    selectBillingAddress(quote.shippingAddress());
+                    this.isAddressDetailsVisible(true);
+                } else {
+                    this.isAddressDetailsVisible(false);
                 }
-                return additionalData;
+                return true;
             },
-            submitBillingAddress: function() {
-                var additionalData = this.checkUseForShipping(this.useForShipping);
-                if (this.selectedBillingAddressId()) {
-                    selectBillingAddress(
-                        addressList.getAddressById(this.selectedBillingAddressId()),
-                        this.useForShipping,
-                        additionalData
-                    );
+
+            updateAddress: function () {
+                if (this.selectedAddress() && this.selectedAddress() != newAddressOption) {
+                    selectBillingAddress(this.selectedAddress());
                 } else {
-                    this.validate();
+                    this.source.set('params.invalid', false);
+                    this.source.trigger(this.dataScopePrefix + '.data.validate');
                     if (!this.source.get('params.invalid')) {
-                        var addressData = this.source.get('billingAddress');
-                        /**
-                         * All the the input fields that are not a part of the address (e. g. CAPTCHA) but need to be
-                         * submitted in the same request must have data-scope attribute set
-                         */
-                        var additionalFields = $('input[data-scope="additionalAddressData"]').serializeArray();
-                        additionalFields.forEach(function (field) {
-                            additionalData[field.name] = field.value;
-                        });
-                        if (quote.getCheckoutMethod()() && !customer.isLoggedIn()()) {
-                            addressData.email = this.source.get('customerDetails.email');
-                        }
-                        if($(billingFormSelector).validation() && $(billingFormSelector).validation('isValid')) {
-                            selectBillingAddress(addressData, this.useForShipping, additionalData);
+                        var addressData = this.source.get(this.dataScopePrefix);
+
+                        if (this.isCustomerLoggedIn && !this.customerHasAddresses) {
+                            this.saveInAddressBook = true;
                         }
+                        addressData.save_in_address_book = this.saveInAddressBook;
+
+                        // New address must be selected as a billing address
+                        selectBillingAddress(createBillingAddress(addressData));
                     }
                 }
             },
-            navigateToCurrentStep: function() {
-                if (!navigator.isStepVisible(stepName)()) {
-                    navigator.goToStep(stepName);
-                }
-            },
-            isNewAddressSelected: function() {
-                if (!this.customerAddressCount) {
-                    return true;
-                }
-                return newAddressSelected();
-            },
-            onAddressChange: function (value) {
-                value() === null ? newAddressSelected(true) : newAddressSelected(false);
+
+            editAddress: function () {
+                this.isAddressDetailsVisible(false);
             },
-            validate: function() {
-                var fields = $(billingFormSelector).find('input, select');
-
-                this.source.set('params.invalid', false);
-                fields.trigger('change');
-                this.source.trigger('billingAddress.data.validate');
-                if (!customer.isLoggedIn()()) {
-                    this.source.trigger('customerDetails.data.validate');
+
+            cancelAddressEdit: function () {
+                if (quote.billingAddress()) {
+                    // restore 'Same As Shipping' checkbox state
+                    this.isAddressSameAsShipping(
+                        !quote.isVirtual() && (quote.shippingAddress() == quote.billingAddress())
+                    );
+                    this.isAddressDetailsVisible(true);
                 }
-                this.validateAdditionalAddressFields();
             },
-            validateAdditionalAddressFields: function() {
-                $(billingFormSelector).validation();
-                $(billingFormSelector + ' input[data-scope="additionalAddressData"]').each(function(key, item) {
-                    $(item).valid();
-                });
-            },
-            isCustomerLoggedIn: customer.isLoggedIn(),
-            customerAddressCount: window.checkoutConfig.customerAddressCount,
-            hideExtraFields: function() {
-                if (!quote.getCheckoutMethod()() && customer.isLoggedIn()()) {
-                    $('[name="customerDetails.email"]').hide();
-                }
+
+            onAddressChange: function (address) {
+                this.isAddressFormVisible(address == newAddressOption);
             }
         });
     }
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/cart/authentication.js b/app/code/Magento/Checkout/view/frontend/web/js/view/cart/authentication.js
new file mode 100644
index 0000000000000000000000000000000000000000..0985d990a697bde35a780beb7d318895548e9103
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/cart/authentication.js
@@ -0,0 +1,71 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(
+    [
+        'jquery',
+        'ko',
+        'Magento_Ui/js/form/form',
+        'Magento_Customer/js/action/login',
+        'Magento_Customer/js/customer-data',
+        'Magento_Checkout/js/model/cart/authentication-popup',
+        'mage/translate',
+        'mage/validation'
+    ],
+    function($, ko, Component, loginAction, customerData, authenticationPopup, $t) {
+        'use strict';
+        return Component.extend({
+            registerUrl: window.checkout.customerRegisterUrl,
+            forgotPasswordUrl: window.checkout.customerForgotPasswordUrl,
+            modalWindow: null,
+            isLoading: ko.observable(false),
+
+            initialize: function() {
+                var self = this;
+                this._super();
+                loginAction.registerLoginCallback(function() {
+                    self.isLoading(false);
+                });
+            },
+
+            /** Init popup login window */
+            setModalElement: function (element) {
+                authenticationPopup.createPopUp(element);
+            },
+
+            /** Is login form enabled for current customer */
+            isActive: function() {
+                var customer = customerData.get('customer');
+                return customer() == false;
+            },
+
+            /** Show login popup window */
+            showModal: function() {
+                if (this.modalWindow) {
+                    $(this.modalWindow).modal('openModal');
+                } else {
+                    alert($t('Guest checkout is disabled.'));
+                }
+            },
+
+            /** Provide login action */
+            login: function(loginForm) {
+                var loginData = {},
+                    formDataArray = $(loginForm).serializeArray();
+                formDataArray.forEach(function (entry) {
+                    loginData[entry.name] = entry.value;
+                });
+
+                if($(loginForm).validation()
+                    && $(loginForm).validation('isValid')
+                ) {
+                    this.isLoading(true);
+                    loginAction(loginData);
+                }
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/columns.js b/app/code/Magento/Checkout/view/frontend/web/js/view/columns.js
deleted file mode 100644
index 85a2097532024573de71c8f0295bd0f6a2e8dc45..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/columns.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*browser:true*/
-/*global define*/
-define(
-    [
-        'uiComponent'
-    ],
-    function (Component) {
-        "use strict";
-        return Component.extend({
-            defaults: {
-                template: 'Magento_Checkout/review/iterator',
-                displayArea: 'columns'
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/discount.js b/app/code/Magento/Checkout/view/frontend/web/js/view/discount.js
deleted file mode 100644
index f2a959dfcdb510885a209738efc74ef0b8372cf4..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/discount.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*global define*/
-define(
-    [
-        'uiComponent',
-        'Magento_Checkout/js/model/quote',
-        'Magento_Catalog/js/price-utils'
-    ],
-    function (Component, quote, priceUtils) {
-        "use strict";
-        return Component.extend({
-            defaults: {
-                template: 'Magento_Checkout/review/discount',
-                displayArea: 'totals'
-            },
-        colspan: 3,
-        style: '',
-        fieldName: 'Discount',
-        totals: quote.getTotals(),
-        getPureValue: function() {
-            var price = 0;
-            if (this.totals()) {
-                price = this.totals().discount_amount;
-            }
-            return price;
-        },
-        getValue: function() {
-            var price = 0;
-            if (this.totals()) {
-                price = this.totals().discount_amount;
-            }
-            return priceUtils.formatPrice(price, quote.getPriceFormat());
-        }
-        });
-    }
-);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/itemsAfter.js b/app/code/Magento/Checkout/view/frontend/web/js/view/itemsAfter.js
deleted file mode 100644
index ee96966658f05bc7ffb0bbe2aabd5cecb9decdb2..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/itemsAfter.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*browser:true*/
-/*global define*/
-define(
-    [
-        'uiComponent'
-    ],
-    function (Component) {
-        "use strict";
-        return Component.extend({
-            defaults: {
-                template: 'Magento_Checkout/review/iterator',
-                displayArea: 'itemsAfter'
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/itemsBefore.js b/app/code/Magento/Checkout/view/frontend/web/js/view/itemsBefore.js
deleted file mode 100644
index 9d2e10ce0a87aeb5bb847e5eb83e11321d9d3c79..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/itemsBefore.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*browser:true*/
-/*global define*/
-define(
-    [
-        'uiComponent'
-    ],
-    function (Component) {
-        "use strict";
-        return Component.extend({
-            defaults: {
-                template: 'Magento_Checkout/review/iterator',
-                displayArea: 'itemsBefore'
-            }
-        });
-    }
-);
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 373056b389e955be7f910313faf38af2e83cddbb..51e59d8ff6bb31bfb06222c8ef965cbdf19f835d 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
@@ -6,11 +6,13 @@ define([
     'uiComponent',
     'Magento_Customer/js/customer-data',
     'jquery',
-    'ko'
-], function (Component, customerData, $, ko) {
+    'ko',
+    'mage/url'
+], function (Component, customerData, $, ko, url) {
     'use strict';
 
     var sidebarInitialized = false;
+    url.setBaseUrl(window.checkout.baseUrl);
 
     function initSidebar() {
         var minicart = $("[data-block='minicart']");
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/payment.js b/app/code/Magento/Checkout/view/frontend/web/js/view/payment.js
index 313ba3b923d06aa5caf03cef5330f719244471af..cde7e59dad6483cd2f2c95c55b1764403f80f035 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/payment.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/payment.js
@@ -6,154 +6,35 @@
 /*global alert*/
 define(
     [
-        'jquery',
         'uiComponent',
-        '../model/quote',
-        '../action/select-payment-method',
+        'ko',
+        'Magento_Checkout/js/model/quote',
         'Magento_Checkout/js/model/step-navigator',
         'Magento_Checkout/js/model/payment-service',
-        'mage/translate',
-        'mageUtils'
+        'Magento_Checkout/js/model/payment/method-converter'
     ],
-    function ($, Component, quote, selectPaymentMethod, navigator, paymentService, $t, utils) {
-        var stepName = 'paymentMethod';
+    function (Component, ko, quote, stepNavigator, paymentService, methodConverter) {
+        'use strict';
+
+        /** Set payment methods to collection */
+        paymentService.setPaymentMethods(methodConverter(window.checkoutConfig.paymentMethods));
+
         return Component.extend({
             defaults: {
                 template: 'Magento_Checkout/payment',
                 activeMethod: ''
             },
-            stepClassAttributes: function() {
-                return navigator.getStepClassAttributes(stepName);
-            },
-            stepNumber: navigator.getStepNumber(stepName),
-            isVisible: navigator.isStepVisible(stepName),
-            paymentForm: '#co-payment-form',
-            initObservable: function () {
-                this._super()
-                    .observe('activeMethod');
-                return this;
-            },
-            quoteHasShippingMethod: function() {
-                return quote.isVirtual() || quote.getShippingMethod();
-            },
-            setPaymentMethod: function() {
-                if (!this.activeMethod()) {
-                    alert($t('Please choose a payment method.'));
-                    return;
-                }
-
-                if (this.isFormValid()) {
-                    selectPaymentMethod(
-                        this.getPaymentMethodData(),
-                        this.getPaymentMethodInfo(),
-                        this.getPaymentMethodCallbacks()
-                    );
-                }
-            },
-            getPaymentMethodData: function() {
-                var data = {
-                    "method": this.activeMethod(),
-                    "po_number": null,
-                    "cc_owner": null,
-                    "cc_number": null,
-                    "cc_type": null,
-                    "cc_exp_year": null,
-                    "cc_exp_month": null,
-                    "additional_data": null
-                };
-                utils.extend(data, this.getActiveMethodView().getData());
-
-                _.each(this.getAdditionalMethods(), function(elem) {
-                    if (elem.isActive()) {
-                        utils.extend(data, elem.getData());
-                    }
-                });
-
-                return data;
-            },
-            getPaymentMethodInfo: function() {
-                var info = this.getActiveMethodView().getInfo();
-
-                _.each(this.getAdditionalMethods(), function(elem) {
-                    if (elem.isActive()) {
-                        info = _.union(info, elem.getInfo());
-                    }
-                });
-
-                return info;
-            },
-            getPaymentMethodCallbacks: function() {
-                var callbacks = [this.getActiveMethodView().afterSave.bind(this.getActiveMethodView())];
-
-                _.each(this.getAdditionalMethods(), function(elem) {
-                    if (elem.isActive()) {
-                        callbacks = _.union(callbacks, [elem.afterSave.bind(elem)]);
-                    }
-                });
+            isVisible: ko.observable(quote.isVirtual()),
+            quoteIsVirtual: quote.isVirtual(),
 
-                return callbacks;
+            initialize: function () {
+                this._super();
+                stepNavigator.registerStep('billing', 'Review & Payments', this.isVisible, 20);
+                return this;
             },
-            getAvailableViews: function () {
-                var sortedElems = [],
-                    self = this;
-
-                _.each(this.getAvailableMethods(), function (originElem) {
-                    var method = self.getMethodViewByCode(originElem.code);
-                    if (method && method.isAvailable()) {
-                        sortedElems.push(method);
-                    }
-                });
 
-                if (sortedElems.length == 1) {
-                    this.activeMethod(sortedElems[0].getCode());
-                }
-
-                return sortedElems;
-            },
-            getAvailableMethods: function() {
-                return paymentService.getAvailablePaymentMethods();
-            },
-            getAvailableCodes: function() {
-                return _.pluck(this.getAvailableMethods(), 'code');
-            },
-            getMethodViewByCode: function(code) {
-                return _.find(this.getRegion('paymentMethods')(), function(elem) {
-                    return elem.getCode() == code;
-                });
-            },
-            getActiveMethodView: function() {
-                return this.getMethodViewByCode(this.activeMethod());
-            },
-            backToShippingMethod: function() {
-                navigator.setCurrent(stepName).goBack();
-            },
-            navigateToCurrentStep: function() {
-                if (!navigator.isStepVisible(stepName)()) {
-                    navigator.goToStep(stepName);
-                }
-            },
-            isMethodActive: function(code) {
-                return this.activeMethod() === code;
-            },
-            isFormValid: function() {
-                $(this.paymentForm).validation();
-                return $(this.paymentForm).validation('isValid');
-            },
             getFormKey: function() {
                 return window.checkoutConfig.formKey;
-            },
-            getAdditionalMethods: function() {
-                var methods = [];
-                _.each(this.getRegion('beforeMethods')(), function(elem) {
-                    methods = _.union(methods, elem.elems());
-                });
-                _.each(this.getRegion('afterMethods')(), function(elem) {
-                    methods = _.union(methods, elem.elems());
-                });
-                return methods;
-            },
-            getMethodControlAdditionalClass: function() {
-                return this.getAvailableViews().length == 1 ? ' hidden' : '';
             }
         });
     }
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/payment/default.js b/app/code/Magento/Checkout/view/frontend/web/js/view/payment/default.js
new file mode 100644
index 0000000000000000000000000000000000000000..7fa9e10b69a781d1f9afc86bc79ae7cc39c388d7
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/payment/default.js
@@ -0,0 +1,110 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define(
+    [
+        'ko',
+        'jquery',
+        'uiComponent',
+        'Magento_Checkout/js/action/place-order',
+        'Magento_Checkout/js/action/select-payment-method',
+        'Magento_Checkout/js/model/quote',
+        'Magento_Customer/js/model/customer',
+        'Magento_Checkout/js/model/payment-service'
+    ],
+    function (ko, $, Component, placeOrderAction, selectPaymentMethodAction, quote, customer, paymentService) {
+        'use strict';
+        return Component.extend({
+            redirectAfterPlaceOrder: true,
+            /**
+             * Initialize view.
+             *
+             * @returns {Component} Chainable.
+             */
+            initialize: function () {
+                this._super().initChildren();
+                return this;
+            },
+
+            /**
+             * Initialize child elements
+             *
+             * @returns {Component} Chainable.
+             */
+            initChildren: function () {
+                return this;
+            },
+
+            /**
+             * Place order.
+             */
+            placeOrder: function () {
+                var emailValidationResult = customer.isLoggedIn(),
+                    loginFormSelector = 'form[data-role=email-with-possible-login]';
+                if (!customer.isLoggedIn()) {
+                    $(loginFormSelector).validation();
+                    emailValidationResult = Boolean($(loginFormSelector + ' input[name=username]').valid());
+                }
+                if (emailValidationResult && this.validate()) {
+                    placeOrderAction(this.getData(), this.redirectAfterPlaceOrder);
+                }
+            },
+
+            selectPaymentMethod: function() {
+                selectPaymentMethodAction(this.getData());
+                return true;
+            },
+
+            isChecked: ko.computed(function () {
+                return quote.paymentMethod() ? quote.paymentMethod().method : null;
+            }),
+
+            isRadioButtonVisible: ko.computed(function () {
+                return paymentService.getAvailablePaymentMethods().length !== 1;
+            }),
+
+            /**
+             * Get payment method data
+             */
+            getData: function() {
+                return {
+                    "method": this.item.method,
+                    "po_number": null,
+                    "cc_owner": null,
+                    "cc_number": null,
+                    "cc_type": null,
+                    "cc_exp_year": null,
+                    "cc_exp_month": null,
+                    "additional_data": null
+                };
+            },
+
+            /**
+             * Get payment method type.
+             */
+            getTitle: function () {
+                return this.item.title;
+            },
+
+            /**
+             * Get payment method code.
+             */
+            getCode: function () {
+                return this.item.method;
+            },
+
+            validate: function () {
+                return true;
+            },
+
+            getBillingAddressFormName: function() {
+                return 'billing-address-form-' + this.item.method;
+            },
+
+            disposeSubscriptions: function () {
+                // dispose all active subscriptions
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/payment/generic.js b/app/code/Magento/Checkout/view/frontend/web/js/view/payment/generic.js
deleted file mode 100644
index 64833500f70a1919a513cb7b6362bf5cc1655be6..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/payment/generic.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*browser:true*/
-/*global define*/
-define(
-    [
-        'uiComponent'
-    ],
-    function (Component) {
-        return Component.extend({
-            getCode: function() {
-                return this.index;
-            },
-            isActive: function(parent) {
-                return false;
-            },
-            getData: function() {
-                return {};
-            },
-            getInfo: function() {
-                return [];
-            },
-            afterSave: function() {
-                return true;
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/payment/list.js b/app/code/Magento/Checkout/view/frontend/web/js/view/payment/list.js
new file mode 100644
index 0000000000000000000000000000000000000000..78faf6ba156658108f4820978fba27190f2cc9a3
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/payment/list.js
@@ -0,0 +1,119 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'underscore',
+    'ko',
+    'mageUtils',
+    'uiComponent',
+    'Magento_Checkout/js/model/payment/method-list',
+    'Magento_Checkout/js/model/payment/renderer-list',
+    'Magento_Ui/js/core/renderer/layout'
+], function (_, ko, utils, Component, paymentMethods, rendererList, layout) {
+    'use strict';
+
+    return Component.extend({
+        defaults: {
+            template: 'Magento_Checkout/payment-methods/list',
+            visible: paymentMethods().length > 0
+        },
+
+        /**
+         * Initialize view.
+         *
+         * @returns {Component} Chainable.
+         */
+        initialize: function () {
+            this._super().initChildren();
+            paymentMethods.subscribe(
+                function (changes) {
+                    _.each(changes, function (change) {
+                        if (change.status === 'added') {
+                            this.createRenderer(change.value);
+                        } else if (change.status === 'deleted') {
+                            this.removeRenderer(change.value.method);
+                        }
+                    }, this);
+                }, this, 'arrayChange');
+
+            return this;
+        },
+
+        /**
+         * Create renders for child payment methods.
+         *
+         * @returns {Component} Chainable.
+         */
+        initChildren: function () {
+            var self = this;
+            _.each(paymentMethods(), function (paymentMethodData) {
+                self.createRenderer(paymentMethodData);
+            });
+
+            return this;
+        },
+
+        /**
+         * Create renderer.
+         *
+         * @param {Object} paymentMethodData
+         */
+        createRenderer: function (paymentMethodData) {
+            var renderer = this.getRendererByType(paymentMethodData.method),
+                rendererTemplate,
+                rendererComponent,
+                templateData;
+
+            if (renderer) {
+                templateData = {
+                    parentName: this.name,
+                    name: paymentMethodData.method
+                };
+                rendererTemplate = {
+                    parent: '${ $.$data.parentName }',
+                    name: '${ $.$data.name }',
+                    displayArea: 'payment-method-items',
+                    component: renderer.component
+                };
+                rendererComponent = utils.template(rendererTemplate, templateData);
+                utils.extend(rendererComponent, {
+                    item: paymentMethodData
+                });
+                layout([rendererComponent]);
+            }
+        },
+
+        /**
+         * Get renderer for payment method type.
+         *
+         * @param {String} paymentMethodCode
+         * @returns {Object}
+         */
+        getRendererByType: function (paymentMethodCode) {
+            var compatibleRenderer;
+            _.find(rendererList(), function (renderer) {
+                if (renderer.type === paymentMethodCode) {
+                    compatibleRenderer = renderer;
+                }
+            });
+
+            return compatibleRenderer;
+        },
+
+        /**
+         * Remove view renderer.
+         *
+         * @param {String} paymentMethodCode
+         */
+        removeRenderer: function (paymentMethodCode) {
+            var items = this.getRegion('payment-method-items');
+            _.find(items(), function (value) {
+                if (value.item.method === paymentMethodCode) {
+                    value.disposeSubscriptions();
+                    this.removeChild(value);
+                }
+            }, this);
+        }
+    });
+});
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/payment/method-info.js b/app/code/Magento/Checkout/view/frontend/web/js/view/payment/method-info.js
deleted file mode 100644
index c653d3f54111d7f52b031e3376bdc8db84c4dce0..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/payment/method-info.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*browser:true*/
-/*global define*/
-define(
-    [
-        'Magento_Checkout/js/view/payment/generic',
-        '../../model/payment-service'
-    ],
-    function (generic, paymentService) {
-        return generic.extend({
-            defaults: {
-                titleTemplate: 'Magento_Checkout/payment/generic-title',
-                displayArea: 'paymentMethods',
-                isEnabled: true
-            },
-            initObservable: function () {
-                this._super()
-                    .observe('isEnabled');
-                return this;
-            },
-            getMethod: function() {
-                var paymentMethods = _.indexBy(paymentService.getAvailablePaymentMethods(), 'code');
-
-                return paymentMethods[this.getCode()];
-            },
-            isAvailable: function() {
-                return this.getMethod() != null;
-            },
-            getTitle: function() {
-                return this.isAvailable() ? this.getMethod()['title'] : '';
-            },
-            isActive: function(parent) {
-                return this.isAvailable() && parent.isMethodActive(this.getCode());
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/payment/virtual.js b/app/code/Magento/Checkout/view/frontend/web/js/view/payment/virtual.js
deleted file mode 100644
index ec20c4d42179aeee395bec21babff8eda2849516..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/payment/virtual.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*jshint browser:true*/
-/*global define*/
-define(
-    [
-        'ko',
-        'Magento_Checkout/js/view/payment/generic',
-        'Magento_Checkout/js/model/quote'
-    ],
-    function (ko, generic, quote) {
-        return generic.extend({
-            defaults: {
-                isChecked: false
-            },
-            isAvailable: function() {
-                return false;
-            },
-            isOn: function() {
-                return false;
-            },
-            getBalance: function() {
-                return 0;
-            },
-            initObservable: function () {
-                this._super()
-                    .observe('isChecked');
-
-                var self = this;
-                this.isChecked.subscribe(
-                    function(isChecked) {
-                        if (isChecked) {
-                            quote.setCollectedTotals(self.getCode(), -parseFloat(self.getBalance()));
-                        } else {
-                            quote.setCollectedTotals(self.getCode(), 0);
-                        }
-                    }
-                );
-                this.isChecked(this.isOn());
-
-                return this;
-            },
-            isActive: function() {
-                return this.isChecked();
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/progress-bar.js b/app/code/Magento/Checkout/view/frontend/web/js/view/progress-bar.js
new file mode 100644
index 0000000000000000000000000000000000000000..626171c589d3d3aaf6ab2a06e5b3b0884fd8322a
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/progress-bar.js
@@ -0,0 +1,35 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(
+    [
+        'ko',
+        'uiComponent',
+        'Magento_Checkout/js/model/step-navigator'
+    ],
+    function (ko, Component, stepNavigator) {
+        var steps = stepNavigator.steps;
+        return Component.extend({
+            defaults: {
+                template: 'Magento_Checkout/progress-bar',
+                visible: true
+            },
+            steps: steps,
+
+            sortItems: function(itemOne, itemTwo) {
+                return stepNavigator.sortItems(itemOne, itemTwo);
+            },
+
+            navigateTo: function(step) {
+                stepNavigator.navigateTo(step);
+            },
+
+            isProcessed: function(item) {
+                return stepNavigator.isProcessed(item.code);
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/progress.js b/app/code/Magento/Checkout/view/frontend/web/js/view/progress.js
deleted file mode 100644
index 1017f9f160eeaa55c9c306bf42b1c98fd8f6d8f5..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/progress.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*jshint browser:true jquery:true*/
-/*global alert*/
-define(
-    [
-        'ko',
-        'uiComponent',
-        'Magento_Checkout/js/model/step-navigator',
-        'Magento_Checkout/js/model/quote',
-        'Magento_Checkout/js/model/shipping-service',
-        'Magento_Checkout/js/model/payment-service'
-    ],
-    function (ko, Component, navigator, quote, shippingService, paymentService) {
-        var className = ko.observable();
-        return Component.extend({
-            defaults: {
-                template: 'Magento_Checkout/progress'
-            },
-            getClassName: function()
-            {
-                className('opc-block-progress');
-                if(quote.getBillingAddress()() && (quote.getShippingAddress()()) || quote.isVirtual()) {
-                    className('opc-block-progress active')
-                }
-                if (quote.getPaymentMethod()()) {
-                    className('opc-block-progress order-review-step')
-                }
-                return className()
-            },
-
-            isShowStep: function (stepName) {
-                switch(stepName){
-                    case 'shippingAddress':
-                        if (quote.isVirtual()) {
-                            return false
-                        }
-                        return navigator.findStepByName(stepName).isEnabled;
-                        break;
-                    case 'shippingMethod':
-                        if (quote.isVirtual()) {
-                            return false
-                        }
-                        return navigator.findStepByName(stepName).isEnabled;
-                        break;
-                    default:
-                        return navigator.findStepByName(stepName).isEnabled;
-                }
-            },
-            isStepComplete: function(stepName) {
-                switch(stepName){
-                    case 'billingAddress':
-                        return quote.getFormattedBillingAddress()|| false;
-                    break;
-                    case 'shippingAddress':
-                        return quote.getFormattedShippingAddress()||false;
-                    break;
-                    case 'shippingMethod':
-                        return quote.getShippingMethod()||false;
-                    break;
-                    case 'paymentMethod':
-                        return quote.getPaymentMethod()||false;
-                        break;
-                    default:
-                        return false;
-                }
-            },
-            getBillingAddress: function() {
-                return quote.getFormattedBillingAddress()();
-            },
-            getShippingAddress: function() {
-                return quote.getFormattedShippingAddress();
-            },
-            getShippingMethod: function() {
-                return quote.getShippingMethod()
-            },
-            getPaymentMethod: function() {
-                return quote.getPaymentMethod();
-            },
-            getPaymentMethodTitle: function() {
-                var code = this.getPaymentMethod()();
-                return paymentService.getTitleByCode(code)
-            },
-            getPaymentMethodInfo: function() {
-                return paymentService.getSelectedPaymentInfo()
-            },
-            goToStep: function(stepName) {
-                navigator.goToStep(stepName);
-            },
-            getShippingMethodTitle: function() {
-                var code = this.getShippingMethod()();
-                return shippingService.getTitleByCode(code)
-            },
-            getShippingRates: function() {
-                var code = this.getShippingMethod()();
-                return shippingService.getRateByCode(code)
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/review.js b/app/code/Magento/Checkout/view/frontend/web/js/view/review.js
deleted file mode 100644
index c2c9c58333f9f990073680f12e449cb67fd96471..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/review.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*browser:true jquery:true*/
-/*global define*/
-define(
-    [
-        'uiComponent',
-        'Magento_Checkout/js/model/quote',
-        'mage/url',
-        'Magento_Checkout/js/model/step-navigator',
-        'Magento_Checkout/js/action/place-order',
-        'underscore'
-    ],
-    function (Component, quote, url, navigator, orderAction, _) {
-        "use strict";
-        var stepName = 'review';
-        var itemsBefore = [];
-        var itemsAfter = [];
-        var beforePlaceOrder = {};
-        return Component.extend({
-            defaults: {
-                template: 'Magento_Checkout/review'
-            },
-            stepClassAttributes: function() {
-                return navigator.getStepClassAttributes(stepName);
-            },
-            stepNumber: navigator.getStepNumber(stepName),
-            quoteHasPaymentMethod: quote.getPaymentMethod(),
-            itemsBefore: itemsBefore,
-            itemsAfter: itemsAfter,
-            beforePlaceOrder: beforePlaceOrder,
-            getItems: function() {
-                return quote.getTotals()().items;
-            },
-            getColHeaders: function() {
-                return ['name', 'price', 'qty', 'subtotal'];
-            },
-            isVisible: navigator.isStepVisible(stepName),
-            cartUrl: url.build('checkout/cart/'),
-            placeOrder: function(callback) {
-                var component,
-                    isValid = false;
-               if (_.isEmpty(this.beforePlaceOrder)) {
-                   orderAction(null, callback);
-               } else {
-                   for (component in this.beforePlaceOrder) {
-                       if (this.beforePlaceOrder.hasOwnProperty(component) && !this.beforePlaceOrder[component].validate()) {
-                           isValid = true;
-                       }
-                   }
-                   if (isValid) {
-                       orderAction(this.beforePlaceOrder[component].getSubmitParams(), callback);
-                   }
-               }
-            },
-            // get recalculated totals when all data set
-            getTotals: quote.getTotals()
-        });
-    }
-);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/review/actions.js b/app/code/Magento/Checkout/view/frontend/web/js/view/review/actions.js
index e160151929985e6a859950e7c33141c7bead36a1..595871bc061e3c513341892fa5f83300e5a8836f 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/review/actions.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/review/actions.js
@@ -17,7 +17,7 @@ define(
                 displayArea: 'actions'
             },
             getActiveView: function() {
-                var view = this.getViewByCode(quote.getPaymentMethod()());
+                var view = this.getViewByCode(quote.paymentMethod());
                 return view ? view : this.getDefaultView();
             },
             getViewByCode: function(code) {
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/review/item/column.js b/app/code/Magento/Checkout/view/frontend/web/js/view/review/item/column.js
deleted file mode 100644
index 3c80b6595f9ef83703676ed7f2c5954da1fd4ac8..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/review/item/column.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*browser:true*/
-/*global define*/
-define(
-    [
-        'uiComponent',
-        '../../../model/quote',
-        'Magento_Catalog/js/price-utils'
-    ],
-    function (Component, quote, priceUtils) {
-        "use strict";
-        var ownClass = '';
-        var columnTitle = '';
-        return Component.extend({
-            defaults: {
-                headerClass: null,
-                ownClass: ownClass,
-                columnTitle: columnTitle,
-                template: 'Magento_Checkout/review/item/column'
-            },
-            getClass: function() {
-                return 'col ' + this.ownClass;
-            },
-            getHeaderClass: function() {
-                if (this.headerClass) {
-                    return this.headerClass;
-                }
-                return 'col ' + this.ownClass;
-            },
-            getColName: function() {
-                return this.columnTitle;
-            },
-            getValue: function(quoteItem) {
-                return quoteItem.name;
-            },
-            getFormattedPrice: function (price) {
-                return priceUtils.formatPrice(price, quote.getPriceFormat());
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/review/item/columns/price.js b/app/code/Magento/Checkout/view/frontend/web/js/view/review/item/columns/price.js
deleted file mode 100644
index 0066f8cce1c0c39607ece39310b05a4226aba5a0..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/review/item/columns/price.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*jshint browser:true jquery:true*/
-/*global alert*/
-define(
-    [
-        '../column'
-    ],
-    function (column) {
-        "use strict";
-        return column.extend({
-            defaults: {
-                ownClass: 'price',
-                columnTitle: 'Price',
-                template: 'Magento_Checkout/review/item/columns/price'
-            },
-            getValue: function(quoteItem) {
-                return this.getFormattedPrice(quoteItem.price);
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/review/item/columns/qty.js b/app/code/Magento/Checkout/view/frontend/web/js/view/review/item/columns/qty.js
deleted file mode 100644
index c3352464d34e2e54cad7c2ed67b2bf314801915e..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/review/item/columns/qty.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*jshint browser:true jquery:true*/
-/*global alert*/
-define(
-    [
-        '../column'
-    ],
-    function (column) {
-        "use strict";
-        return column.extend({
-            defaults: {
-                ownClass: 'qty',
-                columnTitle: 'Qty',
-                template: 'Magento_Checkout/review/item/columns/qty'
-            },
-            getValue: function(quoteItem) {
-                return quoteItem.qty;
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-address.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-address.js
deleted file mode 100644
index aaa5529851d792e13ed91dcb28c29f66773efd24..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-address.js
+++ /dev/null
@@ -1,165 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*global define*/
-define(
-    [
-        "jquery",
-        'Magento_Ui/js/form/form',
-        'ko',
-        'Magento_Checkout/js/action/select-shipping-address',
-        'Magento_Customer/js/model/customer',
-        '../model/quote',
-        'Magento_Checkout/js/model/step-navigator',
-        '../model/addresslist',
-        'underscore'
-    ],
-    function($, Component, ko, selectShippingAddress, customer, quote, navigator, addressList, _) {
-        'use strict';
-        var stepName = 'shippingAddress';
-        var newAddressSelected = ko.observable(false);
-        return Component.extend({
-            defaults: {
-                template: 'Magento_Checkout/shipping-address',
-                visible: true,
-                formVisible: customer.getShippingAddressList().length === 0
-            },
-            stepClassAttributes: function() {
-                return navigator.getStepClassAttributes(stepName);
-            },
-            stepNumber: navigator.getStepNumber(stepName),
-            addresses: function() {
-                var newAddress = {
-                        getAddressInline: function() {
-                            return $.mage.__('New address');
-                        },
-                        customerAddressId: null
-                    },
-                    addresses = addressList.getAddresses();
-                addresses.push(newAddress);
-                return addresses;
-            },
-            selectedAddressId: ko.observable(
-                addressList.getAddresses().length ? addressList.getAddresses()[0].customerAddressId : null
-            ),
-            sameAsBilling: ko.observable(null),
-            quoteHasBillingAddress: quote.getBillingAddress(),
-            isVisible: navigator.isStepVisible(stepName),
-            initObservable: function () {
-                this._super()
-                    .observe('visible');
-                return this;
-            },
-            isActive: function() {
-                if (quote.isVirtual()) {
-                    navigator.setStepEnabled(stepName, false);
-                }
-                return !quote.isVirtual();
-            },
-            selectShippingAddress: function() {
-                var additionalFields,
-                    addressData,
-                    additionalData = {},
-                    billingAddress = quote.getBillingAddress()();
-
-                if (!billingAddress.customerAddressId || !this.visible()) {
-                    /**
-                     * All the the input fields that are not a part of the address but need to be submitted
-                     * in the same request must have data-scope attribute set
-                     */
-                    additionalFields = $('input[data-scope="additionalAddressData"]').serializeArray();
-                    additionalFields.forEach(function (field) {
-                        additionalData[field.name] = field.value;
-                    });
-                }
-
-                if (!newAddressSelected()) {
-                    selectShippingAddress(
-                        addressList.getAddressById(this.selectedAddressId()),
-                        this.sameAsBilling(),
-                        additionalData
-                    );
-                } else {
-                    if (this.visible()) {
-                        this.validate();
-                    }
-
-                    if (!this.source.get('params.invalid')) {
-                        addressData = this.source.get('shippingAddress');
-                        selectShippingAddress(addressData, this.sameAsBilling(), additionalData);
-                    }
-                }
-            },
-            sameAsBillingClick: function() {
-                var billingAddress,
-                    shippingAddress,
-                    property;
-
-                addressList.isBillingSameAsShipping = !addressList.isBillingSameAsShipping;
-
-                if (this.sameAsBilling()) {
-                    billingAddress = quote.getBillingAddress()();
-
-                    if (billingAddress.customerAddressId) {
-                        this.selectedAddressId(billingAddress.customerAddressId);
-                        newAddressSelected(false);
-
-                    } else {
-                        // copy billing address data to shipping address form if customer uses new address for billing
-                        shippingAddress = this.source.get('shippingAddress');
-
-                        for (property in billingAddress) {
-                            if (billingAddress.hasOwnProperty(property) && shippingAddress.hasOwnProperty(property)) {
-                                if (typeof billingAddress[property] === 'string') {
-                                    this.source.set('shippingAddress.' + property, billingAddress[property]);
-                                } else {
-                                    this.source.set('shippingAddress.' + property, _.clone(billingAddress[property]));
-                                }
-                            }
-                        }
-
-                        this.selectedAddressId(null);
-                        newAddressSelected(true);
-                    }
-                }
-                return true;
-            },
-            onAddressChange: function() {
-                var billingAddress = quote.getBillingAddress();
-
-                if (this.selectedAddressId() !== billingAddress().customerAddressId) {
-                    this.sameAsBilling(false);
-                }
-
-                if (this.selectedAddressId() === null) {
-                    newAddressSelected(true);
-                } else {
-                    newAddressSelected(false);
-                }
-            },
-            // Checkout step navigation
-            backToBilling: function() {
-                navigator.setCurrent(stepName).goBack();
-            },
-            navigateToCurrentStep: function() {
-                if (!navigator.isStepVisible(stepName)()) {
-                    navigator.goToStep(stepName);
-                }
-            },
-            isNewAddressSelected: function() {
-                if (!this.customerAddressCount) {
-                    newAddressSelected(true);
-                    return true;
-                }
-                return newAddressSelected();
-            },
-            validate: function() {
-                this.source.set('params.invalid', false);
-                this.source.trigger('shippingAddress.data.validate');
-            },
-            isCustomerLoggedIn: customer.isLoggedIn(),
-            customerAddressCount: window.checkoutConfig.customerAddressCount
-        });
-    }
-);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-address/address-renderer/default.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-address/address-renderer/default.js
new file mode 100644
index 0000000000000000000000000000000000000000..16ed0dbabc78b5ca4141a2c946b6dec97ed34c69
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-address/address-renderer/default.js
@@ -0,0 +1,53 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define([
+    'jquery',
+    'ko',
+    'uiComponent',
+    'Magento_Checkout/js/action/select-shipping-address',
+    'Magento_Checkout/js/model/quote',
+    'Magento_Checkout/js/model/shipping-address/form-popup-state'
+], function($, ko, Component, selectShippingAddressAction, quote, formPopUpState) {
+    'use strict';
+    var countryData = window.checkoutConfig.countryData;
+    return Component.extend({
+        defaults: {
+            template: 'Magento_Checkout/shipping-address/address-renderer/default'
+        },
+
+        initProperties: function () {
+            this._super();
+            this.isSelected = ko.computed(function() {
+                var isSelected = false;
+                var shippingAddress = quote.shippingAddress();
+                if (shippingAddress) {
+                    isSelected = shippingAddress.getKey() == this.address().getKey();
+                }
+                return isSelected;
+            }, this);
+
+            return this;
+        },
+
+        getCountryName: function(countryId) {
+            return (countryData[countryId] != undefined) ? countryData[countryId].name : "";
+        },
+
+        /** Set selected customer shipping address  */
+        selectAddress: function() {
+            selectShippingAddressAction(this.address());
+        },
+
+        editAddress: function() {
+            formPopUpState.isVisible(true);
+            this.showPopup();
+
+        },
+        showPopup: function() {
+            $('[data-open-modal="opc-new-shipping-address"]').trigger('click');
+        }
+    });
+});
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-address/list.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-address/list.js
new file mode 100644
index 0000000000000000000000000000000000000000..352d8e628e37f4a598115181c8a3c576e56b8ed2
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-address/list.js
@@ -0,0 +1,84 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define([
+    'underscore',
+    'ko',
+    'mageUtils',
+    'uiComponent',
+    'Magento_Ui/js/core/renderer/layout',
+    'Magento_Customer/js/model/address-list'
+], function (_, ko, utils, Component, layout, addressList) {
+    'use strict';
+    var defaultRendererTemplate = {
+        parent: '${ $.$data.parentName }',
+        name: '${ $.$data.name }',
+        component: 'Magento_Checkout/js/view/shipping-address/address-renderer/default'
+    };
+
+    return Component.extend({
+        defaults: {
+            template: 'Magento_Checkout/shipping-address/list',
+            visible: addressList().length > 0,
+            rendererTemplates: []
+        },
+
+        initialize: function () {
+            this._super()
+                .initChildren();
+
+            addressList.subscribe(
+                function(changes) {
+                    var self = this;
+                    changes.forEach(function(change) {
+                        if (change.status === 'added') {
+                           self.createRendererComponent(change.value, change.index);
+                        }
+                    });
+                },
+                this,
+                'arrayChange'
+            );
+            return this;
+        },
+
+        initProperties: function () {
+            this._super();
+            // the list of child components that are responsible for address rendering
+            this.rendererComponents = [];
+            return this;
+        },
+
+        initChildren: function () {
+            _.each(addressList(), this.createRendererComponent, this);
+            return this;
+        },
+
+        /**
+         * Create new component that will render given address in the address list
+         *
+         * @param address
+         * @param index
+         */
+        createRendererComponent: function (address, index) {
+            if (index in this.rendererComponents) {
+                this.rendererComponents[index].address(address);
+            } else {
+                // rendererTemplates are provided via layout
+                var rendererTemplate = (address.getType() != undefined && this.rendererTemplates[address.getType()] != undefined)
+                    ? utils.extend({}, defaultRendererTemplate, this.rendererTemplates[address.getType()])
+                    : defaultRendererTemplate;
+                var templateData = {
+                    parentName: this.name,
+                    name: index
+                };
+                var rendererComponent = utils.template(rendererTemplate, templateData);
+                utils.extend(rendererComponent, {address: ko.observable(address)});
+                layout([rendererComponent]);
+                this.rendererComponents[index] = rendererComponent;
+            }
+        }
+    });
+});
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-information.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-information.js
new file mode 100644
index 0000000000000000000000000000000000000000..d33dd69762f9ca3fab4c12c0ea05108d91e61764
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-information.js
@@ -0,0 +1,37 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(
+    [
+        'jquery',
+        'uiComponent',
+        'Magento_Checkout/js/model/quote',
+        'Magento_Checkout/js/model/shipping-service',
+        'Magento_Checkout/js/model/step-navigator'
+    ],
+    function($, Component, quote, shippingService, stepNavigator) {
+        'use strict';
+        return Component.extend({
+            defaults: {
+                template: 'Magento_Checkout/shipping-information'
+            },
+
+            isVisible: function() {
+                return !quote.isVirtual() && stepNavigator.isProcessed('shipping');
+            },
+
+            getShippingMethodTitle: function() {
+                return shippingService.getTitleByCode(quote.shippingMethod())
+            },
+
+            back: function() {
+                // Temp solution for closing summary sliding panel on mobile MAGETWO-3864
+                $('#opc-sidebar').modal('toggleModal');
+                stepNavigator.back();
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-information/address-renderer/default.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-information/address-renderer/default.js
new file mode 100644
index 0000000000000000000000000000000000000000..9df85f97d84c402e33a2dad71ad1e48bf5b643eb
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-information/address-renderer/default.js
@@ -0,0 +1,20 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define([
+    'uiComponent'
+], function(Component) {
+    'use strict';
+    var countryData = window.checkoutConfig.countryData;
+    return Component.extend({
+        defaults: {
+            template: 'Magento_Checkout/shipping-information/address-renderer/default'
+        },
+
+        getCountryName: function(countryId) {
+            return (countryData[countryId] != undefined) ? countryData[countryId].name : "";
+        }
+    });
+});
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-information/list.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-information/list.js
new file mode 100644
index 0000000000000000000000000000000000000000..36342149c66e6fcc140e5c1d6ab9316c45e26958
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-information/list.js
@@ -0,0 +1,84 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define([
+    'jquery',
+    'ko',
+    'mageUtils',
+    'uiComponent',
+    'Magento_Ui/js/core/renderer/layout',
+    'Magento_Checkout/js/model/quote'
+], function ($, ko, utils, Component, layout, quote) {
+    'use strict';
+    var defaultRendererTemplate = {
+        parent: '${ $.$data.parentName }',
+        name: '${ $.$data.name }',
+        component: 'Magento_Checkout/js/view/shipping-information/address-renderer/default'
+    };
+
+    return Component.extend({
+        defaults: {
+            template: 'Magento_Checkout/shipping-information/list',
+            rendererTemplates: {}
+        },
+
+        initialize: function () {
+            this._super()
+                .initChildren();
+
+            var self = this;
+            quote.shippingAddress.subscribe(function(address) {
+                self.createRendererComponent(address);
+            });
+            return this;
+        },
+
+        initProperties: function () {
+            this._super();
+            // the list of child components that are responsible for address rendering
+            this.rendererComponents = {};
+            return this;
+        },
+
+        initChildren: function () {
+            return this;
+        },
+
+        /**
+         * Create new component that will render given address in the address list
+         *
+         * @param address
+         */
+        createRendererComponent: function (address) {
+
+            $.each(this.rendererComponents, function(index, component) {
+                component.visible(false);
+            });
+
+            if (this.rendererComponents[address.getType()]) {
+                this.rendererComponents[address.getType()].address(address);
+                this.rendererComponents[address.getType()].visible(true);
+            } else {
+                // rendererTemplates are provided via layout
+                var rendererTemplate =
+                    (address.getType() != undefined && this.rendererTemplates[address.getType()] != undefined)
+                    ? utils.extend({}, defaultRendererTemplate, this.rendererTemplates[address.getType()])
+                    : defaultRendererTemplate;
+                var templateData = {
+                    parentName: this.name,
+                    name: address.getType()
+                };
+
+                var rendererComponent = utils.template(rendererTemplate, templateData);
+                utils.extend(
+                    rendererComponent,
+                    {address: ko.observable(address), visible: ko.observable(true)}
+                );
+                layout([rendererComponent]);
+                this.rendererComponents[address.getType()] = rendererComponent;
+            }
+        }
+    });
+});
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-method.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-method.js
deleted file mode 100644
index 29f4ebbca2a04b3d8d9eba738a9c734b3abd112b..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping-method.js
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*jshint browser:true jquery:true*/
-/*global alert*/
-define(
-    [
-        'jquery',
-        'underscore',
-        'uiComponent',
-        '../model/quote',
-        '../model/shipping-service',
-        '../action/select-shipping-method',
-        'Magento_Catalog/js/price-utils',
-        'Magento_Checkout/js/model/step-navigator'
-    ],
-    function ($, _, Component, quote, shippingService, selectShippingMethod, priceUtils, navigator) {
-        var stepName = 'shippingMethod';
-        return Component.extend({
-            defaults: {
-                template: 'Magento_Checkout/shipping-method'
-            },
-            stepClassAttributes: function() {
-                return navigator.getStepClassAttributes(stepName);
-            },
-            stepNumber: navigator.getStepNumber(stepName),
-            rates: shippingService.getSippingRates(),
-            // Checkout step navigation
-            isVisible: navigator.isStepVisible(stepName),
-            quoteHasShippingAddress: function() {
-                return quote.isVirtual() || quote.getShippingAddress();
-            },
-
-            selectedMethod: quote.getSelectedShippingMethod(),
-            verifySelectedMethodCode: function (data) {
-                if (this.selectedMethod() == data) {
-                    return data;
-                }
-                return false;
-            },
-
-            setShippingMethod: function (form) {
-                var item,
-                    customOptions = {};
-                for (item in this.elems()) {
-                    if ('submit' in this.elems()[item]) {
-                        customOptions = _.extend(customOptions, this.elems()[item].submit());
-                    }
-                }
-                form = $(form);
-                var code = form.find("input[name='shipping_method']:checked").val();
-                selectShippingMethod(code, customOptions, this.getAfterSelectCallbacks());
-            },
-            getAfterSelectCallbacks: function() {
-                var callbacks = [];
-                _.each(this.getAdditionalMethods(), function(view) {
-                    if (typeof view.afterSelect === 'function') {
-                        callbacks.push(view.afterSelect);
-                    }
-                });
-                return callbacks;
-            },
-            getAdditionalMethods: function() {
-                var methods = [];
-                _.each(this.getRegion('afterSelect')(), function(elem) {
-                    methods = _.union(methods, elem.elems());
-                });
-                return methods;
-            },
-            isActive: function() {
-                if (quote.isVirtual()) {
-                    navigator.setStepEnabled(stepName, false);
-                }
-                return !quote.isVirtual();
-            },
-            backToShippingAddress: function () {
-                navigator.setCurrent(stepName).goBack();
-            },
-            navigateToCurrentStep: function() {
-                if (!navigator.isStepVisible(stepName)()) {
-                    navigator.goToStep(stepName);
-                }
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js
new file mode 100644
index 0000000000000000000000000000000000000000..7a0b60c760956737ff6d178faaa8528a8754d470
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js
@@ -0,0 +1,241 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [
+        'jquery',
+        'Magento_Ui/js/form/form',
+        'ko',
+        'Magento_Customer/js/model/customer',
+        'Magento_Customer/js/model/address-list',
+        'Magento_Checkout/js/model/address-converter',
+        'Magento_Checkout/js/model/quote',
+        'Magento_Checkout/js/action/create-shipping-address',
+        'Magento_Checkout/js/action/select-shipping-address',
+        'Magento_Checkout/js/model/shipping-rates-validator',
+        'Magento_Checkout/js/model/shipping-address/form-popup-state',
+        'Magento_Checkout/js/model/shipping-service',
+        'Magento_Checkout/js/action/select-shipping-method',
+        'Magento_Checkout/js/model/shipping-rate-registry',
+        'Magento_Checkout/js/action/set-shipping-information',
+        'Magento_Checkout/js/model/new-customer-address',
+        'Magento_Checkout/js/model/step-navigator',
+        'Magento_Ui/js/modal/modal',
+        'mage/translate'
+    ],
+    function(
+        $,
+        Component,
+        ko,
+        customer,
+        addressList,
+        addressConverter,
+        quote,
+        createShippingAddress,
+        selectShippingAddress,
+        shippingRatesValidator,
+        formPopUpState,
+        shippingService,
+        selectShippingMethodAction,
+        rateRegistry,
+        setShippingInformationAction,
+        newAddress,
+        stepNavigator,
+        modal,
+        $t
+    ) {
+        'use strict';
+        var rates = window.checkoutConfig.shippingRates.data,
+            rateKey = window.checkoutConfig.shippingRates.key;
+        var popUp = null;
+        if (addressList().length == 0) {
+            var address = new newAddress({});
+            rateRegistry.set(address.getCacheKey(), rates);
+            shippingService.setShippingRates(rates);
+            selectShippingAddress(address);
+        }
+
+        if (rateKey) {
+            rateRegistry.set(rateKey, rates);
+        }
+
+        selectShippingMethodAction(window.checkoutConfig.selectedShippingMethod);
+        shippingService.setShippingRates(rates);
+
+        return Component.extend({
+            defaults: {
+                template: 'Magento_Checkout/shipping'
+            },
+            visible: ko.observable(!quote.isVirtual()),
+            isCustomerLoggedIn: customer.isLoggedIn,
+            isFormPopUpVisible: formPopUpState.isVisible,
+            isFormInline: addressList().length == 0,
+            isNewAddressAdded: ko.observable(false),
+            saveInAddressBook: true,
+            quoteIsVirtual: quote.isVirtual(),
+
+            initialize: function () {
+                var self = this;
+                this._super();
+                var shippingAddress = quote.shippingAddress();
+                if (!shippingAddress) {
+                    var isShippingAddressInitialized = addressList.some(function (address) {
+                        if (address.isDefaultShipping()) {
+                            selectShippingAddress(address);
+                            return true;
+                        }
+                        return false;
+                    });
+                    if (!isShippingAddressInitialized && addressList().length == 1) {
+                        selectShippingAddress(addressList()[0]);
+                    }
+                }
+                if (rates.length == 1) {
+                    selectShippingMethodAction(rates[0])
+                }
+
+                if (!quote.isVirtual()) {
+                    stepNavigator.registerStep('shipping', 'Shipping', this.visible, 10);
+                }
+
+                this.isFormPopUpVisible.subscribe(function(value) {
+                    if (value) {
+                        self.getPopUp().openModal();
+                    }
+                });
+
+                return this;
+            },
+
+            initElement: function(element) {
+                if (element.index === 'shipping-address-fieldset') {
+                    shippingRatesValidator.bindChangeHandlers(element.elems());
+                }
+            },
+
+            getPopUp: function() {
+                var self = this;
+                if (!popUp) {
+                    var buttons = this.popUpForm.options.buttons;
+                    this.popUpForm.options.buttons = [
+                        {
+                            text: buttons.save.text ? buttons.save.text : $t('Save Address'),
+                            class: buttons.save.class ? buttons.save.class : 'action primary action-save-address',
+                            click: self.saveNewAddress.bind(self)
+                        },
+                        {
+                            text: buttons.cancel.text ? buttons.cancel.text: $t('Cancel'),
+                            class: buttons.cancel.class ? buttons.cancel.class : 'action secondary action-hide-popup',
+                            click: function() {
+                                this.closeModal();
+                            }
+                        }
+                    ];
+                    this.popUpForm.options.closed = function() {
+                        self.isFormPopUpVisible(false);
+                    };
+                    popUp = modal(this.popUpForm.options, $(this.popUpForm.element));
+                }
+                return popUp;
+            },
+
+            /** Show address form popup */
+            showFormPopUp: function() {
+                this.isFormPopUpVisible(true);
+            },
+
+
+            /** Save new shipping address */
+            saveNewAddress: function() {
+                this.source.set('params.invalid', false);
+                this.source.trigger('shippingAddress.data.validate');
+
+                if (!this.source.get('params.invalid')) {
+                    var addressData = this.source.get('shippingAddress');
+                    addressData.save_in_address_book = this.saveInAddressBook;
+
+                    // New address must be selected as a shipping address
+                    selectShippingAddress(createShippingAddress(addressData));
+                    this.getPopUp().closeModal();
+                    this.isNewAddressAdded(true);
+                }
+            },
+
+            /** Shipping Method View **/
+            rates: shippingService.getSippingRates(),
+            isLoading: shippingService.isLoading,
+            isSelected: ko.computed(function () {
+                    return quote.shippingMethod()
+                        ? quote.shippingMethod().carrier_code + '_' + quote.shippingMethod().method_code
+                        : null;
+                }
+            ),
+
+            selectShippingMethod: function(shippingMethod) {
+                selectShippingMethodAction(shippingMethod);
+                return true;
+            },
+
+            setShippingInformation: function () {
+                if (this.validateShippingInformation()) {
+                    setShippingInformationAction().done(
+                        function() {
+                            stepNavigator.next();
+                        }
+                    );
+                }
+            },
+
+            validateShippingInformation: function() {
+                var shippingAddress,
+                    addressData,
+                    loginFormSelector = 'form[data-role=email-with-possible-login]',
+                    emailValidationResult = customer.isLoggedIn();
+
+                if (!quote.shippingMethod()) {
+                    alert($t('Please specify a shipping method'));
+                    return false;
+                }
+
+                if (!customer.isLoggedIn()) {
+                    $(loginFormSelector).validation();
+                    emailValidationResult = Boolean($(loginFormSelector + ' input[name=username]').valid());
+                }
+
+                if (this.isFormInline) {
+                    this.source.set('params.invalid', false);
+                    this.source.trigger('shippingAddress.data.validate');
+                    if (this.source.get('params.invalid')
+                        || !quote.shippingMethod().method_code
+                        || !quote.shippingMethod().carrier_code
+                        || !emailValidationResult
+                    ) {
+                        return false;
+                    }
+                    shippingAddress = quote.shippingAddress();
+                    addressData = addressConverter.formAddressDataToQuoteAddress(
+                        this.source.get('shippingAddress')
+                    );
+
+                    //Copy form data to quote shipping address object
+                    for (var field in addressData) {
+                        if (addressData.hasOwnProperty(field)
+                            && shippingAddress.hasOwnProperty(field)
+                            && typeof addressData[field] != 'function'
+                        ) {
+                            shippingAddress[field] = addressData[field];
+                        }
+                    }
+
+                    if (customer.isLoggedIn()) {
+                        shippingAddress.save_in_address_book = true;
+                    }
+                    selectShippingAddress(shippingAddress);
+                }
+                return true;
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/subtotal.js b/app/code/Magento/Checkout/view/frontend/web/js/view/subtotal.js
deleted file mode 100644
index 227129562f0e58471263236a60dff85ce8a26b0b..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/subtotal.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*global define*/
-define(
-    ['uiComponent'],
-    function (Component) {
-        "use strict";
-        return Component.extend({
-            defaults: {
-                template: 'Magento_Checkout/review/iterator',
-                displayArea: 'totals'
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/onepage.js b/app/code/Magento/Checkout/view/frontend/web/js/view/summary.js
similarity index 53%
rename from app/code/Magento/Checkout/view/frontend/web/js/view/onepage.js
rename to app/code/Magento/Checkout/view/frontend/web/js/view/summary.js
index 1d8f713edc4c829a97086f3df4b7b69a150ec92a..7a97079de6bcdf291c0bddacdf8b9e77efed2ac6 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/onepage.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/summary.js
@@ -2,17 +2,16 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-/*browser:true jquery:true*/
 /*global define*/
 define(
     [
-        'uiComponent'
+        'uiComponent',
+        'Magento_Checkout/js/model/totals'
     ],
-    function (Component) {
+    function(Component, totals) {
+        'use strict';
         return Component.extend({
-            defaults: {
-                template: 'Magento_Checkout/onepage'
-            }
+            isLoading: totals.isLoading
         });
     }
 );
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/summary/abstract-total.js b/app/code/Magento/Checkout/view/frontend/web/js/view/summary/abstract-total.js
new file mode 100644
index 0000000000000000000000000000000000000000..35a4b0071d724572aefb3cc1faaeee68123f3606
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/summary/abstract-total.js
@@ -0,0 +1,31 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [
+        'uiComponent',
+        'Magento_Checkout/js/model/quote',
+        'Magento_Catalog/js/price-utils',
+        'Magento_Checkout/js/model/totals',
+        'Magento_Checkout/js/model/step-navigator'
+    ],
+    function (Component, quote, priceUtils, totals, stepNavigator) {
+        "use strict";
+        return Component.extend({
+            getFormattedPrice: function (price) {
+                return priceUtils.formatPrice(price, quote.getPriceFormat());
+            },
+            getTotals: function() {
+                return totals.totals();
+            },
+            isFullMode: function() {
+                if (!this.getTotals()) {
+                    return false;
+                }
+                return stepNavigator.isProcessed('shipping');
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/summary/cart-items.js b/app/code/Magento/Checkout/view/frontend/web/js/view/summary/cart-items.js
new file mode 100644
index 0000000000000000000000000000000000000000..0a41d2b46f2bfe4ec67d75d470b261e7fe7f3626
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/summary/cart-items.js
@@ -0,0 +1,31 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*browser:true*/
+/*global define*/
+define(
+    [
+        'ko',
+        'Magento_Checkout/js/model/totals',
+        'uiComponent',
+        'Magento_Checkout/js/model/step-navigator',
+        'Magento_Checkout/js/model/quote'
+    ],
+    function (ko, totals, Component, stepNavigator, quote) {
+        'use strict';
+        return Component.extend({
+            defaults: {
+                template: 'Magento_Checkout/summary/cart-items'
+            },
+            totals: totals.totals(),
+            getItems: totals.getItems(),
+            getItemsQty: function() {
+                return parseInt(this.totals.items_qty) || 0;
+            },
+            isItemsBlockExpanded: function () {
+                return quote.isVirtual() || stepNavigator.isProcessed('shipping');
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/summary/grand-total.js b/app/code/Magento/Checkout/view/frontend/web/js/view/summary/grand-total.js
new file mode 100644
index 0000000000000000000000000000000000000000..0f341a847edc1f10af2ed256c115573212899d75
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/summary/grand-total.js
@@ -0,0 +1,32 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [
+        'Magento_Checkout/js/view/summary/abstract-total',
+        'Magento_Checkout/js/model/quote'
+    ],
+    function (Component, quote) {
+        "use strict";
+        return Component.extend({
+            defaults: {
+                template: 'Magento_Checkout/summary/grand-total'
+            },
+            isDisplayed: function() {
+                return this.isFullMode();
+            },
+            getPureValue: function() {
+                var totals = quote.getTotals()();
+                if (totals) {
+                    return totals.grand_total;
+                }
+                return quote.grand_total;
+            },
+            getValue: function() {
+                return this.getFormattedPrice(this.getPureValue());
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/review/item/columns/name.js b/app/code/Magento/Checkout/view/frontend/web/js/view/summary/item/details.js
similarity index 59%
rename from app/code/Magento/Checkout/view/frontend/web/js/view/review/item/columns/name.js
rename to app/code/Magento/Checkout/view/frontend/web/js/view/summary/item/details.js
index 7e04d856621c69cb54018ea1aa937ddfad943163..1c965b0d5701be6269b412b9e825d1499531acca 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/review/item/columns/name.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/summary/item/details.js
@@ -6,15 +6,15 @@
 /*global alert*/
 define(
     [
-        '../column'
+        'uiComponent',
+        '../../../model/quote',
+        'Magento_Catalog/js/price-utils'
     ],
-    function (column) {
+    function (Component, quote, priceUtils) {
         "use strict";
-        return column.extend({
+        return Component.extend({
             defaults: {
-                ownClass: 'name',
-                columnTitle: 'Product Name',
-                template: 'Magento_Checkout/review/item/columns/name'
+                template: 'Magento_Checkout/summary/item/details'
             },
             getValue: function(quoteItem) {
                 return quoteItem.name;
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/review/item/columns/subtotal.js b/app/code/Magento/Checkout/view/frontend/web/js/view/summary/item/details/subtotal.js
similarity index 61%
rename from app/code/Magento/Checkout/view/frontend/web/js/view/review/item/columns/subtotal.js
rename to app/code/Magento/Checkout/view/frontend/web/js/view/summary/item/details/subtotal.js
index f08fb4830a0db1ab8aa6e6e474fc0d83d90e03df..30d43f7369298743b79f1fb9d9d76e0de6c93044 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/review/item/columns/subtotal.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/summary/item/details/subtotal.js
@@ -6,15 +6,14 @@
 /*global alert*/
 define(
     [
-        '../column'
+        'Magento_Checkout/js/view/summary/abstract-total'
     ],
-    function (column) {
+    function (viewModel) {
         "use strict";
-        return column.extend({
+        return viewModel.extend({
             defaults: {
-                ownClass: 'subtotal',
-                columnTitle: 'Subtotal',
-                template: 'Magento_Checkout/review/item/columns/price'
+                displayArea: 'after_details',
+                template: 'Magento_Checkout/summary/item/details/subtotal'
             },
             getValue: function(quoteItem) {
                 return this.getFormattedPrice(quoteItem.row_total);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/summary/item/details/thumbnail.js b/app/code/Magento/Checkout/view/frontend/web/js/view/summary/item/details/thumbnail.js
new file mode 100644
index 0000000000000000000000000000000000000000..2efdc4f91f4b071b79cd916c5cc2e090981e5a29
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/summary/item/details/thumbnail.js
@@ -0,0 +1,52 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(
+    [
+        'uiComponent'
+    ],
+    function (Component) {
+        "use strict";
+        var imageData = window.checkoutConfig.imageData;
+        return Component.extend({
+            defaults: {
+                template: 'Magento_Checkout/summary/item/details/thumbnail'
+            },
+            displayArea: 'before_details',
+            imageData: imageData,
+            getImageItem: function(item) {
+                if (this.imageData[item.item_id]) {
+                    return this.imageData[item.item_id];
+                }
+                return [];
+            },
+            getSrc: function(item) {
+                if (this.imageData[item.item_id]) {
+                    return this.imageData[item.item_id]['src'];
+                }
+                return null;
+            },
+            getWidth: function(item) {
+                if (this.imageData[item.item_id]) {
+                    return this.imageData[item.item_id]['width'];
+                }
+                return null;
+            },
+            getHeight: function(item) {
+                if (this.imageData[item.item_id]) {
+                    return this.imageData[item.item_id]['height'];
+                }
+                return null;
+            },
+            getAlt: function(item) {
+                if (this.imageData[item.item_id]) {
+                    return this.imageData[item.item_id]['alt'];
+                }
+                return null;
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/summary/shipping.js b/app/code/Magento/Checkout/view/frontend/web/js/view/summary/shipping.js
new file mode 100644
index 0000000000000000000000000000000000000000..fdce6d6d37db2bb914517a0dfae21b31e63cdf0f
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/summary/shipping.js
@@ -0,0 +1,39 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(
+    [
+        'jquery',
+        'Magento_Checkout/js/view/summary/abstract-total',
+        'Magento_Checkout/js/model/quote',
+        'Magento_Checkout/js/model/shipping-service'
+    ],
+    function ($, Component, quote, shippingService) {
+        return Component.extend({
+            defaults: {
+                template: 'Magento_Checkout/summary/shipping'
+            },
+            quoteIsVirtual: quote.isVirtual(),
+            totals: quote.getTotals(),
+            getShippingMethodTitle: function() {
+                if (!this.isCalculated()) {
+                    return '';
+                }
+                return shippingService.getTitleByCode(quote.shippingMethod())
+            },
+            isCalculated: function() {
+                return this.totals() && this.isFullMode() && null != quote.shippingMethod();
+            },
+            getValue: function() {
+                if (!this.isCalculated()) {
+                    return this.notCalculatedMessage;
+                }
+                var price =  this.totals().shipping_amount;
+                return this.getFormattedPrice(price);
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/summary/subtotal.js b/app/code/Magento/Checkout/view/frontend/web/js/view/summary/subtotal.js
new file mode 100644
index 0000000000000000000000000000000000000000..b5929a2b60562611adeac62ade8f95608d31ff32
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/summary/subtotal.js
@@ -0,0 +1,30 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [
+        'Magento_Checkout/js/view/summary/abstract-total',
+        'Magento_Checkout/js/model/quote'
+    ],
+    function (Component, quote) {
+        "use strict";
+        return Component.extend({
+            defaults: {
+                template: 'Magento_Checkout/summary/subtotal'
+            },
+            getPureValue: function() {
+                var totals = quote.getTotals()();
+                if (totals) {
+                    return totals.subtotal;
+                }
+                return quote.subtotal;
+            },
+            getValue: function () {
+                return this.getFormattedPrice(this.getPureValue());
+            }
+
+        });
+    }
+);
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/totals.js b/app/code/Magento/Checkout/view/frontend/web/js/view/totals.js
deleted file mode 100644
index caca53e801396ac04e93ebbba53ebe2d4815bbfb..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/totals.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*browser:true*/
-/*global define*/
-define(
-    [
-        'uiComponent'
-    ],
-    function (Component) {
-        "use strict";
-        return Component.extend({
-            defaults: {
-                template: 'Magento_Checkout/review/totals',
-                displayArea: 'totals'
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/authentication.html b/app/code/Magento/Checkout/view/frontend/web/template/authentication.html
index 263249c03824174fbc03630df6581d5e256b0909..f6a1e6e73a2bfcdb356a85b00747775a7d094ed4 100644
--- a/app/code/Magento/Checkout/view/frontend/web/template/authentication.html
+++ b/app/code/Magento/Checkout/view/frontend/web/template/authentication.html
@@ -4,92 +4,81 @@
  * See COPYING.txt for license details.
  */
 -->
-<li id="opc-billing"
-    data-bind="visible: isActive(), attr: {'class': stepClassAttributes() }"
-    role="presentation"
-    data-collapsible="true">
-    <div class="step-title"
-         data-role="title"
-         data-bind="click: navigateToCurrentStep"
-         aria-controls="checkout-step-login"
-         role="tab">
-        <span class="number" data-bind="text: stepNumber()"></span>
-        <h2 data-bind="text: $t('Checkout Method')"></h2>
-    </div>
-    <div id="checkout-step-authentication" class="step-content" data-role="content" data-bind="fadeVisible: isVisible()" >
+<div class="authentication-wrapper" data-block="authentication" data-bind="visible: isActive()">
+    <button
+        type="button"
+        class="action action-auth-toggle"
+        data-trigger="authentication">
+        <span data-bind="text: $t('Sign In')"></span>
+    </button>
+    <div class="block-authentication"
+         style="display: none"
+         data-bind="mageInit: {
+            'Magento_Ui/js/modal/modal':{
+                'type': 'custom',
+                'modalClass': 'authentication-dropdown',
+                'trigger': '[data-trigger=authentication]',
+                'wrapperClass': 'authentication-wrapper',
+                'parentModalClass': '_has-modal-custom _has-auth-shown',
+                'responsive': true,
+                'responsiveClass': 'custom-slide',
+                'overlayClass': 'dropdown-overlay modal-custom-overlay',
+                'buttons': []
+            }}">
         <!-- ko foreach: getRegion('before') -->
         <!-- ko template: getTemplate() --><!-- /ko -->
         <!-- /ko -->
-        <div class="login-wrapper">
-            <!-- ko if: (isGuestCheckoutAllowed) -->
-            <div class="block block-guest">
-                <div class="block-title">
-                    <strong id="block-guest-heading" role="heading" aria-level="2">
-                    <!--ko text: $t('Check Out as a Guest')--><!--/ko-->
-                    </strong>
-                </div>
-                <div class="block-content" aria-labelledby="block-guest-heading">
+        <div class="block block-customer-login"
+             data-bind="attr: {'data-label': $t('or')}">
+            <div class="block-title">
+                <strong id="block-customer-login-heading"
+                        role="heading"
+                        aria-level="2"
+                        data-bind="text: $t('Sign In')"></strong>
+            </div>
+            <div class="block-content" aria-labelledby="block-customer-login-heading">
+                <form data-role="login"
+                      data-bind="submit:login"
+                      method="post">
+                    <div class="fieldset"
+                              data-bind="attr: {'data-hasrequired': $t('* Required Fields')}">
+                        <div class="field field-email required">
+                            <label class="label" for="login-email"><span data-bind="text: $t('Email Address')"></span></label>
+                            <div class="control">
+                                <input type="email"
+                                       class="input-text"
+                                       id="login-email"
+                                       name="username"
+                                       data-validate="{required:true, 'validate-email':true}" />
+                            </div>
+                        </div>
+                        <div class="field field-password required">
+                            <label for="login-password" class="label"><span data-bind="text: $t('Password')"></span></label>
+                            <div class="control">
+                                <input type="password"
+                                       class="input-text"
+                                       id="login-password"
+                                       name="password"
+                                       data-validate="{required:true, 'validate-password':true}"/>
+                            </div>
+                        </div>
+                        <!-- ko foreach: getRegion('additional-login-form-fields') -->
+                        <!-- ko template: getTemplate() --><!-- /ko -->
+                        <!-- /ko -->
+                    </div>
                     <div class="actions-toolbar">
+                        <input name="context" type="hidden" value="checkout" />
                         <div class="primary">
-                            <!-- ko if: (isGuestCheckoutAllowed)-->
-                            <button data-bind="visible: isGuestCheckoutAllowed, click: setCheckoutMethod" data-role="opc-continue" id="onepage-guest-register-button" type="button" class="action continue primary" data-checkout='{"isGuestCheckoutAllowed":true}'><span data-bind="text: $t('Continue')"></span></button>
-                            <!-- /ko -->
-                            <!-- ko ifnot: isGuestCheckoutAllowed -->
-                                <!-- ko if: isCustomerLoginRequired -->
-                                    <input type="checkbox" name="checkout_method" data-role="checkout-method-register" id="login:register" value="register" checked="checked" style="display: none"/>
-                                    <button data-bind="click: setCheckoutMethod" data-role="opc-continue" id="onepage-guest-register-button" type="button" class="action register primary" data-checkout='{"isGuestCheckoutAllowed":false, "registrationUrl":"registerUrl"}'><span data-bind="text: $t('Create an Account')"></span></button>
-                                <!-- /ko -->
-                                <!-- ko ifnot: isCustomerLoginRequired -->
-                                    <input type="checkbox" name="checkout_method" data-role="checkout-method-register" id="login:register" value="register" checked="checked" style="display: none"/>
-                                    <button data-bind="click: setCheckoutMethod" data-role="opc-continue" id="onepage-guest-register-button" type="button" class="action register primary" data-checkout='{"isGuestCheckoutAllowed":true}'><span data-bind="text: $t('Create an Account')"></span></button>
-                                <!-- /ko -->
-                            <!-- /ko -->
+                            <button type="submit" class="action action-login secondary"><span data-bind="text: $t('Sign In')"></span></button>
+                        </div>
+                        <div class="secondary">
+                            <a class="action action-remind" data-bind="attr: { href: forgotPasswordUrl }">
+                                <span data-bind="text: $t('Forgot Password')"></span>
+                            </a>
                         </div>
                     </div>
-                </div>
-            </div>
-            <!-- /ko -->
-            <div class="block block-customer-login">
-                <div class="block-title">
-                    <strong id="block-customer-login-heading" role="heading" aria-level="2" data-bind="text: $t('Login')"></strong>
-                </div>
-                <div class="block-content" aria-labelledby="block-customer-login-heading">
-                    <form class="form login" data-role="login"
-                          data-bind="submit:login"
-                          method="post"
-                          data-mage-init='{"validation":{}}'>
-                        <fieldset class="fieldset login" data-bind="attr: {'data-hasrequired': $t('* Required Fields')}">
-                            <div class="field note" data-bind="text: $t('Already registered? Please sign in below:')"></div>
-                            <div class="field email required">
-                                <label class="label" for="login-email"><span data-bind="text: $t('Email')"></span></label>
-                                <div class="control">
-                                    <input type="email" class="input-text" id="login-email" name="username" data-validate="{required:true, 'validate-email':true}" data-bind="value: username" />
-                                </div>
-                            </div>
-                            <div class="field password required">
-                                <label for="login-password" class="label"><span data-bind="text: $t('Password')"></span></label>
-                                <div class="control">
-                                    <input type="password" class="input-text" id="login-password" name="password" data-bind="value:password" data-validate="{required:true, 'validate-password':true}"/>
-                                </div>
-                            </div>
-                            <!-- ko foreach: getRegion('additional-login-form-fields') -->
-                            <!-- ko template: getTemplate() --><!-- /ko -->
-                            <!-- /ko -->
-                            <div class="actions-toolbar">
-                                <input name="context" type="hidden" value="checkout" />
-                                <div class="primary">
-                                    <button type="submit" class="action login primary" data-action="checkout-method-login"><span data-bind="text: $t('Login')"></span></button>
-                                </div>
-                                <div class="secondary">
-                                    <a class="action remind" data-bind="attr: { href: forgotPasswordUrl }">
-                                        <span data-bind="text: $t('Forgot Your Password?')"></span>
-                                    </a>
-                                </div>
-                            </div>
-                        </fieldset>
-                    </form>
-                </div>
+                </form>
             </div>
         </div>
     </div>
-</li>
+</div>
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 baed4c7b53edbfb4715f8ddc7b3d9d8fe817074c..895f94e4cbd9404a667524f3e5cf29ba142371cd 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,54 +4,23 @@
  * See COPYING.txt for license details.
  */
 -->
-<li id="opc-billing" data-bind="attr: {'class': stepClassAttributes() }" role="presentation">
-    <div class="step-title" data-role="title" data-bind="click: navigateToCurrentStep">
-        <span class="number" data-bind="text: stepNumber()"></span>
-        <h2 data-bind="text: $t('Billing Information')"></h2>
-    </div>
-    <div id="checkout-step-billing" class="step-content" data-role="content" data-bind="fadeVisible: isVisible()">
-        <form class="form billing" id="co-billing-form" data-hasrequired="* Required Fields">
-            <!-- ko if: (customerAddressCount)-->
-            <div class="field addresses">
-                <label class="label" for="billing:address-select"><span data-bind="text: $t('Select a billing address from your address book or enter a new address.')"></span></label>
-                <div class="control">
-                    <select name="billing_address_id" id="billing:address-select" data-bind="
-                        options: billingAddresses(),
-                        optionsText: billingAddressesOptionsText,
-                        optionsValue: 'customerAddressId',
-                        value: selectedBillingAddressId,
-                        event: {change: onAddressChange(selectedBillingAddressId)};
-                    "></select>
-                </div>
-            </div>
-            <!--/ko-->
-            <fieldset id="billing-new-address-form" class="fieldset address"
-                      data-bind="fadeVisible: isNewAddressSelected(), event {change: hideExtraFields()}">
-
-            <!-- ko foreach: getRegion('additional-fieldsets') -->
-            <!-- ko template: getTemplate() --><!-- /ko -->
-            <!--/ko-->
-            </fieldset>
-            <!-- ko if: quoteIsVirtual == 0 -->
-            <div class="field choice">
-                <input type="radio" name="billing[use_for_shipping]" id="billing:use_for_shipping_yes" value="1" checked="checked" class="radio" data-bind="checked: useForShipping" />
-                <label class="label" for="billing:use_for_shipping_yes"><span><!-- ko text: $t('Ship to this address')--><!-- /ko --> </span></label>
-            </div>
-            <div class="field choice">
-                <input type="radio" name="billing[use_for_shipping]" id="billing:use_for_shipping_no" value="0" class="radio" data-bind="checked: useForShipping" />
-                <label class="label" for="billing:use_for_shipping_no"><span><!-- ko text: $t('Ship to different address')--><!-- /ko --></span></label>
-            </div>
-                <!-- ko foreach: getRegion('additional-field-choice') -->
-                    <!-- ko template: getTemplate() --><!-- /ko -->
-                <!-- /ko -->
-            <!-- /ko -->
+<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="text: $t('My billing and shipping address are the same'), attr: {for: 'billing-address-same-as-shipping-' + $parent.getCode()}"></label>
+</div>
 
-            <input type="hidden" name="billing[use_for_shipping]" value="1" />
-            <div class="actions" id="billing-buttons-container">
-                <div class="primary">
-                    <button data-role="opc-continue" type="button" class="action continue primary" data-bind="click: submitBillingAddress"><span><!-- ko text: $t('Continue')--><!-- /ko --></span></button>
-                </div>
-            </div>
-        </form>
+<!-- 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="text: $t('Update')"></span>
+            </button>
+            <button class="action action-cancel" type="button" data-bind="click: cancelAddressEdit">
+                <span data-bind="text: $t('Cancel')"></span>
+            </button>
+        </div>
     </div>
-</li>
+</fieldset>
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html
new file mode 100644
index 0000000000000000000000000000000000000000..3d7d38a0f4aa80de63c750c37b0c489572300055
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html
@@ -0,0 +1,18 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<div class="billing-address-details" data-bind="if: isAddressDetailsVisible() && currentBillingAddress()">
+    <!-- ko text: currentBillingAddress().firstname --><!-- /ko --> <!-- ko text: currentBillingAddress().lastname --><!-- /ko --><br/>
+    <!-- ko text: currentBillingAddress().street --><!-- /ko --><br/>
+    <!-- ko text: currentBillingAddress().city --><!-- /ko -->, <!-- ko text: currentBillingAddress().region --><!-- /ko --> <!-- ko text: currentBillingAddress().postcode --><!-- /ko --><br/>
+
+    <!-- ko text: currentBillingAddress().telephone --><!-- /ko --><br/>
+    <button type="button"
+            class="action action-edit-address"
+            data-bind="visible: !isAddressSameAsShipping(), click: editAddress">
+        <span data-bind="text: $t('Edit')"></span>
+    </button>
+</div>
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/form.html b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/form.html
new file mode 100644
index 0000000000000000000000000000000000000000..4174aa194d635afdd5220f2076a8ac71e985a0a7
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/form.html
@@ -0,0 +1,26 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<div class="billing-address-form" data-bind="fadeVisible: isAddressFormVisible">
+    <!-- ko foreach: getRegion('before-fields') -->
+    <!-- ko template: getTemplate() --><!-- /ko -->
+    <!--/ko-->
+    <form data-hasrequired="* Required Fields">
+        <fieldset id="billing-new-address-form" class="fieldset address">
+            <!-- ko foreach: getRegion('additional-fieldsets') -->
+            <!-- ko template: getTemplate() --><!-- /ko -->
+            <!--/ko-->
+            <!-- ko if: (isCustomerLoggedIn && customerHasAddresses) -->
+            <div class="choice field">
+                <input type="checkbox" class="checkbox" id="billing-save-in-address-book" data-bind="checked: saveInAddressBook" />
+                <label class="label" for="billing-save-in-address-book">
+                    <span data-bind="text: $t('Save in address book')"></span>
+                </label>
+            </div>
+            <!-- /ko -->
+        </fieldset>
+    </form>
+</div>
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/list.html b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/list.html
new file mode 100644
index 0000000000000000000000000000000000000000..f826ede448372134c8e7084dadbc973443492ed0
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/list.html
@@ -0,0 +1,17 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<div class="field field-select-billing">
+    <label class="label"><span data-bind="text: $t('My billing and shipping address are the same')"></span></label>
+    <div class="control" data-bind="if: (addressOptions.length > 1)">
+        <select class="select" name="billing_address_id" data-bind="
+        options: addressOptions,
+        optionsText: addressOptionsText,
+        value: selectedAddress,
+        event: {change: onAddressChange(selectedAddress())};
+    "></select>
+    </div>
+</div>
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/cart/authentication.html b/app/code/Magento/Checkout/view/frontend/web/template/cart/authentication.html
new file mode 100644
index 0000000000000000000000000000000000000000..a2d2941754ff84e19bd81ff0acecce2056ee83d5
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/template/cart/authentication.html
@@ -0,0 +1,89 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<div class="block-authentication"
+     data-bind="afterRender: setModalElement, blockLoader: isLoading"
+     style="display: none">
+    <div class="block block-new-customer"
+         data-label="or">
+        <div class="block-title">
+            <strong id="block-new-customer-heading" role="heading" aria-level="2" data-bind="text: $t('Checkout out as a new customer')"></strong>
+        </div>
+        <div class="block-content" aria-labelledby="block-new-customer-heading">
+            <p data-bind="text: $t('Creating an account has many benefits:')"></p>
+            <ul>
+                <li data-bind="text: $t('See order and shipping status')"></li>
+                <li data-bind="text: $t('Track order history')"></li>
+                <li data-bind="text: $t('Check out faster')"></li>
+            </ul>
+            <div class="actions-toolbar">
+                <div class="primary">
+                    <a class="action action-register primary" data-bind="attr: {href: registerUrl}">
+                        <span data-bind="text: $t('Create Account')"></span>
+                    </a>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="block block-customer-login"
+         data-label="or">
+        <div class="block-title">
+            <strong id="block-customer-login-heading" role="heading" aria-level="2" data-bind="text:$t('Checkout out using your account')"></strong>
+        </div>
+        <!-- ko foreach: getRegion('messages') -->
+        <!-- ko template: getTemplate() --><!-- /ko -->
+        <!--/ko-->
+        <!-- ko foreach: getRegion('before') -->
+        <!-- ko template: getTemplate() --><!-- /ko -->
+        <!-- /ko -->
+        <div class="block-content" aria-labelledby="block-customer-login-heading">
+            <form class="form form-login"
+                  method="post"
+                  data-bind="submit:login"
+                  id="login-form">
+                <div class="fieldset login" data-hasrequired="* Required Fields">
+                    <div class="field email required">
+                        <label class="label" for="email"><span data-bind="text: $t('Email Address')"></span></label>
+                        <div class="control">
+                            <input name="username"
+                                   id="email"
+                                   type="email"
+                                   class="input-text"
+                                   data-validate="{required:true, 'validate-email':true}">
+                        </div>
+                    </div>
+                    <div class="field password required">
+                        <label for="pass" class="label"><span data-bind="text: $t('Password')"></span></label>
+                        <div class="control">
+                            <input name="password"
+                                   type="password"
+                                   class="input-text"
+                                   id="pass"
+                                   data-validate="{required:true, 'validate-password':true}">
+                        </div>
+                    </div>
+                    <!-- ko foreach: getRegion('additional-login-form-fields') -->
+                    <!-- ko template: getTemplate() --><!-- /ko -->
+                    <!-- /ko -->
+                    </div>
+                    <div class="actions-toolbar">
+                        <input name="context" type="hidden" value="checkout" />
+                        <div class="primary">
+                            <button type="submit" class="action action-login secondary" name="send" id="send2">
+                                <span data-bind="text: $t('Sign In')"></span>
+                            </button>
+                        </div>
+                        <div class="secondary">
+                            <a class="action" data-bind="attr: {href: forgotPasswordUrl}">
+                                <span data-bind="text: $t('Forgot Your Password?')"></span>
+                            </a>
+                        </div>
+                    </div>
+                </div>
+            </form>
+        </div>
+    </div>
+</div>
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/minicart/content.html b/app/code/Magento/Checkout/view/frontend/web/template/minicart/content.html
index 82475d90a25234b62a37c5e8c73fd01e5d0d61b8..a2fe08baaa52a4265d71b256b2d675514a380047 100644
--- a/app/code/Magento/Checkout/view/frontend/web/template/minicart/content.html
+++ b/app/code/Magento/Checkout/view/frontend/web/template/minicart/content.html
@@ -98,3 +98,6 @@
         <!-- /ko -->
     </div>
 </div>
+<!-- ko foreach: getRegion('sign-in-popup') -->
+<!-- ko template: getTemplate() --><!-- /ko -->
+<!-- /ko -->
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/minicart/item/default.html b/app/code/Magento/Checkout/view/frontend/web/template/minicart/item/default.html
index 7a5432c380b5579dff032a888203426d61ae03ea..ee9b97ccd8ab3441c0f7942baf948799ea2aba9c 100644
--- a/app/code/Magento/Checkout/view/frontend/web/template/minicart/item/default.html
+++ b/app/code/Magento/Checkout/view/frontend/web/template/minicart/item/default.html
@@ -33,9 +33,9 @@
 
             <!-- ko if: options.length -->
             <div class="product options" data-mage-init='{"collapsible":{"openedState": "active", "saveState": false}}'>
-                <span data-role="title" class="more toggle"><!-- ko text: $t('See Details') --><!-- /ko --></span>
+                <span data-role="title" class="toggle"><!-- ko text: $t('See Details') --><!-- /ko --></span>
 
-                <div data-role="content" class="product options details content">
+                <div data-role="content" class="content">
                     <strong class="subtitle"><!-- ko text: $t('Options Details') --><!-- /ko --></strong>
                     <dl class="product options list">
                         <!-- ko foreach: { data: options, as: 'option' } -->
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/onepage.html b/app/code/Magento/Checkout/view/frontend/web/template/onepage.html
index b05de111621164ef6ff48603fa307eb087c49812..51b80426e5dd4a8fc930916241602f4d28da9681 100644
--- a/app/code/Magento/Checkout/view/frontend/web/template/onepage.html
+++ b/app/code/Magento/Checkout/view/frontend/web/template/onepage.html
@@ -4,19 +4,70 @@
  * See COPYING.txt for license details.
  */
 -->
+<!-- ko foreach: getRegion('authentication') -->
+<!-- ko template: getTemplate() --><!-- /ko -->
+<!--/ko-->
 
-<!-- ko foreach: getRegion('errors') -->
+<!-- ko foreach: getRegion('progressBar') -->
 <!-- ko template: getTemplate() --><!-- /ko -->
 <!--/ko-->
+
+<!-- Temp MAGETWO-36025 markup -->
+<div class="opc-estimated-wrapper">
+<!-- Markup for MAGETWO-38644 -->
+    <div class="estimated-block">
+        <span class="estimated-label" data-bind="text: $t('Estimated Total')"></span>
+        <span class="estimated-price">$100.00</span>
+    </div>
+    <div class="minicart-wrapper">
+        <button type="button" class="action showcart" data-toggle="opc-summary">
+            <span class="counter qty">
+                <span class="counter-number">6</span>
+            </span>
+        </button>
+    </div>
+    <!-- Temp MAGETWO-36025 markup
+    <button
+        type="button"
+        class="action showcart"
+        data-toggle="opc-summary">
+        <span data-bind="text: $t('View order summary')"></span>
+    </button>-->
+</div>
+<!-- /Temp MAGETWO-36025 markup -->
+
+<!-- ko foreach: getRegion('messages') -->
+    <!-- ko template: getTemplate() --><!-- /ko -->
+<!--/ko-->
 <div class="opc-wrapper">
     <ol class="opc" id="checkoutSteps">
     <!-- ko foreach: getRegion('steps') -->
-    <!-- ko template: getTemplate() --><!-- /ko -->
+        <!-- ko template: getTemplate() --><!-- /ko -->
     <!--/ko-->
     </ol>
 </div>
-<div id="checkout-progress-wrapper" class="opc-block-progress-wrapper">
-    <!-- ko foreach: getRegion('progress') -->
-    <!-- ko template: getTemplate() --><!-- /ko -->
+
+<div id="opc-sidebar"
+    data-bind="mageInit: {
+    'Magento_Ui/js/modal/modal':{
+        'type': 'custom',
+        'modalClass': 'opc-sidebar opc-summary-wrapper',
+        'trigger': '[data-toggle=opc-summary]',
+        'wrapperClass': 'checkout-container',
+        'parentModalClass': '_has-modal-custom',
+        'responsive': true,
+        'responsiveClass': 'custom-slide',
+        'overlayClass': 'modal-custom-overlay',
+        'buttons': []
+    }}">
+
+    <!-- ko foreach: getRegion('summary') -->
+        <!-- ko template: getTemplate() --><!-- /ko -->
     <!--/ko-->
+
+    <div class="opc-block-shipping-information">
+        <!-- ko foreach: getRegion('shipping-information') -->
+        <!-- ko template: getTemplate() --><!-- /ko -->
+        <!--/ko-->
+    </div>
 </div>
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/payment-methods/list.html b/app/code/Magento/Checkout/view/frontend/web/template/payment-methods/list.html
new file mode 100644
index 0000000000000000000000000000000000000000..386f34af57ecc0486acaca9b73b2f62cf4fe4f5e
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/template/payment-methods/list.html
@@ -0,0 +1,12 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<div class="items payment-methods">
+    <!-- ko foreach: { data: getRegion('payment-method-items'), as: 'element'}  -->
+        <!-- ko template: element.getTemplate() --><!-- /ko -->
+    <!-- /ko -->
+</div>
+<!-- ko ifnot: getRegion('payment-method-items')().length > 0 --><div class="no-payments-block"><!-- ko text: $t('No Payment Methods')--><!-- /ko --></div><!-- /ko -->
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/payment.html b/app/code/Magento/Checkout/view/frontend/web/template/payment.html
index af29231586341e0e2f2cb46ab944a52f6823b77b..d289eacc124401c39893b337149972af7245254e 100644
--- a/app/code/Magento/Checkout/view/frontend/web/template/payment.html
+++ b/app/code/Magento/Checkout/view/frontend/web/template/payment.html
@@ -4,59 +4,33 @@
  * See COPYING.txt for license details.
  */
 -->
-<li id="opc-payment" data-bind=", attr: {'class': stepClassAttributes() }" role="presentation">
-    <div class="step-title" data-role="title" data-bind="click: navigateToCurrentStep">
-        <span class="number" data-bind="text: stepNumber()"></span>
-        <h2 data-bind="text: $t('Payment Information')"></h2>
-    </div>
+<li id="opc-payment" role="presentation" class="checkout-payment-method" data-bind="fadeVisible: isVisible">
+    <div class="step-title" data-bind="text: $t(title)" data-role="title"></div>
     <div id="checkout-step-payment"
          class="step-content"
          data-role="content"
          role="tabpanel"
-         aria-hidden="false"
-         data-bind="fadeVisible: isVisible() && quoteHasShippingMethod()">
-        <form id="co-payment-form" class="form payments" novalidate="novalidate" data-bind="submit: setPaymentMethod">
+         aria-hidden="false">
+        <!-- ko if: (quoteIsVirtual) -->
+            <!-- ko foreach: getRegion('customer-email') -->
+                <!-- ko template: getTemplate() --><!-- /ko -->
+            <!--/ko-->
+        <!--/ko-->
+        <form id="co-payment-form" class="form payments" novalidate="novalidate">
             <input data-bind='attr: {value: getFormKey()}' type="hidden" name="form_key"/>
             <fieldset class="fieldset">
-                <legend class="legend payments-title">
-                    <span><!-- ko text: $t('Payment Information')--><!-- /ko --></span>`
-                </legend>
-                <br>
                 <!-- ko foreach: getRegion('beforeMethods') -->
                     <!-- ko template: getTemplate() --><!-- /ko -->
                 <!-- /ko -->
                 <div id="checkout-payment-method-load" class="opc-payment">
-                    <dl class="items methods-payment">
-                        <!-- ko foreach: getAvailableViews() -->
-                        <dt data-bind='attr: {class: "item-title " + getCode()}'>
-                            <input data-bind='attr: {id: "p_method_" + getCode(), value: getCode(), title: getTitle(), class: "radio" + $parent.getMethodControlAdditionalClass()}, checked: $parent.activeMethod, enable: isEnabled' type="radio" name="payment[method]"/>
-                            <label data-bind='attr: {for: "p_method_" + getCode()}'><!-- ko template: titleTemplate --><!--/ko--></label>
-                        </dt>
-                        <!-- ko if: $data.formTemplate -->
-                        <dd data-bind='attr: {class: "item-content " + getCode()}, visible: $parent.isMethodActive(getCode()), enable: isEnabled'><!-- ko template: formTemplate --><!--/ko--></dd>
-                        <!-- /ko -->
-                        <!-- /ko -->
-                        <!-- ko ifnot: getAvailableViews().length > 0 -->
-                        <dt class="item-title"><!-- ko text: $t('No Payment Methods')--><!-- /ko --></dt>
-                        <!-- /ko -->
-                    </dl>
+                    <!-- ko foreach: getRegion('payment-methods-list') -->
+                        <!-- ko template: getTemplate() --><!-- /ko -->
+                    <!-- /ko -->
                 </div>
                 <!-- ko foreach: getRegion('afterMethods') -->
                     <!-- ko template: getTemplate() --><!-- /ko -->
                 <!-- /ko -->
             </fieldset>
-            <div class="actions-toolbar" id="payment-buttons-container">
-                <div class="primary">
-                    <button data-role="opc-continue"
-                            type="submit"
-                            class="button action continue primary">
-                        <span><!-- ko text: $t('Continue')--><!-- /ko --></span>
-                    </button>
-                </div>
-                <div class="secondary">
-                    <a class="action back" href="#" data-bind="click: backToShippingMethod"><span>Back</span></a>
-                </div>
-            </div>
         </form>
     </div>
 </li>
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/progress-bar.html b/app/code/Magento/Checkout/view/frontend/web/template/progress-bar.html
new file mode 100644
index 0000000000000000000000000000000000000000..6c13c80261d707b2e8b8930ff8e5642035231b11
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/template/progress-bar.html
@@ -0,0 +1,13 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<ul class="opc-progress-bar">
+    <!-- ko foreach: { data: steps().sort(sortItems), as: 'item' } -->
+        <li class="opc-progress-bar-item" data-bind="css: item.isVisible() ? '_active' : ($parent.isProcessed(item) ? '_complete' : '')">
+            <span data-bind="text: $t(item.title), click: $parent.navigateTo"></span>
+        </li>
+    <!-- /ko -->
+</ul>
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/progress.html b/app/code/Magento/Checkout/view/frontend/web/template/progress.html
deleted file mode 100644
index 2831a845897496816dd57d0fefadecd98b44390d..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/template/progress.html
+++ /dev/null
@@ -1,146 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-    <div data-bind = "attr: {'class': getClassName()}">
-    <div class="title">
-        <strong data-bind="text: $t('Your Checkout Progress')"></strong>
-    </div>
-    <div class="content">
-        <dl class="items">
-            <!-- ko if: isShowStep('billingAddress') -->
-            <!-- ko if: isStepComplete('billingAddress') -->
-            <dt class="item-title complete">
-                <span id="billing-address-label" data-bind="text: $t('Billing Address')"></span>
-                <a href="#billing"
-                   data-goto-section="billing"
-                   class="action billing"
-                   aria-describedby="billing-address-label" data-bind="text: $t('Change'), click: goToStep('billingAddress')">
-                </a>
-            </dt>
-            <dd class="item-content complete">
-                <address data-bind="html:getBillingAddress()"></address>
-            </dd>
-            <!--/ko-->
-            <!-- ko ifnot: isStepComplete('billingAddress') -->
-            <dt class="item-title" data-bind="text: $t('Billing Address')"></dt>
-            <!--/ko-->
-            <!--/ko-->
-
-            <!-- ko if: isShowStep('shippingAddress') -->
-            <!-- ko if: isStepComplete('shippingAddress') -->
-            <dt class="item-title complete">
-                <span id="shipping-address-label" data-bind="text: $t('Shipping Address')"></span>
-                <a href="#payment"
-                   data-goto-section="shipping"
-                   class="action shipping address"
-                   aria-describedby="shipping-address-label" data-bind="text:$t('Change'), click: goToStep('shippingAddress')">
-                </a>
-            </dt>
-            <dd class="item-content complete">
-                <address data-bind="html:getShippingAddress()"></address>
-            </dd>
-            <!--/ko-->
-            <!-- ko ifnot: isStepComplete('shippingAddress') -->
-            <dt class="item-title">
-                <span data-bind="text:$t('Shipping Address')"></span>
-            </dt>
-            <!--/ko-->
-            <!--/ko-->
-
-            <!-- ko if: isShowStep('shippingMethod') -->
-            <!-- ko if: isStepComplete('shippingMethod') -->
-            <dt class="item-title complete">
-                <span id="shipping-method-label" data-bind="text:$t('Shipping Method')"></span>
-                <a href="#shipping_method"
-                   data-goto-section="shipping_method"
-                   class="action shipping method"
-                   aria-describedby="shipping-method-label" data-bind="text:$t('Change'), click: goToStep('shippingMethod')">
-                </a>
-            </dt>
-            <dd class="item-content complete">
-                <!--<?php if ($block->getShippingMethod()): ?>-->
-
-                <!-- ko text: getShippingMethodTitle() --><!--/ko-->
-
-                <!--shipping method price rendering-->
-
-                <!-- ko foreach: {data: getShippingRates(), as: 'item'} -->
-                    <!-- ko foreach: $parent.getRegion('shipping') -->
-                        <!-- ko template: getTemplate() --><!-- /ko -->
-                    <!--/ko-->
-                <!--/ko-->
-
-                <!-- ko ifnot : (getShippingRates().length > 0) -->
-                <!-- ko text: $t('Please choose a shipping method.') --><!--/ko-->
-                <!--/ko-->
-            </dd>
-            <!--/ko-->
-            <!-- ko ifnot: isStepComplete('shippingMethod') -->
-            <dt class="item-title">
-                <span data-bind="text:$t('Shipping Method')"></span>
-            </dt>
-            <!--/ko-->
-            <!--/ko-->
-
-            <!-- ko if: isShowStep('paymentMethod') -->
-            <!-- ko if: isStepComplete('paymentMethod') -->
-            <dt class="item-title complete">
-                <span id="payment-method-label" data-bind="text:$t('Payment Method')"></span>
-                <a href="#payment"
-                   data-goto-section="payment"
-                   class="action payment method"
-                   aria-describedby="payment-method-label" data-bind="text:$t('Change'), click: goToStep('paymentMethod')">
-                </a>
-            </dt>
-            <dd class="item-content complete">
-                <dl class="payment-method">
-                    <dt class="title"><!-- ko text: getPaymentMethodTitle() --><!--/ko--></dt>
-                    <dd class="content">
-                        <!-- ko if: getPaymentMethodInfo().length > 0 -->
-                        <table class="data table">
-                            <tbody data-bind="foreach: {data: getPaymentMethodInfo(), as: 'item'}">
-                            <!-- ko if: item.name && (item.value || item.html) -->
-                            <tr>
-                                <th scope="row" data-bind="html: $t(item.name)"></th>
-                                <!-- ko if: item.value -->
-                                <td data-bind="text: $t(item.value)"></td>
-                                <!--/ko-->
-                                <!-- ko if: !item.value && item.html -->
-                                <td data-bind="html: $t(item.html)"></td>
-                                <!--/ko-->
-                            </tr>
-                            <!--/ko-->
-                            <!-- ko if: item.name && !item.value && !item.html -->
-                            <tr>
-                                <th colspan="2" scope="row"><!-- ko text: $t(item.name) --><!--/ko--></th>
-                            </tr>
-                            <!--/ko-->
-                            <!-- ko if: !item.name && (item.value || item.html) -->
-                            <tr>
-                                <!-- ko if: item.value -->
-                                <td colspan="2" data-bind="text: $t(item.value)"></td>
-                                <!--/ko-->
-                                <!-- ko if: !item.value && item.html -->
-                                <td colspan="2" data-bind="html: $t(item.html)"></td>
-                                <!--/ko-->
-                            </tr>
-                            <!--/ko-->
-                            </tbody>
-                        </table>
-                        <!--/ko-->
-                    </dd>
-                </dl>
-            </dd>
-            <!--/ko-->
-            <!-- ko ifnot: isStepComplete('paymentMethod') -->
-            <dt class="item-title">
-                <span data-bind="text:$t('Payment Method')"></span>
-            </dt>
-            <!--/ko-->
-            <!--/ko-->
-        </dl>
-    </div>
-</div>
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/review.html b/app/code/Magento/Checkout/view/frontend/web/template/review.html
deleted file mode 100644
index 2258e50fd37a2a127040dbc0f3595e80c280012b..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/template/review.html
+++ /dev/null
@@ -1,63 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<li id="opc-review" data-bind="attr: {'class': stepClassAttributes() }" role="presentation">
-    <div class="step-title" data-role="title">
-        <span class="number" data-bind="text: stepNumber()"></span>
-        <h2 data-bind="text: $t('Order Review')"></h2>
-    </div>
-    <div id="checkout-step-review"
-         class="step-content"
-         data-role="content"
-         role="tabpanel"
-         aria-hidden="false"
-         data-bind="fadeVisible: isVisible() && quoteHasPaymentMethod()">
-        <div class="order-review" id="checkout-review-load">
-            <!-- ko foreach: getRegion('itemsBefore') -->
-                <!-- ko template: getTemplate() --><!-- /ko -->
-            <!-- /ko -->
-            <div id="checkout-review-table-wrapper" class="order-review-wrapper table-wrapper">
-                <table class="data table table-order-review items" id="checkout-review-table">
-                    <caption class="table-caption" data-bind="text: $t('Order Review')"></caption>
-                    <thead>
-                        <tr>
-                            <!-- ko foreach: getRegion('columns') -->
-                                <!-- ko foreach: elems() -->
-                                    <th class="col" scope="col" data-bind=" text: $t(getColName()) , attr: { class: getHeaderClass() }" ></th>
-                                <!-- /ko -->
-                            <!-- /ko -->
-                        </tr>
-                    </thead>
-                    <tbody>
-                    <!-- ko foreach: {data: getItems(), as: 'item'} -->
-                        <tr>
-                            <!-- ko foreach: $parent.getRegion('columns') -->
-                                <!-- ko template: getTemplate() --><!-- /ko -->
-                            <!-- /ko -->
-                        </tr>
-                    <!-- /ko -->
-                    </tbody>
-                    <tfoot>
-                    <!-- ko foreach: getRegion('totals') -->
-                    <!-- ko template: getTemplate() --><!-- /ko -->
-                    <!-- /ko -->
-                    </tfoot>
-                </table>
-            </div>
-            <!-- ko foreach: getRegion('itemsAfter') -->
-                <!-- ko template: getTemplate() --><!-- /ko -->
-            <!-- /ko -->
-            <div id="checkout-review-submit" data-mage-init='{"paymentAuthentication":{}}' class="checkout-submit-order">
-                <!-- ko foreach: getRegion('beforePlaceOrder') -->
-                    <!-- ko template: getTemplate() --><!-- /ko -->
-                <!-- /ko -->
-                <!-- ko foreach: getRegion('actions') -->
-                    <!-- ko template: getTemplate() --><!-- /ko -->
-                <!-- /ko -->
-            </div>
-        </div>
-    </div>
-</li>
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/review/discount.html b/app/code/Magento/Checkout/view/frontend/web/template/review/discount.html
deleted file mode 100644
index 3123b421025ed575861d20ea2b6ebc5902df48dd..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/template/review/discount.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<!-- ko if: getPureValue() != 0 -->
-<tr class="totals">
-    <th data-bind="text: $t(fieldName) , attr: {'style':style, 'colspan': colspan}" class="mark" scope="row">
-    </th>
-    <td data-bind="text: getValue(), attr: {'style': style, 'data-th': $t(name) }" class="amount"></td>
-</tr>
-<!-- /ko -->
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/review/item/column.html b/app/code/Magento/Checkout/view/frontend/web/template/review/item/column.html
deleted file mode 100644
index c32d4991c36b0bcacca083ee241d5ca5149f1fa9..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/template/review/item/column.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<td data-bind="attr: { 'data-th': getColName(), class: getClass() }">
-    <span data-bind="text: getValue($parents[1])"></span>
-</td>
\ No newline at end of file
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/review/item/columns/name.html b/app/code/Magento/Checkout/view/frontend/web/template/review/item/columns/name.html
deleted file mode 100644
index 54f6daf92fd94f087ab5c8aba02fe9b7d9585391..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/template/review/item/columns/name.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<td class="col item" data-th="Product Name"><strong class="product name product-item-name" data-bind="text: $t(item.name)"></strong>
-    <!-- ko foreach: elems() -->
-        <!-- ko template: getTemplate() --><!-- /ko -->
-    <!-- /ko -->
-
-    <!-- ko if: (JSON.parse(item.options).length > 0)-->
-    <dl class="item-options">
-        <!--ko foreach: JSON.parse(item.options)-->
-        <dt data-bind="text: $t(label)"></dt>
-            <!-- ko if: ($data.full_view)-->
-            <dd data-bind="html: full_view"></dd>
-            <!-- /ko -->
-            <!-- ko ifnot: ($data.full_view)-->
-            <dd data-bind="html: value"></dd>
-            <!-- /ko -->
-        <!-- /ko -->
-    </dl>
-    <!-- /ko -->
-</td>
\ No newline at end of file
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/review/item/columns/price.html b/app/code/Magento/Checkout/view/frontend/web/template/review/item/columns/price.html
deleted file mode 100644
index 25e9e79a35d89d2487140d9b3b5db518927be2e5..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/template/review/item/columns/price.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<td data-bind="attr: { 'data-th': getColName(), class: getClass() }">
-    <span class="cart-price">
-        <span class="price" data-bind="text: getValue($parents[1])"></span>
-    </span>
-</td>
\ No newline at end of file
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/review/item/columns/qty.html b/app/code/Magento/Checkout/view/frontend/web/template/review/item/columns/qty.html
deleted file mode 100644
index cc5e4d63f7890acb036bb3adb5a681e689df3743..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/template/review/item/columns/qty.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<td class="col qty" data-th="Qty"><span class="qty" data-bind="text: item.qty"></span></td>
\ No newline at end of file
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/review/iterator.html b/app/code/Magento/Checkout/view/frontend/web/template/review/iterator.html
deleted file mode 100644
index 3e2032f2c631a6bebe2e29d02589aa44cae5c0dc..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/template/review/iterator.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-
-<!-- ko foreach: elems() -->
-    <!-- ko template: getTemplate() --><!-- /ko -->
-<!-- /ko -->
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address.html
deleted file mode 100644
index acd04e1fca45cfca1ead82a33c4d7c34de5637f0..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address.html
+++ /dev/null
@@ -1,62 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<li id="opc-shipping" data-bind="fadeVisible: isActive(), attr: {'class': stepClassAttributes() }">
-    <div class="step-title" data-role="title" data-bind="click: navigateToCurrentStep">
-        <span class="number" data-bind="text: stepNumber()"></span>
-        <h2 data-bind="text: $t('Shipping Information')"></h2>
-    </div>
-    <div id="checkout-step-shipping"
-         class="step-content"
-         data-role="content"
-         data-bind="fadeVisible: isVisible() && quoteHasBillingAddress()">
-        <form class="form shipping address" id="co-shipping-form" data-hasrequired="* Required Fields">
-            <!-- ko foreach: getRegion('before-fields') -->
-            <!-- ko template: getTemplate() --><!-- /ko -->
-            <!--/ko-->
-            <!-- ko if: (customerAddressCount)-->
-            <div class="field addresses" data-bind="visible: visible">
-                <label class="label" for="shipping:address-select"><span data-bind="text: $t('Select a shipping address from your address book or enter a new address.')"></span></label>
-                <div class="control">
-                    <select name="shipping_address_id" id="shipping:address-select" data-bind="
-                    options: addresses(),
-                    optionsText: function(item) { return item.getAddressInline(); },
-                    optionsValue: 'customerAddressId',
-                    value: selectedAddressId,
-                    event: {change: onAddressChange}
-                    ">
-                    </select>
-                </div>
-            </div>
-            <!-- /ko -->
-            <fieldset id="shipping-new-address-form" class="fieldset address"
-                      data-bind="fadeVisible: isNewAddressSelected(), visible: formVisible">
-            <!-- ko foreach: getRegion('additional-fieldsets') -->
-            <!-- ko template: getTemplate() --><!-- /ko -->
-            <!--/ko-->
-            </fieldset>
-
-            <div class="choice field" data-bind="visible: visible">
-                <input type="checkbox"
-                       name="shipping[same_as_billing]"
-                       id="shipping:same_as_billing"
-                       value="1"
-                       checked="checked"
-                       class="checkbox"
-                       data-bind="checked: sameAsBilling, click: sameAsBillingClick"/>
-                <label class="label" for="shipping:same_as_billing">
-                    <span data-bind="text: $t('Use Billing Address')"></span>
-                </label>
-            </div>
-            <div class="actions-toolbar" id="shipping-buttons-container">
-                <div class="primary">
-                    <button data-role="opc-continue" type="button" class="action continue primary" data-bind="click: selectShippingAddress"><span data-bind="text: $t('Continue')"></span></button>
-                </div>
-                <div class="secondary"><a href="#" class="action back" data-bind="click: backToBilling"><span data-bind="text: $t('Back')"></span></a></div>
-            </div>
-        </form>
-    </div>
-</li>
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html
new file mode 100644
index 0000000000000000000000000000000000000000..af87b5805b51e16afb0fec1d006c170325f1675c
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html
@@ -0,0 +1,21 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<div class="shipping-address-item" data-bind="css: isSelected() ? 'selected-item' : 'not-selected-item'">
+    <!-- ko text: address().firstname --><!-- /ko --> <!-- ko text: address().lastname --><!-- /ko --><br/>
+    <!-- ko text: address().street --><!-- /ko --><br/>
+    <!-- ko text: address().city --><!-- /ko -->, <!-- ko text: address().region --><!-- /ko --> <!-- ko text: address().postcode --><!-- /ko --><br/>
+    <!-- ko text: getCountryName(address().countryId) --><!-- /ko --><br/>
+    <!-- ko text: address().telephone --><!-- /ko --><br/>
+    <button type="button"
+            class="action edit-address-link"
+            data-bind="click: editAddress, visible: address().isEditable()">
+        <span data-bind="text: $t('Edit')"></span>
+    </button>
+    <button type="button" data-bind="click: selectAddress" class="action action-select-shipping-item">
+        <span data-bind="text: $t('Ship Here')"></span>
+    </button>
+</div>
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/form.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/form.html
new file mode 100644
index 0000000000000000000000000000000000000000..e450ee3fd9c3d04ae0c99208a64b244f3811c055
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/form.html
@@ -0,0 +1,24 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<form class="form form-shipping-address" id="co-shipping-form" data-bind="attr: {'data-hasrequired': $t('* Required Fields')}">
+    <!-- ko foreach: getRegion('before-fields') -->
+    <!-- ko template: getTemplate() --><!-- /ko -->
+    <!--/ko-->
+    <fieldset id="shipping-new-address-form" class="fieldset address">
+        <!-- ko foreach: getRegion('additional-fieldsets') -->
+        <!-- ko template: getTemplate() --><!-- /ko -->
+        <!--/ko-->
+        <!-- ko if: (isCustomerLoggedIn) -->
+        <div class="field choice" data-bind="visible: !isFormInline">
+            <input type="checkbox" class="checkbox" id="shipping-save-in-address-book" data-bind="checked: saveInAddressBook" />
+            <label class="label" for="shipping-save-in-address-book">
+                <span data-bind="text: $t('Save in address book')"></span>
+            </label>
+        </div>
+        <!-- /ko -->
+    </fieldset>
+</form>
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/list.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/list.html
new file mode 100644
index 0000000000000000000000000000000000000000..84b0b3679c69f0b1d3efbf0cdf633bd0ca0519e0
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/list.html
@@ -0,0 +1,18 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+
+<!-- ko if: (visible)-->
+<div class="field addresses">
+    <div class="control">
+        <div class="shipping-address-items">
+            <!-- ko foreach: { data: elems, as: 'element' } -->
+            <!-- ko template: element.getTemplate() --><!-- /ko -->
+            <!-- /ko -->
+        </div>
+    </div>
+</div>
+<!-- /ko -->
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information.html
new file mode 100644
index 0000000000000000000000000000000000000000..6d262c39d9f0cd0bf99259e870819e6ddc63dafe
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information.html
@@ -0,0 +1,35 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+
+<!-- ko if: (isVisible()) -->
+<div class="shipping-information">
+    <div class="ship-to">
+        <div class="shipping-information-title">
+            <span data-bind="text: $t('Ship To')"></span>
+            <button class="action action-edit" data-bind="click: back">
+                <span data-bind="text: $t('edit')"></span>
+            </button>
+        </div>
+        <div class="shipping-information-content">
+            <!-- ko foreach: getRegion('ship-to') -->
+            <!-- ko template: getTemplate() --><!-- /ko -->
+            <!--/ko-->
+        </div>
+    </div>
+    <div class="ship-via">
+        <div class="shipping-information-title">
+            <span data-bind="text: $t('Ship Via')"></span>
+            <button class="action action-edit" data-bind="click: back">
+                <span data-bind="text: $t('edit')"></span>
+            </button>
+        </div>
+        <div class="shipping-information-content">
+            <span class="value" data-bind="text: $t(getShippingMethodTitle())"></span>
+        </div>
+    </div>
+</div>
+<!--/ko-->
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html
new file mode 100644
index 0000000000000000000000000000000000000000..32d832ca3092a32e8b8687325903880ce9274ee6
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html
@@ -0,0 +1,13 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<!-- ko if: (visible()) -->
+    <!-- ko text: address().firstname --><!-- /ko --> <!-- ko text: address().lastname --><!-- /ko --><br/>
+    <!-- ko text: address().street --><!-- /ko --><br/>
+    <!-- ko text: address().city --><!-- /ko -->, <!-- ko text: address().region --><!-- /ko --> <!-- ko text: address().postcode --><!-- /ko --><br/>
+    <!-- ko text: getCountryName(address().countryId) --><!-- /ko --><br/>
+    <!-- ko text: address().telephone --><!-- /ko --><br/>
+<!-- /ko -->
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/review/totals.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/list.html
similarity index 53%
rename from app/code/Magento/Checkout/view/frontend/web/template/review/totals.html
rename to app/code/Magento/Checkout/view/frontend/web/template/shipping-information/list.html
index 3e2032f2c631a6bebe2e29d02589aa44cae5c0dc..c7a1eb499da7079fc81eaf82513fa59a3c3346de 100644
--- a/app/code/Magento/Checkout/view/frontend/web/template/review/totals.html
+++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/list.html
@@ -5,6 +5,6 @@
  */
 -->
 
-<!-- ko foreach: elems() -->
-    <!-- ko template: getTemplate() --><!-- /ko -->
+<!-- ko foreach: { data: elems, as: 'element' } -->
+<!-- ko template: element.getTemplate() --><!-- /ko -->
 <!-- /ko -->
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-method.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-method.html
deleted file mode 100644
index 523c1eb3b34f4c2c47d692b4401f945bbe422471..0000000000000000000000000000000000000000
--- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-method.html
+++ /dev/null
@@ -1,94 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<li id="opc-shipping_method" data-bind="fadeVisible: isActive(), attr: {'class': stepClassAttributes() }" role="presentation">
-    <div class="step-title" data-role="title" data-bind="click: navigateToCurrentStep">
-        <span class="number" data-bind="text: stepNumber()"></span>
-        <h2 data-bind="text: $t('Shipping Method')"></h2>
-    </div>
-    <div id="checkout-step-shipping_method"
-         class="step-content"
-         data-role="content"
-         role="tabpanel"
-         aria-hidden="false"
-         data-bind="fadeVisible: isVisible() && quoteHasShippingAddress()">
-        <!-- ko if: rates().length == 0 -->
-        <!-- ko text: $t('Sorry, no quotes are available for this order right now.')--><!-- /ko -->
-        <!-- /ko -->
-        <!-- ko if: rates().length  -->
-        <form class="form methods-shipping" id="co-shipping-method-form" data-bind="submit: setShippingMethod" novalidate="novalidate">
-            <div id="checkout-shipping-method-load">
-                <dl class="items methods-shipping">
-                    <!--ko foreach: { data: rates(), as: 'method'}-->
-                    <dt data-bind="text: $t(method.carrier_title), attr: {'class': 'item-title ' + method.carrier_code}"></dt>
-                    <dd data-bind="attr: {'class': 'item-content ' + method.carrier_code}">
-                        <fieldset class="fieldset">
-                            <legend class="legend"><span data-bind="text: $t(method.carrier_title)"></span></legend>
-                            <br>
-                            <!--ko foreach: { data: items, as: 'item'}-->
-                            <div class="field choice">
-                                <!-- ko if:  item.error_message -->
-                                <div class="message error">
-                                    <div data-bind="text: $t(item.error_message)"></div>
-                                </div>
-                                <span class="no-display">
-                                    <input name="shipping_method" type="radio" data-bind="attr: {'value' : item.method_code, 'id': 's_method_' + item.method_code}"/>
-                                </span>
-                                <!-- /ko -->
-                                <!-- ko ifnot: item.error_message -->
-                                <!-- ko if: $parent.items.length && $parents[1].rates().length == 1 -->
-                                <span class="no-display">
-                                    <input data-bind="attr: {'value' : item.carrier_code + '_' + item.method_code, 'id': 's_method_' + item.method_code}"
-                                           name="shipping_method" class="radio" type="radio" checked="checked"/>
-                                    </span>
-                                <!-- /ko -->
-                                 <!--ko ifnot: ($parent.items.length && $parents[1].rates().length == 1)-->
-                                <div class="control">
-                                    <input name="shipping_method" type="radio"
-                                           data-bind="checked:$parents[1].verifySelectedMethodCode(item.carrier_code + '_' + item.method_code), attr: {'value': item.carrier_code + '_' + item.method_code, 'id': 's_method_' + item.carrier_code + '_' + item.method_code}"
-                                           class="radio"/>
-                                </div>
-                                 <!--/ko-->
-                                <label class="label" data-bind="attr: {'for': 's_method_' + item.carrier_code + '_' + item.method_code}">
-                                    <span>
-                                        <!-- ko text: $t(item.method_title) --><!-- /ko -->
-                                        <!-- ko foreach: $parents[1].getRegion('price') -->
-                                            <!-- ko template: getTemplate() --><!-- /ko -->
-                                    <!-- /ko -->
-                                    </span>
-                                </label>
-                                <!-- /ko -->
-                            </div>
-                            <!-- /ko -->
-                        </fieldset>
-                    </dd>
-
-                    <!-- /ko -->
-                </dl>
-
-            </div>
-
-            <div id="onepage-checkout-shipping-method-additional-load">
-                <!-- ko foreach: getRegion('shippingAdditional') -->
-                    <!-- ko template: getTemplate() --><!-- /ko -->
-                <!-- /ko -->
-            </div>
-            <div class="actions-toolbar" id="shipping-method-buttons-container">
-                <div class="primary">
-                    <button data-role="opc-continue" type="submit" class="button action continue primary">
-                        <span><!-- ko text: $t('Continue')--><!-- /ko --></span>
-                    </button>
-                </div>
-                <div class="secondary">
-                    <a class="action back" href="#" data-bind="click: backToShippingAddress">
-                        <span><!-- ko text: $t('Back')--><!-- /ko --></span>
-                    </a>
-                </div>
-            </div>
-        </form>
-        <!-- /ko -->
-        </div>
-</li>
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping.html
new file mode 100644
index 0000000000000000000000000000000000000000..a62f3634547c53e3aa887261e137761c78394705
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping.html
@@ -0,0 +1,141 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<li id="opc-shipping" data-bind="fadeVisible: visible()">
+    <div class="step-title" data-bind="text: $t('Shipping Address')" data-role="title"></div>
+    <div id="checkout-step-shipping"
+         class="step-content"
+         data-role="content">
+
+        <!-- ko if: (!quoteIsVirtual) -->
+            <!-- ko foreach: getRegion('customer-email') -->
+                <!-- ko template: getTemplate() --><!-- /ko -->
+            <!--/ko-->
+        <!--/ko-->
+
+        <!-- ko foreach: getRegion('address-list') -->
+        <!-- ko template: getTemplate() --><!-- /ko -->
+        <!--/ko-->
+
+        <!-- ko foreach: getRegion('address-list-additional-addresses') -->
+        <!-- ko template: getTemplate() --><!-- /ko -->
+        <!--/ko-->
+
+        <!-- Address form pop up -->
+        <!-- ko if: (!isFormInline) -->
+        <button type="button"
+                data-bind="click: showFormPopUp, visible: !isNewAddressAdded()"
+                class="action action-show-popup">
+            <span data-bind="text: $t('New Address')"></span></button>
+        <div id="opc-new-shipping-address" data-bind="visible: isFormPopUpVisible()">
+            <!-- ko template: 'Magento_Checkout/shipping-address/form' --><!-- /ko -->
+        </div>
+        <!-- /ko -->
+
+        <!-- ko foreach: getRegion('before-form') -->
+        <!-- ko template: getTemplate() --><!-- /ko -->
+        <!--/ko-->
+
+        <!-- Inline address form -->
+        <!-- ko if: (isFormInline) -->
+        <!-- ko template: 'Magento_Checkout/shipping-address/form' --><!-- /ko -->
+        <!-- /ko -->
+    </div>
+</li>
+
+
+<!--Shipping method template-->
+<li id="opc-shipping_method" data-bind="fadeVisible: visible(), blockLoader: isLoading" role="presentation">
+    <div class="checkout-shipping-method">
+        <div class="step-title" data-bind="text: $t('Shipping Method')" data-role="title"></div>
+        <!-- ko foreach: getRegion('before-shipping-method-form') -->
+        <!-- ko template: getTemplate() --><!-- /ko -->
+        <!-- /ko -->
+        <div id="checkout-step-shipping_method"
+             class="step-content"
+             data-role="content"
+             role="tabpanel"
+             aria-hidden="false">
+            <!-- ko if: rates().length  -->
+            <form class="form methods-shipping" id="co-shipping-method-form" data-bind="submit: setShippingInformation" novalidate="novalidate">
+                <div id="checkout-shipping-method-load">
+                    <table class="table-checkout-shipping-method">
+                        <thead>
+                            <tr class="row">
+                                <th class="col">&nbsp;</th>
+                                <th class="col col-price" data-bind="text: $t('Price')"></th>
+                                <th class="col col-method" data-bind="text: $t('Method Title')"></th>
+                                <th class="col col-carrier" data-bind="text: $t('Carrier Title')"></th>
+                            </tr>
+                        </thead>
+                        <tbody>
+
+                        <!--ko foreach: { data: rates(), as: 'method'}-->
+                        <tr class="row" data-bind="click: $parent.selectShippingMethod">
+                            <td class="col">
+                                <!-- ko ifnot: method.error_message -->
+                                <!-- ko if: $parent.rates().length == 1 -->
+                                <input name="shipping_method"
+                                       class="radio"
+                                       type="radio"
+                                       data-bind="attr: {checked: $parent.rates().length == 1, 'value' : method.carrier_code + '_' + method.method_code, 'id': 's_method_' + method.method_code}" />
+                                <!-- /ko -->
+                                <!--ko ifnot: ($parent.rates().length == 1)-->
+                                <input name="shipping_method" type="radio"
+                                       data-bind="
+                                                value: method.carrier_code + '_' + method.method_code,
+                                                checked: $parent.isSelected,
+                                                attr: {'id': 's_method_' + method.carrier_code + '_' + method.method_code},
+                                                click: $parent.selectShippingMethod"
+                                       class="radio"/>
+                                <!--/ko-->
+                                <!-- /ko -->
+                            </td>
+                            <td class="col col-price">
+                                <!-- ko foreach: $parent.getRegion('price') -->
+                                <!-- ko template: getTemplate() --><!-- /ko -->
+                                <!-- /ko -->
+                            </td>
+                            <td class="col col-method" data-bind="text: $t(method.method_title)"></td>
+                            <td class="col col-carrier" data-bind="text: $t(method.carrier_title)"></td>
+                        </tr>
+
+                        <!-- ko if:  method.error_message -->
+                        <tr class="row row-error">
+                            <td class="col col-error" colspan="4">
+                                <div class="message error">
+                                    <div data-bind="text: $t(method.error_message)"></div>
+                                </div>
+                                <span class="no-display">
+                                    <input name="shipping_method" type="radio" data-bind="attr: {'value' : method.method_code, 'id': 's_method_' + method.method_code}"/>
+                                </span>
+                            </td>
+                        </tr>
+                        <!-- /ko -->
+
+                        <!-- /ko -->
+                        </tbody>
+                    </table>
+                </div>
+
+                <div id="onepage-checkout-shipping-method-additional-load">
+                    <!-- ko foreach: getRegion('shippingAdditional') -->
+                    <!-- ko template: getTemplate() --><!-- /ko -->
+                    <!-- /ko -->
+                </div>
+                <div class="actions-toolbar" id="shipping-method-buttons-container">
+                    <div class="primary">
+                        <button data-role="opc-continue" type="submit" class="button action continue primary">
+                            <span><!-- ko text: $t('Next')--><!-- /ko --></span>
+                        </button>
+                    </div>
+                </div>
+            </form>
+            <!-- /ko -->
+            <!-- ko ifnot: rates().length > 0 --><div class="no-quotes-block"><!-- ko text: $t('Sorry, no quotes are available for this order at this time')--><!-- /ko --></div><!-- /ko -->
+        </div>
+    </div>
+</li>
diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/review/agreements.html b/app/code/Magento/Checkout/view/frontend/web/template/summary.html
similarity index 55%
rename from app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/review/agreements.html
rename to app/code/Magento/Checkout/view/frontend/web/template/summary.html
index 7de21298dcc66e6e6d094e5be4d5b9163fb5830a..322ef76b8f053604505b4f054ceedde082c362e0 100644
--- a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/review/agreements.html
+++ b/app/code/Magento/Checkout/view/frontend/web/template/summary.html
@@ -4,8 +4,9 @@
  * See COPYING.txt for license details.
  */
 -->
-<ol id="checkout-agreements" class="agreements checkout items">
+<div class="opc-block-summary" data-bind="blockLoader: isLoading">
+    <span data-bind="text: $t('Order Summary')" class="title"></span>
     <!-- ko foreach: elems() -->
         <!-- ko template: getTemplate() --><!-- /ko -->
-    <!--/ko-->
-</ol>
+    <!-- /ko -->
+</div>
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/summary/cart-items.html b/app/code/Magento/Checkout/view/frontend/web/template/summary/cart-items.html
new file mode 100644
index 0000000000000000000000000000000000000000..b262445e97dcaaf4972312823ea20b772a9cca7f
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/template/summary/cart-items.html
@@ -0,0 +1,54 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<!-- ko ifnot: isItemsBlockExpanded() -->
+<div class="block items-in-cart" data-bind="mageInit: {'collapsible':{'openedState': 'active'}}">
+    <div class="title" data-role="title">
+        <strong role="heading"><span data-bind="text: getItemsQty()"></span>
+            <!-- ko text: $t('Items in cart') --><!-- /ko -->
+        </strong>
+    </div>
+    <div class="content minicart-items" data-role="content">
+        <div class="minicart-items-wrapper overflowed">
+            <ol class="minicart-items">
+                <!-- ko foreach: getItems -->
+                <li class="product-item">
+                    <div class="product">
+                        <!-- ko foreach: $parent.elems() -->
+                        <!-- ko template: getTemplate() --><!-- /ko -->
+                        <!-- /ko -->
+                    </div>
+                </li>
+                <!-- /ko -->
+            </ol>
+        </div>
+    </div>
+</div>
+<!-- /ko -->
+<!-- ko if: isItemsBlockExpanded() -->
+<div class="block items-in-cart" data-bind="mageInit: {'collapsible':{'openedState': 'active', 'active': true}}">
+    <div class="title" data-role="title">
+        <strong role="heading"><span data-bind="text: getItemsQty()"></span>
+            <!-- ko text: $t('Items in cart') --><!-- /ko -->
+        </strong>
+    </div>
+    <div class="content minicart-items" data-role="content">
+        <div class="minicart-items-wrapper overflowed">
+            <ol class="minicart-items">
+                <!-- ko foreach: getItems -->
+                <li class="product-item">
+                    <div class="product">
+                        <!-- ko foreach: $parent.elems() -->
+                        <!-- ko template: getTemplate() --><!-- /ko -->
+                        <!-- /ko -->
+                    </div>
+                </li>
+                <!-- /ko -->
+            </ol>
+        </div>
+    </div>
+</div>
+<!-- /ko -->
\ No newline at end of file
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/summary/grand-total.html b/app/code/Magento/Checkout/view/frontend/web/template/summary/grand-total.html
new file mode 100644
index 0000000000000000000000000000000000000000..78954c0a4feff1a869912afebbb6051c57f34922
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/template/summary/grand-total.html
@@ -0,0 +1,17 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<!-- ko if: isDisplayed() -->
+<tr>
+    <td colspan="2" data-bind="text: $t(title)"></td>
+    <td class="col grandtotal">
+        <span data-bind ="text: getValue(), attr:{'data-label': $t(title)}"></span>
+        <!-- ko foreach: elems() -->
+            <!-- ko template: getTemplate() --><!-- /ko -->
+        <!-- /ko -->
+    </td>
+</tr>
+<!-- /ko -->
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/summary/item/details.html b/app/code/Magento/Checkout/view/frontend/web/template/summary/item/details.html
new file mode 100644
index 0000000000000000000000000000000000000000..dab4d8393326c266bbdff3cf1f54883b6b218c73
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/template/summary/item/details.html
@@ -0,0 +1,45 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+
+<!-- ko foreach: getRegion('before_details') -->
+    <!-- ko template: getTemplate() --><!-- /ko -->
+<!-- /ko -->
+<div class="product-item-details">
+
+    <div class="product-item-inner">
+        <div class="product-item-name-block">
+            <strong class="product-item-name" data-bind="text: $t($parent.name)"></strong>
+            <div class="details-qty">
+                <span class="label"><!-- ko text: $t('Qty') --><!-- /ko --></span>
+                <span class="value" data-bind="text: $parent.qty"></span>
+            </div>
+        </div>
+        <!-- ko foreach: getRegion('after_details') -->
+            <!-- ko template: getTemplate() --><!-- /ko -->
+        <!-- /ko -->
+    </div>
+
+    <!-- ko if: (JSON.parse($parent.options).length > 0)-->
+    <div class="product options" data-bind="mageInit: {'collapsible':{'openedState': 'active'}}">
+        <span data-role="title" class="toggle"><!-- ko text: $t('View Details') --><!-- /ko --></span>
+        <div data-role="content" class="content">
+            <strong class="subtitle"><!-- ko text: $t('Options Details') --><!-- /ko --></strong>
+            <dl class="item-options">
+                <!--ko foreach: JSON.parse($parent.options)-->
+                <dt class="label" data-bind="text: $t(label)"></dt>
+                    <!-- ko if: ($data.full_view)-->
+                    <dd class="values" data-bind="html: full_view"></dd>
+                    <!-- /ko -->
+                    <!-- ko ifnot: ($data.full_view)-->
+                    <dd class="values" data-bind="html: value"></dd>
+                    <!-- /ko -->
+                <!-- /ko -->
+            </dl>
+        </div>
+    </div>
+    <!-- /ko -->
+</div>
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/model/item.js b/app/code/Magento/Checkout/view/frontend/web/template/summary/item/details/subtotal.html
similarity index 54%
rename from app/code/Magento/Checkout/view/frontend/web/js/model/item.js
rename to app/code/Magento/Checkout/view/frontend/web/template/summary/item/details/subtotal.html
index d1927d19e9288d2b244ff8f5761bc12556b605a2..f90013fcebbca354cb4ee7c7d3a0c756145ace6a 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/model/item.js
+++ b/app/code/Magento/Checkout/view/frontend/web/template/summary/item/details/subtotal.html
@@ -1,9 +1,7 @@
+<!--
 /**
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-/*jshint browser:true jquery:true*/
-/*global alert*/
-define([], function() {
-
-});
+-->
+<span class="subtotal" data-bind="text: getValue($parents[1])"></span>
\ No newline at end of file
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/summary/item/details/thumbnail.html b/app/code/Magento/Checkout/view/frontend/web/template/summary/item/details/thumbnail.html
new file mode 100644
index 0000000000000000000000000000000000000000..1b8cb1fada8c6d21332167f59d4a5cf68d342ca0
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/template/summary/item/details/thumbnail.html
@@ -0,0 +1,13 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<span class="product-image-container"
+      data-bind="attr: {'style': 'height: ' + getHeight($parents[1]) + 'px; width: ' + getWidth($parents[1]) + 'px;' }">
+    <span class="product-image-wrapper">
+        <img
+            data-bind="attr: {'src': getSrc($parents[1]), 'width': getWidth($parents[1]), 'height': getHeight($parents[1]), 'alt': getAlt($parents[1]) }"/>
+    </span>
+</span>
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/summary/shipping.html b/app/code/Magento/Checkout/view/frontend/web/template/summary/shipping.html
new file mode 100644
index 0000000000000000000000000000000000000000..34707698e61b6d43a73c743b908c3b4c8c246fbc
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/template/summary/shipping.html
@@ -0,0 +1,24 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<!-- ko if: quoteIsVirtual == 0 -->
+    <tr class="totals shipping excl">
+        <th class="mark" scope="row">
+            <span class="label" data-bind="text: $t(title)"></span>
+            <span class="value" data-bind="text: $t(getShippingMethodTitle())"></span>
+        </th>
+        <td class="amount">
+            <!-- ko if: isCalculated() -->
+            <span class="price"
+                  data-bind="text: $t(getValue()), attr: {'data-th': $t(title)}"></span>
+            <!-- /ko -->
+            <!-- ko ifnot: isCalculated() -->
+            <span class="not-calculated"
+                  data-bind="text: $t(getValue()), attr: {'data-th': $t(title)}"></span>
+            <!-- /ko -->
+        </td>
+    </tr>
+<!-- /ko -->
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/summary/subtotal.html b/app/code/Magento/Checkout/view/frontend/web/template/summary/subtotal.html
new file mode 100644
index 0000000000000000000000000000000000000000..f241430924ac88f2a773699f978c33228d9beb9c
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/template/summary/subtotal.html
@@ -0,0 +1,16 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+
+<tr class="totals">
+    <th class="mark" scope="row" data-bind="text: $t(title)"></th>
+    <td class="amount">
+        <span class="price" data-bind ="text: getValue(), attr:{'data-label': $t(title)}"></span>
+        <!-- ko foreach: elems() -->
+            <!-- ko template: getTemplate() --><!-- /ko -->
+        <!-- /ko -->
+    </td>
+</tr>
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/summary/totals.html b/app/code/Magento/Checkout/view/frontend/web/template/summary/totals.html
new file mode 100644
index 0000000000000000000000000000000000000000..074024dee00d9d0bdd55fef06c933f6df9d94330
--- /dev/null
+++ b/app/code/Magento/Checkout/view/frontend/web/template/summary/totals.html
@@ -0,0 +1,14 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<table class="data table table-totals">
+    <caption class="table-caption" data-bind="text: $t('Order Summary')"></caption>
+    <tbody>
+    <!-- ko foreach: elems() -->
+        <!-- ko template: getTemplate() --><!-- /ko -->
+    <!-- /ko -->
+    </tbody>
+</table>
diff --git a/app/code/Magento/CheckoutAgreements/Block/Checkout/LayoutProcessor.php b/app/code/Magento/CheckoutAgreements/Block/Checkout/LayoutProcessor.php
index b13012ae47336a32c14f4f96ca9c22cdaa1a5914..ad8bdfc822cd6cf47021150f599f6e43320d709d 100644
--- a/app/code/Magento/CheckoutAgreements/Block/Checkout/LayoutProcessor.php
+++ b/app/code/Magento/CheckoutAgreements/Block/Checkout/LayoutProcessor.php
@@ -34,34 +34,22 @@ class LayoutProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcesso
      */
     public function process($jsLayout)
     {
-        $form = [];
+        $agreementConfiguration = [];
         $agreementsList = $this->checkoutAgreementsRepository->getList();
+
         foreach ($agreementsList as $agreement) {
-            $name = $agreement->getAgreementId();
-            $form[$name] = [
-                'component' => 'Magento_Ui/js/form/element/abstract',
-                'config' => [
-                    'customScope' => 'checkoutAgreements',
-                    'customEntry' => 'checkoutAgreements.' . $name,
-                    'template' => 'Magento_CheckoutAgreements/form/element/agreement'
-                ],
-                'agreementConfiguration' => [
-                    'content' => $agreement->getIsHtml()
-                        ? $agreement->getContent()
-                        : nl2br($this->escaper->escapeHtml($agreement->getContent())),
-                    'height' => $agreement->getContentHeight(),
-                    'checkboxText' => $agreement->getCheckboxText()
-                ],
-                'dataScope' => $name,
-                'provider' => 'checkoutProvider',
-                'validation' => ['checked' => true],
-                'customEntry' => null,
-                'visible' => true
+            $agreementConfiguration[] = [
+                'content' => $agreement->getIsHtml()
+                    ? $agreement->getContent()
+                    : nl2br($this->escaper->escapeHtml($agreement->getContent())),
+                'height' => $agreement->getContentHeight(),
+                'checkboxText' => $agreement->getCheckboxText()
             ];
         }
-        $result['components']['checkout']['children']['steps']['children']['review']['children']
-        ['beforePlaceOrder']['children']['checkoutAgreements']['children'] = $form;
+        $jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']
+        ['children']['payments-list']['children']['before-place-order']['children']['checkout-agreements-modal']
+        ['config']['agreementConfiguration'] = $agreementConfiguration;
 
-        return array_merge_recursive($jsLayout, $result);
+        return $jsLayout;
     }
 }
diff --git a/app/code/Magento/CheckoutAgreements/composer.json b/app/code/Magento/CheckoutAgreements/composer.json
index 13f10a6560e989f70548019e6eb5b043740c431b..1c9182b3add4bac268176432b51c4704d97b8cd9 100644
--- a/app/code/Magento/CheckoutAgreements/composer.json
+++ b/app/code/Magento/CheckoutAgreements/composer.json
@@ -6,7 +6,6 @@
         "magento/module-checkout": "0.74.0-beta15",
         "magento/module-store": "0.74.0-beta15",
         "magento/module-backend": "0.74.0-beta15",
-        "magento/module-ui": "0.74.0-beta15",
         "magento/framework": "0.74.0-beta15",
         "magento/magento-composer-installer": "*"
     },
diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/layout/checkout_onepage_index.xml b/app/code/Magento/CheckoutAgreements/view/frontend/layout/checkout_onepage_index.xml
index b80bfc39aef43beb4d75914c654e68171d66a546..5f883201ee2dc7a65fb206b071dea0216d7c8b3b 100644
--- a/app/code/Magento/CheckoutAgreements/view/frontend/layout/checkout_onepage_index.xml
+++ b/app/code/Magento/CheckoutAgreements/view/frontend/layout/checkout_onepage_index.xml
@@ -15,16 +15,25 @@
                             <item name="children" xsi:type="array">
                                 <item name="steps" xsi:type="array">
                                     <item name="children" xsi:type="array">
-                                        <item name="review" xsi:type="array">
+                                        <item name="billing-step" xsi:type="array">
                                             <item name="children" xsi:type="array">
-                                                <item name="beforePlaceOrder" xsi:type="array">
+                                                <item name="payment" xsi:type="array">
                                                     <item name="children" xsi:type="array">
-                                                        <item name="checkoutAgreements" xsi:type="array">
-                                                            <item name="component"  xsi:type="string">Magento_CheckoutAgreements/js/view/checkoutAgreements</item>
-                                                            <item name="dataScope" xsi:type="string">checkoutAgreements</item>
-                                                            <item name="displayArea" xsi:type="string">checkoutAgreements</item>
-                                                            <item name="provider" xsi:type="string">checkoutProvider</item>
+                                                        <item name="payments-list" xsi:type="array">
                                                             <item name="children" xsi:type="array">
+                                                                <item name="before-place-order" xsi:type="array">
+                                                                    <item name="component" xsi:type="string">Magento_CheckoutAgreements/js/view/checkout-agreements-link</item>
+                                                                    <item name="displayArea" xsi:type="string">before-place-order</item>
+                                                                    <item name="dataScope" xsi:type="string">checkoutAgreements</item>
+                                                                    <item name="provider" xsi:type="string">checkoutProvider</item>
+                                                                    <item name="children" xsi:type="array">
+                                                                        <item name="checkout-agreements-modal" xsi:type="array">
+                                                                            <item name="component" xsi:type="string">Magento_CheckoutAgreements/js/view/checkout-agreements-modal</item>
+                                                                            <item name="dataScope" xsi:type="string">checkoutAgreements</item>
+                                                                            <item name="provider" xsi:type="string">checkoutProvider</item>
+                                                                        </item>
+                                                                    </item>
+                                                                </item>
                                                             </item>
                                                         </item>
                                                     </item>
diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/layout/checkout_onepage_original.xml b/app/code/Magento/CheckoutAgreements/view/frontend/layout/checkout_onepage_original.xml
new file mode 100644
index 0000000000000000000000000000000000000000..89eb6278a7646836ff461eb6955899faae9b5fb9
--- /dev/null
+++ b/app/code/Magento/CheckoutAgreements/view/frontend/layout/checkout_onepage_original.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<!-- TODO remove this file as soon as enhanced checkout is implemented -->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+    <body>
+        <referenceBlock name="checkout.root">
+            <arguments>
+                <argument name="jsLayout" xsi:type="array">
+                    <item name="components" xsi:type="array">
+                        <item name="checkout" xsi:type="array">
+                            <item name="children" xsi:type="array">
+                                <item name="steps" xsi:type="array">
+                                    <item name="children" xsi:type="array">
+                                        <item name="review" xsi:type="array">
+                                            <item name="children" xsi:type="array">
+                                                <item name="beforePlaceOrder" xsi:type="array">
+                                                    <item name="children" xsi:type="array">
+                                                        <item name="checkoutAgreements" xsi:type="array">
+                                                            <item name="component"  xsi:type="string">Magento_CheckoutAgreements/js/view/checkoutAgreements</item>
+                                                            <item name="dataScope" xsi:type="string">checkoutAgreements</item>
+                                                            <item name="displayArea" xsi:type="string">checkoutAgreements</item>
+                                                            <item name="provider" xsi:type="string">checkoutProvider</item>
+                                                            <item name="children" xsi:type="array">
+                                                            </item>
+                                                        </item>
+                                                    </item>
+                                                </item>
+                                            </item>
+                                        </item>
+                                    </item>
+                                </item>
+                            </item>
+                        </item>
+                    </item>
+                </argument>
+            </arguments>
+        </referenceBlock>
+    </body>
+</page>
diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkout-agreements-link.js b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkout-agreements-link.js
new file mode 100644
index 0000000000000000000000000000000000000000..071602c254c40f864b7654cfb56293d1c250d2dc
--- /dev/null
+++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkout-agreements-link.js
@@ -0,0 +1,24 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+        'ko',
+        'uiComponent'
+    ], function (ko, Component) {
+        'use strict';
+
+        return Component.extend({
+            defaults: {
+                template: 'Magento_CheckoutAgreements/checkout/payment/checkout-agreements-link'
+            },
+            isVisible: window.checkoutConfig.checkoutAgreementsEnabled,
+            /**
+             * Opens modal window with Terms&Conditions
+             */
+            showAgreements: function () {
+                this.elems()[0].showAgreements();
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkout-agreements-modal.js b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkout-agreements-modal.js
new file mode 100644
index 0000000000000000000000000000000000000000..e7762f7ea5b9f1c2448110c50be7ec42d28733a9
--- /dev/null
+++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkout-agreements-modal.js
@@ -0,0 +1,56 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+        'ko',
+        'uiComponent',
+        'Magento_Ui/js/modal/modal'
+    ], function (ko, Component, modal) {
+        'use strict';
+
+        /**
+         * Provides an empty div to force load template into.
+         * @todo MAGETWO-39170 Refactor this as soon as modal component is updated to support ko view models.
+         * @returns {HTMLElement}
+         */
+        function createTemporayContainer() {
+            var temporaryDiv = document.createElement('div');
+            temporaryDiv.style.display = 'none';
+            document.body.appendChild(temporaryDiv);
+
+            return temporaryDiv;
+        }
+
+        return Component.extend({
+            defaults: {
+                template: 'Magento_CheckoutAgreements/checkout/modal/agreements-modal'
+            },
+            /**
+             * Initialize view and render it's template to temporary div. This will be refactored as soon as
+             * modal component is integrated with uiComponent.
+             * @returns {*}
+             */
+            initialize: function () {
+                var temporaryContainer = createTemporayContainer();
+
+                this._super();
+                ko.renderTemplate(this.template, this, {}, temporaryContainer);
+                temporaryContainer.parentNode.removeChild(temporaryContainer);
+
+                return this;
+            },
+            modal: modal({
+                responsive: true,
+                innerScroll: true,
+                buttons: []
+            }),
+            /**
+             * Show Terms&Conditions pop-up
+             */
+            showAgreements: function () {
+                ko.renderTemplate(this.template, this, {}, this.modal.openModal(), 'replaceNode');
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkoutAgreements.js b/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkoutAgreements.js
deleted file mode 100644
index 094136c756467124a11a6c509263af55c8bd69c1..0000000000000000000000000000000000000000
--- a/app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkoutAgreements.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*global define*/
-define(
-    ['Magento_Ui/js/form/form', 'Magento_Checkout/js/view/review', 'underscore'],
-    function (Component, review, _) {
-        "use strict";
-        return Component.extend({
-            defaults: {
-                template: 'Magento_CheckoutAgreements/checkout/review/agreements'
-            },
-            initialize: function() {
-                this._super();
-                if (window.checkoutConfig.checkoutAgreementsEnabled) {
-                    review.prototype.beforePlaceOrder.checkoutAgreements = this;
-                }
-            },
-            validate: function() {
-                this.source.set('params.invalid', false);
-                this.source.trigger('checkoutAgreements.data.validate');
-                return this.source.get('params.invalid');
-            },
-            getSubmitParams: function() {
-                return {
-                    agreements: _.keys(this.source.get('checkoutAgreements'))
-                };
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/modal/agreements-modal.html b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/modal/agreements-modal.html
new file mode 100644
index 0000000000000000000000000000000000000000..0129cab3aebd3c2d9aaba585274e4bfc70413ccb
--- /dev/null
+++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/modal/agreements-modal.html
@@ -0,0 +1,15 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<ol class="checkout-agreements-items">
+    <!-- ko foreach: agreementConfiguration -->
+    <li class="checkout-agreements-item">
+        <div class="checkout-agreements-item-title" data-bind="html: checkboxText"></div>
+        <div class="checkout-agreements-item-content"
+             data-bind="style: { height: height || null }, html: content"></div>
+    </li>
+    <!-- /ko -->
+</ol>
diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/payment/checkout-agreements-link.html b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/payment/checkout-agreements-link.html
new file mode 100644
index 0000000000000000000000000000000000000000..315bc47af7dac0607ace233f00b8dce7273a96db
--- /dev/null
+++ b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/checkout/payment/checkout-agreements-link.html
@@ -0,0 +1,14 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+
+<div class="checkout-agreements" data-bind="visible: isVisible">
+    <!-- ko text: $t('You automatically accept') --><!-- /ko -->
+    <button type="button" class="action action-show" data-bind="click: showAgreements">
+        <span><!-- ko text: $t('terms and conditions') --><!-- /ko --></span>
+    </button>
+    <!-- ko text: $t('before placing the order') --><!-- /ko -->
+</div>
diff --git a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/form/element/agreement.html b/app/code/Magento/CheckoutAgreements/view/frontend/web/template/form/element/agreement.html
deleted file mode 100644
index 0f029cfe2f3b4113a83c4b7256f867ce8e5ca592..0000000000000000000000000000000000000000
--- a/app/code/Magento/CheckoutAgreements/view/frontend/web/template/form/element/agreement.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<li class="item">
-    <div class="agreement content" data-bind="style: { height: agreementConfiguration.height || null }, html: agreementConfiguration.content"></div>
-    <form class="field choice agree required" id="checkout-agreements">
-        <input type="checkbox" class="control-checkbox" data-bind="checked: value, attr: { id: uid, disabled: disabled, name: inputName }, hasFocus: focused">
-        <label class="field-label" data-bind="checked: value, attr: { for: uid }">
-            <span data-bind="html: agreementConfiguration.checkboxText"></span>
-        </label>
-    </form>
-    <!-- ko if: error() -->
-    <div class="mage-error" data-bind="attr: { for: uid }, text: error" generated="true"></div>
-    <!-- /ko -->
-</li>
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/check-email-availability.js b/app/code/Magento/Customer/view/frontend/web/js/action/check-email-availability.js
similarity index 66%
rename from app/code/Magento/Checkout/view/frontend/web/js/action/check-email-availability.js
rename to app/code/Magento/Customer/view/frontend/web/js/action/check-email-availability.js
index f25cd3f00ac28fb40a4a560426d5644e2f7855ba..6c658bace739f0f4343fe2b74836a7cab053febf 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/action/check-email-availability.js
+++ b/app/code/Magento/Customer/view/frontend/web/js/action/check-email-availability.js
@@ -2,22 +2,21 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-/*jshint browser:true*/
-/*global define*/
 define(
     [
         'mage/storage',
-        '../model/url-builder',
-        'Magento_Customer/js/model/customer'
+        'Magento_Checkout/js/model/url-builder'
     ],
-    function(storage, urlBuilder, customer) {
-        "use strict";
-        return function(deferred) {
-            storage.post(
+    function (storage, urlBuilder) {
+        'use strict';
+
+        return function (deferred, email) {
+            return storage.post(
                 urlBuilder.createUrl('/customers/isEmailAvailable', {}),
                 JSON.stringify({
-                    customerEmail: customer.customerData.email
-                })
+                    customerEmail: email
+                }),
+                false
             ).done(
                 function (isEmailAvailable) {
                     if (isEmailAvailable) {
diff --git a/app/code/Magento/Customer/view/frontend/web/js/action/login.js b/app/code/Magento/Customer/view/frontend/web/js/action/login.js
index 11dcaeec5cb4b0943bd8b5d043bb59238a4df1c5..31d928825415b94304ca8b6f57fb912f6760a8cd 100644
--- a/app/code/Magento/Customer/view/frontend/web/js/action/login.js
+++ b/app/code/Magento/Customer/view/frontend/web/js/action/login.js
@@ -7,30 +7,45 @@ define(
     [
         'jquery',
         'mage/storage',
-        'Magento_Ui/js/model/errorlist',
-        'Magento_Customer/js/model/customer'
+        'Magento_Ui/js/model/messageList',
+        'Magento_Customer/js/customer-data'
     ],
-    function($, storage, errorlist, customer) {
-        "use strict";
-        return function(loginData, redirectUrl) {
-            return storage.post(
-                'customer/ajax/login',
-                JSON.stringify(loginData)
-            ).done(function (response) {
-                if (response.errors) {
-                    customer.increaseFailedLoginAttempt();
-                    errorlist.add(response);
-                } else {
-                    if (redirectUrl) {
-                        window.location.href = redirectUrl;
+    function($, storage, messageList, customerData) {
+        'use strict';
+        var callbacks = [],
+            action = function(loginData, redirectUrl) {
+                return storage.post(
+                    'customer/ajax/login',
+                    JSON.stringify(loginData)
+                ).done(function (response) {
+                    if (response.errors) {
+                        messageList.addErrorMessage(response);
+                        callbacks.forEach(function(callback) {
+                            callback(loginData);
+                        });
                     } else {
-                        location.reload();
+                        callbacks.forEach(function(callback) {
+                            callback(loginData);
+                        });
+                        customerData.invalidate(['customer']);
+                        if (redirectUrl) {
+                            window.location.href = redirectUrl;
+                        } else {
+                            location.reload();
+                        }
                     }
-                }
-            }).fail(function () {
-                customer.increaseFailedLoginAttempt();
-                errorlist.add({'message': 'Could not authenticate. Please try again later'});
-            });
+                }).fail(function () {
+                    messageList.addErrorMessage({'message': 'Could not authenticate. Please try again later'});
+                    callbacks.forEach(function(callback) {
+                        callback(loginData);
+                    });
+                });
+            };
+
+        action.registerLoginCallback = function(callback) {
+            callbacks.push(callback);
         };
+
+        return action;
     }
 );
diff --git a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js
index 2f5c1181ea10d44c4a4e99294dac2ee068822387..bfb277c067d57bb85961c7824bdaf3919f1340b1 100644
--- a/app/code/Magento/Customer/view/frontend/web/js/customer-data.js
+++ b/app/code/Magento/Customer/view/frontend/web/js/customer-data.js
@@ -9,7 +9,6 @@ define([
     'Magento_Customer/js/section-config',
     'jquery/jquery-storageapi',
     'jquery/jquery.cookie'
-
 ], function ($, _, ko, sectionConfig) {
     'use strict';
 
diff --git a/app/code/Magento/Customer/view/frontend/web/js/model/address-list.js b/app/code/Magento/Customer/view/frontend/web/js/model/address-list.js
new file mode 100644
index 0000000000000000000000000000000000000000..a67a3e0b693973ad41af5205b6887abef0ffa797
--- /dev/null
+++ b/app/code/Magento/Customer/view/frontend/web/js/model/address-list.js
@@ -0,0 +1,15 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [
+        'ko',
+        './customer-addresses'
+    ],
+    function(ko, defaultProvider) {
+        "use strict";
+        return ko.observableArray(defaultProvider.getAddressItems());
+    }
+);
\ No newline at end of file
diff --git a/app/code/Magento/Customer/view/frontend/web/js/model/customer-addresses.js b/app/code/Magento/Customer/view/frontend/web/js/model/customer-addresses.js
new file mode 100644
index 0000000000000000000000000000000000000000..c14cffb2c59e3e8edb233a90f34e25a374688d65
--- /dev/null
+++ b/app/code/Magento/Customer/view/frontend/web/js/model/customer-addresses.js
@@ -0,0 +1,30 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [
+        'jquery',
+        'ko',
+        './customer/address'
+    ],
+    function($, ko, address) {
+        "use strict";
+        var isLoggedIn = ko.observable(window.isCustomerLoggedIn);
+        return {
+            getAddressItems: function() {
+                var items = [];
+                if (isLoggedIn) {
+                    var customerData = window.customerData;
+                    if (Object.keys(customerData).length) {
+                        $.each(customerData.addresses, function (key, item) {
+                            items.push(new address(item));
+                        });
+                    }
+                }
+                return items;
+            }
+        }
+    }
+);
\ No newline at end of file
diff --git a/app/code/Magento/Customer/view/frontend/web/js/model/customer.js b/app/code/Magento/Customer/view/frontend/web/js/model/customer.js
index 28a43254db2efdcf3e2e6e5d52b1eeca3841f9d4..25654444d6cc5ee783b134afdf41c44eaac28bdf 100644
--- a/app/code/Magento/Customer/view/frontend/web/js/model/customer.js
+++ b/app/code/Magento/Customer/view/frontend/web/js/model/customer.js
@@ -9,46 +9,31 @@ define(
         'ko',
         'underscore',
         'mage/storage',
-        'Magento_Checkout/js/model/addresslist',
-        './customer/address'
+        './address-list'
     ],
-    function($, ko, _, storage, addressList, address) {
+    function($, ko, _, storage, addressList) {
         "use strict";
         var isLoggedIn = ko.observable(window.isCustomerLoggedIn),
-            failedLoginAttempts = ko.observable(0),
             customerData = {};
 
         if (isLoggedIn()) {
             customerData = window.customerData;
-            if (Object.keys(customerData).length) {
-                $.each(customerData.addresses, function (key, item) {
-                    addressList.add(new address(item));
-                });
-            }
         } else {
             customerData = {};
         }
+
         return {
             customerData: customerData,
             customerDetails: {},
-            isLoggedIn: function() {
-                return isLoggedIn;
-            },
+            isLoggedIn: isLoggedIn,
             setIsLoggedIn: function (flag) {
                 isLoggedIn(flag);
             },
-            getFailedLoginAttempts: function() {
-                return failedLoginAttempts;
-            },
-            increaseFailedLoginAttempt: function() {
-                var oldAttempts = failedLoginAttempts();
-                failedLoginAttempts(++oldAttempts);
-            },
             getBillingAddressList: function () {
-                return addressList.getAddresses();
+                return addressList();
             },
             getShippingAddressList: function () {
-                return addressList.getAddresses();
+                return addressList();
             },
             setDetails: function (fieldName, value) {
                 if (fieldName) {
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 104655e0f2224625ceb03f07e78453fa9cfb9e14..c3f656411450d8f6a9603d7688a93d5e8f788fd7 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
@@ -5,6 +5,10 @@
 /*jshint browser:true jquery:true*/
 /*global alert*/
 define([], function() {
+    /**
+     * @param addressData
+     * Returns new address object
+     */
     return function (addressData) {
         return {
             customerAddressId: addressData.id,
@@ -26,9 +30,28 @@ define([], function() {
             prefix: addressData.prefix,
             suffix: addressData.suffix,
             vatId: addressData.vat_id,
-            sameAsBilling: null,
+            sameAsBilling: addressData.same_as_billing,
+            saveInAddressBook: addressData.save_in_address_book,
+            isDefaultShipping: function() {
+                return addressData.default_shipping;
+            },
+            isDefaultBilling: function() {
+                return addressData.default_billing;
+            },
             getAddressInline: function() {
                 return addressData.inline;
+            },
+            getType: function() {
+                return 'customer-address'
+            },
+            getKey: function() {
+                return this.getType() + this.customerAddressId;
+            },
+            isEditable: function() {
+                return false;
+            },
+            canUseForBilling: function() {
+                return true;
             }
         }
     }
diff --git a/app/code/Magento/Customer/view/frontend/web/js/view/customer-email.js b/app/code/Magento/Customer/view/frontend/web/js/view/customer-email.js
new file mode 100644
index 0000000000000000000000000000000000000000..ae864756661c84ffe7ab65d320d6b80d32822bca
--- /dev/null
+++ b/app/code/Magento/Customer/view/frontend/web/js/view/customer-email.js
@@ -0,0 +1,116 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*browser:true*/
+/*global define*/
+define(
+    [
+        'jquery',
+        'uiComponent',
+        'ko',
+        'Magento_Customer/js/model/customer',
+        'Magento_Customer/js/action/check-email-availability',
+        'Magento_Customer/js/action/login',
+        'Magento_Checkout/js/model/quote',
+        'mage/validation'
+    ],
+    function ($, Component, ko, customer, checkEmailAvailability, loginAction, quote) {
+        "use strict";
+        return Component.extend({
+            defaults: {
+                template: 'Magento_Customer/customer-email',
+                email: '',
+                isLoading: false,
+                isPasswordVisible: false
+            },
+            checkDelay: 2000,
+            checkRequest: null,
+            isEmailCheckComplete: null,
+            isCustomerLoggedIn: customer.isLoggedIn,
+            forgotPasswordUrl: window.checkoutConfig.forgotPasswordUrl,
+            emailCheckTimeout: 0,
+
+            initialize: function() {
+                this._super();
+                var self = this;
+                this.email.subscribe(function() {
+                    self.emailHasChanged();
+                });
+            },
+
+            /** Initialize observable properties */
+            initObservable: function () {
+                this._super()
+                    .observe(['email', 'isLoading', 'isPasswordVisible']);
+                return this;
+            },
+
+            emailHasChanged: function () {
+                var self = this;
+                clearTimeout(this.emailCheckTimeout);
+                this.emailCheckTimeout = setTimeout(function () {
+                    if (self.validateEmail()) {
+                        self.checkEmailAvailability();
+                        quote.guestEmail = self.email();
+                    } else {
+                        self.isPasswordVisible(false);
+                    }
+                }, self.checkDelay);
+
+            },
+
+            checkEmailAvailability: function() {
+                var self = this;
+                this.validateRequest();
+                this.isEmailCheckComplete = $.Deferred();
+                this.isLoading(true);
+                this.checkRequest = checkEmailAvailability(this.isEmailCheckComplete, this.email());
+
+                $.when(this.isEmailCheckComplete).done(function() {
+                    self.isPasswordVisible(false);
+                }).fail( function() {
+                    self.isPasswordVisible(true);
+                }).always(function () {
+                    self.isLoading(false);
+                });
+            },
+
+            validateRequest: function() {
+                /*
+                 * If request has been sent -> abort it.
+                 * ReadyStates for request aborting:
+                 * 1 - The request has been set up
+                 * 2 - The request has been sent
+                 * 3 - The request is in process
+                 */
+                if (this.checkRequest != null && $.inArray(this.checkRequest.readyState, [1, 2, 3])) {
+                    this.checkRequest.abort();
+                    this.checkRequest = null;
+                }
+            },
+
+            validateEmail: function() {
+                var loginFormSelector = 'form[data-role=email-with-possible-login]';
+                $(loginFormSelector).validation();
+                var validationResult = $(loginFormSelector + ' input[name=username]').valid();
+                return Boolean(validationResult);
+            },
+
+            login: function(loginForm) {
+                var loginData = {},
+                    formDataArray = $(loginForm).serializeArray();
+
+                formDataArray.forEach(function (entry) {
+                    loginData[entry.name] = entry.value;
+                });
+                if (this.isPasswordVisible()
+                    && $(loginForm).validation()
+                    && $(loginForm).validation('isValid')
+                ) {
+                    loginAction(loginData);
+                }
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/Customer/view/frontend/web/template/customer-email.html b/app/code/Magento/Customer/view/frontend/web/template/customer-email.html
new file mode 100644
index 0000000000000000000000000000000000000000..898a3300ed78e3e2262baaf6fbf040fef297620c
--- /dev/null
+++ b/app/code/Magento/Customer/view/frontend/web/template/customer-email.html
@@ -0,0 +1,67 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<!-- ko ifnot: isCustomerLoggedIn() -->
+
+<!-- ko foreach: getRegion('before-login-form') -->
+<!-- ko template: getTemplate() --><!-- /ko -->
+<!-- /ko -->
+<form class="form form-login" data-role="email-with-possible-login"
+      data-bind="submit:login"
+      method="post">
+    <fieldset id="customer-email-fieldset" class="fieldset" data-bind="blockLoader: isLoading">
+        <div class="field required">
+            <label class="label" for="customer-email">
+                <span data-bind="text: $t('Email Address')"></span>
+            </label>
+            <div class="control _with-tooltip">
+                <input class="input-text"
+                       type="email"
+                       data-bind="textInput: email"
+                       name="username"
+                       data-validate="{required:true, 'validate-email':true}"
+                       id="customer-email" />
+                <!-- ko template: 'ui/form/element/helper/tooltip' --><!-- /ko -->
+                <span class="note"><!-- ko text: $t("(You can create an account after checkout)")--><!-- /ko --></span>
+            </div>
+        </div>
+
+        <!--Hidden fields -->
+        <fieldset class="fieldset hidden-fields" data-bind="fadeVisible: isPasswordVisible">
+            <div class="field">
+                <label class="label" for="customer-password">
+                    <span data-bind="text: $t('Password')"></span>
+                </label>
+                <div class="control">
+                    <input class="input-text"
+                           placeholder="optional"
+                           type="password"
+                           name="password"
+                           id="customer-password"
+                           data-validate="{required:true, 'validate-password':true}" />
+                    <span class="note" data-bind="text: $t('You already have an account with us. Sign in or continue as guest.')"></span>
+                </div>
+
+            </div>
+            <!-- ko foreach: getRegion('additional-login-form-fields') -->
+            <!-- ko template: getTemplate() --><!-- /ko -->
+            <!-- /ko -->
+            <div class="actions-toolbar">
+                <input name="context" type="hidden" value="checkout" />
+                <div class="primary">
+                    <button type="submit" class="action login primary" data-action="checkout-method-login"><span data-bind="text: $t('Login')"></span></button>
+                </div>
+                <div class="secondary">
+                    <a class="action remind" data-bind="attr: { href: forgotPasswordUrl }">
+                        <span data-bind="text: $t('Forgot Your Password?')"></span>
+                    </a>
+                </div>
+            </div>
+        </fieldset>
+        <!--Hidden fields -->
+    </fieldset>
+</form>
+<!-- /ko -->
diff --git a/app/code/Magento/Dhl/view/frontend/layout/checkout_onepage_index.xml b/app/code/Magento/Dhl/view/frontend/layout/checkout_onepage_index.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ac3abe1cd6cb6fa38d82426add0139152f4b1e5b
--- /dev/null
+++ b/app/code/Magento/Dhl/view/frontend/layout/checkout_onepage_index.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+    <body>
+        <referenceBlock name="checkout.root">
+            <arguments>
+                <argument name="jsLayout" xsi:type="array">
+                    <item name="components" xsi:type="array">
+                        <item name="checkout" xsi:type="array">
+                            <item name="children" xsi:type="array">
+                                <item name="steps" xsi:type="array">
+                                    <item name="children" xsi:type="array">
+                                        <item name="shipping-step" xsi:type="array">
+                                            <item name="children" xsi:type="array">
+                                                <item name="step-config" xsi:type="array">
+                                                    <item name="children" xsi:type="array">
+                                                        <item name="shipping-rates-validation" xsi:type="array">
+                                                            <item name="children" xsi:type="array">
+                                                                <item name="dhl-rates-validation" xsi:type="array">
+                                                                    <item name="component" xsi:type="string">Magento_Dhl/js/view/shipping-rates-validation</item>
+                                                                </item>
+                                                            </item>
+                                                        </item>
+                                                    </item>
+                                                </item>
+                                            </item>
+                                        </item>
+                                    </item>
+                                </item>
+                            </item>
+                        </item>
+                    </item>
+                </argument>
+            </arguments>
+        </referenceBlock>
+    </body>
+</page>
diff --git a/app/code/Magento/Dhl/view/frontend/web/js/model/shipping-rates-validation-rules.js b/app/code/Magento/Dhl/view/frontend/web/js/model/shipping-rates-validation-rules.js
new file mode 100644
index 0000000000000000000000000000000000000000..9f22914a8d29b73f75c2dfc51dfc776ed284e557
--- /dev/null
+++ b/app/code/Magento/Dhl/view/frontend/web/js/model/shipping-rates-validation-rules.js
@@ -0,0 +1,23 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [],
+    function () {
+        "use strict";
+        return {
+            getRules: function() {
+                return {
+                    'postcode': {
+                        'required': true
+                    },
+                    'country_id': {
+                        'required': true
+                    }
+                };
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/Dhl/view/frontend/web/js/model/shipping-rates-validator.js b/app/code/Magento/Dhl/view/frontend/web/js/model/shipping-rates-validator.js
new file mode 100644
index 0000000000000000000000000000000000000000..71dac1b92c10ff0cab212709c93478227c2262c1
--- /dev/null
+++ b/app/code/Magento/Dhl/view/frontend/web/js/model/shipping-rates-validator.js
@@ -0,0 +1,30 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [
+        'jquery',
+        'mageUtils',
+        './shipping-rates-validation-rules',
+        'mage/translate'
+    ],
+    function ($, utils, validationRules, $t) {
+        "use strict";
+        return {
+            validationErrors: [],
+            validate: function(address) {
+                var self = this;
+                this.validationErrors = [];
+                $.each(validationRules.getRules(), function(field, rule) {
+                    if (rule.required && utils.isEmpty(address[field])) {
+                        var message = $t('Field ') + field + $t(' is required.');
+                        self.validationErrors.push(message);
+                    }
+                });
+                return !Boolean(this.validationErrors.length);
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/Dhl/view/frontend/web/js/view/shipping-rates-validation.js b/app/code/Magento/Dhl/view/frontend/web/js/view/shipping-rates-validation.js
new file mode 100644
index 0000000000000000000000000000000000000000..de18ca91237cd6affd9e4f56b167bcdbcfd056ef
--- /dev/null
+++ b/app/code/Magento/Dhl/view/frontend/web/js/view/shipping-rates-validation.js
@@ -0,0 +1,27 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*browser:true*/
+/*global define*/
+define(
+    [
+        'uiComponent',
+        'Magento_Checkout/js/model/shipping-rates-validator',
+        'Magento_Checkout/js/model/shipping-rates-validation-rules',
+        '../model/shipping-rates-validator',
+        '../model/shipping-rates-validation-rules'
+    ],
+    function (
+        Component,
+        defaultShippingRatesValidator,
+        defaultShippingRatesValidationRules,
+        dhlShippingRatesValidator,
+        dhlShippingRatesValidationRules
+    ) {
+        "use strict";
+        defaultShippingRatesValidator.registerValidator('dhl', dhlShippingRatesValidator);
+        defaultShippingRatesValidationRules.registerRules('dhl', dhlShippingRatesValidationRules);
+        return Component;
+    }
+);
diff --git a/app/code/Magento/Directory/Helper/Data.php b/app/code/Magento/Directory/Helper/Data.php
index 1f7bae3fd00d0910f2c2c9589c180bd1be37cf16..fbd071c13824eb155d3adbd91b6ee9595beb8a5c 100644
--- a/app/code/Magento/Directory/Helper/Data.php
+++ b/app/code/Magento/Directory/Helper/Data.php
@@ -160,28 +160,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
             $cacheKey = 'DIRECTORY_REGIONS_JSON_STORE' . $this->_storeManager->getStore()->getId();
             $json = $this->_configCacheType->load($cacheKey);
             if (empty($json)) {
-                $countryIds = [];
-                foreach ($this->getCountryCollection() as $country) {
-                    $countryIds[] = $country->getCountryId();
-                }
-                $collection = $this->_regCollectionFactory->create();
-                $collection->addCountryFilter($countryIds)->load();
-                $regions = [
-                    'config' => [
-                        'show_all_regions' => $this->isShowNonRequiredState(),
-                        'regions_required' => $this->getCountriesWithStatesRequired(),
-                    ],
-                ];
-                foreach ($collection as $region) {
-                    /** @var $region \Magento\Directory\Model\Region */
-                    if (!$region->getRegionId()) {
-                        continue;
-                    }
-                    $regions[$region->getCountryId()][$region->getRegionId()] = [
-                        'code' => $region->getCode(),
-                        'name' => (string)__($region->getName()),
-                    ];
-                }
+                $regions = $this->getRegionData();
                 $json = $this->jsonHelper->jsonEncode($regions);
                 if ($json === false) {
                     $json = 'false';
@@ -324,4 +303,36 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
             $store
         );
     }
+
+    /**
+     * Retrieve regions data
+     *
+     * @return array
+     */
+    public function getRegionData()
+    {
+        $countryIds = [];
+        foreach ($this->getCountryCollection() as $country) {
+            $countryIds[] = $country->getCountryId();
+        }
+        $collection = $this->_regCollectionFactory->create();
+        $collection->addCountryFilter($countryIds)->load();
+        $regions = [
+            'config' => [
+                'show_all_regions' => $this->isShowNonRequiredState(),
+                'regions_required' => $this->getCountriesWithStatesRequired(),
+            ],
+        ];
+        foreach ($collection as $region) {
+            /** @var $region \Magento\Directory\Model\Region */
+            if (!$region->getRegionId()) {
+                continue;
+            }
+            $regions[$region->getCountryId()][$region->getRegionId()] = [
+                'code' => $region->getCode(),
+                'name' => (string)__($region->getName()),
+            ];
+        }
+        return $regions;
+    }
 }
diff --git a/app/code/Magento/Directory/Model/Country/Postcode/Config.php b/app/code/Magento/Directory/Model/Country/Postcode/Config.php
new file mode 100644
index 0000000000000000000000000000000000000000..344938c4aaf54bc448544d2439235adddcd0700d
--- /dev/null
+++ b/app/code/Magento/Directory/Model/Country/Postcode/Config.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Directory\Model\Country\Postcode;
+
+class Config implements ConfigInterface
+{
+    /**
+     * @var Config\Data
+     */
+    protected $dataStorage;
+
+    /**
+     * @param Config\Data $dataStorage
+     */
+    public function __construct(\Magento\Directory\Model\Country\Postcode\Config\Data $dataStorage)
+    {
+        $this->dataStorage = $dataStorage;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPostCodes()
+    {
+        return $this->dataStorage->get();
+    }
+}
diff --git a/app/code/Magento/Directory/Model/Country/Postcode/Config/Converter.php b/app/code/Magento/Directory/Model/Country/Postcode/Config/Converter.php
new file mode 100644
index 0000000000000000000000000000000000000000..be9ee4dca475c8be5b5be9364a3741f1b0cde6cd
--- /dev/null
+++ b/app/code/Magento/Directory/Model/Country/Postcode/Config/Converter.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Directory\Model\Country\Postcode\Config;
+
+class Converter implements \Magento\Framework\Config\ConverterInterface
+{
+    /**
+     * @var \Magento\Framework\Stdlib\BooleanUtils
+     */
+    protected $booleanUtils;
+
+    /**
+     * @param \Magento\Framework\Stdlib\BooleanUtils $booleanUtils
+     */
+    public function __construct(\Magento\Framework\Stdlib\BooleanUtils $booleanUtils)
+    {
+        $this->booleanUtils = $booleanUtils;
+    }
+
+    /**
+     * Convert dom node tree to array
+     *
+     * @param \DOMDocument $source
+     * @return array
+     */
+    public function convert($source)
+    {
+        $result = [];
+        /** @var \DOMNode $zipNode */
+        foreach ($source->documentElement->childNodes as $zipNode) {
+            if ($zipNode->nodeType != XML_ELEMENT_NODE) {
+                continue;
+            }
+            $groupName = $zipNode->attributes->getNamedItem('countryCode')->nodeValue;
+            /** @var \DOMNode $codesNode */
+            foreach ($zipNode->childNodes as $codesNode) {
+                if ($codesNode->nodeType != XML_ELEMENT_NODE) {
+                    continue;
+                }
+                /** @var \DOMNode $code */
+                foreach ($codesNode->childNodes as $code) {
+                    if ($code->nodeType != XML_ELEMENT_NODE
+                        || !$this->booleanUtils->toBoolean($code->attributes->getNamedItem('active')->nodeValue)
+                    ) {
+                        continue;
+                    }
+                    $result[$groupName][$code->attributes->getNamedItem('id')->nodeValue] = [
+                        'example' => $code->attributes->getNamedItem('example')->nodeValue,
+                        'pattern' => $code->nodeValue
+                    ];
+                }
+            }
+        }
+        return $result;
+    }
+}
diff --git a/app/code/Magento/Directory/Model/Country/Postcode/Config/Data.php b/app/code/Magento/Directory/Model/Country/Postcode/Config/Data.php
new file mode 100644
index 0000000000000000000000000000000000000000..b3dc1a7a6c7a3c575172f6d2ddc8e87efff99488
--- /dev/null
+++ b/app/code/Magento/Directory/Model/Country/Postcode/Config/Data.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Directory\Model\Country\Postcode\Config;
+
+class Data extends \Magento\Framework\Config\Data
+{
+    /**
+     * @param \Magento\Directory\Model\Country\Postcode\Config\Reader $reader
+     * @param \Magento\Framework\Config\CacheInterface $cache
+     */
+    public function __construct(
+        \Magento\Directory\Model\Country\Postcode\Config\Reader $reader,
+        \Magento\Framework\Config\CacheInterface $cache
+    ) {
+        parent::__construct($reader, $cache, 'country_postcodes');
+    }
+}
diff --git a/app/code/Magento/Directory/Model/Country/Postcode/Config/Reader.php b/app/code/Magento/Directory/Model/Country/Postcode/Config/Reader.php
new file mode 100644
index 0000000000000000000000000000000000000000..7fb5878318dccc009756dc4feacf15ab015f22fd
--- /dev/null
+++ b/app/code/Magento/Directory/Model/Country/Postcode/Config/Reader.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Directory\Model\Country\Postcode\Config;
+
+class Reader extends \Magento\Framework\Config\Reader\Filesystem
+{
+    /**
+     * Construct the FileSystem Reader Class
+     *
+     * @param \Magento\Framework\Config\FileResolverInterface $fileResolver
+     * @param Converter $converter
+     * @param SchemaLocator $schemaLocator
+     * @param \Magento\Framework\Config\ValidationStateInterface $validationState
+     * @param string $fileName
+     * @param array $idAttributes
+     * @param string $domDocumentClass
+     * @param string $defaultScope
+     */
+    public function __construct(
+        \Magento\Framework\Config\FileResolverInterface $fileResolver,
+        Converter $converter,
+        \Magento\Directory\Model\Country\Postcode\Config\SchemaLocator $schemaLocator,
+        \Magento\Framework\Config\ValidationStateInterface $validationState,
+        $fileName = 'zip_codes.xml',
+        $idAttributes = [],
+        $domDocumentClass = 'Magento\Framework\Config\Dom',
+        $defaultScope = 'global'
+    ) {
+        parent::__construct(
+            $fileResolver,
+            $converter,
+            $schemaLocator,
+            $validationState,
+            $fileName,
+            $idAttributes,
+            $domDocumentClass,
+            $defaultScope
+        );
+    }
+}
diff --git a/app/code/Magento/Directory/Model/Country/Postcode/Config/SchemaLocator.php b/app/code/Magento/Directory/Model/Country/Postcode/Config/SchemaLocator.php
new file mode 100644
index 0000000000000000000000000000000000000000..5984a2e501b71983b6c9c6a00bdf546e7f81827a
--- /dev/null
+++ b/app/code/Magento/Directory/Model/Country/Postcode/Config/SchemaLocator.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Directory\Model\Country\Postcode\Config;
+
+class SchemaLocator implements \Magento\Framework\Config\SchemaLocatorInterface
+{
+    /**
+     * Path to corresponding XSD file with validation rules for both individual and merged configs
+     *
+     * @var string
+     */
+    private $schema;
+
+    /**
+     * @param \Magento\Framework\Module\Dir\Reader $moduleReader
+     */
+    public function __construct(\Magento\Framework\Module\Dir\Reader $moduleReader)
+    {
+        $this->schema = $moduleReader->getModuleDir('etc', 'Magento_Directory') . '/zip_codes.xsd';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getSchema()
+    {
+        return $this->schema;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPerFileSchema()
+    {
+        return $this->schema;
+    }
+}
diff --git a/app/code/Magento/Directory/Model/Country/Postcode/ConfigInterface.php b/app/code/Magento/Directory/Model/Country/Postcode/ConfigInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..ac1d487d47575c814c8c364f3e4d438494aaca87
--- /dev/null
+++ b/app/code/Magento/Directory/Model/Country/Postcode/ConfigInterface.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Directory\Model\Country\Postcode;
+
+interface ConfigInterface
+{
+
+    /**
+     * Returns array of postcodes validation patterns
+     *
+     * @return array
+     */
+    public function getPostCodes();
+}
diff --git a/app/code/Magento/Directory/Model/Country/Postcode/Validator.php b/app/code/Magento/Directory/Model/Country/Postcode/Validator.php
new file mode 100644
index 0000000000000000000000000000000000000000..a57d379683b3c802f1ac7060e5f8460a88416907
--- /dev/null
+++ b/app/code/Magento/Directory/Model/Country/Postcode/Validator.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Directory\Model\Country\Postcode;
+
+class Validator implements ValidatorInterface
+{
+    /**
+     * @var ConfigInterface
+     */
+    protected $postCodesConfig;
+
+    /**
+     * @param ConfigInterface $postCodesConfig
+     */
+    public function __construct(\Magento\Directory\Model\Country\Postcode\ConfigInterface $postCodesConfig)
+    {
+        $this->postCodesConfig = $postCodesConfig;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function validate($postcode, $countryId)
+    {
+        $postCodes = $this->postCodesConfig->getPostCodes();
+        if (isset($postCodes[$countryId]) && is_array($postCodes[$countryId])) {
+            $patterns = $postCodes[$countryId];
+            foreach ($patterns as $pattern) {
+                preg_match('/' . $pattern['pattern'] . '/', $postcode, $matches);
+                if (count($matches)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        throw new \InvalidArgumentException('Provided countryId does not exist.');
+    }
+}
diff --git a/app/code/Magento/Directory/Model/Country/Postcode/ValidatorInterface.php b/app/code/Magento/Directory/Model/Country/Postcode/ValidatorInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..b6517be656a31a4ace53ffec657867ae22360ace
--- /dev/null
+++ b/app/code/Magento/Directory/Model/Country/Postcode/ValidatorInterface.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Directory\Model\Country\Postcode;
+
+interface ValidatorInterface
+{
+    /**
+     * Validate postcode for selected country by mask
+     *
+     * @param string $postcode
+     * @param string $countryId
+     * @return bool
+     * @throws \InvalidArgumentException
+     */
+    public function validate($postcode, $countryId);
+}
diff --git a/app/code/Magento/Directory/Test/Unit/Model/Country/Postcode/Config/ConverterTest.php b/app/code/Magento/Directory/Test/Unit/Model/Country/Postcode/Config/ConverterTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a4f4d4b5bbd79536735e3a78a5b1b99bf0ef7893
--- /dev/null
+++ b/app/code/Magento/Directory/Test/Unit/Model/Country/Postcode/Config/ConverterTest.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Directory\Test\Unit\Model\Country\Postcode\Config;
+
+class ConverterTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Customer\Model\Address\Config\Converter
+     */
+    protected $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $booleanUtilsMock;
+
+    public function setUp()
+    {
+        $this->booleanUtilsMock = $this->getMock('Magento\Framework\Stdlib\BooleanUtils', [], [], '', false);
+        $this->model = new \Magento\Directory\Model\Country\Postcode\Config\Converter($this->booleanUtilsMock);
+    }
+
+    public function testConvert()
+    {
+        $inputData = new \DOMDocument();
+        $this->booleanUtilsMock->expects($this->any())->method('toBoolean')->willReturn(true);
+        $inputData->load(__DIR__ . '/../../../../_files/zip_codes.xml');
+        $expectedResult = require __DIR__ . '/../../../../_files/zip_codes.php';
+        $this->assertEquals($expectedResult, $this->model->convert($inputData));
+    }
+}
diff --git a/app/code/Magento/Directory/Test/Unit/Model/Country/Postcode/Config/DataTest.php b/app/code/Magento/Directory/Test/Unit/Model/Country/Postcode/Config/DataTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..18663e83e74f9c63b1a2ca9f51e9b84cc8d82882
--- /dev/null
+++ b/app/code/Magento/Directory/Test/Unit/Model/Country/Postcode/Config/DataTest.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Directory\Test\Unit\Model\Country\Postcode\Config;
+
+class DataTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $readerMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $cacheMock;
+
+    protected function setUp()
+    {
+        $this->readerMock = $this->getMockBuilder(
+            'Magento\Directory\Model\Country\Postcode\Config\Reader'
+        )->disableOriginalConstructor()->getMock();
+        $this->cacheMock = $this->getMockBuilder(
+            'Magento\Framework\App\Cache\Type\Config'
+        )->disableOriginalConstructor()->getMock();
+    }
+
+    public function testGet()
+    {
+        $expected = ['someData' => ['someValue', 'someKey' => 'someValue']];
+        $this->cacheMock->expects($this->any())->method('load')->will($this->returnValue(serialize($expected)));
+        $configData = new \Magento\Directory\Model\Country\Postcode\Config\Data($this->readerMock, $this->cacheMock);
+
+        $this->assertEquals($expected, $configData->get());
+    }
+}
diff --git a/app/code/Magento/Directory/Test/Unit/Model/Country/Postcode/Config/ReaderTest.php b/app/code/Magento/Directory/Test/Unit/Model/Country/Postcode/Config/ReaderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..066dcbcbd6668e319b1ea9c9e9b2a5c728f69064
--- /dev/null
+++ b/app/code/Magento/Directory/Test/Unit/Model/Country/Postcode/Config/ReaderTest.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Directory\Test\Unit\Model\Country\Postcode\Config;
+
+class ReaderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Sales\Model\Config\Reader
+     */
+    protected $reader;
+
+    /**
+     * Prepare parameters
+     */
+    public function setUp()
+    {
+        $fileResolver = $this->getMockBuilder(
+            'Magento\Framework\App\Config\FileResolver'
+        )->disableOriginalConstructor()->getMock();
+        $converter = $this->getMockBuilder(
+            'Magento\Directory\Model\Country\Postcode\Config\Converter'
+        )->disableOriginalConstructor()->getMock();
+        $schema = $this->getMockBuilder(
+            'Magento\Directory\Model\Country\Postcode\Config\SchemaLocator'
+        )->disableOriginalConstructor()->getMock();
+        $validator = $this->getMockBuilder(
+            'Magento\Framework\Config\ValidationStateInterface'
+        )->disableOriginalConstructor()->getMock();
+        $this->reader = new \Magento\Directory\Model\Country\Postcode\Config\Reader(
+            $fileResolver,
+            $converter,
+            $schema,
+            $validator
+        );
+    }
+
+    /**
+     * Test creating object
+     */
+    public function testInstanceof()
+    {
+        $this->assertInstanceOf('Magento\Directory\Model\Country\Postcode\Config\Reader', $this->reader);
+    }
+}
diff --git a/app/code/Magento/Directory/Test/Unit/Model/Country/Postcode/Config/SchemaLocatorTest.php b/app/code/Magento/Directory/Test/Unit/Model/Country/Postcode/Config/SchemaLocatorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..794dc5a1ce9fe90129b8e8f47e8f73a004d1f2e6
--- /dev/null
+++ b/app/code/Magento/Directory/Test/Unit/Model/Country/Postcode/Config/SchemaLocatorTest.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Directory\Test\Unit\Model\Country\Postcode\Config;
+
+class SchemaLocatorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $moduleReaderMock;
+
+    /**
+     * @var \Magento\Directory\Model\Country\Postcode\Config\SchemaLocator
+     */
+    protected $model;
+
+    protected function setUp()
+    {
+        $this->moduleReaderMock = $this->getMock('Magento\Framework\Module\Dir\Reader', [], [], '', false);
+        $this->moduleReaderMock->expects(
+            $this->any()
+        )->method(
+            'getModuleDir'
+        )->with(
+            'etc',
+            'Magento_Directory'
+        )->will(
+            $this->returnValue('schema_dir')
+        );
+
+        $this->model = new \Magento\Directory\Model\Country\Postcode\Config\SchemaLocator($this->moduleReaderMock);
+    }
+
+    public function testGetSchema()
+    {
+        $this->assertEquals('schema_dir/zip_codes.xsd', $this->model->getSchema());
+    }
+
+    public function testGetPerFileSchema()
+    {
+        $this->assertEquals('schema_dir/zip_codes.xsd', $this->model->getPerFileSchema());
+    }
+}
diff --git a/app/code/Magento/Directory/Test/Unit/Model/Country/Postcode/ConfigTest.php b/app/code/Magento/Directory/Test/Unit/Model/Country/Postcode/ConfigTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d24ead182cb394c290616125b3084a466eb8a385
--- /dev/null
+++ b/app/code/Magento/Directory/Test/Unit/Model/Country/Postcode/ConfigTest.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Directory\Test\Unit\Model\Country\Postcode;
+
+class ConfigTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $dataStorageMock;
+
+    protected function setUp()
+    {
+        $this->dataStorageMock = $this->getMock(
+            '\Magento\Directory\Model\Country\Postcode\Config\Data',
+            [],
+            [],
+            '',
+            false
+        );
+    }
+
+    public function testGet()
+    {
+        $expected = ['US' => ['pattern_01' => 'pattern_01', 'pattern_02' => 'pattern_02']];
+        $this->dataStorageMock->expects($this->once())->method('get')->willReturn($expected);
+        $configData = new \Magento\Directory\Model\Country\Postcode\Config($this->dataStorageMock);
+        $this->assertEquals($expected, $configData->getPostCodes());
+    }
+}
diff --git a/app/code/Magento/Directory/Test/Unit/Model/Country/Postcode/ValidatorTest.php b/app/code/Magento/Directory/Test/Unit/Model/Country/Postcode/ValidatorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7bf2562a6ed01b9f0d725a50ba9ce6eae6bf9c01
--- /dev/null
+++ b/app/code/Magento/Directory/Test/Unit/Model/Country/Postcode/ValidatorTest.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Directory\Test\Unit\Model\Country\Postcode;
+
+class ValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $postcodesConfigMock;
+
+    /**
+     * @var \Magento\Directory\Model\Country\Postcode\Validator
+     */
+    protected $model;
+
+    protected function setUp()
+    {
+        $this->postcodesConfigMock = $this->getMock(
+            '\Magento\Directory\Model\Country\Postcode\Config',
+            [],
+            [],
+            '',
+            false
+        );
+        $postCodes = [
+            'US' => [
+                'pattern_1' => ['pattern' => '^[0-9]{5}\-[0-9]{4}$'],
+                'pattern_2' => ['pattern' => '^[0-9]{5}$']
+            ]
+        ];
+        $this->postcodesConfigMock->expects($this->once())->method('getPostCodes')->willReturn($postCodes);
+        $this->model = new \Magento\Directory\Model\Country\Postcode\Validator($this->postcodesConfigMock);
+    }
+
+    public function testValidatePositive()
+    {
+        $postcode = '12345-6789';
+        $countryId = 'US';
+        $this->assertTrue($this->model->validate($postcode, $countryId));
+    }
+
+    public function testValidateNegative()
+    {
+        $postcode = 'POST-CODE';
+        $countryId = 'US';
+        $this->assertFalse($this->model->validate($postcode, $countryId));
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     * @expectedExceptionMessage Provided countryId does not exist.
+     */
+    public function testValidateThrowExceptionIfCountryDoesNotExist()
+    {
+        $postcode = '12345-6789';
+        $countryId = 'QQ';
+        $this->assertFalse($this->model->validate($postcode, $countryId));
+    }
+}
diff --git a/app/code/Magento/Directory/Test/Unit/_files/zip_codes.php b/app/code/Magento/Directory/Test/Unit/_files/zip_codes.php
new file mode 100644
index 0000000000000000000000000000000000000000..7a151e73a3e72cd6b7c86874441aeaa2a1106c87
--- /dev/null
+++ b/app/code/Magento/Directory/Test/Unit/_files/zip_codes.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+return [
+    'US' => [
+        'pattern_1' => [
+            'example' => 12345,
+            'pattern' => '^[0-9]{5}\-[0-9]{4}$'
+        ],
+        'pattern_2' => [
+            'example' => 12345,
+            'pattern' => '^[0-9]{5}$'
+        ]
+    ]
+];
diff --git a/app/code/Magento/Directory/Test/Unit/_files/zip_codes.xml b/app/code/Magento/Directory/Test/Unit/_files/zip_codes.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bbe7582ea62c267702eb25b4415ea01ac9585e8f
--- /dev/null
+++ b/app/code/Magento/Directory/Test/Unit/_files/zip_codes.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Directory/etc/zip_codes.xsd">
+    <zip countryCode="US">
+        <codes>
+            <code id="pattern_1" example="12345" active="true">^[0-9]{5}\-[0-9]{4}$</code>
+            <code id="pattern_2" example="12345" active="true">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+</config>
diff --git a/app/code/Magento/Directory/etc/di.xml b/app/code/Magento/Directory/etc/di.xml
index 36d16743f8363c39e4aa87e8019fcb0a51014af5..c1e11e69808025b7013f0e5837ec784ca0f40be3 100644
--- a/app/code/Magento/Directory/etc/di.xml
+++ b/app/code/Magento/Directory/etc/di.xml
@@ -27,4 +27,6 @@
             <argument name="helperData" xsi:type="object">DirectoryHelperDataProxy</argument>
         </arguments>
     </type>
+    <preference for="Magento\Directory\Model\Country\Postcode\ConfigInterface" type="Magento\Directory\Model\Country\Postcode\Config" />
+    <preference for="Magento\Directory\Model\Country\Postcode\ValidatorInterface" type="Magento\Directory\Model\Country\Postcode\Validator" />
 </config>
diff --git a/app/code/Magento/Directory/etc/zip_codes.xml b/app/code/Magento/Directory/etc/zip_codes.xml
new file mode 100644
index 0000000000000000000000000000000000000000..dfca9b740fa036ae66a94aaac0fc60154a79a626
--- /dev/null
+++ b/app/code/Magento/Directory/etc/zip_codes.xml
@@ -0,0 +1,487 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Directory/etc/zip_codes.xsd">
+    <zip countryCode="DZ">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="AS">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="AR">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="AM">
+        <codes>
+            <code id="pattern_1" active="true" example="123456">^[0-9]{6}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="AU">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="AT">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="AZ">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+            <code id="pattern_2" active="true" example="123456">^[0-9]{6}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="BD">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="BY">
+        <codes>
+            <code id="pattern_1" active="true" example="123456">^[0-9]{6}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="BE">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="BA">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="BR">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+            <code id="pattern_2" active="true" example="12345-678">^[0-9]{5}\-[0-9]{3}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="BN">
+        <codes>
+            <code id="pattern_1" active="true" example="AB1234">^[a-zA-z]{2}[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="BG">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="CA">
+        <codes>
+            <code id="pattern_1" active="true" example="A1B 2C3">^[a-zA-z]{1}[0-9]{1}[a-zA-z]{1}\s[0-9]{1}[a-zA-z]{1}[0-9]{1}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="IC">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="CN">
+        <codes>
+            <code id="pattern_1" active="true" example="123456">^[0-9]{6}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="HR">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="CU">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="CY">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="CZ">
+        <codes>
+            <code id="pattern_1" active="true" example="123 45">^[0-9]{3}\s[0-9]{2}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="DK">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="EE">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="FI">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="FR">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="GF">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="GE">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="DE">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="GR">
+        <codes>
+            <code id="pattern_1" active="true" example="123 45">^[0-9]{3}\s[0-9]{2}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="GL">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="GP">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="GU">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="GG">
+        <codes>
+            <code id="pattern_1" active="true" example="AB1 2CD">^[a-zA-Z]{2}[0-9]{1}\s[0-9]{1}[a-zA-Z]{2}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="HU">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="IS">
+        <codes>
+            <code id="pattern_1" active="true" example="123">^[0-9]{3}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="IN">
+        <codes>
+            <code id="pattern_1" active="true" example="123456">^[0-9]{6}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="ID">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="IL">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="IT">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="JP">
+        <codes>
+            <code id="pattern_1" active="true" example="123-4567">^[0-9]{3}-[0-9]{4}$</code>
+            <code id="pattern_2" active="true" example="123">^[0-9]{3}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="JE">
+        <codes>
+            <code id="pattern_1" active="true" example="AB1 2CD">^[a-zA-Z]{2}[0-9]{1}\s[0-9]{1}[a-zA-Z]{2}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="KZ">
+        <codes>
+            <code id="pattern_1" active="true" example="123456">^[0-9]{6}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="KE">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="KR">
+        <codes>
+            <code id="pattern_1" active="true" example="123-456">^[0-9]{3}-[0-9]{3}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="KG">
+        <codes>
+            <code id="pattern_1" active="true" example="123456">^[0-9]{6}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="LV">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="LI">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="LT">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="LU">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="MK">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="MG">
+        <codes>
+            <code id="pattern_1" active="true" example="123">^[0-9]{3}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="MY">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="MV">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+            <code id="pattern_2" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="MT">
+        <codes>
+            <code id="pattern_1" active="true" example="ABC 123">^[a-zA-Z]{3}\s[0-9]{3}$</code>
+            <code id="pattern_2" active="true" example="ABC 12">^[a-zA-Z]{3}\s[0-9]{2}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="MH">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="MQ">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="MX">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="MD">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="MC">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="MN">
+        <codes>
+            <code id="pattern_1" active="true" example="123456">^[0-9]{6}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="MA">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="NL">
+        <codes>
+            <code id="pattern_1" active="true" example="1234 AB">^[0-9]{4}\s[a-zA-Z]{2}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="NO">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="PK">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="PH">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="PL">
+        <codes>
+            <code id="pattern_1" active="true" example="12-345">^[0-9]{2}-[0-9]{3}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="PT">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+            <code id="pattern_2" active="true" example="1234-567">^[0-9]{4}-[0-9]{3}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="PR">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="RE">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="RO">
+        <codes>
+            <code id="pattern_1" active="true" example="123456">^[0-9]{6}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="RU">
+        <codes>
+            <code id="pattern_1" active="true" example="123456">^[0-9]{6}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="MP">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="CS">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="SG">
+        <codes>
+            <code id="pattern_1" active="true" example="123456">^[0-9]{6}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="SK">
+        <codes>
+            <code id="pattern_1" active="true" example="123 45">^[0-9]{3}\s[0-9]{2}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="SI">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="ZA">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="ES">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="XY">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="SZ">
+        <codes>
+            <code id="pattern_1" active="true" example="A123">^[a-zA-Z]{1}[0-9]{3}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="SE">
+        <codes>
+            <code id="pattern_1" active="true" example="123 45">^[0-9]{3}\s[0-9]{2}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="CH">
+        <codes>
+            <code id="pattern_1" active="true" example="1234">^[0-9]{4}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="TW">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+            <code id="pattern_2" active="true" example="123">^[0-9]{3}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="TJ">
+        <codes>
+            <code id="pattern_1" active="true" example="123456">^[0-9]{6}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="TH">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="TR">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="TM">
+        <codes>
+            <code id="pattern_1" active="true" example="123456">^[0-9]{6}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="UA">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="GB">
+        <codes>
+            <code id="pattern_1" active="true" example="AB12 3CD">^[a-zA-Z]{2}[0-9]{2}\s[0-9]{1}[a-zA-Z]{2}$</code>
+            <code id="pattern_2" active="true" example="A1B 2CD">^[a-zA-Z]{1}[0-9]{1}[a-zA-Z]{1}\s[0-9]{1}[a-zA-Z]{2}$</code>
+            <code id="pattern_3" active="true" example="AB1 2CD">^[a-zA-Z]{2}[0-9]{1}\s[0-9]{1}[a-zA-Z]{2}$</code>
+            <code id="pattern_4" active="true" example="AB1C 2DF">^[a-zA-Z]{2}[0-9]{1}[a-zA-Z]{1}\s[0-9]{1}[a-zA-Z]{2}$</code>
+            <code id="pattern_5" active="true" example="A12 3BC">^[a-zA-Z]{1}[0-9]{2}\s[0-9]{1}[a-zA-Z]{2}$</code>
+            <code id="pattern_6" active="true" example="A1 2BC">^[a-zA-Z]{1}[0-9]{1}\s[0-9]{1}[a-zA-Z]{2}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="US">
+        <codes>
+            <code id="pattern_1" active="true" example="12345-6789">^[0-9]{5}\-[0-9]{4}$</code>
+            <code id="pattern_2" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="UY">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="UZ">
+        <codes>
+            <code id="pattern_1" active="true" example="123456">^[0-9]{6}$</code>
+        </codes>
+    </zip>
+    <zip countryCode="VI">
+        <codes>
+            <code id="pattern_1" active="true" example="12345">^[0-9]{5}$</code>
+        </codes>
+    </zip>
+</config>
diff --git a/app/code/Magento/Directory/etc/zip_codes.xsd b/app/code/Magento/Directory/etc/zip_codes.xsd
new file mode 100644
index 0000000000000000000000000000000000000000..5400633a0df327bc20546c074d4b5b89d6ccdd12
--- /dev/null
+++ b/app/code/Magento/Directory/etc/zip_codes.xsd
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+    <xs:element name="config" type="configType">
+    </xs:element>
+
+    <xs:complexType name="zipType">
+        <xs:sequence>
+            <xs:element type="codesType" name="codes"/>
+        </xs:sequence>
+        <xs:attribute type="xs:string" name="countryCode" use="required"/>
+    </xs:complexType>
+
+    <xs:complexType name="codesType">
+        <xs:sequence>
+            <xs:element type="codeType" name="code" maxOccurs="unbounded" minOccurs="0"/>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="configType">
+        <xs:sequence>
+            <xs:element type="zipType" name="zip" maxOccurs="unbounded" minOccurs="1"/>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="codeType">
+        <xs:simpleContent>
+            <xs:extension base="xs:string">
+                <xs:attribute type="xs:string" name="id" use="required"/>
+                <xs:attribute type="xs:string" name="example" use="required"/>
+                <xs:attribute type="xs:boolean" name="active" use="optional"/>
+            </xs:extension>
+        </xs:simpleContent>
+    </xs:complexType>
+</xs:schema>
\ No newline at end of file
diff --git a/app/code/Magento/Fedex/view/frontend/layout/checkout_onepage_index.xml b/app/code/Magento/Fedex/view/frontend/layout/checkout_onepage_index.xml
new file mode 100644
index 0000000000000000000000000000000000000000..541e46a36a627814c6989c5c8d237e7d1e83aaf5
--- /dev/null
+++ b/app/code/Magento/Fedex/view/frontend/layout/checkout_onepage_index.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+    <body>
+        <referenceBlock name="checkout.root">
+            <arguments>
+                <argument name="jsLayout" xsi:type="array">
+                    <item name="components" xsi:type="array">
+                        <item name="checkout" xsi:type="array">
+                            <item name="children" xsi:type="array">
+                                <item name="steps" xsi:type="array">
+                                    <item name="children" xsi:type="array">
+                                        <item name="shipping-step" xsi:type="array">
+                                            <item name="children" xsi:type="array">
+                                                <item name="step-config" xsi:type="array">
+                                                    <item name="children" xsi:type="array">
+                                                        <item name="shipping-rates-validation" xsi:type="array">
+                                                            <item name="children" xsi:type="array">
+                                                                <item name="fedex-rates-validation" xsi:type="array">
+                                                                    <item name="component" xsi:type="string">Magento_Fedex/js/view/shipping-rates-validation</item>
+                                                                </item>
+                                                            </item>
+                                                        </item>
+                                                    </item>
+                                                </item>
+                                            </item>
+                                        </item>
+                                    </item>
+                                </item>
+                            </item>
+                        </item>
+                    </item>
+                </argument>
+            </arguments>
+        </referenceBlock>
+    </body>
+</page>
diff --git a/app/code/Magento/Fedex/view/frontend/web/js/model/shipping-rates-validation-rules.js b/app/code/Magento/Fedex/view/frontend/web/js/model/shipping-rates-validation-rules.js
new file mode 100644
index 0000000000000000000000000000000000000000..9f22914a8d29b73f75c2dfc51dfc776ed284e557
--- /dev/null
+++ b/app/code/Magento/Fedex/view/frontend/web/js/model/shipping-rates-validation-rules.js
@@ -0,0 +1,23 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [],
+    function () {
+        "use strict";
+        return {
+            getRules: function() {
+                return {
+                    'postcode': {
+                        'required': true
+                    },
+                    'country_id': {
+                        'required': true
+                    }
+                };
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/Fedex/view/frontend/web/js/model/shipping-rates-validator.js b/app/code/Magento/Fedex/view/frontend/web/js/model/shipping-rates-validator.js
new file mode 100644
index 0000000000000000000000000000000000000000..71dac1b92c10ff0cab212709c93478227c2262c1
--- /dev/null
+++ b/app/code/Magento/Fedex/view/frontend/web/js/model/shipping-rates-validator.js
@@ -0,0 +1,30 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [
+        'jquery',
+        'mageUtils',
+        './shipping-rates-validation-rules',
+        'mage/translate'
+    ],
+    function ($, utils, validationRules, $t) {
+        "use strict";
+        return {
+            validationErrors: [],
+            validate: function(address) {
+                var self = this;
+                this.validationErrors = [];
+                $.each(validationRules.getRules(), function(field, rule) {
+                    if (rule.required && utils.isEmpty(address[field])) {
+                        var message = $t('Field ') + field + $t(' is required.');
+                        self.validationErrors.push(message);
+                    }
+                });
+                return !Boolean(this.validationErrors.length);
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/Fedex/view/frontend/web/js/view/shipping-rates-validation.js b/app/code/Magento/Fedex/view/frontend/web/js/view/shipping-rates-validation.js
new file mode 100644
index 0000000000000000000000000000000000000000..dc9bc66b93e5ee503719ef80794bf1fb91a9acfe
--- /dev/null
+++ b/app/code/Magento/Fedex/view/frontend/web/js/view/shipping-rates-validation.js
@@ -0,0 +1,27 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*browser:true*/
+/*global define*/
+define(
+    [
+        'uiComponent',
+        'Magento_Checkout/js/model/shipping-rates-validator',
+        'Magento_Checkout/js/model/shipping-rates-validation-rules',
+        '../model/shipping-rates-validator',
+        '../model/shipping-rates-validation-rules'
+    ],
+    function (
+        Component,
+        defaultShippingRatesValidator,
+        defaultShippingRatesValidationRules,
+        fedexShippingRatesValidator,
+        fedexShippingRatesValidationRules
+    ) {
+        "use strict";
+        defaultShippingRatesValidator.registerValidator('fedex', fedexShippingRatesValidator);
+        defaultShippingRatesValidationRules.registerRules('fedex', fedexShippingRatesValidationRules);
+        return Component;
+    }
+);
diff --git a/app/code/Magento/GiftMessage/view/frontend/web/js/action/gift-options.js b/app/code/Magento/GiftMessage/view/frontend/web/js/action/gift-options.js
index 4896aeb00b5b87c57ad90cdcc86c26e68da0b794..51e72540458efd1cd3a3f8fe564f148e9357a0b7 100644
--- a/app/code/Magento/GiftMessage/view/frontend/web/js/action/gift-options.js
+++ b/app/code/Magento/GiftMessage/view/frontend/web/js/action/gift-options.js
@@ -7,10 +7,10 @@ define(
     [
         '../model/url-builder',
         'mage/storage',
-        'Magento_Ui/js/model/errorlist',
+        'Magento_Ui/js/model/messageList',
         'mage/url'
     ],
-    function(urlBuilder, storage, errorList, url) {
+    function(urlBuilder, storage, messageList, url) {
         "use strict";
         return function(giftMessage, remove) {
             url.setBaseUrl(giftMessage.getConfigValue('baseUrl'));
@@ -30,7 +30,7 @@ define(
                     );
                 }
             }
-            errorList.clear();
+            messageList.clear();
 
             storage.post(
                 serviceUrl,
@@ -49,7 +49,7 @@ define(
             ).fail(
                 function(response) {
                     var error = JSON.parse(response.responseText);
-                    errorList.add(error);
+                    messageList.addErrorMessage(error);
                 }
             );
         };
diff --git a/app/code/Magento/OfflinePayments/view/frontend/layout/checkout_onepage_index.xml b/app/code/Magento/OfflinePayments/view/frontend/layout/checkout_onepage_index.xml
index c6140255ab7f1141c453b557d25a282a92abc897..8e1eb709250e00164ef7c62f3dc6468334b0ef73 100644
--- a/app/code/Magento/OfflinePayments/view/frontend/layout/checkout_onepage_index.xml
+++ b/app/code/Magento/OfflinePayments/view/frontend/layout/checkout_onepage_index.xml
@@ -15,30 +15,34 @@
                             <item name="children" xsi:type="array">
                                 <item name="steps" xsi:type="array">
                                     <item name="children" xsi:type="array">
-                                        <item name="payment" xsi:type="array">
+                                        <item name="billing-step" xsi:type="array">
+                                            <item name="component" xsi:type="string">uiComponent</item>
+                                            <item name="sortOrder" xsi:type="string">2</item>
                                             <item name="children" xsi:type="array">
-                                                <item name="checkmo" xsi:type="array">
-                                                    <item name="component" xsi:type="string">Magento_OfflinePayments/js/view/payment/checkmo-method</item>
-                                                    <item name="config" xsi:type="array">
-                                                        <item name="formTemplate" xsi:type="string">Magento_OfflinePayments/payment/checkmo-form</item>
-                                                    </item>
-                                                </item>
-                                                <item name="cashondelivery" xsi:type="array">
-                                                    <item name="component" xsi:type="string">Magento_OfflinePayments/js/view/payment/instructions-method</item>
-                                                    <item name="config" xsi:type="array">
-                                                        <item name="formTemplate" xsi:type="string">Magento_OfflinePayments/payment/instructions-form</item>
-                                                    </item>
-                                                </item>
-                                                <item name="banktransfer" xsi:type="array">
-                                                    <item name="component" xsi:type="string">Magento_OfflinePayments/js/view/payment/instructions-method</item>
-                                                    <item name="config" xsi:type="array">
-                                                        <item name="formTemplate" xsi:type="string">Magento_OfflinePayments/payment/instructions-form</item>
-                                                    </item>
-                                                </item>
-                                                <item name="purchaseorder" xsi:type="array">
-                                                    <item name="component" xsi:type="string">Magento_OfflinePayments/js/view/payment/purchaseorder-method</item>
-                                                    <item name="config" xsi:type="array">
-                                                        <item name="formTemplate" xsi:type="string">Magento_OfflinePayments/payment/purchaseorder-form</item>
+                                                <item name="payment" xsi:type="array">
+                                                    <item name="children" xsi:type="array">
+                                                        <item name="renders" xsi:type="array">
+                                                            <!-- merge payment method renders here -->
+                                                            <item name="children" xsi:type="array">
+                                                                <item name="offline-payments" xsi:type="array">
+                                                                    <item name="component" xsi:type="string">Magento_OfflinePayments/js/view/payment/offline-payments</item>
+                                                                    <item name="methods" xsi:type="array">
+                                                                        <item name="checkmo" xsi:type="array">
+                                                                            <item name="isBillingAddressRequired" xsi:type="boolean">true</item>
+                                                                        </item>
+                                                                        <item name="banktransfer" xsi:type="array">
+                                                                            <item name="isBillingAddressRequired" xsi:type="boolean">true</item>
+                                                                        </item>
+                                                                        <item name="cashondelivery" xsi:type="array">
+                                                                            <item name="isBillingAddressRequired" xsi:type="boolean">true</item>
+                                                                        </item>
+                                                                        <item name="purchaseorder" xsi:type="array">
+                                                                            <item name="isBillingAddressRequired" xsi:type="boolean">true</item>
+                                                                        </item>
+                                                                    </item>
+                                                                </item>
+                                                            </item>
+                                                        </item>
                                                     </item>
                                                 </item>
                                             </item>
@@ -52,4 +56,4 @@
             </arguments>
         </referenceBlock>
     </body>
-</page>
+</page>
\ No newline at end of file
diff --git a/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/checkmo-method.js b/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/checkmo-method.js
deleted file mode 100644
index 5093e525aaea7e12e2e138f33884d33217120b54..0000000000000000000000000000000000000000
--- a/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/checkmo-method.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*browser:true*/
-/*global define*/
-define(
-    [
-        'Magento_Checkout/js/view/payment/method-info',
-        'mage/translate'
-    ],
-    function (methodInfo, $t) {
-        return methodInfo.extend({
-            getMailingAddress: function() {
-                return window.checkoutConfig.payment.checkmo.mailingAddress;
-            },
-            getPayableTo: function() {
-                return window.checkoutConfig.payment.checkmo.payableTo;
-            },
-            getInfo: function() {
-                var info = [];
-                if (this.getPayableTo()) {
-                    info.push({name: $t('Make Check payable to')});
-                    info.push({value: this.getPayableTo()});
-                }
-                if (this.getMailingAddress()) {
-                    info.push({name: $t('Send Check to')});
-                    info.push({html: this.getMailingAddress()});
-                }
-                return info;
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/instructions-method.js b/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/instructions-method.js
deleted file mode 100644
index a3d9e9cdbae67265888a71dfe8aaae79fdbf778c..0000000000000000000000000000000000000000
--- a/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/instructions-method.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*browser:true*/
-/*global define*/
-define(
-    [
-        'Magento_Checkout/js/view/payment/method-info'
-    ],
-    function (methodInfo) {
-        return methodInfo.extend({
-            getInstructions: function() {
-                return window.checkoutConfig.payment.instructions[this.getCode()];
-            },
-            getInfo: function() {
-                var info = [];
-                if (this.getInstructions()) {
-                    info.push({html: this.getInstructions()});
-                }
-                return info;
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/method-renderer/banktransfer-method.js b/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/method-renderer/banktransfer-method.js
new file mode 100644
index 0000000000000000000000000000000000000000..e139bbf2fa4b1d5148317167bc8d4a1ae2392bc9
--- /dev/null
+++ b/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/method-renderer/banktransfer-method.js
@@ -0,0 +1,26 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define(
+    [
+        'ko',
+        'Magento_Checkout/js/view/payment/default'
+    ],
+    function (ko, Component) {
+        'use strict';
+
+        return Component.extend({
+            defaults: {
+                template: 'Magento_OfflinePayments/payment/banktransfer'
+            },
+            /**
+             * Get value of instruction field.
+             * @returns {String}
+             */
+            getInstructions: function () {
+                return window.checkoutConfig.payment.instructions[this.item.method];
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/method-renderer/cashondelivery-method.js b/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/method-renderer/cashondelivery-method.js
new file mode 100644
index 0000000000000000000000000000000000000000..9dea96883c3235d087e106bc20b728f9fc8315da
--- /dev/null
+++ b/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/method-renderer/cashondelivery-method.js
@@ -0,0 +1,24 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*browser:true*/
+/*global define*/
+define(
+    [
+        'Magento_Checkout/js/view/payment/default'
+    ],
+    function (Component) {
+        'use strict';
+        return Component.extend({
+            defaults: {
+                template: 'Magento_OfflinePayments/payment/cashondelivery'
+            },
+
+            /** Returns payment method instructions */
+            getInstructions: function() {
+                return window.checkoutConfig.payment.instructions[this.item.method];
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/method-renderer/checkmo-method.js b/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/method-renderer/checkmo-method.js
new file mode 100644
index 0000000000000000000000000000000000000000..6eb00662593f1e0a2213af36b50fc6ca29f271c7
--- /dev/null
+++ b/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/method-renderer/checkmo-method.js
@@ -0,0 +1,30 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*browser:true*/
+/*global define*/
+define(
+    [
+        'Magento_Checkout/js/view/payment/default'
+    ],
+    function (Component) {
+        'use strict';
+
+        return Component.extend({
+            defaults: {
+                template: 'Magento_OfflinePayments/payment/checkmo'
+            },
+
+            /** Returns send check to info */
+            getMailingAddress: function() {
+                return window.checkoutConfig.payment.checkmo.mailingAddress;
+            },
+
+            /** Returns payable to info */
+            getPayableTo: function() {
+                return window.checkoutConfig.payment.checkmo.payableTo;
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/method-renderer/purchaseorder-method.js b/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/method-renderer/purchaseorder-method.js
new file mode 100644
index 0000000000000000000000000000000000000000..a5d09084f5cb8c5fefdb256cfdf94079f2b9e9e6
--- /dev/null
+++ b/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/method-renderer/purchaseorder-method.js
@@ -0,0 +1,44 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*browser:true*/
+/*global define*/
+define(
+    [
+        'Magento_Checkout/js/view/payment/default',
+        'jquery',
+        "mage/validation"
+    ],
+    function (Component, $) {
+        'use strict';
+        return Component.extend({
+            defaults: {
+                template: 'Magento_OfflinePayments/payment/purchaseorder-form',
+                purchaseOrderNumber: ''
+            },
+            initObservable: function () {
+                this._super()
+                    .observe('purchaseOrderNumber');
+                return this;
+            },
+            getData: function () {
+                return {
+                    "method": this.item.method,
+                    'po_number': this.purchaseOrderNumber(),
+                    "cc_owner": null,
+                    "cc_number": null,
+                    "cc_type": null,
+                    "cc_exp_year": null,
+                    "cc_exp_month": null,
+                    "additional_data": null
+                };
+
+            },
+            validate: function () {
+                var form = '#purchaseorder';
+                return $(form).validation() && $(form).validation('isValid');
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/offline-payments.js b/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/offline-payments.js
new file mode 100644
index 0000000000000000000000000000000000000000..809df962245fb2c225f117b2866c6b3d4c70a5bd
--- /dev/null
+++ b/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/offline-payments.js
@@ -0,0 +1,38 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*browser:true*/
+/*global define*/
+define(
+    [
+        'uiComponent',
+        'Magento_Checkout/js/model/payment/renderer-list'
+    ],
+    function (
+        Component,
+        rendererList
+    ) {
+        'use strict';
+        rendererList.push(
+            {
+                type: 'checkmo',
+                component: 'Magento_OfflinePayments/js/view/payment/method-renderer/checkmo-method'
+            },
+            {
+                type: 'banktransfer',
+                component: 'Magento_OfflinePayments/js/view/payment/method-renderer/banktransfer-method'
+            },
+            {
+                type: 'cashondelivery',
+                component: 'Magento_OfflinePayments/js/view/payment/method-renderer/cashondelivery-method'
+            },
+            {
+                type: 'purchaseorder',
+                component: 'Magento_OfflinePayments/js/view/payment/method-renderer/purchaseorder-method'
+            }
+        );
+        /** Add view logic here if needed */
+        return Component.extend({});
+    }
+);
\ No newline at end of file
diff --git a/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/purchaseorder-method.js b/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/purchaseorder-method.js
deleted file mode 100644
index 1233199cc2d862f2048fb7bcf1f0f05e72502a2a..0000000000000000000000000000000000000000
--- a/app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/purchaseorder-method.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*browser:true*/
-/*global define*/
-define(
-    [
-        'jquery',
-        "mage/translate",
-        'Magento_Checkout/js/view/payment/method-info'
-    ],
-    function ($, $t, methodInfo) {
-        return methodInfo.extend({
-            defaults: {
-                purchaseOrderNumber: ''
-            },
-            initObservable: function () {
-                this._super()
-                    .observe('purchaseOrderNumber');
-                return this;
-            },
-            getData: function() {
-                return {'po_number': this.purchaseOrderNumber()};
-            },
-            getInfo: function() {
-                return [
-                    {'name': 'Purchase Order Number', value: this.purchaseOrderNumber()}
-                ];
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/banktransfer.html b/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/banktransfer.html
new file mode 100644
index 0000000000000000000000000000000000000000..dfcbf3131970749bfec9ab0537c3ef12f689fae7
--- /dev/null
+++ b/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/banktransfer.html
@@ -0,0 +1,40 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<div class="payment-method" data-bind="css: {'_active': (getCode() == isChecked())}">
+    <div class="payment-method-title field choice">
+        <input type="radio"
+               name="payment[method]"
+               class="radio"
+               data-bind="attr: {'id': getCode()}, value: getCode(), checked: isChecked, click: selectPaymentMethod, visible: isRadioButtonVisible()" />
+        <label data-bind="attr: {'for': getCode()}" class="label"><span data-bind="text: getTitle()"></span></label>
+    </div>
+
+    <div class="payment-method-content">
+        <div class="payment-method-billing-address">
+            <!-- ko foreach: $parent.getRegion(getBillingAddressFormName()) -->
+            <!-- ko template: getTemplate() --><!-- /ko -->
+            <!--/ko-->
+        </div>
+        <p data-bind="text: getInstructions()"></p>
+        <div class="checkout-agreements-block">
+            <!-- ko foreach: $parent.getRegion('before-place-order') -->
+                <!-- ko template: getTemplate() --><!-- /ko -->
+            <!--/ko-->
+        </div>
+        <div class="actions-toolbar">
+            <div class="primary">
+                <button class="action primary checkout"
+                        type="submit"
+                        data-bind="click: placeOrder, attr: {'title': $t('Place Order')}, enable: (getCode() == isChecked())"
+                        disabled>
+                    <span data-bind="text: $t('Place Order')"></span>
+                </button>
+            </div>
+        </div>
+    </div>
+</div>
+        
\ No newline at end of file
diff --git a/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/cashondelivery.html b/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/cashondelivery.html
new file mode 100644
index 0000000000000000000000000000000000000000..569d5b0a48eb368622fee51306a8d9c30b075cf7
--- /dev/null
+++ b/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/cashondelivery.html
@@ -0,0 +1,41 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<div class="payment-method" data-bind="css: {'_active': (getCode() == isChecked())}">
+    <div class="payment-method-title field choice">
+        <input type="radio"
+               name="payment[method]"
+               class="radio"
+               data-bind="attr: {'id': getCode()}, value: getCode(), checked: isChecked, click: selectPaymentMethod, visible: isRadioButtonVisible()"/>
+        <label data-bind="attr: {'for': getCode()}" class="label"><span data-bind="text: getTitle()"></span></label>
+    </div>
+
+    <div class="payment-method-content">
+        <div class="payment-method-billing-address">
+            <!-- ko foreach: $parent.getRegion(getBillingAddressFormName()) -->
+            <!-- ko template: getTemplate() --><!-- /ko -->
+            <!--/ko-->
+        </div>
+        <p data-bind="text: getInstructions()"></p>
+        <div class="checkout-agreements-block">
+            <!-- ko foreach: $parent.getRegion('before-place-order') -->
+                <!-- ko template: getTemplate() --><!-- /ko -->
+            <!--/ko-->
+        </div>
+        <div class="actions-toolbar">
+            <div class="primary">
+                <button class="action primary checkout"
+                        type="submit"
+                        data-bind="click: placeOrder, attr: {title: $t('Place Order')}, enable: (getCode() == isChecked())"
+                        disabled>
+                    <span data-bind="text: $t('Place Order')"></span>
+                </button>
+            </div>
+        </div>
+
+    </div>
+</div>
+        
\ No newline at end of file
diff --git a/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/checkmo-form.html b/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/checkmo-form.html
deleted file mode 100644
index 92c84f0662ddda6acf0fdff41ed3233ff69fe447..0000000000000000000000000000000000000000
--- a/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/checkmo-form.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<!-- ko if: getMailingAddress() || getPayableTo() -->
-<dl class="items check payable" id="payment_form_<?php echo $block->getMethodCode() ?>">
-    <!-- ko if: getPayableTo() -->
-    <dt class="title"><!-- ko text: $t('Make Check payable to:') --><!-- /ko --></dt>
-    <dd class="content"><!-- ko text: $t(getPayableTo()) --><!-- /ko --></dd>
-    <!-- /ko -->
-    <!-- ko if: getMailingAddress() -->
-    <dt class="title"><!-- ko text: $t('Send Check to:') --><!-- /ko --></dt>
-    <dd class="content">
-        <address class="checkmo mailing address" data-bind="html: $t(getMailingAddress())"></address>
-    </dd>
-    <!-- /ko -->
-</dl>
-<!-- /ko -->
diff --git a/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/checkmo.html b/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/checkmo.html
new file mode 100644
index 0000000000000000000000000000000000000000..58f85845434792ab778b177461ac493a743d649d
--- /dev/null
+++ b/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/checkmo.html
@@ -0,0 +1,52 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<div class="payment-method" data-bind="css: {'_active': (getCode() == isChecked())}">
+    <div class="payment-method-title field choice">
+        <input type="radio"
+               name="payment[method]"
+               class="radio"
+               data-bind="attr: {'id': getCode()}, value: getCode(), checked: isChecked, click: selectPaymentMethod, visible: isRadioButtonVisible()"/>
+        <label data-bind="attr: {'for': getCode()}" class="label"><span data-bind="text: getTitle()"></span></label>
+    </div>
+    <div class="payment-method-content">
+        <div class="payment-method-billing-address">
+            <!-- ko foreach: $parent.getRegion(getBillingAddressFormName()) -->
+            <!-- ko template: getTemplate() --><!-- /ko -->
+            <!--/ko-->
+        </div>
+        <!-- ko if: getMailingAddress() || getPayableTo() -->
+        <dl class="items check payable">
+            <!-- ko if: getPayableTo() -->
+            <dt class="title"><!-- ko text: $t('Make Check payable to:') --><!-- /ko --></dt>
+            <dd class="content"><!-- ko text: $t(getPayableTo()) --><!-- /ko --></dd>
+            <!-- /ko -->
+            <!-- ko if: getMailingAddress() -->
+            <dt class="title"><!-- ko text: $t('Send Check to:') --><!-- /ko --></dt>
+            <dd class="content">
+                <address class="checkmo mailing address" data-bind="html: $t(getMailingAddress())"></address>
+            </dd>
+            <!-- /ko -->
+        </dl>
+        <!-- /ko -->
+        <div class="checkout-agreements-block">
+            <!-- ko foreach: $parent.getRegion('before-place-order') -->
+                <!-- ko template: getTemplate() --><!-- /ko -->
+            <!--/ko-->
+        </div>
+        <div class="actions-toolbar">
+            <div class="primary">
+                <button class="action primary checkout"
+                        type="submit"
+                        data-bind="click: placeOrder, attr: {title: $t('Place Order')}, enable: (getCode() == isChecked())"
+                        disabled>
+                    <span data-bind="text: $t('Place Order')"></span>
+                </button>
+            </div>
+        </div>
+    </div>
+</div>
+        
\ No newline at end of file
diff --git a/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/instructions-form.html b/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/instructions-form.html
deleted file mode 100644
index 56f30d9cc42c14d7997f02c5c51b0dd22624fb21..0000000000000000000000000000000000000000
--- a/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/instructions-form.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<!-- ko if: getInstructions() -->
-<div data-bind="attr: {class: 'items ' + getCode() + ' instructions agreement content', id: 'payment_form_' + getCode()}, html: $t(getInstructions())"></div>
-<!-- /ko -->
\ No newline at end of file
diff --git a/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/purchaseorder-form.html b/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/purchaseorder-form.html
index 828045b5b7321a6893dc0493cb48d2e5ea14341e..585d61feae7d7c7423285c3db12f5351adc2d385 100644
--- a/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/purchaseorder-form.html
+++ b/app/code/Magento/OfflinePayments/view/frontend/web/template/payment/purchaseorder-form.html
@@ -4,19 +4,59 @@
  * See COPYING.txt for license details.
  */
 -->
-<fieldset class="fieldset payment method" data-bind='attr: {id: "payment_form_" + getCode()}'>
-    <div class="field field-number required">
-        <label for="po_number" class="label"><span><!-- ko text: $t('Purchase Order Number')--><!-- /ko --></span></label>
-        <div class="control">
-            <input type="text"
-                   id="po_number"
-                   name="payment[po_number]"
-                   data-validate="{required:true}"
-                   data-bind='
-                        attr: {title: $t("Purchase Order Number")},
-                        value: purchaseOrderNumber,
-                        enable: isActive($parent)'
-                   class="input-text"/>
+<div class="payment-method" data-bind="css: {'_active': (getCode() == isChecked())}">
+    <form id="purchaseorder-form" class="form form-purchase-order">
+
+        <div class="payment-method-title field choice">
+            <input type="radio"
+                   name="payment[method]"
+                   class="radio"
+                   data-bind="attr: {'id': getCode()}, value: getCode(), checked: isChecked, click: selectPaymentMethod, visible: isRadioButtonVisible()"/>
+            <label data-bind="attr: {'for': getCode()}" class="label">
+                <span data-bind="text: getTitle()"></span>
+            </label>
         </div>
-    </div>
-</fieldset>
\ No newline at end of file
+
+        <div class="payment-method-content">
+            <div class="payment-method-billing-address">
+                <!-- ko foreach: $parent.getRegion(getBillingAddressFormName()) -->
+                <!-- ko template: getTemplate() --><!-- /ko -->
+                <!--/ko-->
+            </div>
+
+            <fieldset class="fieldset payment method" data-bind='attr: {id: "payment_form_" + getCode()}'>
+                <div class="field field-number required">
+                    <label for="po_number" class="label">
+                        <span><!-- ko text: $t('Purchase Order Number')--><!-- /ko --></span>
+                    </label>
+                    <div class="control">
+                        <input type="text"
+                               id="po_number"
+                               name="payment[po_number]"
+                               data-validate="{required:true}"
+                               data-bind='
+                                attr: {title: $t("Purchase Order Number")},
+                                value: purchaseOrderNumber'
+                               class="input-text"/>
+                    </div>
+                </div>
+                <div class="checkout-agreements-block">
+                    <!-- ko foreach: $parent.getRegion('before-place-order') -->
+                        <!-- ko template: getTemplate() --><!-- /ko -->
+                    <!--/ko-->
+                </div>
+                <div class="actions-toolbar" id="review-buttons-container">
+                    <div class="primary">
+                        <button class="action primary checkout"
+                                type="submit"
+                                data-bind="click: placeOrder, attr: {title: $t('Place Order')}, enable: (getCode() == isChecked())"
+                                data-role="review-save">
+                            <span data-bind="text: $t('Place Order')"></span>
+                        </button>
+                    </div>
+                </div>
+            </fieldset>
+        </div>
+    </form>
+</div>
+        
\ No newline at end of file
diff --git a/app/code/Magento/OfflineShipping/view/frontend/layout/checkout_onepage_index.xml b/app/code/Magento/OfflineShipping/view/frontend/layout/checkout_onepage_index.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f97709a21bd0aa5313a6bdc0f44ef0167205a1e1
--- /dev/null
+++ b/app/code/Magento/OfflineShipping/view/frontend/layout/checkout_onepage_index.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+    <body>
+        <referenceBlock name="checkout.root">
+            <arguments>
+                <argument name="jsLayout" xsi:type="array">
+                    <item name="components" xsi:type="array">
+                        <item name="checkout" xsi:type="array">
+                            <item name="children" xsi:type="array">
+                                <item name="steps" xsi:type="array">
+                                    <item name="children" xsi:type="array">
+                                        <item name="shipping-step" xsi:type="array">
+                                            <item name="children" xsi:type="array">
+                                                <item name="step-config" xsi:type="array">
+                                                    <item name="children" xsi:type="array">
+                                                        <item name="shipping-rates-validation" xsi:type="array">
+                                                            <item name="children" xsi:type="array">
+                                                                <item name="freeshipping-rates-validation" xsi:type="array">
+                                                                    <item name="component" xsi:type="string">Magento_OfflineShipping/js/view/shipping-rates-validation/freeshipping</item>
+                                                                </item>
+                                                                <item name="flatrate-rates-validation" xsi:type="array">
+                                                                    <item name="component" xsi:type="string">Magento_OfflineShipping/js/view/shipping-rates-validation/flatrate</item>
+                                                                </item>
+                                                                <item name="tablerate-rates-validation" xsi:type="array">
+                                                                    <item name="component" xsi:type="string">Magento_OfflineShipping/js/view/shipping-rates-validation/tablerate</item>
+                                                                </item>
+                                                            </item>
+                                                        </item>
+                                                    </item>
+                                                </item>
+                                            </item>
+                                        </item>
+                                    </item>
+                                </item>
+                            </item>
+                        </item>
+                    </item>
+                </argument>
+            </arguments>
+        </referenceBlock>
+    </body>
+</page>
diff --git a/app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validation-rules/flatrate.js b/app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validation-rules/flatrate.js
new file mode 100644
index 0000000000000000000000000000000000000000..f45450e5359e06c86e85badb235aa193797c3a48
--- /dev/null
+++ b/app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validation-rules/flatrate.js
@@ -0,0 +1,20 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [],
+    function () {
+        "use strict";
+        return {
+            getRules: function() {
+                return {
+                    'country_id': {
+                        'required': true
+                    }
+                };
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validation-rules/freeshipping.js b/app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validation-rules/freeshipping.js
new file mode 100644
index 0000000000000000000000000000000000000000..f45450e5359e06c86e85badb235aa193797c3a48
--- /dev/null
+++ b/app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validation-rules/freeshipping.js
@@ -0,0 +1,20 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [],
+    function () {
+        "use strict";
+        return {
+            getRules: function() {
+                return {
+                    'country_id': {
+                        'required': true
+                    }
+                };
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validation-rules/tablerate.js b/app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validation-rules/tablerate.js
new file mode 100644
index 0000000000000000000000000000000000000000..174ca5d9b9506d9c7ea4d39d45b4bf1502ba6104
--- /dev/null
+++ b/app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validation-rules/tablerate.js
@@ -0,0 +1,26 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [],
+    function () {
+        "use strict";
+        return {
+            getRules: function() {
+                return {
+                    'postcode': {
+                        'required': true
+                    },
+                    'country_id': {
+                        'required': true
+                    },
+                    'region_id': {
+                        'required': true
+                    }
+                };
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validator/flatrate.js b/app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validator/flatrate.js
new file mode 100644
index 0000000000000000000000000000000000000000..39faae263931600a6eec596c1e127ce6098b595d
--- /dev/null
+++ b/app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validator/flatrate.js
@@ -0,0 +1,30 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [
+        'jquery',
+        'mageUtils',
+        '../shipping-rates-validation-rules/flatrate',
+        'mage/translate'
+    ],
+    function ($, utils, validationRules, $t) {
+        "use strict";
+        return {
+            validationErrors: [],
+            validate: function(address) {
+                var self = this;
+                this.validationErrors = [];
+                $.each(validationRules.getRules(), function(field, rule) {
+                    if (rule.required && utils.isEmpty(address[field])) {
+                        var message = $t('Field ') + field + $t(' is required.');
+                        self.validationErrors.push(message);
+                    }
+                });
+                return !Boolean(this.validationErrors.length);
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validator/freeshipping.js b/app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validator/freeshipping.js
new file mode 100644
index 0000000000000000000000000000000000000000..d3e970cc8f7676a446ab94bc1c727cc7ad7a11cf
--- /dev/null
+++ b/app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validator/freeshipping.js
@@ -0,0 +1,30 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [
+        'jquery',
+        'mageUtils',
+        '../shipping-rates-validation-rules/freeshipping',
+        'mage/translate'
+    ],
+    function ($, utils, validationRules, $t) {
+        "use strict";
+        return {
+            validationErrors: [],
+            validate: function(address) {
+                var self = this;
+                this.validationErrors = [];
+                $.each(validationRules.getRules(), function(field, rule) {
+                    if (rule.required && utils.isEmpty(address[field])) {
+                        var message = $t('Field ') + field + $t(' is required.');
+                        self.validationErrors.push(message);
+                    }
+                });
+                return !Boolean(this.validationErrors.length);
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validator/tablerate.js b/app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validator/tablerate.js
new file mode 100644
index 0000000000000000000000000000000000000000..3a04b4cf03756da06de7a377ef65df08fe8599de
--- /dev/null
+++ b/app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validator/tablerate.js
@@ -0,0 +1,30 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [
+        'jquery',
+        'mageUtils',
+        '../shipping-rates-validation-rules/tablerate',
+        'mage/translate'
+    ],
+    function ($, utils, validationRules, $t) {
+        "use strict";
+        return {
+            validationErrors: [],
+            validate: function(address) {
+                var self = this;
+                this.validationErrors = [];
+                $.each(validationRules.getRules(), function(field, rule) {
+                    if (rule.required && utils.isEmpty(address[field])) {
+                        var message = $t('Field ') + field + $t(' is required.');
+                        self.validationErrors.push(message);
+                    }
+                });
+                return !Boolean(this.validationErrors.length);
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/OfflineShipping/view/frontend/web/js/view/shipping-rates-validation/flatrate.js b/app/code/Magento/OfflineShipping/view/frontend/web/js/view/shipping-rates-validation/flatrate.js
new file mode 100644
index 0000000000000000000000000000000000000000..c7cd3490469ad1b1c18a30fb1873ee7b2d9b9e2b
--- /dev/null
+++ b/app/code/Magento/OfflineShipping/view/frontend/web/js/view/shipping-rates-validation/flatrate.js
@@ -0,0 +1,27 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*browser:true*/
+/*global define*/
+define(
+    [
+        'uiComponent',
+        'Magento_Checkout/js/model/shipping-rates-validator',
+        'Magento_Checkout/js/model/shipping-rates-validation-rules',
+        '../../model/shipping-rates-validator/flatrate',
+        '../../model/shipping-rates-validation-rules/flatrate'
+    ],
+    function (
+        Component,
+        defaultShippingRatesValidator,
+        defaultShippingRatesValidationRules,
+        flatrateShippingRatesValidator,
+        flatrateShippingRatesValidationRules
+    ) {
+        "use strict";
+        defaultShippingRatesValidator.registerValidator('flatrate', flatrateShippingRatesValidator);
+        defaultShippingRatesValidationRules.registerRules('flatrate', flatrateShippingRatesValidationRules);
+        return Component;
+    }
+);
diff --git a/app/code/Magento/OfflineShipping/view/frontend/web/js/view/shipping-rates-validation/freeshipping.js b/app/code/Magento/OfflineShipping/view/frontend/web/js/view/shipping-rates-validation/freeshipping.js
new file mode 100644
index 0000000000000000000000000000000000000000..a58024dcff35edb777ec6f6da89a3707364ae75f
--- /dev/null
+++ b/app/code/Magento/OfflineShipping/view/frontend/web/js/view/shipping-rates-validation/freeshipping.js
@@ -0,0 +1,27 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*browser:true*/
+/*global define*/
+define(
+    [
+        'uiComponent',
+        'Magento_Checkout/js/model/shipping-rates-validator',
+        'Magento_Checkout/js/model/shipping-rates-validation-rules',
+        '../../model/shipping-rates-validator/freeshipping',
+        '../../model/shipping-rates-validation-rules/freeshipping'
+    ],
+    function (
+        Component,
+        defaultShippingRatesValidator,
+        defaultShippingRatesValidationRules,
+        freeshippingShippingRatesValidator,
+        freeshippingShippingRatesValidationRules
+    ) {
+        "use strict";
+        defaultShippingRatesValidator.registerValidator('freeshipping', freeshippingShippingRatesValidator);
+        defaultShippingRatesValidationRules.registerRules('freeshipping', freeshippingShippingRatesValidationRules);
+        return Component;
+    }
+);
diff --git a/app/code/Magento/OfflineShipping/view/frontend/web/js/view/shipping-rates-validation/tablerate.js b/app/code/Magento/OfflineShipping/view/frontend/web/js/view/shipping-rates-validation/tablerate.js
new file mode 100644
index 0000000000000000000000000000000000000000..9f9754eedd202d1a8fb6c766d44de4e91f66bdd3
--- /dev/null
+++ b/app/code/Magento/OfflineShipping/view/frontend/web/js/view/shipping-rates-validation/tablerate.js
@@ -0,0 +1,27 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*browser:true*/
+/*global define*/
+define(
+    [
+        'uiComponent',
+        'Magento_Checkout/js/model/shipping-rates-validator',
+        'Magento_Checkout/js/model/shipping-rates-validation-rules',
+        '../../model/shipping-rates-validator/tablerate',
+        '../../model/shipping-rates-validation-rules/tablerate'
+    ],
+    function (
+        Component,
+        defaultShippingRatesValidator,
+        defaultShippingRatesValidationRules,
+        tablerateShippingRatesValidator,
+        tablerateShippingRatesValidationRules
+    ) {
+        "use strict";
+        defaultShippingRatesValidator.registerValidator('tablerate', tablerateShippingRatesValidator);
+        defaultShippingRatesValidationRules.registerRules('tablerate', tablerateShippingRatesValidationRules);
+        return Component;
+    }
+);
diff --git a/app/code/Magento/Payment/view/adminhtml/templates/transparent/form.phtml b/app/code/Magento/Payment/view/adminhtml/templates/transparent/form.phtml
index c6a429a0fbe08f624c53f03d7998879281dfde27..a2cf8e3a6383311ba7b2e20bd57c858fa88d368f 100644
--- a/app/code/Magento/Payment/view/adminhtml/templates/transparent/form.phtml
+++ b/app/code/Magento/Payment/view/adminhtml/templates/transparent/form.phtml
@@ -7,14 +7,22 @@
 <?php
 // @codingStandardsIgnoreFile
 
-/** @var \Magento\Payment\Block\Transparent\Form $block*/
+/** @var \Magento\Payment\Block\Transparent\Form $block */
 $code = $block->getMethodCode();
 ?>
 
 <!-- IFRAME for request to Payment Gateway -->
-<iframe id="<?php echo $code ?>-transparent-iframe" data-container="<?php echo $code ?>-transparent-iframe" allowtransparency="true" frameborder="0"  name="iframeTransparent" style="display:none;width:100%;background-color:transparent" src="<?php echo $block->getViewFileUrl('blank.html') ?>"></iframe>
-<div id="payment_form_<?php echo $code ?>"
-     data-mage-init='{
+<iframe id="<?php echo $code ?>-transparent-iframe"
+        data-container="<?php echo $code ?>-transparent-iframe"
+        allowtransparency="true"
+        frameborder="0"
+        name="iframeTransparent"
+        style="display: none; width: 100%; background-color: transparent;"
+        src="<?php echo $block->getViewFileUrl('blank.html') ?>"></iframe>
+<fieldset
+    id="payment_form_<?php echo $code ?>"
+    class="admin__fieldset"
+    data-mage-init='{
      "transparent":{
         "controller":"<?php echo $block->getRequest()->getControllerName() ?>",
         "gateway":"<?php echo $block->getMethodCode() ?>",
@@ -25,71 +33,96 @@ $code = $block->getMethodCode();
         "expireYearLength":"<?php echo $block->getMethodConfigData('cc_year_length') ?>",
         "nativeAction":"<?php echo $block->getUrl('*/*/save', ['_secure' => $block->getRequest()->isSecure()]) ?>"
       }, "validation":[]}'
-     style="display:none;">
+    style="display: none;">
+    <div class="admin__field _required">
+        <label for="<?php echo $code ?>_cc_type" class="admin__field-label">
+            <span><?php echo __('Credit Card Type') ?></span>
+        </label>
 
-        <div class="field required type">
-            <label for="<?php echo $code ?>_cc_type" class="label"><span><?php echo __('Credit Card Type') ?></span></label>
-            <div class="control">
-                <select id="<?php echo $code ?>_cc_type" data-container="<?php echo $code ?>-cc-type" name="payment[cc_type]" data-validate='{required:true, "validate-cc-type-select":"#<?php echo $code ?>_cc_number"}'>
-                    <option value=""><?php echo __('--Please Select--')?></option>
-                    <?php $_ccType = $block->getInfoData('cc_type') ?>
-                    <?php foreach ($block->getCcAvailableTypes() as $_typeCode => $_typeName): ?>
-                        <option value="<?php echo $_typeCode ?>"<?php if ($_typeCode == $_ccType): ?> selected="selected"<?php endif ?>><?php echo $_typeName ?></option>
-                    <?php endforeach ?>
-                </select>
-            </div>
+        <div class="admin__field-control">
+            <select id="<?php echo $code ?>_cc_type"
+                    data-container="<?php echo $code ?>-cc-type"
+                    name="payment[cc_type]"
+                    data-validate='{required:true, "validate-cc-type-select":"#<?php echo $code ?>_cc_number"}'
+                    class="admin__control-select">
+                <option value=""><?php echo __('Please Select') ?></option>
+                <?php $_ccType = $block->getInfoData('cc_type') ?>
+                <?php foreach ($block->getCcAvailableTypes() as $_typeCode => $_typeName): ?>
+                    <option
+                        value="<?php echo $_typeCode ?>"<?php if ($_typeCode == $_ccType): ?> selected="selected"<?php endif ?>><?php echo $_typeName ?></option>
+                <?php endforeach ?>
+            </select>
         </div>
+    </div>
 
-        <div class="field required number">
-            <label for="<?php echo $code ?>_cc_number" class="label"><span><?php echo __('Credit Card Number') ?></span></label>
-            <div class="control">
-                <input type="number" id="<?php echo $code ?>_cc_number" data-container="<?php echo $code ?>-cc-number" name="payment[cc_number]" title="<?php echo __('Credit Card Number') ?>" class="input-text" value="" data-validate='{"required-number":true, "validate-cc-number":"#<?php echo $code ?>_cc_type", "validate-cc-type":"#<?php echo $code ?>_cc_type"}' autocomplete="off"/>
-            </div>
+    <div class="admin__field _required field-number">
+        <label for="<?php echo $code ?>_cc_number" class="admin__field-label">
+            <span><?php echo __('Credit Card Number') ?></span>
+        </label>
+
+        <div class="admin__field-control">
+            <input type="text" id="<?php echo $code ?>_cc_number" data-container="<?php echo $code ?>-cc-number"
+                   name="payment[cc_number]" title="<?php echo __('Credit Card Number') ?>"
+                   class="admin__control-text"
+                   value=""
+                   data-validate='{"required-number":true, "validate-cc-number":"#<?php echo $code ?>_cc_type", "validate-cc-type":"#<?php echo $code ?>_cc_type"}'
+                   autocomplete="off"/>
         </div>
+    </div>
 
-        <div class="field required date" id="<?php echo $code ?>_cc_type_exp_div">
-            <label for="<?php echo $code ?>_expiration" class="label"><span><?php echo __('Expiration Date') ?></span></label>
-            <div class="control">
-                <div class="fields group group-2">
-                    <div class="field no-label month">
-                        <div class="control">
-                            <select id="<?php echo $code ?>_expiration" name="payment[cc_exp_month]" data-container="<?php echo $code ?>-cc-month" class="month" data-validate='{required:true, "validate-cc-exp":"#<?php echo $code ?>_expiration_yr"}'>
-                                <?php $_ccExpMonth = $block->getInfoData('cc_exp_month') ?>
-                                <?php foreach ($block->getCcMonths() as $k => $v): ?>
-                                    <option value="<?php echo $k ? $k : '' ?>"<?php if ($k == $_ccExpMonth): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
-                                <?php endforeach ?>
-                            </select>
-                        </div>
-                    </div>
-                    <div class="field no-label year">
-                        <div class="control">
-                            <?php $_ccExpYear = $block->getInfoData('cc_exp_year') ?>
-                            <select id="<?php echo $code ?>_expiration_yr" name="payment[cc_exp_year]" class="year" data-container="<?php echo $code ?>-cc-year" data-validate='{required:true}'>
-                                <?php foreach ($block->getCcYears() as $k => $v): ?>
-                                    <option value="<?php echo $k ? $k : '' ?>"<?php if ($k == $_ccExpYear): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
-                                <?php endforeach ?>
-                            </select>
-                        </div>
-                    </div>
-                </div>
-            </div>
+    <div class="admin__field _required field-date" id="<?php echo $code ?>_cc_type_exp_div">
+        <label for="<?php echo $code ?>_expiration" class="admin__field-label">
+            <span><?php echo __('Expiration Date') ?></span>
+        </label>
+
+        <div class="admin__field-control">
+            <select id="<?php echo $code ?>_expiration" name="payment[cc_exp_month]"
+                    data-container="<?php echo $code ?>-cc-month"
+                    class="admin__control-select admin__control-select-month"
+                    data-validate='{required:true, "validate-cc-exp":"#<?php echo $code ?>_expiration_yr"}'>
+                <?php $_ccExpMonth = $block->getInfoData('cc_exp_month') ?>
+                <?php foreach ($block->getCcMonths() as $k => $v): ?>
+                    <option
+                        value="<?php echo $k ? $k : '' ?>"<?php if ($k == $_ccExpMonth): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
+                <?php endforeach ?>
+            </select>
+
+            <?php $_ccExpYear = $block->getInfoData('cc_exp_year') ?>
+            <select id="<?php echo $code ?>_expiration_yr" name="payment[cc_exp_year]"
+                    class="admin__control-select admin__control-select-year"
+                    data-container="<?php echo $code ?>-cc-year" data-validate='{required:true}'>
+                <?php foreach ($block->getCcYears() as $k => $v): ?>
+                    <option
+                        value="<?php echo $k ? $k : '' ?>"<?php if ($k == $_ccExpYear): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
+                <?php endforeach ?>
+            </select>
         </div>
-        <?php if ($block->hasVerification()): ?>
-            <div class="field required cvv" id="<?php echo $code ?>_cc_type_cvv_div">
-                <label for="<?php echo $code ?>_cc_cid" class="label"><span><?php echo __('Card Verification Number') ?></span></label>
-                <div class="control">
-                    <input type="number" title="<?php echo __('Card Verification Number') ?>" data-container="<?php echo $code ?>-cc-cvv" class="input-text cvv" id="<?php echo $code ?>_cc_cid" name="payment[cc_cid]" value="" data-validate='{"required-number":true, "validate-cc-cvn":"#<?php echo $code ?>_cc_type"}' autocomplete="off"/>
-                </div>
+    </div>
+    <?php if ($block->hasVerification()): ?>
+        <div class="admin__field _required field-cvv" id="<?php echo $code ?>_cc_type_cvv_div">
+            <label for="<?php echo $code ?>_cc_cid" class="admin__field-label">
+                <span><?php echo __('Card Verification Number') ?></span>
+            </label>
+
+            <div class="admin__field-control">
+                <input type="text" title="<?php echo __('Card Verification Number') ?>"
+                       data-container="<?php echo $code ?>-cc-cvv"
+                       class="admin__control-text cvv"
+                       id="<?php echo $code ?>_cc_cid" name="payment[cc_cid]"
+                       value=""
+                       data-validate='{"required-number":true, "validate-cc-cvn":"#<?php echo $code ?>_cc_type"}'
+                       autocomplete="off"/>
             </div>
-        <?php endif; ?>
-        <?php echo $block->getChildHtml() ?>
-</div>
+        </div>
+    <?php endif; ?>
+    <?php echo $block->getChildHtml() ?>
+</fieldset>
 
 <script>
     /**
      * Disable card server validation in admin
      */
-    require(["Magento_Sales/order/create/form"], function(){
+    require(["Magento_Sales/order/create/form"], function () {
         order.addExcludedPaymentMethod('<?php echo $code ?>');
     });
 </script>
diff --git a/app/code/Magento/Payment/view/base/web/images/cc/ae.png b/app/code/Magento/Payment/view/base/web/images/cc/ae.png
new file mode 100644
index 0000000000000000000000000000000000000000..f72ae5c26c314ac95ebfabb5887f3a1daf4cdd22
Binary files /dev/null and b/app/code/Magento/Payment/view/base/web/images/cc/ae.png differ
diff --git a/app/code/Magento/Payment/view/base/web/images/cc/di.png b/app/code/Magento/Payment/view/base/web/images/cc/di.png
new file mode 100644
index 0000000000000000000000000000000000000000..130d5a4aec88e9eec99e435f94f75725bf5728c7
Binary files /dev/null and b/app/code/Magento/Payment/view/base/web/images/cc/di.png differ
diff --git a/app/code/Magento/Payment/view/base/web/images/cc/dn.png b/app/code/Magento/Payment/view/base/web/images/cc/dn.png
new file mode 100644
index 0000000000000000000000000000000000000000..3444db7ea5945a86ac9ca506a5ff25939bb49c6b
Binary files /dev/null and b/app/code/Magento/Payment/view/base/web/images/cc/dn.png differ
diff --git a/app/code/Magento/Payment/view/base/web/images/cc/jc.png b/app/code/Magento/Payment/view/base/web/images/cc/jc.png
new file mode 100644
index 0000000000000000000000000000000000000000..86df1caa5da6e869e462941402e1129213e9f05c
Binary files /dev/null and b/app/code/Magento/Payment/view/base/web/images/cc/jc.png differ
diff --git a/app/code/Magento/Payment/view/base/web/images/cc/mc.png b/app/code/Magento/Payment/view/base/web/images/cc/mc.png
new file mode 100644
index 0000000000000000000000000000000000000000..bf0a4c2b8727fa824f3e902e88ee31d4d144a474
Binary files /dev/null and b/app/code/Magento/Payment/view/base/web/images/cc/mc.png differ
diff --git a/app/code/Magento/Payment/view/base/web/images/cc/sm.png b/app/code/Magento/Payment/view/base/web/images/cc/sm.png
new file mode 100644
index 0000000000000000000000000000000000000000..d239695ab2a41091981b4f34732276281bf8c992
Binary files /dev/null and b/app/code/Magento/Payment/view/base/web/images/cc/sm.png differ
diff --git a/app/code/Magento/Payment/view/base/web/images/cc/un.png b/app/code/Magento/Payment/view/base/web/images/cc/un.png
new file mode 100644
index 0000000000000000000000000000000000000000..b60791a0900184b6aea16155e06777ea7646158c
Binary files /dev/null and b/app/code/Magento/Payment/view/base/web/images/cc/un.png differ
diff --git a/app/code/Magento/Payment/view/base/web/images/cc/vi.png b/app/code/Magento/Payment/view/base/web/images/cc/vi.png
new file mode 100644
index 0000000000000000000000000000000000000000..0885f78a93765fa61e350c60641302b498b109c0
Binary files /dev/null and b/app/code/Magento/Payment/view/base/web/images/cc/vi.png differ
diff --git a/app/code/Magento/Payment/view/frontend/layout/checkout_onepage_index.xml b/app/code/Magento/Payment/view/frontend/layout/checkout_onepage_index.xml
index 3f89143cb971ba996a0a3298a3807bec96d2d958..979a1c039cfedda69eb2821b528ad9c246824b68 100644
--- a/app/code/Magento/Payment/view/frontend/layout/checkout_onepage_index.xml
+++ b/app/code/Magento/Payment/view/frontend/layout/checkout_onepage_index.xml
@@ -15,10 +15,26 @@
                             <item name="children" xsi:type="array">
                                 <item name="steps" xsi:type="array">
                                     <item name="children" xsi:type="array">
-                                        <item name="payment" xsi:type="array">
+                                        <item name="billing-step" xsi:type="array">
+                                            <item name="component" xsi:type="string">uiComponent</item>
+                                            <item name="sortOrder" xsi:type="string">2</item>
                                             <item name="children" xsi:type="array">
-                                                <item name="free" xsi:type="array">
-                                                    <item name="component" xsi:type="string">Magento_Payment/js/view/payment/free-method</item>
+                                                <item name="payment" xsi:type="array">
+                                                    <item name="children" xsi:type="array">
+                                                        <item name="renders" xsi:type="array">
+                                                            <!-- merge payment method renders here -->
+                                                            <item name="children" xsi:type="array">
+                                                                <item name="free-payments" xsi:type="array">
+                                                                    <item name="component" xsi:type="string">Magento_Payment/js/view/payment/payments</item>
+                                                                    <item name="methods" xsi:type="array">
+                                                                        <item name="free" xsi:type="array">
+                                                                            <item name="isBillingAddressRequired" xsi:type="boolean">true</item>
+                                                                        </item>
+                                                                    </item>
+                                                                </item>
+                                                            </item>
+                                                        </item>
+                                                    </item>
                                                 </item>
                                             </item>
                                         </item>
@@ -31,4 +47,4 @@
             </arguments>
         </referenceBlock>
     </body>
-</page>
+</page>
\ No newline at end of file
diff --git a/app/code/Magento/Payment/view/frontend/templates/transparent/iframe.phtml b/app/code/Magento/Payment/view/frontend/templates/transparent/iframe.phtml
index 93ac9970e145338451895c1d54d29a977e19f7bc..f71a9bdd9fa412d02330b38ad6cb347b409bfd19 100644
--- a/app/code/Magento/Payment/view/frontend/templates/transparent/iframe.phtml
+++ b/app/code/Magento/Payment/view/frontend/templates/transparent/iframe.phtml
@@ -26,9 +26,15 @@ $params = $block->getParams();
             window.top.location = "<?php echo $params['order_success'] ?>";
         <?php else: ?>
             var require = window.top.require;
-            require(['jquery'], function($) {
-                $('#originalPlaceOrder').click();
-            });
+            require(
+                [
+                    'Magento_Checkout/js/model/quote',
+                    'Magento_Checkout/js/action/place-order'
+                ],
+                function(quote, placeOrderAction) {
+                    placeOrderAction(quote.paymentMethod(), true);
+                }
+            );
         <?php endif; ?>
         </script>
     </head>
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/frontend/web/js/model/credit-card-validation/credit-card-data.js
new file mode 100644
index 0000000000000000000000000000000000000000..ef6dd82c179b4591a89a43987f72ca91ca974478
--- /dev/null
+++ b/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/credit-card-data.js
@@ -0,0 +1,19 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(
+    [],
+    function() {
+        'use strict';
+        return {
+            creditCard: null,
+            creditCardNumber: null,
+            expirationMonth: null,
+            expirationYear: null,
+            cvvCode: null
+        }
+    }
+);
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/frontend/web/js/model/credit-card-validation/credit-card-number-validator.js
new file mode 100644
index 0000000000000000000000000000000000000000..1f13a5af7c60a297dd13867daa9e1ba4694fbe5d
--- /dev/null
+++ b/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/credit-card-number-validator.js
@@ -0,0 +1,72 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(
+    [
+        'mageUtils',
+        'Magento_Payment/js/model/credit-card-validation/credit-card-number-validator/luhn10-validator',
+        'Magento_Payment/js/model/credit-card-validation/credit-card-number-validator/credit-card-type'
+    ],
+    function (utils, luhn10, creditCardTypes) {
+        'use strict';
+
+        function resultWrapper(card, isPotentiallyValid, isValid) {
+            return {
+                card: card,
+                isValid: isValid,
+                isPotentiallyValid: isPotentiallyValid
+            };
+        }
+
+        return function (value) {
+            var potentialTypes,
+                cardType,
+                valid,
+                i,
+                maxLength;
+
+            if (utils.isEmpty(value)) {
+                return resultWrapper(null, false, false);
+            }
+
+            value = value.replace(/\-|\s/g, '');
+
+            if (!/^\d*$/.test(value)) {
+                return resultWrapper(null, false, false);
+            }
+
+            potentialTypes = creditCardTypes.getCardTypes(value);
+
+            if (potentialTypes.length === 0) {
+                return resultWrapper(null, false, false);
+            } else if (potentialTypes.length !== 1) {
+                return resultWrapper(null, true, false);
+            }
+
+            cardType = potentialTypes[0];
+
+            if (cardType.type === 'unionpay') {  // UnionPay is not Luhn 10 compliant
+                valid = true;
+            } else {
+                valid = luhn10(value);
+            }
+
+            for (i = 0; i < cardType.lengths.length; i++) {
+                if (cardType.lengths[i] === value.length) {
+                    return resultWrapper(cardType, valid, valid);
+                }
+            }
+
+            maxLength = Math.max.apply(null, cardType.lengths);
+
+            if (value.length < maxLength) {
+                return resultWrapper(cardType, true, false);
+            }
+
+            return resultWrapper(cardType, false, false);
+        };
+    }
+);
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/frontend/web/js/model/credit-card-validation/credit-card-number-validator/credit-card-type.js
new file mode 100644
index 0000000000000000000000000000000000000000..71e0e57c5c16e71a394d1fa948f35ed807c75495
--- /dev/null
+++ b/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/credit-card-number-validator/credit-card-type.js
@@ -0,0 +1,144 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(
+    [
+        'jquery',
+        'mageUtils'
+    ],
+    function ($, utils) {
+        'use strict';
+        var types = [
+            {
+                title: 'Visa',
+                type: 'VI',
+                pattern: '^4\\d*$',
+                gaps: [4, 8, 12],
+                lengths: [16],
+                code: {
+                    name: 'CVV',
+                    size: 3
+                }
+            },
+            {
+                title: 'MasterCard',
+                type: 'MC',
+                pattern: '^5([1-5]\\d*)?$',
+                gaps: [4, 8, 12],
+                lengths: [16],
+                code: {
+                    name: 'CVC',
+                    size: 3
+                }
+            },
+            {
+                title: 'American Express',
+                type: 'AE',
+                pattern: '^3([47]\\d*)?$',
+                isAmex: true,
+                gaps: [4, 10],
+                lengths: [15],
+                code: {
+                    name: 'CID',
+                    size: 4
+                }
+            },
+            {
+                title: 'Diners',
+                type: 'DN',
+                pattern: '^3((0([0-5]\\d*)?)|[689]\\d*)?$',
+                gaps: [4, 10],
+                lengths: [14],
+                code: {
+                    name: 'CVV',
+                    size: 3
+                }
+            },
+            {
+                title: 'Discover',
+                type: 'DI',
+                pattern: '^6(0|01|011\\d*|5\\d*|4|4[4-9]\\d*)?$',
+                gaps: [4, 8, 12],
+                lengths: [16],
+                code: {
+                    name: 'CID',
+                    size: 3
+                }
+            },
+            {
+                title: 'JCB',
+                type: 'JC',
+                pattern: '^((2|21|213|2131\\d*)|(1|18|180|1800\\d*)|(3|35\\d*))$',
+                gaps: [4, 8, 12],
+                lengths: [16],
+                code: {
+                    name: 'CVV',
+                    size: 3
+                }
+            },
+            {
+                title: 'UnionPay',
+                type: 'UN',
+                pattern: '^6(2\\d*)?$',
+                gaps: [4, 8, 12],
+                lengths: [16, 17, 18, 19],
+                code: {
+                    name: 'CVN',
+                    size: 3
+                }
+            },
+            {
+                title: 'Maestro',
+                type: 'SM',
+                pattern: '(^(5[0678])[0-9]{11,18}$)' +
+                '|(^(6[^05])[0-9]{11,18}$)' +
+                '|(^(601)[^1][0-9]{9,16}$)' +
+                '|(^(6011)[0-9]{9,11}$)' +
+                '|(^(6011)[0-9]{13,16}$)' +
+                '|(^(65)[0-9]{11,13}$)' +
+                '|(^(65)[0-9]{15,18}$)' +
+                '|(^(49030)[2-9]([0-9]{10}$' +
+                '|[0-9]{12,13}$))' +
+                '|(^(49033)[5-9]([0-9]{10}$' +
+                '|[0-9]{12,13}$))' +
+                '|(^(49110)[1-2]([0-9]{10}$' +
+                '|[0-9]{12,13}$))' +
+                '|(^(49117)[4-9]([0-9]{10}$|[0-9]{12,13}$))' +
+                '|(^(49118)[0-2]([0-9]{10}$|[0-9]{12,13}$))' +
+                '|(^(4936)([0-9]{12}$|[0-9]{14,15}$))',
+                gaps: [4, 8, 12],
+                lengths: [12, 13, 14, 15, 16, 17, 18, 19],
+                code: {
+                    name: 'CVC',
+                    size: 3
+                }
+            }
+        ];
+        return {
+            getCardTypes: function (cardNumber) {
+                var i, value,
+                    result = [];
+
+                if (utils.isEmpty(cardNumber)) {
+                    return result;
+                }
+
+                if (cardNumber === '') {
+                    return $.extend(true, {}, types);
+                }
+
+                for (i = 0; i < types.length; i++) {
+                    value = types[i];
+
+                    if (new RegExp(value.pattern).test(cardNumber)) {
+                        result.push($.extend(true, {}, value));
+                    }
+                }
+                return result;
+            }
+        }
+    }
+);
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/frontend/web/js/model/credit-card-validation/credit-card-number-validator/luhn10-validator.js
new file mode 100644
index 0000000000000000000000000000000000000000..38e93f084a25c72c8be813e52fa4f75b44c46622
--- /dev/null
+++ b/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/credit-card-number-validator/luhn10-validator.js
@@ -0,0 +1,22 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(
+    [],
+    function() {
+        'use strict';
+        /**
+         * Luhn algorithm verification
+         */
+        return function(a, b, c, d, e) {
+            for(d = +a[b = a.length-1], e = 0; b--;) {
+                c = +a[b];
+                d += ++e % 2 ? 2 * c % 10 + (c > 4) : c;
+            }
+            return !(d%10)
+        };
+    }
+);
diff --git a/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/cvv-validator.js b/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/cvv-validator.js
new file mode 100644
index 0000000000000000000000000000000000000000..45733c9f8ff4623727ba757c88f0cd92ad346f21
--- /dev/null
+++ b/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/cvv-validator.js
@@ -0,0 +1,41 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(
+    [],
+    function() {
+        'use strict';
+
+        function resultWrapper(isValid, isPotentiallyValid) {
+            return {
+                isValid: isValid,
+                isPotentiallyValid: isPotentiallyValid
+            };
+        }
+
+        /**
+         * CVV number validation
+         * validate digit count fot CVV code
+         */
+        return function(value, maxLength) {
+            var DEFAULT_LENGTH = 3;
+            maxLength = maxLength || DEFAULT_LENGTH;
+
+            if (!/^\d*$/.test(value)) {
+                return resultWrapper(false, false);
+            }
+            if (value.length === maxLength) {
+                return resultWrapper(true, true);
+            }
+            if (value.length < maxLength) {
+                return resultWrapper(false, true);
+            }
+            if (value.length > maxLength) {
+                return resultWrapper(false, false);
+            }
+        };
+    }
+);
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/frontend/web/js/model/credit-card-validation/expiration-date-validator.js
new file mode 100644
index 0000000000000000000000000000000000000000..f7266a282740c6eb258839a7746bf57dbb1b329b
--- /dev/null
+++ b/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator.js
@@ -0,0 +1,51 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(
+    [
+        'mageUtils',
+        'Magento_Payment/js/model/credit-card-validation/expiration-date-validator/parse-date',
+        'Magento_Payment/js/model/credit-card-validation/expiration-date-validator/expiration-month-validator',
+        'Magento_Payment/js/model/credit-card-validation/expiration-date-validator/expiration-year-validator'
+    ],
+    function(utils, parseDate, expirationMonth, expirationYear) {
+        'use strict';
+
+        function resultWrapper(isValid, isPotentiallyValid, month, year) {
+            return {
+                isValid: isValid,
+                isPotentiallyValid: isPotentiallyValid,
+                month: month,
+                year: year
+            };
+        }
+
+        return function(value) {
+            var date,
+                monthValid,
+                yearValid;
+
+            if (utils.isEmpty(value)) {
+                return resultWrapper(false, false, null, null);
+            }
+
+            value = value.replace(/^(\d\d) (\d\d(\d\d)?)$/, '$1/$2');
+            date = parseDate(value);
+            monthValid = expirationMonth(date.month);
+            yearValid = expirationYear(date.year);
+
+            if (monthValid.isValid && yearValid.isValid) {
+                return resultWrapper(true, true, date.month, date.year);
+            }
+
+            if (monthValid.isPotentiallyValid && yearValid.isPotentiallyValid) {
+                return resultWrapper(false, true, null, null);
+            }
+
+            return resultWrapper(false, false, null, null);
+        }
+    }
+);
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/frontend/web/js/model/credit-card-validation/expiration-date-validator/expiration-month-validator.js
new file mode 100644
index 0000000000000000000000000000000000000000..c41ad14a459dbe7f788b8b0e21dd07a62150561c
--- /dev/null
+++ b/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator/expiration-month-validator.js
@@ -0,0 +1,41 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(
+    [],
+    function () {
+        'use strict';
+
+        function resultWrapper(isValid, isPotentiallyValid) {
+            return {
+                isValid: isValid,
+                isPotentiallyValid: isPotentiallyValid
+            };
+        }
+
+        return function (value) {
+            var month,
+                monthValid;
+
+            if ((value.replace(/\s/g, '') === '') || (value === '0')) {
+                return resultWrapper(false, true);
+            }
+
+            if (!/^\d*$/.test(value)) {
+                return resultWrapper(false, false);
+            }
+
+            if (isNaN(value)) {
+                return resultWrapper(false, false);
+            }
+
+            month = parseInt(value, 10);
+            monthValid = month > 0 && month < 13;
+
+            return resultWrapper(monthValid, monthValid);
+        };
+    }
+);
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/frontend/web/js/model/credit-card-validation/expiration-date-validator/expiration-year-validator.js
new file mode 100644
index 0000000000000000000000000000000000000000..132c8dc42e9f2675647eb4112d09100fae84f7dd
--- /dev/null
+++ b/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator/expiration-year-validator.js
@@ -0,0 +1,42 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(
+    [],
+    function() {
+        'use strict';
+
+        function resultWrapper(isValid, isPotentiallyValid) {
+            return {
+                isValid: isValid,
+                isPotentiallyValid: isPotentiallyValid
+            };
+        }
+
+        return function(value) {
+            var currentYear = new Date().getFullYear(),
+                len = value.length,
+                valid,
+                expMaxLifetime = 19;
+
+            if (value.replace(/\s/g, '') === '') {
+                return resultWrapper(false, true);
+            }
+
+            if (!/^\d*$/.test(value)) {
+                return resultWrapper(false, false);
+            }
+
+            if (len !== 4) {
+                return resultWrapper(false, true);
+            }
+
+            value = parseInt(value, 10);
+            valid = value >= currentYear && value <= currentYear + expMaxLifetime;
+            return resultWrapper(valid, valid);
+        };
+    }
+);
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/frontend/web/js/model/credit-card-validation/expiration-date-validator/parse-date.js
new file mode 100644
index 0000000000000000000000000000000000000000..119bfa698732ecb0bf8895dad4ec75d8edeac063
--- /dev/null
+++ b/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator/parse-date.js
@@ -0,0 +1,32 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(
+    [],
+    function() {
+        'use strict';
+        return function(value) {
+            var month, len;
+
+            if (value.match('/')) {
+                value = value.split(/\s*\/\s*/g);
+
+                return {
+                    month: value[0],
+                    year: value.slice(1).join()
+                };
+            }
+
+            len = (value[0] === '0' || value.length > 5 || value.length === 4 || value.length === 3) ? 2 : 1;
+            month = value.substr(0, len);
+
+            return {
+                month: month,
+                year: value.substr(month.length, 4)
+            };
+        }
+    }
+);
diff --git a/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/validator.js b/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/validator.js
new file mode 100644
index 0000000000000000000000000000000000000000..660f3e3c0471f40d168481723d316bfcf792c0ed
--- /dev/null
+++ b/app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/validator.js
@@ -0,0 +1,74 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+(function (factory) {
+    if (typeof define === 'function' && define.amd) {
+        define([
+            'jquery',
+            'Magento_Payment/js/model/credit-card-validation/cvv-validator',
+            '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'
+        ], factory);
+    } else {
+        factory(jQuery);
+    }
+}(function ($, cvvValidator, creditCardNumberValidator, expirationDateValidator, monthValidator, creditCardData) {
+    "use strict";
+
+    $.each({
+        'validate-card-number': [
+            /**
+             * Validate credit card number based on mod 10
+             * @param number - credit card number
+             * @return {boolean}
+             */
+            function (number) {
+                return creditCardNumberValidator(number).isValid;
+            },
+            'Please enter a valid credit card number.'
+        ],
+        'validate-card-date': [
+            /**
+             * Validate credit card number based on mod 10
+             * @param date - month
+             * @return {boolean}
+             */
+                function (date) {
+                return monthValidator(date).isValid;
+            },
+            'Incorrect credit card expiration month.'
+        ],
+        'validate-card-cvv': [
+            /**
+             * Validate credit card number based on mod 10
+             * @param cvv - month
+             * @return {boolean}
+             */
+                function (cvv) {
+                var maxLength = creditCardData.creditCard ? creditCardData.creditCard.code.size : 3;
+                return cvvValidator(cvv, maxLength).isValid;
+            },
+            'Please enter a valid credit card verification number.'
+        ],
+        'validate-card-year': [
+            /**
+             * Validate credit card number based on mod 10
+             * @param date - month
+             * @return {boolean}
+             */
+                function (date) {
+                return monthValidator(date).isValid;
+            },
+            'Incorrect credit card expiration year.'
+        ]
+
+    }, function (i, rule) {
+        rule.unshift(i);
+        $.validator.addMethod.apply($.validator, rule);
+    });
+}));
\ No newline at end of file
diff --git a/app/code/Magento/Payment/view/frontend/web/js/view/payment/cc-form.js b/app/code/Magento/Payment/view/frontend/web/js/view/payment/cc-form.js
index 8e6e53f0ae7e5061322e0a525bc733c057d938e2..5c1abc1e3c75b1721a889badee6e364009bd448f 100644
--- a/app/code/Magento/Payment/view/frontend/web/js/view/payment/cc-form.js
+++ b/app/code/Magento/Payment/view/frontend/web/js/view/payment/cc-form.js
@@ -7,21 +7,24 @@
 define(
     [
         'underscore',
-        'uiComponent',
+        'Magento_Checkout/js/view/payment/default',
+        'Magento_Payment/js/model/credit-card-validation/credit-card-data',
+        'Magento_Payment/js/model/credit-card-validation/credit-card-number-validator',
         'mage/translate'
     ],
-    function (_, component, $t) {
-        return component.extend({
+    function (_, Component, creditCardData, cardNumberValidator, $t) {
+        return Component.extend({
             defaults: {
-                template: 'Magento_Payment/payment/cc-form',
                 creditCardType: '',
                 creditCardExpYear: '',
                 creditCardExpMonth: '',
                 creditCardNumber: '',
                 creditCardSsStartMonth: '',
                 creditCardSsStartYear: '',
-                creditCardVerificationNumber: ''
+                creditCardVerificationNumber: '',
+                selectedCardType: null
             },
+
             initObservable: function () {
                 this._super()
                     .observe([
@@ -31,15 +34,62 @@ define(
                         'creditCardNumber',
                         'creditCardVerificationNumber',
                         'creditCardSsStartMonth',
-                        'creditCardSsStartYear'
+                        'creditCardSsStartYear',
+                        'selectedCardType'
                     ]);
                 return this;
             },
+
+            initialize: function() {
+                var self = this;
+                this._super();
+
+                //Set credit card number to credit card data object
+                this.creditCardNumber.subscribe(function(value) {
+                    var result;
+                    self.selectedCardType(null);
+
+                    if (value == '' || value == null) {
+                        return false;
+                    }
+                    result = cardNumberValidator(value);
+
+                    if (!result.isPotentiallyValid && !result.isValid) {
+                        return false;
+                    }
+                    if (result.card !== null) {
+                        self.selectedCardType(result.card.type);
+                        creditCardData.creditCard = result.card;
+                    }
+
+                    if (result.isValid) {
+                        creditCardData.creditCardNumber = value;
+                        self.creditCardType(result.card.type);
+                    }
+                });
+
+                //Set expiration year to credit card data object
+                this.creditCardExpYear.subscribe(function(value) {
+                    creditCardData.expirationYear = value;
+                });
+
+                //Set expiration month to credit card data object
+                this.creditCardExpMonth.subscribe(function(value) {
+                    creditCardData.expirationYear = value;
+                });
+
+                //Set cvv code to credit card data object
+                this.creditCardVerificationNumber.subscribe(function(value) {
+                    creditCardData.cvvCode = value;
+                });
+            },
+
             getCode: function() {
                 return 'cc';
             },
             getData: function() {
                 return {
+                    'method': this.item.method,
                     'cc_type': this.creditCardType(),
                     'cc_exp_year': this.creditCardExpYear(),
                     'cc_exp_month': this.creditCardExpMonth(),
diff --git a/app/code/Magento/Payment/view/frontend/web/js/view/review/actions/iframe.js b/app/code/Magento/Payment/view/frontend/web/js/view/payment/iframe.js
similarity index 90%
rename from app/code/Magento/Payment/view/frontend/web/js/view/review/actions/iframe.js
rename to app/code/Magento/Payment/view/frontend/web/js/view/payment/iframe.js
index 5349dab7b4d93202a4dec1f9924de97d0c564645..83a229af3bfbea8019ea0897b206b91f768377ee 100644
--- a/app/code/Magento/Payment/view/frontend/web/js/view/review/actions/iframe.js
+++ b/app/code/Magento/Payment/view/frontend/web/js/view/payment/iframe.js
@@ -6,12 +6,12 @@
 /*global define*/
 define(
     [
-        'uiComponent'
+        'Magento_Payment/js/view/payment/cc-form'
     ],
     function (Component) {
         return Component.extend({
             defaults: {
-                template: 'Magento_Payment/review/actions/iframe'
+                template: 'Magento_Payment/payment/iframe'
             },
             getSource: function () {
                 return window.checkoutConfig.payment.iframe.source[this.getCode()];
@@ -34,9 +34,6 @@ define(
             getCardFieldsMap: function() {
                 return window.checkoutConfig.payment.iframe.cardFieldsMap[this.getCode()];
             },
-            getCode: function() {
-                return this.index;
-            },
             originalPlaceOrder: function(parent) {
                 return parent.placeOrder.bind(parent);
             },
diff --git a/app/code/Magento/Payment/view/frontend/web/js/view/payment/method-renderer/free-method.js b/app/code/Magento/Payment/view/frontend/web/js/view/payment/method-renderer/free-method.js
new file mode 100644
index 0000000000000000000000000000000000000000..72c249027684b153892f992c3ce14cdd47aa84ad
--- /dev/null
+++ b/app/code/Magento/Payment/view/frontend/web/js/view/payment/method-renderer/free-method.js
@@ -0,0 +1,23 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define(
+    [
+        'Magento_Checkout/js/view/payment/default',
+        'Magento_Checkout/js/model/quote'
+    ],
+    function (Component, quote) {
+        'use strict';
+        return Component.extend({
+            defaults: {
+                template: 'Magento_Payment/payment/free'
+            },
+
+            /** Returns is method available */
+            isAvailable: function() {
+                return quote.totals().grand_total <= 0;
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/Payment/view/frontend/web/js/view/payment/payments.js b/app/code/Magento/Payment/view/frontend/web/js/view/payment/payments.js
new file mode 100644
index 0000000000000000000000000000000000000000..cff4f3810842e9ce77510d4b95da261e9475392b
--- /dev/null
+++ b/app/code/Magento/Payment/view/frontend/web/js/view/payment/payments.js
@@ -0,0 +1,26 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*browser:true*/
+/*global define*/
+define(
+    [
+        'uiComponent',
+        'Magento_Checkout/js/model/payment/renderer-list'
+    ],
+    function (
+        Component,
+        rendererList
+    ) {
+        'use strict';
+        rendererList.push(
+            {
+                type: 'free',
+                component: 'Magento_Payment/js/view/payment/method-renderer/free-method'
+            }
+        );
+        /** Add view logic here if needed */
+        return Component.extend({});
+    }
+);
\ No newline at end of file
diff --git a/app/code/Magento/Payment/view/frontend/web/template/payment/cc-form.html b/app/code/Magento/Payment/view/frontend/web/template/payment/cc-form.html
index 96fd1446d2cf33028c3f63f07d6400b1ef82a342..49d1d57f958bdd938284aaeaf11abf1ca926fb3d 100644
--- a/app/code/Magento/Payment/view/frontend/web/template/payment/cc-form.html
+++ b/app/code/Magento/Payment/view/frontend/web/template/payment/cc-form.html
@@ -4,20 +4,36 @@
  * See COPYING.txt for license details.
  */
 -->
+
 <fieldset data-bind="attr: {class: 'fieldset payment items ccard ' + getCode(), id: 'payment_form_' + getCode()}">
     <!-- ko if: (isShowLegend())-->
-    <legend class="legend"><span><!-- ko text: $t('Credit Card Information')--><!-- /ko --></span></legend><br />
+    <legend class="legend">
+        <span><!-- ko text: $t('Credit Card Information')--><!-- /ko --></span>
+    </legend><br />
     <!-- /ko -->
     <div class="field type required">
         <label data-bind="attr: {for: getCode() + '_cc_type'}" class="label">
             <span><!-- ko text: $t('Credit Card Type')--><!-- /ko --></span>
         </label>
         <div class="control">
-            <select name="payment[cc_type]" class="select"
-                data-bind="attr: {id: getCode() + '_cc_type', 'data-container': getCode() + '-cc-type', 'data-validate': JSON.stringify({required:true, 'validate-cc-type-select':'#' + getCode() + '_cc_number'})},
-                mageInit: {creditCardType:{creditCardTypeContainer:'#' + getCode() + '_cc_type_ss_div'}},
-                enable: isActive($parents), options: getCcAvailableTypesValues(), optionsValue: 'value', optionsText: 'type', optionsCaption: $t('--Please Select--'), value: creditCardType">
-            </select>
+            <ul class="credit-card-types">
+                <!-- ko foreach: {data: getCcAvailableTypesValues(), as: 'item'} -->
+                <li class="item" data-bind="css: {_active: $parent.selectedCardType() == item.value} ">
+                    <!-- if picture -->
+                    <img data-bind="attr: {
+                        'src': 'Magento_Payment::images/cc/'+ item.value + '.png',
+                        'alt': item.type
+                        }">
+                    <!-- if NOpicture -->
+                    <span><!-- ko text: item.type --><!-- /ko --></span>
+                </li>
+                <!--/ko-->
+            </ul>
+            <input type="hidden"
+                   name="payment[cc_number]"
+                   class="input-text"
+                   value=""
+                   data-bind="attr: {id: getCode() + '_cc_type'}, value: creditCardType">
         </div>
     </div>
     <div class="field number required">
@@ -25,9 +41,15 @@
             <span><!-- ko text: $t('Credit Card Number')--><!-- /ko --></span>
         </label>
         <div class="control">
-            <input type="number" name="payment[cc_number]" class="input-text" value=""
-                data-bind="attr: {id: getCode() + '_cc_number', title: $t('Credit Card Number'), 'data-container': getCode() + '-cc-number', 'data-validate': JSON.stringify({'required-number':true, 'validate-cc-number':'#' + getCode() + '_cc_type', 'validate-cc-type':'#' + getCode() + '_cc_type'})},
-                enable: isActive($parents), value: creditCardNumber"/>
+            <input type="text" name="payment[cc_number]" class="input-text" value=""
+                   data-bind="attr: {
+                                    id: getCode() + '_cc_number',
+                                    title: $t('Credit Card Number'),
+                                    'data-container': getCode() + '-cc-number',
+                                    'data-validate': JSON.stringify({'required-number':true, 'validate-card-number':'#' + getCode() + '_cc_type', 'validate-cc-type':'#' + getCode() + '_cc_type'})},
+                              enable: isActive($parents),
+                              value: creditCardNumber,
+                              valueUpdate: 'keyup' "/>
         </div>
     </div>
     <div class="field date required" data-bind="attr: {id: getCode() + '_cc_type_exp_div'}">
@@ -38,17 +60,29 @@
             <div class="fields group group-2">
                 <div class="field no-label month">
                     <div class="control">
-                        <select  name="payment[cc_exp_month]" class="select month"
-                            data-bind="attr: {id: getCode() + '_expiration', 'data-container': getCode() + '-cc-month', 'data-validate': JSON.stringify({required:true, 'validate-cc-exp':'#' + getCode() + '_expiration_yr'})},
-                            enable: isActive($parents), options: getCcMonthsValues(), optionsValue: 'value', optionsText: 'month', optionsCaption: $t('Month'), value: creditCardExpMonth">
+                        <select  name="payment[cc_exp_month]"
+                                 class="select select-month"
+                                 data-bind="attr: {id: getCode() + '_expiration', 'data-container': getCode() + '-cc-month', 'data-validate': JSON.stringify({required:true, 'validate-cc-exp':'#' + getCode() + '_expiration_yr'})},
+                                            enable: isActive($parents),
+                                            options: getCcMonthsValues(),
+                                            optionsValue: 'value',
+                                            optionsText: 'month',
+                                            optionsCaption: $t('Month'),
+                                            value: creditCardExpMonth">
                         </select>
                     </div>
                 </div>
                 <div class="field no-label year">
                     <div class="control">
-                        <select name="payment[cc_exp_year]" class="select year"
-                            data-bind="attr: {id: getCode() + '_expiration_yr', 'data-container': getCode() + '-cc-year', 'data-validate': JSON.stringify({required:true})},
-                            enable: isActive($parents), options: getCcYearsValues(), optionsValue: 'value', optionsText: 'year', optionsCaption: $t('Year'), value: creditCardExpYear">
+                        <select name="payment[cc_exp_year]"
+                                class="select select-year"
+                                data-bind="attr: {id: getCode() + '_expiration_yr', 'data-container': getCode() + '-cc-year', 'data-validate': JSON.stringify({required:true})},
+                                           enable: isActive($parents),
+                                           options: getCcYearsValues(),
+                                           optionsValue: 'value',
+                                           optionsText: 'year',
+                                           optionsCaption: $t('Year'),
+                                           value: creditCardExpYear">
                         </select>
                     </div>
                 </div>
@@ -60,11 +94,16 @@
         <label data-bind="attr: {for: getCode() + '_cc_cid'}" class="label">
             <span><!-- ko text: $t('Card Verification Number')--><!-- /ko --></span>
         </label>
-        <div class="control">
-            <input type="number" class="input-text cvv" name="payment[cc_cid]" value=""
-                    data-bind="attr: {id: getCode() + '_cc_cid', title: $t('Card Verification Number'), 'data-container': getCode() + '-cc-cvv', 'data-validate': JSON.stringify({'required-number':true, 'validate-cc-cvn':'#' + getCode() + '_cc_type'})}, enable: isActive($parents), value: creditCardVerificationNumber"/>
-            <div class="note">
-                <a href="#" class="action cvv" data-bind="attr: {title: $t('What is this?')}, mageInit:{'tooltip': {'content': getCvvImageHtml()}}"><span><!-- ko text: $t('What is this?')--><!-- /ko --></span></a>
+        <div class="control _with-tooltip">
+            <input type="text" class="input-text cvv" name="payment[cc_cid]" value=""
+                   data-bind="attr: {id: getCode() + '_cc_cid', title: $t('Card Verification Number'), 'data-container': getCode() + '-cc-cvv', 'data-validate': JSON.stringify({'required-number':true, 'validate-card-cvv':'#' + getCode() + '_cc_type'})},
+                             enable: isActive($parents),
+                             value: creditCardVerificationNumber"/>
+            <div class="field-tooltip toggle">
+                <span class="field-tooltip-action action-cvv" data-bind="attr: {title: $t('What is this?')}">
+                    <span><!-- ko text: $t('What is this?')--><!-- /ko --></span>
+                </span>
+                <div class="field-tooltip-content" data-bind="html: getCvvImageHtml()"></div>
             </div>
         </div>
     </div>
@@ -72,33 +111,55 @@
     <!-- ko if: (hasSsCardType())-->
     <div class="field switch solo required" data-bind="attr: {id: getCode() + '_cc_type_ss_div'}">
         <div class="nested">
-            <div class="field switch solo required">
-                <label data-bind="attr: {for: getCode() + '_cc_issue'}" class="label"><span><!-- ko text: $t('Switch/Solo/Maestro Only')--><!-- /ko --></span></label>
+            <div class="field switch-solo required">
+                <label data-bind="attr: {for: getCode() + '_cc_issue'}" class="label">
+                    <span><!-- ko text: $t('Switch/Solo/Maestro Only')--><!-- /ko --></span>
+                </label>
             </div>
             <div class="field number required">
-                <label data-bind="attr: {for: getCode() + '_cc_issue'}" class="label"><span><!-- ko text: $t('Issue Number')--><!-- /ko --></span></label>
+                <label data-bind="attr: {for: getCode() + '_cc_issue'}" class="label">
+                    <span><!-- ko text: $t('Issue Number')--><!-- /ko --></span>
+                </label>
                 <div class="control">
-                    <input type="text" name="payment[cc_ss_issue]" value="" class="input-text cvv" data-bind="attr: {id: getCode() + '_cc_issue', title: $t('Issue Number'), 'data-container': getCode() + '-cc-issue', 'data-validate': JSON.stringify({'validate-cc-ukss':true})}, enable: isActive($parents)"/>
+                    <input type="text" name="payment[cc_ss_issue]"
+                           value=""
+                           class="input-text cvv"
+                           data-bind="attr: {id: getCode() + '_cc_issue', title: $t('Issue Number'), 'data-container': getCode() + '-cc-issue', 'data-validate': JSON.stringify({'validate-cc-ukss':true})}, enable: isActive($parents)"/>
                 </div>
             </div>
 
             <div class="field date required">
-                <label data-bind="attr: {for: getCode() + '_start_month'}" class="label"><span><!-- ko text: $t('Start Date')--><!-- /ko --></span></label>
+                <label data-bind="attr: {for: getCode() + '_start_month'}" class="label">
+                    <span><!-- ko text: $t('Start Date')--><!-- /ko --></span>
+                </label>
                 <div class="control">
                     <div class="fields group group-2">
-                        <div class="field no-label">
+                        <div class="field no-label month">
                             <div class="control">
-                                <select name="payment[cc_ss_start_month]" class="select month"
+                                <select name="payment[cc_ss_start_month]"
+                                        class="select select-month"
                                         data-bind="attr: {id: getCode() + '_start_month', 'data-container': getCode() + '-cc-start-month', 'data-validate': JSON.stringify({'validate-cc-ukss':true})},
-                                        enable: isActive($parents), options: getCcMonthsValues(), optionsValue: 'value', optionsText: 'month', optionsCaption: $t('Month'), value: creditCardSsStartMonth">
+                                                  enable: isActive($parents),
+                                                  options: getCcMonthsValues(),
+                                                  optionsValue: 'value',
+                                                  optionsText: 'month',
+                                                  optionsCaption: $t('Month'),
+                                                  value: creditCardSsStartMonth">
                                 </select>
                             </div>
                         </div>
-                        <div class="field no-label">
+                        <div class="field no-label year">
                             <div class="control">
-                                <select name="payment[cc_ss_start_year]" class="select year"
-                                        data-bind="attr: {id: getCode() + '_start_year', 'data-container': getCode() + '-cc-start-year', 'data-validate': JSON.stringify({'validate-cc-ukss':true})},
-                                        enable: isActive($parents), options: getSsStartYearsValues(), optionsValue: 'value', optionsText: 'year', optionsCaption: $t('Year'), value: creditCardSsStartYear">
+                                <select name="payment[cc_ss_start_year]"
+                                        class="select select-year"
+                                        data-bind="attr: {id: getCode() + '_start_year', 'data-container': getCode() + '-cc-start-year',
+                                        'data-validate': JSON.stringify({'validate-cc-ukss':true})},
+                                        enable: isActive($parents),
+                                        options: getSsStartYearsValues(),
+                                        optionsValue: 'value',
+                                        optionsText: 'year',
+                                        optionsCaption: $t('Year'),
+                                        value: creditCardSsStartYear">
                                 </select>
                             </div>
                         </div>
diff --git a/app/code/Magento/Payment/view/frontend/web/template/payment/free.html b/app/code/Magento/Payment/view/frontend/web/template/payment/free.html
new file mode 100644
index 0000000000000000000000000000000000000000..fb33eafd3cfbb59e8fffe9983692fe3d2fad1050
--- /dev/null
+++ b/app/code/Magento/Payment/view/frontend/web/template/payment/free.html
@@ -0,0 +1,36 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<div class="payment-method" data-bind="css: {'_active': (getCode() == isChecked())}, visible: isAvailable()">
+    <div class="payment-method-title field choice">
+        <input type="radio"
+               name="payment[method]"
+               class="radio"
+               data-bind="attr: {'id': getCode()}, value: getCode(), checked: isChecked, click: selectPaymentMethod, visible: isRadioButtonVisible()"/>
+        <label data-bind="attr: {'for': getCode()}" class="label"><span data-bind="text: getTitle()"></span></label>
+    </div>
+    <div class="payment-method-content">
+        <div class="payment-method-billing-address">
+            <!-- ko foreach: $parent.getRegion(getBillingAddressFormName()) -->
+            <!-- ko template: getTemplate() --><!-- /ko -->
+            <!--/ko-->
+        </div>
+        <div class="checkout-agreements-block">
+            <!-- ko foreach: $parent.getRegion('before-place-order') -->
+                <!-- ko template: getTemplate() --><!-- /ko -->
+            <!--/ko-->
+        </div>
+        <div class="actions-toolbar">
+            <div class="primary">
+                <button class="action primary checkout"
+                        type="submit"
+                        data-bind="click: placeOrder, attr: {title: $t('Place Order')}">
+                    <span data-bind="text: $t('Place Order')"></span>
+                </button>
+            </div>
+        </div>
+    </div>
+</div>
diff --git a/app/code/Magento/Payment/view/frontend/web/template/review/actions/iframe.html b/app/code/Magento/Payment/view/frontend/web/template/payment/iframe.html
similarity index 91%
rename from app/code/Magento/Payment/view/frontend/web/template/review/actions/iframe.html
rename to app/code/Magento/Payment/view/frontend/web/template/payment/iframe.html
index df5212f51e03f9a2b54332ca117c38d7abb0d5ba..2fec488a491cb1787d622de53a3c4764c404c4c4 100644
--- a/app/code/Magento/Payment/view/frontend/web/template/review/actions/iframe.html
+++ b/app/code/Magento/Payment/view/frontend/web/template/payment/iframe.html
@@ -21,6 +21,11 @@
     <!-- ko template: getTemplate() --><!-- /ko -->
 <!-- /ko -->
 </form>
+<div class="checkout-agreements-block">
+    <!-- ko foreach: $parent.getRegion('before-place-order') -->
+        <!-- ko template: getTemplate() --><!-- /ko -->
+    <!--/ko-->
+</div>
 <div class="actions-toolbar" id="review-buttons-container">
     <div class="primary">
         <button data-role="review-save" type="submit"
diff --git a/app/code/Magento/Payment/view/frontend/web/transparent.js b/app/code/Magento/Payment/view/frontend/web/transparent.js
index 6394cf38fee739a4667b1845efc4e11f4582b913..2060ca7c8ea5e5a344329c0e48ad935859f77f8a 100644
--- a/app/code/Magento/Payment/view/frontend/web/transparent.js
+++ b/app/code/Magento/Payment/view/frontend/web/transparent.js
@@ -6,12 +6,14 @@
 define([
     "jquery",
     "mage/template",
-    "jquery/ui"
+    "jquery/ui",
+    "Magento_Payment/js/model/credit-card-validation/validator"
 ], function($, mageTemplate){
-    "use strict";
+    'use strict';
 
     $.widget('mage.transparent', {
         options: {
+            context: null,
             placeOrderSelector: '[data-role="review-save"]',
             paymentFormSelector: '#co-payment-form',
             updateSelectorPrefix: '#checkout-',
@@ -34,9 +36,24 @@ define([
 
         _create: function() {
             this.hiddenFormTmpl = mageTemplate(this.options.hiddenFormTmpl);
-            $(this.options.placeOrderSelector)
-                .off('click')
-                .on('click', $.proxy(this._placeOrderHandler, this));
+
+            if (this.options.context) {
+                this.options.context.setPlaceOrderHandler($.proxy(this._orderSave, this));
+                this.options.context.setValidateHandler($.proxy(this._validateHandler, this));
+            } else {
+                $(this.options.placeOrderSelector)
+                    .off('click')
+                    .on('click', $.proxy(this._placeOrderHandler, this));
+            }
+        },
+
+        /**
+         * handler for credit card validation
+         * @return {Boolean}
+         * @private
+         */
+        _validateHandler: function() {
+            return (this.element.validation && this.element.validation('isValid'));
         },
 
         /**
@@ -45,7 +62,7 @@ define([
          * @private
          */
         _placeOrderHandler: function() {
-            if (this.element.validation && this.element.validation('isValid')) {
+            if (this._validateHandler()) {
                 this._orderSave();
             }
             return false;
@@ -65,7 +82,7 @@ define([
                 '[data-container="' + this.options.gateway + '-cc-type"]'
             ).val();
 
-            $.ajax({
+            return $.ajax({
                 url: this.options.orderSaveUrl,
                 type: 'post',
                 context: this,
@@ -110,7 +127,6 @@ define([
                     inputs: data
                 }
             });
-
             $(tmpl).appendTo($(iframeSelector)).submit();
         },
 
diff --git a/app/code/Magento/Persistent/view/frontend/layout/checkout_onepage_index.xml b/app/code/Magento/Persistent/view/frontend/layout/checkout_onepage_original.xml
similarity index 97%
rename from app/code/Magento/Persistent/view/frontend/layout/checkout_onepage_index.xml
rename to app/code/Magento/Persistent/view/frontend/layout/checkout_onepage_original.xml
index 80989653fc335a36a6ebf2298af1ebab84a33a53..6d8cd9506b3907770cbb9e49e44996503a4337bd 100644
--- a/app/code/Magento/Persistent/view/frontend/layout/checkout_onepage_index.xml
+++ b/app/code/Magento/Persistent/view/frontend/layout/checkout_onepage_original.xml
@@ -5,6 +5,7 @@
  * See COPYING.txt for license details.
  */
 -->
+<!-- TODO remove this file as soon as enhanced checkout is implemented -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
     <body>
         <referenceBlock name="checkout.root">
diff --git a/app/code/Magento/Quote/Api/AddressDetailsManagementInterface.php b/app/code/Magento/Quote/Api/AddressDetailsManagementInterface.php
deleted file mode 100644
index a721e539ddf505abedd92f68433c26e917833a75..0000000000000000000000000000000000000000
--- a/app/code/Magento/Quote/Api/AddressDetailsManagementInterface.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Quote\Api;
-
-interface AddressDetailsManagementInterface
-{
-    /**
-     * Save billing and shipping addresses
-     *
-     * @param int $cartId
-     * @param \Magento\Quote\Api\Data\AddressInterface $billingAddress
-     * @param \Magento\Quote\Api\Data\AddressInterface $shippingAddress
-     * @param \Magento\Quote\Api\Data\AddressAdditionalDataInterface|null $additionalData
-     * @param string|null $checkoutMethod
-     * @return \Magento\Quote\Api\Data\AddressDetailsInterface
-     */
-    public function saveAddresses(
-        $cartId,
-        \Magento\Quote\Api\Data\AddressInterface $billingAddress,
-        \Magento\Quote\Api\Data\AddressInterface $shippingAddress = null,
-        \Magento\Quote\Api\Data\AddressAdditionalDataInterface $additionalData = null,
-        $checkoutMethod = null
-    );
-}
diff --git a/app/code/Magento/Quote/Api/Data/AddressDetailsInterface.php b/app/code/Magento/Quote/Api/Data/AddressDetailsInterface.php
deleted file mode 100644
index 843d5faa1e38723531baed4c6f1ad6c564f6b674..0000000000000000000000000000000000000000
--- a/app/code/Magento/Quote/Api/Data/AddressDetailsInterface.php
+++ /dev/null
@@ -1,97 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Quote\Api\Data;
-
-interface AddressDetailsInterface extends \Magento\Framework\Api\ExtensibleDataInterface
-{
-    /**#@+
-     * Constants defined for keys of array, makes typos less likely
-     */
-    const SHIPPING_METHODS = 'shipping_methods';
-
-    const PAYMENT_METHODS = 'payment_methods';
-
-    const FORMATTED_BILLING_ADDRESS = 'formatted_billing_address';
-
-    const FORMATTED_SHIPPING_ADDRESS = 'formatted_shipping_address';
-
-    const TOTALS = 'totals';
-
-    /**#@-*/
-
-    /**
-     * @return \Magento\Quote\Api\Data\ShippingMethodInterface[]
-     */
-    public function getShippingMethods();
-
-    /**
-     * @return \Magento\Quote\Api\Data\PaymentMethodInterface[]
-     */
-    public function getPaymentMethods();
-
-    /**
-     * @param \Magento\Quote\Api\Data\ShippingMethodInterface[] $shippingMethods
-     * @return $this
-     */
-    public function setShippingMethods($shippingMethods);
-
-    /**
-     * @param \Magento\Quote\Api\Data\PaymentMethodInterface[] $paymentMethods
-     * @return $this
-     */
-    public function setPaymentMethods($paymentMethods);
-
-    /**
-     * @return string|null
-     */
-    public function getFormattedShippingAddress();
-
-    /**
-     * @return string
-     */
-    public function getFormattedBillingAddress();
-
-    /**
-     * @param string $formattedBillingAddress
-     * @return $this
-     */
-    public function setFormattedBillingAddress($formattedBillingAddress);
-
-    /**
-     * @param string $formattedShippingAddress
-     * @return $this
-     */
-    public function setFormattedShippingAddress($formattedShippingAddress);
-
-
-    /**
-     * Retrieve existing extension attributes object or create a new one.
-     *
-     * @return \Magento\Quote\Api\Data\AddressDetailsExtensionInterface|null
-     */
-    public function getExtensionAttributes();
-
-    /**
-     * Set an extension attributes object.
-     *
-     * @param \Magento\Quote\Api\Data\AddressDetailsExtensionInterface $extensionAttributes
-     * @return $this
-     */
-    public function setExtensionAttributes(
-        \Magento\Quote\Api\Data\AddressDetailsExtensionInterface $extensionAttributes
-    );
-
-    /**
-     * @return \Magento\Quote\Api\Data\TotalsInterface
-     */
-    public function getTotals();
-
-    /**
-     * @param \Magento\Quote\Api\Data\TotalsInterface $totals
-     * @return $this
-     */
-    public function setTotals($totals);
-}
diff --git a/app/code/Magento/Quote/Api/Data/TotalSegmentInterface.php b/app/code/Magento/Quote/Api/Data/TotalSegmentInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..6ab64d64cf93fe303ff96b15eccceeef0a898045
--- /dev/null
+++ b/app/code/Magento/Quote/Api/Data/TotalSegmentInterface.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Quote\Api\Data;
+
+/**
+ * Interface TotalsInterface
+ * @api
+ */
+interface TotalSegmentInterface extends \Magento\Framework\Api\ExtensibleDataInterface
+{
+    /**#@+
+     * Constants defined for keys of array, makes typos less likely
+     */
+    const CODE  = 'code';
+    const TITLE = 'title';
+    const VALUE = 'value';
+    const AREA  = 'area';
+    /**#@-*/
+
+    /**
+     * Total code
+     *
+     * @return string
+     */
+    public function getCode();
+
+    /**
+     * Set total code
+     *
+     * @param string $code
+     * @return $this
+     */
+    public function setCode($code);
+
+    /**
+     * Get total title
+     *
+     * @return string|null
+     */
+    public function getTitle();
+
+    /**
+     * Set total title
+     *
+     * @param string|null $title
+     * @return $this
+     */
+    public function setTitle($title = null);
+
+    /**
+     * Get total value
+     *
+     * @return float
+     */
+    public function getValue();
+
+    /**
+     * Set total value
+     *
+     * @param float $value
+     * @return $this
+     */
+    public function setValue($value);
+
+    /**
+     * Get display area code.
+     *
+     * @return string|null
+     */
+    public function getArea();
+
+    /**
+     * Set display area code
+     *
+     * @param string|null $area
+     * @return $this
+     */
+    public function setArea($area = null);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Quote\Api\Data\TotalSegmentExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Quote\Api\Data\TotalSegmentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Quote\Api\Data\TotalSegmentExtensionInterface $extensionAttributes
+    );
+}
diff --git a/app/code/Magento/Quote/Api/Data/TotalsInterface.php b/app/code/Magento/Quote/Api/Data/TotalsInterface.php
index 5e8d5349ba1c13ee7c06603ba275131f570649fb..d11e5260c459ac3c706f5f347c91f236384785d9 100644
--- a/app/code/Magento/Quote/Api/Data/TotalsInterface.php
+++ b/app/code/Magento/Quote/Api/Data/TotalsInterface.php
@@ -42,6 +42,8 @@ interface TotalsInterface extends \Magento\Framework\Api\ExtensibleDataInterface
 
     const KEY_BASE_TAX_AMOUNT = 'base_tax_amount';
 
+    const KEY_WEEE_TAX_APPLIED_AMOUNT = 'weee_tax_applied_amount';
+
     const KEY_SHIPPING_TAX_AMOUNT = 'shipping_tax_amount';
 
     const KEY_BASE_SHIPPING_TAX_AMOUNT = 'base_shipping_tax_amount';
@@ -58,8 +60,14 @@ interface TotalsInterface extends \Magento\Framework\Api\ExtensibleDataInterface
 
     const KEY_QUOTE_CURRENCY_CODE = 'quote_currency_code';
 
+    const KEY_COUPON_CODE = 'coupon_code';
+
     const KEY_ITEMS = 'items';
 
+    const KEY_TOTAL_SEGMENTS = 'total_segments';
+
+    const KEY_ITEMS_QTY = 'items_qty';
+
     /**#@-*/
 
     /**
@@ -272,6 +280,21 @@ interface TotalsInterface extends \Magento\Framework\Api\ExtensibleDataInterface
      */
     public function setBaseTaxAmount($baseTaxAmount);
 
+    /**
+     * Returns the total weee tax applied amount in quote currency.
+     *
+     * @return float Item weee tax applied amount in quote currency.
+     */
+    public function getWeeeTaxAppliedAmount();
+
+    /**
+     * Sets the total weee tax applied amount in quote currency.
+     *
+     * @param float $weeeTaxAppliedAmount
+     * @return $this
+     */
+    public function setWeeeTaxAppliedAmount($weeeTaxAppliedAmount);
+
     /**
      * Get shipping tax amount in quote currency
      *
@@ -392,6 +415,36 @@ interface TotalsInterface extends \Magento\Framework\Api\ExtensibleDataInterface
      */
     public function setQuoteCurrencyCode($quoteCurrencyCode);
 
+    /**
+     * Get applied coupon code
+     *
+     * @return string|null
+     */
+    public function getCouponCode();
+
+    /**
+     * Set applied coupon code
+     *
+     * @param string $couponCode
+     * @return $this
+     */
+    public function setCouponCode($couponCode);
+
+    /**
+     * Get items qty
+     *
+     * @return int||null
+     */
+    public function getItemsQty();
+
+    /**
+     * Set items qty
+     *
+     * @param int $itemsQty
+     * @return $this
+     */
+    public function setItemsQty($itemsQty = null);
+
     /**
      * Get totals by items
      *
@@ -407,6 +460,21 @@ interface TotalsInterface extends \Magento\Framework\Api\ExtensibleDataInterface
      */
     public function setItems(array $items = null);
 
+    /**
+     * Get dynamically calculated totals
+     *
+     * @return \Magento\Quote\Api\Data\TotalSegmentInterface[]
+     */
+    public function getTotalSegments();
+
+    /**
+     * Set dynamically calculated totals
+     *
+     * @param \Magento\Quote\Api\Data\TotalSegmentInterface[] $totals
+     * @return $this
+     */
+    public function setTotalSegments($totals = []);
+
     /**
      * Retrieve existing extension attributes object or create a new one.
      *
diff --git a/app/code/Magento/Quote/Api/GuestAddressDetailsManagementInterface.php b/app/code/Magento/Quote/Api/GuestAddressDetailsManagementInterface.php
deleted file mode 100644
index a4eea1464145c613a5c06acdfb164bd9de819527..0000000000000000000000000000000000000000
--- a/app/code/Magento/Quote/Api/GuestAddressDetailsManagementInterface.php
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Quote\Api;
-
-interface GuestAddressDetailsManagementInterface
-{
-    /**
-     * Save billing and shipping addresses for guest.
-     *
-     * @param string $cartId
-     * @param \Magento\Quote\Api\Data\AddressInterface $billingAddress
-     * @param \Magento\Quote\Api\Data\AddressInterface|null $shippingAddress
-     * @param \Magento\Quote\Api\Data\AddressAdditionalDataInterface|null $additionalData
-     * @return \Magento\Quote\Api\Data\AddressDetailsInterface
-     */
-    public function saveAddresses(
-        $cartId,
-        \Magento\Quote\Api\Data\AddressInterface $billingAddress,
-        \Magento\Quote\Api\Data\AddressInterface $shippingAddress = null,
-        \Magento\Quote\Api\Data\AddressAdditionalDataInterface $additionalData = null
-    );
-}
diff --git a/app/code/Magento/Quote/Api/GuestShippingMethodManagementInterface.php b/app/code/Magento/Quote/Api/GuestShippingMethodManagementInterface.php
index 10bd639cf93c5e30ddb57fde13595a67f2a5f945..29c4a07ca8d46c9d85d9f1a901c9303a86eaec3e 100644
--- a/app/code/Magento/Quote/Api/GuestShippingMethodManagementInterface.php
+++ b/app/code/Magento/Quote/Api/GuestShippingMethodManagementInterface.php
@@ -45,4 +45,13 @@ interface GuestShippingMethodManagementInterface
      * @throws \Magento\Framework\Exception\StateException The shipping address is not set.
      */
     public function getList($cartId);
+
+    /**
+     * Estimate shipping
+     *
+     * @param string $cartId The shopping cart ID.
+     * @param \Magento\Quote\Api\Data\EstimateAddressInterface $address The estimate address
+     * @return \Magento\Quote\Api\Data\ShippingMethodInterface[] An array of shipping methods.
+     */
+    public function estimateByAddress($cartId, \Magento\Quote\Api\Data\EstimateAddressInterface $address);
 }
diff --git a/app/code/Magento/Quote/Model/AddressDetails.php b/app/code/Magento/Quote/Model/AddressDetails.php
deleted file mode 100644
index ba3e3bf697708ee8c0d9fc6c0b5c161c6adb3ab3..0000000000000000000000000000000000000000
--- a/app/code/Magento/Quote/Model/AddressDetails.php
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Quote\Model;
-
-/**
- * @codeCoverageIgnoreStart
- */
-class AddressDetails extends \Magento\Framework\Model\AbstractExtensibleModel implements
-    \Magento\Quote\Api\Data\AddressDetailsInterface
-{
-    //@codeCoverageIgnoreStart
-    /**
-     * @{inheritdoc}
-     */
-    public function getShippingMethods()
-    {
-        return $this->getData(self::SHIPPING_METHODS);
-    }
-
-    /**
-     * @{inheritdoc}
-     */
-    public function setShippingMethods($shippingMethods)
-    {
-        return $this->setData(self::SHIPPING_METHODS, $shippingMethods);
-    }
-
-    /**
-     * @{inheritdoc}
-     */
-    public function getPaymentMethods()
-    {
-        return $this->getData(self::PAYMENT_METHODS);
-    }
-
-    /**
-     * @{inheritdoc}
-     */
-    public function setPaymentMethods($paymentMethods)
-    {
-        return $this->setData(self::PAYMENT_METHODS, $paymentMethods);
-    }
-
-    /**
-     * @{inheritdoc}
-     */
-    public function getFormattedShippingAddress()
-    {
-        return $this->getData(self::FORMATTED_SHIPPING_ADDRESS);
-    }
-
-    /**
-     * @{inheritdoc}
-     */
-    public function getFormattedBillingAddress()
-    {
-        return $this->getData(self::FORMATTED_BILLING_ADDRESS);
-    }
-
-    /**
-     * @{inheritdoc}
-     */
-    public function setFormattedBillingAddress($formattedBillingAddress)
-    {
-        return $this->setData(self::FORMATTED_BILLING_ADDRESS, $formattedBillingAddress);
-    }
-
-    /**
-     * @{inheritdoc}
-     */
-    public function setFormattedShippingAddress($formattedShippingAddress)
-    {
-        return $this->setData(self::FORMATTED_SHIPPING_ADDRESS, $formattedShippingAddress);
-    }
-
-    /**
-     * @{inheritdoc}
-     */
-    public function getTotals()
-    {
-        return $this->getData(self::TOTALS);
-    }
-
-    /**
-     * @{inheritdoc}
-     */
-    public function setTotals($totals)
-    {
-        return $this->setData(self::TOTALS, $totals);
-    }
-    //@codeCoverageIgnoreEnd
-
-    /**
-     * {@inheritdoc}
-     *
-     * @return \Magento\Quote\Api\Data\AddressDetailsExtensionInterface|null
-     */
-    public function getExtensionAttributes()
-    {
-        return $this->_getExtensionAttributes();
-    }
-
-    /**
-     * {@inheritdoc}
-     *
-     * @param \Magento\Quote\Api\Data\AddressDetailsExtensionInterface $extensionAttributes
-     * @return $this
-     */
-    public function setExtensionAttributes(
-        \Magento\Quote\Api\Data\AddressDetailsExtensionInterface $extensionAttributes
-    ) {
-        return $this->_setExtensionAttributes($extensionAttributes);
-    }
-}
diff --git a/app/code/Magento/Quote/Model/AddressDetailsManagement.php b/app/code/Magento/Quote/Model/AddressDetailsManagement.php
deleted file mode 100644
index 84c6492510a6d02f6b668612047585920dc1bb75..0000000000000000000000000000000000000000
--- a/app/code/Magento/Quote/Model/AddressDetailsManagement.php
+++ /dev/null
@@ -1,122 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Quote\Model;
-
-use Magento\Quote\Api\CartTotalRepositoryInterface;
-use Magento\Quote\Model\AddressAdditionalDataProcessor;
-
-class AddressDetailsManagement implements \Magento\Quote\Api\AddressDetailsManagementInterface
-{
-    /**
-     * @var \Magento\Quote\Api\BillingAddressManagementInterface
-     */
-    protected $billingAddressManagement;
-
-    /**
-     * @var \Magento\Quote\Api\ShippingAddressManagementInterface
-     */
-    protected $shippingAddressManagement;
-
-    /**
-     * @var \Magento\Quote\Api\PaymentMethodManagementInterface
-     */
-    protected $paymentMethodManagement;
-
-    /**
-     * @var \Magento\Quote\Api\ShippingMethodManagementInterface
-     */
-    protected $shippingMethodManagement;
-
-    /**
-     * @var AddressDetailsFactory
-     */
-    protected $addressDetailsFactory;
-
-    /**
-     * @var AddressAdditionalDataProcessor
-     */
-    protected $dataProcessor;
-
-    /**
-     * @var QuoteRepository
-     */
-    protected $quoteRepository;
-
-    /**
-     * @var CartTotalRepositoryInterface
-     */
-    protected $cartTotalsRepository;
-
-    /**
-     * @param \Magento\Quote\Api\BillingAddressManagementInterface $billingAddressManagement
-     * @param \Magento\Quote\Api\ShippingAddressManagementInterface $shippingAddressManagement
-     * @param \Magento\Quote\Api\PaymentMethodManagementInterface $paymentMethodManagement
-     * @param \Magento\Quote\Api\ShippingMethodManagementInterface $shippingMethodManagement
-     * @param AddressDetailsFactory $addressDetailsFactory
-     * @param AddressAdditionalDataProcessor $dataProcessor
-     * @param QuoteRepository $quoteRepository
-     * @param CartTotalRepositoryInterface $cartTotalsRepository
-     */
-    public function __construct(
-        \Magento\Quote\Api\BillingAddressManagementInterface $billingAddressManagement,
-        \Magento\Quote\Api\ShippingAddressManagementInterface $shippingAddressManagement,
-        \Magento\Quote\Api\PaymentMethodManagementInterface $paymentMethodManagement,
-        \Magento\Quote\Api\ShippingMethodManagementInterface $shippingMethodManagement,
-        \Magento\Quote\Model\AddressDetailsFactory $addressDetailsFactory,
-        AddressAdditionalDataProcessor $dataProcessor,
-        QuoteRepository $quoteRepository,
-        CartTotalRepositoryInterface $cartTotalsRepository
-    ) {
-        $this->billingAddressManagement = $billingAddressManagement;
-        $this->shippingAddressManagement = $shippingAddressManagement;
-        $this->paymentMethodManagement = $paymentMethodManagement;
-        $this->shippingMethodManagement = $shippingMethodManagement;
-        $this->addressDetailsFactory = $addressDetailsFactory;
-        $this->dataProcessor = $dataProcessor;
-        $this->quoteRepository = $quoteRepository;
-        $this->cartTotalsRepository = $cartTotalsRepository;
-    }
-
-    /**
-     * @{inheritdoc}
-     */
-    public function saveAddresses(
-        $cartId,
-        \Magento\Quote\Api\Data\AddressInterface $billingAddress,
-        \Magento\Quote\Api\Data\AddressInterface $shippingAddress = null,
-        \Magento\Quote\Api\Data\AddressAdditionalDataInterface $additionalData = null,
-        $checkoutMethod = null
-    ) {
-        $this->billingAddressManagement->assign($cartId, $billingAddress);
-
-        /** @var \Magento\Quote\Api\Data\AddressDetailsInterface  $addressDetails */
-        $addressDetails = $this->addressDetailsFactory->create();
-        if ($shippingAddress) {
-            $this->shippingAddressManagement->assign($cartId, $shippingAddress);
-            $addressDetails->setFormattedShippingAddress(
-                $this->shippingAddressManagement->get($cartId)->format('html')
-            );
-            $addressDetails->setShippingMethods($this->shippingMethodManagement->getList($cartId));
-        }
-        $addressDetails->setPaymentMethods($this->paymentMethodManagement->getList($cartId));
-        if ($additionalData !== null) {
-            $this->dataProcessor->process($additionalData);
-        }
-        if ($checkoutMethod != null) {
-            $this->quoteRepository->save(
-                $this->quoteRepository->getActive($cartId)
-                    ->setCheckoutMethod($checkoutMethod)
-            );
-        }
-
-        $addressDetails->setFormattedBillingAddress(
-            $this->billingAddressManagement->get($cartId)->format('html')
-        );
-
-        $addressDetails->setTotals($this->cartTotalsRepository->get($cartId));
-        return $addressDetails;
-    }
-}
diff --git a/app/code/Magento/Quote/Model/Cart/CartTotalRepository.php b/app/code/Magento/Quote/Model/Cart/CartTotalRepository.php
index 78bdf6da18569990d10fe5ac97330780b6bd14ed..88906928f9a72034da279a9d51c51e7f6944d1a3 100644
--- a/app/code/Magento/Quote/Model/Cart/CartTotalRepository.php
+++ b/app/code/Magento/Quote/Model/Cart/CartTotalRepository.php
@@ -11,6 +11,7 @@ use Magento\Quote\Api\CartTotalRepositoryInterface;
 use Magento\Catalog\Helper\Product\ConfigurationPool;
 use Magento\Framework\Api\DataObjectHelper;
 use Magento\Quote\Model\Cart\Totals\ItemConverter;
+use Magento\Quote\Api\CouponManagementInterface;
 
 /**
  * Cart totals data object.
@@ -39,24 +40,40 @@ class CartTotalRepository implements CartTotalRepositoryInterface
     /**
      * @var ConfigurationPool
      */
-    private $converter;
+    private $itemConverter;
+
+    /**
+     * @var CouponManagementInterface
+     */
+    protected $couponService;
+
+    /**
+     * @var TotalsConverter
+     */
+    protected $totalsConverter;
 
     /**
      * @param Api\Data\TotalsInterfaceFactory $totalsFactory
      * @param QuoteRepository $quoteRepository
      * @param DataObjectHelper $dataObjectHelper
+     * @param CouponManagementInterface $couponService
+     * @param TotalsConverter $totalsConverter
      * @param ItemConverter $converter
      */
     public function __construct(
         Api\Data\TotalsInterfaceFactory $totalsFactory,
         QuoteRepository $quoteRepository,
         DataObjectHelper $dataObjectHelper,
+        CouponManagementInterface $couponService,
+        TotalsConverter $totalsConverter,
         ItemConverter $converter
     ) {
         $this->totalsFactory = $totalsFactory;
         $this->quoteRepository = $quoteRepository;
         $this->dataObjectHelper = $dataObjectHelper;
-        $this->converter = $converter;
+        $this->couponService = $couponService;
+        $this->totalsConverter = $totalsConverter;
+        $this->itemConverter = $converter;
     }
 
     /**
@@ -82,11 +99,19 @@ class CartTotalRepository implements CartTotalRepositoryInterface
         $totals = $this->totalsFactory->create();
         $this->dataObjectHelper->populateWithArray($totals, $totalsData, '\Magento\Quote\Api\Data\TotalsInterface');
         $items = [];
+        $weeeTaxAppliedAmount = 0;
         foreach ($quote->getAllVisibleItems() as $index => $item) {
-            $items[$index] = $this->converter->modelToDataObject($item);
+            $items[$index] = $this->itemConverter->modelToDataObject($item);
+            $weeeTaxAppliedAmount += $item->getWeeeTaxAppliedAmount();
         }
+        $totals->setCouponCode($this->couponService->get($cartId));
+        $calculatedTotals = $this->totalsConverter->process($quote->getTotals());
+        $amount = $totals->getGrandTotal() - $totals->getTaxAmount();
+        $amount = $amount > 0 ? $amount : 0;
+        $totals->setGrandTotal($amount);
+        $totals->setTotalSegments($calculatedTotals);
         $totals->setItems($items);
-
+        $totals->setWeeeTaxAppliedAmount($weeeTaxAppliedAmount);
         return $totals;
     }
 }
diff --git a/app/code/Magento/Quote/Model/Cart/TotalSegment.php b/app/code/Magento/Quote/Model/Cart/TotalSegment.php
new file mode 100644
index 0000000000000000000000000000000000000000..203c8996f5fb2e55b92580cb86a41f93c0dba7e5
--- /dev/null
+++ b/app/code/Magento/Quote/Model/Cart/TotalSegment.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Quote\Model\Cart;
+
+use Magento\Quote\Api\Data\TotalSegmentInterface;
+use Magento\Framework\Model\AbstractExtensibleModel;
+
+/**
+ * Extensible Cart Totals
+ *
+ * @codeCoverageIgnore
+ */
+class TotalSegment extends AbstractExtensibleModel implements TotalSegmentInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getCode()
+    {
+        return $this->getData(self::CODE);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setCode($code)
+    {
+        return $this->setData(self::CODE, $code);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getValue()
+    {
+        return $this->getData(self::VALUE);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setValue($value)
+    {
+        return $this->setData(self::VALUE, $value);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getTitle()
+    {
+        return $this->getData(self::TITLE);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setTitle($title = null)
+    {
+        return $this->setData(self::TITLE, $title);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getArea()
+    {
+        return $this->getData(self::AREA);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setArea($area = null)
+    {
+        return $this->setData(self::AREA, $area);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setExtensionAttributes(
+        \Magento\Quote\Api\Data\TotalSegmentExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
+}
diff --git a/app/code/Magento/Quote/Model/Cart/Totals.php b/app/code/Magento/Quote/Model/Cart/Totals.php
index 4612824f9cebb05dc6c4dedbb00bd8827e4019a3..742f27d4df5497d6adbafdf6e1dd7fd6ddb791c0 100644
--- a/app/code/Magento/Quote/Model/Cart/Totals.php
+++ b/app/code/Magento/Quote/Model/Cart/Totals.php
@@ -310,6 +310,27 @@ class Totals extends AbstractExtensibleModel implements TotalsInterface
         return $this->setData(self::KEY_BASE_TAX_AMOUNT, $baseTaxAmount);
     }
 
+    /**
+     * Returns the total weee tax applied amount in quote currency.
+     *
+     * @return float Item weee tax applied amount in quote currency.
+     */
+    public function getWeeeTaxAppliedAmount()
+    {
+        return $this->getData(self::KEY_WEEE_TAX_APPLIED_AMOUNT);
+    }
+
+    /**
+     * Sets the total weee tax applied amount in quote currency.
+     *
+     * @param float $weeeTaxAppliedAmount
+     * @return $this
+     */
+    public function setWeeeTaxAppliedAmount($weeeTaxAppliedAmount)
+    {
+        return $this->setData(self::KEY_WEEE_TAX_APPLIED_AMOUNT, $weeeTaxAppliedAmount);
+    }
+
     /**
      * Get shipping tax amount in quote currency
      *
@@ -478,6 +499,43 @@ class Totals extends AbstractExtensibleModel implements TotalsInterface
         return $this->setData(self::KEY_QUOTE_CURRENCY_CODE, $quoteCurrencyCode);
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function getCouponCode()
+    {
+        return $this->getData(self::KEY_COUPON_CODE);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setCouponCode($couponCode)
+    {
+        return $this->setData(self::KEY_COUPON_CODE, $couponCode);
+    }
+
+    /**
+     * Get items qty
+     *
+     * @return int||null
+     */
+    public function getItemsQty()
+    {
+        return $this->getData(self::KEY_ITEMS_QTY);
+    }
+
+    /**
+     * Set items qty
+     *
+     * @param int $itemsQty
+     * @return $this
+     */
+    public function setItemsQty($itemsQty = null)
+    {
+        return $this->setData(self::KEY_ITEMS_QTY, $itemsQty);
+    }
+
     /**
      * Get totals by items
      *
@@ -499,6 +557,22 @@ class Totals extends AbstractExtensibleModel implements TotalsInterface
         return $this->setData(self::KEY_ITEMS, $items);
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function getTotalSegments()
+    {
+        return $this->getData(self::KEY_TOTAL_SEGMENTS);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setTotalSegments($totals = [])
+    {
+        return $this->setData(self::KEY_TOTAL_SEGMENTS, $totals);
+    }
+
     /**
      * {@inheritdoc}
      *
diff --git a/app/code/Magento/Quote/Model/Cart/Totals/ItemConverter.php b/app/code/Magento/Quote/Model/Cart/Totals/ItemConverter.php
index f569f8478b09d566bb3e65131436214d772a3b94..2b4792d2e44a2d884e8bf2f99b444abbc6a3ae43 100644
--- a/app/code/Magento/Quote/Model/Cart/Totals/ItemConverter.php
+++ b/app/code/Magento/Quote/Model/Cart/Totals/ItemConverter.php
@@ -86,10 +86,12 @@ class ItemConverter
     private function getFormattedOptionValue($item)
     {
         $optionsData = [];
+
+        /* @var $helper \Magento\Catalog\Helper\Product\Configuration */
+        $helper = $this->configurationPool->getByProductType('default');
+
         $options = $this->configurationPool->getByProductType($item->getProductType())->getOptions($item);
         foreach ($options as $index => $optionValue) {
-            /* @var $helper \Magento\Catalog\Helper\Product\Configuration */
-            $helper = $this->configurationPool->getByProductType('default');
             $params = [
                 'max_length' => 55,
                 'cut_replacer' => ' <a href="#" class="dots tooltip toggle" onclick="return false">...</a>'
diff --git a/app/code/Magento/Quote/Model/Cart/TotalsConverter.php b/app/code/Magento/Quote/Model/Cart/TotalsConverter.php
new file mode 100644
index 0000000000000000000000000000000000000000..a041844c8ed5023dd4884459a0a95e222d3a882a
--- /dev/null
+++ b/app/code/Magento/Quote/Model/Cart/TotalsConverter.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Quote\Model\Cart;
+
+use Magento\Quote\Api\Data\TotalSegmentInterface;
+use Magento\Quote\Api\Data\TotalSegmentInterfaceFactory;
+
+/**
+ * Cart totals data objects converter.
+ */
+class TotalsConverter
+{
+    /**
+     * @var TotalSegmentInterfaceFactory
+     */
+    protected $factory;
+
+    /**
+     * @param TotalSegmentInterfaceFactory $factory
+     */
+    public function __construct(
+        TotalSegmentInterfaceFactory $factory
+    ) {
+        $this->factory = $factory;
+    }
+
+
+    /**
+     * @param \Magento\Quote\Model\Quote\Address\Total[] $addressTotals
+     * @return \Magento\Quote\Api\Data\TotalSegmentInterface[]
+     */
+    public function process($addressTotals)
+    {
+        $data = [];
+        /** @var \Magento\Quote\Model\Quote\Address\Total $addressTotal */
+        foreach ($addressTotals as $addressTotal) {
+            $pureData = [
+                TotalSegmentInterface::CODE => $addressTotal->getCode(),
+                TotalSegmentInterface::TITLE => '',
+                TotalSegmentInterface::VALUE => $addressTotal->getValue(),
+                TotalSegmentInterface::AREA => $addressTotal->getArea(),
+            ];
+            if (is_object($addressTotal->getTitle())) {
+                $pureData[TotalSegmentInterface::TITLE] = $addressTotal->getTitle()->getText();
+            }
+            /** @var \Magento\Quote\Model\Cart\TotalSegment $total */
+            $total = $this->factory->create();
+            $total->setData($pureData);
+            $data[] = $total;
+        }
+        return $data;
+    }
+}
diff --git a/app/code/Magento/Quote/Model/GuestCart/GuestAddressDetailsManagement.php b/app/code/Magento/Quote/Model/GuestCart/GuestAddressDetailsManagement.php
deleted file mode 100644
index 2671a1ccb7665ebddf0b526f923090d6440c85f4..0000000000000000000000000000000000000000
--- a/app/code/Magento/Quote/Model/GuestCart/GuestAddressDetailsManagement.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Quote\Model\GuestCart;
-
-use Magento\Quote\Model\QuoteIdMaskFactory;
-
-class GuestAddressDetailsManagement implements \Magento\Quote\Api\GuestAddressDetailsManagementInterface
-{
-    /**
-     * @var \Magento\Quote\Api\AddressDetailsManagementInterface
-     */
-    protected $addressDetailsManagement;
-
-    /**
-     * @var QuoteIdMaskFactory
-     */
-    protected $quoteIdMaskFactory;
-
-    /**
-     * @param \Magento\Quote\Api\AddressDetailsManagementInterface $addressDetailsManagement
-     * @param QuoteIdMaskFactory $quoteIdMaskFactory
-     */
-    public function __construct(
-        \Magento\Quote\Api\AddressDetailsManagementInterface $addressDetailsManagement,
-        QuoteIdMaskFactory $quoteIdMaskFactory
-    ) {
-        $this->addressDetailsManagement = $addressDetailsManagement;
-        $this->quoteIdMaskFactory = $quoteIdMaskFactory;
-    }
-
-    /**
-     * @{inheritdoc}
-     */
-    public function saveAddresses(
-        $cartId,
-        \Magento\Quote\Api\Data\AddressInterface $billingAddress,
-        \Magento\Quote\Api\Data\AddressInterface $shippingAddress = null,
-        \Magento\Quote\Api\Data\AddressAdditionalDataInterface $additionalData = null
-    ) {
-        $quoteIdMask = $this->quoteIdMaskFactory->create()->load($cartId, 'masked_id');
-        return $this->addressDetailsManagement->saveAddresses(
-            $quoteIdMask->getQuoteId(),
-            $billingAddress,
-            $shippingAddress,
-            $additionalData
-        );
-    }
-}
diff --git a/app/code/Magento/Quote/Model/GuestCart/GuestShippingMethodManagement.php b/app/code/Magento/Quote/Model/GuestCart/GuestShippingMethodManagement.php
index 0687ca395de869030d97dbb780f474bf1ebc1733..6026ff8f8da0406a98dcc1beaf5212c816e81df6 100644
--- a/app/code/Magento/Quote/Model/GuestCart/GuestShippingMethodManagement.php
+++ b/app/code/Magento/Quote/Model/GuestCart/GuestShippingMethodManagement.php
@@ -69,4 +69,14 @@ class GuestShippingMethodManagement implements GuestShippingMethodManagementInte
         $quoteIdMask = $this->quoteIdMaskFactory->create()->load($cartId, 'masked_id');
         return $this->shippingMethodManagement->set($quoteIdMask->getQuoteId(), $carrierCode, $methodCode);
     }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function estimateByAddress($cartId, \Magento\Quote\Api\Data\EstimateAddressInterface $address)
+    {
+        /** @var $quoteIdMask QuoteIdMask */
+        $quoteIdMask = $this->quoteIdMaskFactory->create()->load($cartId, 'masked_id');
+        return $this->shippingMethodManagement->estimateByAddress($quoteIdMask->getQuoteId(), $address);
+    }
 }
diff --git a/app/code/Magento/Quote/Model/Quote/Item.php b/app/code/Magento/Quote/Model/Quote/Item.php
index 56ea708036533251670e39c59ed59569732de0b2..51694e5f68864efedb456e3628e2c0d66d2d557e 100644
--- a/app/code/Magento/Quote/Model/Quote/Item.php
+++ b/app/code/Magento/Quote/Model/Quote/Item.php
@@ -20,7 +20,6 @@ use Magento\Framework\Api\ExtensionAttributesFactory;
  * @method \Magento\Quote\Model\Quote\Item setCreatedAt(string $value)
  * @method string getUpdatedAt()
  * @method \Magento\Quote\Model\Quote\Item setUpdatedAt(string $value)
- * @method \Magento\Quote\Model\Quote\Item setProductId(int $value)
  * @method int getStoreId()
  * @method \Magento\Quote\Model\Quote\Item setStoreId(int $value)
  * @method int getParentItemId()
diff --git a/app/code/Magento/Quote/Model/QuoteAddressValidator.php b/app/code/Magento/Quote/Model/QuoteAddressValidator.php
index e92780f4056dba9f10a7158e9abd6cdae5470a4a..13df66e5f9f2513a5b176abb3c90d2b641a8ea88 100644
--- a/app/code/Magento/Quote/Model/QuoteAddressValidator.php
+++ b/app/code/Magento/Quote/Model/QuoteAddressValidator.php
@@ -13,7 +13,7 @@ class QuoteAddressValidator
      *
      * @var \Magento\Customer\Api\AddressRepositoryInterface
      */
-    protected $addressReporitory;
+    protected $addressRepository;
 
     /**
      * Customer repository.
@@ -39,7 +39,7 @@ class QuoteAddressValidator
         \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
         \Magento\Customer\Model\Session $customerSession
     ) {
-        $this->addressReporitory = $addressRepository;
+        $this->addressRepository = $addressRepository;
         $this->customerRepository = $customerRepository;
         $this->customerSession = $customerSession;
     }
@@ -67,7 +67,7 @@ class QuoteAddressValidator
         // validate address id
         if ($addressData->getId()) {
             try {
-                $address = $this->addressReporitory->getById($addressData->getId());
+                $address = $this->addressRepository->getById($addressData->getId());
             } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
                 throw new \Magento\Framework\Exception\NoSuchEntityException(
                     __('Invalid address id %1', $addressData->getId())
diff --git a/app/code/Magento/Quote/Model/QuoteManagement.php b/app/code/Magento/Quote/Model/QuoteManagement.php
index f341b5894b9fb0a5a5da68f92c6a5b04e79fe2ca..8efb0a3794ddc6a584f1b4ae333c14a12ccac911 100644
--- a/app/code/Magento/Quote/Model/QuoteManagement.php
+++ b/app/code/Magento/Quote/Model/QuoteManagement.php
@@ -297,11 +297,6 @@ class QuoteManagement implements \Magento\Quote\Api\CartManagementInterface
      */
     public function placeOrder($cartId, $agreements = null, PaymentInterface $paymentMethod = null)
     {
-        if (!$this->agreementsValidator->isValid($agreements)) {
-            throw new \Magento\Framework\Exception\CouldNotSaveException(
-                __('Please agree to all the terms and conditions before placing the order.')
-            );
-        }
         $quote = $this->quoteRepository->getActive($cartId);
         if ($paymentMethod) {
             $paymentMethod->setChecks([
diff --git a/app/code/Magento/Quote/Model/ShippingMethodManagement.php b/app/code/Magento/Quote/Model/ShippingMethodManagement.php
index f8a39533b4233cf77b9365821857ca0e973ada0c..f54ab223a9d55f23a7610bbd204064ac86c0ac97 100644
--- a/app/code/Magento/Quote/Model/ShippingMethodManagement.php
+++ b/app/code/Magento/Quote/Model/ShippingMethodManagement.php
@@ -46,7 +46,6 @@ class ShippingMethodManagement implements ShippingMethodManagementInterface
      * @param QuoteRepository $quoteRepository Quote repository.
      * @param \Magento\Quote\Model\Cart\ShippingMethodConverter $converter Shipping method converter.
      * @param \Magento\Customer\Api\AddressRepositoryInterface $addressRepository Customer Address repository
-     *
      */
     public function __construct(
         QuoteRepository $quoteRepository,
@@ -80,6 +79,9 @@ class ShippingMethodManagement implements ShippingMethodManagementInterface
         $shippingAddress->collectShippingRates();
         /** @var \Magento\Quote\Model\Quote\Address\Rate $shippingRate */
         $shippingRate = $shippingAddress->getShippingRateByCode($shippingMethod);
+        if (!$shippingRate) {
+            return null;
+        }
         return $this->converter->modelToDataObject($shippingRate, $quote->getQuoteCurrencyCode());
     }
 
@@ -140,10 +142,6 @@ class ShippingMethodManagement implements ShippingMethodManagementInterface
         if (!$shippingAddress->getCountryId()) {
             throw new StateException(__('Shipping address is not set'));
         }
-        $billingAddress = $quote->getBillingAddress();
-        if (!$billingAddress->getCountryId()) {
-            throw new StateException(__('Billing address is not set'));
-        }
         $shippingAddress->setShippingMethod($carrierCode . '_' . $methodCode);
         if (!$shippingAddress->getShippingRateByCode($shippingAddress->getShippingMethod())) {
             throw new NoSuchEntityException(
@@ -222,7 +220,7 @@ class ShippingMethodManagement implements ShippingMethodManagementInterface
         $shippingAddress->setRegionId($regionId);
         $shippingAddress->setRegion($region);
         $shippingAddress->setCollectShippingRates(true);
-        $shippingAddress->collectShippingRates();
+        $shippingAddress->collectTotals();
         $shippingRates = $shippingAddress->getGroupedAllShippingRates();
         foreach ($shippingRates as $carrierRates) {
             foreach ($carrierRates as $rate) {
diff --git a/app/code/Magento/Quote/Test/Unit/Model/AddressDetailsManagementTest.php b/app/code/Magento/Quote/Test/Unit/Model/AddressDetailsManagementTest.php
deleted file mode 100644
index ab1e0e6c18be2874a5fbc5f5af17ffd48452e028..0000000000000000000000000000000000000000
--- a/app/code/Magento/Quote/Test/Unit/Model/AddressDetailsManagementTest.php
+++ /dev/null
@@ -1,151 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Quote\Test\Unit\Model;
-
-use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
-
-class AddressDetailsManagementTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Quote\Model\AddressDetailsManagement
-     */
-    protected $model;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $billingAddressManagement;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $shippingAddressManagement;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $paymentMethodManagement;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $shippingMethodManagement;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $addressDetailsFactory;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $dataProcessor;
-
-    /** @var \Magento\Quote\Model\QuoteRepository|\PHPUnit_Framework_MockObject_MockObject */
-    protected $quoteRepository;
-
-    /**
-     * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
-     */
-    protected $objectManager;
-
-    protected function setUp()
-    {
-        $this->objectManager = new ObjectManager($this);
-        $this->billingAddressManagement = $this->getMock('Magento\Quote\Api\BillingAddressManagementInterface');
-        $this->shippingAddressManagement = $this->getMock('Magento\Quote\Api\ShippingAddressManagementInterface');
-        $this->paymentMethodManagement = $this->getMock('Magento\Quote\Api\PaymentMethodManagementInterface');
-        $this->shippingMethodManagement = $this->getMock('Magento\Quote\Api\ShippingMethodManagementInterface');
-        $this->addressDetailsFactory = $this->getMock(
-            'Magento\Quote\Model\AddressDetailsFactory',
-            ['create'],
-            [],
-            '',
-            false
-        );
-        $this->dataProcessor = $this->getMock('Magento\Quote\Model\AddressAdditionalDataProcessor', [], [], '', false);
-        $this->quoteRepository = $this->getMock('Magento\Quote\Model\QuoteRepository', [], [], '', false);
-
-        $this->model = $this->objectManager->getObject(
-            'Magento\Quote\Model\AddressDetailsManagement',
-            [
-                'billingAddressManagement' => $this->billingAddressManagement,
-                'shippingAddressManagement' => $this->shippingAddressManagement,
-                'paymentMethodManagement' => $this->paymentMethodManagement,
-                'shippingMethodManagement' => $this->shippingMethodManagement,
-                'addressDetailsFactory' => $this->addressDetailsFactory,
-                'dataProcessor' => $this->dataProcessor,
-                'quoteRepository' => $this->quoteRepository,
-            ]
-        );
-    }
-
-    public function testSaveAddresses()
-    {
-        $cartId = 100;
-        $additionalData = $this->getMock('\Magento\Quote\Api\Data\AddressAdditionalDataInterface');
-        $billingAddressMock = $this->getMock('\Magento\Quote\Model\Quote\Address', [], [], '', false);
-        $shippingAddressMock = $this->getMock('\Magento\Quote\Model\Quote\Address', [], [], '', false);
-
-        $this->billingAddressManagement->expects($this->once())
-            ->method('assign')
-            ->with($cartId, $billingAddressMock)
-            ->willReturn(1);
-
-        $billingAddressMock->expects($this->once())->method('format')->with('html');
-        $this->billingAddressManagement->expects($this->once())
-            ->method('get')
-            ->with($cartId)
-            ->willReturn($billingAddressMock);
-
-        $this->shippingAddressManagement->expects($this->once())
-            ->method('assign')
-            ->with($cartId, $shippingAddressMock)
-            ->willReturn(1);
-
-        $shippingAddressMock->expects($this->once())->method('format')->with('html');
-        $this->shippingAddressManagement->expects($this->once())
-            ->method('get')
-            ->with($cartId)
-            ->willReturn($shippingAddressMock);
-
-        $shippingMethodMock = $this->getMock('\Magento\Quote\Api\Data\ShippingMethodInterface');
-        $this->shippingMethodManagement->expects($this->once())
-            ->method('getList')
-            ->with($cartId)
-            ->willReturn([$shippingMethodMock]);
-        $paymentMethodMock = $this->getMock('\Magento\Quote\Api\Data\PaymentMethodInterface');
-        $this->paymentMethodManagement->expects($this->once())
-            ->method('getList')
-            ->with($cartId)
-            ->willReturn([$paymentMethodMock]);
-
-        $addressDetailsMock = $this->getMock('\Magento\Quote\Model\AddressDetails', [], [], '', false);
-        $this->addressDetailsFactory->expects($this->once())->method('create')->willReturn($addressDetailsMock);
-
-        $addressDetailsMock->expects($this->once())
-            ->method('setShippingMethods')
-            ->with([$shippingMethodMock])
-            ->willReturnSelf();
-        $addressDetailsMock->expects($this->once())
-            ->method('setPaymentMethods')
-            ->with([$paymentMethodMock])
-            ->willReturnSelf();
-        $this->dataProcessor->expects($this->once())->method('process')->with($additionalData);
-
-        $quote = $this->getMock('Magento\Quote\Model\Quote', [], [], '', false);
-        $quote->expects($this->once())
-            ->method('setCheckoutMethod')
-            ->willReturnSelf();
-
-        $this->quoteRepository
-            ->expects($this->once())
-            ->method('getActive')
-            ->willReturn($quote);
-
-        $this->model->saveAddresses($cartId, $billingAddressMock, $shippingAddressMock, $additionalData, 'register');
-    }
-}
diff --git a/app/code/Magento/Quote/Test/Unit/Model/Cart/Totals/ItemConverterTest.php b/app/code/Magento/Quote/Test/Unit/Model/Cart/Totals/ItemConverterTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b9770ab17fc4d02eb7d75838f4104acf4f41735b
--- /dev/null
+++ b/app/code/Magento/Quote/Test/Unit/Model/Cart/Totals/ItemConverterTest.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Quote\Test\Unit\Model\Cart\Totals;
+
+class ItemConverterTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $configPoolMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $eventManagerMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $totalsFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $dataObjectHelperMock;
+
+    /**
+     * @var \Magento\Quote\Model\Cart\Totals\ItemConverter
+     */
+    private $model;
+
+    public function setUp()
+    {
+        $this->configPoolMock = $this->getMock('Magento\Catalog\Helper\Product\ConfigurationPool', [], [], '', false);
+        $this->eventManagerMock = $this->getMock('Magento\Framework\Event\ManagerInterface');
+        $this->dataObjectHelperMock = $this->getMock('Magento\Framework\Api\DataObjectHelper', [], [], '', false);
+        $this->totalsFactoryMock = $this->getMock(
+            'Magento\Quote\Api\Data\TotalsItemInterfaceFactory',
+            ['create'],
+            [],
+            '',
+            false
+        );
+
+        $this->model = new \Magento\Quote\Model\Cart\Totals\ItemConverter(
+            $this->configPoolMock,
+            $this->eventManagerMock,
+            $this->totalsFactoryMock,
+            $this->dataObjectHelperMock
+        );
+    }
+
+    public function testModelToDataObject()
+    {
+        $productType = 'simple';
+
+        $itemMock = $this->getMock('Magento\Quote\Model\Quote\Item', [], [], '', false);
+        $itemMock->expects($this->once())->method('toArray')->will($this->returnValue(['options' => []]));
+        $itemMock->expects($this->any())->method('getProductType')->will($this->returnValue($productType));
+
+        $simpleConfigMock = $this->getMock('Magento\Catalog\Helper\Product\Configuration', [], [], '', false);
+        $defaultConfigMock = $this->getMock('Magento\Catalog\Helper\Product\Configuration', [], [], '', false);
+
+        $this->configPoolMock->expects($this->any())->method('getByProductType')
+            ->will($this->returnValueMap([['simple', $simpleConfigMock], ['default', $defaultConfigMock]]));
+
+        $options = ['1' => ['label' => 'option1'], '2' => ['label' => 'option2']];
+        $simpleConfigMock->expects($this->once())->method('getOptions')->with($itemMock)
+            ->will($this->returnValue($options));
+
+        $option = ['data' => 'optionsData', 'label' => ''];
+        $defaultConfigMock->expects($this->any())->method('getFormattedOptionValue')->will($this->returnValue($option));
+
+        $this->eventManagerMock->expects($this->once())->method('dispatch')
+            ->with('items_additional_data', ['item' => $itemMock]);
+
+        $this->totalsFactoryMock->expects($this->once())->method('create');
+
+        $expectedData = [
+            'options' => '{"1":{"data":"optionsData","label":"option1"},"2":{"data":"optionsData","label":"option2"}}'
+        ];
+        $this->dataObjectHelperMock->expects($this->once())->method('populateWithArray')
+            ->with(null, $expectedData, '\Magento\Quote\Api\Data\TotalsItemInterface');
+
+        $this->model->modelToDataObject($itemMock);
+    }
+}
diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php
index 56885a81d78648500927d8b77992e9cddea8a2ee..287aaaa980f7ae354b3726adaea44f2e893cdbfc 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteManagementTest.php
@@ -717,47 +717,10 @@ class QuoteManagementTest extends \PHPUnit_Framework_TestCase
         $this->checkoutSessionMock->expects($this->once())->method('setLastSuccessQuoteId')->with($cartId);
         $this->checkoutSessionMock->expects($this->once())->method('setLastOrderId')->with($orderId);
         $this->checkoutSessionMock->expects($this->once())->method('setLastRealOrderId')->with($orderIncrementId);
-        $this->agreementsValidatorMock->expects($this->once())->method('isValid')->willReturn(true);
 
         $this->assertEquals($orderId, $service->placeOrder($cartId));
     }
 
-    /**
-     * @expectedException \Magento\Framework\Exception\CouldNotSaveException
-     */
-    public function testPlaceOrderIfAgreementsIsNotValid()
-    {
-        $this->agreementsValidatorMock->expects($this->once())->method('isValid')->willReturn(false);
-        
-        /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Quote\Model\QuoteManagement $service */
-        $service = $this->getMock(
-            '\Magento\Quote\Model\QuoteManagement',
-            ['submit'],
-            [
-                'eventManager' => $this->eventManager,
-                'quoteValidator' => $this->quoteValidator,
-                'orderFactory' => $this->orderFactory,
-                'orderManagement' => $this->orderManagement,
-                'customerManagement' => $this->customerManagement,
-                'quoteAddressToOrder' => $this->quoteAddressToOrder,
-                'quoteAddressToOrderAddress' => $this->quoteAddressToOrderAddress,
-                'quoteItemToOrderItem' => $this->quoteItemToOrderItem,
-                'quotePaymentToOrderPayment' => $this->quotePaymentToOrderPayment,
-                'userContext' => $this->userContextMock,
-                'quoteRepository' => $this->quoteRepositoryMock,
-                'customerRepository' => $this->customerRepositoryMock,
-                'customerModelFactory' => $this->customerFactoryMock,
-                'dataObjectHelper' => $this->dataObjectHelperMock,
-                'storeManager' => $this->storeManagerMock,
-                'checkoutSession' => $this->checkoutSessionMock,
-                'customerSession' => $this->customerSessionMock,
-                'accountManagement' => $this->accountManagementMock,
-                'agreementsValidator' => $this->agreementsValidatorMock,
-            ]
-        );
-        $service->placeOrder(45);
-    }
-
     public function testPlaceOrder()
     {
         $cartId = 323;
@@ -829,7 +792,6 @@ class QuoteManagementTest extends \PHPUnit_Framework_TestCase
         $this->checkoutSessionMock->expects($this->once())->method('setLastSuccessQuoteId')->with($cartId);
         $this->checkoutSessionMock->expects($this->once())->method('setLastOrderId')->with($orderId);
         $this->checkoutSessionMock->expects($this->once())->method('setLastRealOrderId')->with($orderIncrementId);
-        $this->agreementsValidatorMock->expects($this->once())->method('isValid')->willReturn(true);
 
         $paymentMethod = $this->getMock('Magento\Quote\Model\Quote\Payment', ['setChecks', 'getData'], [], '', false);
         $paymentMethod->expects($this->once())->method('setChecks');
diff --git a/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressManagementTest.php b/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressManagementTest.php
index 4c5bffe80077615734f94e7df2f3cee0f0c61f4d..2fea9a5b9a15c1c67d7bcf85e49814f90162f5f6 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressManagementTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/ShippingAddressManagementTest.php
@@ -32,6 +32,11 @@ class ShippingAddressManagementTest extends \PHPUnit_Framework_TestCase
      */
     protected $validatorMock;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $scopeConfigMock;
+
     /**
      * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
      */
@@ -41,6 +46,7 @@ class ShippingAddressManagementTest extends \PHPUnit_Framework_TestCase
     {
         $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
         $this->quoteRepositoryMock = $this->getMock('\Magento\Quote\Model\QuoteRepository', [], [], '', false);
+        $this->scopeConfigMock = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
 
         $this->quoteAddressMock = $this->getMock(
             '\Magento\Quote\Model\Quote\Address',
@@ -66,7 +72,8 @@ class ShippingAddressManagementTest extends \PHPUnit_Framework_TestCase
             [
                 'quoteRepository' => $this->quoteRepositoryMock,
                 'addressValidator' => $this->validatorMock,
-                'logger' => $this->getMock('\Psr\Log\LoggerInterface')
+                'logger' => $this->getMock('\Psr\Log\LoggerInterface'),
+                'scopeConfig' => $this->scopeConfigMock
             ]
         );
     }
@@ -167,6 +174,28 @@ class ShippingAddressManagementTest extends \PHPUnit_Framework_TestCase
         $this->service->assign('cart867', $this->quoteAddressMock);
     }
 
+    /**
+     * @expectedException \Magento\Framework\Exception\InputException
+     */
+    public function testSetAddressWithViolationOfMinimumAmount()
+    {
+        $storeId = 12;
+        $this->quoteAddressMock->expects($this->once())->method('collectTotals')->willReturnSelf();
+        $this->quoteAddressMock->expects($this->once())->method('save');
+
+        $quoteMock = $this->getMock('\Magento\Quote\Model\Quote', [], [], '', false);
+        $this->quoteRepositoryMock->expects($this->once())->method('getActive')->with('cart123')
+            ->will($this->returnValue($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->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);
+    }
+
     public function testGetAddress()
     {
         $quoteMock = $this->getMock('\Magento\Quote\Model\Quote', [], [], '', false);
diff --git a/app/code/Magento/Quote/Test/Unit/Model/ShippingMethodManagementTest.php b/app/code/Magento/Quote/Test/Unit/Model/ShippingMethodManagementTest.php
index ef5992e11f7af3c0dbedf4f7b8d263a12cf1804e..fd760977a6c89f57308b2142d4acd827af06bfa4 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/ShippingMethodManagementTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/ShippingMethodManagementTest.php
@@ -316,39 +316,6 @@ class ShippingMethodManagementTest extends \PHPUnit_Framework_TestCase
         $this->model->set($cartId, $carrierCode, $methodCode);
     }
 
-    /**
-     * @expectedException \Magento\Framework\Exception\StateException
-     * @expectedExceptionMessage Billing address is not set
-     */
-    public function testSetMethodWithoutBillingAddress()
-    {
-        $cartId = 12;
-        $carrierCode = 34;
-        $methodCode = 56;
-        $countryId = 1;
-
-        $this->quoteRepositoryMock->expects($this->once())
-            ->method('getActive')->with($cartId)->will($this->returnValue($this->quoteMock));
-        $this->quoteMock->expects($this->once())->method('getItemsCount')->will($this->returnValue(1));
-        $this->quoteMock->expects($this->once())->method('isVirtual')->will($this->returnValue(false));
-        $this->quoteMock->expects($this->once())
-            ->method('getShippingAddress')->will($this->returnValue($this->shippingAddressMock));
-        $this->shippingAddressMock->expects($this->once())
-            ->method('getCountryId')->will($this->returnValue($countryId));
-        $billingAddressMock = $this->getMock(
-            '\Magento\Quote\Model\Quote\Address',
-            ['getCountryId', '__wakeup'],
-            [],
-            '',
-            false
-        );
-        $this->quoteMock->expects($this->once())
-            ->method('getBillingAddress')->will($this->returnValue($billingAddressMock));
-        $billingAddressMock->expects($this->once())->method('getCountryId')->will($this->returnValue(null));
-
-        $this->model->set($cartId, $carrierCode, $methodCode);
-    }
-
     /**
      * @expectedException \Magento\Framework\Exception\NoSuchEntityException
      * @expectedExceptionMessage Carrier with such method not found: 34, 56
@@ -365,16 +332,6 @@ class ShippingMethodManagementTest extends \PHPUnit_Framework_TestCase
         $this->quoteMock->expects($this->once())->method('isVirtual')->will($this->returnValue(false));
         $this->quoteMock->expects($this->once())
             ->method('getShippingAddress')->will($this->returnValue($this->shippingAddressMock));
-        $billingAddressMock = $this->getMock(
-            '\Magento\Quote\Model\Quote\Address',
-            ['getCountryId', '__wakeup'],
-            [],
-            '',
-            false
-        );
-        $this->quoteMock->expects($this->once())
-            ->method('getBillingAddress')->will($this->returnValue($billingAddressMock));
-        $billingAddressMock->expects($this->once())->method('getCountryId')->will($this->returnValue(23));
         $this->shippingAddressMock->expects($this->once())
             ->method('getCountryId')->will($this->returnValue($countryId));
         $this->shippingAddressMock->expects($this->once())
@@ -405,19 +362,6 @@ class ShippingMethodManagementTest extends \PHPUnit_Framework_TestCase
             ->method('getShippingAddress')->will($this->returnValue($this->shippingAddressMock));
         $this->shippingAddressMock->expects($this->once())
             ->method('getCountryId')->will($this->returnValue($countryId));
-        $billingAddressMock = $this->getMock(
-            '\Magento\Quote\Model\Quote\Address',
-            [
-                'getCountryId',
-                '__wakeup'
-            ],
-            [],
-            '',
-            false
-        );
-        $this->quoteMock->expects($this->once())
-            ->method('getBillingAddress')->will($this->returnValue($billingAddressMock));
-        $billingAddressMock->expects($this->once())->method('getCountryId')->will($this->returnValue(23));
         $this->shippingAddressMock->expects($this->once())
             ->method('setShippingMethod')->with($carrierCode . '_' . $methodCode);
         $this->shippingAddressMock->expects($this->once())
@@ -464,19 +408,6 @@ class ShippingMethodManagementTest extends \PHPUnit_Framework_TestCase
         $this->quoteMock->expects($this->once())->method('isVirtual')->will($this->returnValue(false));
         $this->quoteMock->expects($this->once())
             ->method('getShippingAddress')->will($this->returnValue($this->shippingAddressMock));
-        $billingAddressMock = $this->getMock(
-            '\Magento\Quote\Model\Quote\Address',
-            [
-                'getCountryId',
-                '__wakeup'
-            ],
-            [],
-            '',
-            false
-        );
-        $this->quoteMock->expects($this->once())
-            ->method('getBillingAddress')->will($this->returnValue($billingAddressMock));
-        $billingAddressMock->expects($this->once())->method('getCountryId')->will($this->returnValue(23));
         $this->shippingAddressMock->expects($this->once())
             ->method('getCountryId')->will($this->returnValue($countryId));
         $this->shippingAddressMock->expects($this->once())
diff --git a/app/code/Magento/Quote/etc/di.xml b/app/code/Magento/Quote/etc/di.xml
index 66cae592e21018589902a907529cbcc87007c8e4..0c3b51e3a5ddc2e2a5c3b6991de7eb92629c999b 100644
--- a/app/code/Magento/Quote/etc/di.xml
+++ b/app/code/Magento/Quote/etc/di.xml
@@ -24,6 +24,7 @@
     <preference for="Magento\Quote\Api\CartTotalRepositoryInterface" type="\Magento\Quote\Model\Cart\CartTotalRepository" />
     <preference for="Magento\Quote\Api\CartTotalManagementInterface" type="\Magento\Quote\Model\Cart\CartTotalManagement" />
     <preference for="Magento\Quote\Api\Data\TotalsInterface" type="\Magento\Quote\Model\Cart\Totals" />
+    <preference for="Magento\Quote\Api\Data\TotalSegmentInterface" type="\Magento\Quote\Model\Cart\TotalSegment" />
     <preference for="Magento\Quote\Api\Data\TotalsItemInterface" type="\Magento\Quote\Model\Cart\Totals\Item" />
     <preference for="Magento\Quote\Api\Data\CurrencyInterface" type="\Magento\Quote\Model\Cart\Currency" />
     <preference for="Magento\Quote\Api\GuestCartManagementInterface" type="Magento\Quote\Model\GuestCart\GuestCartManagement" />
@@ -35,7 +36,6 @@
     <preference for="Magento\Quote\Api\GuestShippingAddressManagementInterface" type="Magento\Quote\Model\GuestCart\GuestShippingAddressManagement" />
     <preference for="Magento\Quote\Api\GuestShippingMethodManagementInterface" type="Magento\Quote\Model\GuestCart\GuestShippingMethodManagement" />
     <preference for="Magento\Quote\Api\GuestBillingAddressManagementInterface" type="Magento\Quote\Model\GuestCart\GuestBillingAddressManagement" />
-    <preference for="Magento\Quote\Api\GuestAddressDetailsManagementInterface" type="Magento\Quote\Model\GuestCart\GuestAddressDetailsManagement" />
     <preference for="Magento\Quote\Api\GuestCartTotalManagementInterface" type="\Magento\Quote\Model\GuestCart\GuestCartTotalManagement" />
     <preference for="Magento\Quote\Api\Data\EstimateAddressInterface" type="Magento\Quote\Model\EstimateAddress" />
     <type name="Magento\Webapi\Controller\Rest\ParamsOverrider">
@@ -55,8 +55,6 @@
             <argument name="addressConfig" xsi:type="object">Magento\Customer\Model\Address\Config\Proxy</argument>
         </arguments>
     </type>
-    <preference for="Magento\Quote\Api\AddressDetailsManagementInterface" type="Magento\Quote\Model\AddressDetailsManagement" />
-    <preference for="Magento\Quote\Api\Data\AddressDetailsInterface" type="Magento\Quote\Model\AddressDetails" />
     <preference for="Magento\Quote\Api\Data\AddressAdditionalDataInterface" type="Magento\Quote\Model\AddressAdditionalData" />
     <preference for="Magento\Quote\Api\Data\TotalsAdditionalDataInterface" type="Magento\Quote\Model\Cart\TotalsAdditionalData" />
     <preference for="\Magento\Quote\Model\Quote\Address\CustomAttributeListInterface" type="\Magento\Quote\Model\Quote\Address\CustomAttributeList" />
diff --git a/app/code/Magento/Quote/etc/webapi.xml b/app/code/Magento/Quote/etc/webapi.xml
index 9b6ca15468d654d70622b0dba27d47a02f5f806d..8e5e097a995cd6aa38aa77f568f2c0ba97f1d9cd 100644
--- a/app/code/Magento/Quote/etc/webapi.xml
+++ b/app/code/Magento/Quote/etc/webapi.xml
@@ -145,6 +145,24 @@
             <parameter name="cartId" force="true">%cart_id%</parameter>
         </data>
     </route>
+    <route url="/V1/carts/mine/estimate-shipping-methods" method="POST">
+        <service class="Magento\Quote\Api\ShippingMethodManagementInterface" method="estimateByAddress"/>
+        <resources>
+            <resource ref="self" />
+        </resources>
+        <data>
+            <parameter name="cartId" force="true">%cart_id%</parameter>
+        </data>
+    </route>
+    <route url="/V1/carts/mine/estimate-shipping-methods-by-address-id" method="POST">
+        <service class="Magento\Quote\Api\ShippingMethodManagementInterface" method="estimateByAddressId"/>
+        <resources>
+            <resource ref="self" />
+        </resources>
+        <data>
+            <parameter name="cartId" force="true">%cart_id%</parameter>
+        </data>
+    </route>
 
     <!-- Managing Guest Cart Shipment Method -->
     <route url="/V1/guest-carts/:cartId/selected-shipping-method" method="PUT">
@@ -165,6 +183,12 @@
             <resource ref="anonymous" />
         </resources>
     </route>
+    <route url="/V1/guest-carts/:cartId/estimate-shipping-methods" method="POST">
+        <service class="Magento\Quote\Api\GuestShippingMethodManagementInterface" method="estimateByAddress"/>
+        <resources>
+            <resource ref="anonymous" />
+        </resources>
+    </route>
 
     <!-- Managing Cart Items -->
     <route url="/V1/carts/:cartId/items" method="GET">
@@ -352,12 +376,6 @@
             <resource ref="anonymous" />
         </resources>
     </route>
-    <route url="/V1/guest-carts/:cartId/addresses" method="POST">
-        <service class="Magento\Quote\Api\GuestAddressDetailsManagementInterface" method="saveAddresses"/>
-        <resources>
-            <resource ref="anonymous" />
-        </resources>
-    </route>
 
     <!-- Managing My Cart Billing address -->
     <route url="/V1/carts/mine/billing-address" method="GET">
@@ -495,15 +513,6 @@
             <parameter name="cartId" force="true">%cart_id%</parameter>
         </data>
     </route>
-    <route url="/V1/carts/mine/addresses" method="POST">
-        <service class="Magento\Quote\Api\AddressDetailsManagementInterface" method="saveAddresses"/>
-        <resources>
-            <resource ref="self" />
-        </resources>
-        <data>
-            <parameter name="cartId" force="true">%cart_id%</parameter>
-        </data>
-    </route>
 
     <!-- Managing Cart Order -->
     <route url="/V1/carts/:cartId/order" method="PUT">
diff --git a/app/code/Magento/SalesRule/view/frontend/layout/checkout_onepage_index.xml b/app/code/Magento/SalesRule/view/frontend/layout/checkout_onepage_index.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b9ba81bfaa8ec98f6f906d86cc704b184ee417ff
--- /dev/null
+++ b/app/code/Magento/SalesRule/view/frontend/layout/checkout_onepage_index.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+    <body>
+        <referenceBlock name="checkout.root">
+            <arguments>
+                <argument name="jsLayout" xsi:type="array">
+                    <item name="components" xsi:type="array">
+                        <item name="checkout" xsi:type="array">
+                            <item name="children" xsi:type="array">
+                                <item name="steps" xsi:type="array">
+                                    <item name="children" xsi:type="array">
+                                        <item name="billing-step" xsi:type="array">
+                                            <item name="component" xsi:type="string">uiComponent</item>
+                                            <item name="children" xsi:type="array">
+                                                <item name="payment" xsi:type="array">
+                                                    <item name="children" xsi:type="array">
+                                                        <item name="afterMethods" xsi:type="array">
+                                                            <item name="children" xsi:type="array">
+                                                                <item name="store-credit" xsi:type="array">
+                                                                    <item name="component" xsi:type="string">Magento_SalesRule/js/view/payment/discount</item>
+                                                                </item>
+                                                            </item>
+                                                        </item>
+                                                    </item>
+                                                </item>
+                                            </item>
+                                        </item>
+                                    </item>
+                                </item>
+                                <item name="summary" xsi:type="array">
+                                    <item name="children" xsi:type="array">
+                                        <item name="totals" xsi:type="array">
+                                            <item name="children" xsi:type="array">
+                                                <item name="discount" xsi:type="array">
+                                                    <item name="component"  xsi:type="string">Magento_SalesRule/js/view/summary/discount</item>
+                                                    <item name="config" xsi:type="array">
+                                                        <item name="title" xsi:type="string">Discount</item>
+                                                    </item>
+                                                </item>
+                                            </item>
+                                        </item>
+                                    </item>
+                                </item>
+                            </item>
+                        </item>
+                    </item>
+                </argument>
+            </arguments>
+        </referenceBlock>
+    </body>
+</page>
\ No newline at end of file
diff --git a/app/code/Magento/SalesRule/view/frontend/web/js/action/cancel-coupon.js b/app/code/Magento/SalesRule/view/frontend/web/js/action/cancel-coupon.js
new file mode 100644
index 0000000000000000000000000000000000000000..80a6488fb285a34fcf91dc07693843ce731ed85f
--- /dev/null
+++ b/app/code/Magento/SalesRule/view/frontend/web/js/action/cancel-coupon.js
@@ -0,0 +1,51 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+/**
+ * Customer store credit(balance) application
+ */
+/*global define,alert*/
+define(
+    [
+        'ko',
+        'jquery',
+        'Magento_Checkout/js/model/quote',
+        'Magento_Checkout/js/model/resource-url-manager',
+        'Magento_Checkout/js/model/payment-service',
+        'Magento_Ui/js/model/messageList',
+        'mage/storage',
+        'Magento_Checkout/js/action/get-totals'
+    ],
+    function (ko, $, quote, urlManager, paymentService, messageList, storage, getTotalsAction) {
+        'use strict';
+        return function (isApplied, isLoading) {
+            var quoteId = quote.getQuoteId();
+            var url = urlManager.getCancelCouponUrl(quoteId);
+            return storage.delete(
+                url,
+                false
+            ).done(
+                function (response) {
+                    isLoading(false);
+                    var deferred = $.Deferred();
+
+                    getTotalsAction([], deferred);
+                    $.when(deferred).done(function() {
+                        isApplied(false);
+                        paymentService.setPaymentMethods(
+                            paymentService.getAvailablePaymentMethods()
+                        );
+                    });
+                }
+            ).error(
+                function (response) {
+                    isLoading(false);
+                    var error = JSON.parse(response.responseText);
+                    messageList.addErrorMessage(error);
+                }
+            );
+        };
+    }
+);
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
new file mode 100644
index 0000000000000000000000000000000000000000..a76500e4517208b0a166af5a7162b17ddcad9099
--- /dev/null
+++ b/app/code/Magento/SalesRule/view/frontend/web/js/action/set-coupon-code.js
@@ -0,0 +1,54 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+/**
+ * Customer store credit(balance) application
+ */
+/*global define,alert*/
+define(
+    [
+        'ko',
+        'jquery',
+        'Magento_Checkout/js/model/quote',
+        'Magento_Checkout/js/model/resource-url-manager',
+        'Magento_Checkout/js/model/payment-service',
+        'Magento_Ui/js/model/messageList',
+        'mage/storage',
+        'Magento_Checkout/js/action/get-totals'
+    ],
+    function (ko, $, quote, urlManager, paymentService, messageList, storage, getTotalsAction) {
+        'use strict';
+        return function (couponCode, isApplied, isLoading) {
+            var quoteId = quote.getQuoteId();
+            var url = urlManager.getApplyCouponUrl(couponCode, quoteId);
+            return storage.put(
+                url,
+                {},
+                false
+            ).done(
+                function (response) {
+                    if (response) {
+                        isLoading(false);
+                        isApplied(true);
+                        var deferred = $.Deferred();
+
+                        getTotalsAction([], deferred);
+                        $.when(deferred).done(function() {
+                            paymentService.setPaymentMethods(
+                                paymentService.getAvailablePaymentMethods()
+                            );
+                        });
+                    }
+                }
+            ).error(
+                function (response) {
+                    isLoading(false);
+                    var error = JSON.parse(response.responseText);
+                    messageList.addErrorMessage(error);
+                }
+            );
+        };
+    }
+);
diff --git a/app/code/Magento/SalesRule/view/frontend/web/js/view/payment/discount.js b/app/code/Magento/SalesRule/view/frontend/web/js/view/payment/discount.js
new file mode 100644
index 0000000000000000000000000000000000000000..ddbce5003a402df4de8db9b23a181beed36c7a59
--- /dev/null
+++ b/app/code/Magento/SalesRule/view/frontend/web/js/view/payment/discount.js
@@ -0,0 +1,63 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define(
+    [
+        'jquery',
+        'ko',
+        'uiComponent',
+        'Magento_Checkout/js/model/quote',
+        'Magento_SalesRule/js/action/set-coupon-code',
+        'Magento_SalesRule/js/action/cancel-coupon'
+    ],
+    function ($, ko, Component, quote, setCouponCodeAction, cancelCouponAction) {
+        'use strict';
+        var totals = quote.getTotals();
+        var couponCode = ko.observable(null);
+        if (totals()) {
+            couponCode(totals()['coupon_code']);
+        }
+        var isApplied = ko.observable(couponCode() != null);
+        var isLoading = ko.observable(false);
+        return Component.extend({
+            defaults: {
+                template: 'Magento_SalesRule/payment/discount'
+            },
+            couponCode: couponCode,
+            /**
+             * Applied flag
+             */
+            isApplied: isApplied,
+            isLoading: isLoading,
+            /**
+             * Coupon code application procedure
+             */
+            apply: function() {
+                if (this.validate()) {
+                    isLoading(true);
+                    setCouponCodeAction(couponCode(), isApplied, isLoading);
+                }
+            },
+            /**
+             * Cancel using coupon
+             */
+            cancel: function() {
+                if (this.validate()) {
+                    isLoading(true);
+                    couponCode('');
+                    cancelCouponAction(isApplied, isLoading);
+                }
+            },
+            /**
+             * Coupon form validation
+             *
+             * @returns {boolean}
+             */
+            validate: function() {
+                var form = '#discount-form';
+                return $(form).validation() && $(form).validation('isValid');
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/SalesRule/view/frontend/web/js/view/summary/discount.js b/app/code/Magento/SalesRule/view/frontend/web/js/view/summary/discount.js
new file mode 100644
index 0000000000000000000000000000000000000000..8558966cd71e5aa7af00dc70ba339179ce9d4917
--- /dev/null
+++ b/app/code/Magento/SalesRule/view/frontend/web/js/view/summary/discount.js
@@ -0,0 +1,39 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [
+        'Magento_Checkout/js/view/summary/abstract-total',
+        'Magento_Checkout/js/model/quote',
+    ],
+    function (Component, quote) {
+        "use strict";
+        return Component.extend({
+            defaults: {
+                template: 'Magento_SalesRule/summary/discount'
+            },
+            totals: quote.getTotals(),
+            isDisplayed: function() {
+                return this.isFullMode() && this.getPureValue() != 0;
+            },
+            getCouponCode: function() {
+                if (!this.totals()) {
+                    return null;
+                }
+                return this.totals()['coupon_code'];
+            },
+            getPureValue: function() {
+                var price = 0;
+                if (this.totals() && this.totals().discount_amount) {
+                    price = parseFloat(this.totals().discount_amount);
+                }
+                return price;
+            },
+            getValue: function() {
+                return this.getFormattedPrice(this.getPureValue());
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/SalesRule/view/frontend/web/template/payment/discount.html b/app/code/Magento/SalesRule/view/frontend/web/template/payment/discount.html
new file mode 100644
index 0000000000000000000000000000000000000000..92041308eada737fc81f6ab15b7bad6e0e041e8f
--- /dev/null
+++ b/app/code/Magento/SalesRule/view/frontend/web/template/payment/discount.html
@@ -0,0 +1,47 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<div class="payment-option _collapsible opc-payment-additional discount-code"
+     data-bind="mageInit: {'collapsible':{'openedState': '_active'}}">
+    <div class="payment-option-title field choice" data-role="title">
+        <span class="action action-toggle" id="block-discount-heading" role="heading" aria-level="2">
+            <!-- ko text: $t('Apply promo code')--><!-- /ko -->
+        </span>
+    </div>
+    <div class="payment-option-content" data-role="content">
+        <form class="form form-discount" id="discount-form" data-bind="blockLoader: isLoading">
+            <div class="payment-option-inner">
+                <div class="field">
+                    <label class="label" for="discount-code">
+                        <span data-bind="text: $t('Enter promo code')"></span>
+                    </label>
+                    <div class="control">
+                        <input class="input-text"
+                               type="text"
+                               id="discount-code"
+                               name="discount_code"
+                               data-validate="{'required-entry':true}"
+                               data-bind="value: couponCode, attr:{placeholder: $t('Enter promo code')} " />
+                    </div>
+                </div>
+            </div>
+            <div class="actions-toolbar">
+                <div class="primary">
+                    <!-- ko ifnot: isApplied() -->
+                        <button class="action action-apply" type="submit" data-bind="'value': $t('Apply'), click: apply">
+                            <span><!-- ko text: $t('Apply')--><!-- /ko --></span>
+                        </button>
+                    <!-- /ko -->
+                    <!-- ko if: isApplied() -->
+                        <button class="action action-cancel" type="submit" data-bind="'value': $t('Cancel'), click: cancel">
+                            <span><!-- ko text: $t('Cancel coupon')--><!-- /ko --></span>
+                        </button>
+                    <!-- /ko -->
+                </div>
+            </div>
+        </form>
+    </div>
+</div>
diff --git a/app/code/Magento/SalesRule/view/frontend/web/template/summary/discount.html b/app/code/Magento/SalesRule/view/frontend/web/template/summary/discount.html
new file mode 100644
index 0000000000000000000000000000000000000000..60ac9c7982a5f6a0a510abd25fb67e4ee11dc13a
--- /dev/null
+++ b/app/code/Magento/SalesRule/view/frontend/web/template/summary/discount.html
@@ -0,0 +1,17 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<!-- ko if: isDisplayed() -->
+<tr class="totals discount">
+    <th class="mark" scope="row">
+        <span class="title" data-bind="text: title"></span>
+        <span class="discount coupon" data-bind="text: getCouponCode()"></span>
+    </th>
+    <td class="amount">
+        <span class="price" data-bind="text: getValue(), attr: {'data-th': $t(name) }"></span>
+    </td>
+</tr>
+<!-- /ko -->
diff --git a/app/code/Magento/Shipping/etc/acl.xml b/app/code/Magento/Shipping/etc/acl.xml
index 74811607f3d06fbc8d002fa03dc27d47a0be0f59..feacd4d501dc3da36c629f277754c456eb7f6762 100644
--- a/app/code/Magento/Shipping/etc/acl.xml
+++ b/app/code/Magento/Shipping/etc/acl.xml
@@ -13,6 +13,7 @@
                     <resource id="Magento_Backend::stores_settings">
                         <resource id="Magento_Config::config">
                             <resource id="Magento_Shipping::config_shipping" title="Shipping Settings Section" sortOrder="5" />
+                            <resource id="Magento_Shipping::shipping_policy" title="Shipping Policy Parameters Section" sortOrder="5" />
                             <resource id="Magento_Shipping::carriers" title="Shipping Methods Section" sortOrder="5" />
                         </resource>
                     </resource>
diff --git a/app/code/Magento/Shipping/etc/adminhtml/system.xml b/app/code/Magento/Shipping/etc/adminhtml/system.xml
index 40e4568907c17aa71bd790790b3ea912932eb260..5b56b96f719b7fbd3270e7b253dab0b1f862205d 100644
--- a/app/code/Magento/Shipping/etc/adminhtml/system.xml
+++ b/app/code/Magento/Shipping/etc/adminhtml/system.xml
@@ -7,7 +7,7 @@
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../Config/etc/system_file.xsd">
     <system>
-        <section id="shipping" translate="label" type="text" sortOrder="310" showInDefault="1" showInWebsite="1" showInStore="0">
+        <section id="shipping" translate="label" type="text" sortOrder="310" showInDefault="1" showInWebsite="1" showInStore="1">
             <label>Shipping Settings</label>
             <tab>sales</tab>
             <resource>Magento_Shipping::config_shipping</resource>
@@ -34,6 +34,19 @@
                     <label>Street Address Line 2</label>
                 </field>
             </group>
+            <group id="shipping_policy" translate="label" type="text" sortOrder="120" showInDefault="1" showInWebsite="1" showInStore="1">
+                <label>Shipping Policy Parameters</label>
+                <field id="enable_shipping_policy" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Apply custom Shipping Policy</label>
+                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
+                </field>
+                <field id="shipping_policy_content" translate="label" type="textarea" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Shipping Policy</label>
+                    <depends>
+                        <field id="enable_shipping_policy">1</field>
+                    </depends>
+                </field>
+            </group>
         </section>
         <section id="carriers" translate="label" type="text" sortOrder="320" showInDefault="1" showInWebsite="1" showInStore="1">
             <label>Shipping Methods</label>
diff --git a/app/code/Magento/Shipping/view/frontend/layout/checkout_onepage_index.xml b/app/code/Magento/Shipping/view/frontend/layout/checkout_onepage_index.xml
new file mode 100644
index 0000000000000000000000000000000000000000..14a25393667d7b7bfe54cce7ba0b750f65b0cfd6
--- /dev/null
+++ b/app/code/Magento/Shipping/view/frontend/layout/checkout_onepage_index.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+    <body>
+        <referenceBlock name="checkout.root">
+            <arguments>
+                <argument name="jsLayout" xsi:type="array">
+                    <item name="components" xsi:type="array">
+                        <item name="checkout" xsi:type="array">
+                            <item name="children" xsi:type="array">
+                                <item name="steps" xsi:type="array">
+                                    <item name="children" xsi:type="array">
+                                        <item name="shipping-step" xsi:type="array">
+                                            <item name="children" xsi:type="array">
+                                                <item name="shippingAddress" xsi:type="array">
+                                                    <item name="children" xsi:type="array">
+                                                        <item name="before-shipping-method-form" xsi:type="array">
+                                                            <item name="children" xsi:type="array">
+                                                                <item name="shipping_policy" xsi:type="array">
+                                                                    <item name="component" xsi:type="string">Magento_Shipping/js/view/checkout/shipping/shipping-policy</item>
+                                                                </item>
+                                                            </item>
+                                                        </item>
+                                                    </item>
+                                                </item>
+                                            </item>
+                                        </item>
+                                    </item>
+                                </item>
+                            </item>
+                        </item>
+                    </item>
+                </argument>
+            </arguments>
+        </referenceBlock>
+    </body>
+</page>
diff --git a/app/code/Magento/Shipping/view/frontend/web/js/model/config.js b/app/code/Magento/Shipping/view/frontend/web/js/model/config.js
new file mode 100644
index 0000000000000000000000000000000000000000..d69bd10ae7c674ea543ddd0cb30d97b567ef3056
--- /dev/null
+++ b/app/code/Magento/Shipping/view/frontend/web/js/model/config.js
@@ -0,0 +1,13 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define([], function () {
+        "use strict";
+        return function () {
+            return window.checkoutConfig.shippingPolicy
+        }
+    }
+);
diff --git a/app/code/Magento/Shipping/view/frontend/web/js/view/checkout/shipping/shipping-policy.js b/app/code/Magento/Shipping/view/frontend/web/js/view/checkout/shipping/shipping-policy.js
new file mode 100644
index 0000000000000000000000000000000000000000..1a41b1ae5770388c85fa13b76b3fa4abdf2689a7
--- /dev/null
+++ b/app/code/Magento/Shipping/view/frontend/web/js/view/checkout/shipping/shipping-policy.js
@@ -0,0 +1,18 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'uiComponent',
+    'Magento_Shipping/js/model/config'
+
+], function (Component, config) {
+    'use strict';
+
+    return Component.extend({
+        defaults: {
+            template: 'Magento_Shipping/checkout/shipping/shipping-policy'
+        },
+        config: config()
+    });
+});
diff --git a/app/code/Magento/Shipping/view/frontend/web/template/checkout/shipping/shipping-policy.html b/app/code/Magento/Shipping/view/frontend/web/template/checkout/shipping/shipping-policy.html
new file mode 100644
index 0000000000000000000000000000000000000000..1c0cc5c80e2efc4a25ad4c7f9e52266b569bbb82
--- /dev/null
+++ b/app/code/Magento/Shipping/view/frontend/web/template/checkout/shipping/shipping-policy.html
@@ -0,0 +1,14 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<div class="shipping-policy-block field-tooltip" data-bind="visible: config.isEnabled">
+    <span class="field-tooltip-action">
+        <!-- ko text: $t('See our shipping policy') --><!-- /ko -->
+    </span>
+    <div class="field-tooltip-content">
+        <span data-bind="html: config.shippingPolicyContent"></span>
+    </div>
+</div>
diff --git a/app/code/Magento/Tax/Api/Data/GrandTotalDetailsInterface.php b/app/code/Magento/Tax/Api/Data/GrandTotalDetailsInterface.php
index 3fb1e6fd5b28ea248de75a35a11bf4336d10684c..e36af22d214c62161943940fd4e7439596ca4b56 100644
--- a/app/code/Magento/Tax/Api/Data/GrandTotalDetailsInterface.php
+++ b/app/code/Magento/Tax/Api/Data/GrandTotalDetailsInterface.php
@@ -3,11 +3,9 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Tax\Api\Data;
 
-
-interface GrandTotalDetailsInterface extends \Magento\Framework\Api\ExtensibleDataInterface
+interface GrandTotalDetailsInterface
 {
     /**
      * Get tax amount value
@@ -47,21 +45,4 @@ interface GrandTotalDetailsInterface extends \Magento\Framework\Api\ExtensibleDa
      * @return $this
      */
     public function setGroupId($id);
-
-    /**
-     * {@inheritdoc}
-     *
-     * @return \Magento\Tax\Api\Data\GrandTotalDetailsExtensionInterface|null
-     */
-    public function getExtensionAttributes();
-
-    /**
-     * {@inheritdoc}
-     *
-     * @param \Magento\Tax\Api\Data\GrandTotalDetailsExtensionInterface $extensionAttributes
-     * @return $this
-     */
-    public function setExtensionAttributes(
-        \Magento\Tax\Api\Data\GrandTotalDetailsExtensionInterface $extensionAttributes
-    );
 }
diff --git a/app/code/Magento/Tax/Api/Data/GrandTotalRatesInterface.php b/app/code/Magento/Tax/Api/Data/GrandTotalRatesInterface.php
index f6d39a9d385d5add5389df19846d273fd42f31c9..39dda8c3536fc456bf9ac4d9d22dd9c46d9d2d22 100644
--- a/app/code/Magento/Tax/Api/Data/GrandTotalRatesInterface.php
+++ b/app/code/Magento/Tax/Api/Data/GrandTotalRatesInterface.php
@@ -3,11 +3,9 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
 namespace Magento\Tax\Api\Data;
 
-
-interface GrandTotalRatesInterface extends \Magento\Framework\Api\ExtensibleDataInterface
+interface GrandTotalRatesInterface
 {
     /**
      * Get tax percentage value
@@ -34,21 +32,4 @@ interface GrandTotalRatesInterface extends \Magento\Framework\Api\ExtensibleData
      * @return $this
      */
     public function setTitle($title);
-
-    /**
-     * Retrieve existing extension attributes object or create a new one.
-     *
-     * @return \Magento\Tax\Api\Data\GrandTotalRatesExtensionInterface|null
-     */
-    public function getExtensionAttributes();
-
-    /**
-     * Set an extension attributes object.
-     *
-     * @param \Magento\Tax\Api\Data\GrandTotalRatesExtensionInterface $extensionAttributes
-     * @return $this
-     */
-    public function setExtensionAttributes(
-        \Magento\Tax\Api\Data\GrandTotalRatesExtensionInterface $extensionAttributes
-    );
 }
diff --git a/app/code/Magento/Tax/Model/Calculation/GrandTotalDetails.php b/app/code/Magento/Tax/Model/Calculation/GrandTotalDetails.php
index 79cc180e80fceddbf6fde95b704b79c5c09e143b..a3301eb85796a2163d3435005b0a11c80ee6d83a 100644
--- a/app/code/Magento/Tax/Model/Calculation/GrandTotalDetails.php
+++ b/app/code/Magento/Tax/Model/Calculation/GrandTotalDetails.php
@@ -7,19 +7,19 @@
 namespace Magento\Tax\Model\Calculation;
 
 use Magento\Tax\Api\Data\GrandTotalDetailsInterface;
-use Magento\Framework\Model\AbstractExtensibleModel;
+use Magento\Framework\Api\AbstractSimpleObject;
 
 /**
  * Grand Total Tax Details Model
  */
-class GrandTotalDetails extends AbstractExtensibleModel implements GrandTotalDetailsInterface
+class GrandTotalDetails extends AbstractSimpleObject implements GrandTotalDetailsInterface
 {
     /**#@+
      * Constants defined for keys of array, makes typos less likely
      */
-    const AMOUNT        = 'amount';
-    const RATES         = 'rates';
-    const GROUP_ID      = 'group_id';
+    const AMOUNT = 'amount';
+    const RATES = 'rates';
+    const GROUP_ID = 'group_id';
     /**#@-*/
 
     /**
@@ -27,7 +27,7 @@ class GrandTotalDetails extends AbstractExtensibleModel implements GrandTotalDet
      */
     public function getGroupId()
     {
-        return $this->getData(self::GROUP_ID);
+        return $this->_get(self::GROUP_ID);
     }
 
     /**
@@ -43,7 +43,7 @@ class GrandTotalDetails extends AbstractExtensibleModel implements GrandTotalDet
      */
     public function getAmount()
     {
-        return $this->getData(self::AMOUNT);
+        return $this->_get(self::AMOUNT);
     }
 
     /**
@@ -59,7 +59,7 @@ class GrandTotalDetails extends AbstractExtensibleModel implements GrandTotalDet
      */
     public function getRates()
     {
-        return $this->getData(self::RATES);
+        return $this->_get(self::RATES);
     }
 
     /**
@@ -69,26 +69,4 @@ class GrandTotalDetails extends AbstractExtensibleModel implements GrandTotalDet
     {
         return $this->setData(self::RATES, $rates);
     }
-
-    /**
-     * {@inheritdoc}
-     *
-     * @return \Magento\Tax\Api\Data\GrandTotalDetailsExtensionInterface|null
-     */
-    public function getExtensionAttributes()
-    {
-        return $this->_getExtensionAttributes();
-    }
-
-    /**
-     * {@inheritdoc}
-     *
-     * @param \Magento\Tax\Api\Data\GrandTotalDetailsExtensionInterface $extensionAttributes
-     * @return $this
-     */
-    public function setExtensionAttributes(
-        \Magento\Tax\Api\Data\GrandTotalDetailsExtensionInterface $extensionAttributes
-    ) {
-        return $this->_setExtensionAttributes($extensionAttributes);
-    }
 }
diff --git a/app/code/Magento/Tax/Model/Calculation/GrandTotalRates.php b/app/code/Magento/Tax/Model/Calculation/GrandTotalRates.php
index 4c23c6444d7236a25ebf661b9d5d75a53f0fa829..b7be0cc4a3d36ab0aa5ae35cd8286245064d62d8 100644
--- a/app/code/Magento/Tax/Model/Calculation/GrandTotalRates.php
+++ b/app/code/Magento/Tax/Model/Calculation/GrandTotalRates.php
@@ -7,12 +7,12 @@
 namespace Magento\Tax\Model\Calculation;
 
 use Magento\Tax\Api\Data\GrandTotalRatesInterface;
-use Magento\Framework\Model\AbstractExtensibleModel;
+use Magento\Framework\Api\AbstractSimpleObject;
 
 /**
  * Grand Total Tax Details Model
  */
-class GrandTotalRates extends AbstractExtensibleModel implements GrandTotalRatesInterface
+class GrandTotalRates extends AbstractSimpleObject implements GrandTotalRatesInterface
 {
     /**#@+
      * Constants defined for keys of array, makes typos less likely
@@ -26,7 +26,7 @@ class GrandTotalRates extends AbstractExtensibleModel implements GrandTotalRates
      */
     public function getTitle()
     {
-        return $this->getData(self::TITLE);
+        return $this->_get(self::TITLE);
     }
 
     /**
@@ -42,7 +42,7 @@ class GrandTotalRates extends AbstractExtensibleModel implements GrandTotalRates
      */
     public function getPercent()
     {
-        return $this->getData(self::PERCENT);
+        return $this->_get(self::PERCENT);
     }
 
     /**
@@ -52,26 +52,4 @@ class GrandTotalRates extends AbstractExtensibleModel implements GrandTotalRates
     {
         return $this->setData(self::PERCENT, $percent);
     }
-
-    /**
-     * {@inheritdoc}
-     *
-     * @return \Magento\Tax\Api\Data\GrandTotalRatesExtensionInterface|null
-     */
-    public function getExtensionAttributes()
-    {
-        return $this->_getExtensionAttributes();
-    }
-
-    /**
-     * {@inheritdoc}
-     *
-     * @param \Magento\Tax\Api\Data\GrandTotalRatesExtensionInterface $extensionAttributes
-     * @return $this
-     */
-    public function setExtensionAttributes(
-        \Magento\Tax\Api\Data\GrandTotalRatesExtensionInterface $extensionAttributes
-    ) {
-        return $this->_setExtensionAttributes($extensionAttributes);
-    }
 }
diff --git a/app/code/Magento/Tax/Model/Quote/GrandTotalDetails.php b/app/code/Magento/Tax/Model/Quote/GrandTotalDetailsPlugin.php
similarity index 87%
rename from app/code/Magento/Tax/Model/Quote/GrandTotalDetails.php
rename to app/code/Magento/Tax/Model/Quote/GrandTotalDetailsPlugin.php
index e20684a73b880754f7285dbe561485e298361d28..1de7b6d223d5648f009b1598917b54d46dc6643c 100644
--- a/app/code/Magento/Tax/Model/Quote/GrandTotalDetails.php
+++ b/app/code/Magento/Tax/Model/Quote/GrandTotalDetailsPlugin.php
@@ -6,8 +6,9 @@
 namespace Magento\Tax\Model\Quote;
 
 use Magento\Quote\Model\Cart\CartTotalRepository;
+use Magento\Quote\Api\Data\TotalsExtensionFactory;
 
-class GrandTotalDetails
+class GrandTotalDetailsPlugin
 {
     /**
      * @var \Magento\Tax\Api\Data\GrandTotalDetailsInterfaceFactory
@@ -20,7 +21,7 @@ class GrandTotalDetails
     protected $ratesFactory;
 
     /**
-     * @var \Magento\Framework\Api\ExtensionAttributesFactory
+     * @var TotalsExtensionFactory
      */
     protected $extensionFactory;
 
@@ -42,7 +43,7 @@ class GrandTotalDetails
     /**
      * @param \Magento\Tax\Api\Data\GrandTotalDetailsInterfaceFactory $detailsFactory
      * @param \Magento\Tax\Api\Data\GrandTotalRatesInterfaceFactory $ratesFactory
-     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
+     * @param TotalsExtensionFactory $extensionFactory
      * @param \Magento\Tax\Model\Config $taxConfig
      * @param \Magento\Quote\Model\Quote\Address\Total\Tax $taxTotal
      * @param \Magento\Quote\Model\QuoteRepository $quoteRepository
@@ -50,7 +51,7 @@ class GrandTotalDetails
     public function __construct(
         \Magento\Tax\Api\Data\GrandTotalDetailsInterfaceFactory $detailsFactory,
         \Magento\Tax\Api\Data\GrandTotalRatesInterfaceFactory $ratesFactory,
-        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
+        TotalsExtensionFactory $extensionFactory,
         \Magento\Tax\Model\Config $taxConfig,
         \Magento\Quote\Model\Quote\Address\Total\Tax $taxTotal,
         \Magento\Quote\Model\QuoteRepository $quoteRepository
@@ -81,7 +82,7 @@ class GrandTotalDetails
 
     /**
      * @param CartTotalRepository $subject
-     * @param callable $proceed
+     * @param \Closure $proceed
      * @param int $cartId
      * @return \Magento\Quote\Model\Cart\Totals
      * @throws \Magento\Framework\Exception\NoSuchEntityException
@@ -119,11 +120,13 @@ class GrandTotalDetails
             $finalData[] = $taxDetails;
             $detailsId++;
         }
-        $taxInfo = $this->extensionFactory->create('\\Magento\\Quote\\Model\\Cart\\Totals', []);
-        $taxInfo->setTaxGrandtotalDetails($finalData);
+        $attributes = $result->getExtensionAttributes();
+        if ($attributes === null) {
+            $attributes = $this->extensionFactory->create();
+        }
+        $attributes->setTaxGrandtotalDetails($finalData);
         /** @var $result \Magento\Quote\Model\Cart\Totals */
-        $result->setExtensionAttributes($taxInfo);
-        $result->setTaxAmount($taxes['value']);
+        $result->setExtensionAttributes($attributes);
         return $result;
     }
 }
diff --git a/app/code/Magento/Tax/Model/TaxConfigProvider.php b/app/code/Magento/Tax/Model/TaxConfigProvider.php
index 4f40850d8bfb1657011a84f9d135076b82b4f9a4..8ce354850537f39125869c4f4baf5b01161c19ee 100644
--- a/app/code/Magento/Tax/Model/TaxConfigProvider.php
+++ b/app/code/Magento/Tax/Model/TaxConfigProvider.php
@@ -43,6 +43,7 @@ class TaxConfigProvider implements ConfigProviderInterface
             'reviewTotalsDisplayMode' => $this->getReviewTotalsDisplayMode(),
             'includeTaxInGrandTotal' => $this->isTaxDisplayedInGrandTotal(),
             'isFullTaxSummaryDisplayed' => $this->isFullTaxSummaryDisplayed(),
+            'isZeroTaxDisplayed' => $this->taxConfig->displayCartZeroTax(),
         ];
     }
 
diff --git a/app/code/Magento/Tax/Test/Unit/Model/TaxConfigProviderTest.php b/app/code/Magento/Tax/Test/Unit/Model/TaxConfigProviderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..cad8010f39cf0056c67efb00f98d427cdbbc9d9a
--- /dev/null
+++ b/app/code/Magento/Tax/Test/Unit/Model/TaxConfigProviderTest.php
@@ -0,0 +1,197 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Tax\Test\Unit\Model;
+
+class TaxConfigProviderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $taxHelperMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $taxConfigMock;
+
+    /**
+     * @var \Magento\Tax\Model\TaxConfigProvider
+     */
+    protected $model;
+
+    protected function setUp()
+    {
+        $this->taxHelperMock = $this->getMock('Magento\Tax\Helper\Data', [], [], '', false);
+        $this->taxConfigMock = $this->getMock('Magento\Tax\Model\Config', [], [], '', false);
+
+        $this->model = new \Magento\Tax\Model\TaxConfigProvider($this->taxHelperMock, $this->taxConfigMock);
+    }
+
+    /**
+     * @dataProvider getConfigDataProvider
+     * @param array $expectedResult
+     * @param int $cartShippingBoth
+     * @param int $cartShippingExclTax
+     * @param int $cartBothPrices
+     * @param int $cartPriceExclTax
+     * @param int $cartSubTotalBoth
+     * @param int $cartSubTotalExclTax
+     */
+    public function testGetConfig(
+        $expectedResult,
+        $cartShippingBoth,
+        $cartShippingExclTax,
+        $cartBothPrices,
+        $cartPriceExclTax,
+        $cartSubTotalBoth,
+        $cartSubTotalExclTax
+    ) {
+        $this->taxConfigMock->expects($this->any())->method('displayCartShippingBoth')
+            ->will($this->returnValue($cartShippingBoth));
+        $this->taxConfigMock->expects($this->any())->method('displayCartShippingExclTax')
+            ->will($this->returnValue($cartShippingExclTax));
+
+        $this->taxHelperMock->expects($this->any())->method('displayCartBothPrices')
+            ->will($this->returnValue($cartBothPrices));
+        $this->taxHelperMock->expects($this->any())->method('displayCartPriceExclTax')
+            ->will($this->returnValue($cartPriceExclTax));
+
+        $this->taxConfigMock->expects($this->any())->method('displayCartSubtotalBoth')
+            ->will($this->returnValue($cartSubTotalBoth));
+        $this->taxConfigMock->expects($this->any())->method('displayCartSubtotalExclTax')
+            ->will($this->returnValue($cartSubTotalExclTax));
+
+        $this->taxHelperMock->expects(($this->any()))->method('displayShippingPriceExcludingTax')
+            ->will($this->returnValue(1));
+        $this->taxHelperMock->expects(($this->any()))->method('displayShippingBothPrices')
+            ->will($this->returnValue(1));
+        $this->taxHelperMock->expects(($this->any()))->method('displayFullSummary')
+            ->will($this->returnValue(1));
+        $this->taxConfigMock->expects(($this->any()))->method('displayCartTaxWithGrandTotal')
+            ->will($this->returnValue(1));
+        $this->taxConfigMock->expects(($this->any()))->method('displayCartZeroTax')
+            ->will($this->returnValue(1));
+        $this->assertEquals($expectedResult, $this->model->getConfig());
+    }
+
+    /**
+     * @return array
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function getConfigDataProvider()
+    {
+        return [
+            [
+                'expectedResult' => [
+                    'isDisplayShippingPriceExclTax' => 1,
+                    'isDisplayShippingBothPrices' => 1,
+                    'reviewShippingDisplayMode' => 'both',
+                    'reviewItemPriceDisplayMode' => 'both',
+                    'reviewTotalsDisplayMode' => 'both',
+                    'includeTaxInGrandTotal' => 1,
+                    'isFullTaxSummaryDisplayed' => 1,
+                    'isZeroTaxDisplayed' => 1
+                ],
+                'cartShippingBoth' => 1,
+                'cartShippingExclTax' => 1,
+                'cartBothPrices' => 1,
+                'cartPriceExclTax' => 1,
+                'cartSubTotalBoth' => 1,
+                'cartSubTotalExclTax' => 1
+            ],
+            [
+                'expectedResult' => [
+                    'isDisplayShippingPriceExclTax' => 1,
+                    'isDisplayShippingBothPrices' => 1,
+                    'reviewShippingDisplayMode' => 'excluding',
+                    'reviewItemPriceDisplayMode' => 'excluding',
+                    'reviewTotalsDisplayMode' => 'excluding',
+                    'includeTaxInGrandTotal' => 1,
+                    'isFullTaxSummaryDisplayed' => 1,
+                    'isZeroTaxDisplayed' => 1
+                ],
+                'cartShippingBoth' => 0,
+                'cartShippingExclTax' => 1,
+                'cartBothPrices' => 0,
+                'cartPriceExclTax' => 1,
+                'cartSubTotalBoth' => 0,
+                'cartSubTotalExclTax' => 1
+            ],
+            [
+                'expectedResult' => [
+                    'isDisplayShippingPriceExclTax' => 1,
+                    'isDisplayShippingBothPrices' => 1,
+                    'reviewShippingDisplayMode' => 'including',
+                    'reviewItemPriceDisplayMode' => 'including',
+                    'reviewTotalsDisplayMode' => 'including',
+                    'includeTaxInGrandTotal' => 1,
+                    'isFullTaxSummaryDisplayed' => 1,
+                    'isZeroTaxDisplayed' => 1
+                ],
+                'cartShippingBoth' => 0,
+                'cartShippingExclTax' => 0,
+                'cartBothPrices' => 0,
+                'cartPriceExclTax' => 0,
+                'cartSubTotalBoth' => 0,
+                'cartSubTotalExclTax' => 0
+            ],
+            [
+                'expectedResult' => [
+                    'isDisplayShippingPriceExclTax' => 1,
+                    'isDisplayShippingBothPrices' => 1,
+                    'reviewShippingDisplayMode' => 'including',
+                    'reviewItemPriceDisplayMode' => 'including',
+                    'reviewTotalsDisplayMode' => 'including',
+                    'includeTaxInGrandTotal' => 1,
+                    'isFullTaxSummaryDisplayed' => 1,
+                    'isZeroTaxDisplayed' => 1
+                ],
+                'cartShippingBoth' => 0,
+                'cartShippingExclTax' => 0,
+                'cartBothPrices' => 0,
+                'cartPriceExclTax' => 0,
+                'cartSubTotalBoth' => 0,
+                'cartSubTotalExclTax' => 0
+            ],
+            [
+                'expectedResult' => [
+                    'isDisplayShippingPriceExclTax' => 1,
+                    'isDisplayShippingBothPrices' => 1,
+                    'reviewShippingDisplayMode' => 'both',
+                    'reviewItemPriceDisplayMode' => 'both',
+                    'reviewTotalsDisplayMode' => 'both',
+                    'includeTaxInGrandTotal' => 1,
+                    'isFullTaxSummaryDisplayed' => 1,
+                    'isZeroTaxDisplayed' => 1
+                ],
+                'cartShippingBoth' => 1,
+                'cartShippingExclTax' => 0,
+                'cartBothPrices' => 1,
+                'cartPriceExclTax' => 0,
+                'cartSubTotalBoth' => 1,
+                'cartSubTotalExclTax' => 0
+            ],
+            [
+                'expectedResult' => [
+                    'isDisplayShippingPriceExclTax' => 1,
+                    'isDisplayShippingBothPrices' => 1,
+                    'reviewShippingDisplayMode' => 'excluding',
+                    'reviewItemPriceDisplayMode' => 'including',
+                    'reviewTotalsDisplayMode' => 'both',
+                    'includeTaxInGrandTotal' => 1,
+                    'isFullTaxSummaryDisplayed' => 1,
+                    'isZeroTaxDisplayed' => 1
+                ],
+                'cartShippingBoth' => 0,
+                'cartShippingExclTax' => 1,
+                'cartBothPrices' => 0,
+                'cartPriceExclTax' => 0,
+                'cartSubTotalBoth' => 1,
+                'cartSubTotalExclTax' => 0
+            ],
+        ];
+    }
+}
diff --git a/app/code/Magento/Tax/etc/di.xml b/app/code/Magento/Tax/etc/di.xml
index 48b3173d60f09e739305f3c68cf501be8315be96..12dd5b270fc3c2740cf0f272bcd38fdb812d9b0d 100644
--- a/app/code/Magento/Tax/etc/di.xml
+++ b/app/code/Magento/Tax/etc/di.xml
@@ -65,7 +65,7 @@
         <plugin name="add_tax_to_order" type="Magento\Tax\Model\Quote\ToOrderConverter"/>
     </type>
     <type name="Magento\Quote\Model\Cart\CartTotalRepository">
-        <plugin name="add_tax_details" type="Magento\Tax\Model\Quote\GrandTotalDetails"/>
+        <plugin name="add_tax_details" type="Magento\Tax\Model\Quote\GrandTotalDetailsPlugin"/>
     </type>
     <type name="Magento\Tax\Model\Resource\Report\Tax\Createdat">
         <arguments>
diff --git a/app/code/Magento/Tax/view/frontend/layout/checkout_onepage_index.xml b/app/code/Magento/Tax/view/frontend/layout/checkout_onepage_index.xml
index 85969a844c674559ccb839ed2d3d092807e691bf..db20c4572b1d90cde9ed306a8e68a06ae42a6ada 100644
--- a/app/code/Magento/Tax/view/frontend/layout/checkout_onepage_index.xml
+++ b/app/code/Magento/Tax/view/frontend/layout/checkout_onepage_index.xml
@@ -15,52 +15,71 @@
                             <item name="children" xsi:type="array">
                                 <item name="steps" xsi:type="array">
                                     <item name="children" xsi:type="array">
-                                        <item name="shipping" xsi:type="array">
+                                        <item name="shipping-step" xsi:type="array">
                                             <item name="children" xsi:type="array">
-                                                <item name="price" xsi:type="array">
-                                                    <item name="component" xsi:type="string">Magento_Tax/js/view/checkout/shipping_method/price</item>
-                                                    <item name="displayArea" xsi:type="string">price</item>
+                                                <item name="shippingAddress" xsi:type="array">
+                                                    <item name="children" xsi:type="array">
+                                                        <item name="price" xsi:type="array">
+                                                            <item name="component" xsi:type="string">Magento_Tax/js/view/checkout/shipping_method/price</item>
+                                                            <item name="displayArea" xsi:type="string">price</item>
+                                                        </item>
+                                                    </item>
                                                 </item>
                                             </item>
                                         </item>
-                                        <item name="review" xsi:type="array">
+                                    </item>
+                                </item>
+                                <item name="summary" xsi:type="array">
+                                    <item name="children" xsi:type="array">
+                                        <item name="totals" xsi:type="array">
                                             <item name="children" xsi:type="array">
-                                                <item name="columns" xsi:type="array">
-                                                    <item name="component" xsi:type="string">Magento_Checkout/js/view/columns</item>
+                                                <!-- sort order for this totals is configured on admin panel-->
+                                                <!-- Stores->Configuration->SALES->Sales->General->Checkout Totals Sort Order -->
+                                                <item name="subtotal" xsi:type="array">
+                                                    <item name="component"  xsi:type="string">Magento_Tax/js/view/checkout/summary/subtotal</item>
+                                                    <item name="config" xsi:type="array">
+                                                        <item name="excludingTaxMessage" xsi:type="string">Excl. Tax</item>
+                                                        <item name="includingTaxMessage" xsi:type="string">Incl. Tax</item>
+                                                    </item>
+                                                </item>
+                                                <item name="shipping" xsi:type="array">
+                                                    <item name="component"  xsi:type="string">Magento_Tax/js/view/checkout/summary/shipping</item>
+                                                    <item name="sortOrder" xsi:type="string">20</item>
+                                                    <item name="config" xsi:type="array">
+                                                        <item name="excludingTaxMessage" xsi:type="string">Excl. Tax</item>
+                                                        <item name="includingTaxMessage" xsi:type="string">Incl. Tax</item>
+                                                    </item>
+                                                </item>
+                                                <item name="before_grandtotal" xsi:type="array">
+                                                    <item name="component"  xsi:type="string">uiComponent</item>
+                                                    <item name="sortOrder" xsi:type="string">30</item>
                                                     <item name="children" xsi:type="array">
-                                                        <item name="price" xsi:type="array">
-                                                            <item name="component" xsi:type="string">Magento_Tax/js/view/checkout/review/item/columns/price</item>
-                                                        </item>
-                                                        <item name="subtotal" xsi:type="array">
-                                                            <item name="component" xsi:type="string">Magento_Tax/js/view/checkout/review/item/columns/subtotal</item>
-                                                        </item>
+                                                        <!-- merge your components here -->
+                                                    </item>
+                                                </item>
+                                                <item name="tax" xsi:type="array">
+                                                    <item name="component"  xsi:type="string">Magento_Tax/js/view/checkout/summary/tax</item>
+                                                    <item name="config" xsi:type="array">
+                                                        <item name="title" xsi:type="string">Tax</item>
+                                                    </item>
+                                                </item>
+                                                <item name="grand-total" xsi:type="array">
+                                                    <item name="component"  xsi:type="string">Magento_Tax/js/view/checkout/summary/grand-total</item>
+                                                    <item name="config" xsi:type="array">
+                                                        <item name="exclTaxLabel" xsi:type="string">Order Total Excl. Tax</item>
+                                                        <item name="inclTaxLabel" xsi:type="string">Order Total Incl. Tax</item>
+                                                        <item name="basicCurrencyMessage" xsi:type="string">Your credit card will be charged for</item>
+                                                        <item name="title" xsi:type="string">Order Total</item>
                                                     </item>
                                                 </item>
-                                                <item name="totals" xsi:type="array">
+                                            </item>
+                                        </item>
+                                        <item name="cart_items" xsi:type="array">
+                                            <item name="children" xsi:type="array">
+                                                <item name="details" xsi:type="array">
                                                     <item name="children" xsi:type="array">
                                                         <item name="subtotal" xsi:type="array">
-                                                            <item name="component"  xsi:type="string">Magento_Tax/js/view/checkout/review/subtotal</item>
-                                                            <item name="sortOrder" xsi:type="string">10</item>
-                                                        </item>
-                                                        <item name="shipping" xsi:type="array">
-                                                            <item name="component"  xsi:type="string">Magento_Tax/js/view/checkout/review/shipping</item>
-                                                            <item name="sortOrder" xsi:type="string">20</item>
-                                                        </item>
-                                                        <item name="before_grandtotal" xsi:type="array">
-                                                            <item name="component"  xsi:type="string">Magento_Tax/js/view/checkout/review/before_grandtotal</item>
-                                                            <item name="sortOrder" xsi:type="string">30</item>
-                                                            <item name="children" xsi:type="array">
-                                                                <!-- merge your components here -->
-                                                            </item>
-                                                        </item>
-                                                        <item name="grandtotal" xsi:type="array">
-                                                            <item name="component"  xsi:type="string">Magento_Tax/js/view/checkout/review/grandtotal</item>
-                                                            <item name="sortOrder" xsi:type="string">40</item>
-                                                            <item name="children" xsi:type="array">
-                                                                <item name="grandtotal_tax" xsi:type="array">
-                                                                    <item name="component"  xsi:type="string">Magento_Tax/js/view/checkout/review/tax_total</item>
-                                                                </item>
-                                                            </item>
+                                                            <item name="component" xsi:type="string">Magento_Tax/js/view/checkout/summary/item/details/subtotal</item>
                                                         </item>
                                                     </item>
                                                 </item>
diff --git a/app/code/Magento/Tax/view/frontend/layout/checkout_onepage_original.xml b/app/code/Magento/Tax/view/frontend/layout/checkout_onepage_original.xml
new file mode 100644
index 0000000000000000000000000000000000000000..012d3de66d1ddaf42f7320f1cb3c064b9f2c4486
--- /dev/null
+++ b/app/code/Magento/Tax/view/frontend/layout/checkout_onepage_original.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<!-- TODO remove this file as soon as enhanced checkout is implemented -->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+    <body>
+        <referenceBlock name="checkout.root">
+            <arguments>
+                <argument name="jsLayout" xsi:type="array">
+                    <item name="components" xsi:type="array">
+                        <item name="checkout" xsi:type="array">
+                            <item name="children" xsi:type="array">
+                                <item name="steps" xsi:type="array">
+                                    <item name="children" xsi:type="array">
+                                        <item name="shipping" xsi:type="array">
+                                            <item name="children" xsi:type="array">
+                                                <item name="price" xsi:type="array">
+                                                    <item name="component" xsi:type="string">Magento_Tax/js/view/checkout/shipping_method/price</item>
+                                                    <item name="displayArea" xsi:type="string">price</item>
+                                                </item>
+                                            </item>
+                                        </item>
+                                        <item name="review" xsi:type="array">
+                                            <item name="children" xsi:type="array">
+                                                <item name="columns" xsi:type="array">
+                                                    <item name="component" xsi:type="string">Magento_Checkout/js/view/columns</item>
+                                                    <item name="children" xsi:type="array">
+                                                        <item name="price" xsi:type="array">
+                                                            <item name="component" xsi:type="string">Magento_Tax/js/view/checkout/review/item/columns/price</item>
+                                                        </item>
+                                                        <item name="subtotal" xsi:type="array">
+                                                            <item name="component" xsi:type="string">Magento_Tax/js/view/checkout/review/item/columns/subtotal</item>
+                                                        </item>
+                                                    </item>
+                                                </item>
+                                                <item name="totals" xsi:type="array">
+                                                    <item name="children" xsi:type="array">
+                                                        <item name="subtotal" xsi:type="array">
+                                                            <item name="component"  xsi:type="string">Magento_Tax/js/view/checkout/review/subtotal</item>
+                                                            <item name="sortOrder" xsi:type="string">10</item>
+                                                        </item>
+                                                        <item name="shipping" xsi:type="array">
+                                                            <item name="component"  xsi:type="string">Magento_Tax/js/view/checkout/review/shipping</item>
+                                                            <item name="sortOrder" xsi:type="string">20</item>
+                                                        </item>
+                                                        <item name="before_grandtotal" xsi:type="array">
+                                                            <item name="component"  xsi:type="string">Magento_Tax/js/view/checkout/review/before_grandtotal</item>
+                                                            <item name="sortOrder" xsi:type="string">30</item>
+                                                            <item name="children" xsi:type="array">
+                                                                <!-- merge your components here -->
+                                                            </item>
+                                                        </item>
+                                                        <item name="grandtotal" xsi:type="array">
+                                                            <item name="component"  xsi:type="string">Magento_Tax/js/view/checkout/review/grandtotal</item>
+                                                            <item name="sortOrder" xsi:type="string">40</item>
+                                                            <item name="children" xsi:type="array">
+                                                                <item name="grandtotal_tax" xsi:type="array">
+                                                                    <item name="component"  xsi:type="string">Magento_Tax/js/view/checkout/review/tax_total</item>
+                                                                </item>
+                                                            </item>
+                                                        </item>
+                                                    </item>
+                                                </item>
+                                            </item>
+                                        </item>
+                                    </item>
+                                </item>
+                            </item>
+                        </item>
+                    </item>
+                </argument>
+            </arguments>
+        </referenceBlock>
+    </body>
+</page>
\ No newline at end of file
diff --git a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/before_grandtotal.js b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/before_grandtotal.js
deleted file mode 100644
index 72f01914f2df6bd4afd9e0478616f8c2a9474373..0000000000000000000000000000000000000000
--- a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/before_grandtotal.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*jshint browser:true jquery:true*/
-/*global alert*/
-define(
-    [
-        'uiComponent'
-    ],
-    function (Component) {
-        "use strict";
-        return Component.extend({
-            defaults: {
-                template: 'Magento_Tax/checkout/review/before_grandtotal'
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/item/columns/price.js b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/item/columns/price.js
deleted file mode 100644
index 839e4a1be856e3fcd8ea4ae7dafaa25ea6030066..0000000000000000000000000000000000000000
--- a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/item/columns/price.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*jshint browser:true jquery:true*/
-/*global alert*/
-define(
-    [
-        'Magento_Checkout/js/view/review/item/column'
-    ],
-    function (column) {
-        "use strict";
-        var displayPriceMode = window.checkoutConfig.reviewItemPriceDisplayMode || 'including';
-        return column.extend({
-            defaults: {
-                displayPriceMode: displayPriceMode,
-                ownClass: 'price',
-                columnTitle: 'Price',
-                template: 'Magento_Tax/checkout/review/item/columns/price'
-            },
-            isPriceInclTaxDisplayed: function() {
-                return 'both' == this.displayPriceMode || 'including' == this.displayPriceMode;
-            },
-            isPriceExclTaxDisplayed: function() {
-                return 'both' == this.displayPriceMode || 'excluding' == this.displayPriceMode;
-            },
-            isBothPricesDisplayed: function() {
-                return 'both' == this.displayPriceMode;
-            },
-            getPriceExclTax: function(quoteItem) {
-                return this.getFormattedPrice(quoteItem.price);
-            },
-            getPriceInclTax: function(quoteItem) {
-                return this.getFormattedPrice(quoteItem.price_incl_tax);
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/item/columns/subtotal.js b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/item/columns/subtotal.js
deleted file mode 100644
index 2d1bee80d8fb585c4bd0f7277cdec70cb24da129..0000000000000000000000000000000000000000
--- a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/item/columns/subtotal.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*jshint browser:true jquery:true*/
-/*global alert*/
-define(
-    [
-        'Magento_Tax/js/view/checkout/review/item/columns/price'
-    ],
-    function (Price) {
-        "use strict";
-        var displayPriceMode = window.checkoutConfig.reviewItemPriceDisplayMode || 'including';
-        return Price.extend({
-            defaults: {
-                displayPriceMode: displayPriceMode,
-                ownClass: 'subtotal',
-                columnTitle: 'Subtotal',
-                template: 'Magento_Tax/checkout/review/item/columns/subtotal'
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/shipping.js b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/shipping.js
deleted file mode 100644
index 1fc18683237bb750ea9ca55548be418378c1d5cb..0000000000000000000000000000000000000000
--- a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/shipping.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*jshint browser:true jquery:true*/
-/*global alert*/
-define(
-    [
-        'jquery',
-        'uiComponent',
-        'Magento_Checkout/js/model/quote',
-        'Magento_Catalog/js/price-utils',
-        'Magento_Checkout/js/model/shipping-service'
-    ],
-    function ($, Component, quote, priceUtils, shippingService) {
-        var displayMode = window.checkoutConfig.reviewShippingDisplayMode;
-        return Component.extend({
-            defaults: {
-                displayMode: displayMode,
-                template: 'Magento_Tax/checkout/review/shipping'
-            },
-            getColspan: 3,
-            style: "",
-            quoteIsVirtual: quote.isVirtual(),
-            selectedShippingMethod: quote.getShippingMethod(),
-            getTitle: function() {
-                return "Shipping & Handling" + "(" + shippingService.getTitleByCode(this.selectedShippingMethod()) + ")";
-            },
-            getExcludingLabel: function() {
-                return "Shipping Excl. Tax" + "(" + shippingService.getTitleByCode(this.selectedShippingMethod()) + ")";
-            },
-            getIncludingLabel: function() {
-                return "Shipping Incl. Tax" + "(" + shippingService.getTitleByCode(this.selectedShippingMethod()) + ")";
-            },
-            totals: quote.getTotals(),
-            isBothPricesDisplayed: function() {
-                return 'both' == this.displayMode
-            },
-            isIncludingDisplayed: function() {
-                return 'including' == this.displayMode;
-            },
-            isExcludingDisplayed: function() {
-                return 'excluding' == this.displayMode;
-            },
-            getValue: function() {
-                var price = 0;
-                if (this.totals()) {
-                    price =  this.totals().shipping_amount;
-                }
-                return priceUtils.formatPrice(price, quote.getPriceFormat());
-            },
-            getIncludingValue: function() {
-                var price = 0;
-                if (this.totals()) {
-                    price =  this.totals().shipping_incl_tax;
-                }
-                return priceUtils.formatPrice(price, quote.getPriceFormat());
-            },
-            getExcludingValue: function() {
-                var price = 0;
-                if (this.totals()) {
-                    price =  this.totals().shipping_amount;
-                }
-                return priceUtils.formatPrice(price, quote.getPriceFormat());
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/tax_total.js b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/tax_total.js
deleted file mode 100644
index 56f70a8993f977d833331dd7c3d76c44d61c37cc..0000000000000000000000000000000000000000
--- a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/tax_total.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*jshint browser:true jquery:true*/
-/*global alert*/
-define(
-    [
-        'ko',
-        'uiComponent',
-        'Magento_Checkout/js/model/quote',
-        'Magento_Catalog/js/price-utils'
-    ],
-    function (ko, Component, quote, priceUtils) {
-        "use strict";
-        var isTaxDisplayedInGrandTotal = window.checkoutConfig.includeTaxInGrandTotal;
-        var isFullTaxSummaryDisplayed = window.checkoutConfig.isFullTaxSummaryDisplayed;
-        return Component.extend({
-            defaults: {
-                isTaxDisplayedInGrandTotal: isTaxDisplayedInGrandTotal,
-                template: 'Magento_Tax/checkout/review/tax_total'
-            },
-            colspan: 3,
-            totals: quote.getTotals(),
-            style: "",
-            isFullTaxSummaryDisplayed: isFullTaxSummaryDisplayed,
-            lastTaxGroupId: null,
-            isDetailsVisible: ko.observable(),
-            getTitle: function() {
-                return "Tax";
-            },
-            getValue: function() {
-                var amount = 0;
-                if (this.totals()) {
-                    amount = this.totals().tax_amount;
-                }
-                return priceUtils.formatPrice(amount, quote.getPriceFormat());
-            },
-            formatPrice: function(amount) {
-                return priceUtils.formatPrice(amount, quote.getPriceFormat());
-            },
-            getDetails: function() {
-                var totals = this.totals();
-                if (totals.extension_attributes) {
-                    return totals.extension_attributes.tax_grandtotal_details;
-                }
-                return [];
-            },
-            toggleDetails: function() {
-                this.isDetailsVisible(!this.isDetailsVisible());
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/shipping_method/price.js b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/shipping_method/price.js
index bdb1256f25678a1a3ac005965ebc90ddc69682c4..018eb3b9d3ef7ea9206f43f5ac1efb2562c1779d 100644
--- a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/shipping_method/price.js
+++ b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/shipping_method/price.js
@@ -14,7 +14,7 @@ define(
         "use strict";
         return Component.extend({
             defaults: {
-                template: 'Magento_Tax/checkout/shipping_method/price',
+                template: 'Magento_Tax/checkout/shipping_method/price'
             },
 
             isDisplayShippingPriceExclTax: window.checkoutConfig.isDisplayShippingPriceExclTax,
diff --git a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/grandtotal.js b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/grand-total.js
similarity index 51%
rename from app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/grandtotal.js
rename to app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/grand-total.js
index 214e16f531e78aee0aec37621fbbd41ffc62f5e6..2ad991e704ed63d83dd1d3c91bd9e8a69dc63e7c 100644
--- a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/grandtotal.js
+++ b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/grand-total.js
@@ -6,34 +6,29 @@
 /*global alert*/
 define(
     [
-        'uiComponent',
+        'Magento_Checkout/js/view/summary/abstract-total',
         'Magento_Checkout/js/model/quote',
-        'Magento_Catalog/js/price-utils'
+        'Magento_Catalog/js/price-utils',
+        'Magento_Checkout/js/model/totals'
     ],
-    function (Component, quote, priceUtils) {
+    function (Component, quote, priceUtils, totals) {
         "use strict";
-        var isTaxDisplayedInGrandTotal = window.checkoutConfig.includeTaxInGrandTotal || false;
-        var isFullTaxSummaryDisplayed = window.checkoutConfig.isFullTaxSummaryDisplayed || false;
         return Component.extend({
             defaults: {
-                isFullTaxSummaryDisplayed: isFullTaxSummaryDisplayed,
-                template: 'Magento_Tax/checkout/review/grandtotal'
-            },
-            getColspan: 3,
-            style: "",
-            exclTaxLabel: 'Grand Total Excl. Tax',
-            inclTaxLabel: 'Grand Total Incl. Tax',
-            basicCurrencyMessage: 'Your credit card will be charged for',
-            getTitle: function() {
-                return "Grand Total";
+                isFullTaxSummaryDisplayed: window.checkoutConfig.isFullTaxSummaryDisplayed || false,
+                template: 'Magento_Tax/checkout/summary/grand-total'
             },
             totals: quote.getTotals(),
+            isTaxDisplayedInGrandTotal: window.checkoutConfig.includeTaxInGrandTotal || false,
+            isDisplayed: function() {
+                return this.isFullMode();
+            },
             getValue: function() {
                 var price = 0;
                 if (this.totals()) {
-                    price = this.totals().grand_total;
+                    price = totals.getSegment('grand_total').value;
                 }
-                return priceUtils.formatPrice(price, quote.getPriceFormat());
+                return this.getFormattedPrice(price);
             },
             getBaseValue: function() {
                 var price = 0;
@@ -42,17 +37,12 @@ define(
                 }
                 return priceUtils.formatPrice(price, quote.getBasePriceFormat());
             },
-            isTaxDisplayedInGrandTotal: isTaxDisplayedInGrandTotal,
             getGrandTotalExclTax: function() {
                 var totals = this.totals();
                 if (!totals) {
                     return 0;
                 }
-                var amount = totals.grand_total - totals.tax_amount;
-                if (amount < 0) {
-                    return 0;
-                }
-                return priceUtils.formatPrice(amount, quote.getPriceFormat());
+                return this.getFormattedPrice(totals.grand_total);
             },
             isBaseGrandTotalDisplayNeeded: function() {
                 var totals = this.totals();
diff --git a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/item/details/subtotal.js b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/item/details/subtotal.js
new file mode 100644
index 0000000000000000000000000000000000000000..f75c7733bab9a9aa72776d85af6dedf7d5442225
--- /dev/null
+++ b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/item/details/subtotal.js
@@ -0,0 +1,34 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(
+    [
+        'Magento_Checkout/js/view/summary/item/details/subtotal'
+    ],
+    function (subtotal) {
+        "use strict";
+        var displayPriceMode = window.checkoutConfig.reviewItemPriceDisplayMode || 'including';
+        return subtotal.extend({
+            defaults: {
+                displayPriceMode: displayPriceMode,
+                template: 'Magento_Tax/checkout/summary/item/details/subtotal'
+            },
+            isPriceInclTaxDisplayed: function() {
+                return 'both' == displayPriceMode || 'including' == displayPriceMode;
+            },
+            isPriceExclTaxDisplayed: function() {
+                return 'both' == displayPriceMode || 'excluding' == displayPriceMode;
+            },
+            getValueInclTax: function(quoteItem) {
+                return this.getFormattedPrice(quoteItem['row_total_incl_tax']);
+            },
+            getValueExclTax: function(quoteItem) {
+                return this.getFormattedPrice(quoteItem['row_total']);
+            }
+
+        });
+    }
+);
diff --git a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/shipping.js b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/shipping.js
new file mode 100644
index 0000000000000000000000000000000000000000..b6c3631c7869d1b912a046c8b3a097897a973eeb
--- /dev/null
+++ b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/shipping.js
@@ -0,0 +1,48 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(
+    [
+        'jquery',
+        'Magento_Checkout/js/view/summary/shipping',
+        'Magento_Checkout/js/model/quote'
+    ],
+    function ($, Component, quote) {
+        var displayMode = window.checkoutConfig.reviewShippingDisplayMode;
+        return Component.extend({
+            defaults: {
+                displayMode: displayMode,
+                template: 'Magento_Tax/checkout/summary/shipping'
+            },
+            isBothPricesDisplayed: function() {
+                return 'both' == this.displayMode
+            },
+            isIncludingDisplayed: function() {
+                return 'including' == this.displayMode;
+            },
+            isExcludingDisplayed: function() {
+                return 'excluding' == this.displayMode;
+            },
+            isCalculated: function() {
+                return this.totals() && this.isFullMode() && null != quote.shippingMethod();
+            },
+            getIncludingValue: function() {
+                if (!this.isCalculated()) {
+                    return this.notCalculatedMessage;
+                }
+                var price =  this.totals().shipping_incl_tax;
+                return this.getFormattedPrice(price);
+            },
+            getExcludingValue: function() {
+                if (!this.isCalculated()) {
+                    return this.notCalculatedMessage;
+                }
+                var price =  this.totals().shipping_amount;
+                return this.getFormattedPrice(price);
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/subtotal.js b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/subtotal.js
similarity index 63%
rename from app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/subtotal.js
rename to app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/subtotal.js
index 06a169784c3f625b7784a67dec4b79905c8d1bad..e9e86cd9fa03119f034eb91a70b48227ad169987 100644
--- a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/review/subtotal.js
+++ b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/subtotal.js
@@ -6,23 +6,15 @@
 /*global alert*/
 define(
     [
-        'uiComponent',
-        'Magento_Checkout/js/model/quote',
-        'Magento_Catalog/js/price-utils'
+        'Magento_Checkout/js/view/summary/abstract-total',
+        'Magento_Checkout/js/model/quote'
     ],
-    function (Component, quote, priceUtils) {
+    function (Component, quote) {
         var displaySubtotalMode = window.checkoutConfig.reviewTotalsDisplayMode;
         return Component.extend({
             defaults: {
                 displaySubtotalMode: displaySubtotalMode,
-                template: 'Magento_Tax/checkout/review/subtotal'
-            },
-            getColspan: 3,
-            style: "",
-            excludingTaxMessage: 'Subtotal (Excl. Tax)',
-            includingTaxMessage: 'Subtotal (Incl. Tax)',
-            getTitle: function() {
-                return "Subtotal"
+                template: 'Magento_Tax/checkout/summary/subtotal'
             },
             totals: quote.getTotals(),
             getValue: function () {
@@ -30,7 +22,7 @@ define(
                 if (this.totals()) {
                     price = this.totals().subtotal;
                 }
-                return priceUtils.formatPrice(price, quote.getPriceFormat());
+                return this.getFormattedPrice(price);
             },
             isBothPricesDisplayed: function() {
                 return 'both' == this.displaySubtotalMode;
@@ -43,7 +35,7 @@ define(
                 if (this.totals()) {
                     price = this.totals().subtotal_incl_tax;
                 }
-                return priceUtils.formatPrice(price, quote.getPriceFormat());
+                return this.getFormattedPrice(price);
             }
         });
     }
diff --git a/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/tax.js b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/tax.js
new file mode 100644
index 0000000000000000000000000000000000000000..019b0717c70afdebf57d04f73e75e6fdb6564956
--- /dev/null
+++ b/app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/tax.js
@@ -0,0 +1,77 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*jshint browser:true jquery:true*/
+/*global alert*/
+define(
+    [
+        'ko',
+        'Magento_Checkout/js/view/summary/abstract-total',
+        'Magento_Checkout/js/model/quote',
+        'Magento_Checkout/js/model/totals'
+    ],
+    function (ko, Component, quote, totals) {
+        "use strict";
+        var isTaxDisplayedInGrandTotal = window.checkoutConfig.includeTaxInGrandTotal;
+        var isFullTaxSummaryDisplayed = window.checkoutConfig.isFullTaxSummaryDisplayed;
+        var isZeroTaxDisplayed = window.checkoutConfig.isZeroTaxDisplayed;
+        return Component.extend({
+            defaults: {
+                isTaxDisplayedInGrandTotal: isTaxDisplayedInGrandTotal,
+                notCalculatedMessage: 'Not yet calculated',
+                template: 'Magento_Tax/checkout/summary/tax'
+            },
+            totals: quote.getTotals(),
+            isFullTaxSummaryDisplayed: isFullTaxSummaryDisplayed,
+            ifShowValue: function() {
+                if (!isTaxDisplayedInGrandTotal) {
+                    return false;
+                }
+                if (!this.totals() || null == totals.getSegment('tax')) {
+                    return true;
+                }
+                if (this.getPureValue() == 0) {
+                    return isZeroTaxDisplayed;
+                }
+                return true;
+            },
+            ifShowDetails: function() {
+                if (!this.isFullMode()) {
+                    return false;
+                }
+                return isTaxDisplayedInGrandTotal && this.getPureValue() > 0 && isFullTaxSummaryDisplayed;
+            },
+            getPureValue: function() {
+                var amount = 0;
+                if (this.totals()) {
+                    var taxTotal = totals.getSegment('tax');
+                    if (taxTotal) {
+                        amount = taxTotal.value;
+                    }
+                }
+                return amount;
+            },
+            isCalculated: function() {
+                return this.totals() && this.isFullMode() && null != totals.getSegment('tax');
+            },
+            getValue: function() {
+                if (!this.isCalculated()) {
+                    return this.notCalculatedMessage;
+                }
+                var amount = totals.getSegment('tax').value;
+                return this.getFormattedPrice(amount);
+            },
+            formatPrice: function(amount) {
+                return this.getFormattedPrice(amount);
+            },
+            getDetails: function() {
+                var totals = this.totals();
+                if (totals.extension_attributes) {
+                    return totals.extension_attributes.tax_grandtotal_details;
+                }
+                return [];
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/Tax/view/frontend/web/template/checkout/review/before_grandtotal.html b/app/code/Magento/Tax/view/frontend/web/template/checkout/review/before_grandtotal.html
deleted file mode 100644
index 237b692b59a6f20c62fab5b3c9c5ef157ffe37ab..0000000000000000000000000000000000000000
--- a/app/code/Magento/Tax/view/frontend/web/template/checkout/review/before_grandtotal.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-
-<!-- ko foreach: elems() -->
-<!-- ko template: getTemplate() --><!-- /ko -->
-<!-- /ko -->
diff --git a/app/code/Magento/Tax/view/frontend/web/template/checkout/review/grandtotal.html b/app/code/Magento/Tax/view/frontend/web/template/checkout/review/grandtotal.html
deleted file mode 100644
index 8c533bcae6fca5bb34f84282e33adcf595e4167d..0000000000000000000000000000000000000000
--- a/app/code/Magento/Tax/view/frontend/web/template/checkout/review/grandtotal.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<!-- ko if: isTaxDisplayedInGrandTotal -->
-<tr class="grand totals excl">
-    <th data-bind="attr: {'style':style, 'colspan': getColspan}" class="mark" scope="row">
-        <strong data-bind="text: exclTaxLabel"></strong>
-    </th>
-    <td data-bind="attr: {'style': style, 'data-th': exclTaxLabel }" class="amount">
-        <strong data-bind="text: getGrandTotalExclTax()"></strong>
-    </td>
-</tr>
-    <!-- ko foreach: elems() -->
-        <!-- ko template: getTemplate() --><!-- /ko -->
-    <!-- /ko -->
-<tr class="grand totals incl">
-    <th data-bind="attr: {'style':style, 'colspan': getColspan}" class="mark" scope="row">
-        <strong data-bind="text: $t(inclTaxLabel)"></strong>
-    </th>
-    <td data-bind="attr: {'style': style, 'data-th': $t(inclTaxLabel) }" class="amount">
-        <strong data-bind="text: getValue()"></strong>
-    </td>
-</tr>
-<!-- /ko -->
-<!-- ko if: !isTaxDisplayedInGrandTotal -->
-<tr class="grand totals">
-    <th data-bind="attr: {'style':style, 'colspan': getColspan }" class="mark" scope="row">
-        <strong data-bind="text: $t(getTitle())"></strong>
-    </th>
-    <td data-bind="attr: {'style':style, 'data-th': getTitle()}" class="amount">
-        <strong data-bind="text: getValue()"></strong>
-    </td>
-</tr>
-<!-- /ko -->
-<!-- ko if: isBaseGrandTotalDisplayNeeded() -->
-<tr class="totals charge">
-    <th class="mark" data-bind="text: $t(basicCurrencyMessage), attr: { 'colspan': getColspan }" scope="row"></th>
-    <td class="amount" data-bind="text: getBaseValue(), attr: {'data-th': $t(basicCurrencyMessage)}"></td>
-</tr>
-<!-- /ko -->
diff --git a/app/code/Magento/Tax/view/frontend/web/template/checkout/review/item/columns/price.html b/app/code/Magento/Tax/view/frontend/web/template/checkout/review/item/columns/price.html
deleted file mode 100644
index fc596c7d1ac5e35a6d6590ecf2231b0fc88b52e9..0000000000000000000000000000000000000000
--- a/app/code/Magento/Tax/view/frontend/web/template/checkout/review/item/columns/price.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<td data-bind="attr: { 'data-th': $t(getColName()), class: getClass() }">
-    <!-- ko if: isPriceInclTaxDisplayed() -->
-    <span class="price-including-tax" data-bind ="attr:{'data-label': $t('Incl. Tax')}">
-            <!-- ko foreach: getRegion('unit_incl_tax') -->
-                <!-- ko template: getTemplate() --><!-- /ko -->
-            <!-- /ko -->
-    </span>
-
-    <!-- /ko -->
-    <!-- ko if: isPriceExclTaxDisplayed() -->
-    <span class="price-excluding-tax" data-bind ="attr:{'data-label': $t('Excl. Tax')}">
-            <!-- ko foreach: getRegion('unit_excl_tax') -->
-                <!-- ko template: getTemplate() --><!-- /ko -->
-            <!-- /ko -->
-    </span>
-    <!-- /ko -->
-</td>
\ No newline at end of file
diff --git a/app/code/Magento/Tax/view/frontend/web/template/checkout/review/shipping.html b/app/code/Magento/Tax/view/frontend/web/template/checkout/review/shipping.html
deleted file mode 100644
index 6c7900d23315bdf25c4b3ad02a2382295cc1a90d..0000000000000000000000000000000000000000
--- a/app/code/Magento/Tax/view/frontend/web/template/checkout/review/shipping.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<!-- ko if: quoteIsVirtual == 0 -->
-    <!-- ko if: isBothPricesDisplayed() -->
-    <tr class="totals shipping excl">
-        <th data-bind="text: $t(getExcludingLabel()), attr: {'style':style, 'colspan': getColspan }" class="mark" scope="row"></th>
-        <td class="amount" data-bind="text: getExcludingValue(), attr: {'style':style, 'data-th': $t(getExcludingLabel())}"></td>
-    </tr>
-    <tr class="totals shipping incl">
-        <th data-bind="text: $t(getIncludingLabel()), attr: {'style':style, 'colspan': getColspan }" class="mark" scope="row"></th>
-        <td class="amount" data-bind="text: getIncludingValue(), attr: {'style':style, 'data-th': $t(getIncludingLabel())}"></td>
-    </tr>
-    <!-- /ko -->
-    <!-- ko if: isIncludingDisplayed() -->
-    <tr class="totals shipping incl">
-        <th data-bind="text: $t(getTitle()), attr: {'style':style, 'colspan': getColspan }" class="mark" scope="row"></th>
-        <td class="amount" data-bind="text: getIncludingValue(), attr: {'style':style, 'data-th': $t(getTitle())}"></td>
-    </tr>
-    <!-- /ko -->
-    <!-- ko if: isExcludingDisplayed() -->
-    <tr class="totals shipping excl">
-        <th data-bind="text: $t(getTitle()), attr: {'style':style, 'colspan': getColspan }" class="mark" scope="row"></th>
-        <td  data-bind="text: getValue(), attr: {'style':style, 'data-th': $t(getTitle())}" class="amount"></td>
-    </tr>
-    <!-- /ko -->
-<!-- /ko -->
-
diff --git a/app/code/Magento/Tax/view/frontend/web/template/checkout/review/subtotal.html b/app/code/Magento/Tax/view/frontend/web/template/checkout/review/subtotal.html
deleted file mode 100644
index 022131d8a0cc957a96ea074f4fe05c1292e4616d..0000000000000000000000000000000000000000
--- a/app/code/Magento/Tax/view/frontend/web/template/checkout/review/subtotal.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<!-- ko if: isBothPricesDisplayed() -->
-<tr class="totals sub excl">
-    <th data-bind="text: excludingTaxMessage, attr: {'style':style, 'colspan': getColspan}" class="mark" scope="row">
-    </th>
-    <td data-bind="text: getValue(), attr: {'style': style, 'data-th': $t(excludingTaxMessage) }" class="amount"></td>
-</tr>
-<tr class="totals sub incl">
-    <th data-bind="text: includingTaxMessage, attr: {'style':style, 'colspan': getColspan}" class="mark" scope="row">
-    </th>
-    <td data-bind="text: getValueInclTax(), attr: {'style': style, 'data-th': $t(includingTaxMessage) }" class="amount">
-    </td>
-</tr>
-<!-- /ko -->
-<!-- ko if: !isBothPricesDisplayed() && isIncludingTaxDisplayed() -->
-<tr class="totals sub">
-    <th data-bind="text: $t(getTitle()), attr: {'style':style, 'colspan': getColspan}" class="mark" scope="row"></th>
-    <td data-bind="text: getValueInclTax(), attr: {'style':style, 'data-th': $t(getTitle())}" class="amount"></td>
-</tr>
-<!-- /ko -->
-<!-- ko if: !isBothPricesDisplayed() && !isIncludingTaxDisplayed() -->
-<tr class="totals sub">
-    <th data-bind="text: $t(getTitle()), attr: {'style':style, 'colspan': getColspan}" class="mark" scope="row"></th>
-    <td data-bind="text: getValue(), attr: {'style':style, 'data-th': $t(getTitle())}" class="amount"></td>
-</tr>
-<!-- /ko -->
diff --git a/app/code/Magento/Tax/view/frontend/web/template/checkout/review/tax_total.html b/app/code/Magento/Tax/view/frontend/web/template/checkout/review/tax_total.html
deleted file mode 100644
index e22db68f36617b6c3ceb614fcf4fc1d250bf62ed..0000000000000000000000000000000000000000
--- a/app/code/Magento/Tax/view/frontend/web/template/checkout/review/tax_total.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<!-- ko ifnot: isFullTaxSummaryDisplayed -->
-<tr class="totals-tax">
-    <th data-bind="text: getTitle(), attr: {'style':style, 'colspan': colspan}" class="mark" scope="row">
-    </th>
-    <td data-bind="attr: {'style': style, 'data-th': $t(getTitle()) }" class="amount">
-        <span class="price" data-bind="text: getValue()"></span>
-    </td>
-</tr>
-<!-- /ko -->
-<!-- ko if: isFullTaxSummaryDisplayed -->
-    <tr class="totals-tax-summary" data-bind="click: toggleDetails()">
-        <th data-bind="text: getTitle(), attr: {'style':style, 'colspan': colspan}" class="mark" scope="row">
-        </th>
-        <td data-bind="attr: {'style': style, 'data-th': $t(getTitle()) }" class="amount">
-            <span class="price" data-bind="text: getValue()"></span>
-        </td>
-    </tr>
-    <!-- ko foreach: getDetails() -->
-        <!-- ko foreach: rates -->
-        <tr class="totals-tax-details" data-bind="visible: $parents[1].isDetailsVisible">
-            <!-- ko if: percent -->
-                <th class="mark" scope="row" data-bind="text: title + ' (' + percent + '%)', attr: {'style': $parents[1].style, 'colspan': $parents[1].colspan}">
-                </th>
-            <!-- /ko -->
-            <!-- ko if: !percent -->
-                <th class="mark" scope="row" data-bind="text: title, attr: {'style': $parents[1].style, 'colspan': $parents[1].colspan}">
-                </th>
-            <!-- /ko -->
-            <!-- ko if: $index() == 0 -->
-                <td class="amount" data-bind="text: $parents[1].formatPrice($parents[0].amount), attr: {'data-th': title, 'style': $parents[1].style, 'rowspan': $parents[0].rates.length }">
-                </td>
-            <!-- /ko -->
-        </tr>
-        <!-- /ko -->
-    <!-- /ko -->
-<!-- /ko -->
diff --git a/app/code/Magento/Tax/view/frontend/web/template/checkout/shipping_method/price.html b/app/code/Magento/Tax/view/frontend/web/template/checkout/shipping_method/price.html
index e854b9f1e0bc2e4a9a8f50c89ebc77e82f084fce..345b3eea5b0490a15af75cda91627f31bf06ffa6 100644
--- a/app/code/Magento/Tax/view/frontend/web/template/checkout/shipping_method/price.html
+++ b/app/code/Magento/Tax/view/frontend/web/template/checkout/shipping_method/price.html
@@ -5,22 +5,22 @@
  */
 -->
 <!-- ko if:  isDisplayShippingPriceExclTax -->
-<span class="price"><span class="price" data-bind="text: getFormattedPrice(item.price_excl_tax)"></span></span>
+<span class="price"><span class="price" data-bind="text: getFormattedPrice(method.price_excl_tax)"></span></span>
 <!-- /ko -->
 <!-- ko ifnot: isDisplayShippingPriceExclTax -->
-<!-- ko if:  (isDisplayShippingBothPrices && (item.price_excl_tax != item.price_incl_tax))-->
+<!-- ko if:  (isDisplayShippingBothPrices && (method.price_excl_tax != method.price_incl_tax))-->
 <span class="price-including-tax" data-bind = "attr: {'data-label': $t('Incl. Tax')}">
-    <span class="price"><span class="price" data-bind="text: getFormattedPrice(item.price_incl_tax)"></span></span>
+    <span class="price"><span class="price" data-bind="text: getFormattedPrice(method.price_incl_tax)"></span></span>
 </span>
 <!-- /ko -->
 
-<!-- ko ifnot:  (isDisplayShippingBothPrices && (item.price_excl_tax != item.price_incl_tax))-->
-    <span class="price"><span class="price" data-bind="text: getFormattedPrice(item.price_incl_tax)"></span></span>
+<!-- ko ifnot:  (isDisplayShippingBothPrices && (method.price_excl_tax != method.price_incl_tax))-->
+    <span class="price"><span class="price" data-bind="text: getFormattedPrice(method.price_incl_tax)"></span></span>
 <!-- /ko -->
 
 <!-- /ko -->
-<!-- ko if:  (isDisplayShippingBothPrices && (item.price_excl_tax != item.price_incl_tax))-->
+<!-- ko if:  (isDisplayShippingBothPrices && (method.price_excl_tax != method.price_incl_tax))-->
 <span class="price-excluding-tax" data-bind = "attr: {'data-label': $t('Excl. Tax')}">
-    <span class="price"><span class="price" data-bind="text: getFormattedPrice(item.price_excl_tax)"></span></span>
+    <span class="price"><span class="price" data-bind="text: getFormattedPrice(method.price_excl_tax)"></span></span>
 </span>
 <!-- /ko -->
diff --git a/app/code/Magento/Tax/view/frontend/web/template/checkout/summary/grand-total.html b/app/code/Magento/Tax/view/frontend/web/template/checkout/summary/grand-total.html
new file mode 100644
index 0000000000000000000000000000000000000000..d37e8816ae3e05c1cf806e520ac810e4d7a653b2
--- /dev/null
+++ b/app/code/Magento/Tax/view/frontend/web/template/checkout/summary/grand-total.html
@@ -0,0 +1,42 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<!-- ko if: isTaxDisplayedInGrandTotal && isDisplayed() -->
+<tr class="grand totals incl">
+    <th class="mark" scope="row">
+        <strong data-bind="text: $t(inclTaxLabel)"></strong>
+    </th>
+    <td data-bind="attr: {'data-th': $t(inclTaxLabel) }" class="amount">
+        <strong><span class="price" data-bind="text: getValue()"></span></strong>
+    </td>
+</tr>
+<tr class="grand totals excl">
+    <th class="mark" scope="row">
+        <strong data-bind="text: $t(exclTaxLabel)"></strong>
+    </th>
+    <td data-bind="attr: {'data-th': exclTaxLabel }" class="amount">
+        <strong><span class="price" data-bind="text: getGrandTotalExclTax()"></span></strong>
+    </td>
+</tr>
+<!-- /ko -->
+<!-- ko if: !isTaxDisplayedInGrandTotal && isDisplayed() -->
+<tr class="grand totals">
+    <th class="mark" scope="row">
+        <strong data-bind="text: $t(title)"></strong>
+    </th>
+    <td data-bind="attr: {'data-th': $t(title)}" class="amount">
+        <strong><span class="price" data-bind="text: getValue()"></span></strong>
+    </td>
+</tr>
+<!-- /ko -->
+<!-- ko if: isBaseGrandTotalDisplayNeeded() && isDisplayed() -->
+<tr class="totals charge">
+    <th class="mark" data-bind="text: $t(basicCurrencyMessage)" scope="row"></th>
+    <td class="amount">
+        <span class="price" data-bind="text: getBaseValue(), attr: {'data-th': $t(basicCurrencyMessage)}"></span>
+    </td>
+</tr>
+<!-- /ko -->
diff --git a/app/code/Magento/Tax/view/frontend/web/template/checkout/review/item/columns/subtotal.html b/app/code/Magento/Tax/view/frontend/web/template/checkout/summary/item/details/subtotal.html
similarity index 50%
rename from app/code/Magento/Tax/view/frontend/web/template/checkout/review/item/columns/subtotal.html
rename to app/code/Magento/Tax/view/frontend/web/template/checkout/summary/item/details/subtotal.html
index d489e741ba0474ea1af3e1ca0c72e24d8ac4de85..5d555b1b54f50c13ada9f31da8ffce63f85795a3 100644
--- a/app/code/Magento/Tax/view/frontend/web/template/checkout/review/item/columns/subtotal.html
+++ b/app/code/Magento/Tax/view/frontend/web/template/checkout/summary/item/details/subtotal.html
@@ -4,20 +4,29 @@
  * See COPYING.txt for license details.
  */
 -->
-<td data-bind="attr: { 'data-th': $t(getColName())}" class="col subtotal">
-    <!-- ko if: isPriceInclTaxDisplayed() -->
+<div class="subtotal">
+    <!-- ko if: isPriceInclTaxDisplayed() && !getRegion('row_incl_tax') -->
+    <span class="price-including-tax" data-bind ="text: getValueInclTax($parents[1]), attr:{'data-label': $t('Incl. Tax')}">
+    </span>
+    <!-- /ko -->
+
+    <!-- ko if: isPriceInclTaxDisplayed() && getRegion('row_incl_tax') -->
     <span class="price-including-tax" data-bind ="attr:{'data-label': $t('Incl. Tax')}">
             <!-- ko foreach: getRegion('row_incl_tax') -->
                 <!-- ko template: getTemplate() --><!-- /ko -->
             <!-- /ko -->
     </span>
+    <!-- /ko -->
 
+    <!-- ko if: isPriceExclTaxDisplayed() && !getRegion('row_excl_tax') -->
+    <span class="price-excluding-tax" data-bind ="text: getValueExclTax($parents[1]), attr:{'data-label': $t('Excl. Tax')}">
+    </span>
     <!-- /ko -->
-    <!-- ko if: isPriceExclTaxDisplayed() -->
+    <!-- ko if: isPriceExclTaxDisplayed() && getRegion('row_excl_tax') -->
     <span class="price-excluding-tax" data-bind ="attr:{'data-label': $t('Excl. Tax')}">
             <!-- ko foreach: getRegion('row_excl_tax') -->
                 <!-- ko template: getTemplate() --><!-- /ko -->
             <!-- /ko -->
     </span>
     <!-- /ko -->
-</td>
\ No newline at end of file
+</div>
\ No newline at end of file
diff --git a/app/code/Magento/Tax/view/frontend/web/template/checkout/summary/shipping.html b/app/code/Magento/Tax/view/frontend/web/template/checkout/summary/shipping.html
new file mode 100644
index 0000000000000000000000000000000000000000..8caba625561dfde89afdef0c04a97dbfb0de6c0e
--- /dev/null
+++ b/app/code/Magento/Tax/view/frontend/web/template/checkout/summary/shipping.html
@@ -0,0 +1,78 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<!-- ko if: quoteIsVirtual == 0 -->
+    <!-- ko if: isBothPricesDisplayed() -->
+    <tr class="totals shipping excl">
+        <th class="mark" scope="row">
+            <span class="label" data-bind="text: $t(title) + ' ' + $t(excludingTaxMessage)"></span>
+            <span class="value" data-bind="text: $t(getShippingMethodTitle())"></span>
+        </th>
+        <td class="amount">
+            <!-- ko if: isCalculated() -->
+            <span class="price"
+                  data-bind="text: $t(getExcludingValue()), attr: {'data-th': $t(excludingTaxMessage)}"></span>
+            <!-- /ko -->
+            <!-- ko ifnot: isCalculated() -->
+            <span class="not-calculated"
+                  data-bind="text: $t(getExcludingValue()), attr: {'data-th': $t(excludingTaxMessage)}"></span>
+            <!-- /ko -->
+        </td>
+    </tr>
+    <tr class="totals shipping incl">
+        <th class="mark" scope="row">
+            <span class="label" data-bind="text: $t(title) + ' ' + $t(includingTaxMessage)"></span>
+            <span class="value" data-bind="text: $t(getShippingMethodTitle())"></span>
+        </th>
+        <td class="amount">
+            <!-- ko if: isCalculated() -->
+            <span class="price"
+                  data-bind="text: $t(getIncludingValue()), attr: {'data-th': $t(title) + ' ' + $t(excludingTaxMessage)}"></span>
+            <!-- /ko -->
+            <!-- ko ifnot: isCalculated() -->
+            <span class="not-calculated"
+                  data-bind="text: $t(getIncludingValue()), attr: {'data-th': $t(title) + ' ' + $t(excludingTaxMessage)}"></span>
+            <!-- /ko -->
+        </td>
+    </tr>
+    <!-- /ko -->
+    <!-- ko if: isIncludingDisplayed() -->
+    <tr class="totals shipping incl">
+        <th class="mark" scope="row">
+            <span class="label" data-bind="text: $t(title)"></span>
+            <span class="value" data-bind="text: $t(getShippingMethodTitle())"></span>
+        </th>
+        <td class="amount">
+            <!-- ko if: isCalculated() -->
+            <span class="price"
+                  data-bind="text: $t(getIncludingValue()), attr: {'data-th': $t(title)}"></span>
+            <!-- /ko -->
+            <!-- ko ifnot: isCalculated() -->
+            <span class="not-calculated"
+                  data-bind="text: $t(getIncludingValue()), attr: {'data-th': $t(title)}"></span>
+            <!-- /ko -->
+        </td>
+    </tr>
+    <!-- /ko -->
+    <!-- ko if: isExcludingDisplayed() -->
+    <tr class="totals shipping excl">
+        <th class="mark" scope="row">
+            <span class="label" data-bind="text: $t(title)"></span>
+            <span class="value" data-bind="text: $t(getShippingMethodTitle())"></span>
+        </th>
+        <td class="amount">
+            <!-- ko if: isCalculated() -->
+            <span class="price"
+                  data-bind="text: $t(getValue()), attr: {'data-th': $t(title)}"></span>
+            <!-- /ko -->
+            <!-- ko ifnot: isCalculated() -->
+            <span class="not-calculated"
+                  data-bind="text: $t(getValue()), attr: {'data-th': $t(title)}"></span>
+            <!-- /ko -->
+        </td>
+    </tr>
+    <!-- /ko -->
+<!-- /ko -->
diff --git a/app/code/Magento/Tax/view/frontend/web/template/checkout/summary/subtotal.html b/app/code/Magento/Tax/view/frontend/web/template/checkout/summary/subtotal.html
new file mode 100644
index 0000000000000000000000000000000000000000..4652d47e5e35a6b7a868c795ac946999b43b6612
--- /dev/null
+++ b/app/code/Magento/Tax/view/frontend/web/template/checkout/summary/subtotal.html
@@ -0,0 +1,42 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<!-- ko if: isBothPricesDisplayed() -->
+<tr class="totals sub excl">
+    <th class="mark" scope="row">
+        <span data-bind="text: $t(title)"></span>
+        <span data-bind="text: $t(excludingTaxMessage)"></span>
+    </th>
+    <td class="amount">
+        <span class="price" data-bind="text: getValue(), attr: {'data-th': $t(excludingTaxMessage) }"></span>
+    </td>
+</tr>
+<tr class="totals sub incl">
+    <th class="mark" scope="row">
+        <span data-bind="text: $t(title)"></span>
+        <span data-bind="text: $t(includingTaxMessage)"></span>
+    </th>
+    <td class="amount">
+        <span class="price" data-bind="text: getValueInclTax(), attr: {'data-th': $t(includingTaxMessage) }"></span>
+    </td>
+</tr>
+<!-- /ko -->
+<!-- ko if: !isBothPricesDisplayed() && isIncludingTaxDisplayed() -->
+<tr class="totals sub">
+    <th data-bind="text: $t(title)" class="mark" scope="row"></th>
+    <td class="amount">
+        <span class="price" data-bind="text: getValueInclTax(), attr: {'data-th': $t(title)}"></span>
+    </td>
+</tr>
+<!-- /ko -->
+<!-- ko if: !isBothPricesDisplayed() && !isIncludingTaxDisplayed() -->
+<tr class="totals sub">
+    <th data-bind="text: $t(title)" class="mark" scope="row"></th>
+    <td class="amount">
+        <span class="price" data-bind="text: getValue(), attr: {'data-th': $t(title)}"></span>
+    </td>
+</tr>
+<!-- /ko -->
diff --git a/app/code/Magento/Tax/view/frontend/web/template/checkout/summary/tax.html b/app/code/Magento/Tax/view/frontend/web/template/checkout/summary/tax.html
new file mode 100644
index 0000000000000000000000000000000000000000..5b2b739402261b01f95e51d363961e015d840c1a
--- /dev/null
+++ b/app/code/Magento/Tax/view/frontend/web/template/checkout/summary/tax.html
@@ -0,0 +1,61 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<!-- ko if: ifShowValue() && !ifShowDetails() -->
+<tr class="totals-tax">
+    <th data-bind="text: $t(title)" class="mark" scope="row"></th>
+    <td data-bind="attr: {'data-th': $t(title) }" class="amount">
+        <!-- ko if: isCalculated() -->
+            <span class="price"
+                  data-bind="text: $t(getValue())"></span>
+        <!-- /ko -->
+        <!-- ko ifnot: isCalculated() -->
+            <span class="not-calculated"
+                  data-bind="text: $t(getValue())"></span>
+        <!-- /ko -->
+    </td>
+</tr>
+<!-- /ko -->
+<!-- ko if: ifShowValue() && ifShowDetails() -->
+    <tr class="totals-tax-summary"
+        data-bind="mageInit: {'toggleAdvanced':{'selectorsToggleClass': 'shown', 'baseToggleClass': 'expanded', 'toggleContainers': '.totals-tax-details'}}">
+        <th data-bind="text: $t(title)" class="mark" scope="row"></th>
+        <td data-bind="attr: {'data-th': $t(title) }" class="amount">
+            <!-- ko if: isCalculated() -->
+            <span class="price"
+                  data-bind="text: $t(getValue())"></span>
+            <!-- /ko -->
+            <!-- ko ifnot: isCalculated() -->
+            <span class="not-calculated"
+                  data-bind="text: $t(getValue())"></span>
+            <!-- /ko -->
+        </td>
+    </tr>
+    <!-- ko foreach: getDetails() -->
+        <!-- ko foreach: rates -->
+        <tr class="totals-tax-details">
+            <!-- ko if: percent -->
+                <th class="mark" scope="row" data-bind="text: title + ' (' + percent + '%)'"></th>
+            <!-- /ko -->
+            <!-- ko if: !percent -->
+                <th class="mark" scope="row" data-bind="text: title"></th>
+            <!-- /ko -->
+            <!-- ko if: $index() == 0 -->
+                <td class="amount">
+                    <!-- ko if: $parents[1].isCalculated() -->
+                    <span class="price"
+                          data-bind="text: $parents[1].formatPrice($parents[0].amount), attr: {'data-th': title, 'rowspan': $parents[0].rates.length }"></span>
+                    <!-- /ko -->
+                    <!-- ko ifnot: $parents[1].isCalculated() -->
+                    <span class="not-calculated"
+                          data-bind="text: $parents[1].formatPrice($parents[0].amount), attr: {'data-th': title, 'rowspan': $parents[0].rates.length }"></span>
+                    <!-- /ko -->
+                </td>
+            <!-- /ko -->
+        </tr>
+        <!-- /ko -->
+    <!-- /ko -->
+<!-- /ko -->
diff --git a/app/code/Magento/Ui/view/base/web/js/block-loader.js b/app/code/Magento/Ui/view/base/web/js/block-loader.js
new file mode 100644
index 0000000000000000000000000000000000000000..e3cb1b422bb31f070307e26f8f037cb3753f4e99
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/block-loader.js
@@ -0,0 +1,90 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'ko',
+    'jquery',
+    'Magento_Ui/js/lib/loader',
+    'mage/template'
+], function (ko, $, templateLoader, template) {
+    'use strict';
+
+    var blockLoaderTemplatePath = 'ui/block-loader',
+        blockContentLoadingClass = '_block-content-loading',
+        blockLoader,
+        blockLoaderClass,
+        loaderImageHref;
+
+    templateLoader.loadTemplate(blockLoaderTemplatePath).done(function (blockLoaderTemplate) {
+        blockLoader = template($.trim(blockLoaderTemplate), {
+            loaderImageHref: loaderImageHref
+        });
+        blockLoader = $(blockLoader);
+        blockLoaderClass = '.' + blockLoader.attr('class');
+    });
+
+    /**
+     * Helper function to check if blockContentLoading class should be applied.
+     * @param {Object} element
+     * @returns {Boolean}
+     */
+    function isLoadingClassRequired(element) {
+        var position = element.css('position');
+
+        if (position === 'absolute' || position === 'fixed') {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Add loader to block.
+     * @param {Object} element
+     */
+    function addBlockLoader(element) {
+        element.find(':focus').blur();
+        element.find('input:disabled, select:disabled').addClass('_disabled');
+        element.find('input, select').prop('disabled', true);
+
+        if (isLoadingClassRequired(element)) {
+            element.addClass(blockContentLoadingClass);
+        }
+        element.append(blockLoader.clone());
+    }
+
+    /**
+     * Remove loader from block.
+     * @param {Object} element
+     */
+    function removeBlockLoader(element) {
+        if (!element.has(blockLoaderClass).length) {
+            return;
+        }
+        element.find(blockLoaderClass).remove();
+        element.find('input:not("._disabled"), select:not("._disabled")').prop('disabled', false);
+        element.find('input:disabled, select:disabled').removeClass('_disabled');
+        element.removeClass(blockContentLoadingClass);
+    }
+
+    return function (loaderHref) {
+        loaderImageHref = loaderHref;
+        ko.bindingHandlers.blockLoader = {
+            /**
+             * Process loader for block
+             * @param {String} element
+             * @param {Boolean} displayBlockLoader
+             */
+            update: function (element, displayBlockLoader) {
+                element = $(element);
+
+                if (ko.unwrap(displayBlockLoader())) {
+                    addBlockLoader(element);
+                } else {
+                    removeBlockLoader(element);
+                }
+            }
+        };
+    };
+});
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 1b9c0c18860a88b2faccfa8490a5c243746ce6b5..aa415e7aeacebaf5d9ffed007bdc3cbe5a59e9fa 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
@@ -8,9 +8,10 @@ define([
     "mage/template",
     "text!ui/template/modal/modal-popup.html",
     "text!ui/template/modal/modal-slide.html",
+    "text!ui/template/modal/modal-custom.html",
     "jquery/ui",
     "mage/translate"
-], function($, _, template, popupTpl, slideTpl){
+], function($, _, template, popupTpl, slideTpl, customTpl){
     "use strict";
 
     /**
@@ -23,6 +24,7 @@ define([
             modalClass: '',
             popupTpl: popupTpl,
             slideTpl: slideTpl,
+            customTpl: customTpl,
             modalVisibleClass: '_show',
             parentModalClass: '_has-modal',
             innerScrollClass: '_inner-scroll',
@@ -36,6 +38,7 @@ define([
             wrapperClass: 'modals-wrapper',
             overlayClass: 'modals-overlay',
             responsiveClass: 'modal-slide',
+            trigger: '',
             modalLeftMargin: 45,
             closeText: $.mage.__('Close'),
             buttons: [{
@@ -56,6 +59,7 @@ define([
             this._createButtons();
 
             this.modal.find(this.options.modalCloseBtn).on('click',  _.bind(this.closeModal, this));
+            $(this.options.trigger).on('click', _.bind(this.toggleModal, this));
             this.element.on('openModal', _.bind(this.openModal, this));
             this.element.on('closeModal', _.bind(this.closeModal, this));
         },
@@ -82,6 +86,13 @@ define([
 
             return elems.filter('.'+this.options.modalVisibleClass).length;
         },
+        toggleModal: function() {
+            if (this.options.isOpen == true) {
+                this.closeModal();
+            } else {
+                this.openModal();
+            }
+        },
         openModal: function() {
             var that = this;
 
diff --git a/app/code/Magento/Ui/view/base/web/templates/block-loader.html b/app/code/Magento/Ui/view/base/web/templates/block-loader.html
new file mode 100644
index 0000000000000000000000000000000000000000..cc98e6a19688cfc7d3e92d4d7c0753075dcd901c
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/block-loader.html
@@ -0,0 +1,11 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<div data-role="loader" class="loading-mask" style="position: absolute;">
+    <div class="loader">
+        <img src="<%= loaderImageHref %>" alt="Loading..." style="position: absolute;">
+    </div>
+</div>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/base/web/templates/modal/modal-custom.html b/app/code/Magento/Ui/view/base/web/templates/modal/modal-custom.html
new file mode 100644
index 0000000000000000000000000000000000000000..990630aa02b9c1ee71088b56bd345ed33e4d3a6e
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/templates/modal/modal-custom.html
@@ -0,0 +1,38 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+
+<aside class="modal-<%= data.type %> <%= data.modalClass %>
+       <% if(data.responsive){ %><%= data.responsiveClass %><% } %>
+       <% if(data.innerScroll){ %><%= data.innerScrollClass %><% } %>"
+    data-role="modal"
+    data-type="<%= data.type %>">
+    <div class="modal-inner-wrap">
+        <header class="modal-header">
+            <% if(data.title){ %>
+            <h1 class="modal-title"
+                data-role="title"><%= data.title %></h1>
+            <% } %>
+            <button
+                class="action-close"
+                data-role="closeBtn"
+                type="button">
+                <span><%= data.closeText %></span>
+            </button>
+        </header>
+        <div class="modal-content" data-role="content"></div>
+        <% if(data.buttons.length > 0){ %>
+        <footer class="modal-footer">
+            <% _.each(data.buttons, function(button) { %>
+            <button
+                    class="<%= button.class %>"
+                    type="button"
+                    data-role="action"><span><%= button.text %></span></button>
+            <% }); %>
+        </footer>
+        <% } %>
+    </div>
+</aside>
diff --git a/app/code/Magento/Ui/view/base/web/templates/modal/modal-popup.html b/app/code/Magento/Ui/view/base/web/templates/modal/modal-popup.html
index 7c45aefbb35a66ab80274fa4891f31804b246f93..43ac20b2aeb1e26bce6330232755be77e5c4605c 100644
--- a/app/code/Magento/Ui/view/base/web/templates/modal/modal-popup.html
+++ b/app/code/Magento/Ui/view/base/web/templates/modal/modal-popup.html
@@ -13,8 +13,10 @@
     data-type="<%= data.type %>">
     <div class="modal-inner-wrap">
         <header class="modal-header">
+            <% if(data.title){ %>
             <h1 class="modal-title"
                 data-role="title"><%= data.title %></h1>
+            <% } %>
             <button
                 class="action-close"
                 data-role="closeBtn"
@@ -25,6 +27,7 @@
         <div
             class="modal-content"
             data-role="content"></div>
+        <% if(data.buttons.length > 0){ %>
         <footer class="modal-footer">
             <% _.each(data.buttons, function(button) { %>
             <button
@@ -33,5 +36,6 @@
                 data-role="action"><span><%= button.text %></span></button>
             <% }); %>
         </footer>
+        <% } %>
     </div>
 </aside>
diff --git a/app/code/Magento/Ui/view/base/web/templates/modal/modal-slide.html b/app/code/Magento/Ui/view/base/web/templates/modal/modal-slide.html
index dbe99544b3e076a5d5fb670caad2ecdd77671437..abffa4573962a7acc129a0f3f0a96c2765240731 100644
--- a/app/code/Magento/Ui/view/base/web/templates/modal/modal-slide.html
+++ b/app/code/Magento/Ui/view/base/web/templates/modal/modal-slide.html
@@ -12,14 +12,17 @@
     data-type="<%= data.type %>">
     <div class="modal-inner-wrap">
         <header class="modal-header">
+            <% if(data.title){ %>
             <h1 class="modal-title"
                 data-role="title"><%= data.title %></h1>
+            <% } %>
             <button
                 class="action-close"
                 data-role="closeBtn"
                 type="button">
                 <span><%= data.closeText %></span>
             </button>
+            <% if(data.buttons.length > 0){ %>
             <div class="page-main-actions">
                 <div class="page-actions">
                     <div class="page-actions-buttons">
@@ -33,6 +36,7 @@
                     </div>
                 </div>
             </div>
+            <% } %>
         </header>
         <div class="modal-content" data-role="content"></div>
     </div>
diff --git a/app/code/Magento/Ui/view/frontend/web/js/model/errorlist.js b/app/code/Magento/Ui/view/frontend/web/js/model/errorlist.js
deleted file mode 100644
index 4eca983e1f4334cc21901eec3b3a95245956c7d9..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/frontend/web/js/model/errorlist.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*global define*/
-define(['ko'], function(ko) {
-    "use strict";
-    var errors = ko.observableArray([]);
-    return {
-        add: function (error) {
-            var expr = /([%])\w+/g,
-                errorMessage;
-            if (!error.hasOwnProperty('parameters')) {
-                this.clear();
-                errors.push(error.message);
-                return true;
-            }
-            errorMessage = error.message.replace(expr, function(varName) {
-                varName = varName.substr(1);
-                if (error.parameters.hasOwnProperty(varName)) {
-                    return error.parameters[varName];
-                }
-                return error.parameters.shift();
-            });
-            this.clear();
-            errors.push(errorMessage);
-            return true;
-        },
-        remove: function() {
-            errors.shift();
-        },
-        getAll: function () {
-            return errors;
-        },
-        clear: function() {
-            errors.removeAll();
-        }
-    };
-});
diff --git a/app/code/Magento/Ui/view/frontend/web/js/model/messageList.js b/app/code/Magento/Ui/view/frontend/web/js/model/messageList.js
new file mode 100644
index 0000000000000000000000000000000000000000..15da0c25dc7922e8d69a51b5647597c2540c9db0
--- /dev/null
+++ b/app/code/Magento/Ui/view/frontend/web/js/model/messageList.js
@@ -0,0 +1,78 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define(['ko'], function (ko) {
+    'use strict';
+
+    var errors = ko.observableArray([]);
+    var success =  ko.observableArray([]);
+
+    return {
+        errors: errors,
+        success: success,
+        /**
+         * Add  message to list.
+         * @param {Object} messageObj
+         * @param {Object} type
+         * @returns {Boolean}
+         */
+        add: function (messageObj, type) {
+            var expr = /([%])\w+/g,
+                message;
+
+            if (!messageObj.hasOwnProperty('parameters')) {
+                this.clear();
+                type.push(messageObj.message);
+
+                return true;
+            }
+            message = messageObj.message.replace(expr, function (varName) {
+                varName = varName.substr(1);
+
+                if (messageObj.parameters.hasOwnProperty(varName)) {
+                    return messageObj.parameters[varName];
+                }
+
+                return messageObj.parameters.shift();
+            });
+            this.clear();
+            errors.push(message);
+
+            return true;
+        },
+        addSuccessMessage: function (message) {
+            return this.add(message, this.success)
+
+        },
+        addErrorMessage: function (message) {
+            return this.add(message, this.errors)
+        },
+        /**
+         * Remove first error message in list
+         */
+        remove: function (type) {
+            type.shift();
+        },
+        /**
+         * Get all error messages
+         * @returns {Object}
+         */
+        getAll: function () {
+            return errors;
+        },
+        /**
+         * Clear error list
+         */
+        clear: function () {
+            errors.removeAll();
+            success.removeAll();
+        },
+        getAllErrors: function () {
+            return errors;
+        },
+        getAllSuccess: function () {
+            return success;
+        }
+    };
+});
diff --git a/app/code/Magento/Ui/view/frontend/web/js/view/errors.js b/app/code/Magento/Ui/view/frontend/web/js/view/errors.js
deleted file mode 100644
index 192a218bb4845cfccbef5d13a1664806bae574c7..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/frontend/web/js/view/errors.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*global define*/
-define(['uiComponent', '../model/errorlist'], function (Component, errors) {
-    "use strict";
-    return Component.extend({
-        errorList: errors.getAll(),
-        defaults: {
-            template: 'Magento_Ui/errors'
-        }
-    });
-});
diff --git a/app/code/Magento/Ui/view/frontend/web/js/view/messages.js b/app/code/Magento/Ui/view/frontend/web/js/view/messages.js
new file mode 100644
index 0000000000000000000000000000000000000000..02a5a2e6beb0ec893fd22b10c0a360d0984fa2d8
--- /dev/null
+++ b/app/code/Magento/Ui/view/frontend/web/js/view/messages.js
@@ -0,0 +1,31 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define(['uiComponent', '../model/messageList'], function (Component, messages) {
+    'use strict';
+
+    return Component.extend({
+        errorList: messages.getAllErrors(),
+        successList: messages.getAllSuccess(),
+
+        defaults: {
+            template: 'Magento_Ui/messages'
+        },
+
+        /**
+         *
+         * @returns {*}
+         */
+        isVisible: function () {
+            return this.errorList().length || this.successList().length;
+        },
+        /**
+         * Remove all errors
+         */
+        removeAll: function () {
+            this.errorList.removeAll();
+            this.successList.removeAll();
+        }
+    });
+});
diff --git a/app/code/Magento/Ui/view/frontend/web/template/errors.html b/app/code/Magento/Ui/view/frontend/web/template/errors.html
deleted file mode 100644
index 15d1bf5d80d2215869aa676d5acd7950a9c9c591..0000000000000000000000000000000000000000
--- a/app/code/Magento/Ui/view/frontend/web/template/errors.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<div class="messages" data-bind="visible: errorList().length">
-    <div class="message message-error error" data-bind="foreach: errorList">
-        <div data-ui-id="checkout-cart-validationmessages-message-error" data-bind="text: $data"></div>
-    </div>
-</div>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/frontend/web/template/messages.html b/app/code/Magento/Ui/view/frontend/web/template/messages.html
new file mode 100644
index 0000000000000000000000000000000000000000..d842c4b10ff29428a4427ad00f89a7529ece12ae
--- /dev/null
+++ b/app/code/Magento/Ui/view/frontend/web/template/messages.html
@@ -0,0 +1,18 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<div class="messages" data-bind="visible: isVisible(), click: removeAll">
+    <!-- ko foreach: errorList -->
+    <div class="message message-error error">
+        <div data-ui-id="checkout-cart-validationmessages-message-error" data-bind="text: $data"></div>
+    </div>
+    <!--/ko-->
+    <!-- ko foreach: successList -->
+    <div class="message message-success success">
+        <div data-ui-id="checkout-cart-validationmessages-message-success" data-bind="text: $data"></div>
+    </div>
+    <!--/ko-->
+</div>
\ No newline at end of file
diff --git a/app/code/Magento/Ui/view/frontend/web/templates/form/element/helper/tooltip.html b/app/code/Magento/Ui/view/frontend/web/templates/form/element/helper/tooltip.html
new file mode 100644
index 0000000000000000000000000000000000000000..b2ef214e944a5e63c14f8b00f6d4297280baa284
--- /dev/null
+++ b/app/code/Magento/Ui/view/frontend/web/templates/form/element/helper/tooltip.html
@@ -0,0 +1,13 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+ <div class="field-tooltip toggle">
+    <a class="field-tooltip-action action-help" target="_blank" data-bind="attr: {href: tooltip.link}">
+    </a>
+    <div class="field-tooltip-content">
+        <!-- ko text: tooltip.description --><!-- /ko -->
+    </div>
+</div>
diff --git a/app/code/Magento/Ui/view/frontend/web/templates/form/element/input.html b/app/code/Magento/Ui/view/frontend/web/templates/form/element/input.html
index 75e6ff74dbe80b383441e20d4eea3dd2014d3743..e35184926cadcfd10f8a83883858be2d6e532761 100644
--- a/app/code/Magento/Ui/view/frontend/web/templates/form/element/input.html
+++ b/app/code/Magento/Ui/view/frontend/web/templates/form/element/input.html
@@ -6,6 +6,7 @@
 -->
 <input class="input-text" type="text" data-bind="
     value: value,
+    valueUpdate: 'keyup',
     hasFocus: focused,
     attr: {
         name: inputName,
diff --git a/app/code/Magento/Ui/view/frontend/web/templates/form/field.html b/app/code/Magento/Ui/view/frontend/web/templates/form/field.html
index fef8f712455113ecf7aca9f717e58192e7e0b58f..9f746c7e4542408b4e75475866a8d95676308a15 100644
--- a/app/code/Magento/Ui/view/frontend/web/templates/form/field.html
+++ b/app/code/Magento/Ui/view/frontend/web/templates/form/field.html
@@ -12,7 +12,7 @@
         <!-- /ko -->
     </label>
 
-    <div class="control">
+    <div class="control" data-bind="css: {'_with-tooltip': element.tooltip}">
         <!-- ko ifnot: element.hasAddons() -->
             <!-- ko template: element.elementTmpl --><!-- /ko -->
         <!-- /ko -->
diff --git a/app/code/Magento/Ups/view/frontend/layout/checkout_onepage_index.xml b/app/code/Magento/Ups/view/frontend/layout/checkout_onepage_index.xml
new file mode 100644
index 0000000000000000000000000000000000000000..50df5c58c00ce7af4c6dc661ad541bcdcad91ad4
--- /dev/null
+++ b/app/code/Magento/Ups/view/frontend/layout/checkout_onepage_index.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+    <body>
+        <referenceBlock name="checkout.root">
+            <arguments>
+                <argument name="jsLayout" xsi:type="array">
+                    <item name="components" xsi:type="array">
+                        <item name="checkout" xsi:type="array">
+                            <item name="children" xsi:type="array">
+                                <item name="steps" xsi:type="array">
+                                    <item name="children" xsi:type="array">
+                                        <item name="shipping-step" xsi:type="array">
+                                            <item name="children" xsi:type="array">
+                                                <item name="step-config" xsi:type="array">
+                                                    <item name="children" xsi:type="array">
+                                                        <item name="shipping-rates-validation" xsi:type="array">
+                                                            <item name="children" xsi:type="array">
+                                                                <item name="ups-rates-validation" xsi:type="array">
+                                                                    <item name="component" xsi:type="string">Magento_Ups/js/view/shipping-rates-validation</item>
+                                                                </item>
+                                                            </item>
+                                                        </item>
+                                                    </item>
+                                                </item>
+                                            </item>
+                                        </item>
+                                    </item>
+                                </item>
+                            </item>
+                        </item>
+                    </item>
+                </argument>
+            </arguments>
+        </referenceBlock>
+    </body>
+</page>
diff --git a/app/code/Magento/Ups/view/frontend/web/js/model/shipping-rates-validation-rules.js b/app/code/Magento/Ups/view/frontend/web/js/model/shipping-rates-validation-rules.js
new file mode 100644
index 0000000000000000000000000000000000000000..9f22914a8d29b73f75c2dfc51dfc776ed284e557
--- /dev/null
+++ b/app/code/Magento/Ups/view/frontend/web/js/model/shipping-rates-validation-rules.js
@@ -0,0 +1,23 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [],
+    function () {
+        "use strict";
+        return {
+            getRules: function() {
+                return {
+                    'postcode': {
+                        'required': true
+                    },
+                    'country_id': {
+                        'required': true
+                    }
+                };
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/Ups/view/frontend/web/js/model/shipping-rates-validator.js b/app/code/Magento/Ups/view/frontend/web/js/model/shipping-rates-validator.js
new file mode 100644
index 0000000000000000000000000000000000000000..71dac1b92c10ff0cab212709c93478227c2262c1
--- /dev/null
+++ b/app/code/Magento/Ups/view/frontend/web/js/model/shipping-rates-validator.js
@@ -0,0 +1,30 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [
+        'jquery',
+        'mageUtils',
+        './shipping-rates-validation-rules',
+        'mage/translate'
+    ],
+    function ($, utils, validationRules, $t) {
+        "use strict";
+        return {
+            validationErrors: [],
+            validate: function(address) {
+                var self = this;
+                this.validationErrors = [];
+                $.each(validationRules.getRules(), function(field, rule) {
+                    if (rule.required && utils.isEmpty(address[field])) {
+                        var message = $t('Field ') + field + $t(' is required.');
+                        self.validationErrors.push(message);
+                    }
+                });
+                return !Boolean(this.validationErrors.length);
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/Ups/view/frontend/web/js/view/shipping-rates-validation.js b/app/code/Magento/Ups/view/frontend/web/js/view/shipping-rates-validation.js
new file mode 100644
index 0000000000000000000000000000000000000000..42d6e855218d13fa54bad60bd238a4469bb1a565
--- /dev/null
+++ b/app/code/Magento/Ups/view/frontend/web/js/view/shipping-rates-validation.js
@@ -0,0 +1,27 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*browser:true*/
+/*global define*/
+define(
+    [
+        'uiComponent',
+        'Magento_Checkout/js/model/shipping-rates-validator',
+        'Magento_Checkout/js/model/shipping-rates-validation-rules',
+        '../model/shipping-rates-validator',
+        '../model/shipping-rates-validation-rules'
+    ],
+    function (
+        Component,
+        defaultShippingRatesValidator,
+        defaultShippingRatesValidationRules,
+        upsShippingRatesValidator,
+        upsShippingRatesValidationRules
+    ) {
+        "use strict";
+        defaultShippingRatesValidator.registerValidator('ups', upsShippingRatesValidator);
+        defaultShippingRatesValidationRules.registerRules('ups', upsShippingRatesValidationRules);
+        return Component;
+    }
+);
diff --git a/app/code/Magento/Usps/view/frontend/layout/checkout_onepage_index.xml b/app/code/Magento/Usps/view/frontend/layout/checkout_onepage_index.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ed6d123a6e4dfc7c7f443a2339a0f5cbfbac3d2f
--- /dev/null
+++ b/app/code/Magento/Usps/view/frontend/layout/checkout_onepage_index.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+    <body>
+        <referenceBlock name="checkout.root">
+            <arguments>
+                <argument name="jsLayout" xsi:type="array">
+                    <item name="components" xsi:type="array">
+                        <item name="checkout" xsi:type="array">
+                            <item name="children" xsi:type="array">
+                                <item name="steps" xsi:type="array">
+                                    <item name="children" xsi:type="array">
+                                        <item name="shipping-step" xsi:type="array">
+                                            <item name="children" xsi:type="array">
+                                                <item name="step-config" xsi:type="array">
+                                                    <item name="children" xsi:type="array">
+                                                        <item name="shipping-rates-validation" xsi:type="array">
+                                                            <item name="children" xsi:type="array">
+                                                                <item name="usps-rates-validation" xsi:type="array">
+                                                                    <item name="component" xsi:type="string">Magento_Usps/js/view/shipping-rates-validation</item>
+                                                                </item>
+                                                            </item>
+                                                        </item>
+                                                    </item>
+                                                </item>
+                                            </item>
+                                        </item>
+                                    </item>
+                                </item>
+                            </item>
+                        </item>
+                    </item>
+                </argument>
+            </arguments>
+        </referenceBlock>
+    </body>
+</page>
diff --git a/app/code/Magento/Usps/view/frontend/web/js/model/shipping-rates-validation-rules.js b/app/code/Magento/Usps/view/frontend/web/js/model/shipping-rates-validation-rules.js
new file mode 100644
index 0000000000000000000000000000000000000000..85ec105f7e4b3ab6886fa28534b0530b44e1a61c
--- /dev/null
+++ b/app/code/Magento/Usps/view/frontend/web/js/model/shipping-rates-validation-rules.js
@@ -0,0 +1,23 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [],
+    function () {
+        "use strict";
+        return {
+            getRules: function() {
+                return {
+                    'country_id': {
+                        'required': true
+                    },
+                    'postcode': {
+                        'required': false
+                    }
+                };
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/Usps/view/frontend/web/js/model/shipping-rates-validator.js b/app/code/Magento/Usps/view/frontend/web/js/model/shipping-rates-validator.js
new file mode 100644
index 0000000000000000000000000000000000000000..b897eb4e83ccde4647aca4f656c4bbc67b261512
--- /dev/null
+++ b/app/code/Magento/Usps/view/frontend/web/js/model/shipping-rates-validator.js
@@ -0,0 +1,40 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*global define*/
+define(
+    [
+        'jquery',
+        'mageUtils',
+        './shipping-rates-validation-rules',
+        'mage/translate'
+    ],
+    function ($, utils, validationRules, $t) {
+        "use strict";
+        var checkoutConfig = window.checkoutConfig;
+
+        return {
+            validationErrors: [],
+            validate: function(address) {
+                var rules = validationRules.getRules(),
+                    self = this;
+
+                $.each(rules, function(field, rule) {
+                    if (rule.required && utils.isEmpty(address[field])) {
+                        var message = $t('Field ') + field + $t(' is required.');
+                        self.validationErrors.push(message);
+                    }
+                });
+
+                if (!Boolean(this.validationErrors.length)) {
+                    if (address.country_id == checkoutConfig.originCountryCode) {
+                        return !utils.isEmpty(address.postcode);
+                    }
+                    return true;
+                }
+                return false;
+            }
+        };
+    }
+);
diff --git a/app/code/Magento/Usps/view/frontend/web/js/view/shipping-rates-validation.js b/app/code/Magento/Usps/view/frontend/web/js/view/shipping-rates-validation.js
new file mode 100644
index 0000000000000000000000000000000000000000..c47818efc2ede4a7aef4c48fcf7a4d58c5c712c9
--- /dev/null
+++ b/app/code/Magento/Usps/view/frontend/web/js/view/shipping-rates-validation.js
@@ -0,0 +1,27 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*browser:true*/
+/*global define*/
+define(
+    [
+        'uiComponent',
+        'Magento_Checkout/js/model/shipping-rates-validator',
+        'Magento_Checkout/js/model/shipping-rates-validation-rules',
+        '../model/shipping-rates-validator',
+        '../model/shipping-rates-validation-rules'
+    ],
+    function (
+        Component,
+        defaultShippingRatesValidator,
+        defaultShippingRatesValidationRules,
+        uspsShippingRatesValidator,
+        uspsShippingRatesValidationRules
+    ) {
+        "use strict";
+        defaultShippingRatesValidator.registerValidator('usps', uspsShippingRatesValidator);
+        defaultShippingRatesValidationRules.registerRules('usps', uspsShippingRatesValidationRules);
+        return Component;
+    }
+);
diff --git a/app/code/Magento/Weee/Test/Unit/Model/Total/Observer/Webapi/ItemTest.php b/app/code/Magento/Weee/Test/Unit/Model/Total/Observer/Webapi/ItemTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..772907c4b11381c761808f215afbaaba8fa9ae78
--- /dev/null
+++ b/app/code/Magento/Weee/Test/Unit/Model/Total/Observer/Webapi/ItemTest.php
@@ -0,0 +1,190 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Weee\Test\Unit\Model\Total\Observer\Webapi;
+
+class ItemTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $weeeHelperMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManagerMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeMock;
+
+    /**
+     * @var \Magento\Weee\Model\Total\Observer\Webapi\Item
+     */
+    protected $model;
+
+    protected function setUp()
+    {
+        $this->weeeHelperMock = $this->getMock('Magento\Weee\Helper\Data', [], [], '', false);
+        $this->storeManagerMock = $this->getMock('Magento\Store\Model\StoreManagerInterface');
+        $this->storeMock = $this->getMock('Magento\Store\Model\Store', [], [], '', false);
+
+        $this->storeManagerMock->expects($this->any())->method('getStore')->will($this->returnValue($this->storeMock));
+
+        $this->model = new \Magento\Weee\Model\Total\Observer\Webapi\Item(
+            $this->weeeHelperMock,
+            $this->storeManagerMock
+        );
+    }
+
+    /**
+     * @dataProvider processTaxDataDataProvider
+     *
+     * @param bool $helperIsEnabled
+     * @param int $weeeTaxInclTax
+     * @param int $rowTotal
+     * @param bool $weeeTaxRowApplied
+     * @param int $rowTotalInclTax
+     * @param int $rowWeeeInclTax
+     * @param int $weeeTaxApplied
+     * @param int $weeeTaxAppliedAmount
+     * @param bool $includeWeeeFlag
+     * @param int $priceIncTax
+     * @param int $calculationPrice
+     * @param int $expectedRowTotal
+     * @param int $expectedRowInclTax
+     * @param int $expectedPrice
+     * @param int $expectedPriceInclTax
+     *
+     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
+     */
+    public function testProcessTaxData(
+        $helperIsEnabled,
+        $weeeTaxInclTax,
+        $rowTotal,
+        $weeeTaxRowApplied,
+        $rowTotalInclTax,
+        $rowWeeeInclTax,
+        $weeeTaxApplied,
+        $weeeTaxAppliedAmount,
+        $includeWeeeFlag,
+        $priceIncTax,
+        $calculationPrice,
+        $expectedRowTotal,
+        $expectedRowInclTax,
+        $expectedPrice,
+        $expectedPriceInclTax
+    ) {
+        $observerMock = $this->getMock('Magento\Framework\Object', ['getEvent'], [], '', false);
+        $eventMock = $this->getMock('Magento\Framework\Event', ['getItem'], [], '', false);
+        $itemMock = $this->getMock(
+            'Magento\Quote\Model\Quote\Item',
+            [
+                'setRowTotal', 'setRowTotalInclTax', 'setPrice', 'setPriceInclTax',
+                'getPriceInclTax', 'getCalculationPrice', 'getRowTotal', 'getRowTotalInclTax', 'getWeeeTaxApplied',
+                'getWeeeTaxAppliedRowAmount', 'getWeeeTaxAppliedAmount'
+            ],
+            [],
+            '',
+            false
+        );
+
+        $eventMock->expects($this->once())->method('getItem')->will($this->returnValue($itemMock));
+        $observerMock->expects($this->once())->method('getEvent')->will($this->returnValue($eventMock));
+
+        $this->weeeHelperMock->expects($this->any())->method('isEnabled')
+            ->will($this->returnValue($helperIsEnabled));
+        $this->weeeHelperMock->expects($this->any())->method('getWeeeTaxInclTax')
+            ->with($itemMock)->will($this->returnValue($weeeTaxInclTax));
+        $this->weeeHelperMock->expects($this->any())->method('getRowWeeeTaxInclTax')
+            ->will($this->returnValue($rowWeeeInclTax));
+        $this->weeeHelperMock->expects($this->any())->method('typeOfDisplay')
+            ->will($this->returnValue($includeWeeeFlag));
+
+        $weeeTaxApplied = serialize($weeeTaxApplied);
+        $itemMock->expects($this->any())->method('getPriceInclTax')->will($this->returnValue($priceIncTax));
+        $itemMock->expects($this->any())->method('getCalculationPrice')->will($this->returnValue($calculationPrice));
+        $itemMock->expects($this->any())->method('getRowTotal')->will($this->returnValue($rowTotal));
+        $itemMock->expects($this->any())->method('getRowTotalInclTax')->will($this->returnValue($rowTotalInclTax));
+        $itemMock->expects($this->any())->method('getWeeeTaxApplied')->will($this->returnValue($weeeTaxApplied));
+        $itemMock->expects($this->any())->method('getWeeeTaxAppliedAmount')
+            ->will($this->returnValue($weeeTaxAppliedAmount));
+        $itemMock->expects($this->any())->method('getWeeeTaxAppliedRowAmount')
+            ->will($this->returnValue($weeeTaxRowApplied));
+
+        $itemMock->expects($this->once())->method('setRowTotal')->with($expectedRowTotal)
+            ->will($this->returnSelf());
+        $itemMock->expects($this->once())->method('setRowTotalInclTax')->with($expectedRowInclTax)
+            ->will($this->returnSelf());
+        $itemMock->expects($this->once())->method('setPrice')->with($expectedPrice)
+            ->will($this->returnSelf());
+        $itemMock->expects($this->once())->method('setPriceInclTax')->with($expectedPriceInclTax)
+            ->will($this->returnSelf());
+
+        $this->model->processTaxData($observerMock);
+    }
+
+    /**
+     * @return array
+     */
+    public function processTaxDataDataProvider()
+    {
+        return [
+            [
+                'helperIsEnabled' => false,
+                'weeeTaxInclTax' => 10,
+                'rowTotal' => 17,
+                'weeeTaxRowApplied' => 3,
+                'rowTotalInclTax' => 11,
+                'rowWeeeInclTax' => 14,
+                'weeeTaxApplied' => 4,
+                'weeeTaxAppliedAmount' => 4,
+                'includeWeeeFlag' => false,
+                'priceIncTax' => 5,
+                'calculationPrice' => 12,
+                'expectedRowTotal' => 17,
+                'expectedRowInclTax' => 11,
+                'expectedPrice' => 12,
+                'expectedPriceInclTax' => 5
+            ],
+            [
+                'helperIsEnabled' => true,
+                'weeeTaxInclTax' => 10,
+                'rowTotal' => 17,
+                'weeeTaxRowApplied' => 3,
+                'rowTotalInclTax' => 11,
+                'rowWeeeInclTax' => 14,
+                'weeeTaxApplied' => 4,
+                'weeeTaxAppliedAmount' => 4,
+                'includeWeeeFlag' => false,
+                'priceIncTax' => 5,
+                'calculationPrice' => 12,
+                'expectedRowTotal' => 17,
+                'expectedRowInclTax' => 11,
+                'expectedPrice' => 12,
+                'expectedPriceInclTax' => 5
+            ],
+            [
+                'helperIsEnabled' => true,
+                'weeeTaxInclTax' => 10,
+                'rowTotal' => 17,
+                'weeeTaxRowApplied' => 3,
+                'rowTotalInclTax' => 11,
+                'rowWeeeInclTax' => 14,
+                'weeeTaxApplied' => 4,
+                'weeeTaxAppliedAmount' => 4,
+                'includeWeeeFlag' => true,
+                'priceIncTax' => 5,
+                'calculationPrice' => 12,
+                'expectedRowTotal' => 20,
+                'expectedRowInclTax' => 25,
+                'expectedPrice' => 16,
+                'expectedPriceInclTax' => 15
+            ]
+        ];
+    }
+}
diff --git a/app/code/Magento/Weee/Test/Unit/Model/WeeeConfigProviderTest.php b/app/code/Magento/Weee/Test/Unit/Model/WeeeConfigProviderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..548ad82139b34802fadc77310423804350e08924
--- /dev/null
+++ b/app/code/Magento/Weee/Test/Unit/Model/WeeeConfigProviderTest.php
@@ -0,0 +1,180 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Weee\Test\Unit\Model;
+
+class WeeeConfigProviderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $weeeHelperMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $weeeConfigMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManagerMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeMock;
+
+    /**
+     * @var \Magento\Weee\Model\WeeeConfigProvider
+     */
+    protected $model;
+
+    protected function setUp()
+    {
+        $this->weeeHelperMock = $this->getMock('Magento\Weee\Helper\Data', [], [], '', false);
+        $this->weeeConfigMock = $this->getMock('Magento\Weee\Model\Config', [], [], '', false);
+        $this->storeManagerMock = $this->getMock('Magento\Store\Model\StoreManagerInterface');
+        $this->storeMock = $this->getMock('Magento\Store\Model\Store', [], [], '', false);
+
+        $this->storeManagerMock->expects($this->any())->method('getStore')->will($this->returnValue($this->storeMock));
+
+        $this->model = new \Magento\Weee\Model\WeeeConfigProvider(
+            $this->weeeHelperMock,
+            $this->storeManagerMock,
+            $this->weeeConfigMock
+        );
+    }
+
+    /**
+     * @dataProvider getConfigDataProvider
+     * @param array $expectedResult
+     * @param bool $weeeHelperEnabled
+     * @param bool $displayWeeeDetails
+     * @param bool $weeeConfigEnabled
+     * @param bool $includeInSubtotal
+     */
+    public function testGetConfig(
+        $expectedResult,
+        $weeeHelperEnabled,
+        $displayWeeeDetails,
+        $weeeConfigEnabled,
+        $includeInSubtotal
+    ) {
+        $storeId = 1;
+        $this->storeMock->expects($this->any())->method('getId')->will($this->returnValue($storeId));
+        $this->weeeHelperMock->expects($this->any())->method('isEnabled')->with($storeId)
+            ->will($this->returnValue($weeeHelperEnabled));
+        $this->weeeHelperMock->expects($this->any())->method('typeOfDisplay')
+            ->will($this->returnValue($displayWeeeDetails));
+
+        $this->weeeConfigMock->expects($this->any())->method('isEnabled')
+            ->will($this->returnValue($weeeConfigEnabled));
+        $this->weeeConfigMock->expects($this->any())->method('includeInSubtotal')
+            ->will($this->returnValue($includeInSubtotal));
+
+        $this->assertEquals($expectedResult, $this->model->getConfig());
+    }
+
+    /**
+     * @return array
+     */
+    public function getConfigDataProvider()
+    {
+        return [
+            [
+                'expectedResult' => [
+                    'isDisplayPriceWithWeeeDetails' => false,
+                    'isDisplayFinalPrice' => true,
+                    'isWeeeEnabled' => false,
+                    'isIncludedInSubtotal' => true,
+                    'getIncludeWeeeFlag' => true,
+                ],
+                'weeeHelperEnabled' => false,
+                'displayWeeeDetails' => true,
+                'weeeConfigEnabled' => true,
+                'includeInSubtotal' => true,
+            ],
+            [
+                'expectedResult' => [
+                    'isDisplayPriceWithWeeeDetails' => true,
+                    'isDisplayFinalPrice' => true,
+                    'isWeeeEnabled' => true,
+                    'isIncludedInSubtotal' => true,
+                    'getIncludeWeeeFlag' => true,
+                ],
+                'weeeHelperEnabled' => true,
+                'displayWeeeDetails' => true,
+                'weeeConfigEnabled' => true,
+                'includeInSubtotal' => true,
+            ],
+            [
+                'expectedResult' => [
+                    'isDisplayPriceWithWeeeDetails' => false,
+                    'isDisplayFinalPrice' => false,
+                    'isWeeeEnabled' => true,
+                    'isIncludedInSubtotal' => true,
+                    'getIncludeWeeeFlag' => false,
+                ],
+                'weeeHelperEnabled' => true,
+                'displayWeeeDetails' => false,
+                'weeeConfigEnabled' => true,
+                'includeInSubtotal' => true,
+            ],
+            [
+                'expectedResult' => [
+                    'isDisplayPriceWithWeeeDetails' => false,
+                    'isDisplayFinalPrice' => false,
+                    'isWeeeEnabled' => false,
+                    'isIncludedInSubtotal' => true,
+                    'getIncludeWeeeFlag' => false,
+                ],
+                'weeeHelperEnabled' => false,
+                'displayWeeeDetails' => false,
+                'weeeConfigEnabled' => true,
+                'includeInSubtotal' => true,
+            ],
+            [
+                'expectedResult' => [
+                    'isDisplayPriceWithWeeeDetails' => false,
+                    'isDisplayFinalPrice' => false,
+                    'isWeeeEnabled' => false,
+                    'isIncludedInSubtotal' => false,
+                    'getIncludeWeeeFlag' => false,
+                ],
+                'weeeHelperEnabled' => false,
+                'displayWeeeDetails' => false,
+                'weeeConfigEnabled' => false,
+                'includeInSubtotal' => true,
+            ],
+            [
+                'expectedResult' => [
+                    'isDisplayPriceWithWeeeDetails' => false,
+                    'isDisplayFinalPrice' => false,
+                    'isWeeeEnabled' => false,
+                    'isIncludedInSubtotal' => false,
+                    'getIncludeWeeeFlag' => false,
+                ],
+                'weeeHelperEnabled' => false,
+                'displayWeeeDetails' => false,
+                'weeeConfigEnabled' => true,
+                'includeInSubtotal' => false,
+            ],
+            [
+                'expectedResult' => [
+                    'isDisplayPriceWithWeeeDetails' => false,
+                    'isDisplayFinalPrice' => false,
+                    'isWeeeEnabled' => false,
+                    'isIncludedInSubtotal' => false,
+                    'getIncludeWeeeFlag' => false,
+                ],
+                'weeeHelperEnabled' => false,
+                'displayWeeeDetails' => false,
+                'weeeConfigEnabled' => false,
+                'includeInSubtotal' => false,
+            ],
+        ];
+    }
+}
diff --git a/app/code/Magento/Weee/view/frontend/layout/checkout_onepage_index.xml b/app/code/Magento/Weee/view/frontend/layout/checkout_onepage_index.xml
index e5aa37b3c77ed809a449fa828489f38808d2d3fa..6e3439d0775862400bec88a4cf5885f4005358e5 100644
--- a/app/code/Magento/Weee/view/frontend/layout/checkout_onepage_index.xml
+++ b/app/code/Magento/Weee/view/frontend/layout/checkout_onepage_index.xml
@@ -5,6 +5,7 @@
  * See COPYING.txt for license details.
  */
 -->
+<!-- TODO remove this file as soon as enhanced checkout is implemented -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
     <body>
         <referenceBlock name="checkout.root">
@@ -13,50 +14,36 @@
                     <item name="components" xsi:type="array">
                         <item name="checkout" xsi:type="array">
                             <item name="children" xsi:type="array">
-                                <item name="steps" xsi:type="array">
+                                <item name="summary" xsi:type="array">
                                     <item name="children" xsi:type="array">
-                                        <item name="review" xsi:type="array">
+                                        <item name="totals" xsi:type="array">
                                             <item name="children" xsi:type="array">
-                                                <item name="columns" xsi:type="array">
+                                                <item name="weee" xsi:type="array">
+                                                    <item name="component" xsi:type="string">Magento_Weee/js/view/checkout/summary/weee</item>
+                                                    <item name="config" xsi:type="array">
+                                                        <item name="title" xsi:type="string">FPT</item>
+                                                    </item>
+                                                </item>
+                                            </item>
+                                        </item>
+                                        <item name="cart_items" xsi:type="array">
+                                            <item name="children" xsi:type="array">
+                                                <item name="details" xsi:type="array">
                                                     <item name="children" xsi:type="array">
-                                                        <item name="price" xsi:type="array">
-                                                            <item name="children" xsi:type="array">
-                                                                <item name="unit_incl_tax" xsi:type="array">
-                                                                    <item name="component"  xsi:type="string">Magento_Weee/js/view/checkout/review/item/price/unit_incl_tax</item>
-                                                                    <item name="displayArea" xsi:type="string">unit_incl_tax</item>
-                                                                </item>
-                                                                <item name="unit_excl_tax" xsi:type="array">
-                                                                    <item name="component"  xsi:type="string">Magento_Weee/js/view/checkout/review/item/price/unit_excl_tax</item>
-                                                                    <item name="displayArea" xsi:type="string">unit_excl_tax</item>
-                                                                </item>
-                                                            </item>
-                                                        </item>
                                                         <item name="subtotal" xsi:type="array">
                                                             <item name="children" xsi:type="array">
-                                                                <item name="row_incl_tax" xsi:type="array">
-                                                                    <item name="component"  xsi:type="string">Magento_Weee/js/view/checkout/review/item/price/row_incl_tax</item>
-                                                                    <item name="displayArea" xsi:type="string">row_incl_tax</item>
+                                                                <item name="weee_row_incl_tax" xsi:type="array">
+                                                                    <item name="component"  xsi:type="string">Magento_Weee/js/view/checkout/summary/item/price/row_incl_tax</item>
+                                                                <item name="displayArea" xsi:type="string">row_incl_tax</item>
                                                                 </item>
-                                                                <item name="row_excl_tax" xsi:type="array">
-                                                                    <item name="component"  xsi:type="string">Magento_Weee/js/view/checkout/review/item/price/row_excl_tax</item>
+                                                                <item name="weee_row_excl_tax" xsi:type="array">
+                                                                    <item name="component"  xsi:type="string">Magento_Weee/js/view/checkout/summary/item/price/row_excl_tax</item>
                                                                     <item name="displayArea" xsi:type="string">row_excl_tax</item>
                                                                 </item>
                                                             </item>
                                                         </item>
                                                     </item>
                                                 </item>
-                                                <item name="totals" xsi:type="array">
-                                                    <item name="children" xsi:type="array">
-                                                        <item name="before_grandtotal" xsi:type="array">
-                                                            <item name="children" xsi:type="array">
-                                                                <item name="weee_total" xsi:type="array">
-                                                                    <item name="component" xsi:type="string">Magento_Weee/js/view/checkout/review/weee_total</item>
-                                                                </item>
-                                                            </item>
-                                                        </item>
-                                                    </item>
-                                                </item>
-
                                             </item>
                                         </item>
                                     </item>
diff --git a/app/code/Magento/Weee/view/frontend/web/js/view/checkout/review/item/price/unit_excl_tax.js b/app/code/Magento/Weee/view/frontend/web/js/view/checkout/review/item/price/unit_excl_tax.js
deleted file mode 100644
index 484b00bacb94409548202088b0d36b5dce9c113c..0000000000000000000000000000000000000000
--- a/app/code/Magento/Weee/view/frontend/web/js/view/checkout/review/item/price/unit_excl_tax.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*browser:true*/
-/*global define*/
-define(
-    [
-        'Magento_Weee/js/view/checkout/review/item/price/weee'
-    ],
-    function (weee) {
-        "use strict";
-        return weee.extend({
-            defaults: {
-                template: 'Magento_Weee/checkout/review/item/price/unit_excl_tax'
-            },
-
-            getFinalUnitDisplayPriceExclTax: function(item) {
-                var unitExclTax = parseFloat(item.price);
-                if(!window.checkoutConfig.getIncludeWeeeFlag) {
-                    return unitExclTax + parseFloat(item.weee_tax_applied_amount);
-                }
-                return unitExclTax;
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Weee/view/frontend/web/js/view/checkout/review/item/price/unit_incl_tax.js b/app/code/Magento/Weee/view/frontend/web/js/view/checkout/review/item/price/unit_incl_tax.js
deleted file mode 100644
index d6e03c37b5e1a9b7c6db4ef86ebd2bb67736a1ce..0000000000000000000000000000000000000000
--- a/app/code/Magento/Weee/view/frontend/web/js/view/checkout/review/item/price/unit_incl_tax.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*browser:true*/
-/*global define*/
-define(
-    [
-        'Magento_Weee/js/view/checkout/review/item/price/weee'
-    ],
-    function (weee) {
-        "use strict";
-        return weee.extend({
-            defaults: {
-                template: 'Magento_Weee/checkout/review/item/price/unit_incl_tax'
-            },
-            getFinalUnitDisplayPriceInclTax: function(item) {
-                var unitInclTax = parseFloat(item.price_incl_tax);
-                if(!window.checkoutConfig.getIncludeWeeeFlag) {
-                    return unitInclTax + this.getWeeeTaxInclTax(item);
-                }
-                return unitInclTax;
-            },
-            getWeeeTaxInclTax: function(item) {
-                var weeeTaxAppliedAmounts = JSON.parse(item.weee_tax_applied);
-                var totalWeeeTaxIncTaxApplied = 0;
-                weeeTaxAppliedAmounts.forEach(function (weeeTaxAppliedAmount) {
-                    totalWeeeTaxIncTaxApplied+=parseFloat(Math.max(weeeTaxAppliedAmount.amount_incl_tax, 0));
-                });
-                return totalWeeeTaxIncTaxApplied;
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Weee/view/frontend/web/js/view/checkout/review/weee_total.js b/app/code/Magento/Weee/view/frontend/web/js/view/checkout/review/weee_total.js
deleted file mode 100644
index 41aec2c8475928ad094bd69f433f7f12fe689020..0000000000000000000000000000000000000000
--- a/app/code/Magento/Weee/view/frontend/web/js/view/checkout/review/weee_total.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-/*browser:true*/
-/*global define*/
-define(
-    [
-        'uiComponent',
-        'Magento_Checkout/js/model/quote',
-        'Magento_Catalog/js/price-utils'
-    ],
-    function (Component,quote, priceUtils) {
-        "use strict";
-        return Component.extend({
-            defaults: {
-                colspan: 3,
-                displayArea: 'before_grandtotal',
-                title: 'FPT',
-                template: 'Magento_Weee/checkout/review/weee_total'
-            },
-            isIncludedInSubtotal: window.checkoutConfig.isIncludedInSubtotal,
-            totals: quote.getTotals(),
-            getColspan: function() {
-                return this.colspan;
-            },
-            getTitle: function() {
-                return this.title;
-            },
-            getPureValue: function() {
-                var items = quote.getItems();
-                var sum = 0;
-                for (var i = 0; i < items.length; i++) {
-                    sum += parseFloat(items[i].weee_tax_applied_row_amount);
-                }
-                return sum;
-            },
-            getValue: function() {
-                var items = quote.getItems();
-                var sum = 0;
-                for (var i = 0; i < items.length; i++) {
-                    sum += parseFloat(items[i].weee_tax_applied_row_amount);
-                }
-                return priceUtils.formatPrice(sum, quote.getPriceFormat());
-            }
-        });
-    }
-);
diff --git a/app/code/Magento/Weee/view/frontend/web/js/view/checkout/review/item/price/row_excl_tax.js b/app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/item/price/row_excl_tax.js
similarity index 81%
rename from app/code/Magento/Weee/view/frontend/web/js/view/checkout/review/item/price/row_excl_tax.js
rename to app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/item/price/row_excl_tax.js
index 000d08a5ca07a481989b64f76aa1376ec9cedac8..07c7f94305e991453c0eeb7d8d51550fd94db966 100644
--- a/app/code/Magento/Weee/view/frontend/web/js/view/checkout/review/item/price/row_excl_tax.js
+++ b/app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/item/price/row_excl_tax.js
@@ -6,13 +6,13 @@
 /*global define*/
 define(
     [
-        'Magento_Weee/js/view/checkout/review/item/price/weee'
+        'Magento_Weee/js/view/checkout/summary/item/price/weee'
     ],
     function (weee) {
         "use strict";
         return weee.extend({
             defaults: {
-                template: 'Magento_Weee/checkout/review/item/price/row_excl_tax'
+                template: 'Magento_Weee/checkout/summary/item/price/row_excl_tax'
             },
 
             getFinalRowDisplayPriceExclTax: function(item) {
diff --git a/app/code/Magento/Weee/view/frontend/web/js/view/checkout/review/item/price/row_incl_tax.js b/app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/item/price/row_incl_tax.js
similarity index 88%
rename from app/code/Magento/Weee/view/frontend/web/js/view/checkout/review/item/price/row_incl_tax.js
rename to app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/item/price/row_incl_tax.js
index 6fc8b67643282d0a8bea4cb700baa37b56dbdff4..15aec47fd0f36c377a513757c4f207d05bd71ed0 100644
--- a/app/code/Magento/Weee/view/frontend/web/js/view/checkout/review/item/price/row_incl_tax.js
+++ b/app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/item/price/row_incl_tax.js
@@ -6,13 +6,13 @@
 /*global define*/
 define(
     [
-        'Magento_Weee/js/view/checkout/review/item/price/weee'
+        'Magento_Weee/js/view/checkout/summary/item/price/weee'
     ],
     function (weee) {
         "use strict";
         return weee.extend({
             defaults: {
-                template: 'Magento_Weee/checkout/review/item/price/row_incl_tax',
+                template: 'Magento_Weee/checkout/summary/item/price/row_incl_tax',
                 displayArea: 'row_incl_tax'
             },
             getFinalRowDisplayPriceInclTax: function(item) {
diff --git a/app/code/Magento/Weee/view/frontend/web/js/view/checkout/review/item/price/weee.js b/app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/item/price/weee.js
similarity index 77%
rename from app/code/Magento/Weee/view/frontend/web/js/view/checkout/review/item/price/weee.js
rename to app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/item/price/weee.js
index f6c146aa688fb67e68d3d82cf383ec3726605ea9..919504bd6270e066a0caa6aacf47506e69ec4e9b 100644
--- a/app/code/Magento/Weee/view/frontend/web/js/view/checkout/review/item/price/weee.js
+++ b/app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/item/price/weee.js
@@ -6,11 +6,10 @@
 /*global define*/
 define(
     [
-        'uiComponent',
-        'Magento_Checkout/js/model/quote',
-        'Magento_Catalog/js/price-utils'
+        'Magento_Checkout/js/view/summary/abstract-total',
+        'Magento_Checkout/js/model/quote'
     ],
-    function (Component,quote, priceUtils) {
+    function (Component,quote) {
         "use strict";
         return Component.extend({
 
@@ -26,9 +25,6 @@ define(
                 }
                 return window.checkoutConfig.isDisplayFinalPrice;
             },
-            getFormattedPrice: function (price) {
-                return priceUtils.formatPrice(price, quote.getPriceFormat());
-            },
             getWeeeTaxApplied: function(item) {
                 if (item.weee_tax_applied) {
                     return JSON.parse(item.weee_tax_applied)
diff --git a/app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/weee.js b/app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/weee.js
new file mode 100644
index 0000000000000000000000000000000000000000..22209e41d2028a98c61b8b3876345ff5e1d33f4b
--- /dev/null
+++ b/app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/weee.js
@@ -0,0 +1,31 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*browser:true*/
+/*global define*/
+define(
+    [
+        'Magento_Checkout/js/view/summary/abstract-total',
+        'Magento_Checkout/js/model/quote',
+        'Magento_Checkout/js/model/totals',
+        'Magento_Catalog/js/price-utils'
+    ],
+    function (Component,quote, totals) {
+        "use strict";
+        return Component.extend({
+            defaults: {
+                template: 'Magento_Weee/checkout/summary/weee'
+            },
+            isIncludedInSubtotal: window.checkoutConfig.isIncludedInSubtotal,
+            totals: totals.totals,
+            getValue: function() {
+                return this.getFormattedPrice(this.totals()['weee_tax_applied_amount']);
+            },
+            isDisplayed: function() {
+                return this.isFullMode() && this.isIncludedInSubtotal &&
+                    this.totals()['weee_tax_applied_amount'] > 0;
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/Weee/view/frontend/web/template/checkout/review/item/price/row_incl_tax.html b/app/code/Magento/Weee/view/frontend/web/template/checkout/review/item/price/row_incl_tax.html
deleted file mode 100644
index bfaa8c3f176722b4e50b1c0e7ff9f0bff45410af..0000000000000000000000000000000000000000
--- a/app/code/Magento/Weee/view/frontend/web/template/checkout/review/item/price/row_incl_tax.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<!-- ko if:  (isDisplayPriceWithWeeeDetails(item)) -->
-    <span class="cart-tax-total" data-bind="mageInit: {taxToggle: {itemTaxId : '#subtotal-item-tax-details'+item.item_id}}">
-        <span class="price" data-bind="text: getFormattedPrice(item.row_total_incl_tax)"></span>
-    </span>
-<!-- /ko -->
-<!-- ko ifnot: (isDisplayPriceWithWeeeDetails(item)) -->
-    <span class="cart-price"><span class="price" data-bind="text: getFormattedPrice(item.row_total_incl_tax)"></span></span>
-<!-- /ko -->
-
-<!--ko if: getWeeeTaxApplied(item).length > 0-->
-<!-- ko ifnot:  (isDisplayPriceWithWeeeDetails(item))-->
-<span class="cart-tax-info" data-bind ="attr: {'id': 'subtotal-item-tax-details' + item.item_id}" style="display: none;"></span>
-<!-- /ko-->
-<!-- ko if:  (isDisplayPriceWithWeeeDetails(item))-->
-<span class="cart-tax-info" data-bind ="attr: {'id': 'subtotal-item-tax-details' + item.item_id}" style="display: none;">
-         <!-- ko foreach: getWeeeTaxApplied(item)-->
-            <span class="weee" data-bind="attr:{'data-label':title}">
-                <span class="price" data-bind="text: $parent.getFormattedPrice(row_amount_incl_tax)"></span>
-            </span>
-         <!-- /ko-->
-        </span>
-<!-- /ko-->
-
-<!-- ko if: isDisplayFinalPrice(item)-->
-        <span class="cart-tax-total" data-bind="mageInit: {taxToggle: {itemTaxId : '#subtotal-item-tax-details'+item.item_id}}">
-            <span class="weee" data-bind="attr: {'data-label':$t('Total Incl. Tax')}">
-                <span class="price" data-bind="text: getFormattedPrice(getFinalRowDisplayPriceInclTax(item))"></span>
-            </span>
-        </span>
-<!-- /ko -->
-<!-- /ko -->
diff --git a/app/code/Magento/Weee/view/frontend/web/template/checkout/review/item/price/unit_excl_tax.html b/app/code/Magento/Weee/view/frontend/web/template/checkout/review/item/price/unit_excl_tax.html
deleted file mode 100644
index eb34f588887cef129456b0c537b5dffc9260bb40..0000000000000000000000000000000000000000
--- a/app/code/Magento/Weee/view/frontend/web/template/checkout/review/item/price/unit_excl_tax.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-
-<!-- ko if:  (isDisplayPriceWithWeeeDetails(item)) -->
-    <span class="cart-tax-total" data-bind="mageInit:{taxToggle: {itemTaxId : '#eunit-item-tax-details' + item.item_id}}">
-        <span class="price" data-bind="text: getFormattedPrice(item.price)"></span>
-    </span>
-<!-- /ko -->
-<!-- ko ifnot:  (isDisplayPriceWithWeeeDetails(item)) -->
-    <span class="cart-price"><span class="price" data-bind="text: getFormattedPrice(item.price)"></span></span>
-<!-- /ko -->
-
-
-<!--ko if:  (getWeeeTaxApplied(item).length > 0)-->
-    <!-- ko ifnot:  (isDisplayPriceWithWeeeDetails(item))-->
-        <span class="cart-tax-info" data-bind ="attr: {'id': 'eunit-item-tax-details' + item.item_id}" style="display: none;"></span>
-    <!-- /ko-->
-    <!-- ko if:  (isDisplayPriceWithWeeeDetails(item))-->
-        <span class="cart-tax-info" data-bind ="attr: {'id': 'eunit-item-tax-details' + item.item_id}" style="display: none;">
-             <!-- ko foreach: getWeeeTaxApplied(item)-->
-                <span class="weee" data-bind="attr:{'data-label':title}">
-                    <span class="price" data-bind="text: $parent.getFormattedPrice(amount)"></span>
-                </span>
-            <!-- /ko-->
-            </span>
-    <!-- /ko-->
-
-
-    <!-- ko if: isDisplayFinalPrice(item)-->
-        <span class="cart-tax-total" data-bind="mageInit:{taxToggle: {itemTaxId : '#eunit-item-tax-details' + item.item_id}}">
-            <span class="weee" data-bind="attr: {'data-label':$t('Total')}">
-                <span class="price" data-bind="text: getFormattedPrice(getFinalUnitDisplayPriceExclTax(item))"></span>
-            </span>
-        </span>
-    <!-- /ko -->
-<!-- /ko -->
diff --git a/app/code/Magento/Weee/view/frontend/web/template/checkout/review/item/price/unit_incl_tax.html b/app/code/Magento/Weee/view/frontend/web/template/checkout/review/item/price/unit_incl_tax.html
deleted file mode 100644
index 1a67282073225531a6137bd83361a08d60c2287e..0000000000000000000000000000000000000000
--- a/app/code/Magento/Weee/view/frontend/web/template/checkout/review/item/price/unit_incl_tax.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-
-<!-- ko if:  (isDisplayPriceWithWeeeDetails(item)) -->
-    <span class="cart-tax-total" data-bind="mageInit: {taxToggle: {itemTaxId : '#unit-item-tax-details'+item.item_id}}">
-        <span class="price" data-bind="text: getFormattedPrice(item.price_incl_tax)"></span>
-    </span>
-<!-- /ko -->
-<!-- ko ifnot:  (isDisplayPriceWithWeeeDetails(item)) -->
-    <span class="cart-price"><span class="price" data-bind="text: getFormattedPrice(item.price_incl_tax)"></span></span>
-<!-- /ko -->
-
-<!--ko if:  (getWeeeTaxApplied(item).length > 0)-->
-    <!-- ko ifnot:  (isDisplayPriceWithWeeeDetails(item))-->
-        <span class="cart-tax-info" data-bind ="attr: {'id': 'unit-item-tax-details' + item.item_id}" style="display: none;"></span>
-    <!-- /ko-->
-    <!-- ko if:  (isDisplayPriceWithWeeeDetails(item))-->
-        <span class="cart-tax-info" data-bind ="attr: {'id': 'unit-item-tax-details' + item.item_id}" style="display: none;">
-            <!-- ko foreach: getWeeeTaxApplied(item)-->
-                <span class="weee" data-bind="attr:{'data-label':title}">
-                    <span class="price" data-bind="text: $parent.getFormattedPrice(amount_incl_tax)"></span>
-                </span>
-            <!-- /ko-->
-        </span>
-    <!-- /ko-->
-
-    <!-- ko if: isDisplayFinalPrice(item)-->
-        <span class="cart-tax-total" data-bind="mageInit: {taxToggle: {itemTaxId : '#unit-item-tax-details'+item.item_id}}">
-            <span class="weee"  data-bind="attr: {'data-label':$t('Total Incl. Tax')}">
-                <span class="price" data-bind="text: getFormattedPrice(getFinalUnitDisplayPriceInclTax(item))"></span>
-            </span>
-        </span>
-    <!-- /ko -->
-<!-- /ko -->
diff --git a/app/code/Magento/Weee/view/frontend/web/template/checkout/review/weee_total.html b/app/code/Magento/Weee/view/frontend/web/template/checkout/review/weee_total.html
deleted file mode 100644
index 3e9b25d84db8239da763e6bc4d740bcd6dc947f1..0000000000000000000000000000000000000000
--- a/app/code/Magento/Weee/view/frontend/web/template/checkout/review/weee_total.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!--
-/**
-* Copyright © 2015 Magento. All rights reserved.
-* See COPYING.txt for license details.
-*/
--->
-<!-- ko if: isIncludedInSubtotal && getPureValue() > 0 -->
-<tr class="totals">
-    <th data-bind="text: getTitle(), attr: {'colspan': getColspan()}" class="mark" scope="row"></th>
-    <td class="amount" data-bind="attr: {'data-th': $t(getTitle()) }">
-        <span data-bind="text: getValue()"></span>
-    </td>
-</tr>
-<!-- /ko -->
\ No newline at end of file
diff --git a/app/code/Magento/Weee/view/frontend/web/template/checkout/review/item/price/row_excl_tax.html b/app/code/Magento/Weee/view/frontend/web/template/checkout/summary/item/price/row_excl_tax.html
similarity index 51%
rename from app/code/Magento/Weee/view/frontend/web/template/checkout/review/item/price/row_excl_tax.html
rename to app/code/Magento/Weee/view/frontend/web/template/checkout/summary/item/price/row_excl_tax.html
index c1a8590e1fe157967c7490e497ba072389d45399..39e2bfa7815e8d8d5658ae91b0838982ce62636b 100644
--- a/app/code/Magento/Weee/view/frontend/web/template/checkout/review/item/price/row_excl_tax.html
+++ b/app/code/Magento/Weee/view/frontend/web/template/checkout/summary/item/price/row_excl_tax.html
@@ -4,22 +4,22 @@
  * See COPYING.txt for license details.
  */
 -->
-<!-- ko if:  (isDisplayPriceWithWeeeDetails(item)) -->
-    <span class="cart-tax-total" data-bind="mageInit: {taxToggle: {itemTaxId : '#esubtotal-item-tax-details'+item.item_id}}">
-        <span class="price" data-bind="text: getFormattedPrice(item.row_total)"></span>
+<!-- ko if:  (isDisplayPriceWithWeeeDetails($parents[2])) -->
+    <span class="cart-tax-total" data-bind="mageInit: {taxToggle: {itemTaxId : '#esubtotal-item-tax-details'+$parents[2].item_id}}">
+        <span class="price" data-bind="text: getFormattedPrice($parents[2].row_total)"></span>
     </span>
 <!-- /ko -->
-<!-- ko ifnot: (isDisplayPriceWithWeeeDetails(item)) -->
-    <span class="cart-price"><span class="price" data-bind="text: getFormattedPrice(item.row_total)"></span></span>
+<!-- ko ifnot: (isDisplayPriceWithWeeeDetails($parents[2])) -->
+    <span class="cart-price"><span class="price" data-bind="text: getFormattedPrice($parents[2].row_total)"></span></span>
 <!-- /ko -->
 
-<!--ko if:  (getWeeeTaxApplied(item).length > 0)-->
-<!-- ko ifnot:  (isDisplayPriceWithWeeeDetails(item))-->
-<span class="cart-tax-info" data-bind ="attr: {'id': 'esubtotal-item-tax-details' + item.item_id}" style="display: none;"></span>
+<!--ko if:  (getWeeeTaxApplied($parents[2]).length > 0)-->
+<!-- ko ifnot:  (isDisplayPriceWithWeeeDetails($parents[2]))-->
+<span class="cart-tax-info" data-bind ="attr: {'id': 'esubtotal-item-tax-details' + $parents[2].item_id}" style="display: none;"></span>
 <!-- /ko-->
-<!-- ko if:  (isDisplayPriceWithWeeeDetails(item))-->
-<span class="cart-tax-info" data-bind ="attr: {'id': 'esubtotal-item-tax-details' + item.item_id}" style="display: none;">
-         <!-- ko foreach: getWeeeTaxApplied(item)-->
+<!-- ko if:  (isDisplayPriceWithWeeeDetails($parents[2]))-->
+<span class="cart-tax-info" data-bind ="attr: {'id': 'esubtotal-item-tax-details' + $parents[2].item_id}" style="display: none;">
+         <!-- ko foreach: getWeeeTaxApplied($parents[2])-->
             <span class="weee" data-bind="attr:{'data-label':title}">
                 <span class="price" data-bind="text: $parent.getFormattedPrice(row_amount)"></span>
             </span>
@@ -27,10 +27,10 @@
         </span>
 <!-- /ko-->
 
-<!-- ko if: isDisplayFinalPrice(item)-->
-        <span class="cart-tax-total" data-bind="mageInit: {taxToggle: {itemTaxId : '#esubtotal-item-tax-details'+item.item_id}}">
+<!-- ko if: isDisplayFinalPrice($parents[2])-->
+        <span class="cart-tax-total" data-bind="mageInit: {taxToggle: {itemTaxId : '#esubtotal-item-tax-details'+$parents[2].item_id}}">
             <span class="weee" data-bind="attr: {'data-label':$t('Total')}">
-                <span class="price" data-bind="text: getFormattedPrice(getFinalRowDisplayPriceExclTax(item))">
+                <span class="price" data-bind="text: getFormattedPrice(getFinalRowDisplayPriceExclTax($parents[2]))">
 
                 </span>
             </span>
diff --git a/app/code/Magento/Weee/view/frontend/web/template/checkout/summary/item/price/row_incl_tax.html b/app/code/Magento/Weee/view/frontend/web/template/checkout/summary/item/price/row_incl_tax.html
new file mode 100644
index 0000000000000000000000000000000000000000..562bd3293cf960a41046ebb132d3258c8e5a1651
--- /dev/null
+++ b/app/code/Magento/Weee/view/frontend/web/template/checkout/summary/item/price/row_incl_tax.html
@@ -0,0 +1,37 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<!-- ko if:  (isDisplayPriceWithWeeeDetails($parents[2])) -->
+    <span class="cart-tax-total" data-bind="mageInit: {taxToggle: {itemTaxId : '#subtotal-item-tax-details'+$parents[2].item_id}}">
+        <span class="price" data-bind="text: getFormattedPrice($parents[2].row_total_incl_tax)"></span>
+    </span>
+<!-- /ko -->
+<!-- ko ifnot: (isDisplayPriceWithWeeeDetails($parents[2])) -->
+<span class="cart-price"><span class="price" data-bind="text: getFormattedPrice($parents[2].row_total_incl_tax)"></span></span>
+<!-- /ko -->
+
+<!--ko if: getWeeeTaxApplied($parents[2]).length > 0-->
+<!-- ko ifnot:  (isDisplayPriceWithWeeeDetails($parents[2]))-->
+<span class="cart-tax-info" data-bind ="attr: {'id': 'subtotal-item-tax-details' + $parents[2].item_id}" style="display: none;"></span>
+<!-- /ko-->
+<!-- ko if:  (isDisplayPriceWithWeeeDetails($parents[2]))-->
+<span class="cart-tax-info" data-bind ="attr: {'id': 'subtotal-item-tax-details' + $parents[2].item_id}" style="display: none;">
+         <!-- ko foreach: getWeeeTaxApplied($parents[2])-->
+            <span class="weee" data-bind="attr:{'data-label':title}">
+                <span class="price" data-bind="text: $parent.getFormattedPrice(row_amount_incl_tax)"></span>
+            </span>
+         <!-- /ko-->
+        </span>
+<!-- /ko-->
+
+<!-- ko if: isDisplayFinalPrice($parents[2])-->
+<span class="cart-tax-total" data-bind="mageInit: {taxToggle: {itemTaxId : '#subtotal-item-tax-details'+$parents[2].item_id}}">
+            <span class="weee" data-bind="attr: {'data-label':$t('Total incl. tax')}">
+                <span class="price" data-bind="text: getFormattedPrice(getFinalRowDisplayPriceInclTax($parents[2]))"></span>
+            </span>
+        </span>
+<!-- /ko -->
+<!-- /ko -->
diff --git a/app/code/Magento/Weee/view/frontend/web/template/checkout/summary/weee.html b/app/code/Magento/Weee/view/frontend/web/template/checkout/summary/weee.html
new file mode 100644
index 0000000000000000000000000000000000000000..7a3696a829ef86c82efc2a53342c25cadbdb451e
--- /dev/null
+++ b/app/code/Magento/Weee/view/frontend/web/template/checkout/summary/weee.html
@@ -0,0 +1,14 @@
+<!--
+/**
+* Copyright © 2015 Magento. All rights reserved.
+* See COPYING.txt for license details.
+*/
+-->
+<!-- ko if: isDisplayed() -->
+<tr class="totals">
+    <th data-bind="text: title" class="mark" scope="row"></th>
+    <td class="amount" data-bind="attr: {'data-th': $t(title) }">
+        <span data-bind="text: getValue()"></span>
+    </td>
+</tr>
+<!-- /ko -->
\ No newline at end of file
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/_module.less
index 8795421c0d241fc95cdaf6a43e597fdd2fb8f13e..85932830410a8ee3ef47bc3eabf105116270a9cc 100644
--- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/_module.less
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/_module.less
@@ -5,448 +5,4 @@
 
 @import 'module/_cart.less';
 @import 'module/_minicart.less';
-
-@desktop-form-field-vertical-indent: 29px;
-
-//
-//  Common
-//  _____________________________________________
-
-& when (@media-common = true) {
-
-    //
-    //  One Page Checkout
-    //  ---------------------------------------------
-
-    .opc-wrapper:extend(.abs-add-box-sizing all) {
-        .css(padding-bottom, @indent__xl);
-        > .opc:extend(.abs-reset-list all) {
-        }
-        .section {
-            &.allow .step-title {
-                cursor: pointer;
-            }
-            &.active {
-                .step {
-                    &-title {
-                        .css(color, @primary__color__darker);
-                        cursor: default;
-                    }
-                    &-content {
-                        display: block;
-                    }
-                }
-            }
-        }
-        .step {
-            &-title {
-                border-bottom: @border-width__base solid @border-color__base;
-                .css(color, @primary__color__lighter);
-                line-height: 50px;
-                h2,
-                .number {
-                    display: inline-block;
-                    .heading(h3);
-                }
-                .number:after {
-                    content: '.';
-                }
-            }
-            &-content {
-                display: none;
-                padding: @indent__base @indent__s;
-                position: relative;
-                .addresses .control {
-                    margin: @indent__base 0;
-                }
-                .fieldset {
-                    margin-bottom: 0;
-                    &.login {
-                        .form-hasrequired(bottom);
-                        &:after {
-                            margin-top: 35px;
-                            text-align: center;
-                        }
-                    }
-                    > .field {
-                        margin: @form-field__vertical-indent 0 0;
-                    }
-                    &.address {
-                        .field:first-of-type:not(.additional) {
-                            margin: 0;
-                        }
-                    }
-                    .legend.payments-title:extend(.abs-visually-hidden all) {
-                    }
-                }
-                .methods-shipping {
-                    .item-content {
-                        .fieldset {
-                            > .legend:extend(.abs-visually-hidden all) {
-                            }
-                            > .legend + br:extend(.abs-no-display all) {
-                            }
-                            > .field {
-                                margin: @indent__base 0 0;
-                                &:before {
-                                    display: none;
-                                }
-                                .control {
-                                    display: inline-block;
-                                }
-                            }
-                            br + .field {
-                                margin: 0;
-                            }
-                        }
-                    }
-                }
-                .form {
-                    .form-hasrequired(bottom);
-                    &:after {
-                        text-align: center;
-                    }
-                    .field:not(:first-child) {
-                        margin: @indent__base 0 0;
-                    }
-                    > .field.choice {
-                        margin: @form-field__vertical-indent 0 0;
-                    }
-                    .field {
-                        &.month {
-                            padding-right: @indent__s;
-                        }
-                        &.year {
-                            margin-top: 0;
-                        }
-                    }
-                }
-                .form:not(.login),
-                .order-review {
-                    .action.primary:extend(.abs-button-l all) {
-                    }
-                }
-                .actions {
-                    margin-top: @indent__base;
-                }
-                .field.street {
-                    .field.additional {
-                        .label:extend(.abs-visually-hidden all) {
-                        }
-                    }
-                }
-            }
-        }
-
-        .opc-payment-additional {
-            margin: 0 0 @indent__xs;
-            + .opc-payment {
-                margin: @indent__base 0 0;
-            }
-        }
-
-        //
-        //  Order review
-        //  ---------------------------------------------
-
-        .order-review {
-            .fieldset > .field > .label {
-                font-weight: @font-weight__regular;
-            }
-            .product-item-name {
-                margin: 0;
-            }
-        }
-        
-        .data.table:extend(.abs-product-options-list all) {
-            .col {
-                &.price,
-                &.qty {
-                    text-align: center;
-                    white-space: nowrap;
-                }
-            }
-            .item-options:extend(.abs-add-clearfix all) {
-                font-size: @font-size__s;
-                margin: @indent__s 0 0;
-            }
-            .cart-price:extend(.abs-checkout-cart-price all) {
-            }
-        }
-
-        .action.primary.checkout {
-            margin: 0 0 @indent__base;
-        }
-
-        .hidden:extend(.abs-no-display all) {
-        }
-
-        //
-        //  Customer login
-        //  ---------------------------------------------
-
-        .login-wrapper {
-            .block {
-                .block-title:extend(.abs-login-block-title all) {
-                }
-                .fieldset.guest {
-                    margin-top: @indent__base;
-                }
-                .field.choice {
-                    margin-bottom: @indent__s;
-                }
-            }
-        }
-
-        .actions-toolbar {
-            margin: @indent__xl 0 0;
-        }
-    }
-
-    //
-    //  Shipping methods
-    //  ---------------------------------------------
-
-    .methods-shipping {
-        .item-title:extend(.abs-methods-shipping-title all) {
-        }
-        .item-content:extend(.abs-adjustment-incl-excl-tax all) {
-            margin: 0 0 @indent__xl;
-            .price {
-                font-weight: @font-weight__bold;
-            }
-            .field.choice {
-                margin: 0 0 @indent__s;
-                .control {
-                    float: left;
-                }
-                .label {
-                    display: block;
-                    overflow: hidden;
-                }
-            }
-        }
-        .price-box {
-            margin-bottom: @indent__xs;
-            margin-left: @indent__xl;
-            margin-top: @indent__s;
-            .label + .price {
-                font-weight: @font-weight__bold;
-            }
-        }
-        img {
-            vertical-align: middle;
-        }
-    }
-
-    //
-    //  Payment methods
-    //  ---------------------------------------------
-
-    .methods-payment {
-        .item {
-            &-title {
-                font-weight: @font-weight__regular;
-            }
-            &-content {
-                margin: 0 0 0 @indent__base;
-                .label {
-                    font-weight: @font-weight__regular;
-                }
-            }
-        }
-        .fieldset {
-            padding: 15px 0 @indent__m;
-        }
-        .fieldset & {
-            .item-content > .fieldset > .field:first-child {
-                margin-top: 0;
-            }
-        }
-        .redirect {
-            .font-size(@font-size__s);
-            padding: 0 0 15px;
-        }
-        img {
-            margin-right: @indent__xs;
-            vertical-align: middle;
-        }
-    }
-
-    .cart-tax-info + .cart-tax-total {
-        display: block;
-    }
-
-    //
-    //  Checkout Progress
-    //  ---------------------------------------------
-
-    .opc-block-progress:extend(.abs-add-box-sizing all) {
-        margin-bottom: @indent__l;
-        > .title {
-            .css(background, @sidebar__background-color);
-            .heading(h3);
-            margin: 0;
-            padding: 15px 15px @indent__base;
-            strong {
-                font-weight: @font-weight__regular;
-            }
-        }
-        > .content {
-            .css(background, @sidebar__background-color);
-            padding: 0 15px @indent__xs;
-            .item-content.complete {
-                margin: 0 0 15px;
-                overflow: hidden;
-            }
-            .action,
-            .payment-method .title {
-                font-weight: @font-weight__regular;
-            }
-            .data.table {
-                font-size: @font-size__s;
-            }
-        }
-        .payment-method {
-            > .title {
-                font-weight: @font-weight__light;
-            }
-            > .content {
-                margin: 0 0 @indent__s;
-                &:last-child {
-                    margin-bottom: 0;
-                }
-            }
-            .items-cards {
-                margin: 0;
-                > .content {
-                    margin: 0;
-                }
-            }
-            .data.table {
-                th {
-                    padding: @indent__xs @indent__s @indent__xs 0;
-                }
-                td {
-                    padding: @indent__xs 0;
-                }
-            }
-        }
-    }
-
-    //
-    //  Checkout Success
-    //  ---------------------------------------------
-
-    .checkout-onepage-success {
-        .page-title-wrapper {
-            .print:extend(.abs-no-display all) {
-            }
-        }
-    }
-
-    .checkout-success {
-        .actions-toolbar {
-            margin-top: @indent__xl;
-        }
-    }
-
-    .checkout-onepage-index {
-        .nav-toggle:extend(.abs-no-display all) {
-        }
-        .logo {
-            margin-left: 0;
-        }
-    }
-}
-
-//
-//  Mobile
-//  _____________________________________________
-
-.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) {
-    .opc-wrapper {
-        table.data.table:extend(.abs-checkout-order-review all) {
-        }
-    }
-}
-
-//
-//  Desktop
-//  _____________________________________________
-
-.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__s) {
-    .checkout-onepage-index .column.main:extend(.abs-add-clearfix-desktop-s all) {
-    }
-
-    .opc-wrapper:extend(.abs-add-box-sizing-desktop-s all) {
-        .layout-column(2, 2, @layout-column-checkout__width-main);
-        .step-content {
-            padding: @indent__base 18px @indent__xl;
-            .addresses .control {
-                margin-bottom: @desktop-form-field-vertical-indent;
-            }
-            .form {
-                &:after {
-                    text-align: right;
-                }
-                &:not(.login) {
-                    .actions-toolbar:extend(.abs-reset-left-margin-desktop-s all) {
-                    }
-                }
-                > .field.choice,
-                .fieldset > .field {
-                    margin: @desktop-form-field-vertical-indent 0 0;
-                }
-                .fieldset.address {
-                    .field:first-of-type:not(.additional) {
-                        margin: 0;
-                    }
-                }
-            }
-            .fieldset.login:after:extend(.abs-margin-for-forms-desktop-s all) {
-                text-align: left;
-            }
-        }
-    }
-
-    .opc-block-progress:extend(.abs-add-box-sizing-desktop-s all) {
-        .layout-column(2, 1, @layout-column-checkout__width-left);
-        padding-right: @layout-column-main__sidebar-offset;
-    }
-
-    .login-wrapper:extend(.abs-add-clearfix-desktop-s all) {
-        .block:extend(.abs-blocks-2columns-s all) {
-        }
-        .field.choice:not(.persistent) {
-            &:before {
-                display: none;
-            }
-        }
-        .fieldset.login {
-            .actions:extend(.abs-margin-for-forms-desktop-s all) {
-            }
-        }
-    }
-
-    //
-    //  Checkout success
-    //  ---------------------------------------------
-
-    .checkout-onepage-success {
-        .page-title-wrapper {
-            .print {
-                display: inline-block;
-                .font-size(14);
-                margin-left: @indent__xl;
-            }
-        }
-    }
-
-    .table-order-review {
-        .col.subtotal,
-        .amount {
-            text-align: right;
-        }
-    }
-}
+@import 'module/_checkout.less';
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_cart.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_cart.less
index 089a66bff442b12dda09f922093d1e215abc9e43..fa4e5ad9ad23c9e319d9291c51799ce02bb1364c 100644
--- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_cart.less
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_cart.less
@@ -9,315 +9,236 @@
 
 & when (@media-common = true) {
 
-    //
-    //  Shopping cart
-    //  ---------------------------------------------
+  //
+  //  Shopping cart
+  //  ---------------------------------------------
 
-    .cart {
-        //  Summary block
-        &-summary {
-            &:extend(.abs-add-box-sizing all);
-            .css(background, @sidebar__background-color);
-            margin-bottom: @indent__m;
-            padding: 1px 15px @indent__m;
-            > .title {
-                display: block;
-                .heading(h3);
-            }
-            .block {
-                margin-bottom: 0;
-                > .title {
-                    border-top: @border-width__base solid @border-color__base;
-                    cursor: pointer;
-                    font-weight: @font-weight__semibold;
-                    .icon-font(
-                    @_icon-font-content: @icon-down,
-                    @_icon-font-size: 30px,
-                    @_icon-font-position: after,
-                    @_icon-font-display: block
-                    );
-                    margin-bottom: 0;
-                    overflow: hidden;
-                    padding: 7px @indent__base 7px @indent__xs;
-                    position: relative;
-                    &:after {
-                        position: absolute;
-                        right: 0;
-                        top: -5px;
-                    }
-                    strong {
-                        .column.main & {
-                            .font-size(18);
-                            font-weight: @font-weight__regular;
-                        }
-                    }
-                }
-                > .content {
-                    display: none;
-                }
-                &.active {
-                    > .title {
-                        .icon-font-symbol(
-                        @_icon-font-content: @icon-prev,
-                        @_icon-font-position: after
-                        );
-                    }
-                    > .content {
-                        display: block;
-                    }
-                }
-                .item-options {
-                    margin-left: 0;
-                }
-                .fieldset {
-                    margin: 15px 0 @indent__m @indent__xs;
-                    .field {
-                        margin: 0 0 @indent__s;
-                        &.note {
-                            font-size: @font-size__s;
-                        }
-                    }
-                }
-                .fieldset {
-                    .methods {
-                        .field {
-                            > .label {
-                                display: inline;
-                            }
-                        }
-                    }
-                }
-                .fieldset.estimate {
-                    > .legend,
-                    > .legend + br {
-                        &:extend(.abs-no-display all);
-                    }
-                }
-            }
-            .actions-toolbar {
-                > .primary {
-                    button {
-                        &:extend(.abs-revert-secondary-color all);
-                    }
-                }
-            }
-            &:extend(.abs-adjustment-incl-excl-tax all);
+  .cart {
+    //  Summary block
+    &-summary {
+      &:extend(.abs-add-box-sizing all);
+      .css(background, @sidebar__background-color);
+      margin-bottom: @indent__m;
+      padding: 1px 15px @indent__m;
+      > .title {
+        display: block;
+        .heading(h3);
+      }
+      .block {
+        margin-bottom: 0;
+        > .title {
+          border-top: @border-width__base solid @border-color__base;
+          cursor: pointer;
+          font-weight: @font-weight__semibold;
+          .icon-font(
+          @_icon-font-content: @icon-down,
+          @_icon-font-size: 30px,
+          @_icon-font-position: after,
+          @_icon-font-display: block
+          );
+          margin-bottom: 0;
+          overflow: hidden;
+          padding: 7px @indent__base 7px @indent__xs;
+          position: relative;
+          &:after {
+            position: absolute;
+            right: 0;
+            top: -5px;
+          }
+          strong {
+            .column.main & {
+              .font-size(18);
+              font-weight: @font-weight__regular;
+            }
+          }
         }
-
-        //  Totals block
-        &-totals {
-            border-top: 1px solid @border-color__base;
-            padding-top: 10px;
-            .table-wrapper {
-                overflow: inherit;
-            }
-            .mark {
-                font-weight: @font-weight__regular;
-                padding-left: 4px;
-                strong {
-                    font-weight: @font-weight__regular;
-                }
-            }
-            .amount {
-                padding-right: 4px;
-                text-align: right;
-                strong {
-                    font-weight: @font-weight__regular;
-                }
-            }
-            .grand:last-child {
-                .mark,
-                .amount {
-                    padding-top: @indent__base;
-                }
-                .amount {
-                    padding-right: 4px;
-                    text-align: right;
-                    strong {
-                        font-weight: @font-weight__bold;
-                    }
-                }
-            }
-            .msrp {
-                margin-bottom: @indent__s;
-            }
-            .totals-tax {
-                &-summary {
-                    .mark,
-                    .amount {
-                        border-bottom: @border-width__base solid @border-color__base;
-                        border-top: @border-width__base solid @border-color__base;
-                        cursor: pointer;
-                    }
-                    .amount .price {
-                        .icon-font(
-                        @icon-down,
-                        @_icon-font-size: 30px,
-                        @_icon-font-text-hide: true,
-                        @_icon-font-position: after,
-                        @_icon-font-display: block
-                        );
-                        padding-right: @indent__m;
-                        position: relative;
-                        &:after {
-                            position: absolute;
-                            right: -5px;
-                            top: -12px;
-                        }
-                    }
-                    &.expanded {
-                        .mark,
-                        .amount {
-                            border-bottom: 0;
-                        }
-                        .amount .price {
-                            .icon-font-symbol(
-                            @_icon-font-content: @icon-up,
-                            @_icon-font-position: after
-                            );
-                        }
-                    }
-                }
-                &-details {
-                    border-bottom: @border-width__base solid @border-color__base;
-                    display: none;
-                    &.shown {
-                        display: table-row;
-                    }
-                }
-            }
-            .table-wrapper {
-                margin-bottom: 0;
-            }
-            .table-caption {
-                &:extend(.abs-no-display all);
-            }
+        > .content {
+          display: none;
         }
+        &.active {
+          > .title {
+            .icon-font-symbol(
+            @_icon-font-content: @icon-prev,
+            @_icon-font-position: after
+            );
+          }
+          > .content {
+            display: block;
+          }
+        }
+        .item-options {
+          margin-left: 0;
+        }
+        .fieldset {
+          margin: 15px 0 @indent__m @indent__xs;
+          .field {
+            margin: 0 0 @indent__s;
+            &.note {
+              font-size: @font-size__s;
+            }
+          }
+        }
+        .fieldset {
+          .methods {
+            .field {
+              > .label {
+                display: inline;
+              }
+            }
+          }
+        }
+        .fieldset.estimate {
+          > .legend,
+          > .legend + br {
+            &:extend(.abs-no-display all);
+          }
+        }
+      }
+      .actions-toolbar {
+        > .primary {
+          button {
+            &:extend(.abs-revert-secondary-color all);
+          }
+        }
+      }
+      &:extend(.abs-adjustment-incl-excl-tax all);
+    }
 
-        //  Products table
-        &.table-wrapper {
-            .items {
-                thead + .item {
-                    border-top: @border-width__base solid @border-color__base;
-                }
-                > .item {
-                    border-bottom: @border-width__base solid @border-color__base;
-                    position: relative;
-                }
-            }
-            .col {
-                padding-top: 20px;
-                &.qty {
-                    .input-text {
-                        margin-top: -5px;
-                        &:extend(.abs-input-qty all);
-                    }
-                    .label {
-                        &:extend(.abs-visually-hidden all);
-                    }
-                }
-            }
-            .item {
-                &-actions td {
-                    padding-bottom: @indent__s;
-                    text-align: center;
-                    white-space: normal;
-                }
-                .col {
-                    &.item {
-                        display: block;
-                        min-height: 75px;
-                        padding: @indent__m 0 @indent__s 75px;
-                        position: relative;
-                    }
-                }
-            }
-            .actions-toolbar {
-                &:extend(.abs-add-clearfix all);
-                > .action {
-                    &:extend(button all);
-                    .link-as-button();
-                    margin-bottom: @indent__s;
-                    margin-right: @indent__s;
-                    &:last-child {
-                        margin-right: 0;
-                    }
-                }
-            }
-            .action {
-                &.help.map {
-                    &:extend(.abs-action-button-as-link all);
-                    font-weight: @font-weight__regular;
-                }
-            }
-            .product {
-                &-item-photo {
-                    display: block;
-                    left: 0;
-                    max-width: 60px;
-                    padding: 0;
-                    position: absolute;
-                    top: 15px;
-                    width: 100%;
-                }
-                &-item-details {
-                    white-space: normal;
-                }
-                &-item-name {
-                    display: inline-block;
-                    font-weight: @font-weight__regular;
-                    margin-top: -6px;
-                }
-            }
-            .gift-registry-name-label {
-                &:after {
-                    content: ':';
-                }
-            }
-            //  Product options
-            .item-options {
-                font-size: @font-size__s;
-                margin-bottom: @indent__s;
-                &:extend(.abs-product-options-list all);
-                &:extend(.abs-add-clearfix all);
-            }
-
-            .product-item-name + .item-options {
-                margin-top: @indent__s;
-            }
+    //  Totals block
+    &-totals {
+      border-top: 1px solid @border-color__base;
+      padding-top: 10px;
+      &:extend(.abs-sidebar-totals all);
+      .table-wrapper {
+        margin-bottom: 0;
+        overflow: inherit;
+      }
+    }
 
-            .product-image-wrapper {
-                &:extend(.abs-reset-image-wrapper all);
-            }
-            .action.configure {
-                display: inline-block;
-                margin: 0 0 @indent__base;
-            }
+    //  Products table
+    &.table-wrapper {
+      .items {
+        thead + .item {
+          border-top: @border-width__base solid @border-color__base;
         }
-        &-container {
-            .form-cart {
-                &:extend(.abs-shopping-cart-items all);
-            }
-            .checkout-methods-items {
-                margin-top: @indent__base;
-                &:extend(.abs-reset-list all);
-                text-align: center;
-                .action.primary {
-                    &:extend(.abs-button-l all);
-                    margin-bottom: @indent__s;
-                    width: 100%;
-                }
-            }
+        > .item {
+          border-bottom: @border-width__base solid @border-color__base;
+          position: relative;
         }
-    }
+      }
+      .col {
+        padding-top: 20px;
+        &.qty {
+          .input-text {
+            margin-top: -5px;
+            &:extend(.abs-input-qty all);
+          }
+          .label {
+            &:extend(.abs-visually-hidden all);
+          }
+        }
+      }
+      .item {
+        &-actions td {
+          padding-bottom: @indent__s;
+          text-align: center;
+          white-space: normal;
+        }
+        .col {
+          &.item {
+            display: block;
+            min-height: 75px;
+            padding: @indent__m 0 @indent__s 75px;
+            position: relative;
+          }
+        }
+      }
+      .actions-toolbar {
+        &:extend(.abs-add-clearfix all);
+        > .action {
+          &:extend(button all);
+          .link-as-button();
+          margin-bottom: @indent__s;
+          margin-right: @indent__s;
+          &:last-child {
+            margin-right: 0;
+          }
+        }
+      }
+      .action {
+        &.help.map {
+          &:extend(.abs-action-button-as-link all);
+          font-weight: @font-weight__regular;
+        }
+      }
+      .product {
+        &-item-photo {
+          display: block;
+          left: 0;
+          max-width: 60px;
+          padding: 0;
+          position: absolute;
+          top: 15px;
+          width: 100%;
+        }
+        &-item-details {
+          white-space: normal;
+        }
+        &-item-name {
+          display: inline-block;
+          font-weight: @font-weight__regular;
+          margin-top: -6px;
+        }
+      }
+      .gift-registry-name-label {
+        &:after {
+          content: ':';
+        }
+      }
+      //  Product options
+      .item-options {
+        font-size: @font-size__s;
+        margin-bottom: @indent__s;
+        &:extend(.abs-product-options-list all);
+        &:extend(.abs-add-clearfix all);
+      }
 
-    //
-    //  Cross sell
-    //  ---------------------------------------------
+      .product-item-name + .item-options {
+        margin-top: @indent__s;
+      }
 
-    .block.crosssell {
-        margin-top: 70px;
+      .product-image-wrapper {
+        &:extend(.abs-reset-image-wrapper all);
+      }
+      .action.configure {
+        display: inline-block;
+        margin: 0 0 @indent__base;
+      }
+    }
+    &-container {
+      .form-cart {
+        &:extend(.abs-shopping-cart-items all);
+      }
+      .checkout-methods-items {
+        margin-top: @indent__base;
+        &:extend(.abs-reset-list all);
+        text-align: center;
+        .action.primary {
+          &:extend(.abs-button-l all);
+          margin-bottom: @indent__s;
+          width: 100%;
+        }
+      }
     }
+  }
+
+  //
+  //  Cross sell
+  //  ---------------------------------------------
+
+  .block.crosssell {
+    margin-top: 70px;
+  }
 }
 
 //
@@ -325,48 +246,48 @@
 //  _____________________________________________
 
 .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) {
-    .cart {
-        &.table-wrapper {
-            thead {
-                .col:not(.item) {
-                    display: none;
-                }
-            }
-            .col {
-                &.qty,
-                &.price,
-                &.subtotal,
-                &.msrp {
-                    box-sizing: border-box;
-                    display: block;
-                    float: left;
-                    text-align: center;
-                    white-space: nowrap;
-                    width: 33%;
-                    &:before {
-                        content: attr(data-th) ':';
-                        display: block;
-                        font-weight: @font-weight__bold;
-                        padding-bottom: 10px;
-                    }
-                }
-                &.msrp {
-                    white-space: normal;
-                }
-            }
-            .item .col.item {
-                padding-bottom: 0;
-            }
+  .cart {
+    &.table-wrapper {
+      thead {
+        .col:not(.item) {
+          display: none;
         }
-        &-container {
-            .form-cart {
-                &:extend(.abs-shopping-cart-items-mobile all);
-            }
+      }
+      .col {
+        &.qty,
+        &.price,
+        &.subtotal,
+        &.msrp {
+          box-sizing: border-box;
+          display: block;
+          float: left;
+          text-align: center;
+          white-space: nowrap;
+          width: 33%;
+          &:before {
+            content: attr(data-th) ':';
+            display: block;
+            font-weight: @font-weight__bold;
+            padding-bottom: 10px;
+          }
         }
-        &.table-wrapper {
-            overflow: inherit;
+        &.msrp {
+          white-space: normal;
         }
+      }
+      .item .col.item {
+        padding-bottom: 0;
+      }
+    }
+    &-container {
+      .form-cart {
+        &:extend(.abs-shopping-cart-items-mobile all);
+      }
     }
+    &.table-wrapper {
+      overflow: inherit;
+    }
+  }
 }
 
 //
@@ -374,69 +295,69 @@
 //  _____________________________________________
 
 .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
-    .cart {
-        &-container {
-            &:extend(.abs-add-clearfix-desktop all);
-            .form-cart {
-                &:extend(.abs-shopping-cart-items-desktop all);
-            }
-            .widget {
-                float: left;
-            }
+  .cart {
+    &-container {
+      &:extend(.abs-add-clearfix-desktop all);
+      .form-cart {
+        &:extend(.abs-shopping-cart-items-desktop all);
+      }
+      .widget {
+        float: left;
+      }
+    }
+    &-summary {
+      float: right;
+      position: relative;
+      width: 23%;
+      .actions-toolbar {
+        .column.main & {
+          &:extend(.abs-reset-left-margin-desktop all);
+          > .secondary {
+            float: none;
+          }
         }
-        &-summary {
-            float: right;
-            position: relative;
-            width: 23%;
-            .actions-toolbar {
-                .column.main & {
-                    &:extend(.abs-reset-left-margin-desktop all);
-                    > .secondary {
-                        float: none;
-                    }
-                }
-            }
-            .block {
-                .fieldset {
-                    .field {
-                        .form-field-type-revert(@_type: block);
-                        margin: 0 0 @indent__s;
-                    }
-                }
-            }
+      }
+      .block {
+        .fieldset {
+          .field {
+            .form-field-type-revert(@_type: block);
+            margin: 0 0 @indent__s;
+          }
         }
+      }
+    }
 
-        &.table-wrapper {
-            .item {
-                .col {
-                    &.item {
-                        padding: 27px 8px @indent__s;
-                    }
-                }
-                &-actions td {
-                    text-align: right;
-                }
-            }
-            .product {
-                &-item-photo {
-                    display: table-cell;
-                    max-width: 100%;
-                    padding-right: @indent__base;
-                    position: static;
-                    vertical-align: top;
-                    width: 1%;
-                }
-                &-item-details {
-                    display: table-cell;
-                    vertical-align: top;
-                    white-space: normal;
-                    width: 99%;
-                }
-            }
-            .item-actions .actions-toolbar {
-                text-align: left;
-                &:extend(.abs-reset-left-margin-desktop all);
-            }
+    &.table-wrapper {
+      .item {
+        .col {
+          &.item {
+            padding: 27px 8px @indent__s;
+          }
+        }
+        &-actions td {
+          text-align: right;
+        }
+      }
+      .product {
+        &-item-photo {
+          display: table-cell;
+          max-width: 100%;
+          padding-right: @indent__base;
+          position: static;
+          vertical-align: top;
+          width: 1%;
+        }
+        &-item-details {
+          display: table-cell;
+          vertical-align: top;
+          white-space: normal;
+          width: 99%;
         }
+      }
+      .item-actions .actions-toolbar {
+        text-align: left;
+        &:extend(.abs-reset-left-margin-desktop all);
+      }
     }
+  }
 }
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_checkout.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_checkout.less
new file mode 100644
index 0000000000000000000000000000000000000000..db93ffc7fe3f173d56b45df4318ea789099a0b04
--- /dev/null
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_checkout.less
@@ -0,0 +1,26 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Page components
+//  ---------------------------------------------
+
+@import 'checkout/_checkout.less';
+@import 'checkout/_estimated-total.less';
+@import 'checkout/_progress-bar.less';
+@import 'checkout/_fields.less';
+@import 'checkout/_modals.less';
+@import 'checkout/_tooltip.less';
+@import 'checkout/_shipping.less';
+@import 'checkout/_shipping-policy.less';
+
+@import 'checkout/_sidebar.less';
+@import 'checkout/_sidebar-shipping-information.less';
+@import 'checkout/_order-summary.less';
+@import 'checkout/_authentication.less';
+
+@import 'checkout/_payments.less';
+@import 'checkout/_payment-options.less';
+@import 'checkout/_checkout-agreements.less';
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less
index 535a47ff7f9ee5ddad63365a0f0f07f37b1208c9..317c57334f11c36998d524588599196c5d632184 100644
--- a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/_minicart.less
@@ -5,93 +5,93 @@
 
 //
 //  Variables
-//  ---------------------------------------------
+//  _____________________________________________
 
 @minicart__border-color: @color-gray80;
 @minicart__padding-horizontal: @indent__base;
 
 //
 //  Common
-//  ---------------------------------------------
+//  _____________________________________________
 
 & when (@media-common = true) {
 
-//
-//  Minicart
-//  ---------------------------------------------
+    //
+    //  Minicart
+    //  ---------------------------------------------
 
-.block-minicart {
-    .items-total {
-        float: left;
-        margin: 0 @indent__s;
-        .count {
-            font-weight: @font-weight__bold;
+    .block-minicart {
+        .items-total {
+            float: left;
+            margin: 0 @indent__s;
+            .count {
+                font-weight: @font-weight__bold;
+            }
         }
-    }
-    .subtotal {
-        margin: 0 @indent__s;
-        text-align: right;
-        .label {
-            &:extend(.abs-colon all);
+        .subtotal {
+            margin: 0 @indent__s;
+            text-align: right;
+            .label {
+                &:extend(.abs-colon all);
+            }
         }
-    }
-    .amount {
-        .price-wrapper {
-            &:first-child {
-                .price {
-                    font-size: @font-size__l;
-                    font-weight: @font-weight__bold;
+        .amount {
+            .price-wrapper {
+                &:first-child {
+                    .price {
+                        font-size: @font-size__l;
+                        font-weight: @font-weight__bold;
+                    }
                 }
             }
         }
-    }
-    .subtitle {
-        display: none;
-    }
-    .subtitle {
-        &.empty {
-            display: block;
-            padding: @indent__l 0 @indent__base;
-            text-align: center;
-            font-size: 14px;
+        .subtitle {
+            display: none;
         }
-    }
-    .text {
-        &.empty {
-            text-align: center;
+        .subtitle {
+            &.empty {
+                display: block;
+                font-size: 14px;
+                padding: @indent__l 0 @indent__base;
+                text-align: center;
+            }
         }
-    }
-    .block-content {
-        > .actions {
-            margin-top: 15px;
-            text-align: center;
-            > .primary {
-                margin: 0 @indent__s 15px;
-                .action {
-                    &.primary {
-                        &:extend(.abs-button-l all);
-                        display: block;
-                        width: 100%;
-                        margin-bottom: 15px;
-                        &:last-child {
-                            margin-bottom: 0;
+        .text {
+            &.empty {
+                text-align: center;
+            }
+        }
+        .block-content {
+            > .actions {
+                margin-top: 15px;
+                text-align: center;
+                > .primary {
+                    margin: 0 @indent__s 15px;
+                    .action {
+                        &.primary {
+                            &:extend(.abs-button-l all);
+                            display: block;
+                            margin-bottom: 15px;
+                            width: 100%;
+                            &:last-child {
+                                margin-bottom: 0;
+                            }
                         }
                     }
                 }
             }
         }
+        .block-category-link,
+        .block-product-link,
+        .block-cms-link,
+        .block-banners {
+            margin: 15px 0 0;
+            text-align: center;
+        }
     }
-    .block-category-link,
-    .block-product-link,
-    .block-cms-link,
-    .block-banners {
-        margin: 15px 0 0;
-        text-align: center;
-    }
-}
 
-.minicart-wrapper {
-    .dropdown(
+    .minicart-wrapper {
+        .dropdown(
         @_toggle-selector: ~".action.showcart",
         @_options-selector: ~".block-minicart",
         @_dropdown-toggle-icon-content: @icon-cart,
@@ -104,200 +104,229 @@
         @_icon-font-color: @minicart-icons-color,
         @_icon-font-color-hover: @minicart-icons-color-hover,
         @_icon-font-color-active: @minicart-icons-color
-    );
-    float: right;
-    .block-minicart {
-        .css(padding, 25px @minicart__padding-horizontal);
-        right: 0;
-        width: 320px;
-        .block-title {
-            display: none;
-        }
-        &:after {
-            left: auto;
-            right: 25px;
-        }
-        &:before {
-            left: auto;
-            right: 26px;
+        );
+        float: right;
+        .block-minicart {
+            .css(padding, 25px @minicart__padding-horizontal);
+            right: 0;
+            width: 320px;
+            .block-title {
+                display: none;
+            }
+            &:after {
+                left: auto;
+                right: 25px;
+            }
+            &:before {
+                left: auto;
+                right: 26px;
+            }
         }
-    }
-    .product.actions {
-        text-align: right;
-        > .primary,
-        > .secondary {
-            display: inline;
+        .product.actions {
+            text-align: right;
+            > .primary, > .secondary {
+                display: inline;
+            }
         }
-    }
 
-    .action {
-        &.close {
-            width: 40px;
-            height: 40px;
-            top: 0;
-            right: 0;
-            position: absolute;
-            .button-reset();
-            .button-icon(
+        .action {
+            &.close {
+                .button-icon(
                 @icon-remove,
                 @_icon-font-size: 32px,
                 @_icon-font-line-height: 32px,
                 @_icon-font-text-hide: true
-            );
-        }
-        &.showcart {
-            .text {
-                &:extend(.abs-visually-hidden all);
+                );
+                .button-reset();
+                height: 40px;
+                position: absolute;
+                right: 0;
+                top: 0;
+                width: 40px;
             }
-            white-space: nowrap;
-            .counter.qty {
-                &.empty {
-                   display: none;
+            &.showcart {
+                white-space: nowrap;
+                .text {
+                    &:extend(.abs-visually-hidden all);
+                }
+                .counter.qty {
+                    border-radius: 2px;
+                    clip: none;
+                    .css(color, @page__background-color);
+                    .css(background, @active__color);
+                    display: inline-block;
+                    height: 24px;
+                    line-height: 24px;
+                    margin: 3px 0 0;
+                    min-width: 18px;
+                    overflow: hidden;
+                    padding: 0 3px;
+                    text-align: center;
+                    white-space: normal;
+                    &.empty {
+                        &:extend(.abs-no-display all);
+                    }
+                }
+                .counter-label {
+                    &:extend(.abs-visually-hidden all);
                 }
-                .css(background, @active__color);
-                border-radius: 2px;
-                .css(color, @page__background-color);
-                clip: none;
-                display: inline-block;
-                height: 24px;
-                line-height: 24px;
-                min-width: 18px;
-                margin: 3px 0 0;
-                padding: 0 3px;
-                overflow: hidden;
-                text-align: center;
-                white-space: normal;
-            }
-            .counter-label {
-                &:extend(.abs-visually-hidden all);
             }
         }
+        .minicart-widgets {
+            margin-top: 15px;
+        }
     }
-    .minicart-widgets {
-        margin-top: 15px;
-    }
-}
 
-.minicart-items-wrapper {
-    .css(border, 1px solid @minicart__border-color);
-    .css(margin, 0 -@minicart__padding-horizontal);
-    border-left: 0;
-    border-right: 0;
-    overflow-x: auto;
-    padding: 15px;
-}
+    .minicart-items-wrapper {
+        border-left: 0;
+        border-right: 0;
+        .css(margin, 0 -@minicart__padding-horizontal);
+        .css(border, 1px solid @minicart__border-color);
+        overflow-x: auto;
+        padding: 15px;
+    }
 
-.minicart-items {
-    .list-reset-styles(0, 0);
-    .item {
-        &:not(:first-child) {
-            .css(border-top, 1px solid @minicart__border-color);
-        }
-        padding: @indent__base 0;
-        &:first-child {
-            padding-top: 0;
+    .minicart-items {
+        .list-reset-styles(0, 0);
+        .product-item {
+            padding: @indent__base 0;
+            &:not(:first-child) {
+                .css(border-top, 1px solid @minicart__border-color);
+            }
+            &:first-child {
+                padding-top: 0;
+            }
+            > .product {
+                &:extend(.abs-add-clearfix all);
+            }
         }
-        > .product {
-            &:extend(.abs-add-clearfix all);
+        .product-image-wrapper {
+            &:extend(.abs-reset-image-wrapper all);
         }
-    }
-    .product-image-wrapper {
-        &:extend(.abs-reset-image-wrapper all);
-    }
-    .product-item-pricing {
-        .label {
-            display: inline-block;
-            width: 4.5rem;
-         }
-    }
-    .price-minicart {
-        margin-bottom: @indent__xs;
-    }
-    .product-item-photo {
-        float: left;
-    }
-    .product-item-name {
-        font-weight: @font-weight__regular;
-        margin: 0 0 @indent__s;
-        a {
-            .css(color, @link__color);
+        .product-item-pricing {
+            .label {
+                display: inline-block;
+                width: 4.5rem;
+            }
         }
-    }
-    .product-item-details {
-        padding-left: 88px;
-        .price {
-            font-weight: @font-weight__bold;
+        .price-minicart {
+            margin-bottom: @indent__xs;
         }
-        .price-including-tax,
-        .price-excluding-tax {
-            margin: @indent__xs 0;
+        .product {
+            > .product-item-photo,
+            > .product-image-container {
+                float: left;
+            }
+            .toggle {
+                .icon-font(
+                @_icon-font-content: @icon-down,
+                @_icon-font-size: 28px,
+                @_icon-font-line-height: 16px,
+                @_icon-font-text-hide: false,
+                @_icon-font-position: after,
+                @_icon-font-display: block
+                );
+                cursor: pointer;
+                position: relative;
+                &:after {
+                    position: static;
+                    right: @indent__base;
+                    top: 0;
+                }
+            }
+            &.active {
+                > .toggle {
+                    .icon-font-symbol(
+                    @_icon-font-content: @icon-up,
+                    @_icon-font-position: after
+                    );
+                }
+            }
         }
-        .weee[data-label] {
-            .font-size(11);
-            .label {
-                &:extend(.abs-no-display all);
+        .product-item-name {
+            font-weight: @font-weight__regular;
+            margin: 0 0 @indent__s;
+            a {
+                .css(color, @link__color);
             }
         }
-        .details-qty {
-            margin-top: @indent__s;
+        .product-item-details {
+            padding-left: 88px;
+            .price {
+                font-weight: @font-weight__bold;
+            }
+            .price-including-tax,
+            .price-excluding-tax {
+                margin: @indent__xs 0 0;
+            }
+            .weee[data-label] {
+                .font-size(11);
+                .label {
+                    &:extend(.abs-no-display all);
+                }
+            }
+            .details-qty {
+                margin-top: @indent__s;
+            }
         }
-    }
-    .product.options {
-        .tooltip.toggle {
-            .icon-font(
+        .product.options {
+            .tooltip.toggle {
+                .icon-font(
                 @icon-down,
                 @_icon-font-size: 28px,
                 @_icon-font-line-height: 28px,
                 @_icon-font-text-hide: true,
                 @_icon-font-margin: -3px 0 0 7px,
                 @_icon-font-position: after
-            );
-            .details {
-                display: none;
+                );
+                .details {
+                    display: none;
+                }
             }
         }
-    }
-    .details-qty,
-    .price-minicart {
-        .label {
-            &:extend(.abs-colon all);
+        .details-qty,
+        .price-minicart {
+            .label {
+                &:extend(.abs-colon all);
+            }
+        }
+        .item-qty {
+            margin-right: @indent__s;
+            text-align: center;
+            width: 40px;
+        }
+        .item-update {
+            .font-size(11);
+            vertical-align: top;
+        }
+        .subtitle {
+            &:extend(.abs-no-display all);
+        }
+        .action {
+            &.edit,
+            &.delete {
+                .icon-font(
+                @icon-settings,
+                @_icon-font-size: 28px,
+                @_icon-font-line-height: 28px,
+                @_icon-font-text-hide: true,
+                @_icon-font-color: @color-gray19,
+                @_icon-font-color-hover: @color-gray19,
+                @_icon-font-color-active: @color-gray19
+                );
+            }
+            &.delete {
+                .icon-font-symbol(
+                @_icon-font-content: @icon-trash
+                );
+            }
         }
     }
-    .item-qty {
-        width: 40px;
-        text-align: center;
-        margin-right: @indent__s;
-    }
-    .item-update {
-        vertical-align: top;
-        .font-size(11);
-    }
-    .action {
-         &.edit,
-         &.delete {
-             .icon-font(
-                 @icon-settings,
-                 @_icon-font-size: 28px,
-                 @_icon-font-line-height: 28px,
-                 @_icon-font-text-hide: true,
-                 @_icon-font-color: @color-gray19,
-                 @_icon-font-color-hover: @color-gray19,
-                 @_icon-font-color-active: @color-gray19
-             );
-         }
-         &.delete {
-             .icon-font-symbol(
-                 @_icon-font-content: @icon-trash
-             );
-         }
-    }
-}
-
 }
 
 //
 //  Mobile
-//  ---------------------------------------------
+//  _____________________________________________
 
 .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__xs) {
     .minicart-wrapper .block-minicart {
@@ -313,7 +342,7 @@
 
 //
 //  Desktop
-//  ---------------------------------------------
+//  _____________________________________________
 
 .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
     .minicart-wrapper {
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_authentication.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_authentication.less
new file mode 100644
index 0000000000000000000000000000000000000000..26c1ac83c04217bc2ad84483a5ec3b608cecf4ae
--- /dev/null
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_authentication.less
@@ -0,0 +1,196 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+@block-auth__dropdown__padding: @indent__m;
+@block-auth__dropdown__background-color: @color-white;
+@block-auth__or-label__size: 36px;
+@block-auth__width: 0;
+@block-auth__border: 1px solid @color-gray-light3;
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+    .authentication-dropdown {
+        box-sizing: border-box;
+        .modal-inner-wrap {
+            padding: @block-auth__dropdown__padding;
+        }
+    }
+    .authentication-wrapper {
+        float: right;
+        margin-top: -1.5*@indent__xl;
+        max-width: 50%;
+        position: relative;
+        z-index: 1;
+        ._has-auth-shown & {
+            z-index: @modal__z-index;
+        }
+    }
+    .action-auth-toggle {
+        &:extend(.abs-action-button-as-link all);
+    }
+    .block-authentication {
+        .block-title {
+            .font-size(@h3__font-size);
+            border-bottom: 0;
+            margin-bottom: @indent__m;
+            strong {
+                font-weight: @font-weight__light;
+            }
+        }
+        .field {
+            .label {
+                font-weight: @font-weight__regular;
+            }
+        }
+        .actions-toolbar {
+            margin-bottom: @indent__xs;
+            > .secondary {
+                padding-top: @indent__m;
+                text-align: left;
+            }
+        }
+        .action.action-register,
+        .action.action-login {
+            &:extend(.abs-button-l all);
+        }
+        .block[class] {
+            margin: 0;
+            ul {
+                list-style: none;
+                padding-left: @indent__s;
+            }
+            .field {
+                .control,
+                .label {
+                    float: none;
+                    width: auto;
+                }
+            }
+            & + .block {
+                border-top: 1px solid @color-gray-light5;
+                margin-top: @indent__xl;
+                padding-top: @indent__xl;
+                position: relative;
+                &::before {
+                    .css(height, @block-auth__or-label__size);
+                    .css(line-height, @block-auth__or-label__size - 2px);
+                    .css(margin, -(@block-auth__or-label__size/2 + 1px) 0 0 -(@block-auth__or-label__size / 2));
+                    .css(min-width, @block-auth__or-label__size);
+                    background: @color-white;
+                    border-radius: 50%;
+                    border: 1px solid @color-gray-light5;
+                    box-sizing: border-box;
+                    color: @color-gray-light5;
+                    content: attr(data-label);
+                    display: inline-block;
+                    left: 50%;
+                    letter-spacing: normal;
+                    padding: 0 .2rem;
+                    position: absolute;
+                    text-align: center;
+                    text-transform: uppercase;
+                    top: 0;
+                }
+            }
+        }
+    }
+}
+
+//
+//  Desktop
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
+    .authentication-dropdown {
+        .css(background-color, @block-auth__dropdown__background-color);
+        .css(border, @block-auth__border);
+        position: absolute;
+        text-align: left;
+        top: 100%;
+        transform-origin: 0 0;
+        transform: scale(1,0);
+        transition: transform linear .1s, visibility 0s linear .1s;
+        visibility: hidden;
+        width: 100%;
+        &._show {
+            .css(z-index, @dropdown-list__z-index);
+            transform: scale(1,1);
+            transition: transform linear .1s, visibility 0s linear 0s;
+            visibility: visible;
+        }
+    }
+    .authentication-wrapper {
+        .column-width(@checkout-sidebar__columns);
+        text-align: right;
+    }
+    .block-authentication {
+        .block-title {
+            .font-size(@h2__font-size);
+            border-bottom: 0;
+            margin-bottom: @indent__m;
+        }
+        .actions-toolbar {
+            > .primary {
+                display: inline;
+                float: right;
+                margin-right: 0;
+                .action {
+                    margin-right: 0;
+                }
+            }
+            > .secondary {
+                float: left;
+                margin-right: 2rem;
+                padding-top: 1rem;
+            }
+        }
+    }
+    .popup-authentication {
+        .modal-inner-wrap {
+            min-width: @screen__m;
+            width: 60%;
+        }
+        .block-authentication {
+            .vendor-prefix-display(flex);
+            .vendor-prefix-flex-direction(row);
+            border-top: 1px solid @color-gray-light5;
+        }
+        .block[class],
+        .form-login,
+        .fieldset,
+        .block-content {
+            .vendor-prefix-display(flex);
+            .vendor-prefix-flex-direction(column);
+            .vendor-prefix-flex-grow(1);
+        }
+        .block[class] {
+            box-sizing: border-box;
+            float: left;
+            padding: @indent__s @indent__l 0 0;
+            width: 50%;
+            & + .block {
+                border-left: 1px solid @color-gray-light5;
+                border-top: 0;
+                margin: 0;
+                padding: @indent__s 0 0 @indent__xl;
+                &::before {
+                    left: 0;
+                    top: 50%;
+                }
+            }
+        }
+        .actions-toolbar {
+            margin-bottom: 0;
+            margin-top: auto;
+        }
+    }
+}
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_checkout-agreements.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_checkout-agreements.less
new file mode 100644
index 0000000000000000000000000000000000000000..02fbbeb1faa431e4056b78be1daf0cd0c90cffdd
--- /dev/null
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_checkout-agreements.less
@@ -0,0 +1,34 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+    .checkout-agreements-block {
+        margin-bottom: @indent__base;
+
+        .action-show {
+            &:extend(.abs-action-button-as-link all);
+            vertical-align: baseline;
+        }
+    }
+
+    // Checkout Agreements in popup
+    .checkout-agreements-items {
+        &:extend(.abs-reset-list all);
+        padding-bottom: @indent__l;
+
+        .checkout-agreements-item {
+            margin-bottom: @indent__base;
+        }
+
+        .checkout-agreements-item-title {
+            &:extend(.abs-checkout-title all);
+            border-bottom: 0;
+        }
+    }
+}
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_checkout.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_checkout.less
new file mode 100644
index 0000000000000000000000000000000000000000..6fcaedd24084e3c230ab32cb01186949bfc06b0e
--- /dev/null
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_checkout.less
@@ -0,0 +1,86 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+@checkout-wrapper__margin: @indent__base;
+@checkout-wrapper__columns: 8;
+
+@checkout-step-title__border: @border-width__base solid @color-gray80;
+@checkout-step-title__font-size: 26px;
+@checkout-step-title__font-weight: @font-weight__light;
+@checkout-step-title__margin-bottom: 28px;
+@checkout-step-title__padding: @indent__s;
+
+@checkout-step-title-mobile__font-size: 18px;
+@checkout-step-title-mobile__margin-bottom: @indent__base;
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+
+    .checkout-container {
+        &:extend(.abs-add-clearfix all);
+        .css(margin, 0 0 @checkout-wrapper__margin);
+    }
+
+    .opc-wrapper {
+        .css(margin, 0 0 @checkout-wrapper__margin);
+
+        .opc {
+            &:extend(.abs-reset-list all);
+        }
+
+        .step-title {
+            &:extend(.abs-checkout-title all);
+            .css(margin, 0 0 @checkout-step-title__margin-bottom);
+        }
+
+        .step-content {
+            margin: 0 0 @indent__xl;
+        }
+    }
+
+    .checkout-onepage-index {
+        .nav-sections,
+        .nav-toggle {
+            display: none;
+        }
+        .logo {
+            margin-left: 0;
+        }
+    }
+}
+
+//
+//  Mobile
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) {
+    .opc-wrapper {
+        .step-title {
+            .css(font-size, @checkout-step-title-mobile__font-size);
+            .css(margin-bottom, @checkout-step-title-mobile__margin-bottom);
+            border-bottom: 0;
+            padding-bottom: 0;
+        }
+    }
+}
+
+//
+//  Desktop
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
+    .opc-wrapper {
+        &:extend(.abs-add-box-sizing-desktop-m all);
+        .layout-column(2, 1, @checkout-wrapper__columns);
+        padding-right: @indent__l;
+    }
+}
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_estimated-total.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_estimated-total.less
new file mode 100644
index 0000000000000000000000000000000000000000..5119231620d6ee172e9906402baedc181b3f77fd
--- /dev/null
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_estimated-total.less
@@ -0,0 +1,54 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+
+    //
+    //  Checkout Estimated Total
+    //  ---------------------------------------------
+
+    .opc-estimated-wrapper {
+        &:extend(.abs-add-clearfix all);
+        &:extend(.abs-no-display-desktop all);
+        .css(border-bottom, @border-width__base solid @color-gray80);
+        margin: 0 0 15px;
+        padding: 18px 15px;
+
+        .estimated-block {
+            .css(font-size, @checkout-step-title-mobile__font-size);
+            .css(font-weight, @font-weight__bold);
+            float: left;
+
+            .estimated-label {
+                margin: 0 0 @indent__xs;
+                display: block;
+            }
+        }
+
+        .minicart-wrapper {
+            .action {
+                &.showcart {
+                    &:before {
+                        .css(color, @primary__color);
+                    }
+                }
+            }
+        }
+    }
+}
+
+//
+//  Desktop
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__s) {
+    .opc-estimated-wrapper {
+        display: none;
+    }
+}
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_fields.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_fields.less
new file mode 100644
index 0000000000000000000000000000000000000000..17fd35ed14fc6f2229338e1bd568d7ee0dcdfdde
--- /dev/null
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_fields.less
@@ -0,0 +1,33 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+@checkout-field-validation__border-color: @form-element-validation__border-error;
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+    .field {
+        .control {
+            &._with-tooltip {
+                &:extend(.abs-field-tooltip all);
+            }
+        }
+        &._error {
+            .control {
+                input,
+                select,
+                textarea {
+                    .css(border-color, @checkout-field-validation__border-color);
+                }
+            }
+        }
+    }
+}
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_modals.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_modals.less
new file mode 100644
index 0000000000000000000000000000000000000000..a11423841e94f407b735e34095037f10978ce784
--- /dev/null
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_modals.less
@@ -0,0 +1,61 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+@checkout-modal-popup__width: 800px;
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+    .checkout-onepage-index {
+        .modal-popup {
+            .field-tooltip {
+                .field-tooltip-content {
+                    &:extend(.abs-checkout-tooltip-content-position-top all);
+                }
+            }
+        }
+    }
+}
+
+//
+//  Desktop
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
+    .checkout-onepage-index {
+        .modal-popup {
+            .form-shipping-address {
+                .css(max-width, @checkout-shipping-address__max-width);
+            }
+            .modal-footer {
+                .action-save-address {
+                    float: right;
+                    margin: 0 0 0 @indent__s;
+                }
+                .action-hide-popup {
+                    &:extend(.abs-action-button-as-link all);
+                }
+            }
+        }
+    }
+}
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__l) {
+    .checkout-onepage-index {
+        .modal-popup {
+            .modal-inner-wrap {
+                .css(margin-left, -(@checkout-modal-popup__width/2));
+                .css(width, @checkout-modal-popup__width);
+                left: 50%;
+            }
+        }
+    }
+}
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_order-summary.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_order-summary.less
new file mode 100644
index 0000000000000000000000000000000000000000..0cc46910745bc2c366c049f1fa689ca0c6a7c0e5
--- /dev/null
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_order-summary.less
@@ -0,0 +1,171 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+@checkout-summary__background-color: @color-white-smoke;
+@checkout-summary__padding: 22px @indent__l;
+
+@checkout-summary-title__margin: @indent__s;
+@checkout-summary-mark-value__color: @color-gray60;
+
+@checkout-summary-items__max-height: 370px;
+@checkout-summary-items__padding: 15px;
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+
+    //
+    //  Order Summary
+    //  ---------------------------------------------
+
+    .opc-block-summary {
+        &:extend(.abs-add-box-sizing all);
+        .css(background, @checkout-summary__background-color);
+        .css(padding, @checkout-summary__padding);
+        margin: 0 0 @indent__base;
+
+        > .title {
+            &:extend(.abs-checkout-title all);
+            display: block;
+        }
+
+        //  Totals table
+        .table-totals {
+            &:extend(.abs-sidebar-totals all);
+        }
+
+        .mark {
+            .value {
+                .css(color, @checkout-summary-mark-value__color);
+                display: block;
+            }
+        }
+
+        .grand.incl {
+            & + .grand.excl {
+                .mark,
+                .amount {
+                    border-top: 0;
+                    .font-size(14);
+                    padding-top: 0;
+                    strong {
+                        font-weight: @font-weight__regular;
+                    }
+                }
+            }
+        }
+
+        .not-calculated {
+            font-style: italic;
+        }
+
+        //
+        //  Items list
+        //  ---------------------------------------------
+
+        //  Block title
+        .items-in-cart {
+            > .title {
+                border-bottom: @border-width__base solid @border-color__base;
+                .css(padding, @indent__s @indent__xl @indent__s 0);
+                cursor: pointer;
+                .icon-font(
+                @icon-down,
+                @_icon-font-size: 30px,
+                @_icon-font-line-height: 12px,
+                @_icon-font-text-hide: true,
+                @_icon-font-margin: 3px 0 0,
+                @_icon-font-position: after,
+                @_icon-font-display: block
+                );
+                margin-bottom: 0;
+                position: relative;
+                &:after {
+                    position: absolute;
+                    right: 0;
+                    top: @indent__s;
+                }
+                strong {
+                    .font-size(18);
+                    font-weight: @font-weight__light;
+                    margin: 0;
+                }
+            }
+            &.active {
+                > .title {
+                    .icon-font-symbol(
+                    @_icon-font-content: @icon-up,
+                    @_icon-font-position: after
+                    );
+                }
+            }
+            .product {
+                position: relative;
+            }
+        }
+
+        //  Cart items
+        .minicart-items-wrapper {
+            .css(margin, 0 -(@checkout-summary-items__padding) 0 0);
+            .css(max-height, @checkout-summary-items__max-height);
+            .css(padding, @checkout-summary-items__padding @checkout-summary-items__padding 0 0);
+            border: 0;
+        }
+        .column.main & {
+            .product-item {
+                margin: 0;
+                padding-left: 0;
+            }
+        }
+        .product-item {
+            .product-item-inner {
+                display: table;
+                margin: 0 0 @indent__s;
+                width: 100%;
+            }
+            .product-item-name-block {
+                display: table-cell;
+                padding-right: @indent__xs;
+                text-align: left;
+            }
+            .subtotal {
+                display: table-cell;
+                text-align: right;
+            }
+            .price {
+                .font-size(16);
+                font-weight: @font-weight__regular;
+            }
+            .price-including-tax {
+                & + .price-excluding-tax {
+                    margin: 0;
+                    .price {
+                        .font-size(10);
+                    }
+                }
+            }
+        }
+    }
+}
+
+//
+//  Desktop
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
+    .opc-summary-wrapper {
+        .modal-header {
+            .action-close {
+                display: none;
+            }
+        }
+    }
+}
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payment-options.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payment-options.less
new file mode 100644
index 0000000000000000000000000000000000000000..c9741c735bbf296c192f285242f05704190b1515
--- /dev/null
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payment-options.less
@@ -0,0 +1,139 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+@checkout-payment-option-title__border: @checkout-payment-method-title__border;
+@checkout-payment-option-title__color: @link__color;
+@checkout-payment-option-title__padding: @checkout-payment-method-title__padding;
+@checkout-payment-option-title-mobile__padding: @checkout-payment-method-title-mobile__padding;
+
+@checkout-payment-option-title-icon__font-size: 32px;
+@checkout-payment-option-title-icon__line-height: 16px;
+@checkout-payment-option-title-icon__margin: 0;
+@checkout-payment-option-title-icon__color: @minicart-icons-color;
+@checkout-payment-option-title-icon__hover__color: @primary__color;
+
+@checkout-payment-option-content__padding__xl: @checkout-payment-method-content__padding__xl;
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+    .checkout-payment-method {
+        .payment-option {
+            &._active {
+                .payment-option-title {
+                    .action-toggle {
+                        &:after {
+                            content: @icon-up;
+                        }
+                    }
+                }
+            }
+            &._collapsible {
+                .payment-option-title {
+                    cursor: pointer;
+                }
+                .payment-option-content {
+                    display: none;
+                }
+            }
+        }
+
+        .payment-option-title {
+            .css(border-top, @checkout-payment-option-title__border);
+            .css(padding, @checkout-payment-option-title__padding 0);
+
+            .action-toggle {
+                .css(color, @checkout-payment-option-title__color);
+                .icon-font(
+                    @icon-down,
+                    @_icon-font-size: @checkout-payment-option-title-icon__font-size,
+                    @_icon-font-line-height: @checkout-payment-option-title-icon__line-height,
+                    @_icon-font-color: @checkout-payment-option-title-icon__color,
+                    @_icon-font-color-hover: @checkout-payment-option-title-icon__hover__color,
+                    @_icon-font-color-active: @checkout-payment-option-title-icon__color,
+                    @_icon-font-margin: @checkout-payment-option-title-icon__margin,
+                    @_icon-font-position: after
+                );
+            }
+        }
+
+        .payment-option-content {
+            .css(padding, 0 0 @indent__base @checkout-payment-option-content__padding__xl);
+        }
+
+        .payment-option-inner {
+            margin: 0 0 @indent__base;
+        }
+
+        .credit-card-types {
+            padding: 0;
+            .item {
+                display: inline-block;
+                list-style: none;
+                margin: 0 @indent__xs 0 0;
+                &._active {
+                    font-weight: @font-weight__bold;
+                    img {
+                        -webkit-filter: grayscale(0%);
+                        filter: grayscale(0%);
+                        filter: none;
+                    }
+                }
+            }
+            img {
+                -webkit-filter: grayscale(100%); // For Webkit browsers
+                -webkit-transition: all .6s ease; // Fade to color for Chrome and Safari
+                filter: grayscale(100%);
+                filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale"); // Firefox 10+, Firefox on Android
+                filter: gray; // For IE 6 - 9
+            }
+        }
+    }
+}
+
+//
+//  Mobile
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) {
+    .checkout-payment-method {
+        .payment-option {
+            .css(margin, 0 -(@checkout-payment-option-title-mobile__padding));
+
+            .payment-option-title {
+                .css(padding, @checkout-payment-option-title-mobile__padding)
+            }
+
+            .payment-option-content {
+                .css(padding, 0 @checkout-payment-option-title-mobile__padding @indent__base);
+            }
+        }
+    }
+}
+
+//
+//  Desktop
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
+    .checkout-payment-method {
+        .payment-option-title {
+            .css(padding-left, @checkout-payment-option-content__padding__xl);
+        }
+        .payment-option-content {
+            .payment-option-inner {
+                + .actions-toolbar {
+                    margin-left: 0;
+                }
+            }
+        }
+    }
+}
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
new file mode 100644
index 0000000000000000000000000000000000000000..b880027e5493df788807dbbeabfaa94d0c36fb0b
--- /dev/null
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payments.less
@@ -0,0 +1,198 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+@checkout-payment-method-title__border: @checkout-shipping-method__border;
+@checkout-payment-method-title__padding: @checkout-shipping-method__padding;
+@checkout-payment-method-title-mobile__padding: 15px;
+
+@checkout-payment-method-content__padding__xl: 22px;
+
+@checkout-billing-address-details__line-height: 27px;
+@checkout-billing-address-details__padding: 0 0 0 23px;
+@checkout-billing-address-form__max-width: @checkout-shipping-address__max-width;
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+    .checkout-payment-method {
+        .step-title {
+            margin-bottom: 0;
+        }
+        .payment-method {
+            &:first-child {
+                .payment-method-title {
+                    border-top: 0;
+                }
+            }
+            &._active {
+                .payment-method-content {
+                    display: block;
+                }
+            }
+            .action {
+                &.primary {
+                    &:extend(.abs-button-l all);
+                }
+            }
+        }
+
+        .payment-method-title {
+            .css(border-top, @checkout-payment-method-title__border);
+            .css(padding, @checkout-payment-method-title__padding 0);
+            margin: 0;
+
+            .payment-icon {
+                display: inline-block;
+                margin-right: @indent__xs;
+                vertical-align: middle;
+            }
+
+            .action-help {
+                display: inline-block;
+                margin-left: @indent__xs;
+            }
+        }
+
+        .payment-method-content {
+            display: none;
+            .css(padding, 0 0 @indent__base @checkout-payment-method-content__padding__xl);
+            .fieldset {
+                &:not(:last-child) {
+                    margin: 0 0 @indent__base;
+                }
+                > .field {
+                    margin: 0 0 @indent__base;
+                }
+            }
+        }
+
+        .field-select-billing,
+        .billing-address-form {
+            .css(max-width, @checkout-billing-address-form__max-width);
+        }
+
+        .billing-address-same-as-shipping-block {
+            margin: 0 0 @indent__s;
+        }
+
+        .payment-method-billing-address {
+            margin: 0 0 @indent__base;
+
+            .primary {
+                .action-update {
+                    margin-right: 0;
+                }
+            }
+
+            .action-cancel {
+                &:extend(.abs-action-button-as-link all);
+            }
+
+            .billing-address-details {
+                .css(line-height, @checkout-billing-address-details__line-height);
+                .css(padding, @checkout-billing-address-details__padding);
+
+                .action-edit-address {
+                    &:extend(.abs-action-button-as-link all);
+                }
+            }
+        }
+
+        .payment-method-note {
+            & + .payment-method-billing-address {
+                margin-top: @indent__base;
+            }
+        }
+
+        .field-select-billing {
+            > .label {
+                &:extend(.abs-visually-hidden all);
+            }
+        }
+        .payment-method-iframe {
+            background-color: transparent;
+            display: none;
+            width: 100%;
+        }
+        .no-payments-block {
+            margin: @indent__base 0;
+        }
+        .ccard {
+            .legend {
+                &:extend(.abs-visually-hidden all);
+            }
+            .year {
+                padding-left: @indent__l;
+            }
+        }
+    }
+}
+
+//
+//  Mobile
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) {
+    .checkout-payment-method {
+        .payment-methods {
+            .css(margin, 0 -(@checkout-payment-method-title-mobile__padding));
+        }
+
+        .payment-method-title {
+            .css(padding, @checkout-payment-method-title-mobile__padding)
+        }
+
+        .payment-method-content {
+            .css(padding, 0 @checkout-payment-method-title-mobile__padding @indent__base);
+        }
+
+        .payment-method-billing-address {
+            .action-cancel {
+                margin-top: @indent__s;
+            }
+        }
+    }
+}
+
+//
+//  Desktop
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
+    .checkout-payment-method {
+        .payment-methods {
+            .actions-toolbar {
+                .primary {
+                    float: right;
+                    margin: 0;
+                }
+            }
+        }
+        .fieldset {
+            > .field-select-billing {
+                > .control {
+                    float: none;
+                    width: 100%;
+                }
+            }
+        }
+    }
+    .payment-method-billing-address {
+        .action-update {
+            float: right;
+        }
+        .actions-toolbar {
+            .action-cancel {
+                margin: 6px @indent__base 0 0;
+            }
+        }
+    }
+}
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_progress-bar.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_progress-bar.less
new file mode 100644
index 0000000000000000000000000000000000000000..386889c75d410cd854fbced42f136d0ce4bb0dd8
--- /dev/null
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_progress-bar.less
@@ -0,0 +1,169 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+@checkout-progress-bar__font-size: 18px;
+@checkout-progress-bar__font-weight: @font-weight__light;
+@checkout-progress-bar__margin: @indent__base;
+
+@checkout-progress-bar-item__background-color: @color-gray-middle1;
+@checkout-progress-bar-item__border-radius: 6px;
+@checkout-progress-bar-item__color: @primary__color;
+@checkout-progress-bar-item__margin: @indent__s;
+@checkout-progress-bar-item__width: 185px;
+@checkout-progress-bar-item__active__background-color: @color-orange-red1;
+@checkout-progress-bar-item__complete__color: @link__color;
+
+@checkout-progress-bar-item-element__height: @checkout-progress-bar-item-element__width;
+@checkout-progress-bar-item-element__width: 38px;
+
+@checkout-progress-bar-item-element-inner__background-color: @page__background-color;
+@checkout-progress-bar-item-element-inner__color: @checkout-progress-bar-item__color;
+@checkout-progress-bar-item-element-inner__height: @checkout-progress-bar-item-element-inner__width;
+@checkout-progress-bar-item-element-inner__width: @checkout-progress-bar-item-element__width - (@checkout-progress-bar-item-element-outer-radius__width * 2);
+@checkout-progress-bar-item-element-inner__active__content: @icon-checkmark;
+@checkout-progress-bar-item-element-inner__active__font-size: 28px;
+@checkout-progress-bar-item-element-inner__active__line-height: 1;
+
+@checkout-progress-bar-item-element-outer-radius__width: 6px;
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+
+    //
+    //  Checkout Progress Bar
+    //  ---------------------------------------------
+
+    .opc-progress-bar {
+        &:extend(.abs-reset-list all);
+        .css(margin, 0 0 @checkout-progress-bar__margin);
+        counter-reset: i;
+        font-size: 0;
+    }
+    .opc-progress-bar-item {
+        .css(margin, 0 0 @checkout-progress-bar-item__margin);
+        display: inline-block;
+        position: relative;
+        text-align: center;
+        vertical-align: top;
+        width: 50%;
+
+        &:before { // Horizontal line
+            .css(background, @checkout-progress-bar-item__background-color);
+            .css(top, @checkout-progress-bar-item-element__width/2);
+            content: '';
+            height: 7px;
+            left: 0;
+            position: absolute;
+            width: 100%;
+        }
+
+        &:first-child {
+            &:before {
+                .css(border-radius, @checkout-progress-bar-item__border-radius 0 0 @checkout-progress-bar-item__border-radius);
+            }
+        }
+
+        &:last-child {
+            &:before {
+                .css(border-radius, 0 @checkout-progress-bar-item__border-radius @checkout-progress-bar-item__border-radius 0);
+            }
+        }
+
+        > span {
+            display: inline-block;
+            padding-top: 45px;
+            width: 100%;
+            word-wrap: break-word;
+
+            .typography(
+            @_color: @checkout-progress-bar-item__background-color,
+            @_font-family: false,
+            @_font-size: @checkout-progress-bar__font-size,
+            @_font-style: false,
+            @_font-weight: @checkout-progress-bar__font-weight,
+            @_line-height: false
+            );
+
+            &:before, // Item element
+            &:after {
+                .css(background, @checkout-progress-bar-item__background-color);
+                .css(height, @checkout-progress-bar-item-element__height);
+                .css(margin-left, -(@checkout-progress-bar-item-element__width/2));
+                .css(width, @checkout-progress-bar-item-element__width);
+                border-radius: 50%;
+                content: '';
+                left: 50%;
+                position: absolute;
+                top: 0;
+            }
+
+            &:after { // Item element inner
+                .css(background, @checkout-progress-bar-item-element-inner__background-color);
+                .css(height, @checkout-progress-bar-item-element-inner__height);
+                .css(margin-left, -(@checkout-progress-bar-item-element-inner__width/2));
+                .css(top, @checkout-progress-bar-item-element-outer-radius__width);
+                .css(width, @checkout-progress-bar-item-element-inner__width);
+                content: counter(i);
+                counter-increment: i;
+                .typography(
+                @_color: @checkout-progress-bar-item-element-inner__color,
+                @_font-family: false,
+                @_font-size: @checkout-progress-bar__font-size,
+                @_font-style: false,
+                @_font-weight: @font-weight__semibold,
+                @_line-height: false
+                );
+            }
+        }
+
+        &._active {
+            &:before {
+                background: @checkout-progress-bar-item__active__background-color;
+            }
+            > span {
+                .css(color, @checkout-progress-bar-item__color);
+                &:before {
+                    .css(background, @checkout-progress-bar-item__active__background-color);
+                }
+                &:after {
+                    .css(content, @checkout-progress-bar-item-element-inner__active__content);
+                    .css(font-family, @icons__font-name);
+                    .css(line-height, @checkout-progress-bar-item-element-inner__active__line-height);
+                    .font-size(@checkout-progress-bar-item-element-inner__active__font-size);
+                }
+            }
+        }
+
+        &._complete {
+            cursor: pointer;
+            > span {
+                .css(color, @checkout-progress-bar-item__color);
+                &:after {
+                    .css(content, @checkout-progress-bar-item-element-inner__active__content);
+                    .css(font-family, @icons__font-name);
+                    .css(line-height, @checkout-progress-bar-item-element-inner__active__line-height);
+                    .font-size(@checkout-progress-bar-item-element-inner__active__font-size);
+                }
+            }
+        }
+    }
+}
+
+//
+//  Desktop
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
+    .opc-progress-bar-item {
+        .css(width, @checkout-progress-bar-item__width);
+    }
+}
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping-policy.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping-policy.less
new file mode 100644
index 0000000000000000000000000000000000000000..adb28706810e8c0f90b112c38936cfe1fc5a9a73
--- /dev/null
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping-policy.less
@@ -0,0 +1,67 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+@checkout-shipping-policy-action__color: @link__color;
+@checkout-shipping-policy-tooltip__width: 420px;
+@checkout-shipping-policy-tooltip-mobile__width: 300px;
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+    .checkout-shipping-method {
+        position: relative;
+    }
+
+    .shipping-policy-block {
+        &.field-tooltip {
+            top: 12px;
+
+            .field-tooltip-action {
+                .css(color, @checkout-shipping-policy-action__color);
+                cursor: pointer;
+                &:before {
+                   display: none;
+                }
+            }
+
+            .field-tooltip-content {
+                &:extend(.abs-add-box-sizing all);
+                &:extend(.abs-checkout-tooltip-content-position-top all);
+                .css(width, @checkout-shipping-policy-tooltip__width);
+                top: @indent__l;
+            }
+        }
+    }
+}
+
+//
+//  Mobile
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) {
+    .shipping-policy-block {
+        &.field-tooltip {
+            margin-bottom: @indent__base;
+            position: relative;
+            right: auto;
+            top: auto;
+
+            .field-tooltip-content {
+                .css(width, @checkout-shipping-policy-tooltip-mobile__width);
+                right: auto;
+                &:before,
+                &:after {
+                    right: auto;
+                }
+            }
+        }
+    }
+}
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping.less
new file mode 100644
index 0000000000000000000000000000000000000000..3b052c7401101077be3125a7b522953a515acb3b
--- /dev/null
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_shipping.less
@@ -0,0 +1,321 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+@checkout-shipping-address__max-width: 600px;
+
+@checkout-shipping-item-icon__background-color: @checkout-shipping-item__active__border-color;
+@checkout-shipping-item-icon__color: @color-white;
+@checkout-shipping-item-icon__content: @icon-checkmark;
+
+@checkout-shipping-item__border: 2px solid transparent;
+@checkout-shipping-item__line-height: 30px;
+@checkout-shipping-item__margin: 0 0 @indent__base;
+@checkout-shipping-item__padding: @indent__base (@indent__l + 5px) @indent__base @indent__base;
+@checkout-shipping-item__transition: .3s border-color;
+@checkout-shipping-item__width: 100%/3;
+@checkout-shipping-item-tablet__width: 100%/2;
+@checkout-shipping-item-mobile__width: 100%;
+@checkout-shipping-item__active__border-color: @color-orange-red1;
+
+@checkout-shipping-item-icon__selected__height: 27px;
+@checkout-shipping-item-icon__selected__width: 29px;
+
+@checkout-shipping-item-mobile__padding: 0 0 15px;
+@checkout-shipping-item-mobile__margin: @checkout-shipping-item-mobile__padding;
+@checkout-shipping-item-mobile__active__padding: 15px (@indent__l + 5px) 15px 18px;
+
+@checkout-shipping-item-before__border-color: @color-gray80;
+@checkout-shipping-item-before__height: calc(~"100% - 20px");
+
+@checkout-shipping-method__border: @checkout-step-title__border;
+@checkout-shipping-method__padding: @indent__base;
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+
+    .opc-wrapper {
+
+        //
+        //  Shipping Address
+        //  ---------------------------------------------
+
+        .form-login,
+        .form-shipping-address {
+            margin-bottom: @indent__base;
+
+            .fieldset {
+                .field {
+                    .label {
+                        font-weight: @font-weight__regular;
+                    }
+                }
+                .note {
+                    font-size: @font-size__base;
+                    margin-top: @indent__s;
+                }
+            }
+        }
+
+        .shipping-address-items {
+            font-size: 0;
+        }
+
+        .shipping-address-item {
+            &:extend(.abs-add-box-sizing all);
+            .css(border, @checkout-shipping-item__border);
+            .css(line-height, @checkout-shipping-item__line-height);
+            .css(margin, @checkout-shipping-item__margin);
+            .css(padding, @checkout-shipping-item__padding);
+            .css(transition, @checkout-shipping-item__transition);
+            .css(width, @checkout-shipping-item-tablet__width);
+            display: inline-block;
+            font-size: @font-size__base;
+            position: relative;
+            vertical-align: top;
+            word-wrap: break-word;
+
+            &.selected-item {
+                .css(border-color, @checkout-shipping-item__active__border-color);
+
+                &:after {
+                    .css(background, @checkout-shipping-item-icon__background-color);
+                    .css(color, @checkout-shipping-item-icon__color);
+                    .css(content, @checkout-shipping-item-icon__content);
+                    .css(font-family, @icons__font-name);
+                    .css(height, @checkout-shipping-item-icon__selected__height);
+                    .css(width, @checkout-shipping-item-icon__selected__width);
+                    font-size: 27px;
+                    line-height: 21px;
+                    padding-top: 2px;
+                    position: absolute;
+                    right: 0;
+                    text-align: center;
+                    top: 0;
+                }
+
+                .action-select-shipping-item {
+                    &:extend(.abs-no-display-s all);
+                    visibility: hidden;
+                }
+            }
+        }
+
+        .field {
+            &.addresses {
+                &:extend(.abs-add-clearfix all);
+            }
+        }
+
+        .action-show-popup {
+            margin: 0 0 @indent__base;
+            > span {
+                &:before {
+                    content: '+';
+                    padding-right: @indent__xs;
+                }
+            }
+        }
+
+        .action-select-shipping-item {
+            float: right;
+            margin: @indent__base 0 0;
+        }
+
+        .edit-address-link {
+            &:extend(.abs-action-button-as-link all);
+            display: block;
+            float: left;
+            margin: 26px 5px 0 0;
+        }
+    }
+
+    //
+    //  Shipping Methods
+    //  ---------------------------------------------
+
+    .checkout-shipping-method {
+        .step-title {
+            margin-bottom: 0;
+        }
+        .no-quotes-block {
+            margin: @indent__base 0;
+        }
+    }
+
+    .methods-shipping {
+        .actions-toolbar {
+            .action {
+                &.primary {
+                    &:extend(.abs-button-l all);
+                    margin: @indent__base 0 0;
+                }
+            }
+        }
+    }
+
+    .table-checkout-shipping-method {
+        thead {
+            th {
+                display: none;
+            }
+        }
+        tbody {
+            td {
+                .css(border-top, @checkout-shipping-method__border);
+                .css(padding-bottom, @checkout-shipping-method__padding);
+                .css(padding-top, @checkout-shipping-method__padding);
+                &:first-child {
+                    padding-left: 0;
+                    padding-right: 0;
+                    width: 20px;
+                }
+            }
+
+            tr {
+                &:first-child {
+                    td {
+                        border-top: none;
+                    }
+                }
+            }
+            .row-error {
+                td {
+                    border-top: none;
+                    padding-bottom: @indent__s;
+                    padding-top: 0;
+                }
+            }
+        }
+    }
+}
+
+//
+//  Mobile
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) {
+    .opc-wrapper {
+        .form-login {
+            .css(border-bottom, 1px solid @checkout-shipping-item-before__border-color);
+            .css(margin, @checkout-shipping-item-mobile__padding);
+            .css(padding, @checkout-shipping-item-mobile__padding);
+        }
+        .shipping-address-item {
+            .css(border-bottom, 1px solid @checkout-shipping-item-before__border-color);
+            .css(margin, @checkout-shipping-item-mobile__margin);
+            .css(padding, @checkout-shipping-item-mobile__padding);
+            width: 100%;
+            &.selected-item {
+                .css(padding, @checkout-shipping-item-mobile__active__padding);
+                border-bottom-width: 2px;
+
+                .edit-address-link {
+                    .css(right, @checkout-shipping-item-icon__selected__width + @indent__s);
+                }
+            }
+        }
+
+        .action-select-shipping-item {
+            float: none;
+            margin-top: @indent__s;
+            width: 100%;
+        }
+
+        .action-show-popup {
+            width: 100%;
+        }
+
+        .edit-address-link {
+            .icon-font(
+                @icon-settings,
+                @_icon-font-size: 28px,
+                @_icon-font-line-height: 28px,
+                @_icon-font-text-hide: true,
+                @_icon-font-color: @color-gray19,
+                @_icon-font-color-hover: @color-gray19,
+                @_icon-font-color-active: @color-gray19
+            );
+            margin: 0;
+            position: absolute;
+            right: 0;
+            top: 1px;
+        }
+    }
+}
+
+//
+//  Desktop
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
+    .checkout-shipping-method {
+        .actions-toolbar {
+            > .primary {
+                float: right;
+            }
+            .action {
+                &.primary {
+                    margin: 0;
+                }
+            }
+        }
+    }
+
+    .opc-wrapper {
+        .form-login,
+        .form-shipping-address {
+            .css(max-width, @checkout-shipping-address__max-width);
+        }
+    }
+    .table-checkout-shipping-method {
+        width: auto;
+    }
+}
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__l) {
+    .opc-wrapper {
+        .shipping-address-item {
+            .css(width, @checkout-shipping-item__width);
+
+            &:before {
+                .css(background, @checkout-shipping-item-before__border-color);
+                .css(height, @checkout-shipping-item-before__height);
+                content: '';
+                left: 0;
+                position: absolute;
+                top: 0;
+                width: 1px;
+            }
+
+            &:nth-child(3n+1) {
+                &:before {
+                    display: none;
+                }
+            }
+
+            &.selected-item {
+                &:before {
+                    display: none;
+                }
+
+                + .shipping-address-item {
+                    &:before {
+                        display: none;
+                    }
+                }
+            }
+        }
+    }
+    .table-checkout-shipping-method {
+        min-width: 500px;
+    }
+}
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_sidebar-shipping-information.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_sidebar-shipping-information.less
new file mode 100644
index 0000000000000000000000000000000000000000..ed940f5fd3c4b45ee959dbfa48335ae02c642a7c
--- /dev/null
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_sidebar-shipping-information.less
@@ -0,0 +1,69 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+@checkout-sidebar-shipping-information__padding: @indent__l;
+@checkout-sidebar-shipping-information__line-height: @checkout-billing-address-details__line-height;
+
+@checkout-sidebar-shipping-information-edit-icon__color: @minicart-icons-color;
+@checkout-sidebar-shipping-information-edit-icon__content: @icon-settings;
+@checkout-sidebar-shipping-information-edit-icon__font-size: 28px;
+@checkout-sidebar-shipping-information-edit-icon__line-height: 28px;
+@checkout-sidebar-shipping-information-edit-icon__top: 2px;
+@checkout-sidebar-shipping-information-edit-icon__hover__color: @primary__color;
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+
+    //
+    //  Shipping Information
+    //  ---------------------------------------------
+
+    .opc-block-shipping-information {
+        .css(padding, 0 @checkout-sidebar-shipping-information__padding);
+
+        .shipping-information-title {
+            &:extend(.abs-checkout-title all);
+            .css(border-bottom, @checkout-step-title__border);
+            margin: 0 0 @indent__base;
+            position: relative;
+
+            .action-edit {
+                &:extend(.abs-action-button-as-link all);
+                .css(top, @checkout-sidebar-shipping-information-edit-icon__top);
+                .icon-font(
+                    @checkout-sidebar-shipping-information-edit-icon__content,
+                    @_icon-font-size: @checkout-sidebar-shipping-information-edit-icon__font-size,
+                    @_icon-font-line-height: @checkout-sidebar-shipping-information-edit-icon__line-height,
+                    @_icon-font-text-hide: true,
+                    @_icon-font-color: @checkout-sidebar-shipping-information-edit-icon__color,
+                    @_icon-font-color-hover: @checkout-sidebar-shipping-information-edit-icon__hover__color,
+                    @_icon-font-color-active: @checkout-sidebar-shipping-information-edit-icon__color
+                );
+                margin: 0;
+                position: absolute;
+                right: 0;
+            }
+        }
+
+        .shipping-information-content {
+            .css(line-height, @checkout-sidebar-shipping-information__line-height);
+            .actions-toolbar {
+                margin-left: 0;
+            }
+        }
+
+        .ship-to,
+        .ship-via {
+            margin: 0 0 @indent__base;
+        }
+    }
+}
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_sidebar.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_sidebar.less
new file mode 100644
index 0000000000000000000000000000000000000000..83934eaf6aab5185021cf59db52d2ea4f7c69c9a
--- /dev/null
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_sidebar.less
@@ -0,0 +1,23 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+@checkout-sidebar__margin: @indent__base;
+@checkout-sidebar__margin__xl: 46px;
+@checkout-sidebar__columns: 4;
+
+//
+//  Desktop
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
+    .opc-sidebar {
+        .css(margin, @checkout-sidebar__margin__xl 0 @checkout-sidebar__margin);
+        .layout-column(2, 2, @checkout-sidebar__columns);
+    }
+}
diff --git a/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_tooltip.less b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_tooltip.less
new file mode 100644
index 0000000000000000000000000000000000000000..d867cc3387355f400f35932bbad34242d21c4c06
--- /dev/null
+++ b/app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_tooltip.less
@@ -0,0 +1,137 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+@checkout-tooltip__hover__z-index: @tooltip__z-index;
+@checkout-tooltip-breakpoint__screen-m: @modal-popup-breakpoint-screen__m;
+
+@checkout-tooltip-icon-arrow__font-size: 10px;
+@checkout-tooltip-icon-arrow__left: -( @checkout-tooltip-content__padding + @checkout-tooltip-icon-arrow__font-size - @checkout-tooltip-content__border-width);
+
+@checkout-tooltip-icon__color: @color-gray-light2;
+@checkout-tooltip-icon__content: @icon-help;
+@checkout-tooltip-icon__font-size: 24px;
+@checkout-tooltip-icon__hover__color: @primary__color;
+
+@checkout-tooltip-content__background-color: @color-gray-light01;
+@checkout-tooltip-content__border-color: @color-gray60;
+@checkout-tooltip-content__border-width: 1px;
+@checkout-tooltip-content__font-size: @font-size__base;
+@checkout-tooltip-content__padding: 12px;
+@checkout-tooltip-content__width: 270px;
+@checkout-tooltip-content__active__border-color: darken(@checkout-tooltip-content__border-color, 20%);
+
+@checkout-tooltip-content-mobile-popup__width: 200px;
+@checkout-tooltip-content-mobile__right: -(@indent__s);
+@checkout-tooltip-content-mobile__top: 30px + @checkout-tooltip-icon-arrow__font-size;
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+
+    .field-tooltip {
+        position: absolute;
+        right: 0;
+        top: 1px;
+
+        &:hover {
+            .css(z-index, @checkout-tooltip__hover__z-index);
+            cursor: pointer;
+            .field-tooltip-content {
+                display: block;
+            }
+            .field-tooltip-action {
+                &:before {
+                    .css(color, @checkout-tooltip-icon__hover__color);
+                }
+            }
+        }
+
+        .field-tooltip-action {
+            .icon-font(
+            @checkout-tooltip-icon__content,
+            @_icon-font-size: @checkout-tooltip-icon__font-size,
+            @_icon-font-text-hide: true,
+            @_icon-font-color: @checkout-tooltip-icon__color,
+            @_icon-font-color-hover: @checkout-tooltip-icon__hover__color,
+            @_icon-font-color-active: false
+            );
+            &:focus {
+                &:before {
+                    .css(color, @checkout-tooltip-icon__hover__color);
+                }
+                + .field-tooltip-content {
+                    display: block;
+                }
+            }
+        }
+
+        .field-tooltip-content {
+            .css(background, @checkout-tooltip-content__background-color);
+            .css(border, @checkout-tooltip-content__border-width solid @checkout-tooltip-content__border-color);
+            .css(border-radius, @checkout-tooltip-content__border-width);
+            .css(font-size, @checkout-tooltip-content__font-size);
+            .css(padding, @checkout-tooltip-content__padding);
+            .css(width, @checkout-tooltip-content__width);
+            display: none;
+            left: 38px;
+            position: absolute;
+            text-transform: none;
+            top: -9px;
+            word-wrap: break-word;
+            z-index: 2;
+
+            &:before,
+            &:after {
+                .arrow(
+                @_position: left,
+                @_size: @checkout-tooltip-icon-arrow__font-size,
+                @_color: @checkout-tooltip-content__background-color
+                );
+                .css(left, @checkout-tooltip-icon-arrow__left);
+                .css(top, @checkout-tooltip-content__padding);
+                content: '';
+                display: block;
+                position: absolute;
+                z-index: 3;
+            }
+            &:before {
+                .css(border-right-color, @checkout-tooltip-content__active__border-color);
+            }
+            &:after {
+                .css(border-right-color, @checkout-tooltip-content__background-color);
+                width: 1px;
+                z-index: 4;
+            }
+        }
+    }
+}
+
+//
+//  Mobile
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__xs) {
+    .modal-popup {
+        .field-tooltip {
+            .field-tooltip-content {
+                .css(width, @checkout-tooltip-content-mobile-popup__width);
+            }
+        }
+    }
+}
+
+.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @checkout-tooltip-breakpoint__screen-m) {
+    .field-tooltip {
+        .field-tooltip-content {
+            &:extend(.abs-checkout-tooltip-content-position-top-mobile all);
+        }
+    }
+}
diff --git a/app/design/frontend/Magento/blank/Magento_SalesRule/web/css/source/_module.less b/app/design/frontend/Magento/blank/Magento_SalesRule/web/css/source/_module.less
new file mode 100644
index 0000000000000000000000000000000000000000..8361a32c5e8f3a20e2278ab8896b015237ade8c0
--- /dev/null
+++ b/app/design/frontend/Magento/blank/Magento_SalesRule/web/css/source/_module.less
@@ -0,0 +1,21 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+    .opc-wrapper {
+        .form-discount {
+            max-width: 500px;
+            .field {
+                .label {
+                    &:extend(.abs-visually-hidden all);
+                }
+            }
+        }
+    }
+}
diff --git a/app/design/frontend/Magento/blank/web/css/_styles.less b/app/design/frontend/Magento/blank/web/css/_styles.less
index e1f7113c61eafb29ebc4494b82ab2269961c86f9..75ff8775d8c8a10a656cc55c1d0bfd163bb4f800 100644
--- a/app/design/frontend/Magento/blank/web/css/_styles.less
+++ b/app/design/frontend/Magento/blank/web/css/_styles.less
@@ -5,3 +5,4 @@
 
 @import 'source/lib/_lib.less'; // Global lib
 @import 'source/_sources.less'; // Theme styles
+@import 'source/_components.less'; // Components styles (modal/sliding panel)
diff --git a/app/design/frontend/Magento/blank/web/css/source/_components.less b/app/design/frontend/Magento/blank/web/css/source/_components.less
new file mode 100644
index 0000000000000000000000000000000000000000..9f6db89c38d126d254ae3e4423ed7fccf8d3e1ed
--- /dev/null
+++ b/app/design/frontend/Magento/blank/web/css/source/_components.less
@@ -0,0 +1,11 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Components
+//  _____________________________________________
+
+@import 'components/_modals.less'; // from lib
+@import 'components/_modals_extend.less'; // local
diff --git a/app/design/frontend/Magento/blank/web/css/source/_extends.less b/app/design/frontend/Magento/blank/web/css/source/_extends.less
index df818e7003ce2e68d7f529b31d2af5e2f82e6943..19705339dae3c4f0430aac361f16a2952ef1350c 100644
--- a/app/design/frontend/Magento/blank/web/css/source/_extends.less
+++ b/app/design/frontend/Magento/blank/web/css/source/_extends.less
@@ -507,6 +507,12 @@
     }
 }
 
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
+    .abs-add-box-sizing-desktop-m {
+        @abs-add-box-sizing();
+    }
+}
+
 //
 //  Revert field type
 //  ---------------------------------------------
@@ -1022,9 +1028,176 @@
 }
 
 //
-//    Form Field Date Input
-//--------------------------------------
+//  Form Field Date Input
+//  ---------------------------------------------
+
 .abs-field-date-input {
-    margin-right: @indent__s;
+    .css(margin-right, @indent__s);
     width: calc(~"100% - (@{icon-calendar__font-size} + @{indent__s})");
 }
+
+//
+//  Form Field Tooltip
+//  ---------------------------------------------
+
+.abs-field-tooltip {
+    &:extend(.abs-add-box-sizing all);
+    position: relative;
+    input {
+        .css(margin-right, @indent__s);
+        width: calc(~"100% - (@{checkout-tooltip-icon__font-size} + @{indent__s} + @{indent__xs})");
+        &:focus {
+            + .field-tooltip {
+                .field-tooltip-action {
+                    &:before {
+                        .css(color, @checkout-tooltip-icon__hover__color);
+                    }
+                }
+                .field-tooltip-content {
+                    display: block;
+                }
+            }
+        }
+    }
+}
+
+//
+//  Checkout Tooltip Content (position: top)
+//  ---------------------------------------------
+
+@abs-checkout-tooltip-content-position-top: {
+    .css(right, @checkout-tooltip-content-mobile__right);
+    .css(top, @checkout-tooltip-content-mobile__top);
+    left: auto;
+
+    &:before,
+    &:after {
+        .arrow(
+        @_position: top,
+        @_size: @checkout-tooltip-icon-arrow__font-size,
+        @_color: @checkout-tooltip-content__background-color
+        );
+        .css(margin-top, @checkout-tooltip-icon-arrow__left);
+        .css(right, @indent__s);
+        left: auto;
+        top: 0%;
+    }
+    &:before {
+        .css(border-bottom-color, @checkout-tooltip-content__border-color);
+    }
+    &:after {
+        .css(border-bottom-color, @checkout-tooltip-content__background-color);
+        top: 1px;
+    }
+};
+
+.abs-checkout-tooltip-content-position-top {
+    @abs-checkout-tooltip-content-position-top();
+}
+
+.media-width(@extremum, @break) when (@extremum = 'max') and (@break = (@screen__m + 1)) {
+    .abs-checkout-tooltip-content-position-top-mobile {
+        @abs-checkout-tooltip-content-position-top();
+    }
+}
+
+//
+//  Checkout title
+//  ---------------------------------------------
+
+.abs-checkout-title {
+    .css(border-bottom, @checkout-step-title__border);
+    .css(padding-bottom, @checkout-step-title__padding);
+    .typography(
+    @_font-size: @checkout-step-title__font-size,
+    @_font-weight: @checkout-step-title__font-weight,
+    @_font-family: false,
+    @_font-style: false,
+    @_line-height: false
+    );
+}
+
+//
+//  Shopping cart sidebar and checkout sidebar totals
+//  ---------------------------------------------
+
+.abs-sidebar-totals {
+    .mark {
+        font-weight: @font-weight__regular;
+        padding-left: 4px;
+        strong {
+            font-weight: @font-weight__regular;
+        }
+    }
+    .amount {
+        padding-right: 4px;
+        text-align: right;
+        strong {
+            font-weight: @font-weight__regular;
+        }
+    }
+    .grand {
+        .mark,
+        .amount {
+            padding-top: @indent__base;
+        }
+        .amount {
+            padding-right: 4px;
+            text-align: right;
+            strong {
+                font-weight: @font-weight__bold;
+            }
+        }
+    }
+    .msrp {
+        margin-bottom: @indent__s;
+    }
+    .totals-tax {
+        &-summary {
+            .mark,
+            .amount {
+                .css(border-top, @border-width__base solid @border-color__base);
+                .css(border-bottom, @border-width__base solid @border-color__base);
+                cursor: pointer;
+            }
+            .amount .price {
+                position: relative;
+                padding-right: @indent__m;
+                .icon-font(
+                @icon-down,
+                @_icon-font-size: 30px,
+                @_icon-font-text-hide: true,
+                @_icon-font-position: after,
+                @_icon-font-display: block
+                );
+                &:after {
+                    position: absolute;
+                    right: -5px;
+                    top: -12px;
+                }
+            }
+            &.expanded {
+                .mark,
+                .amount {
+                    border-bottom: 0;
+                }
+                .amount .price {
+                    .icon-font-symbol(
+                    @_icon-font-content: @icon-up,
+                    @_icon-font-position: after
+                    );
+                }
+            }
+        }
+        &-details {
+            display: none;
+            .css(border-bottom, @border-width__base solid @border-color__base);
+            &.shown {
+                display: table-row;
+            }
+        }
+    }
+    .table-caption {
+        &:extend(.abs-no-display all);
+    }
+}
diff --git a/app/design/frontend/Magento/blank/web/css/source/_loaders.less b/app/design/frontend/Magento/blank/web/css/source/_loaders.less
index 0c608a402d54782d412ab447990f01e045c00e73..576c7b2ca933ec7e365f24e50e12163c6819dfe5 100644
--- a/app/design/frontend/Magento/blank/web/css/source/_loaders.less
+++ b/app/design/frontend/Magento/blank/web/css/source/_loaders.less
@@ -9,25 +9,34 @@
 
 & when (@media-common = true) {
 
-.load.indicator {
-    .loader();
-    position: absolute;
-    > span {
-        display: none;
+    .load.indicator {
+        .loader();
+        position: absolute;
+        > span {
+            display: none;
+        }
     }
-}
 
-.loading-mask {
-    .loading-mask();
-    background: rgba(255, 255, 255, .5);
-    .loader {
-        > img {
-            .loading-mask();
+    .loading-mask {
+        .loading-mask();
+        background: rgba(255, 255, 255, .5);
+        .loader {
+            > img {
+                .loading-mask();
+            }
+            > p {
+                display: none;
+            }
         }
-        > p {
-            display: none;
+    }
+
+    body {
+        > .loading-mask {
+            z-index: @loader-overlay__z-index;
         }
     }
-}
 
+    ._block-content-loading {
+        position: relative;
+    }
 }
diff --git a/app/design/frontend/Magento/blank/web/css/source/_navigation.less b/app/design/frontend/Magento/blank/web/css/source/_navigation.less
index c16516b0e20bd4069c4f9ee32df098ffb00ac623..f1809aeafb167fec419655d62d4f7969d68b8485 100644
--- a/app/design/frontend/Magento/blank/web/css/source/_navigation.less
+++ b/app/design/frontend/Magento/blank/web/css/source/_navigation.less
@@ -149,7 +149,7 @@
         height: 100%;
         width: 100%;
         .page-wrapper {
-            height:100%;
+            height: 100%;
             overflow: hidden;
             position: relative;
             left: 0;
diff --git a/app/design/frontend/Magento/blank/web/css/source/components/_modals_extend.less b/app/design/frontend/Magento/blank/web/css/source/components/_modals_extend.less
new file mode 100644
index 0000000000000000000000000000000000000000..e4b01ecd0df6e5d9a9c0c10e275d6ccc5098efa1
--- /dev/null
+++ b/app/design/frontend/Magento/blank/web/css/source/components/_modals_extend.less
@@ -0,0 +1,166 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Components -> Modals
+//  _____________________________________________
+
+//
+//  Variables
+//  ---------------------------------------------
+
+@modal-title__color: @text__color;
+@modal-title__border: 1px solid @color-gray-light5;
+
+@modal-popup-title__font-size: 26px;
+@modal-popup-title-mobile__font-size: @font-size__base;
+@modal-popup-breakpoint-screen__m: @screen__m + 1;
+
+@modal-slide__first__indent-left: 44px;
+@modal-slide-mobile__background-color: @color-gray-light01;
+@modal-overlay__background-color: fade(@color-gray20, 55%);
+
+@modal-action-close__color: @primary__color;
+@modal-action-close__font-size: 32px;
+@modal-action-close__hover__color: darken(@primary__color, 10%);
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+    .modal-custom,
+    .modal-popup,
+    .modal-slide {
+        .action-close {
+            .button-reset();
+            .button-icon(
+                @icon-remove,
+                @_icon-font-color: @minicart-icons-color,
+                @_icon-font-size: @modal-action-close__font-size,
+                @_icon-font-line-height: @modal-action-close__font-size,
+                @_icon-font-text-hide: true
+            );
+            position: absolute;
+            right: 0;
+            top: 0;
+            &:hover {
+                &:before {
+                    color: @modal-action-close__hover__color;
+                }
+            }
+        }
+    }
+    .modal-custom {
+        .action-close {
+            .css(margin, @indent__m);
+        }
+    }
+    .modal-popup {
+        .modal-title {
+            .css(border-bottom, @modal-title__border);
+            .css(font-weight, @font-weight__light);
+            .css(padding-bottom, @indent__s);
+            font-size: @modal-popup-title__font-size;
+            margin-bottom: 0;
+            min-height: 1em;
+            word-wrap: break-word;
+        }
+        .action-close {
+            padding: @modal-popup__padding;
+        }
+    }
+
+    .modal-slide {
+        .action-close {
+            padding: @modal-slide-header__padding-vertical @modal-slide__padding;
+        }
+        .page-main-actions {
+            margin-top: @modal-slide-header__padding-vertical;
+            margin-bottom: @modal-slide-header__padding-vertical - (@indent__l/2);
+        }
+    }
+
+    .modals-overlay {
+        .css(background-color, @modal-overlay__background-color);
+        bottom: 0;
+        left: 0;
+        position: fixed;
+        right: 0;
+        top: 0;
+    }
+}
+
+//
+//  Mobile
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @modal-popup-breakpoint-screen__m) {
+    .modal-popup {
+        &.modal-slide {
+            .modal-inner-wrap[class] {
+                .css(background-color, @modal-slide-mobile__background-color);
+            }
+            &._inner-scroll {
+                &._show {
+                    -webkit-overflow-scrolling: touch;
+                    overflow-y: auto;
+                }
+                .modal-inner-wrap {
+                    height: auto;
+                    min-height: 100%;
+                }
+            }
+        }
+        .modal-title {
+            .css(font-size, @modal-popup-title-mobile__font-size);
+            .css(font-weight, @font-weight__bold);
+        }
+    }
+    .custom-slide {
+        .abs-modal();
+        .abs-modal-slide();
+        &._show {
+            -webkit-overflow-scrolling: touch;
+            overflow-y: auto;
+            overflow-x: hidden;
+        }
+        .modal-inner-wrap {
+            .css(background-color, @modal-slide-mobile__background-color);
+            box-sizing: border-box;
+            height: auto;
+            min-height: 100%;
+        }
+    }
+    body._has-modal-custom {
+        height: 100vh;
+        overflow: hidden;
+        width: 100vw;
+        .modal-custom-overlay {
+            .css(background-color, @modal-overlay__background-color);
+            height: 100vh;
+            left: 0;
+            position: fixed;
+            top: 0;
+            width: 100vw;
+            z-index: @overlay__z-index;
+        }
+    }
+}
+
+//
+//  Desktop
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @modal-popup-breakpoint-screen__m) {
+    .modal-popup {
+        &.modal-slide {
+            .modal-footer {
+                .css(border-top, @modal-title__border);
+                text-align: right;
+            }
+        }
+    }
+}
diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/_module.less
index 9b111f1353784f0f84d6b39f63bd79fc1d246df1..85932830410a8ee3ef47bc3eabf105116270a9cc 100644
--- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/_module.less
+++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/_module.less
@@ -5,647 +5,4 @@
 
 @import 'module/_cart.less';
 @import 'module/_minicart.less';
-
-@opc-margin-left: 10%;
-
-//
-//  Common
-//  _____________________________________________
-
-& when (@media-common = true) {
-
-    //
-    //  One Page Checkout
-    //  ---------------------------------------------
-
-    .opc-wrapper:extend(.abs-add-box-sizing all) {
-        .field select {
-            max-width: none;
-        }
-        > .opc:extend(.abs-reset-list all) {
-        }
-        .section {
-            &.allow {
-                .step-title {
-                    cursor: pointer;
-                    .icon-font(
-                    @icon-edit,
-                    @_icon-font-size: 20px,
-                    @_icon-font-display: block,
-                    @_icon-font-position: after
-                    );
-                    &:after {
-                        position: absolute;
-                        right: 18px;
-                        top: 12px;
-                    }
-                }
-                &.active {
-                    .step-title {
-                        cursor: default;
-                    }
-                    .step-title:after {
-                        display: none;
-                    }
-                }
-            }
-            .step-content {
-                display: none;
-            }
-            &.active {
-                .step-title {
-                    .css(color, @primary__color);
-                }
-                .step-content {
-                    display: block;
-                }
-            }
-        }
-        .step {
-            &-title {
-                .css(background, @sidebar__background-color);
-                .css(color, lighten(@primary__color, 40%));
-                margin-bottom: 2px;
-                padding: 13px @indent__m;
-                position: relative;
-                h2 {
-                    .font-size(18);
-                    font-weight: @font-weight__semibold;
-                    margin: 0;
-                }
-                .number {
-                    display: none;
-                }
-            }
-
-            &-content {
-                padding: 35px @indent__m 80px;
-                position: relative;
-                .addresses .control {
-                    margin: @indent__base 0 @indent__l;
-                }
-                .fieldset {
-                    margin-bottom: 0;
-                    &.login {
-                        .form-hasrequired(bottom);
-                        &:after {
-                            margin-top: 35px;
-                            text-align: center;
-                        }
-                    }
-                    .legend.payments-title:extend(.abs-visually-hidden all) {
-                    }
-                }
-                .methods-shipping {
-                    .item-content {
-                        .fieldset {
-                            > .legend:extend(.abs-visually-hidden all) {
-                            }
-                            > .legend + br:extend(.abs-no-display all) {
-                            }
-                            > .field {
-                                margin-bottom: 15px;
-                                &:before {
-                                    display: none;
-                                }
-                                .control {
-                                    display: inline-block;
-                                }
-                            }
-                        }
-                    }
-                }
-                .form {
-                    .form-hasrequired(bottom);
-                    &:after {
-                        text-align: center;
-                    }
-                    > .choice {
-                        margin-top: @form-field__vertical-indent;
-                    }
-                }
-                .form:not(.login),
-                .order-review {
-                    .action.primary:extend(.abs-button-l all) {
-                    }
-                }
-                .actions {
-                    margin-top: @indent__xl;
-                }
-                .field.street {
-                    .field.additional {
-                        .label:extend(.abs-visually-hidden all) {
-                        }
-                    }
-                }
-            }
-
-            .fieldset > .field:last-of-type {
-                margin-bottom: 0;
-            }
-        }
-
-        //
-        //  Customer login
-        //  ---------------------------------------------
-
-        .login-wrapper {
-            .block {
-                .block-title {
-                    margin-bottom: @indent__l;
-                    strong {
-                        .font-size(22);
-                        font-weight: @font-weight__light;
-                        margin: 0;
-                    }
-                }
-                .fieldset.guest {
-                    margin-top: @indent__base;
-                }
-                .field {
-                    &.choice {
-                        margin-bottom: @indent__s;
-                    }
-                    &.note {
-                        margin-bottom: @indent__l;
-                    }
-                }
-            }
-        }
-
-        .opc-payment-additional {
-            margin: 0 0 @indent__s 15px;
-            + .opc-payment {
-                margin: @indent__xl 0 0;
-            }
-        }
-
-        .action.primary.checkout {
-            margin: 0 0 @indent__base;
-        }
-
-        .hidden:extend(.abs-no-display all) {
-        }
-
-        .actions-toolbar {
-            margin: @indent__xl 0 0;
-        }
-
-        .field {
-            &.month {
-                padding-right: @indent__s;
-                .control {
-                    position: relative;
-                    &:after {
-                        color: @primary__color__light;
-                        content: '/';
-                        position: absolute;
-                        right: -9px;
-                        top: @indent__xs;
-                    }
-                }
-            }
-            &.cvv {
-                width: 30%;
-                .control {
-                    position: relative;
-                }
-                .note {
-                    position: absolute;
-                    right: -23px;
-                    top: 0;
-                    &:before {
-                        display: none;
-                    }
-                    > a {
-                        .icon-font(
-                        @_icon-font-content: @icon-help,
-                        @_icon-font-size: 16px,
-                        @_icon-font-color: @primary__color__light,
-                        @_icon-font-color-hover: @primary__color,
-                        @_icon-font-text-hide: true
-                        );
-                    }
-                }
-            }
-        }
-    }
-
-    //
-    //  Shipping methods
-    //  ---------------------------------------------
-
-    .methods-shipping {
-        .item-title:extend(.abs-methods-shipping-title all) {
-        }
-        .item-content:extend(.abs-adjustment-incl-excl-tax all) {
-            margin: 0 0 35px;
-            .field {
-                margin-bottom: 15px;
-                .price {
-                    font-weight: @font-weight__bold;
-                }
-                &.choice {
-                    .control {
-                        float: left;
-                    }
-                    .label {
-                        display: block;
-                        overflow: hidden;
-                    }
-                }
-            }
-        }
-        .price.box {
-            > .price {
-                display: block;
-            }
-            .regular .price,
-            .price .price {
-                font-weight: @font-weight__bold;
-            }
-        }
-        .price-box {
-            margin-bottom: @indent__xs;
-            margin-left: @indent__base;
-            margin-top: @indent__s;
-        }
-    }
-
-    //
-    //  Payment methods
-    //  ---------------------------------------------
-
-    .methods-payment {
-        border-bottom: @border-width__base solid @border-color__base;
-        .item-title {
-            border-top: @border-width__base solid @border-color__base;
-            font-weight: @font-weight__regular;
-            margin: 0;
-            padding: 16px 15px 15px;
-        }
-        .item-content {
-            margin: 0;
-            > .fieldset {
-                padding: 0 @indent__s @indent__xl;
-                &.redirect {
-                    margin: @indent__s 0 @indent__l 37px;
-                    padding: 0;
-                    width: 80%;
-                }
-            }
-        }
-        img {
-            margin-right: @indent__xs;
-            vertical-align: middle;
-        }
-    }
-
-    //
-    //  Order review
-    //  ---------------------------------------------
-    .table-order-review:extend(.abs-product-options-list all) {
-        thead tr:first-child th {
-            padding-top: 0;
-        }
-        .col {
-            &.price,
-            &.qty {
-                text-align: center;
-                white-space: nowrap;
-            }
-            &.price:extend(.abs-incl-excl-tax all),
-            &.subtotal:extend(.abs-incl-excl-tax all) {
-            }
-        }
-        .item-options:extend(.abs-add-clearfix all) {
-            margin: @indent__base 0 0;
-            .price {
-                font-weight: @font-weight__bold;
-            }
-        }
-        .product-item-name:extend(.abs-checkout-product-name all) {
-        }
-        .cart-price:extend(.abs-checkout-cart-price all) {
-        }
-        .grand.totals {
-            .font-size(16);
-            th,
-            td {
-                padding: 0 @indent__s;
-            }
-        }
-    }
-
-    .cart-tax-info + .cart-tax-total,
-    .order-details-items .table-wrapper .cart-tax-info + .cart-tax-total {
-        display: block;
-    }
-
-    //
-    //  Checkout Progress
-    //  ---------------------------------------------
-
-    .opc-block-progress-wrapper {
-        margin-bottom: @indent__l;
-        margin-top: @indent__base;
-    }
-
-    .opc-block-progress:extend(.abs-add-box-sizing all) {
-        display: none;
-        &.order-review-step {
-            display: block;
-        }
-        > .title {
-            .css(background, @sidebar__background-color);
-            .font-size(18);
-            font-weight: @font-weight__light;
-            margin: 0;
-            padding: @indent__s 15px;
-            strong {
-                font-weight: @font-weight__regular;
-            }
-        }
-        > .content {
-            .css(background, @sidebar__background-color);
-            padding: 0 15px;
-            .items {
-                margin: 0;
-            }
-            .item-title {
-                border-top: @border-width__base solid @border-color__base;
-                display: none;
-                margin: 0;
-                padding: 15px 0 7px;
-                &.complete {
-                    display: block;
-                }
-                span {
-                    .font-size(16);
-                    font-weight: @font-weight__semibold;
-                }
-            }
-            .item-content {
-                display: none;
-                margin: 0;
-                overflow: hidden;
-                padding: 0 0 15px;
-                &.complete {
-                    display: block;
-                }
-            }
-            .action {
-                font-weight: @font-weight__regular;
-            }
-            .data.table {
-                font-size: @font-size__s;
-            }
-        }
-        .payment-method {
-            > .title {
-                font-weight: @font-weight__light;
-            }
-            > .content {
-                margin: 0 0 @indent__s;
-                &:last-child {
-                    margin-bottom: 0;
-                }
-            }
-            .items-cards {
-                margin: 0;
-                > .content {
-                    margin: 0;
-                }
-            }
-            .data.table {
-                th {
-                    padding: @indent__xs @indent__s @indent__xs 0;
-                }
-                td {
-                    padding: @indent__xs 0;
-                }
-            }
-        }
-    }
-
-    //
-    //  Checkout Success
-    //  ---------------------------------------------
-
-    .checkout-onepage-success {
-        .page-title-wrapper {
-            .print:extend(.abs-no-display all) {
-            }
-        }
-    }
-
-    .checkout-success {
-        .actions-toolbar {
-            margin-top: 50px;
-        }
-    }
-
-    .checkout-onepage-index {
-        .nav-toggle:extend(.abs-no-display all) {
-        }
-        .logo {
-            margin-left: 0;
-        }
-    }
-}
-
-//
-//  Mobile
-//  _____________________________________________
-
-.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) {
-    .table-wrapper.order-review-wrapper:extend(.abs-no-border-top all) {
-        .table.table-order-review:extend(.abs-checkout-order-review all) {
-            tbody tr {
-                td {
-                    &:not(:last-child) {
-                        border: none;
-                    }
-                }
-                &:first-child td:first-child {
-                    padding-top: 0;
-                }
-            }
-        }
-
-        .table.table-order-review:not(.totals):not(.cart):not(.table-comparison) tbody > tr > td:last-child {
-            border-bottom: none;
-            border-top: none;
-        }
-    }
-}
-
-//
-//  Desktop
-//  _____________________________________________
-
-.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__s) {
-    .checkout-onepage-index .column.main:extend(.abs-add-clearfix-desktop-s all) {
-    }
-
-    .opc-wrapper:extend(.abs-add-box-sizing-desktop-s all) {
-        .layout-column(2, 2, @layout-column-checkout__width-main);
-        .step-content:extend(.abs-form-field-column-2-s all) {
-            .form {
-                &.shipping.address,
-                &.billing,
-                &.methods-shipping {
-                    margin-left: @opc-margin-left;
-                    width: 80%;
-                }
-                &:after {
-                    text-align: right;
-                }
-            }
-
-            .field {
-                &.street,
-                &.choice {
-                    width: 100%;
-                }
-                &.street .field.additional {
-                    padding: 0;
-                    width: 100%;
-                }
-            }
-
-            .payments,
-            .order-review {
-                .field:extend(.abs-form-field-revert-column-1-s all) {
-                    &:nth-last-child(1),
-                    &:nth-last-child(2) {
-                        margin-bottom: @indent__base;
-                    }
-                    &:last-child {
-                        margin: 0;
-                    }
-                }
-            }
-
-            .toolbar {
-                text-align: left;
-            }
-        }
-
-        //
-        //  Login or register
-        //  ---------------------------------------------
-
-        .login-wrapper:extend(.abs-add-clearfix-desktop-s all) {
-            .block:extend(.abs-blocks-2columns-s all) {
-                margin-bottom: 0;
-            }
-            .fieldset {
-                .field {
-                    padding: 0;
-                    width: 100%;
-                }
-                &.login:after {
-                    text-align: left;
-                }
-            }
-            .field.choice:not(.persistent):before {
-                display: none;
-            }
-        }
-
-        .checkout-submit-order .actions-toolbar > .primary {
-            float: right;
-        }
-    }
-
-    //
-    //  Payment methods
-    //  ---------------------------------------------
-
-    .methods-payment .item-content > .fieldset,
-    .order-review .fieldset {
-        margin: @indent__s 0 @indent__l @opc-margin-left;
-        padding: 0;
-        width: 46%;
-        .field .field {
-            &.cvv {
-                display: inline-block;
-                width: 30%;
-            }
-            &.date {
-                display: inline-block;
-                width: 70%;
-            }
-            &.month {
-                padding-right: 12px;
-            }
-            &.month,
-            &.year {
-                margin-bottom: 0;
-            }
-        }
-    }
-
-    .checkout-success .subtitle .print {
-        margin-left: @indent__xl;
-    }
-
-    .table-order-review {
-        .col.subtotal,
-        .amount {
-            text-align: right;
-        }
-        .col.item {
-            width: 70%;
-        }
-        .grand.totals {
-            .font-size(16);
-            th,
-            td {
-                padding: 0 0 @indent__xl;
-            }
-            strong {
-                border-top: @border-width__base solid @border-color__base;
-                display: block;
-                padding-top: 11px;
-            }
-            .mark {
-                strong {
-                    margin-left: @indent__s;
-                    padding-right: @indent__s;
-                }
-            }
-            .amount {
-                strong {
-                    margin-right: @indent__s;
-                    padding-left: @indent__s;
-                }
-            }
-        }
-    }
-
-    //
-    //  Checkout success
-    //  ---------------------------------------------
-
-    .checkout-onepage-success {
-        .page-title-wrapper {
-            .print:extend(.abs-action-print-s all) {
-                display: inline-block;
-                .font-size(14);
-                margin-left: @indent__xl;
-            }
-        }
-    }
-
-    .opc-block-progress-wrapper:extend(.abs-add-box-sizing-desktop-s all) {
-        .layout-column(2, 1, @layout-column-checkout__width-left);
-        margin-top: 0;
-        padding-right: @layout-column-main__sidebar-offset;
-    }
-
-    .opc-block-progress.active {
-        display: block;
-    }
-}
+@import 'module/_checkout.less';
diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less
index 84fe60c7262910782021ee8c38b2d319cc66efc7..9157adac7398e56430135bd4835ffc768cc3d304 100644
--- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less
+++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_cart.less
@@ -13,453 +13,366 @@
 
 & when (@media-common = true) {
 
-    //
-    //  Shopping cart
-    //  ---------------------------------------------
-
-    .checkout-cart-index {
-        .page-main {
-            padding-left: 0;
-            padding-right: 0;
-        }
-        .page-title-wrapper {
-            padding-left: @layout__width-xs-indent;
-            padding-right: @layout__width-xs-indent;
-        }
+  //
+  //  Shopping cart
+  //  ---------------------------------------------
+
+  .checkout-cart-index {
+    .page-main {
+      padding-left: 0;
+      padding-right: 0;
+    }
+    .page-title-wrapper {
+      padding-left: @layout__width-xs-indent;
+      padding-right: @layout__width-xs-indent;
+    }
+  }
+  .cart {
+    //  Cart container
+    &-container {
+      .form-cart {
+        &:extend(.abs-shopping-cart-items all);
+      }
     }
-    .cart {
-        //  Cart container
-        &-container {
-            .form-cart {
-                &:extend(.abs-shopping-cart-items all);
-            }
-        }
-
-        //  Summary block
-        &-summary {
-            &:extend(.abs-add-box-sizing all);
-            .css(background, @sidebar__background-color);
-            margin-bottom: 25px;
-            padding: 1px 0 25px;
-            > .title {
-                display: none;
-                .font-size(24);
-                font-weight: @font-weight__light;
-                margin: 12px 0;
-            }
-
-            .block {
-                form:not(:last-of-type) {
-                    .fieldset {
-                        margin: 0 0 @indent__m;
-                    }
-                }
-
-                .price {
-                    font-weight: @font-weight__bold;
-                }
-
-                .field {
-                    margin: 0 0 16px;
-                    &.note {
-                        display: none;
-                    }
-                }
-
-                .actions-toolbar {
-                    > .primary {
-                        text-align: left;
-                        .action.primary {
-                            &:extend(.abs-revert-to-action-secondary all);
-                            width: auto;
-                        }
-                    }
-                }
-
-                .fieldset.estimate {
-                    > .legend,
-                    > .legend + br {
-                        &:extend(.abs-no-display all);
-                    }
-                }
-                &:extend(.abs-cart-block all);
-                .title {
-                    strong {
-                        .font-size(14);
-                        font-weight: @font-weight__semibold;
-                    }
-                }
-                .item-options {
-                    margin: 0 0 16px;
-                    .field {
-                        .radio {
-                            float: left;
-                        }
-                        .radio {
-                            + .label {
-                                display: block;
-                                margin: 0;
-                                overflow: hidden;
-                            }
-                        }
-                    }
-                }
-            }
-
-            .page-main & {
-                .block {
-                    margin-bottom: 0;
-                }
-            }
-
-            .checkout-methods-items {
-                &:extend(.abs-reset-list all);
-                margin: 20px 0 0;
-                padding: 0 @mobile-cart-padding;
-                text-align: center;
-                .action.primary.checkout {
-                    &:extend(.abs-button-l all);
-                    width: 100%;
-                }
-                .item {
-                    margin-bottom: 25px;
-                    &:last-child {
-                        margin-bottom: 0;
-                    }
-                }
-            }
 
-            .message {
-                padding-left: 20px;
-                > *:first-child:before {
-                    display: none;
-                }
-            }
-            &:extend(.abs-adjustment-incl-excl-tax all);
-        }
-
-        //  Totals block
-        &-totals {
-            border-top: 1px solid @border-color__base;
-            padding-top: 10px;
-            tbody,
-            tfoot {
-                .mark {
-                    border: 0;
-                    font-weight: @font-weight__regular;
-                    padding: 6px 0;
-                    text-align: left;
-                }
-                .amount {
-                    border: 0;
-                    font-weight: @font-weight__regular;
-                    padding: 6px 0 6px 14px;
-                    text-align: right;
-                }
-            }
-            .table-caption {
-                &:extend(.abs-no-display all);
-            }
-            .grand {
-                th,
-                td {
-                    padding: 11px 0;
-                }
-                .mark {
-                    border-top: 1px solid @border-color__base;
-                    .font-size(16);
-                    padding-right: @indent__s;
-                    strong {
-                        display: inline-block;
-                        font-weight: @font-weight__regular;
-                        padding: 3px 0 0;
-                    }
-                }
-                .amount {
-                    border-top: 1px solid @border-color__base;
-                    .font-size(18);
-                }
-            }
-            .msrp {
-                margin-bottom: @indent__s;
-            }
-            tbody tr:last-child td {
-                padding-bottom: 19px;
-            }
-            .totals-tax {
-                &-summary {
-                    .mark,
-                    .amount {
-                        border-bottom: @border-width__base solid @border-color__base;
-                        border-top: @border-width__base solid @border-color__base;
-                        cursor: pointer;
-                    }
-                    .amount .price {
-                        .icon-font(
-                        @icon-down,
-                        @_icon-font-size: 12px,
-                        @_icon-font-line-height: 12px,
-                        @_icon-font-text-hide: true,
-                        @_icon-font-position: after
-                        );
-                        padding-right: 20px;
-                        position: relative;
-                        &:after {
-                            position: absolute;
-                            right: 3px;
-                            top: 3px;
-                        }
-                    }
-                    &.expanded {
-                        .mark,
-                        .amount {
-                            border-bottom: 0;
-                        }
-                        .amount .price {
-                            .icon-font-symbol(
-                            @_icon-font-content: @icon-up,
-                            @_icon-font-position: after
-                            );
-                        }
-                    }
-                }
-                &-details {
-                    border-bottom: @border-width__base solid @border-color__base;
-                    display: none;
-                    &.shown {
-                        display: table-row;
-                    }
-                }
-            }
-            .table-wrapper {
-                margin-bottom: 0;
-            }
+    //  Summary block
+    &-summary {
+      &:extend(.abs-add-box-sizing all);
+      .css(background, @sidebar__background-color);
+      margin-bottom: 25px;
+      padding: 1px 0 25px;
+      > .title {
+        display: none;
+        .font-size(24);
+        font-weight: @font-weight__light;
+        margin: 12px 0;
+      }
+
+      .block {
+        form:not(:last-of-type) {
+          .fieldset {
+            margin: 0 0 @indent__m;
+          }
         }
 
-        //  Products table
-        &.table-wrapper {
-            .cart {
-                thead {
-                    tr th.col {
-                        border-bottom: @border-width__base solid @border-color__base;
-                        padding-bottom: 15px;
-                        padding-top: 24px;
-                    }
-                }
-                tbody {
-                    td {
-                        border: 0;
-                    }
-                }
-                > .item {
-                    border-bottom: @border-width__base solid @border-color__base;
-                    position: relative;
-                }
-            }
-            .col {
-                padding-top: 15px;
-                &.price,
-                &.subtotal,
-                &.msrp {
-                    padding: @cart-item-cell-padding-top 11px @indent__s;
-                    text-align: center;
-                    &:extend(.abs-incl-excl-tax all);
-                }
-                &.qty {
-                    padding: 20px 11px @indent__s;
-                    text-align: center;
-                    .label {
-                        &:extend(.abs-visually-hidden all);
-                    }
-                    .input-text {
-                        height: 36px;
-                        margin-top: -7px;
-                        text-align: center;
-                        width: 45px;
-                    }
-                }
-                > .price {
-                    .css(color, @primary__color__lighter);
-                    .font-size(18);
-                    font-weight: @font-weight__bold;
-                }
-            }
+        .price {
+          font-weight: @font-weight__bold;
+        }
 
-            .item-actions {
-                td {
-                    padding-bottom: 0;
-                    padding-left: @mobile-cart-padding;
-                    padding-right: @mobile-cart-padding;
-                    white-space: normal;
-                }
-            }
-            .item {
-                .col.item {
-                    display: block;
-                    min-height: 75px;
-                    padding: 15px @mobile-cart-padding @indent__s 90px;
-                    position: relative;
-                }
-            }
+        .field {
+          margin: 0 0 16px;
+          &.note {
+            display: none;
+          }
+        }
 
-            .actions-toolbar {
-                &:extend(.abs-add-clearfix all);
-                min-height: 20px;
-                padding-bottom: 15px;
-                position: relative;
-                > .action-edit,
-                > .action-delete {
-                    position: absolute;
-                    right: 16px;
-                    top: 0;
-                    .icon-font(
-                    @icon-edit,
-                    @_icon-font-size: 18px,
-                    @_icon-font-line-height: 20px,
-                    @_icon-font-text-hide: true,
-                    @_icon-font-color: @minicart-icons-color,
-                    @_icon-font-color-hover: @primary__color,
-                    @_icon-font-color-active: @minicart-icons-color
-                    );
-                }
-                > .action-delete {
-                    right: 0;
-                    .icon-font-symbol(
-                    @_icon-font-content: @icon-trash
-                    );
-                }
-            }
-            .action {
-                margin-right: @indent__m;
-                &:last-child {
-                    margin-right: 0;
-                }
-                &.help.map {
-                    &:extend(.abs-action-button-as-link all);
-                    font-weight: @font-weight__regular;
-                }
+        .actions-toolbar {
+          > .primary {
+            text-align: left;
+            .action.primary {
+              &:extend(.abs-revert-to-action-secondary all);
+              width: auto;
             }
+          }
+        }
 
-            .product {
-                &-item-photo {
-                    display: block;
-                    left: @mobile-cart-padding;
-                    max-width: 65px;
-                    padding: 0;
-                    position: absolute;
-                    top: 15px;
-                    width: 100%;
-                }
-                &-item-name {
-                    display: block;
-                    .font-size(18);
-                    margin: -3px 0 @indent__xs;
-                }
-            }
-            .gift-registry-name-label {
-                &:after {
-                    content: ':';
-                }
+        .fieldset.estimate {
+          > .legend,
+          > .legend + br {
+            &:extend(.abs-no-display all);
+          }
+        }
+        &:extend(.abs-cart-block all);
+        .title {
+          strong {
+            .font-size(14);
+            font-weight: @font-weight__semibold;
+          }
+        }
+        .item-options {
+          margin: 0 0 16px;
+          .field {
+            .radio {
+              float: left;
+            }
+            .radio {
+              + .label {
+                display: block;
+                margin: 0;
+                overflow: hidden;
+              }
             }
+          }
+        }
+      }
 
-            //  Product options
-            .item-options {
-                margin-bottom: 0;
-                &:extend(.abs-product-options-list all);
-                &:extend(.abs-add-clearfix all);
-            }
+      .page-main & {
+        .block {
+          margin-bottom: 0;
+        }
+      }
+
+      .checkout-methods-items {
+        &:extend(.abs-reset-list all);
+        margin: 20px 0 0;
+        padding: 0 @mobile-cart-padding;
+        text-align: center;
+        .action.primary.checkout {
+          &:extend(.abs-button-l all);
+          width: 100%;
+        }
+        .item {
+          margin-bottom: 25px;
+          &:last-child {
+            margin-bottom: 0;
+          }
+        }
+      }
 
-            .product-item-name + .item-options {
-                margin-top: @indent__base;
-            }
+      .message {
+        padding-left: 20px;
+        > *:first-child:before {
+          display: none;
+        }
+      }
+      &:extend(.abs-adjustment-incl-excl-tax all);
+    }
 
-            .cart-tax-total {
-                &:extend(.abs-tax-total all);
-                &-expanded {
-                    &:extend(.abs-tax-total-expanded all);
-                }
-            }
-            .product-image-wrapper {
-                &:extend(.abs-reset-image-wrapper all);
-            }
-            .action.configure {
-                display: inline-block;
-                margin: @indent__s 0 0;
-            }
-            .item .message {
-                margin-top: @indent__base;
-            }
+    //  Totals block
+    &-totals {
+      &:extend(.abs-sidebar-totals all);
+      tbody,
+      tfoot {
+        .mark {
+          text-align: left;
         }
+      }
+    }
 
-        //  Discount
-        &-discount {
+    //  Products table
+    &.table-wrapper {
+      .cart {
+        thead {
+          tr th.col {
             border-bottom: @border-width__base solid @border-color__base;
-            clear: left;
-            .block {
-                &:extend(.abs-cart-block all);
-                > .title {
-                    strong {
-                        color: @color-blue1;
-                        font-weight: @font-weight__regular;
-                    }
-                }
-            }
-            .fieldset > .field > .label {
-                display: none;
-            }
-            .actions-toolbar .primary {
-                .action {
-                    &.primary,
-                    &.cancel {
-                        &:extend(.abs-revert-to-action-secondary all);
-                        border-bottom-left-radius: 0;
-                        border-top-left-radius: 0;
-                    }
-                }
-            }
-            .action.check {
-                &:extend(.abs-action-button-as-link all);
-                font-weight: @font-weight__regular;
-            }
-            .fieldset {
-                display: table;
-                width: 100%;
-            }
-            .field {
-                display: table-cell;
-            }
-            .actions-toolbar {
-                display: table-cell;
-                vertical-align: top;
-                width: 1%;
-                .action {
-                    &.primary,
-                    &.cancel {
-                        border-bottom-left-radius: 0;
-                        border-top-left-radius: 0;
-                        margin: 0 0 0 -1px;
-                        white-space: nowrap;
-                        width: auto;
-                    }
-                }
-                .secondary {
-                    bottom: 5px;
-                    left: @mobile-cart-padding;
-                    position: absolute;
-                }
-            }
+            padding-bottom: 15px;
+            padding-top: 24px;
+          }
         }
-
-        //  Empty cart
-        &-empty {
-            padding-left: @layout__width-xs-indent;
-            padding-right: @layout__width-xs-indent;
+        tbody {
+          td {
+            border: 0;
+          }
+        }
+        > .item {
+          border-bottom: @border-width__base solid @border-color__base;
+          position: relative;
+        }
+      }
+      .col {
+        padding-top: 15px;
+        &.price,
+        &.subtotal,
+        &.msrp {
+          padding: @cart-item-cell-padding-top 11px @indent__s;
+          text-align: center;
+          &:extend(.abs-incl-excl-tax all);
+        }
+        &.qty {
+          padding: 20px 11px @indent__s;
+          text-align: center;
+          .label {
+            &:extend(.abs-visually-hidden all);
+          }
+          .input-text {
+            height: 36px;
+            margin-top: -7px;
+            text-align: center;
+            width: 45px;
+          }
+        }
+        > .price {
+          .css(color, @primary__color__lighter);
+          .font-size(18);
+          font-weight: @font-weight__bold;
+        }
+      }
+
+      .item-actions {
+        td {
+          padding-bottom: 0;
+          padding-left: @mobile-cart-padding;
+          padding-right: @mobile-cart-padding;
+          white-space: normal;
+        }
+      }
+      .item {
+        .col.item {
+          display: block;
+          min-height: 75px;
+          padding: 15px @mobile-cart-padding @indent__s 90px;
+          position: relative;
+        }
+      }
+
+      .actions-toolbar {
+        &:extend(.abs-add-clearfix all);
+        min-height: 20px;
+        padding-bottom: 15px;
+        position: relative;
+        > .action-edit,
+        > .action-delete {
+          position: absolute;
+          right: 16px;
+          top: 0;
+          .icon-font(
+          @icon-edit,
+          @_icon-font-size: 18px,
+          @_icon-font-line-height: 20px,
+          @_icon-font-text-hide: true,
+          @_icon-font-color: @minicart-icons-color,
+          @_icon-font-color-hover: @primary__color,
+          @_icon-font-color-active: @minicart-icons-color
+          );
+        }
+        > .action-delete {
+          right: 0;
+          .icon-font-symbol(
+          @_icon-font-content: @icon-trash
+          );
+        }
+      }
+      .action {
+        margin-right: @indent__m;
+        &:last-child {
+          margin-right: 0;
+        }
+        &.help.map {
+          &:extend(.abs-action-button-as-link all);
+          font-weight: @font-weight__regular;
+        }
+      }
+
+      .product {
+        &-item-photo {
+          display: block;
+          left: @mobile-cart-padding;
+          max-width: 65px;
+          padding: 0;
+          position: absolute;
+          top: 15px;
+          width: 100%;
         }
+        &-item-name {
+          display: block;
+          .font-size(18);
+          margin: -3px 0 @indent__xs;
+        }
+      }
+      .gift-registry-name-label {
+        &:after {
+          content: ':';
+        }
+      }
+
+      //  Product options
+      .item-options {
+        margin-bottom: 0;
+        &:extend(.abs-product-options-list all);
+        &:extend(.abs-add-clearfix all);
+      }
+
+      .product-item-name + .item-options {
+        margin-top: @indent__base;
+      }
+
+      .cart-tax-total {
+        &:extend(.abs-tax-total all);
+        &-expanded {
+          &:extend(.abs-tax-total-expanded all);
+        }
+      }
+      .product-image-wrapper {
+        &:extend(.abs-reset-image-wrapper all);
+      }
+      .action.configure {
+        display: inline-block;
+        margin: @indent__s 0 0;
+      }
+      .item .message {
+        margin-top: @indent__base;
+      }
+    }
 
-        .cart-tax-info + .cart-tax-total {
-            display: block;
+    //  Discount
+    &-discount {
+      border-bottom: @border-width__base solid @border-color__base;
+      clear: left;
+      .block {
+        &:extend(.abs-cart-block all);
+        > .title {
+          strong {
+            color: @color-blue1;
+            font-weight: @font-weight__regular;
+          }
         }
+      }
+      .fieldset > .field > .label {
+        display: none;
+      }
+      .actions-toolbar .primary {
+        .action {
+          &.primary,
+          &.cancel {
+            &:extend(.abs-revert-to-action-secondary all);
+            border-bottom-left-radius: 0;
+            border-top-left-radius: 0;
+          }
+        }
+      }
+      .action.check {
+        &:extend(.abs-action-button-as-link all);
+        font-weight: @font-weight__regular;
+      }
+      .fieldset {
+        display: table;
+        width: 100%;
+      }
+      .field {
+        display: table-cell;
+      }
+      .actions-toolbar {
+        display: table-cell;
+        vertical-align: top;
+        width: 1%;
+        .action {
+          &.primary,
+          &.cancel {
+            border-bottom-left-radius: 0;
+            border-top-left-radius: 0;
+            margin: 0 0 0 -1px;
+            white-space: nowrap;
+            width: auto;
+          }
+        }
+        .secondary {
+          bottom: 5px;
+          left: @mobile-cart-padding;
+          position: absolute;
+        }
+      }
     }
+
+    //  Empty cart
+    &-empty {
+      padding-left: @layout__width-xs-indent;
+      padding-right: @layout__width-xs-indent;
+    }
+
+    .cart-tax-info + .cart-tax-total {
+      display: block;
+    }
+  }
 }
 
 //
@@ -467,110 +380,97 @@
 //  _____________________________________________
 
 .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) {
-    .cart {
-        &-totals {
-            .table.totals {
-                th {
-                    &:extend(.abs-col-no-prefix all);
-                    display: table-cell;
-                }
-                td {
-                    &:extend(.abs-col-no-prefix all);
-                    display: table-cell;
-                }
-                tbody tr:not(:last-child) td {
-                    &:extend(.abs-no-border-bottom-top all);
-                }
-                .amount {
-                    text-align: right;
-                }
-            }
-        }
-        .table.items {
-            .col.item,
-            .item-actions td {
-                &:extend(.abs-col-no-prefix all);
-            }
-            .col.qty {
-                text-align: center;
-            }
-            tbody > tr > td:last-child {
-                &:extend(.abs-no-border-bottom-top all);
-            }
-        }
+  .cart {
+    &-totals {
+      .totals {
+        &:extend(.abs-sidebar-totals-mobile all);
+      }
+    }
+    .table.items {
+      .col.item,
+      .item-actions td {
+        &:extend(.abs-col-no-prefix all);
+      }
+      .col.qty {
+        text-align: center;
+      }
+      tbody > tr > td:last-child {
+        &:extend(.abs-no-border-bottom-top all);
+      }
     }
+  }
 }
 
 .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) {
-    .cart {
-        //  Cart container
-        &-container {
-            .form-cart {
-                .actions.main {
-                    text-align: center;
-                }
-            }
+  .cart {
+    //  Cart container
+    &-container {
+      .form-cart {
+        .actions.main {
+          text-align: center;
         }
+      }
+    }
 
-        &-discount {
-            border-bottom: @border-width__base solid @border-color__base;
-        }
+    &-discount {
+      border-bottom: @border-width__base solid @border-color__base;
+    }
 
-        &.table-wrapper {
-            border-top: @border-width__base solid @border-color__base;
-            thead {
-                .col {
-                    &.item,
-                    &.qty,
-                    &.price,
-                    &.subtotal,
-                    &.msrp {
-                        display: none;
-                    }
-                }
-            }
-            .col {
-                &.qty,
-                &.price,
-                &.subtotal,
-                &.msrp {
-                    box-sizing: border-box;
-                    display: block;
-                    float: left;
-                    white-space: nowrap;
-                    width: 33%;
-                    &:before {
-                        content: attr(data-th);
-                        display: block;
-                        font-weight: @font-weight__semibold;
-                        padding-bottom: 10px;
-                    }
-                }
-                &.msrp {
-                    white-space: normal;
-                }
-            }
-            .item .col.item {
-                padding-bottom: 0;
-            }
-            tbody > tr > td:last-child {
-                border: 0;
-            }
+    &.table-wrapper {
+      border-top: @border-width__base solid @border-color__base;
+      thead {
+        .col {
+          &.item,
+          &.qty,
+          &.price,
+          &.subtotal,
+          &.msrp {
+            display: none;
+          }
+        }
+      }
+      .col {
+        &.qty,
+        &.price,
+        &.subtotal,
+        &.msrp {
+          box-sizing: border-box;
+          display: block;
+          float: left;
+          white-space: nowrap;
+          width: 33%;
+          &:before {
+            content: attr(data-th);
+            display: block;
+            font-weight: @font-weight__semibold;
+            padding-bottom: 10px;
+          }
         }
+        &.msrp {
+          white-space: normal;
+        }
+      }
+      .item .col.item {
+        padding-bottom: 0;
+      }
+      tbody > tr > td:last-child {
+        border: 0;
+      }
+    }
 
-        &-totals {
-            padding-left: @mobile-cart-padding;
-            padding-right: @mobile-cart-padding;
-            .table-wrapper {
-                border-top: 0;
-            }
-            .totals {
-                tbody > tr:not(:last-child) > td:last-child {
-                    border: 0;
-                }
-            }
+    &-totals {
+      padding-left: @mobile-cart-padding;
+      padding-right: @mobile-cart-padding;
+      .table-wrapper {
+        border-top: 0;
+      }
+      .totals {
+        tbody > tr:not(:last-child) > td:last-child {
+          border: 0;
         }
+      }
     }
+  }
 }
 
 
@@ -579,14 +479,14 @@
 //  _____________________________________________
 
 & when (@media-common = true) {
-    //  Cross sell
-    .block.crosssell {
-        margin-top: 70px;
-        .css(padding, 0 @mobile-cart-padding);
-        .product-item-info {
-            width: 200px;
-        }
+  //  Cross sell
+  .block.crosssell {
+    margin-top: 70px;
+    .css(padding, 0 @mobile-cart-padding);
+    .product-item-info {
+      width: 200px;
     }
+  }
 }
 
 //
@@ -594,150 +494,150 @@
 //  _____________________________________________
 
 .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
-    .checkout-cart-index {
-        .page-main {
-            padding-left: @layout__width-xs-indent;
-            padding-right: @layout__width-xs-indent;
-        }
-        .page-title-wrapper {
-            &:extend(.abs-revert-side-paddings all);
-        }
+  .checkout-cart-index {
+    .page-main {
+      padding-left: @layout__width-xs-indent;
+      padding-right: @layout__width-xs-indent;
     }
-    .cart {
-        //  Cart container
-        &-container {
-            &:extend(.abs-add-clearfix-desktop all);
-            .form-cart {
-                &:extend(.abs-shopping-cart-items-desktop all);
-                .actions.main {
-                    text-align: right;
-                }
-            }
-            .widget {
-                float: left;
-            }
+    .page-title-wrapper {
+      &:extend(.abs-revert-side-paddings all);
+    }
+  }
+  .cart {
+    //  Cart container
+    &-container {
+      &:extend(.abs-add-clearfix-desktop all);
+      .form-cart {
+        &:extend(.abs-shopping-cart-items-desktop all);
+        .actions.main {
+          text-align: right;
         }
+      }
+      .widget {
+        float: left;
+      }
+    }
 
-        //  Summary block
-        &-summary {
-            .layout-column(2, 2, @layout-column-checkout__width-left);
-            padding: 1px @indent__base @indent__m;
-            position: relative;
-            > .title {
-                display: block;
-            }
-            .fieldset .actions-toolbar {
-                margin-left: 0;
-                > .secondary {
-                    float: none;
-                }
-            }
-            .block {
-                > .title {
-                    padding-left: 0;
-                    &:after {
-                        right: 3px;
-                    }
-                }
-                .content {
-                    &:extend(.abs-revert-side-paddings all);
-                }
-                .fieldset {
-                    .field {
-                        .form-field-type-revert(@_type: block);
-                        margin: 0 0 @indent__s;
-                    }
-                }
-            }
-            .checkout-methods-items {
-                padding: 0;
-            }
+    //  Summary block
+    &-summary {
+      .layout-column(2, 2, @layout-column-checkout__width-left);
+      padding: 1px @indent__base @indent__m;
+      position: relative;
+      > .title {
+        display: block;
+      }
+      .fieldset .actions-toolbar {
+        margin-left: 0;
+        > .secondary {
+          float: none;
         }
+      }
+      .block {
+        > .title {
+          padding-left: 0;
+          &:after {
+            right: 3px;
+          }
+        }
+        .content {
+          &:extend(.abs-revert-side-paddings all);
+        }
+        .fieldset {
+          .field {
+            .form-field-type-revert(@_type: block);
+            margin: 0 0 @indent__s;
+          }
+        }
+      }
+      .checkout-methods-items {
+        padding: 0;
+      }
+    }
 
-        //  Products table
-        &.table-wrapper {
-            tbody td {
-                padding-top: @cart-item-cell-padding-top;
-            }
-
-            .item {
-                .col.item {
-                    padding: @cart-item-cell-padding-top 8px 20px 0;
-                }
-            }
-
-            .item-actions td {
-                padding: 0;
-            }
+    //  Products table
+    &.table-wrapper {
+      tbody td {
+        padding-top: @cart-item-cell-padding-top;
+      }
 
-            .product {
-                &-item-photo {
-                    display: table-cell;
-                    max-width: 100%;
-                    padding-right: 20px;
-                    position: static;
-                    vertical-align: top;
-                    width: 1%;
-                }
-                &-item-details {
-                    padding-bottom: 35px;
-                }
-                &-item-details {
-                    display: table-cell;
-                    vertical-align: top;
-                    white-space: normal;
-                    width: 99%;
-                }
-            }
+      .item {
+        .col.item {
+          padding: @cart-item-cell-padding-top 8px 20px 0;
         }
-
-        //  Discount
-        &-discount {
-            border: 0;
-            .layout-column(2, 1, @layout-column-checkout__width-main);
-            &:extend(.abs-add-box-sizing-desktop all);
-            padding-right: 4%;
-            .block {
-                &:extend(.abs-blocks-2columns all);
-                width: 48%;
-                > .title {
-                    border: 0;
-                    cursor: default;
-                    padding: 0 0 10px;
-                    .column.main & strong {
-                        .font-size(16);
-                    }
-                    &:after {
-                        display: none;
-                    }
-                }
-                .content {
-                    display: block !important; // Need for overwriting collapsible widget
-                    padding: 0;
-                }
-            }
-            .actions-toolbar {
-                .secondary {
-                    bottom: -30px;
-                    left: 0;
-                    position: absolute;
-                }
-            }
+      }
+
+      .item-actions td {
+        padding: 0;
+      }
+
+      .product {
+        &-item-photo {
+          display: table-cell;
+          max-width: 100%;
+          padding-right: 20px;
+          position: static;
+          vertical-align: top;
+          width: 1%;
         }
-
-        //  Empty cart
-        &-empty {
-            &:extend(.abs-revert-side-paddings all);
+        &-item-details {
+          padding-bottom: 35px;
         }
+        &-item-details {
+          display: table-cell;
+          vertical-align: top;
+          white-space: normal;
+          width: 99%;
+        }
+      }
     }
 
-    //  Cross sell
-    .block.crosssell {
-        .layout-column(2, 1, @layout-column-checkout__width-main);
-        &:extend(.abs-add-box-sizing-desktop all);
-        padding: 0 4% 0 0;
-        .products-grid .product-item {
-            width: 100%/4;
+    //  Discount
+    &-discount {
+      border: 0;
+      .layout-column(2, 1, @layout-column-checkout__width-main);
+      &:extend(.abs-add-box-sizing-desktop all);
+      padding-right: 4%;
+      .block {
+        &:extend(.abs-blocks-2columns all);
+        width: 48%;
+        > .title {
+          border: 0;
+          cursor: default;
+          padding: 0 0 10px;
+          .column.main & strong {
+            .font-size(16);
+          }
+          &:after {
+            display: none;
+          }
+        }
+        .content {
+          display: block !important; // Need for overwriting collapsible widget
+          padding: 0;
         }
+      }
+      .actions-toolbar {
+        .secondary {
+          bottom: -30px;
+          left: 0;
+          position: absolute;
+        }
+      }
+    }
+
+    //  Empty cart
+    &-empty {
+      &:extend(.abs-revert-side-paddings all);
+    }
+  }
+
+  //  Cross sell
+  .block.crosssell {
+    .layout-column(2, 1, @layout-column-checkout__width-main);
+    &:extend(.abs-add-box-sizing-desktop all);
+    padding: 0 4% 0 0;
+    .products-grid .product-item {
+      width: 100%/4;
     }
+  }
 }
diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_minicart.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_minicart.less
index ddeb77db7fdfda33523a0f4a167f393ece533d43..86564ca26cb6aa19691789f4b16a2917b8f84744 100644
--- a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_minicart.less
+++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/_minicart.less
@@ -5,330 +5,332 @@
 
 //
 //  Variables
-//  ---------------------------------------------
+//  _____________________________________________
 
 @minicart__border-color: @color-gray80;
 @minicart__padding-horizontal: @indent__base;
 
 //
 //  Common
-//  ---------------------------------------------
+//  _____________________________________________
 
 & when (@media-common = true) {
 
-//
-//  Minicart
-//  ---------------------------------------------
+    //
+    //  Minicart
+    //  ---------------------------------------------
 
-.block-minicart {
-    .items-total {
-        float: left;
-        margin: 0 @indent__s;
-        .count {
-            font-weight: @font-weight__bold;
+    .block-minicart {
+        .items-total {
+            float: left;
+            margin: 0 @indent__s;
+            .count {
+                font-weight: @font-weight__bold;
+            }
         }
-    }
-    .subtotal {
-        margin: 0 @indent__s;
-        text-align: right;
-        .label {
-            &:extend(.abs-colon all);
+        .subtotal {
+            margin: 0 @indent__s;
+            text-align: right;
+            .label {
+                &:extend(.abs-colon all);
+            }
         }
-    }
-    .amount {
-        .price-wrapper {
-            &:first-child {
-                .price {
-                    font-size: @font-size__l;
-                    font-weight: @font-weight__bold;
+        .amount {
+            .price-wrapper {
+                &:first-child {
+                    .price {
+                        font-size: @font-size__l;
+                        font-weight: @font-weight__bold;
+                    }
                 }
             }
         }
-    }
-    .subtitle {
-        display: none;
-    }
-    .subtitle {
-        &.empty {
-            display: block;
-            padding: @indent__l 0 @indent__base;
-            text-align: center;
-            font-size: 14px;
-        }
-    }
-    .text {
-        &.empty {
-            text-align: center;
+        .subtitle {
+            display: none;
+            &.empty {
+                display: block;
+                padding: @indent__l 0 @indent__base;
+                text-align: center;
+                font-size: 14px;
+            }
         }
-    }
-    .block-content {
-        > .actions {
-            margin-top: 15px;
-            > .secondary {
+        .text {
+            &.empty {
                 text-align: center;
             }
-            > .primary {
-                margin: 0 @indent__s 15px;
-                .action {
-                    &.primary {
-                        &:extend(.abs-button-l all);
-                        display: block;
-                        width: 100%;
+        }
+        .block-content {
+            > .actions {
+                margin-top: 15px;
+                > .secondary {
+                    text-align: center;
+                }
+                > .primary {
+                    margin: 0 @indent__s 15px;
+                    .action {
+                        &.primary {
+                            &:extend(.abs-button-l all);
+                            display: block;
+                            width: 100%;
+                        }
                     }
                 }
-            }
-            .paypal-logo {
-                margin-top: 15px;
-                text-align: center;
+                .paypal-logo {
+                    margin-top: 15px;
+                    text-align: center;
+                }
             }
         }
+        .block-category-link,
+        .block-product-link,
+        .block-cms-link,
+        .block-banners {
+            margin: 15px 0 0;
+            text-align: center;
+        }
     }
-    .block-category-link,
-    .block-product-link,
-    .block-cms-link,
-    .block-banners {
-        margin: 15px 0 0;
-        text-align: center;
-    }
-}
 
-.minicart-wrapper {
-    .dropdown(
-        @_toggle-selector: ~".action.showcart",
-        @_options-selector: ~".block-minicart",
-        @_dropdown-toggle-icon-content: @icon-cart,
-        @_dropdown-toggle-active-icon-content: @icon-cart,
-        @_dropdown-list-item-padding: false,
-        @_dropdown-list-item-hover: false,
-        @_icon-font-position: before,
-        @_icon-font-size: 22px,
-        @_icon-font-line-height: 28px,
-        @_icon-font-color: @minicart-icons-color,
-        @_icon-font-color-hover: @minicart-icons-color-hover,
-        @_icon-font-color-active: @minicart-icons-color
-    );
-    float: right;
-    .block-minicart {
-        .css(padding, 25px @minicart__padding-horizontal);
-        right: 0;
-        width: 320px;
-        .block-title {
-            display: none;
-        }
-        &:after {
-            left: auto;
-            right: 25px;
-        }
-        &:before {
-            left: auto;
-            right: 26px;
+    .minicart-wrapper {
+        .dropdown(
+            @_toggle-selector: ~".action.showcart",
+            @_options-selector: ~".block-minicart",
+            @_dropdown-toggle-icon-content: @icon-cart,
+            @_dropdown-toggle-active-icon-content: @icon-cart,
+            @_dropdown-list-item-padding: false,
+            @_dropdown-list-item-hover: false,
+            @_icon-font-position: before,
+            @_icon-font-size: 22px,
+            @_icon-font-line-height: 28px,
+            @_icon-font-color: @minicart-icons-color,
+            @_icon-font-color-hover: @minicart-icons-color-hover,
+            @_icon-font-color-active: @minicart-icons-color
+        );
+        float: right;
+        .block-minicart {
+            .css(padding, 25px @minicart__padding-horizontal);
+            right: 0;
+            width: 320px;
+            .block-title {
+                display: none;
+            }
+            &:after {
+                left: auto;
+                right: 25px;
+            }
+            &:before {
+                left: auto;
+                right: 26px;
+            }
         }
-    }
-    .product {
-        .actions {
-            float: right;
-            margin: -24px 0 0;
-            > .primary,
-            > .secondary {
-                display: inline;
-                &:not(:last-child) {
-                    margin-right: 15px;
+        .product {
+            .actions {
+                float: right;
+                margin: -24px 0 0;
+                > .primary,
+                > .secondary {
+                    display: inline;
+                    &:not(:last-child) {
+                        margin-right: 15px;
+                    }
                 }
             }
         }
-    }
-    .action {
-        &.close {
-            width: 40px;
-            height: 40px;
-            top: 0;
-            right: 0;
-            position: absolute;
-            .button-reset();
-            .button-icon(
-                @icon-remove,
-                @_icon-font-color: @minicart-icons-color,
-                @_icon-font-size: 16px,
-                @_icon-font-line-height: 16px,
-                @_icon-font-text-hide: true
-            );
-        }
-        &.showcart {
-            .text {
-                &:extend(.abs-visually-hidden all);
+        .action {
+            &.close {
+                width: 40px;
+                height: 40px;
+                top: 0;
+                right: 0;
+                position: absolute;
+                .button-reset();
+                .button-icon(
+                    @icon-remove,
+                    @_icon-font-color: @minicart-icons-color,
+                    @_icon-font-size: 16px,
+                    @_icon-font-line-height: 16px,
+                    @_icon-font-text-hide: true
+                );
             }
-            white-space: nowrap;
-            .counter.qty {
-                &.empty {
-                   display: none;
+            &.showcart {
+                .text {
+                    &:extend(.abs-visually-hidden all);
+                }
+                white-space: nowrap;
+                .counter.qty {
+                    &.empty {
+                       display: none;
+                    }
+                    .css(background, @active__color);
+                    border-radius: 2px;
+                    .css(color, @page__background-color);
+                    clip: none;
+                    display: inline-block;
+                    height: 24px;
+                    line-height: 24px;
+                    min-width: 18px;
+                    margin: 3px 0 0;
+                    padding: 0 3px;
+                    overflow: hidden;
+                    text-align: center;
+                    white-space: normal;
+                }
+                .counter-label {
+                    &:extend(.abs-visually-hidden all);
                 }
-                .css(background, @active__color);
-                border-radius: 2px;
-                .css(color, @page__background-color);
-                clip: none;
-                display: inline-block;
-                height: 24px;
-                line-height: 24px;
-                min-width: 18px;
-                margin: 3px 0 0;
-                padding: 0 3px;
-                overflow: hidden;
-                text-align: center;
-                white-space: normal;
-            }
-            .counter-label {
-                &:extend(.abs-visually-hidden all);
             }
         }
+        .minicart-widgets {
+            margin-top: 15px;
+        }
     }
-    .minicart-widgets {
-        margin-top: 15px;
-    }
-}
 
-.minicart-items-wrapper {
-    .css(border, 1px solid @minicart__border-color);
-    .css(margin, 0 -@minicart__padding-horizontal);
-    border-left: 0;
-    border-right: 0;
-    overflow-x: auto;
-    padding: 15px;
-}
+    .minicart-items-wrapper {
+        .css(border, 1px solid @minicart__border-color);
+        .css(margin, 0 -@minicart__padding-horizontal);
+        border-left: 0;
+        border-right: 0;
+        overflow-x: auto;
+        padding: 15px;
+    }
 
-.minicart-items {
-    .list-reset-styles(0, 0);
-    .item {
-        &:not(:first-child) {
-            .css(border-top, 1px solid @minicart__border-color);
-        }
-        padding: @indent__base 0;
-        &:first-child {
-            padding-top: 0;
-        }
-        > .product {
-            &:extend(.abs-add-clearfix all);
+    .minicart-items {
+        .list-reset-styles(0, 0);
+        .product-item {
+            &:not(:first-child) {
+                .css(border-top, 1px solid @minicart__border-color);
+            }
+            padding: @indent__base 0;
+            &:first-child {
+                padding-top: 0;
+            }
+            > .product {
+                &:extend(.abs-add-clearfix all);
+            }
         }
-    }
-    .product-image-wrapper {
-        &:extend(.abs-reset-image-wrapper all);
-    }
-    .product-item-pricing {
-        .label {
-            display: inline-block;
-            width: 4.5rem;
+        .product-image-wrapper {
+            &:extend(.abs-reset-image-wrapper all);
         }
-    }
-    .price-minicart {
-        margin-bottom: @indent__xs;
-    }
-    .product-item-photo {
-        float: left;
-    }
-    .product-item-name {
-        font-weight: @font-weight__regular;
-        margin: 0 0 @indent__s;
-        a {
-            .css(color, @link__color);
-        }
-    }
-    .product-item-details {
-        padding-left: 88px;
-        .price {
-            font-weight: @font-weight__bold;
+        .product-item-pricing {
+            .label {
+                display: inline-block;
+                width: 4.5rem;
+            }
         }
-        .price-including-tax,
-        .price-excluding-tax {
-            margin: @indent__xs 0;
+        .price-minicart {
+            margin-bottom: @indent__xs;
         }
-        .weee[data-label] {
-            .font-size(11);
-            .label {
-                &:extend(.abs-no-display all);
+        .product-item-name {
+            font-weight: @font-weight__regular;
+            margin: 0 0 @indent__s;
+            a {
+                .css(color, @link__color);
             }
         }
-        .details-qty {
-            margin-top: @indent__s;
+        .product-item-details {
+            padding-left: 88px;
+            .price {
+                font-weight: @font-weight__bold;
+            }
+            .price-including-tax,
+            .price-excluding-tax {
+                margin: @indent__xs 0;
+            }
+            .weee[data-label] {
+                .font-size(11);
+                .label {
+                    &:extend(.abs-no-display all);
+                }
+            }
+            .details-qty {
+                margin-top: @indent__s;
+            }
         }
-    }
-    .product {
-        .toggle {
-            &:extend(.abs-toggling-title all);
-            &:after {
-                position: static;
-                margin: 0 0 0 @indent__xs;
-                .css(color, @color-gray56);
+        .product {
+            > .product-item-photo,
+            > .product-image-container {
+                float: left;
+            }
+            .toggle {
+                &:extend(.abs-toggling-title all);
+                &:after {
+                    position: static;
+                    margin: 0 0 0 @indent__xs;
+                    .css(color, @color-gray56);
+                }
+                border: 0;
+                padding: 0 @indent__xl @indent__xs 0;
+            }
+            .active {
+                > .toggle {
+                    .icon-font-symbol(
+                        @_icon-font-content: @icon-up,
+                        @_icon-font-position: after
+                    );
+                }
+            }
+            &.pricing {
+                margin-top: 3px;
+            }
+            &.options {
+                .tooltip.toggle {
+                    .icon-font(
+                        @icon-down,
+                        @_icon-font-size: 12px,
+                        @_icon-font-line-height: 12px,
+                        @_icon-font-text-hide: true,
+                        @_icon-font-margin: -3px 0 0 7px,
+                        @_icon-font-position: after
+                    );
+                }
+                .details {
+                    display: none;
+                }
             }
-            border: 0;
-            padding: 0 @indent__xl @indent__xs 0;
         }
-        .active {
-            > .toggle {
-                .icon-font-symbol(
-                    @_icon-font-content: @icon-up,
-                    @_icon-font-position: after
-                );
+        .details-qty,
+        .price-minicart {
+            .label {
+                &:extend(.abs-colon all);
             }
         }
-        &.pricing {
-            margin-top: 3px;
+        .item-qty {
+            width: 40px;
+            text-align: center;
+            margin-right: @indent__s;
+        }
+        .update-cart-item {
+            vertical-align: top;
+            .font-size(11);
         }
-        &.options {
-            .tooltip.toggle {
+        .action {
+            &.edit,
+            &.delete {
                 .icon-font(
-                    @icon-down,
-                    @_icon-font-size: 12px,
-                    @_icon-font-line-height: 12px,
+                    @icon-edit,
+                    @_icon-font-size: 18px,
+                    @_icon-font-line-height: 20px,
                     @_icon-font-text-hide: true,
-                    @_icon-font-margin: -3px 0 0 7px,
-                    @_icon-font-position: after
+                    @_icon-font-color: @minicart-icons-color,
+                    @_icon-font-color-hover: @primary__color,
+                    @_icon-font-color-active: @minicart-icons-color
                 );
             }
-            .details {
-                display: none;
+            &.delete {
+                .icon-font-symbol(
+                    @_icon-font-content: @icon-trash
+                );
             }
         }
-    }
-    .details-qty,
-    .price-minicart {
-        .label {
-            &:extend(.abs-colon all);
-        }
-    }
-    .item-qty {
-        width: 40px;
-        text-align: center;
-        margin-right: @indent__s;
-    }
-    .update-cart-item {
-        vertical-align: top;
-        .font-size(11);
-    }
-    .action {
-        &.edit,
-        &.delete {
-            .icon-font(
-                @icon-edit,
-                @_icon-font-size: 18px,
-                @_icon-font-line-height: 20px,
-                @_icon-font-text-hide: true,
-                @_icon-font-color: @minicart-icons-color,
-                @_icon-font-color-hover: @primary__color,
-                @_icon-font-color-active: @minicart-icons-color
-            );
-        }
-        &.delete {
-            .icon-font-symbol(
-                @_icon-font-content: @icon-trash
-            );
+        .subtitle {
+            display: none;
         }
     }
-}
 
 }
 
 //
 //  Mobile
-//  ---------------------------------------------
+//  _____________________________________________
 
 .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__xs) {
     .minicart-wrapper .block-minicart {
@@ -345,7 +347,7 @@
 
 //
 //  Desktop
-//  ---------------------------------------------
+//  _____________________________________________
 
 .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
     .minicart-wrapper {
diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_checkout.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_checkout.less
new file mode 100644
index 0000000000000000000000000000000000000000..f8f2ee61ddae6ef52ea6ee2ca6a73c0b2c118cde
--- /dev/null
+++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_checkout.less
@@ -0,0 +1,94 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+@checkout-wrapper__margin: @indent__base;
+@checkout-wrapper__columns: 16;
+
+@checkout-step-title__border: @border-width__base solid @color-gray80;
+@checkout-step-title__font-size: 26px;
+@checkout-step-title__font-weight: @font-weight__light;
+@checkout-step-title__margin-bottom: 28px;
+@checkout-step-title__padding: @indent__s;
+
+@checkout-step-title-mobile__font-size: 18px;
+@checkout-step-title-mobile__margin-bottom: @indent__base;
+
+@checkout-step-content-mobile__background: @color-gray-light01;
+@checkout-step-content-mobile__margin-s: 15px;
+@checkout-step-content-mobile__margin: 0 -(@checkout-step-content-mobile__margin-s) @checkout-step-content-mobile__margin-s;
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+
+    .checkout-container {
+        &:extend(.abs-add-clearfix all);
+        .css(margin, 0 0 @checkout-wrapper__margin);
+    }
+
+    .opc-wrapper {
+        .css(margin, 0 0 @checkout-wrapper__margin);
+
+        .opc {
+            &:extend(.abs-reset-list all);
+        }
+
+        .step-title {
+            &:extend(.abs-checkout-title all);
+            .css(border-bottom, @checkout-step-title__border);
+            .css(margin, 0 0 @checkout-step-title__margin-bottom);
+        }
+
+        .step-content {
+            margin: 0 0 @indent__xl;
+        }
+    }
+
+    .checkout-onepage-index {
+        .nav-sections,
+        .nav-toggle {
+            display: none;
+        }
+        .logo {
+            margin-left: 0;
+        }
+    }
+}
+
+//
+//  Mobile
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) {
+    .opc-wrapper {
+        .step-title {
+            .css(font-size, @checkout-step-title-mobile__font-size);
+            .css(margin-bottom, @checkout-step-title-mobile__margin-bottom);
+            border-bottom: 0;
+            padding-bottom: 0;
+        }
+        .step-content {
+            .css(margin, 0 0 @checkout-step-content-mobile__margin-s);
+        }
+    }
+}
+
+//
+//  Desktop
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
+    .opc-wrapper {
+       &:extend(.abs-add-box-sizing-desktop-m all);
+        .layout-column(2, 1, @checkout-wrapper__columns);
+        padding-right: @indent__l;
+    }
+}
diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_estimated-total.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_estimated-total.less
new file mode 100644
index 0000000000000000000000000000000000000000..ccef519f1cbb1cbb51a1937d9a1ee524e74d621b
--- /dev/null
+++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_estimated-total.less
@@ -0,0 +1,58 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+
+    //
+    //  Checkout Estimated Total
+    //  ---------------------------------------------
+
+    .opc-estimated-wrapper {
+        &:extend(.abs-no-display-desktop all);
+        &:extend(.abs-add-clearfix all);
+        .css(background, @checkout-step-content-mobile__background);
+        .css(border-bottom, @checkout-step-title__border);
+        .css(border-top, @checkout-step-title__border);
+        .css(margin, -21px -(@checkout-step-content-mobile__margin-s) @checkout-step-content-mobile__margin-s);
+        padding: 18px 15px;
+
+        .estimated-block {
+            .css(font-size, @checkout-step-title-mobile__font-size);
+            float: left;
+            font-weight: @font-weight__bold;
+
+            .estimated-label {
+                display: block;
+                margin: 0 0 @indent__xs;
+            }
+        }
+
+        .minicart-wrapper {
+            button {
+                // todo ui: Change .action.showcart to .action-showcart
+                &.action.showcart {
+                    .button-reset();
+                    &:before {
+                        .css(color, @primary__color);
+                    }
+                }
+            }
+        }
+    }
+}
+
+//
+//  Desktop
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__s) {
+    .opc-estimated-wrapper {
+        display: none;
+    }
+}
diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_modals.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_modals.less
new file mode 100644
index 0000000000000000000000000000000000000000..7b2c5a55d6aa4e9000be31b548c098fa17adf33d
--- /dev/null
+++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_modals.less
@@ -0,0 +1,90 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+@checkout-modal-popup__width: 800px;
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+    .checkout-onepage-index {
+        .modal-popup {
+            .field-tooltip {
+                .field-tooltip-content {
+                    &:extend(.abs-checkout-tooltip-content-position-top all);
+                }
+            }
+            .fieldset {
+                .field {
+                    .label {
+                        font-weight: @font-weight__regular;
+                    }
+                }
+            }
+            .modal-footer {
+                .action-hide-popup {
+                    &:extend(.abs-action-button-as-link all);
+                    margin-top: 8px;
+                }
+            }
+        }
+    }
+}
+
+//
+//  Mobile
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) {
+    .checkout-onepage-index {
+        .modal-popup {
+            .modal-footer {
+                .action-save-address {
+                    width: 100%;
+                }
+                .action-hide-popup {
+                    margin-top: @indent__base;
+                }
+            }
+        }
+    }
+}
+
+//
+//  Desktop
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
+    .checkout-onepage-index {
+        .modal-popup {
+            .form-shipping-address {
+                .css(max-width, @checkout-shipping-address__max-width);
+            }
+            .modal-footer {
+                .action-save-address {
+                    float: right;
+                    margin: 0 0 0 @indent__base;
+                }
+            }
+        }
+    }
+}
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__l) {
+    .checkout-onepage-index {
+        .modal-popup {
+            .modal-inner-wrap {
+                .css(margin-left, -(@checkout-modal-popup__width/2));
+                .css(width, @checkout-modal-popup__width);
+                left: 50%;
+            }
+        }
+    }
+}
diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_order-summary.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_order-summary.less
new file mode 100644
index 0000000000000000000000000000000000000000..b77969dddddadfcd9985ed4fde68e3ef7aa9a5b6
--- /dev/null
+++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_order-summary.less
@@ -0,0 +1,188 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+@checkout-summary__background-color: @color-white-smoke;
+@checkout-summary__padding: 22px @indent__l;
+
+@checkout-summary-title__margin: @indent__s;
+@checkout-summary-mark-value__color: @color-gray60;
+
+@checkout-summary-items__max-height: 370px;
+@checkout-summary-items__padding: 15px;
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+
+    //
+    //  Order Summary
+    //  ---------------------------------------------
+
+    .opc-block-summary {
+        .css(background, @checkout-summary__background-color);
+        .css(margin, 0 0 @checkout-sidebar__margin);
+        .css(padding, @checkout-summary__padding);
+        &:extend(.abs-add-box-sizing all);
+
+        > .title {
+            &:extend(.abs-checkout-title all);
+            display: block;
+        }
+
+        //  Totals table
+        .table-totals {
+            &:extend(.abs-sidebar-totals all);
+        }
+
+        .mark {
+            .value {
+                .css(color, @checkout-summary-mark-value__color);
+                display: block;
+            }
+        }
+
+        .grand.incl {
+            & + .grand.excl {
+                .mark,
+                .amount {
+                    border-top: 0;
+                    .font-size(14);
+                    padding-top: 0;
+                    strong {
+                        font-weight: @font-weight__regular;
+                    }
+                }
+            }
+        }
+
+        .not-calculated {
+            font-style: italic;
+        }
+
+        //
+        //  Items list
+        //  ---------------------------------------------
+
+        //  Block title
+        .items-in-cart {
+            > .title {
+                border-bottom: @border-width__base solid @border-color__base;
+                .css(padding, @indent__s @indent__xl @indent__s 0);
+                cursor: pointer;
+                .icon-font(
+                @icon-down,
+                @_icon-font-size: 12px,
+                @_icon-font-line-height: 12px,
+                @_icon-font-text-hide: true,
+                @_icon-font-margin: 3px 0 0,
+                @_icon-font-position: after,
+                @_icon-font-display: block
+                );
+                margin-bottom: 0;
+                position: relative;
+                &:after {
+                    position: absolute;
+                    right: 0;
+                    top: @indent__s;
+                }
+                strong {
+                    .font-size(18);
+                    font-weight: @font-weight__light;
+                    margin: 0;
+                }
+            }
+            &.active {
+                > .title {
+                    .icon-font-symbol(
+                    @_icon-font-content: @icon-up,
+                    @_icon-font-position: after
+                    );
+                }
+            }
+            .product {
+                position: relative;
+            }
+        }
+
+        //  Cart items
+        .minicart-items-wrapper {
+            .css(margin, 0 -(@checkout-summary-items__padding) 0 0);
+            .css(max-height, @checkout-summary-items__max-height);
+            .css(padding, @checkout-summary-items__padding @checkout-summary-items__padding 0 0);
+            border: 0;
+        }
+        .column.main & {
+            .product-item {
+                margin: 0;
+                padding-left: 0;
+            }
+        }
+        .product-item {
+            .product-item-inner {
+                display: table;
+                margin: 0 0 @indent__s;
+                width: 100%;
+            }
+            .product-item-name-block {
+                display: table-cell;
+                padding-right: @indent__xs;
+                text-align: left;
+            }
+            .subtotal {
+                display: table-cell;
+                text-align: right;
+            }
+            .price {
+                .font-size(16);
+                font-weight: @font-weight__regular;
+            }
+            .price-including-tax {
+                & + .price-excluding-tax {
+                    .price {
+                        .font-size(10);
+                    }
+                }
+            }
+        }
+    }
+}
+
+//
+//  Mobile
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) {
+    .opc-block-summary {
+        > .title {
+            border-bottom: 0;
+            .css(font-size, @checkout-step-title-mobile__font-size);
+            .css(margin-bottom, @checkout-step-title-mobile__margin-bottom);
+            padding-bottom: 0;
+        }
+        .totals {
+            &:extend(.abs-sidebar-totals-mobile all);
+        }
+    }
+}
+
+//
+//  Desktop
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
+    .opc-summary-wrapper {
+        .modal-header {
+            .action-close {
+                display: none;
+            }
+        }
+    }
+}
diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_progress-bar.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_progress-bar.less
new file mode 100644
index 0000000000000000000000000000000000000000..13b59d044d72bef7d86ee8c84ee5979a3745407c
--- /dev/null
+++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_progress-bar.less
@@ -0,0 +1,181 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+@checkout-progress-bar__font-size: 18px;
+@checkout-progress-bar__font-weight: @font-weight__light;
+@checkout-progress-bar__margin: @indent__base;
+
+@checkout-progress-bar-item__background-color: @color-gray-middle1;
+@checkout-progress-bar-item__border-radius: 6px;
+@checkout-progress-bar-item__color: @primary__color;
+@checkout-progress-bar-item__margin: @indent__s;
+@checkout-progress-bar-item__transition: background .3s;
+@checkout-progress-bar-item__width: 185px;
+
+@checkout-progress-bar-item__active__background-color: @color-orange-red1;
+@checkout-progress-bar-item__complete__color: @link__color;
+@checkout-progress-bar-item__hover__background-color: darken(@checkout-progress-bar-item__background-color, 5%);
+
+@checkout-progress-bar-item-element__height: @checkout-progress-bar-item-element__width;
+@checkout-progress-bar-item-element__width: 38px;
+
+@checkout-progress-bar-item-element-inner__background-color: @page__background-color;
+@checkout-progress-bar-item-element-inner__color: @checkout-progress-bar-item__color;
+@checkout-progress-bar-item-element-inner__height: @checkout-progress-bar-item-element-inner__width;
+@checkout-progress-bar-item-element-inner__width: @checkout-progress-bar-item-element__width - ( @checkout-progress-bar-item-element-outer-radius__width*2 );
+@checkout-progress-bar-item-element-inner__active__content: @icon-checkmark;
+
+@checkout-progress-bar-item-element-outer-radius__width: 6px;
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+
+    //
+    //  Checkout Progress Bar
+    //  ---------------------------------------------
+
+    .opc-progress-bar {
+        &:extend(.abs-no-display-s all);
+        &:extend(.abs-reset-list all);
+    }
+}
+
+//
+//  Desktop
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__s) {
+
+    .opc-progress-bar {
+        .css(margin, 0 0 @checkout-progress-bar__margin);
+        counter-reset: i;
+        font-size: 0;
+    }
+
+    .opc-progress-bar-item {
+        .css(margin, 0 0 @checkout-progress-bar-item__margin);
+        .css(width, @checkout-progress-bar-item__width);
+        display: inline-block;
+        position: relative;
+        text-align: center;
+        vertical-align: top;
+
+        &:before { // Horizontal line
+            .css(background, @checkout-progress-bar-item__background-color);
+            .css(top, @checkout-progress-bar-item-element__width/2);
+            .css(transition, @checkout-progress-bar-item__transition);
+            content: '';
+            height: 7px;
+            left: 0;
+            position: absolute;
+            width: 100%;
+        }
+
+        &:first-child {
+            &:before {
+                .css(border-radius, @checkout-progress-bar-item__border-radius 0 0 @checkout-progress-bar-item__border-radius);
+            }
+        }
+
+        &:last-child {
+            &:before {
+                .css(border-radius, 0 @checkout-progress-bar-item__border-radius @checkout-progress-bar-item__border-radius 0);
+            }
+        }
+
+        > span {
+            display: inline-block;
+            padding-top: 45px;
+            width: 100%;
+            word-wrap: break-word;
+
+            .typography(
+            @_color: @checkout-progress-bar-item__background-color,
+            @_font-family: false,
+            @_font-size: @checkout-progress-bar__font-size,
+            @_font-style: false,
+            @_font-weight: @checkout-progress-bar__font-weight,
+            @_line-height: false
+            );
+
+            &:before, // Item element
+            &:after {
+                .css(background, @checkout-progress-bar-item__background-color);
+                .css(height, @checkout-progress-bar-item-element__height);
+                .css(margin-left, -(@checkout-progress-bar-item-element__width/2));
+                .css(transition, @checkout-progress-bar-item__transition);
+                .css(width, @checkout-progress-bar-item-element__width);
+                border-radius: 50%;
+                content: '';
+                left: 50%;
+                position: absolute;
+                top: 0;
+            }
+
+            &:after { // Item element inner
+                .css(background, @checkout-progress-bar-item-element-inner__background-color);
+                .css(height, @checkout-progress-bar-item-element-inner__height);
+                .css(margin-left, -(@checkout-progress-bar-item-element-inner__width/2));
+                .css(top, @checkout-progress-bar-item-element-outer-radius__width);
+                .css(width, @checkout-progress-bar-item-element-inner__width);
+                content: counter(i);
+                counter-increment: i;
+                .typography(
+                @_color: @checkout-progress-bar-item-element-inner__color,
+                @_font-family: false,
+                @_font-size: @checkout-progress-bar__font-size,
+                @_font-style: false,
+                @_font-weight: @font-weight__semibold,
+                @_line-height: false
+                );
+            }
+        }
+
+        &._complete {
+            cursor: pointer;
+            &:hover {
+                &:before {
+                    .css(background, @checkout-progress-bar-item__hover__background-color);
+                }
+                > span {
+                    &:before {
+                        .css(background, @checkout-progress-bar-item__hover__background-color);
+                    }
+                }
+            }
+            > span {
+                .css(color, @checkout-progress-bar-item__complete__color);
+
+                &:after {
+                    .css(font-family, @icons__font-name);
+                    .css(content, @checkout-progress-bar-item-element-inner__active__content);
+                }
+            }
+        }
+
+        &._active {
+            &:before {
+                background: @checkout-progress-bar-item__active__background-color;
+            }
+            > span {
+                .css(color, @checkout-progress-bar-item__color);
+                &:before {
+                    .css(background, @checkout-progress-bar-item__active__background-color);
+                }
+                &:after {
+                    .css(font-family, @icons__font-name);
+                    .css(content, @checkout-progress-bar-item-element-inner__active__content);
+                }
+            }
+        }
+    }
+}
diff --git a/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_shipping.less b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_shipping.less
new file mode 100644
index 0000000000000000000000000000000000000000..fb2d200134402a5cc74cf30552da410b542dc21e
--- /dev/null
+++ b/app/design/frontend/Magento/luma/Magento_Checkout/web/css/source/module/checkout/_shipping.less
@@ -0,0 +1,340 @@
+// /**
+//  * Copyright © 2015 Magento. All rights reserved.
+//  * See COPYING.txt for license details.
+//  */
+
+//
+//  Variables
+//  _____________________________________________
+
+@checkout-shipping-address__max-width: 500px;
+
+@checkout-shipping-item-icon__background-color: @checkout-shipping-item__active__border-color;
+@checkout-shipping-item-icon__color: @color-white;
+@checkout-shipping-item-icon__content: @icon-checkmark;
+
+@checkout-shipping-item__border: 2px solid transparent;
+@checkout-shipping-item__line-height: 30px;
+@checkout-shipping-item__margin: 0 0 @indent__base;
+@checkout-shipping-item__padding: @indent__base (@indent__l + 5px) @indent__base @indent__base;
+@checkout-shipping-item__transition: .3s border-color;
+@checkout-shipping-item__width: 100%/3;
+@checkout-shipping-item-tablet__width: 100%/2;
+@checkout-shipping-item-mobile__width: 100%;
+@checkout-shipping-item__active__border-color: @color-orange-red1;
+
+@checkout-shipping-item-icon__selected__height: 27px;
+@checkout-shipping-item-icon__selected__width: 29px;
+
+@checkout-shipping-item-mobile__padding: 0 0 15px;
+@checkout-shipping-item-mobile__margin: @checkout-shipping-item-mobile__padding;
+@checkout-shipping-item-mobile__active__padding: 15px (@indent__l + 5px) 15px 18px;
+
+@checkout-shipping-item-before__border-color: @color-gray80;
+@checkout-shipping-item-before__height: calc(~"100% - 20px");
+
+@checkout-shipping-method__border: @checkout-step-title__border;
+@checkout-shipping-method__padding: @indent__base;
+
+//
+//  Common
+//  _____________________________________________
+
+& when (@media-common = true) {
+
+    .opc-wrapper {
+
+        //
+        //  Shipping Address
+        //  ---------------------------------------------
+
+        .form-login,
+        .form-shipping-address {
+            .css(margin-bottom, @checkout-step-title__margin-bottom);
+            .fieldset {
+                .field {
+                    .label {
+                        font-weight: @font-weight__regular;
+                    }
+                }
+                .note {
+                    font-size: @font-size__base;
+                    margin-top: @indent__s;
+                }
+            }
+        }
+
+        .shipping-address-items {
+            font-size: 0;
+        }
+
+        .shipping-address-item {
+            &:extend(.abs-add-box-sizing all);
+            .css(border, @checkout-shipping-item__border);
+            .css(font-size, @font-size__base);
+            .css(line-height, @checkout-shipping-item__line-height);
+            .css(margin, @checkout-shipping-item__margin);
+            .css(padding, @checkout-shipping-item__padding);
+            .css(transition, @checkout-shipping-item__transition);
+            .css(width, @checkout-shipping-item-tablet__width);
+            display: inline-block;
+            position: relative;
+            vertical-align: top;
+            word-wrap: break-word;
+
+            &.selected-item {
+                .css(border-color, @checkout-shipping-item__active__border-color);
+
+                &:after {
+                    .css(background, @checkout-shipping-item-icon__background-color);
+                    .css(color, @checkout-shipping-item-icon__color);
+                    .css(content, @checkout-shipping-item-icon__content);
+                    .css(font-family, @icons__font-name);
+                    .css(height, @checkout-shipping-item-icon__selected__height);
+                    .css(width, @checkout-shipping-item-icon__selected__width);
+                    font-size: 19px;
+                    line-height: 21px;
+                    padding-top: 2px;
+                    position: absolute;
+                    right: 0;
+                    text-align: center;
+                    top: 0;
+                }
+
+                .action-select-shipping-item {
+                    &:extend(.abs-no-display-s all);
+                    visibility: hidden;
+                }
+            }
+        }
+
+        .field {
+            &.addresses {
+                &:extend(.abs-add-clearfix all);
+            }
+        }
+
+        .action-show-popup {
+            margin: 0 0 @indent__base;
+            > span {
+                &:before {
+                    content: '+';
+                    padding-right: @indent__xs;
+                }
+            }
+        }
+
+        .action-select-shipping-item {
+            float: right;
+            margin: @indent__base 0 0;
+        }
+
+        .edit-address-link {
+            &:extend(.abs-action-button-as-link all);
+            display: block;
+            float: left;
+            margin: 26px 5px 0 0;
+        }
+    }
+
+    //
+    //  Shipping Methods
+    //  ---------------------------------------------
+
+    .checkout-shipping-method {
+        .step-title {
+            margin-bottom: 0;
+        }
+        .no-quotes-block {
+            margin: @indent__base 0;
+        }
+    }
+
+    .methods-shipping {
+        .actions-toolbar {
+            .action {
+                &.primary {
+                    &:extend(.abs-button-l all);
+                    margin: @indent__base 0 0;
+                }
+            }
+        }
+    }
+
+    .table-checkout-shipping-method {
+        thead {
+            th {
+                display: none;
+            }
+        }
+        tbody {
+            td {
+                .css(border-top, @checkout-shipping-method__border);
+                .css(padding-bottom, @checkout-shipping-method__padding);
+                .css(padding-top, @checkout-shipping-method__padding);
+                &:first-child {
+                    padding-left: 0;
+                    padding-right: 0;
+                    width: 20px;
+                }
+            }
+            tr {
+                &:first-child {
+                    td {
+                        border-top: none;
+                    }
+                }
+            }
+            .col-price {
+                font-weight: @font-weight__semibold;
+            }
+            .row-error {
+                td {
+                    border-top: none;
+                    padding-bottom: @indent__s;
+                    padding-top: 0;
+                }
+            }
+        }
+    }
+}
+
+//
+//  Mobile
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) {
+    .opc-wrapper {
+        .form-login,
+        .form-shipping-address,
+        .methods-shipping {
+            .css(background, @checkout-step-content-mobile__background);
+            .css(margin, @checkout-step-content-mobile__margin);
+            .css(padding, @indent__base @checkout-step-content-mobile__margin-s);
+        }
+
+        .form-login {
+            + .form-shipping-address {
+                .css(margin-top, -(@checkout-step-content-mobile__margin-s));
+            }
+        }
+
+        .shipping-address-item {
+            .css(border-bottom, 1px solid @checkout-shipping-item-before__border-color);
+            .css(margin, @checkout-shipping-item-mobile__margin);
+            .css(padding, @checkout-shipping-item-mobile__padding);
+            .css(width, @checkout-shipping-item-mobile__width);
+            &.selected-item {
+                .css(padding, @checkout-shipping-item-mobile__active__padding);
+                border-bottom-width: 2px;
+
+                .edit-address-link {
+                    .css(right, @checkout-shipping-item-icon__selected__width + @indent__s);
+                }
+            }
+        }
+
+        .action-select-shipping-item {
+            float: none;
+            margin-top: @indent__s;
+            width: 100%;
+        }
+
+        .action-show-popup {
+            width: 100%;
+        }
+
+        .methods-shipping {
+            .css(border-bottom, @checkout-step-title__border);
+            padding-top: @indent__l;
+        }
+
+        .edit-address-link {
+            .icon-font(
+                @icon-edit,
+                @_icon-font-size: 18px,
+                @_icon-font-line-height: 20px,
+                @_icon-font-text-hide: true,
+                @_icon-font-color: @minicart-icons-color,
+                @_icon-font-color-hover: @primary__color,
+                @_icon-font-color-active: @minicart-icons-color
+            );
+            margin: 0;
+            position: absolute;
+            right: 0;
+            top: 5px;
+        }
+    }
+}
+
+//
+//  Desktop
+//  _____________________________________________
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
+    .checkout-shipping-method {
+        .actions-toolbar {
+            > .primary {
+                float: right;
+            }
+            .action {
+                &.primary {
+                    margin: 0;
+                }
+            }
+        }
+    }
+    .opc-wrapper {
+        .form-login,
+        .form-shipping-address {
+            .css(max-width, @checkout-shipping-address__max-width);
+        }
+
+        .form-login {
+            .css(border-bottom, @checkout-step-title__border);
+            .css(padding-bottom, @checkout-step-title__margin-bottom);
+        }
+    }
+    .table-checkout-shipping-method {
+        width: auto;
+    }
+}
+
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__l) {
+    .opc-wrapper {
+        .shipping-address-item {
+            .css(width, @checkout-shipping-item__width);
+
+            &:before {
+                .css(background, @checkout-shipping-item-before__border-color);
+                .css(height, @checkout-shipping-item-before__height);
+                content: '';
+                left: 0;
+                position: absolute;
+                top: 0;
+                width: 1px;
+            }
+
+            &:nth-child(3n+1) {
+                &:before {
+                    display: none;
+                }
+            }
+
+            &.selected-item {
+                &:before {
+                    display: none;
+                }
+
+                + .shipping-address-item {
+                    &:before {
+                        display: none;
+                    }
+                }
+            }
+        }
+    }
+    .table-checkout-shipping-method {
+        min-width: 500px;
+    }
+}
diff --git a/app/design/frontend/Magento/luma/Magento_GiftMessage/web/css/source/_module.less b/app/design/frontend/Magento/luma/Magento_GiftMessage/web/css/source/_module.less
index 0d3b4cd47ec03767fba0a2a1291fccd7235b6d4e..d10ebc66f56eaf506ac65e19b8f07dbb1ade7c37 100644
--- a/app/design/frontend/Magento/luma/Magento_GiftMessage/web/css/source/_module.less
+++ b/app/design/frontend/Magento/luma/Magento_GiftMessage/web/css/source/_module.less
@@ -274,13 +274,19 @@
         }
         .gift-content {
             border-top: @border-width__base solid @color-gray-light5;
-            margin-left: -@mobile-cart-padding;
             margin-right: -@mobile-cart-padding;
             padding-left: @mobile-cart-padding;
             padding-right: @mobile-cart-padding;
             overflow: hidden;
         }
     }
+
+    .gift-options-cart-item {
+        & + .action-towishlist {
+            left: 43px;
+            position: absolute;
+        }
+    }
 }
 
 //
diff --git a/app/design/frontend/Magento/luma/web/css/source/_extends.less b/app/design/frontend/Magento/luma/web/css/source/_extends.less
index cc4ab06b849cb5eec4233e701e915deedb4285ed..04018f6977c016c96c9444e206a8eb64ba787fff 100644
--- a/app/design/frontend/Magento/luma/web/css/source/_extends.less
+++ b/app/design/frontend/Magento/luma/web/css/source/_extends.less
@@ -4,8 +4,9 @@
 //  */
 
 //
-//    List default styles reset
-//--------------------------------------
+//  List default styles reset
+//  ---------------------------------------------
+
 .abs-reset-list {
     .list-reset-styles();
     > li {
@@ -14,16 +15,18 @@
 }
 
 //
-//    Primary button
-//--------------------------------------
+//  Primary button
+//  ---------------------------------------------
+
 .action-primary {
     .button-primary();
     .css(border-radius, @button__border-radius);
 }
 
 //
-//    Secondary button
-//--------------------------------------
+//  Secondary button
+//  ---------------------------------------------
+
 .abs-revert-to-action-secondary {
     &:extend(.abs-revert-secondary-color all);
     .css(border-radius, @button__border-radius);
@@ -36,8 +39,9 @@
 }
 
 //
-//    Link as a button
-//--------------------------------------
+//  Link as a button
+//  ---------------------------------------------
+
 .abs-action-link-button {
     .button();
     .link-as-button();
@@ -46,7 +50,8 @@
 
 //
 //   Button as a link
-//--------------------------------------
+//  ---------------------------------------------
+
 .abs-action-button-as-link {
     .button-as-link(
         @_margin: false
@@ -61,28 +66,32 @@
 
 //
 //   Button revert secondary color
-//--------------------------------------
+//  ---------------------------------------------
+
 .abs-revert-secondary-color {
     .button-revert-secondary-color();
 }
 
 //
 //   Button revert secondary size
-//--------------------------------------
+//  ---------------------------------------------
+
 .abs-revert-secondary-size {
     .button-revert-secondary-size();
 }
 
 //
 //   Large button
-//--------------------------------------
+//  ---------------------------------------------
+
 .abs-button-l {
     .button-l();
 }
 
 //
-//    Product options list
-//--------------------------------------
+//  Product options list
+//  ---------------------------------------------
+
 @abs-product-options-list: {
     dt {
         float: left;
@@ -104,8 +113,9 @@
 }
 
 //
-//    Desktop
-//--------------------------------------
+//  Desktop
+//  ---------------------------------------------
+
 .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
     .abs-product-options-list-desktop {
         @abs-product-options-list();
@@ -113,8 +123,9 @@
 }
 
 //
-//    Button reset width, floats, margins
-//--------------------------------------
+//  Button reset width, floats, margins
+//  ---------------------------------------------
+
 .abs-button-responsive {
     .button-responsive();
 }
@@ -126,8 +137,9 @@
 }
 
 //
-//    Blocks in 2 columns
-//--------------------------------------
+//  Blocks in 2 columns
+//  ---------------------------------------------
+
 @abs-blocks-2columns: {
     width: 48%;
     &:nth-child(1) {
@@ -155,8 +167,9 @@
 }
 
 //
-//    Reset image alignment in container
-//--------------------------------------
+//  Reset image alignment in container
+//  ---------------------------------------------
+
 .abs-reset-image-wrapper {
     height: auto;
     padding: 0!important;
@@ -166,8 +179,9 @@
 }
 
 //
-//    Adaptive images
-//--------------------------------------
+//  Adaptive images
+//  ---------------------------------------------
+
 .abs-adaptive-images {
     display: block;
     height: auto;
@@ -182,8 +196,9 @@
 }
 
 //
-//    Title for login blocks
-//--------------------------------------
+//  Title for login blocks
+//  ---------------------------------------------
+
 .abs-login-block-title {
     strong {
         font-weight: 500;
@@ -195,8 +210,9 @@
 }
 
 //
-//    Simple Dropdown
-//--------------------------------------
+//  Simple Dropdown
+//  ---------------------------------------------
+
 .abs-dropdown-simple {
     .dropdown(
         @_dropdown-list-item-padding: 5px 5px 5px 23px,
@@ -210,16 +226,18 @@
 }
 
 //
-//    Input quantity
-//--------------------------------------
+//  Input quantity
+//  ---------------------------------------------
+
 .abs-input-qty {
     width: 54px;
     text-align: center;
 }
 
 //
-//    Marging for blocks & widgets
-//--------------------------------------
+//  Marging for blocks & widgets
+//  ---------------------------------------------
+
 .abs-margin-for-blocks-and-widgets {
     margin-bottom: @indent__xl;
 }
@@ -231,8 +249,9 @@
 }
 
 //
-//    Remove button for blocks
-//--------------------------------------
+//  Remove button for blocks
+//  ---------------------------------------------
+
 .abs-remove-button-for-blocks {
     .icon-font(
         @icon-remove,
@@ -246,8 +265,9 @@
 }
 
 //
-//    Product link
-//--------------------------------------
+//  Product link
+//  ---------------------------------------------
+
 .abs-product-link {
     font-weight: @font-weight__regular;
     > a {
@@ -265,8 +285,9 @@
 }
 
 //
-//    Link
-//--------------------------------------
+//  Link
+//  ---------------------------------------------
+
 .abs-like-link {
     .link();
     cursor: pointer;
@@ -274,7 +295,8 @@
 
 //
 //   Reset left margin
-//--------------------------------------
+//  ---------------------------------------------
+
 @abs-reset-left-margin: {
     margin-left: 0;
 };
@@ -296,8 +318,9 @@
 }
 
 //
-//    Action with icon remove with text
-//--------------------------------------
+//  Action with icon remove with text
+//  ---------------------------------------------
+
 .abs-action-remove {
     &:extend(.abs-action-button-as-link all);
     width: auto;
@@ -308,8 +331,9 @@
 }
 
 //
-//    Action with icon remove with text for desktop
-//--------------------------------------
+//  Action with icon remove with text for desktop
+//  ---------------------------------------------
+
 .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
     .abs-action-remove-desktop {
         margin-left: 90%;
@@ -317,8 +341,9 @@
 }
 
 //
-//    Add Recipient
-//--------------------------------------
+//  Add Recipient
+//  ---------------------------------------------
+
 .abs-add-fields {
     .fieldset {
         .field {
@@ -360,8 +385,9 @@
 }
 
 //
-//    Add Recipient for desktop
-//--------------------------------------
+//  Add Recipient for desktop
+//  ---------------------------------------------
+
 .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
     .abs-add-fields-desktop {
         .fieldset {
@@ -382,8 +408,9 @@
 }
 
 //
-//    Margin for forms
-//--------------------------------------
+//  Margin for forms
+//  ---------------------------------------------
+
 .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
     .abs-margin-for-forms-desktop {
         .css(margin-left, @form-field-type-label-inline__width);
@@ -391,8 +418,9 @@
 }
 
 //
-//    Visibility hidden / show visibility hidden
-//--------------------------------------
+//  Visibility hidden / show visibility hidden
+//  ---------------------------------------------
+
 @abs-hidden: {
     .visibility-hidden();
 };
@@ -402,8 +430,9 @@
 }
 
 //
-//    Visually hidden / show visually hidden
-//--------------------------------------
+//  Visually hidden / show visually hidden
+//  ---------------------------------------------
+
 @abs-visually-hidden: {
     .visually-hidden();
 };
@@ -437,8 +466,9 @@
 }
 
 //
-//    Clearfix
-//--------------------------------------
+//  Clearfix
+//  ---------------------------------------------
+
 @abs-add-clearfix: {
     .clearfix();
 };
@@ -472,8 +502,9 @@
 }
 
 //
-//    Box-sizing
-//--------------------------------------
+//  Box-sizing
+//  ---------------------------------------------
+
 @abs-add-box-sizing: {
     box-sizing: border-box;
 };
@@ -494,9 +525,16 @@
     }
 }
 
+.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
+    .abs-add-box-sizing-desktop-m {
+        @abs-add-box-sizing();
+    }
+}
+
 //
-//    Revert field type
-//--------------------------------------
+//  Revert field type
+//  ---------------------------------------------
+
 .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
     .abs-revert-field-type-desktop {
         .fieldset {
@@ -512,8 +550,9 @@
 }
 
 //
-//    Settings icons
-//--------------------------------------
+//  Settings icons
+//  ---------------------------------------------
+
 .abs-navigation-icon {
     .icon-font(
         @_icon-font-content: @icon-down,
@@ -530,8 +569,9 @@
 }
 
 //
-//    Split button
-//--------------------------------------
+//  Split button
+//  ---------------------------------------------
+
 .abs-split-button {
     .dropdown-split(
         @_options-selector : ~".items",
@@ -541,8 +581,9 @@
 }
 
 //
-//    Field 2 column
-//--------------------------------------
+//  Field 2 column
+//  ---------------------------------------------
+
 @abs-form-field-column-2: {
     .fieldset {
         .field {
@@ -572,8 +613,9 @@
 }
 
 //
-//    Field 1 column
-//--------------------------------------
+//  Field 1 column
+//  ---------------------------------------------
+
 @abs-form-field-revert-column-1: {
     .form-field-column-number(@_column-number: 1);
 };
@@ -591,8 +633,9 @@
 }
 
 //
-//    Checkout shipping methods title
-//--------------------------------------
+//  Checkout shipping methods title
+//  ---------------------------------------------
+
 .abs-methods-shipping-title {
     .font-size(16);
     margin-bottom: 15px;
@@ -600,8 +643,9 @@
 }
 
 //
-//    Checkout order review
-//--------------------------------------
+//  Checkout order review
+//  ---------------------------------------------
+
 .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) {
     .abs-checkout-order-review {
         tbody > tr {
@@ -642,8 +686,9 @@
 }
 
 //
-//    Add to Actions
-//--------------------------------------
+//  Add to Actions
+//  ---------------------------------------------
+
 .abs-actions-addto {
     .css(color, @addto-color);
     display: inline-block;
@@ -664,15 +709,17 @@
 }
 
 //
-//    Box-tocart block
-//--------------------------------------
+//  Box-tocart block
+//  ---------------------------------------------
+
 .abs-box-tocart {
     margin: 0 0 @indent__l;
 }
 
 //
-//    General pages forms
-//--------------------------------------
+//  General pages forms
+//  ---------------------------------------------
+
 .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
     .abs-forms-general-desktop {
         max-width: 500px;
@@ -686,8 +733,9 @@
 }
 
 //
-//    Revert side paddings
-//--------------------------------------
+//  Revert side paddings
+//  ---------------------------------------------
+
 .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
     .abs-revert-side-paddings {
         padding-left: 0;
@@ -696,8 +744,9 @@
 }
 
 //
-//    Abstract toggle title block
-//--------------------------------------
+//  Abstract toggle title block
+//  ---------------------------------------------
+
 @abs-toggling-title: {
     .css(border-top, @border-width__base solid @border-color__base);
     cursor: pointer;
@@ -747,8 +796,9 @@
 }
 
 //
-//    Cart discount block
-//--------------------------------------
+//  Cart discount block
+//  ---------------------------------------------
+
 .abs-cart-block {
     margin: 0;
     > .title {
@@ -780,8 +830,9 @@
 }
 
 //
-//    Checkout order review price
-//--------------------------------------
+//  Checkout order review price
+//  ---------------------------------------------
+
 .abs-checkout-cart-price {
     .css(color, @primary__color__lighter);
     .font-size(16);
@@ -789,8 +840,9 @@
 }
 
 //
-//    Checkout order product name
-//--------------------------------------
+//  Checkout order product name
+//  ---------------------------------------------
+
 .abs-checkout-product-name {
     .font-size(18);
     font-weight: @font-weight__light;
@@ -798,8 +850,9 @@
 }
 
 //
-//    Mobile checkout order product name
-//--------------------------------------
+//  Mobile checkout order product name
+//  ---------------------------------------------
+
 .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) {
     .abs-product-items-summary {
         tbody {
@@ -838,8 +891,9 @@
 }
 
 //
-//    Account pages: title
-//--------------------------------------
+//  Account pages: title
+//  ---------------------------------------------
+
 .abs-account-title {
     > strong,
     > span {
@@ -852,8 +906,9 @@
 }
 
 //
-//    Account pages: block font size
-//--------------------------------------
+//  Account pages: block font size
+//  ---------------------------------------------
+
 .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
     .abs-account-block-font-size {
         .font-size(16);
@@ -861,15 +916,17 @@
 }
 
 //
-//    Account pages: block line-height
-//--------------------------------------
+//  Account pages: block line-height
+//  ---------------------------------------------
+
 .abs-account-block-line-height {
     line-height: 24px;
 }
 
 //
-//    Account pages: margin for table
-//--------------------------------------
+//  Account pages: margin for table
+//  ---------------------------------------------
+
 .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) {
     .abs-account-table-margin-mobile {
         .css(margin-top, -@indent__base);
@@ -882,8 +939,9 @@
 }
 
 //
-//    Account pages: table col actions
-//--------------------------------------
+//  Account pages: table col actions
+//  ---------------------------------------------
+
 .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) {
     .abs-col-no-prefix {
         &:before {
@@ -893,8 +951,9 @@
 }
 
 //
-//    Account pages: order table summary
-//--------------------------------------
+//  Account pages: order table summary
+//  ---------------------------------------------
+
 .abs-account-summary {
     td {
         .css(background, @sidebar__background-color);
@@ -902,8 +961,9 @@
 }
 
 //
-//    Action print with icon
-//--------------------------------------
+//  Action print with icon
+//  ---------------------------------------------
+
 @abs-action-print: {
     .icon-font(
         @icon-print,
@@ -930,8 +990,9 @@
 }
 
 //
-//    Excl/Incl tax
-//--------------------------------------
+//  Excl/Incl tax
+//  ---------------------------------------------
+
 .abs-incl-excl-tax {
     .price-including-tax,
     .price-excluding-tax {
@@ -965,8 +1026,9 @@
 }
 
 //
-//    Cart tax total
-//--------------------------------------
+//  Cart tax total
+//  ---------------------------------------------
+
 .abs-tax-total {
     cursor: pointer;
     position: relative;
@@ -993,15 +1055,17 @@
 }
 
 //
-//    Forms: margin-bottom for small forms
-//--------------------------------------
+//  Forms: margin-bottom for small forms
+//  ---------------------------------------------
+
 .abs-forms-margin-small {
     .css(margin-bottom, @indent__base);
 }
 
 //
-//    Forms: margin-bottom for small forms
-//--------------------------------------
+//  Forms: margin-bottom for small forms
+//  ---------------------------------------------
+
 .abs-rating-summary {
     .rating {
         &-summary {
@@ -1022,8 +1086,9 @@
 }
 
 //
-//    Account pages: actions
-//--------------------------------------
+//  Account pages: actions
+//  ---------------------------------------------
+
 .abs-account-actions {
     &:after {
         content: "";
@@ -1041,8 +1106,9 @@
 }
 
 //
-//    Account blocks
-//--------------------------------------
+//  Account blocks
+//  ---------------------------------------------
+
 .abs-account-blocks {
     .block-title {
         &:extend(.abs-account-title all);
@@ -1064,8 +1130,9 @@
 }
 
 //
-//    Add colon
-//--------------------------------------
+//  Add colon
+//  ---------------------------------------------
+
 .abs-colon {
     &:after {
         content: ": ";
@@ -1073,8 +1140,9 @@
 }
 
 //
-//    Icon - create add
-//--------------------------------------
+//  Icon - create add
+//  ---------------------------------------------
+
 .abs-icon-add {
     .icon-font(
         @_icon-font-content: @icon-expand,
@@ -1098,8 +1166,9 @@
 }
 
 //
-//    Dropdown items - create new
-//--------------------------------------
+//  Dropdown items - create new
+//  ---------------------------------------------
+
 .abs-dropdown-items-new {
     .items .item:last-child {
         &:hover {
@@ -1116,8 +1185,9 @@
 }
 
 //
-//    Abstract no display
-//--------------------------------------
+//  Abstract no display
+//  ---------------------------------------------
+
 @abs-no-display: {
     display: none;
 };
@@ -1139,8 +1209,9 @@
 }
 
 //
-//    Status
-//--------------------------------------
+//  Status
+//  ---------------------------------------------
+
 .abs-status {
     .css(border, 2px solid @border-color__base);
     border-radius: 3px;
@@ -1159,8 +1230,9 @@
 }
 
 //
-//    Page title - orders pages
-//--------------------------------------
+//  Page title - orders pages
+//  ---------------------------------------------
+
 .abs-title-orders {
     .page-main {
         .page-title-wrapper {
@@ -1208,8 +1280,9 @@
 }
 
 //
-//    Table striped
-//--------------------------------------
+//  Table striped
+//  ---------------------------------------------
+
 .abs-table-striped {
     .table-striped(
         @_stripped-highlight: even
@@ -1228,8 +1301,9 @@
 }
 
 //
-//    Table bordered desktop
-//--------------------------------------
+//  Table bordered desktop
+//  ---------------------------------------------
+
 .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
     .abs-table-bordered-desktop {
         .table-bordered(
@@ -1240,8 +1314,9 @@
 }
 
 //
-//    Pager toolbar for non-catalog pages desktop
-//--------------------------------------
+//  Pager toolbar for non-catalog pages desktop
+//  ---------------------------------------------
+
 .media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
     .abs-pager-toolbar {
         position: relative;
@@ -1263,8 +1338,9 @@
 }
 
 //
-//    Items counter in blocks
-//--------------------------------------
+//  Items counter in blocks
+//  ---------------------------------------------
+
 .abs-block-items-counter {
     .css(color, @primary__color__lighter);
     .font-size(12px);
@@ -1272,8 +1348,9 @@
 }
 
 //
-//    Sidebar and widget blocks title
-//--------------------------------------
+//  Sidebar and widget blocks title
+//  ---------------------------------------------
+
 .abs-block-widget-title {
     strong {
         font-size: @font-size__l;
@@ -1283,8 +1360,9 @@
 }
 
 //
-//    Shopping cart items
-//--------------------------------------
+//  Shopping cart items
+//  ---------------------------------------------
+
 .abs-shopping-cart-items {
     margin-bottom: @indent__base;
     .actions.main {
@@ -1305,8 +1383,9 @@
 }
 
 //
-//    Remove top border
-//--------------------------------------
+//  Remove top border
+//  ---------------------------------------------
+
 .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) {
     .abs-no-border-top {
         border-top: 0;
@@ -1314,7 +1393,7 @@
 }
 
 //
-//    Remove bottom border
+//  Remove bottom border
 //--------------------------------------
 .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) {
     .abs-no-border-bottom {
@@ -1323,8 +1402,9 @@
 }
 
 //
-//    Form Field Date
-//--------------------------------------
+//  Form Field Date
+//  ---------------------------------------------
+
 .abs-field-date {
     .control {
         position: relative;
@@ -1336,9 +1416,207 @@
 }
 
 //
-//    Form Field Date Input
-//--------------------------------------
+//  Form Field Date Input
+//  ---------------------------------------------
+
 .abs-field-date-input {
-    margin-right: @indent__s;
+    .css(margin-right, @indent__s);
     width: calc(~"100% - (@{icon-calendar__font-size} + @{indent__s})");
 }
+
+//
+//  Form Field Tooltip
+//  ---------------------------------------------
+
+.abs-field-tooltip {
+    &:extend(.abs-add-box-sizing all);
+    position: relative;
+    input {
+        .css(margin-right, @indent__s);
+        width: calc(~"100% - (@{checkout-tooltip-icon__font-size} + @{indent__s} + @{indent__xs})");
+        &:focus {
+            + .field-tooltip {
+                .field-tooltip-action {
+                    &:before {
+                        .css(color, @checkout-tooltip-icon__hover__color);
+                    }
+                }
+                .field-tooltip-content {
+                    display: block;
+                }
+            }
+        }
+    }
+}
+
+//
+//  Checkout Tooltip Content (position: top)
+//  ---------------------------------------------
+
+@abs-checkout-tooltip-content-position-top: {
+    .css(right, @checkout-tooltip-content-mobile__right);
+    .css(top, @checkout-tooltip-content-mobile__top);
+    left: auto;
+
+    &:before,
+    &:after {
+        .arrow(
+            @_position: top,
+            @_size: @checkout-tooltip-icon-arrow__font-size,
+            @_color: @checkout-tooltip-content__background-color
+        );
+        .css(margin-top, @checkout-tooltip-icon-arrow__left);
+        .css(right, @indent__s);
+        left: auto;
+        top: 0%;
+    }
+    &:before {
+        .css(border-bottom-color, @checkout-tooltip-content__active__border-color);
+    }
+    &:after {
+        .css(border-bottom-color, @checkout-tooltip-content__background-color);
+        top: 1px;
+    }
+};
+
+.abs-checkout-tooltip-content-position-top {
+    @abs-checkout-tooltip-content-position-top();
+}
+
+.media-width(@extremum, @break) when (@extremum = 'max') and (@break = (@screen__m + 1)) {
+    .abs-checkout-tooltip-content-position-top-mobile {
+        @abs-checkout-tooltip-content-position-top();
+    }
+}
+
+//
+//  Checkout title
+//  ---------------------------------------------
+
+.abs-checkout-title {
+    .css(padding-bottom, @checkout-step-title__padding);
+    .typography(
+    @_font-size: @checkout-step-title__font-size,
+    @_font-weight: @checkout-step-title__font-weight,
+    @_font-family: false,
+    @_font-style: false,
+    @_line-height: false
+    );
+}
+
+//
+//  Shopping cart sidebar and checkout sidebar totals
+//  ---------------------------------------------
+
+.abs-sidebar-totals {
+    border-top: 1px solid @border-color__base;
+    padding-top: 10px;
+    tbody,
+    tfoot {
+        .mark {
+            border: 0;
+            font-weight: @font-weight__regular;
+            padding: 6px 0;
+        }
+        .amount {
+            border: 0;
+            font-weight: @font-weight__regular;
+            padding: 6px 0 6px 14px;
+            text-align: right;
+        }
+    }
+    .table-caption {
+        &:extend(.abs-no-display all);
+    }
+    .grand {
+        th,
+        td {
+            padding: 11px 0;
+        }
+        strong {
+            display: inline-block;
+            font-weight: @font-weight__semibold;
+            padding: 3px 0 0;
+        }
+        .mark {
+            border-top: 1px solid @border-color__base;
+            .font-size(18);
+            padding-right: @indent__s;
+        }
+        .amount {
+            border-top: 1px solid @border-color__base;
+            .font-size(18);
+        }
+    }
+    .msrp {
+        margin-bottom: @indent__s;
+    }
+    tbody tr:last-child td {
+        padding-bottom: 19px;
+    }
+    .totals-tax {
+        &-summary {
+            .mark,
+            .amount {
+                border-top: @border-width__base solid @border-color__base;
+                border-bottom: @border-width__base solid @border-color__base;
+                cursor: pointer;
+            }
+            .amount .price {
+                position: relative;
+                padding-right: @indent__base;
+                .icon-font(
+                @icon-down,
+                @_icon-font-size: 12px,
+                @_icon-font-line-height: 12px,
+                @_icon-font-text-hide: true,
+                @_icon-font-position: after
+                );
+                &:after {
+                    position: absolute;
+                    right: 3px;
+                    top: 3px;
+                }
+            }
+            &.expanded {
+                .mark,
+                .amount {
+                    border-bottom: 0;
+                }
+                .amount .price {
+                    .icon-font-symbol(
+                    @_icon-font-content: @icon-up,
+                    @_icon-font-position: after
+                    );
+                }
+            }
+        }
+        &-details {
+            display: none;
+            border-bottom: @border-width__base solid @border-color__base;
+            &.shown {
+                display: table-row;
+            }
+        }
+    }
+    .table-wrapper {
+        margin-bottom: 0;
+    }
+}
+
+.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) {
+    .abs-sidebar-totals-mobile {
+        th {
+            &:extend(.abs-col-no-prefix all);
+        }
+        td {
+            &:extend(.abs-col-no-prefix all);
+        }
+        tbody tr:not(:last-child) td {
+            &:extend(.abs-no-border-bottom-top all);
+        }
+        .amount {
+            text-align: right;
+        }
+    }
+}
diff --git a/app/design/frontend/Magento/luma/web/css/source/_theme.less b/app/design/frontend/Magento/luma/web/css/source/_theme.less
index f293d18d117a1911f079065f25280984a9fd54a7..52914c1bd64117c7cba4af7e2086731a7ae19870 100644
--- a/app/design/frontend/Magento/luma/web/css/source/_theme.less
+++ b/app/design/frontend/Magento/luma/web/css/source/_theme.less
@@ -248,3 +248,23 @@
 @overlay__opacity-old: 70;
 
 @gallery-thumb-border-color-active: @active__color;
+
+//  Modal popup
+@modal-action-close__font-size: @font-size__base;
+
+//  Checkout tooltip icon
+@checkout-tooltip-icon__font-size: 21px;
+
+// Checkout Payment Option icon
+@checkout-payment-option-title-icon__font-size: 14px;
+@checkout-payment-option-title-icon__line-height: 16px;
+@checkout-payment-option-title-icon__margin: 0 0 0 @indent__s;
+
+// Checkout Sidebar Shipping Information
+@checkout-sidebar-shipping-information-edit-icon__content: @icon-edit;
+@checkout-sidebar-shipping-information-edit-icon__font-size: 18px;
+@checkout-sidebar-shipping-information-edit-icon__line-height: 20px;
+@checkout-sidebar-shipping-information-edit-icon__top: @indent__s;
+
+// Checkout
+@checkout-sidebar__columns: 8;
diff --git a/app/design/frontend/Magento/luma/web/css/source/_variables.less b/app/design/frontend/Magento/luma/web/css/source/_variables.less
index dbdbeb65ad660dccec8e724925392cf18b254c96..ee76525dd8cc68c2906c4bfa5aecdbaede9c7f32 100644
--- a/app/design/frontend/Magento/luma/web/css/source/_variables.less
+++ b/app/design/frontend/Magento/luma/web/css/source/_variables.less
@@ -26,7 +26,6 @@
 @icon-success: '\e60e';
 @icon-error: '\e61f';
 @icon-edit: '\e601';
-@icon-help: '\e623';
 @icon-print: '\e624';
 @icon-star-empty: '\e625';
 @icon-download: '\e626';
diff --git a/app/design/frontend/Magento/luma/web/fonts/Luma-Icons.svg b/app/design/frontend/Magento/luma/web/fonts/Luma-Icons.svg
index 5e68e79f8e3e44488f98f45b6a4d1408f485d2ec..fa092836d03823258384bc553188cc92e412a02f 100644
--- a/app/design/frontend/Magento/luma/web/fonts/Luma-Icons.svg
+++ b/app/design/frontend/Magento/luma/web/fonts/Luma-Icons.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg"><defs><font id="Luma-Icons" horiz-adv-x="512"><font-face units-per-em="512" ascent="480" descent="-32"/><missing-glyph horiz-adv-x="512"/><glyph unicode="&#x20;" d="" horiz-adv-x="256"/><glyph unicode="&#xe600;" d="M436.608 435.568c-65.68 31.424-144.064 2.832-174.976-63.84-2.16-4.64-4.016-10.448-5.664-17.2-1.648 6.752-3.504 12.56-5.632 17.2-30.944 66.672-109.248 95.264-174.944 63.84-65.6-31.424-93.744-110.96-62.832-177.648 30.928-66.672 243.344-257.84 243.344-257.84s0.016 0.224 0.048 0.576c0.048-0.352 0.064-0.576 0.064-0.576s212.512 191.168 243.44 257.84c30.896 66.688 2.832 146.224-62.848 177.648z"/><glyph unicode="&#xe601;" d="M362.533 425.051c-49.81-49.792-20.809-20.772-20.809-20.772l96.402-96.384c0 0-31.067-31.049 20.772 20.773s-46.611 146.194-96.365 96.384zM320.147 383.671l-227.987-227.986 0.329-0.293-54.071-146.524 149.833 50.688 0.311-0.311 0.786 0.805v0.019l227.2 227.2-96.403 96.403zM179.036 104.375l-78.811-33.28 37.047 75.044 38.345 38.363 41.764-41.783-38.345-38.345z"/><glyph unicode="&#xe602;" d="M255.952 480l-255.952-448h512l-256.048 448zM287.12 353.808v-65.36l-16.688-128.544h-27.088l-18.032 128.544-0.992 65.36h62.8zM224.096 64.112v64.112h64.24v-64.112h-64.24z"/><glyph unicode="&#xe603;" d="M363.923 112.019c-29.805-28.764-68.663-43.502-108.013-43.538-35.145 0.036-70.199 11.757-99.347 35.932-37.029 30.829-56.046 74.971-56.1 119.661 0 7.442 0.549 14.829 1.591 22.18l-60.672-11.374c-0.164-3.602-0.292-7.186-0.292-10.807-0.036-61.495 26.459-122.899 77.549-165.285 40.009-33.335 88.887-49.683 137.252-49.683h0.128c56.211 0 112.164 22.217 153.746 64.914l39.844-39.772 0.311 124.745-131.803 0.348 45.805-47.324zM393.344 389.23c-40.046 33.335-88.923 49.664-137.271 49.664-55.808 0-111.397-21.833-152.923-63.945l-37.687 34.798-0.677-120.722 130.487-0.75-46.336 48.493c29.641 28.252 68.188 42.697 107.154 42.733 35.108-0.036 70.217-11.721 99.328-35.932 37.029-30.829 56.046-74.935 56.137-119.698 0-6.437-0.457-12.892-1.225-19.365l60.435 11.593c0.036 2.615 0.164 5.212 0.164 7.772-0.036 61.549-26.514 122.899-77.587 165.357z"/><glyph unicode="&#xe604;" d="M95.792-32h320.4v320.080h-320.4v-320.080zM318.336 228.512c0 9.904 8.032 17.904 17.952 17.904 9.904 0 17.936-8 17.936-17.904v-188.736c0-9.888-8.032-17.92-17.936-17.92-9.92 0-17.952 8.032-17.952 17.92v188.736zM238.048 228.512c0 9.904 8.032 17.904 17.92 17.904s17.92-8 17.92-17.904v-188.736c0-9.888-8.032-17.92-17.92-17.92s-17.92 8.032-17.92 17.92v188.736zM157.6 228.512c0 9.904 8 17.904 17.92 17.904 9.888 0 17.92-8 17.92-17.904v-188.736c0-9.888-8.032-17.92-17.92-17.92-9.92 0-17.92 8.032-17.92 17.92v188.736zM423.216 416.528h-71.232v10.896c0 29.040-19.76 52.576-48.8 52.576h-94.72c-29.008 0-48.48-23.536-48.48-52.576v-10.896h-71.232c-13.696 0-24.768-11.088-24.768-24.752v-71.984h384v71.984c0 13.664-11.040 24.752-24.768 24.752zM319.936 416.528h-128.192v14.704c0.032 9.248 7.488 16.736 16.72 16.768h94.72c9.216-0.032 16.704-7.52 16.752-16.768v-14.704z"/><glyph unicode="&#xe605;" d="M511.52 278.496c-1.312 4.096-5.152 6.88-9.44 6.88h-180.704l-55.952 171.744c-1.344 4.096-5.136 6.88-9.44 6.88-4.272 0-8.096-2.784-9.44-6.88l-56.24-171.744h-180.384c-4.256 0-8.096-2.784-9.44-6.88-1.312-4.064 0.128-8.592 3.584-11.088l145.984-106.32-56.256-172.72c-1.328-4.096 0.128-8.592 3.616-11.12 3.456-2.496 8.208-2.496 11.664 0l146.896 106.624 146.64-106.624c1.792-1.28 3.76-1.936 5.808-1.936 2.096 0 4.144 0.656 5.856 1.936 3.568 2.528 4.96 7.008 3.6 11.12l-56.24 172.72 146.288 106.32c3.488 2.496 4.928 6.992 3.6 11.088z"/><glyph unicode="&#xe606;" d="M473.015 200.375v49.371l-7.003 2.268-52.882 17.244-14.116 34.103 27.154 57.381-34.908 34.907-6.583-3.309-49.555-25.198-34.103 14.117-21.394 59.757h-49.371l-2.286-6.985-17.262-52.882-34.048-14.099-57.399 27.136-34.925-34.926 3.309-6.564 25.18-49.591-14.080-34.029-59.758-21.412v-49.39l6.949-2.249 52.901-17.28 14.099-34.067-27.118-57.38 34.925-34.925 6.528 3.328 49.591 25.197 34.066-14.116 21.394-59.757h49.371l2.286 6.985 17.28 52.882 34.029 14.116 57.399-27.136 34.944 34.908-3.346 6.546-25.197 49.572 14.116 34.067 59.813 21.413zM256 154.861c-38.199 0-69.156 30.957-69.156 69.139 0 38.217 30.958 69.156 69.156 69.156 38.163 0 69.156-30.94 69.156-69.156 0-38.18-31.012-69.139-69.156-69.139z"/><glyph unicode="&#xe607;" d="M31.008 351.36l224.992-239.984 225.040 239.984z"/><glyph unicode="&#xe608;" d="M383.415 226.596l-212.571 218.587-37.285-34.981 178.286-183.277-183.278-188.452 36.48-35.657 205.659 211.456-0.201 0.201z"/><glyph unicode="&#xe609;" d="M52.928 345.2h406.144c11.056 0 20 8.976 20 20.016 0 11.072-8.944 20.032-20 20.032h-406.144c-11.056 0-20.016-8.96-20.016-20.032 0-11.040 8.96-20.016 20.016-20.016zM459.072 244.016h-406.144c-11.056 0-20.016-8.944-20.016-20.016s8.96-20.016 20.016-20.016h406.144c11.056 0 20 8.944 20 20.016s-8.928 20.016-20 20.016zM459.072 102.8h-406.144c-11.056 0-20.016-8.96-20.016-20.032s8.96-20.016 20.016-20.016h406.144c11.056 0 20 8.944 20 20.016s-8.928 20.032-20 20.032z"/><glyph unicode="&#xe60a;" d="M256.144 480c-89.12 0-161.344-72.24-161.344-161.376 0-89.104 161.344-350.624 161.344-350.624s161.376 261.52 161.376 350.624c0 89.136-72.192 161.376-161.376 161.376zM256.144 269.616c-27.056 0-49.024 21.952-49.024 49.008 0 27.072 21.984 49.024 49.024 49.024 27.104 0 49.088-21.952 49.088-49.024 0-27.056-21.984-49.008-49.088-49.008z"/><glyph unicode="&#xe60b;" d="M0 256.144h224.032v223.808h-224.032v-223.808zM288.128 479.952v-95.728h224.176v95.728h-224.176zM0-32h224.032v223.808h-224.032v-223.808zM288.128 256.144h224.176v95.728h-224.176v-95.728zM288.128 96.080h224.176v95.728h-224.176v-95.728zM288.128-32h224.176v95.712h-224.176v-95.712z"/><glyph unicode="&#xe60c;" d="M332.764 119.003c-9.216 0-45.495-56.027-65.243-56.027-5.284 0-7.863 4.644-7.863 9.216 0 10.569 7.241 27.044 11.154 36.937l47.397 128.384c23.772 63.891-6.546 81.024-34.871 81.024-38.217 0-72.448-19.091-98.779-44.124-8.576-8.576-37.523-36.206-37.523-48.091 0-3.932 3.931-8.576 8.576-8.576 11.813 0 43.447 57.308 67.803 57.308 5.285 0 11.191-5.924 6.583-17.755l-46.080-115.968c-4.644-11.154-27.044-65.171-27.044-96.786 0-25.015 16.476-36.188 40.192-36.188 66.523 0 143.543 81.645 143.543 100.755-0.019 5.925-4.589 9.892-7.844 9.892zM319.543 439.661c-28.947 0-54.016-23.68-54.016-52.663 0-27.008 17.792-44.8 44.837-44.8 29.55 0 54.62 22.4 54.62 52.7 0 27.008-19.072 44.764-45.44 44.764z"/><glyph unicode="&#xe60d;" d="M0 351.552h128.464v128.448h-128.464v-128.448zM191.76 351.552h128.528v128.448h-128.528v-128.448zM383.568 480v-128.448h128.496v128.448h-128.496zM0 159.744h128.464v128.464h-128.464v-128.464zM191.76 159.744h128.528v128.464h-128.528v-128.464zM383.568 159.744h128.496v128.464h-128.496v-128.464zM0-32h128.464v128h-128.464v-128zM191.76-32h128.528v128h-128.528v-128zM383.568-32h128.496v128h-128.496v-128z"/><glyph unicode="&#xe60e;" d="M255.296 450.464c-124.688 0-225.76-101.072-225.76-225.76 0-124.672 101.072-225.76 225.76-225.76 124.672 0 225.76 101.088 225.76 225.76 0 124.688-101.072 225.76-225.76 225.76zM231.936 94.576l-125.936 128.032 32.208 25.936 72.864-57.088c29.76 35.424 96 106.032 187.312 161.984l7.696-17.792c-83.808-77.088-152.48-185.6-174.144-241.072z"/><glyph unicode="&#xe60f;" d="M0 241.12h512v-34.064h-512v34.064z"/><glyph unicode="&#xe610;" d="M478.263 426.149c-142.555-87.388-245.98-197.632-292.48-252.947l-113.792 89.161-50.267-40.539 196.663-199.973c33.847 86.674 141.056 256.11 271.872 376.485l-11.995 27.813z"/><glyph unicode="&#xe611;" d="M220.576 83.248c-26.352 0-47.696-21.376-47.696-47.712s21.344-47.664 47.696-47.664c26.336 0 47.696 21.328 47.696 47.664s-21.36 47.712-47.696 47.712zM385.344 83.248c-26.4 0-47.76-21.376-47.76-47.712s21.344-47.664 47.76-47.664c26.288 0 47.632 21.328 47.632 47.664s-21.344 47.712-47.632 47.712zM459.856 350.32c-122.384 0-319.856 0-319.856 0s-19.152 52.608-37.392 84.864c-14.128 24.976-43.344 23.968-43.344 23.968-20.096 0-33.024-12.288-33.024-32.4 0-20.096 15.92-36.16 36.032-36.16l8.496-0.080 95.2-262.192 266.832-0.208c0 0 48.784 199.632 46.272 191.888 8.944 27.68-2.448 30.32-19.216 30.32zM166.528 257.344c-14 0-25.36 11.36-25.36 25.376s11.36 25.392 25.36 25.392c14.016 0 25.36-11.376 25.36-25.392s-11.344-25.376-25.36-25.376zM220.768 172.64c-14.016 0-25.376 11.376-25.376 25.392 0 13.984 11.36 25.36 25.376 25.36 14 0 25.36-11.376 25.36-25.36 0.016-14.016-11.36-25.392-25.36-25.392zM248.656 257.344c-14 0-25.376 11.36-25.376 25.376s11.36 25.392 25.376 25.392c14 0 25.36-11.376 25.36-25.392s-11.36-25.376-25.36-25.376zM302.896 172.64c-14 0-25.36 11.376-25.36 25.392 0 13.984 11.36 25.36 25.36 25.36 14.048 0 25.44-11.376 25.44-25.36 0-14.016-11.392-25.392-25.44-25.392zM330.848 257.344c-14 0-25.408 11.36-25.408 25.376s11.408 25.392 25.408 25.392c14 0 25.328-11.376 25.328-25.392s-11.328-25.376-25.328-25.376zM385.040 172.64c-13.984 0-25.328 11.376-25.328 25.392 0 13.984 11.36 25.36 25.328 25.36 14 0 25.408-11.376 25.408-25.36 0-14.016-11.408-25.392-25.408-25.392zM412.96 257.344c-14.016 0-25.36 11.36-25.36 25.376s11.344 25.392 25.36 25.392c14.048 0 25.376-11.376 25.376-25.392s-11.328-25.376-25.376-25.376z"/><glyph unicode="&#xe612;" d="M142.992 332.768c10.352 0 18.8 8.4 18.8 18.8v67.68c0 10.368-8.432 18.784-18.8 18.784-10.384 0-18.8-8.4-18.8-18.784v-67.68c0-10.4 8.416-18.8 18.8-18.8zM394.384 383.344v-0.32c7.776-6.944 12.72-17.008 12.72-28.288 0-20.816-16.88-37.712-37.744-37.712s-37.76 16.912-37.76 37.712c0 11.264 4.976 21.344 12.784 28.288v0.32h-176.416v-0.32c7.824-6.944 12.768-17.008 12.768-28.288 0-20.816-16.896-37.712-37.728-37.712-20.864 0-37.744 16.912-37.744 37.712 0 11.264 4.928 21.344 12.752 28.288v0.32h-85.536v-383.6h447.248v383.6h-85.344zM448.72 32.832h-383.152v254.72h383.152v-254.72zM369.36 332.768c10.384 0 18.784 8.4 18.784 18.8v67.68c0 10.368-8.4 18.784-18.784 18.784-10.352 0-18.816-8.4-18.816-18.784v-67.68c0-10.4 8.464-18.8 18.816-18.8zM349.216 184.128h-47.936v-47.872h47.952v47.872zM349.216 256.112h-47.936v-47.824h47.952v47.824zM349.216 114.112h-47.936v-47.872h47.952v47.872zM416.656 256.112h-47.92v-47.824h47.92v47.824zM416.656 184.128h-47.92v-47.872h47.92v47.872zM281.696 256.112h-47.872v-47.824h47.872v47.824zM146.8 184.128h-47.856v-47.872h47.856v47.872zM214.288 114.112h-47.888v-47.872h47.872v47.872zM146.8 114.112h-47.856v-47.872h47.856v47.872zM281.696 184.128h-47.872v-47.872h47.872v47.872zM281.696 114.112h-47.872v-47.872h47.872v47.872zM214.288 184.128h-47.888v-47.872h47.872v47.872zM214.288 256.112h-47.888v-47.824h47.872v47.824z"/><glyph unicode="&#xe613;" d="M256 444.727l-200.814-243.291h131.054v-198.144h139.575v198.144h131.017z"/><glyph unicode="&#xe614;" d="M325.779 246.583v198.144h-139.593v-198.144h-130.999l200.832-243.292 200.813 243.292z"/><glyph unicode="&#xe615;" d="M487.232 35.872c0 0-78.176 80.288-109.328 111.312-13.552 13.552-22.832 22.752-22.832 22.752 10.56 15.088 18.816 31.616 24.704 49.392 5.84 17.76 8.752 36.496 8.752 56.192 0 25.36-4.816 49.2-14.448 71.552-9.664 22.32-22.784 41.824-39.456 58.432-16.64 16.688-36.144 29.824-58.496 39.472-22.336 9.664-46.176 14.496-71.536 14.496-25.344 0-49.184-4.848-71.552-14.496-22.336-9.648-41.712-22.784-58.192-39.472-16.416-16.608-29.52-36.128-39.152-58.448-9.664-22.336-14.496-46.192-14.496-71.552 0-25.376 4.848-49.216 14.496-71.552 9.632-22.304 22.72-41.792 39.152-58.464 16.464-16.608 35.856-29.776 58.176-39.456 22.368-9.664 46.208-14.448 71.552-14.448 19.68 0 38.416 2.88 56.208 8.768 17.776 5.856 34.288 14.144 49.36 24.72 0 0 8.576-8.512 21.2-21.216 34.512-34.64 110.416-113.392 110.416-113.392 11.456-4.992 29.712 0.336 38.848 8.064 9.040 7.776 14.096 23.984 6.624 37.344zM327.792 223.28c-7.008-16.192-16.576-30.336-28.624-42.336-12.096-12.048-26.192-21.616-42.336-28.608-16.128-7.024-33.392-10.528-51.68-10.528-18.704 0-36.096 3.504-52.256 10.528-16.16 7.008-30.288 16.56-42.336 28.608-12.048 12.016-21.616 26.16-28.608 42.336-7.008 16.112-10.512 33.568-10.512 52.24 0 18.272 3.504 35.632 10.512 51.984 6.992 16.336 16.56 30.56 28.608 42.592 12.048 12.096 26.176 21.664 42.336 28.608 16.16 7.056 33.552 10.512 52.256 10.512 18.288 0 35.552-3.456 51.68-10.512 16.144-6.96 30.24-16.512 42.336-28.608 12.032-12.032 21.616-26.256 28.624-42.592 7.008-16.352 10.48-33.712 10.48-51.984 0.016-18.672-3.456-36.128-10.48-52.24z"/><glyph unicode="&#xe616;" d="M483.255 415.177l-36.023 35.968-191.25-191.268-191.25 191.268-35.986-35.968 191.268-191.269-191.123-191.14 35.968-35.932 191.14 191.104 191.123-191.104 35.932 35.932-191.104 191.123z"/><glyph unicode="&#xe617;" d="M200.21 226.889l178.213 183.315-37.248 34.981-212.608-218.588 218.459-223.78 36.389 35.657z"/><glyph unicode="&#xe618;" d="M256 335.168l-224.992-239.984h450.032z"/><glyph unicode="&#xe619;" d="M96.624 451.12v-454.24l312.928 227.12z"/><glyph unicode="&#xe61a;" d="M102.992 224l312.912-227.12v454.24z"/><glyph unicode="&#xe61b;" d="M0 0.464h63.984v479.536h-63.984v-479.536zM512.080 480h-415.824v-287.888h415.824l-138.208 142.032 138.208 145.856z"/><glyph unicode="&#xe61c;" d="M512 241.12h-238.512v238.88h-34.016v-238.88h-239.472v-34.064h239.472v-239.056h34.016v239.056h238.512z"/><glyph unicode="&#xe61d;" d="M255.968 228.064l221.488 155.84c-2.656 0.528-5.344 0.848-8.128 0.848h-426.656c-2.8 0-5.504-0.32-8.144-0.848l221.44-155.84zM256.928 168.496l-0.96 1.408-0.944-1.408-254.56 179.136c-0.176-1.6-0.464-3.2-0.464-4.816v-267.712c0-23.904 19.104-43.312 42.672-43.312h426.656c23.6 0 42.688 19.408 42.688 43.312v267.712c0 1.632-0.288 3.216-0.496 4.816l-254.592-179.136z"/><glyph unicode="&#xe61e;" d="M127.584 31.776v127.632h-127.584v-127.632h127.584zM319.248 416.24h-126.928v-384.448h126.928v384.448zM511.584 287.472h-127.376v-255.68h127.376v255.68z"/><glyph unicode="&#xe61f;" d="M255.296 450.464c-124.688 0-225.76-101.072-225.76-225.76 0-124.672 101.072-225.76 225.76-225.76 124.672 0 225.76 101.088 225.76 225.76 0 124.688-101.072 225.76-225.76 225.76zM372.16 144.832l-37.104-37.104-79.088 79.056-79.056-79.040-37.12 37.136 79.024 79.024-79.136 79.12 37.136 37.136 79.12-79.136 79.184 79.184 37.152-37.152-79.2-79.168 79.088-79.056z"/><glyph unicode="&#xe620;" d="M262.748 418.688c-113.664 2.249-207.214-67.803-208.969-156.435-0.585-30.829 9.984-59.813 28.8-84.644l-4.919 4.955c32.384-41.618-31.104-153.308-31.104-153.308l142.281 70.345c22.51-7.095 44.16-11.923 69.724-12.452 113.664-2.231 205.111 78.355 206.848 167.004 1.755 88.631-88.96 162.304-202.661 164.535z"/><glyph unicode="&#xe621;" d="M259.163 285.422l201.837-196.224 38.546 41.070-240.713 234.021-246.363-240.476 39.26-40.101z"/><glyph unicode="&#xe622;" d="M252.819 162.579l-201.82 196.224-38.528-41.070 240.677-234.021 246.4 240.476-39.332 40.101z"/><glyph unicode="&#xe623;" d="M256-33.248c-141.408 0-256 114.624-256 256s114.592 256 256 256c141.376 0 256-114.624 256-256s-114.608-256-256-256zM256 447.76c-124.048 0-225.008-100.96-225.008-225.008s100.96-225.024 225.008-225.024 224.992 100.96 224.992 225.008-100.928 225.024-224.992 225.024zM320.24 219.152l-15.6-12.128c-8.496-6.624-14.128-14.32-16.912-23.152-1.776-5.6-3.008-12.256-3.168-24h-59.712c0.88 24.848 3.504 39.968 7.328 49.472 3.808 9.472 13.632 20.368 29.44 32.72l16.032 12.528c5.28 4 9.536 8.32 12.752 13.024 5.872 8.064 8.784 16.976 8.784 26.656 0 11.152-3.248 21.312-9.776 30.496-6.496 9.184-18.4 13.808-35.712 13.808-17.008 0-29.056-5.68-36.16-17.008s-10.592-21.664-10.592-33.84h-63.68c1.744 41.872 16.32 70.16 43.776 87.632 17.344 11.152 38.656 16.752 63.904 16.752 33.216 0 60.784-7.936 82.752-23.808 21.968-15.84 34.8-48.432 34.8-79.6 0-19.088-6.624-26.096-16.144-39.184-5.584-7.92-16.272-18.048-32.112-30.368zM287.728 64h-63.504v63.68h63.504v-63.68z"/><glyph unicode="&#xe624;" d="M416.656 128v135.696h-320.672v-135.696h-95.984v199.344c0 13.76 11.168 24.912 24.944 24.912h462.144c13.744 0 24.912-11.152 24.912-24.912v-199.344h-95.344zM464.304 324.624c-11.024 0-19.92-8.928-19.92-19.936s8.896-19.952 19.92-19.952c10.992 0 19.968 8.96 19.968 19.952 0 11.008-8.992 19.936-19.968 19.936zM127.728 480h256v-96.192h-256v96.192zM160.976 31.664h191.232v192.336h31.824v-224.080h-255.984v224.080h32.912v-192.336z"/><glyph unicode="&#xe625;" d="M502.080 285.376h-180.704l-55.952 171.744c-1.344 4.096-5.136 6.88-9.44 6.88-4.272 0-8.096-2.784-9.44-6.88l-56.24-171.744h-180.384c-4.256 0-8.096-2.784-9.44-6.88-1.312-4.064 0.128-8.592 3.584-11.088l145.984-106.32-56.256-172.72c-1.328-4.096 0.128-8.592 3.616-11.12 3.456-2.496 8.208-2.496 11.664 0l146.896 106.624 146.64-106.624c1.792-1.28 3.76-1.936 5.808-1.936 2.096 0 4.144 0.656 5.856 1.936 3.568 2.528 4.96 7.008 3.6 11.12l-56.24 172.72 146.288 106.32c3.488 2.496 4.928 7.008 3.6 11.088-1.312 4.096-5.168 6.88-9.44 6.88zM333.424 170.256l48.208-148.064-125.632 91.36-125.968-91.44 48.256 148.128-125.168 91.136h154.576l48.256 147.376 48.016-147.376h154.832l-125.376-91.12z"/><glyph unicode="&#xe626;" d="M319.376 223.824v127.76h-126.752v-127.76h-89.744l153.168-188.608 153.088 188.608zM256.016 480c-141.392 0-256-114.608-256-255.984 0-141.392 114.608-256.016 256-256.016 141.376 0 256 114.624 256 256.016 0 141.376-114.624 255.984-256 255.984zM256.016 0c-123.52 0-224 100.496-224 224.016 0 123.504 100.48 223.984 224 223.984s224-100.48 224-223.984c0-123.52-100.48-224.016-224-224.016z"/><glyph unicode="&#xe627;" d="M255.982 440.594c-119.607 0-216.576-96.969-216.576-216.594s96.969-216.595 216.576-216.595c119.625 0 216.595 96.969 216.595 216.595s-96.951 216.595-216.595 216.595zM255.982 419.913c108.051 0 195.913-87.881 195.913-195.913 0-45.184-15.507-86.711-41.325-119.899-3.108 1.134-6.217 2.195-9.197 3.456-19.748 8.265-41.709 17.957-61.421 26.094-5.632 1.536-11.264 3.072-16.896 4.608-6.692 4.589-13.33 19.986-16.914 27.666-3.548 0.512-7.149 1.005-10.752 1.481 0.531 11.868 7.881 12.544 10.752 21.541 2.541 7.954 0.293 18.341 4.279 25.728 2.779 5.12 9.125 5.12 12.233 9.545 2.853 3.95 4.772 10.917 5.668 15.799 1.609 8.905 3.017 21.12-1.207 29.988-2.432 5.065-3.968 5.577-4.644 11.739-0.823 7.516 2.212 31.891 2.341 37.175 0.293 13.678-0.055 14.793-3.346 28.123 0 0-4.005 12.087-10.295 15.726l-12.58 2.158-7.772 7.186c-31.305 19.273-64.877 5.76-82.834-1.499-25.911-8.43-42.295-33.792-30.867-87.955 1.957-9.289-5.065-13.421-4.608-18.468 1.042-11.045 1.207-37.614 11.648-44.124 0.969-0.603 8.375-2.469 8.339-1.938 1.006-10.752 2.048-21.522 3.054-32.238 2.615-7.149 8.869-7.954 10.679-18.048l-7.991-1.92c-3.602-7.68-10.185-23.077-16.896-27.666-5.65-1.517-11.282-3.053-16.915-4.589-19.731-8.119-41.655-17.829-61.422-26.094-1.079-0.439-2.213-0.786-3.291-1.207-24.759 32.786-39.625 73.454-39.625 117.632 0 108.032 87.881 195.913 195.895 195.913z"/><glyph unicode="&#xe628;" d="M94.8 322.592l-93.424 78.464-0.496-321.968 316.688 56.336-89.216 74.96c182.112 167.52 227.904-8.128 246.272-204.784 65.936 574.064-229.84 445.328-379.824 316.992z"/><glyph unicode="&#xe629;" d="M428.432 224h-20.080v96.176c0 43.36-16.448 83.104-43.632 112.144-27.056 29.056-65.632 47.712-108.16 47.68-42.544 0.032-81.12-18.624-108.192-47.68-27.184-29.040-43.632-68.784-43.648-112.144v-96.176h-20.816c-10.816 0-19.584-8.752-19.584-19.584v-216.8c0-10.848 8.768-19.616 19.584-19.616h344.528c10.8 0 19.584 8.768 19.584 19.632v216.8c0 10.816-8.784 19.568-19.584 19.568zM176.816 320.176c0 25.024 9.472 47.168 24.192 62.928 14.848 15.728 34.144 24.784 55.552 24.816 21.376-0.032 40.688-9.072 55.536-24.816 14.704-15.744 24.176-37.888 24.176-62.928v-96.176h-159.44v96.176z"/><glyph unicode="&#xe62a;" d="M150.896 316.944h-112.192c-9.040 0-16.384-7.312-16.384-16.368v-80c0-9.056 7.344-16.368 16.384-16.368h112.192c9.056 0 16.432 7.312 16.432 16.368v80c0 9.056-7.376 16.368-16.432 16.368zM150.896 171.056h-79.376c-9.056 0-16.432-7.312-16.432-16.368v-170.32c-0.016-9.056 7.36-16.368 16.432-16.368h79.376c9.056 0 16.432 7.312 16.432 16.368v170.32c0 9.056-7.376 16.368-16.432 16.368zM473.328 316.944h-244.88c-9.056 0-16.368-7.312-16.368-16.368v-80c0-9.056 7.312-16.368 16.368-16.368h244.88c8.992 0 16.368 7.312 16.368 16.368v80c0 9.056-7.36 16.368-16.368 16.368zM439.52 169.376h-210.56c-9.056 0-16.368-7.344-16.368-16.4v-168.592c0-9.056 7.312-16.368 16.368-16.368h210.56c9.056 0 16.368 7.312 16.368 16.368v168.592c0 9.056-7.312 16.4-16.368 16.4zM251.952 335.68c19.12-3.504 37.568-5.536 54.816-5.536 86.688 0 133.68 46.592 133.936 90.464 0.128 28.256-20.752 58.88-68.368 59.376-63.808 0-103.312-45.056-123.872-78.496-20.944 33.312-60.624 77.472-124.56 77.472-46.256-0.464-67.2-31.088-67.008-59.328 0.176-43.888 47.248-90.512 133.936-90.512v0c18.752 0 38.88 2.128 59.872 6.336l1.248 0.224zM373.264 439.008c8-0.064 26.56-2 26.432-18.192-0.064-20.624-28.992-49.68-92.944-49.68-8.816 0-18 0.56-27.632 1.68 14.576 25.648 45.216 66.192 94.144 66.192zM190.832 370.128v0c-63.936 0-92.88 29.056-92.992 49.68-0.080 16.16 18.496 18.096 27.36 18.192 48.368 0 78.816-40.56 93.184-66.224-9.552-1.088-18.736-1.648-27.552-1.648z"/><glyph unicode="&#xe62b;" d="M182.256 403.408c0-9.248-7.504-16.72-16.688-16.72h-9.776c-9.216 0-16.72 7.472-16.72 16.72v59.872c0 9.216 7.504 16.72 16.72 16.72h9.776c9.184 0 16.688-7.504 16.688-16.72v-59.872zM373.072 403.408c0-9.248-7.504-16.72-16.688-16.72h-9.744c-9.248 0-16.688 7.472-16.688 16.72v59.872c0 9.216 7.424 16.72 16.688 16.72h9.744c9.184 0 16.688-7.504 16.688-16.72v-59.872zM398.816 253.152l-33.936 27.664-133.68-163.872-71.312 56.688-25.28-31.728 105.184-83.648zM471.952 434h-62.432v-26.064c0-27.68-22.56-50.192-50.128-50.192h-9.808c-27.68 0-50.128 22.496-50.128 50.192v26.064h-85.504v-26.064c0-27.68-22.496-50.192-50.128-50.192h-9.76c-27.664 0-50.16 22.496-50.16 50.192v26.064h-63.808c-9.216 0-16.72-7.504-16.72-16.688v-432.592c0-9.216 7.504-16.72 16.72-16.72h431.84c9.184 0 16.688 7.504 16.688 16.72v432.592c0.016 9.184-7.488 16.688-16.672 16.688zM438.512 42.592c0-9.248-7.504-16.72-16.752-16.72h-331.504c-9.248 0-16.752 7.472-16.752 16.72v252.096c0 9.248 7.504 16.688 16.752 16.688h331.504c9.248 0 16.752-7.44 16.752-16.688v-252.096z"/></font></defs></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg"><defs><font-face units-per-em="512" ascent="480" descent="-32" /><missing-glyph horiz-adv-x="512" /><glyph unicode="&#x20;" d="" horiz-adv-x="256" /><glyph unicode="&#xe600;" d="M436.608 435.568c-65.68 31.424-144.064 2.832-174.976-63.84-2.16-4.64-4.016-10.448-5.664-17.2-1.648 6.752-3.504 12.56-5.632 17.2-30.944 66.672-109.248 95.264-174.944 63.84-65.6-31.424-93.744-110.96-62.832-177.648 30.928-66.672 243.344-257.84 243.344-257.84s0.016 0.224 0.048 0.576c0.048-0.352 0.064-0.576 0.064-0.576s212.512 191.168 243.44 257.84c30.896 66.688 2.832 146.224-62.848 177.648z" /><glyph unicode="&#xe601;" d="M362.533 425.051c-49.81-49.792-20.809-20.772-20.809-20.772l96.402-96.384c0 0-31.067-31.049 20.772 20.773s-46.611 146.194-96.365 96.384zM320.147 383.671l-227.987-227.986 0.329-0.293-54.071-146.524 149.833 50.688 0.311-0.311 0.786 0.805v0.019l227.2 227.2-96.403 96.403zM179.036 104.375l-78.811-33.28 37.047 75.044 38.345 38.363 41.764-41.783-38.345-38.345z" /><glyph unicode="&#xe602;" d="M255.952 480l-255.952-448h512l-256.048 448zM287.12 353.808v-65.36l-16.688-128.544h-27.088l-18.032 128.544-0.992 65.36h62.8zM224.096 64.112v64.112h64.24v-64.112h-64.24z" /><glyph unicode="&#xe603;" d="M363.923 112.019c-29.805-28.764-68.663-43.502-108.013-43.538-35.145 0.036-70.199 11.757-99.347 35.932-37.029 30.829-56.046 74.971-56.1 119.661 0 7.442 0.549 14.829 1.591 22.18l-60.672-11.374c-0.164-3.602-0.292-7.186-0.292-10.807-0.036-61.495 26.459-122.899 77.549-165.285 40.009-33.335 88.887-49.683 137.252-49.683h0.128c56.211 0 112.164 22.217 153.746 64.914l39.844-39.772 0.311 124.745-131.803 0.348 45.805-47.324zM393.344 389.23c-40.046 33.335-88.923 49.664-137.271 49.664-55.808 0-111.397-21.833-152.923-63.945l-37.687 34.798-0.677-120.722 130.487-0.75-46.336 48.493c29.641 28.252 68.188 42.697 107.154 42.733 35.108-0.036 70.217-11.721 99.328-35.932 37.029-30.829 56.046-74.935 56.137-119.698 0-6.437-0.457-12.892-1.225-19.365l60.435 11.593c0.036 2.615 0.164 5.212 0.164 7.772-0.036 61.549-26.514 122.899-77.587 165.357z" /><glyph unicode="&#xe604;" d="M95.792-32h320.4v320.080h-320.4v-320.080zM318.336 228.512c0 9.904 8.032 17.904 17.952 17.904 9.904 0 17.936-8 17.936-17.904v-188.736c0-9.888-8.032-17.92-17.936-17.92-9.92 0-17.952 8.032-17.952 17.92v188.736zM238.048 228.512c0 9.904 8.032 17.904 17.92 17.904s17.92-8 17.92-17.904v-188.736c0-9.888-8.032-17.92-17.92-17.92s-17.92 8.032-17.92 17.92v188.736zM157.6 228.512c0 9.904 8 17.904 17.92 17.904 9.888 0 17.92-8 17.92-17.904v-188.736c0-9.888-8.032-17.92-17.92-17.92-9.92 0-17.92 8.032-17.92 17.92v188.736zM423.216 416.528h-71.232v10.896c0 29.040-19.76 52.576-48.8 52.576h-94.72c-29.008 0-48.48-23.536-48.48-52.576v-10.896h-71.232c-13.696 0-24.768-11.088-24.768-24.752v-71.984h384v71.984c0 13.664-11.040 24.752-24.768 24.752zM319.936 416.528h-128.192v14.704c0.032 9.248 7.488 16.736 16.72 16.768h94.72c9.216-0.032 16.704-7.52 16.752-16.768v-14.704z" /><glyph unicode="&#xe605;" d="M511.52 278.496c-1.312 4.096-5.152 6.88-9.44 6.88h-180.704l-55.952 171.744c-1.344 4.096-5.136 6.88-9.44 6.88-4.272 0-8.096-2.784-9.44-6.88l-56.24-171.744h-180.384c-4.256 0-8.096-2.784-9.44-6.88-1.312-4.064 0.128-8.592 3.584-11.088l145.984-106.32-56.256-172.72c-1.328-4.096 0.128-8.592 3.616-11.12 3.456-2.496 8.208-2.496 11.664 0l146.896 106.624 146.64-106.624c1.792-1.28 3.76-1.936 5.808-1.936 2.096 0 4.144 0.656 5.856 1.936 3.568 2.528 4.96 7.008 3.6 11.12l-56.24 172.72 146.288 106.32c3.488 2.496 4.928 6.992 3.6 11.088z" /><glyph unicode="&#xe606;" d="M473.015 200.375v49.371l-7.003 2.268-52.882 17.244-14.116 34.103 27.154 57.381-34.908 34.907-6.583-3.309-49.555-25.198-34.103 14.117-21.394 59.757h-49.371l-2.286-6.985-17.262-52.882-34.048-14.099-57.399 27.136-34.925-34.926 3.309-6.564 25.18-49.591-14.080-34.029-59.758-21.412v-49.39l6.949-2.249 52.901-17.28 14.099-34.067-27.118-57.38 34.925-34.925 6.528 3.328 49.591 25.197 34.066-14.116 21.394-59.757h49.371l2.286 6.985 17.28 52.882 34.029 14.116 57.399-27.136 34.944 34.908-3.346 6.546-25.197 49.572 14.116 34.067 59.813 21.413zM256 154.861c-38.199 0-69.156 30.957-69.156 69.139 0 38.217 30.958 69.156 69.156 69.156 38.163 0 69.156-30.94 69.156-69.156 0-38.18-31.012-69.139-69.156-69.139z" /><glyph unicode="&#xe607;" d="M31.008 351.36l224.992-239.984 225.040 239.984z" /><glyph unicode="&#xe608;" d="M383.415 226.596l-212.571 218.587-37.285-34.981 178.286-183.277-183.278-188.452 36.48-35.657 205.659 211.456-0.201 0.201z" /><glyph unicode="&#xe609;" d="M52.928 345.2h406.144c11.056 0 20 8.976 20 20.016 0 11.072-8.944 20.032-20 20.032h-406.144c-11.056 0-20.016-8.96-20.016-20.032 0-11.040 8.96-20.016 20.016-20.016zM459.072 244.016h-406.144c-11.056 0-20.016-8.944-20.016-20.016s8.96-20.016 20.016-20.016h406.144c11.056 0 20 8.944 20 20.016s-8.928 20.016-20 20.016zM459.072 102.8h-406.144c-11.056 0-20.016-8.96-20.016-20.032s8.96-20.016 20.016-20.016h406.144c11.056 0 20 8.944 20 20.016s-8.928 20.032-20 20.032z" /><glyph unicode="&#xe60a;" d="M256.144 480c-89.12 0-161.344-72.24-161.344-161.376 0-89.104 161.344-350.624 161.344-350.624s161.376 261.52 161.376 350.624c0 89.136-72.192 161.376-161.376 161.376zM256.144 269.616c-27.056 0-49.024 21.952-49.024 49.008 0 27.072 21.984 49.024 49.024 49.024 27.104 0 49.088-21.952 49.088-49.024 0-27.056-21.984-49.008-49.088-49.008z" /><glyph unicode="&#xe60b;" d="M0 256.144h224.032v223.808h-224.032v-223.808zM288.128 479.952v-95.728h224.176v95.728h-224.176zM0-32h224.032v223.808h-224.032v-223.808zM288.128 256.144h224.176v95.728h-224.176v-95.728zM288.128 96.080h224.176v95.728h-224.176v-95.728zM288.128-32h224.176v95.712h-224.176v-95.712z" /><glyph unicode="&#xe60c;" d="M332.764 119.003c-9.216 0-45.495-56.027-65.243-56.027-5.284 0-7.863 4.644-7.863 9.216 0 10.569 7.241 27.044 11.154 36.937l47.397 128.384c23.772 63.891-6.546 81.024-34.871 81.024-38.217 0-72.448-19.091-98.779-44.124-8.576-8.576-37.523-36.206-37.523-48.091 0-3.932 3.931-8.576 8.576-8.576 11.813 0 43.447 57.308 67.803 57.308 5.285 0 11.191-5.924 6.583-17.755l-46.080-115.968c-4.644-11.154-27.044-65.171-27.044-96.786 0-25.015 16.476-36.188 40.192-36.188 66.523 0 143.543 81.645 143.543 100.755-0.019 5.925-4.589 9.892-7.844 9.892zM319.543 439.661c-28.947 0-54.016-23.68-54.016-52.663 0-27.008 17.792-44.8 44.837-44.8 29.55 0 54.62 22.4 54.62 52.7 0 27.008-19.072 44.764-45.44 44.764z" /><glyph unicode="&#xe60d;" d="M0 351.552h128.464v128.448h-128.464v-128.448zM191.76 351.552h128.528v128.448h-128.528v-128.448zM383.568 480v-128.448h128.496v128.448h-128.496zM0 159.744h128.464v128.464h-128.464v-128.464zM191.76 159.744h128.528v128.464h-128.528v-128.464zM383.568 159.744h128.496v128.464h-128.496v-128.464zM0-32h128.464v128h-128.464v-128zM191.76-32h128.528v128h-128.528v-128zM383.568-32h128.496v128h-128.496v-128z" /><glyph unicode="&#xe60e;" d="M255.296 450.464c-124.688 0-225.76-101.072-225.76-225.76 0-124.672 101.072-225.76 225.76-225.76 124.672 0 225.76 101.088 225.76 225.76 0 124.688-101.072 225.76-225.76 225.76zM231.936 94.576l-125.936 128.032 32.208 25.936 72.864-57.088c29.76 35.424 96 106.032 187.312 161.984l7.696-17.792c-83.808-77.088-152.48-185.6-174.144-241.072z" /><glyph unicode="&#xe60f;" d="M0 241.12h512v-34.064h-512v34.064z" /><glyph unicode="&#xe610;" d="M478.263 426.149c-142.555-87.388-245.98-197.632-292.48-252.947l-113.792 89.161-50.267-40.539 196.663-199.973c33.847 86.674 141.056 256.11 271.872 376.485l-11.995 27.813z" /><glyph unicode="&#xe611;" d="M220.576 83.248c-26.352 0-47.696-21.376-47.696-47.712s21.344-47.664 47.696-47.664c26.336 0 47.696 21.328 47.696 47.664s-21.36 47.712-47.696 47.712zM385.344 83.248c-26.4 0-47.76-21.376-47.76-47.712s21.344-47.664 47.76-47.664c26.288 0 47.632 21.328 47.632 47.664s-21.344 47.712-47.632 47.712zM459.856 350.32c-122.384 0-319.856 0-319.856 0s-19.152 52.608-37.392 84.864c-14.128 24.976-43.344 23.968-43.344 23.968-20.096 0-33.024-12.288-33.024-32.4 0-20.096 15.92-36.16 36.032-36.16l8.496-0.080 95.2-262.192 266.832-0.208c0 0 48.784 199.632 46.272 191.888 8.944 27.68-2.448 30.32-19.216 30.32zM166.528 257.344c-14 0-25.36 11.36-25.36 25.376s11.36 25.392 25.36 25.392c14.016 0 25.36-11.376 25.36-25.392s-11.344-25.376-25.36-25.376zM220.768 172.64c-14.016 0-25.376 11.376-25.376 25.392 0 13.984 11.36 25.36 25.376 25.36 14 0 25.36-11.376 25.36-25.36 0.016-14.016-11.36-25.392-25.36-25.392zM248.656 257.344c-14 0-25.376 11.36-25.376 25.376s11.36 25.392 25.376 25.392c14 0 25.36-11.376 25.36-25.392s-11.36-25.376-25.36-25.376zM302.896 172.64c-14 0-25.36 11.376-25.36 25.392 0 13.984 11.36 25.36 25.36 25.36 14.048 0 25.44-11.376 25.44-25.36 0-14.016-11.392-25.392-25.44-25.392zM330.848 257.344c-14 0-25.408 11.36-25.408 25.376s11.408 25.392 25.408 25.392c14 0 25.328-11.376 25.328-25.392s-11.328-25.376-25.328-25.376zM385.040 172.64c-13.984 0-25.328 11.376-25.328 25.392 0 13.984 11.36 25.36 25.328 25.36 14 0 25.408-11.376 25.408-25.36 0-14.016-11.408-25.392-25.408-25.392zM412.96 257.344c-14.016 0-25.36 11.36-25.36 25.376s11.344 25.392 25.36 25.392c14.048 0 25.376-11.376 25.376-25.392s-11.328-25.376-25.376-25.376z" /><glyph unicode="&#xe612;" d="M142.992 332.768c10.352 0 18.8 8.4 18.8 18.8v67.68c0 10.368-8.432 18.784-18.8 18.784-10.384 0-18.8-8.4-18.8-18.784v-67.68c0-10.4 8.416-18.8 18.8-18.8zM394.384 383.344v-0.32c7.776-6.944 12.72-17.008 12.72-28.288 0-20.816-16.88-37.712-37.744-37.712s-37.76 16.912-37.76 37.712c0 11.264 4.976 21.344 12.784 28.288v0.32h-176.416v-0.32c7.824-6.944 12.768-17.008 12.768-28.288 0-20.816-16.896-37.712-37.728-37.712-20.864 0-37.744 16.912-37.744 37.712 0 11.264 4.928 21.344 12.752 28.288v0.32h-85.536v-383.6h447.248v383.6h-85.344zM448.72 32.832h-383.152v254.72h383.152v-254.72zM369.36 332.768c10.384 0 18.784 8.4 18.784 18.8v67.68c0 10.368-8.4 18.784-18.784 18.784-10.352 0-18.816-8.4-18.816-18.784v-67.68c0-10.4 8.464-18.8 18.816-18.8zM349.216 184.128h-47.936v-47.872h47.952v47.872zM349.216 256.112h-47.936v-47.824h47.952v47.824zM349.216 114.112h-47.936v-47.872h47.952v47.872zM416.656 256.112h-47.92v-47.824h47.92v47.824zM416.656 184.128h-47.92v-47.872h47.92v47.872zM281.696 256.112h-47.872v-47.824h47.872v47.824zM146.8 184.128h-47.856v-47.872h47.856v47.872zM214.288 114.112h-47.888v-47.872h47.872v47.872zM146.8 114.112h-47.856v-47.872h47.856v47.872zM281.696 184.128h-47.872v-47.872h47.872v47.872zM281.696 114.112h-47.872v-47.872h47.872v47.872zM214.288 184.128h-47.888v-47.872h47.872v47.872zM214.288 256.112h-47.888v-47.824h47.872v47.824z" /><glyph unicode="&#xe613;" d="M256 444.727l-200.814-243.291h131.054v-198.144h139.575v198.144h131.017z" /><glyph unicode="&#xe614;" d="M325.779 246.583v198.144h-139.593v-198.144h-130.999l200.832-243.292 200.813 243.292z" /><glyph unicode="&#xe615;" d="M487.232 35.872c0 0-78.176 80.288-109.328 111.312-13.552 13.552-22.832 22.752-22.832 22.752 10.56 15.088 18.816 31.616 24.704 49.392 5.84 17.76 8.752 36.496 8.752 56.192 0 25.36-4.816 49.2-14.448 71.552-9.664 22.32-22.784 41.824-39.456 58.432-16.64 16.688-36.144 29.824-58.496 39.472-22.336 9.664-46.176 14.496-71.536 14.496-25.344 0-49.184-4.848-71.552-14.496-22.336-9.648-41.712-22.784-58.192-39.472-16.416-16.608-29.52-36.128-39.152-58.448-9.664-22.336-14.496-46.192-14.496-71.552 0-25.376 4.848-49.216 14.496-71.552 9.632-22.304 22.72-41.792 39.152-58.464 16.464-16.608 35.856-29.776 58.176-39.456 22.368-9.664 46.208-14.448 71.552-14.448 19.68 0 38.416 2.88 56.208 8.768 17.776 5.856 34.288 14.144 49.36 24.72 0 0 8.576-8.512 21.2-21.216 34.512-34.64 110.416-113.392 110.416-113.392 11.456-4.992 29.712 0.336 38.848 8.064 9.040 7.776 14.096 23.984 6.624 37.344zM327.792 223.28c-7.008-16.192-16.576-30.336-28.624-42.336-12.096-12.048-26.192-21.616-42.336-28.608-16.128-7.024-33.392-10.528-51.68-10.528-18.704 0-36.096 3.504-52.256 10.528-16.16 7.008-30.288 16.56-42.336 28.608-12.048 12.016-21.616 26.16-28.608 42.336-7.008 16.112-10.512 33.568-10.512 52.24 0 18.272 3.504 35.632 10.512 51.984 6.992 16.336 16.56 30.56 28.608 42.592 12.048 12.096 26.176 21.664 42.336 28.608 16.16 7.056 33.552 10.512 52.256 10.512 18.288 0 35.552-3.456 51.68-10.512 16.144-6.96 30.24-16.512 42.336-28.608 12.032-12.032 21.616-26.256 28.624-42.592 7.008-16.352 10.48-33.712 10.48-51.984 0.016-18.672-3.456-36.128-10.48-52.24z" /><glyph unicode="&#xe616;" d="M483.255 415.177l-36.023 35.968-191.25-191.268-191.25 191.268-35.986-35.968 191.268-191.269-191.123-191.14 35.968-35.932 191.14 191.104 191.123-191.104 35.932 35.932-191.104 191.123z" /><glyph unicode="&#xe617;" d="M200.21 226.889l178.213 183.315-37.248 34.981-212.608-218.588 218.459-223.78 36.389 35.657z" /><glyph unicode="&#xe618;" d="M256 335.168l-224.992-239.984h450.032z" /><glyph unicode="&#xe619;" d="M96.624 451.12v-454.24l312.928 227.12z" /><glyph unicode="&#xe61a;" d="M102.992 224l312.912-227.12v454.24z" /><glyph unicode="&#xe61b;" d="M0 0.464h63.984v479.536h-63.984v-479.536zM512.080 480h-415.824v-287.888h415.824l-138.208 142.032 138.208 145.856z" /><glyph unicode="&#xe61c;" d="M512 241.12h-238.512v238.88h-34.016v-238.88h-239.472v-34.064h239.472v-239.056h34.016v239.056h238.512z" /><glyph unicode="&#xe61d;" d="M255.968 228.064l221.488 155.84c-2.656 0.528-5.344 0.848-8.128 0.848h-426.656c-2.8 0-5.504-0.32-8.144-0.848l221.44-155.84zM256.928 168.496l-0.96 1.408-0.944-1.408-254.56 179.136c-0.176-1.6-0.464-3.2-0.464-4.816v-267.712c0-23.904 19.104-43.312 42.672-43.312h426.656c23.6 0 42.688 19.408 42.688 43.312v267.712c0 1.632-0.288 3.216-0.496 4.816l-254.592-179.136z" /><glyph unicode="&#xe61e;" d="M127.584 31.776v127.632h-127.584v-127.632h127.584zM319.248 416.24h-126.928v-384.448h126.928v384.448zM511.584 287.472h-127.376v-255.68h127.376v255.68z" /><glyph unicode="&#xe61f;" d="M255.296 450.464c-124.688 0-225.76-101.072-225.76-225.76 0-124.672 101.072-225.76 225.76-225.76 124.672 0 225.76 101.088 225.76 225.76 0 124.688-101.072 225.76-225.76 225.76zM372.16 144.832l-37.104-37.104-79.088 79.056-79.056-79.040-37.12 37.136 79.024 79.024-79.136 79.12 37.136 37.136 79.12-79.136 79.184 79.184 37.152-37.152-79.2-79.168 79.088-79.056z" /><glyph unicode="&#xe620;" d="M262.748 418.688c-113.664 2.249-207.214-67.803-208.969-156.435-0.585-30.829 9.984-59.813 28.8-84.644l-4.919 4.955c32.384-41.618-31.104-153.308-31.104-153.308l142.281 70.345c22.51-7.095 44.16-11.923 69.724-12.452 113.664-2.231 205.111 78.355 206.848 167.004 1.755 88.631-88.96 162.304-202.661 164.535z" /><glyph unicode="&#xe621;" d="M259.163 285.422l201.837-196.224 38.546 41.070-240.713 234.021-246.363-240.476 39.26-40.101z" /><glyph unicode="&#xe622;" d="M252.819 162.579l-201.82 196.224-38.528-41.070 240.677-234.021 246.4 240.476-39.332 40.101z" /><glyph unicode="&#xe623;" d="M256-33.248c-141.408 0-256 114.624-256 256s114.592 256 256 256c141.376 0 256-114.624 256-256s-114.608-256-256-256zM256 447.76c-124.048 0-225.008-100.96-225.008-225.008s100.96-225.024 225.008-225.024 224.992 100.96 224.992 225.008-100.928 225.024-224.992 225.024zM320.24 219.152l-15.6-12.128c-8.496-6.624-14.128-14.32-16.912-23.152-1.776-5.6-3.008-12.256-3.168-24h-59.712c0.88 24.848 3.504 39.968 7.328 49.472 3.808 9.472 13.632 20.368 29.44 32.72l16.032 12.528c5.28 4 9.536 8.32 12.752 13.024 5.872 8.064 8.784 16.976 8.784 26.656 0 11.152-3.248 21.312-9.776 30.496-6.496 9.184-18.4 13.808-35.712 13.808-17.008 0-29.056-5.68-36.16-17.008s-10.592-21.664-10.592-33.84h-63.68c1.744 41.872 16.32 70.16 43.776 87.632 17.344 11.152 38.656 16.752 63.904 16.752 33.216 0 60.784-7.936 82.752-23.808 21.968-15.84 34.8-48.432 34.8-79.6 0-19.088-6.624-26.096-16.144-39.184-5.584-7.92-16.272-18.048-32.112-30.368zM287.728 64h-63.504v63.68h63.504v-63.68z" /><glyph unicode="&#xe624;" d="M416.656 128v135.696h-320.672v-135.696h-95.984v199.344c0 13.76 11.168 24.912 24.944 24.912h462.144c13.744 0 24.912-11.152 24.912-24.912v-199.344h-95.344zM464.304 324.624c-11.024 0-19.92-8.928-19.92-19.936s8.896-19.952 19.92-19.952c10.992 0 19.968 8.96 19.968 19.952 0 11.008-8.992 19.936-19.968 19.936zM127.728 480h256v-96.192h-256v96.192zM160.976 31.664h191.232v192.336h31.824v-224.080h-255.984v224.080h32.912v-192.336z" /><glyph unicode="&#xe625;" d="M502.080 285.376h-180.704l-55.952 171.744c-1.344 4.096-5.136 6.88-9.44 6.88-4.272 0-8.096-2.784-9.44-6.88l-56.24-171.744h-180.384c-4.256 0-8.096-2.784-9.44-6.88-1.312-4.064 0.128-8.592 3.584-11.088l145.984-106.32-56.256-172.72c-1.328-4.096 0.128-8.592 3.616-11.12 3.456-2.496 8.208-2.496 11.664 0l146.896 106.624 146.64-106.624c1.792-1.28 3.76-1.936 5.808-1.936 2.096 0 4.144 0.656 5.856 1.936 3.568 2.528 4.96 7.008 3.6 11.12l-56.24 172.72 146.288 106.32c3.488 2.496 4.928 7.008 3.6 11.088-1.312 4.096-5.168 6.88-9.44 6.88zM333.424 170.256l48.208-148.064-125.632 91.36-125.968-91.44 48.256 148.128-125.168 91.136h154.576l48.256 147.376 48.016-147.376h154.832l-125.376-91.12z" /><glyph unicode="&#xe626;" d="M319.376 223.824v127.76h-126.752v-127.76h-89.744l153.168-188.608 153.088 188.608zM256.016 480c-141.392 0-256-114.608-256-255.984 0-141.392 114.608-256.016 256-256.016 141.376 0 256 114.624 256 256.016 0 141.376-114.624 255.984-256 255.984zM256.016 0c-123.52 0-224 100.496-224 224.016 0 123.504 100.48 223.984 224 223.984s224-100.48 224-223.984c0-123.52-100.48-224.016-224-224.016z" /><glyph unicode="&#xe627;" d="M255.982 440.594c-119.607 0-216.576-96.969-216.576-216.594s96.969-216.595 216.576-216.595c119.625 0 216.595 96.969 216.595 216.595s-96.951 216.595-216.595 216.595zM255.982 419.913c108.051 0 195.913-87.881 195.913-195.913 0-45.184-15.507-86.711-41.325-119.899-3.108 1.134-6.217 2.195-9.197 3.456-19.748 8.265-41.709 17.957-61.421 26.094-5.632 1.536-11.264 3.072-16.896 4.608-6.692 4.589-13.33 19.986-16.914 27.666-3.548 0.512-7.149 1.005-10.752 1.481 0.531 11.868 7.881 12.544 10.752 21.541 2.541 7.954 0.293 18.341 4.279 25.728 2.779 5.12 9.125 5.12 12.233 9.545 2.853 3.95 4.772 10.917 5.668 15.799 1.609 8.905 3.017 21.12-1.207 29.988-2.432 5.065-3.968 5.577-4.644 11.739-0.823 7.516 2.212 31.891 2.341 37.175 0.293 13.678-0.055 14.793-3.346 28.123 0 0-4.005 12.087-10.295 15.726l-12.58 2.158-7.772 7.186c-31.305 19.273-64.877 5.76-82.834-1.499-25.911-8.43-42.295-33.792-30.867-87.955 1.957-9.289-5.065-13.421-4.608-18.468 1.042-11.045 1.207-37.614 11.648-44.124 0.969-0.603 8.375-2.469 8.339-1.938 1.006-10.752 2.048-21.522 3.054-32.238 2.615-7.149 8.869-7.954 10.679-18.048l-7.991-1.92c-3.602-7.68-10.185-23.077-16.896-27.666-5.65-1.517-11.282-3.053-16.915-4.589-19.731-8.119-41.655-17.829-61.422-26.094-1.079-0.439-2.213-0.786-3.291-1.207-24.759 32.786-39.625 73.454-39.625 117.632 0 108.032 87.881 195.913 195.895 195.913z" /><glyph unicode="&#xe628;" d="M94.8 322.592l-93.424 78.464-0.496-321.968 316.688 56.336-89.216 74.96c182.112 167.52 227.904-8.128 246.272-204.784 65.936 574.064-229.84 445.328-379.824 316.992z" /><glyph unicode="&#xe629;" d="M428.432 224h-20.080v96.176c0 43.36-16.448 83.104-43.632 112.144-27.056 29.056-65.632 47.712-108.16 47.68-42.544 0.032-81.12-18.624-108.192-47.68-27.184-29.040-43.632-68.784-43.648-112.144v-96.176h-20.816c-10.816 0-19.584-8.752-19.584-19.584v-216.8c0-10.848 8.768-19.616 19.584-19.616h344.528c10.8 0 19.584 8.768 19.584 19.632v216.8c0 10.816-8.784 19.568-19.584 19.568zM176.816 320.176c0 25.024 9.472 47.168 24.192 62.928 14.848 15.728 34.144 24.784 55.552 24.816 21.376-0.032 40.688-9.072 55.536-24.816 14.704-15.744 24.176-37.888 24.176-62.928v-96.176h-159.44v96.176z" /><glyph unicode="&#xe62a;" d="M150.896 316.944h-112.192c-9.040 0-16.384-7.312-16.384-16.368v-80c0-9.056 7.344-16.368 16.384-16.368h112.192c9.056 0 16.432 7.312 16.432 16.368v80c0 9.056-7.376 16.368-16.432 16.368zM150.896 171.056h-79.376c-9.056 0-16.432-7.312-16.432-16.368v-170.32c-0.016-9.056 7.36-16.368 16.432-16.368h79.376c9.056 0 16.432 7.312 16.432 16.368v170.32c0 9.056-7.376 16.368-16.432 16.368zM473.328 316.944h-244.88c-9.056 0-16.368-7.312-16.368-16.368v-80c0-9.056 7.312-16.368 16.368-16.368h244.88c8.992 0 16.368 7.312 16.368 16.368v80c0 9.056-7.36 16.368-16.368 16.368zM439.52 169.376h-210.56c-9.056 0-16.368-7.344-16.368-16.4v-168.592c0-9.056 7.312-16.368 16.368-16.368h210.56c9.056 0 16.368 7.312 16.368 16.368v168.592c0 9.056-7.312 16.4-16.368 16.4zM251.952 335.68c19.12-3.504 37.568-5.536 54.816-5.536 86.688 0 133.68 46.592 133.936 90.464 0.128 28.256-20.752 58.88-68.368 59.376-63.808 0-103.312-45.056-123.872-78.496-20.944 33.312-60.624 77.472-124.56 77.472-46.256-0.464-67.2-31.088-67.008-59.328 0.176-43.888 47.248-90.512 133.936-90.512v0c18.752 0 38.88 2.128 59.872 6.336l1.248 0.224zM373.264 439.008c8-0.064 26.56-2 26.432-18.192-0.064-20.624-28.992-49.68-92.944-49.68-8.816 0-18 0.56-27.632 1.68 14.576 25.648 45.216 66.192 94.144 66.192zM190.832 370.128v0c-63.936 0-92.88 29.056-92.992 49.68-0.080 16.16 18.496 18.096 27.36 18.192 48.368 0 78.816-40.56 93.184-66.224-9.552-1.088-18.736-1.648-27.552-1.648z" /><glyph unicode="&#xe62b;" d="M182.256 403.408c0-9.248-7.504-16.72-16.688-16.72h-9.776c-9.216 0-16.72 7.472-16.72 16.72v59.872c0 9.216 7.504 16.72 16.72 16.72h9.776c9.184 0 16.688-7.504 16.688-16.72v-59.872zM373.072 403.408c0-9.248-7.504-16.72-16.688-16.72h-9.744c-9.248 0-16.688 7.472-16.688 16.72v59.872c0 9.216 7.424 16.72 16.688 16.72h9.744c9.184 0 16.688-7.504 16.688-16.72v-59.872zM398.816 253.152l-33.936 27.664-133.68-163.872-71.312 56.688-25.28-31.728 105.184-83.648zM471.952 434h-62.432v-26.064c0-27.68-22.56-50.192-50.128-50.192h-9.808c-27.68 0-50.128 22.496-50.128 50.192v26.064h-85.504v-26.064c0-27.68-22.496-50.192-50.128-50.192h-9.76c-27.664 0-50.16 22.496-50.16 50.192v26.064h-63.808c-9.216 0-16.72-7.504-16.72-16.688v-432.592c0-9.216 7.504-16.72 16.72-16.72h431.84c9.184 0 16.688 7.504 16.688 16.72v432.592c0.016 9.184-7.488 16.688-16.672 16.688zM438.512 42.592c0-9.248-7.504-16.72-16.752-16.72h-331.504c-9.248 0-16.752 7.472-16.752 16.72v252.096c0 9.248 7.504 16.688 16.752 16.688h331.504c9.248 0 16.752-7.44 16.752-16.688v-252.096z" /></font></defs></svg>
\ No newline at end of file
diff --git a/dev/tests/api-functional/testsuite/Magento/Quote/Api/AddressDetailsManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Quote/Api/AddressDetailsManagementTest.php
deleted file mode 100644
index 9081283ffa462a2520d277f2826c088e965061c6..0000000000000000000000000000000000000000
--- a/dev/tests/api-functional/testsuite/Magento/Quote/Api/AddressDetailsManagementTest.php
+++ /dev/null
@@ -1,76 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Quote\Api;
-
-class AddressDetailsManagementTest extends \Magento\TestFramework\TestCase\WebapiAbstract
-{
-    const SERVICE_VERSION = 'V1';
-    const SERVICE_NAME = 'quoteAddressDetailsManagementV1';
-    const RESOURCE_PATH = '/V1/carts/';
-
-    /**
-     * @var \Magento\TestFramework\ObjectManager
-     */
-    protected $objectManager;
-
-    protected function setUp()
-    {
-        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-    }
-
-    /**
-     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php
-     */
-    public function testSaveAddresses()
-    {
-        /** @var \Magento\Quote\Model\Quote $quote */
-        $quote = $this->objectManager->create('Magento\Quote\Model\Quote');
-        $quote->load('test_order_1', 'reserved_order_id');
-
-        $serviceInfo = [
-            'rest' => [
-                'resourcePath' => self::RESOURCE_PATH . 'mine/addresses',
-                'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
-            ],
-            'soap' => [
-                'service' => self::SERVICE_NAME,
-                'serviceVersion' => self::SERVICE_VERSION,
-                'operation' => self::SERVICE_NAME . 'SaveAddresses',
-            ],
-        ];
-
-        $addressData = [
-            'firstname' => 'John',
-            'lastname' => 'Smith',
-            'email' => 'cat@dog.com',
-            'company' => 'eBay Inc',
-            'street' => ['Typical Street', 'Tiny House 18'],
-            'city' => 'Big City',
-            'region_id' => 12,
-            'region' => 'California',
-            'region_code' => 'CA',
-            'postcode' => '0985432',
-            'country_id' => 'US',
-            'telephone' => '88776655',
-            'fax' => '44332255',
-        ];
-        $requestData = [
-            'cart_id' => $quote->getId(),
-            'billingAddress' => $addressData,
-            'shippingAddress' => $addressData
-        ];
-
-        $response = $this->_webApiCall($serviceInfo, $requestData);
-
-        $this->assertArrayHasKey('shipping_methods', $response);
-        $this->assertCount(1, $response['shipping_methods']);
-        $this->assertEquals('flatrate', $response['shipping_methods'][0]['method_code']);
-
-        $this->assertArrayHasKey('payment_methods', $response);
-        $this->assertCount(2, $response['payment_methods']);
-        $this->assertEquals('checkmo', $response['payment_methods'][0]['code']);
-    }
-}
diff --git a/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartTotalRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartTotalRepositoryTest.php
index 1380a7251302f4d63ac9f61358ecb24a6bd8643c..bef10d5a5cfb5ab0114aab0bc7e4e60d5fc4e0cc 100644
--- a/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartTotalRepositoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartTotalRepositoryTest.php
@@ -77,6 +77,7 @@ class CartTotalRepositoryTest 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)],
         ];
 
@@ -85,6 +86,10 @@ class CartTotalRepositoryTest extends WebapiAbstract
         $data = $this->formatTotalsData($data);
         $actual = $this->_webApiCall($this->getServiceInfoForTotalsService($cartId), $requestData);
         unset($actual['items'][0]['options']);
+        unset($actual['weee_tax_applied_amount']);
+
+        /** TODO: cover total segments with separate test */
+        unset($actual['total_segments']);
         if (array_key_exists('extension_attributes', $actual)) {
             unset($actual['extension_attributes']);
         }
@@ -231,12 +236,17 @@ class CartTotalRepositoryTest 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)],
         ];
 
         $data = $this->formatTotalsData($data);
         $actual = $this->_webApiCall($serviceInfo);
         unset($actual['items'][0]['options']);
+        unset($actual['weee_tax_applied_amount']);
+
+        /** TODO: cover total segments with separate test */
+        unset($actual['total_segments']);
         if (array_key_exists('extension_attributes', $actual)) {
             unset($actual['extension_attributes']);
         }
diff --git a/dev/tests/integration/testsuite/Magento/Directory/Model/Country/Postcode/ValidatorTest.php b/dev/tests/integration/testsuite/Magento/Directory/Model/Country/Postcode/ValidatorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d2869eb4f6c6a3148ae69e322a02353addd06ab4
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Directory/Model/Country/Postcode/ValidatorTest.php
@@ -0,0 +1,160 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Directory\Model\Country\Postcode;
+
+use Magento\TestFramework\Helper\Bootstrap;
+
+class ValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Directory\Model\Country\Postcode\ValidatorInterface
+     */
+    protected $validator;
+
+    protected function setUp()
+    {
+        $objectManager = Bootstrap::getObjectManager();
+        $this->validator = $objectManager->create('Magento\Directory\Model\Country\Postcode\ValidatorInterface');
+    }
+
+    /**
+     * @dataProvider getPostcodesDataProvider
+     */
+    public function testPostCodes($countryId, $validPostcode)
+    {
+        try {
+            $this->assertTrue($this->validator->validate($validPostcode, $countryId));
+            $this->assertFalse($this->validator->validate('INVALID-100', $countryId));
+        } catch (\InvalidArgumentException $ex) {
+            //skip validation test for none existing countryId
+        }
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     * @expectedExceptionMessage Provided countryId does not exist.
+     */
+    public function testPostCodesThrowsExceptionIfCountryDoesNotExist()
+    {
+        $this->validator->validate('12345', 'INVALID-CODE');
+    }
+
+    /**
+     * @return array
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function getPostcodesDataProvider()
+    {
+        return [
+            ['countryId' => 'DZ', 'postcode' => '12345'],
+            ['countryId' => 'AS', 'postcode' => '12345'],
+            ['countryId' => 'AR', 'postcode' => '1234'],
+            ['countryId' => 'AM', 'postcode' => '123456'],
+            ['countryId' => 'AU', 'postcode' => '1234'],
+            ['countryId' => 'AT', 'postcode' => '1234'],
+            ['countryId' => 'AZ', 'postcode' => '1234'],
+            ['countryId' => 'AZ', 'postcode' => '123456'],
+            ['countryId' => 'BD', 'postcode' => '1234'],
+            ['countryId' => 'BY', 'postcode' => '123456'],
+            ['countryId' => 'BE', 'postcode' => '1234'],
+            ['countryId' => 'BA', 'postcode' => '12345'],
+            ['countryId' => 'BR', 'postcode' => '12345'],
+            ['countryId' => 'BR', 'postcode' => '12345-678'],
+            ['countryId' => 'BN', 'postcode' => 'PS1234'],
+            ['countryId' => 'BG', 'postcode' => '1234'],
+            ['countryId' => 'CA', 'postcode' => 'P9M 3T6'],
+            ['countryId' => 'IC', 'postcode' => '12345'],
+            ['countryId' => 'CN', 'postcode' => '123456'],
+            ['countryId' => 'HR', 'postcode' => '12345'],
+            ['countryId' => 'CU', 'postcode' => '12345'],
+            ['countryId' => 'CY', 'postcode' => '1234'],
+            ['countryId' => 'CZ', 'postcode' => '123 45'],
+            ['countryId' => 'DK', 'postcode' => '1234'],
+            ['countryId' => 'EE', 'postcode' => '12345'],
+            ['countryId' => 'FI', 'postcode' => '12345'],
+            ['countryId' => 'FR', 'postcode' => '12345'],
+            ['countryId' => 'GF', 'postcode' => '12345'],
+            ['countryId' => 'GE', 'postcode' => '1234'],
+            ['countryId' => 'DE', 'postcode' => '12345'],
+            ['countryId' => 'GR', 'postcode' => '123 45'],
+            ['countryId' => 'GL', 'postcode' => '1234'],
+            ['countryId' => 'GP', 'postcode' => '12345'],
+            ['countryId' => 'GU', 'postcode' => '12345'],
+            ['countryId' => 'GG', 'postcode' => 'PL5 7TH'],
+            ['countryId' => 'HU', 'postcode' => '1234'],
+            ['countryId' => 'IS', 'postcode' => '123'],
+            ['countryId' => 'IN', 'postcode' => '123456'],
+            ['countryId' => 'ID', 'postcode' => '12345'],
+            ['countryId' => 'IL', 'postcode' => '12345'],
+            ['countryId' => 'IT', 'postcode' => '12345'],
+            ['countryId' => 'JP', 'postcode' => '123-4567'],
+            ['countryId' => 'JP', 'postcode' => '123'],
+            ['countryId' => 'JE', 'postcode' => 'TY8 9PL'],
+            ['countryId' => 'KZ', 'postcode' => '123456'],
+            ['countryId' => 'KE', 'postcode' => '12345'],
+            ['countryId' => 'KR', 'postcode' => '123-456'],
+            ['countryId' => 'KG', 'postcode' => '123456'],
+            ['countryId' => 'LV', 'postcode' => '1234'],
+            ['countryId' => 'LI', 'postcode' => '1234'],
+            ['countryId' => 'LT', 'postcode' => '12345'],
+            ['countryId' => 'LU', 'postcode' => '1234'],
+            ['countryId' => 'MK', 'postcode' => '1234'],
+            ['countryId' => 'MG', 'postcode' => '123'],
+            ['countryId' => 'MY', 'postcode' => '12345'],
+            ['countryId' => 'MV', 'postcode' => '12345'],
+            ['countryId' => 'MV', 'postcode' => '1234'],
+            ['countryId' => 'MT', 'postcode' => 'WRT 123'],
+            ['countryId' => 'MT', 'postcode' => 'WRT 45'],
+            ['countryId' => 'MH', 'postcode' => '12345'],
+            ['countryId' => 'MQ', 'postcode' => '12345'],
+            ['countryId' => 'MX', 'postcode' => '12345'],
+            ['countryId' => 'MD', 'postcode' => '1234'],
+            ['countryId' => 'MC', 'postcode' => '12345'],
+            ['countryId' => 'MN', 'postcode' => '123456'],
+            ['countryId' => 'MA', 'postcode' => '12345'],
+            ['countryId' => 'NL', 'postcode' => '1234 TR'],
+            ['countryId' => 'NO', 'postcode' => '1234'],
+            ['countryId' => 'PK', 'postcode' => '12345'],
+            ['countryId' => 'PH', 'postcode' => '1234'],
+            ['countryId' => 'PL', 'postcode' => '12-345'],
+            ['countryId' => 'PT', 'postcode' => '1234'],
+            ['countryId' => 'PT', 'postcode' => '1234-567'],
+            ['countryId' => 'PR', 'postcode' => '12345'],
+            ['countryId' => 'RE', 'postcode' => '12345'],
+            ['countryId' => 'RO', 'postcode' => '123456'],
+            ['countryId' => 'RU', 'postcode' => '123456'],
+            ['countryId' => 'MP', 'postcode' => '12345'],
+            ['countryId' => 'CS', 'postcode' => '12345'],
+            ['countryId' => 'SG', 'postcode' => '123456'],
+            ['countryId' => 'SK', 'postcode' => '123 45'],
+            ['countryId' => 'SI', 'postcode' => '1234'],
+            ['countryId' => 'ZA', 'postcode' => '1234'],
+            ['countryId' => 'ES', 'postcode' => '12345'],
+            ['countryId' => 'XY', 'postcode' => '12345'],
+            ['countryId' => 'SZ', 'postcode' => 'R123'],
+            ['countryId' => 'SE', 'postcode' => '123 45'],
+            ['countryId' => 'CH', 'postcode' => '1234'],
+            ['countryId' => 'TW', 'postcode' => '123'],
+            ['countryId' => 'TW', 'postcode' => '12345'],
+            ['countryId' => 'TJ', 'postcode' => '123456'],
+            ['countryId' => 'TH', 'postcode' => '12345'],
+            ['countryId' => 'TR', 'postcode' => '12345'],
+            ['countryId' => 'TM', 'postcode' => '123456'],
+            ['countryId' => 'UA', 'postcode' => '12345'],
+            ['countryId' => 'GB', 'postcode' => 'PL12 3RT'],
+            ['countryId' => 'GB', 'postcode' => 'P1L 2RT'],
+            ['countryId' => 'GB', 'postcode' => 'QW1 2RT'],
+            ['countryId' => 'GB', 'postcode' => 'QW1R 2TG'],
+            ['countryId' => 'GB', 'postcode' => 'L12 3PL'],
+            ['countryId' => 'GB', 'postcode' => 'Q1 2PL'],
+            ['countryId' => 'US', 'postcode' => '12345-6789'],
+            ['countryId' => 'US', 'postcode' => '12345'],
+            ['countryId' => 'UY', 'postcode' => '12345'],
+            ['countryId' => 'UZ', 'postcode' => '123456'],
+            ['countryId' => 'VI', 'postcode' => '12345'],
+        ];
+    }
+}
diff --git a/dev/tests/performance/benchmark.jmx b/dev/tests/performance/benchmark.jmx
index 6fda461b91e00c23daa17bf64a3f578f456c5ffc..92ac0e689898c76a1dd489ec125330ad1f4d3c61 100644
--- a/dev/tests/performance/benchmark.jmx
+++ b/dev/tests/performance/benchmark.jmx
@@ -892,19 +892,16 @@
           <stringProp name="ConstantTimer.delay">${sleep_between_steps}</stringProp>
         </ConstantTimer>
         <hashTree/>
-        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Checkout billing/shipping addresses" enabled="true">
+        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Checkout shipping information" enabled="true">
           <boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
           <elementProp name="HTTPsampler.Arguments" elementType="Arguments">
             <collectionProp name="Arguments.arguments">
               <elementProp name="" elementType="HTTPArgument">
                 <boolProp name="HTTPArgument.always_encode">false</boolProp>
-                <stringProp name="Argument.value">{&quot;shippingAddress&quot;:{&quot;company&quot;:&quot;&quot;,&quot;fax&quot;:&quot;&quot;,&quot;city&quot;:&quot;Culver City&quot;,&quot;firstname&quot;:&quot;Name&quot;,&quot;lastname&quot;:&quot;Lastname&quot;&#xd;
-,&quot;street&quot;:{&quot;0&quot;:&quot;10441 Jefferson Blvd, ste 200&quot;,&quot;1&quot;:&quot;&quot;},&quot;telephone&quot;:&quot;1-310-945-0345&quot;,&quot;postcode&quot;:&quot;90232&quot;&#xd;
-,&quot;region_id&quot;:&quot;12&quot;,&quot;country_id&quot;:&quot;US&quot;,&quot;region&quot;:&quot;&quot;,&quot;save_in_address_book&quot;:&quot;1&quot;,&quot;email&quot;:&quot;test@example.com&quot;&#xd;
-,&quot;same_as_billing&quot;:1},&quot;billingAddress&quot;:{&quot;company&quot;:&quot;&quot;,&quot;fax&quot;:&quot;&quot;,&quot;city&quot;:&quot;Culver City&quot;,&quot;firstname&quot;:&quot;Name&quot;&#xd;
-,&quot;lastname&quot;:&quot;Lastname&quot;,&quot;street&quot;:{&quot;0&quot;:&quot;10441 Jefferson Blvd, ste 200&quot;,&quot;1&quot;:&quot;&quot;},&quot;telephone&quot;:&quot;1-310-945-0345&quot;&#xd;
-,&quot;postcode&quot;:&quot;90232&quot;,&quot;region_id&quot;:&quot;12&quot;,&quot;country_id&quot;:&quot;US&quot;,&quot;region&quot;:&quot;&quot;,&quot;save_in_address_book&quot;:&quot;1&quot;,&quot;email&quot;&#xd;
-:&quot;test@example.com&quot;,&quot;same_as_billing&quot;:1},&quot;additionalData&quot;:{&quot;extensionAttributes&quot;:{}}}</stringProp>
+                <stringProp name="Argument.value">{&quot;addressInformation&quot;:{&quot;shipping_address&quot;:{&quot;countryId&quot;:&quot;US&quot;,&quot;regionId&quot;:&quot;12&quot;,&quot;regionCode&quot;:&quot;CA&quot;,&quot;region&quot;&#xd;
+:&quot;California&quot;,&quot;street&quot;:[&quot;10441 Jefferson Blvd&quot;,&quot;ste 200&quot;],&quot;company&quot;:&quot;&quot;,&quot;telephone&quot;:&quot;1-310-945-0345&quot;,&quot;fax&quot;&#xd;
+:&quot;&quot;,&quot;postcode&quot;:&quot;90232&quot;,&quot;city&quot;:&quot;Culver City&quot;,&quot;firstname&quot;:&quot;Firstname&quot;,&quot;lastname&quot;:&quot;Lastname&quot;,&quot;saveInAddressBook&quot;&#xd;
+:true},&quot;shipping_method_code&quot;:&quot;flatrate&quot;,&quot;shipping_carrier_code&quot;:&quot;flatrate&quot;}}</stringProp>
                 <stringProp name="Argument.metadata">=</stringProp>
               </elementProp>
             </collectionProp>
@@ -915,7 +912,7 @@
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol">http</stringProp>
           <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
-          <stringProp name="HTTPSampler.path">${base_path}rest/default/V1/carts/mine/addresses</stringProp>
+          <stringProp name="HTTPSampler.path">${base_path}rest/default/V1/carts/mine/shipping-information</stringProp>
           <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
@@ -948,7 +945,7 @@
           <hashTree/>
           <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Assert success" enabled="true">
             <collectionProp name="Asserion.test_strings">
-              <stringProp name="-768590464">{&quot;shipping_methods&quot;:</stringProp>
+              <stringProp name="-1494218646">{&quot;payment_methods&quot;:</stringProp>
             </collectionProp>
             <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
             <boolProp name="Assertion.assume_success">false</boolProp>
@@ -960,15 +957,17 @@
           <stringProp name="ConstantTimer.delay">${sleep_between_steps}</stringProp>
         </ConstantTimer>
         <hashTree/>
-        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Checkout shipping/payment method" enabled="true">
+        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Checkout payment information" enabled="true">
           <boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
           <elementProp name="HTTPsampler.Arguments" elementType="Arguments">
             <collectionProp name="Arguments.arguments">
               <elementProp name="" elementType="HTTPArgument">
                 <boolProp name="HTTPArgument.always_encode">false</boolProp>
-                <stringProp name="Argument.value">{&quot;cartId&quot;:&quot;${cart_id}&quot;,&quot;paymentMethod&quot;:{&quot;method&quot;:&quot;checkmo&quot;,&quot;po_number&quot;:null,&quot;cc_owner&quot;&#xd;
-:null,&quot;cc_number&quot;:null,&quot;cc_type&quot;:null,&quot;cc_exp_year&quot;:null,&quot;cc_exp_month&quot;:null,&quot;additional_data&quot;:null}&#xd;
-,&quot;shippingCarrierCode&quot;:&quot;flatrate&quot;,&quot;shippingMethodCode&quot;:&quot;flatrate&quot;}</stringProp>
+                <stringProp name="Argument.value">{&quot;cartId&quot;:&quot;${cart_id}&quot;,&quot;paymentMethod&quot;:{&quot;method&quot;:&quot;checkmo&quot;,&quot;po_number&quot;:null,&quot;cc_owner&quot;:null,&quot;cc_number&quot;:null&#xd;
+,&quot;cc_type&quot;:null,&quot;cc_exp_year&quot;:null,&quot;cc_exp_month&quot;:null,&quot;additional_data&quot;:null},&quot;billingAddress&quot;:{&quot;countryId&quot;&#xd;
+:&quot;US&quot;,&quot;regionId&quot;:&quot;12&quot;,&quot;regionCode&quot;:&quot;CA&quot;,&quot;region&quot;:&quot;California&quot;,&quot;street&quot;:[&quot;10441 Jefferson Blvd&quot;,&quot;ste 200&quot;&#xd;
+],&quot;company&quot;:&quot;&quot;,&quot;telephone&quot;:&quot;1-310-945-0345&quot;,&quot;fax&quot;:&quot;&quot;,&quot;postcode&quot;:&quot;90232&quot;,&quot;city&quot;:&quot;Culver City&quot;,&quot;firstname&quot;&#xd;
+:&quot;Firstname&quot;,&quot;lastname&quot;:&quot;Lastname&quot;,&quot;saveInAddressBook&quot;:true}}</stringProp>
                 <stringProp name="Argument.metadata">=</stringProp>
               </elementProp>
             </collectionProp>
@@ -979,70 +978,8 @@
           <stringProp name="HTTPSampler.response_timeout"></stringProp>
           <stringProp name="HTTPSampler.protocol">http</stringProp>
           <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
-          <stringProp name="HTTPSampler.path">${base_path}rest/default/V1/carts/mine/collect-totals</stringProp>
-          <stringProp name="HTTPSampler.method">PUT</stringProp>
-          <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
-          <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
-          <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
-          <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
-          <boolProp name="HTTPSampler.monitor">false</boolProp>
-          <stringProp name="HTTPSampler.embedded_url_re"></stringProp>
-        </HTTPSamplerProxy>
-        <hashTree>
-          <HeaderManager guiclass="HeaderPanel" testclass="HeaderManager" testname="HTTP Header Manager" enabled="true">
-            <collectionProp name="HeaderManager.headers">
-              <elementProp name="" elementType="Header">
-                <stringProp name="Header.name">Referer</stringProp>
-                <stringProp name="Header.value">http://mage2.com/checkout/onepage/</stringProp>
-              </elementProp>
-              <elementProp name="" elementType="Header">
-                <stringProp name="Header.name">Content-Type</stringProp>
-                <stringProp name="Header.value">application/json; charset=UTF-8 </stringProp>
-              </elementProp>
-              <elementProp name="" elementType="Header">
-                <stringProp name="Header.name">Accept</stringProp>
-                <stringProp name="Header.value">application/json</stringProp>
-              </elementProp>
-              <elementProp name="" elementType="Header">
-                <stringProp name="Header.name">X-Requested-With</stringProp>
-                <stringProp name="Header.value">XMLHttpRequest</stringProp>
-              </elementProp>
-            </collectionProp>
-          </HeaderManager>
-          <hashTree/>
-          <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true">
-            <collectionProp name="Asserion.test_strings">
-              <stringProp name="629313218">{&quot;grand_total&quot;:</stringProp>
-            </collectionProp>
-            <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
-            <boolProp name="Assertion.assume_success">false</boolProp>
-            <intProp name="Assertion.test_type">2</intProp>
-          </ResponseAssertion>
-          <hashTree/>
-        </hashTree>
-        <ConstantTimer guiclass="ConstantTimerGui" testclass="ConstantTimer" testname="Constant Timer" enabled="true">
-          <stringProp name="ConstantTimer.delay">${sleep_between_steps}</stringProp>
-        </ConstantTimer>
-        <hashTree/>
-        <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Checkout place order" enabled="true">
-          <boolProp name="HTTPSampler.postBodyRaw">true</boolProp>
-          <elementProp name="HTTPsampler.Arguments" elementType="Arguments">
-            <collectionProp name="Arguments.arguments">
-              <elementProp name="" elementType="HTTPArgument">
-                <boolProp name="HTTPArgument.always_encode">false</boolProp>
-                <stringProp name="Argument.value"></stringProp>
-                <stringProp name="Argument.metadata">=</stringProp>
-              </elementProp>
-            </collectionProp>
-          </elementProp>
-          <stringProp name="HTTPSampler.domain"></stringProp>
-          <stringProp name="HTTPSampler.port"></stringProp>
-          <stringProp name="HTTPSampler.connect_timeout"></stringProp>
-          <stringProp name="HTTPSampler.response_timeout"></stringProp>
-          <stringProp name="HTTPSampler.protocol">http</stringProp>
-          <stringProp name="HTTPSampler.contentEncoding">UTF-8</stringProp>
-          <stringProp name="HTTPSampler.path">${base_path}rest/default/V1/carts/mine/order</stringProp>
-          <stringProp name="HTTPSampler.method">PUT</stringProp>
+          <stringProp name="HTTPSampler.path">${base_path}rest/default/V1/carts/mine/payment-information</stringProp>
+          <stringProp name="HTTPSampler.method">POST</stringProp>
           <boolProp name="HTTPSampler.follow_redirects">true</boolProp>
           <boolProp name="HTTPSampler.auto_redirects">false</boolProp>
           <boolProp name="HTTPSampler.use_keepalive">true</boolProp>
@@ -1143,7 +1080,7 @@
         <hashTree>
           <ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Assert success" enabled="true">
             <collectionProp name="Asserion.test_strings">
-              <stringProp name="890055751">You are signed out.</stringProp>
+              <stringProp name="1723813687">You are signed out.</stringProp>
             </collectionProp>
             <stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
             <boolProp name="Assertion.assume_success">false</boolProp>
diff --git a/lib/web/css/source/components/_modals.less b/lib/web/css/source/components/_modals.less
index df5c973eef2de55b58b941178d1acf677ee0a219..a57580c88722424f70b28214ed1500e94a4ed6c0 100644
--- a/lib/web/css/source/components/_modals.less
+++ b/lib/web/css/source/components/_modals.less
@@ -46,6 +46,7 @@
     &._show {
         visibility: visible;
         .modal-inner-wrap {
+            -webkit-transform: translate(0, 0);
             transform: translate(0, 0);
         }
     }
@@ -62,6 +63,7 @@
     z-index: @modal-slide__z-index;
     &._show {
         .modal-inner-wrap {
+            -webkit-transform: translateX(0);
             transform: translateX(0);
         }
     }
@@ -69,9 +71,11 @@
         height: 100%;
         overflow-y: auto;
         position: static;
+        -webkit-transform: translateX(100%);
         transform: translateX(100%);
         transition-duration: .3s;
         transition-timing-function: ease-in-out;
+        -webkit-transition-property: -webkit-transform, visibility;
         transition-property: transform, visibility;
         width: auto;
     }
@@ -83,18 +87,24 @@
     z-index: @modal-popup__z-index;
     &._show {
         .modal-inner-wrap {
+            -webkit-transform: translateY(0);
             transform: translateY(0);
         }
     }
     .modal-inner-wrap {
+        box-sizing: border-box;
         .vendor-prefix-display(flex);
         .vendor-prefix-flex-direction(column);
         height: auto;
-        margin: @modal-popup__indent-vertical (100% - @modal-popup__width) / 2;
+        left: 0;
+        right: 0;
+        margin: @modal-popup__indent-vertical auto;
         position: absolute;
+        -webkit-transform: translateY(-200%);
         transform: translateY(-200%);
         transition-duration: .2s;
         transition-timing-function: ease;
+        -webkit-transition-property: -webkit-transform, visibility;
         transition-property: transform, visibility;
         width: @modal-popup__width;
     }
@@ -102,10 +112,12 @@
 
 //
 
-._has-modal {
-    height: 100vh;
-    overflow: hidden;
-    width: 100vw;
+body {
+    &._has-modal {
+        height: 100%;
+        overflow: hidden;
+        width: 100%;
+    }
 }
 
 // Modals overlay
@@ -156,8 +168,16 @@
     //  If applied, switching outer popup scroll to inner
     &._inner-scroll {
         overflow-y: visible;
+        .ie10 &,
+        .ie9 & {
+            overflow-y: auto;
+        }
         .modal-inner-wrap {
             max-height: 90%;
+            .ie10 &,
+            .ie9 & {
+                max-height: none;
+            }
         }
         .modal-content {
             overflow-y: auto;
diff --git a/lib/web/css/source/lib/_responsive.less b/lib/web/css/source/lib/_responsive.less
index 42388a0be5b45753d628afbe2cd916ea13d99a99..105a06e6b5018a5886bc496c713bd3c484a00fc2 100644
--- a/lib/web/css/source/lib/_responsive.less
+++ b/lib/web/css/source/lib/_responsive.less
@@ -39,6 +39,10 @@
         .media-width('max', @screen__m);
     }
 
+    @media only screen and (max-width: @screen__m) {
+        .media-width('max', (@screen__m + 1));
+    }
+
     @media all and (min-width: @screen__s) {
         .media-width('min', @screen__s);
     }
@@ -56,6 +60,11 @@
         .media-width('min', @screen__m);
     }
 
+    @media all and (min-width: (@screen__m + 1)),
+    print {
+        .media-width('min', (@screen__m + 1));
+    }
+
     @media all and (min-width: @screen__l),
     print {
         .media-width('min', @screen__l);
diff --git a/lib/web/css/source/lib/variables/_icons.less b/lib/web/css/source/lib/variables/_icons.less
index 999e9c2cf7922b5a9acb500e499ba271a116e992..ac6e0c0c9bd0c422c4c6f3fda7cb99f30b197858 100644
--- a/lib/web/css/source/lib/variables/_icons.less
+++ b/lib/web/css/source/lib/variables/_icons.less
@@ -75,10 +75,11 @@
 @icon-comment: '\e620';
 @icon-up: '\e621';
 @icon-down: '\e622';
-@icon-arrow-up-thin: '\e623';
+@icon-help: '\e623';
 @icon-arrow-right-thin: '\e624';
 @icon-arrow-left-thin: '\e625';
 @icon-arrow-down-thin: '\e626';
 @icon-account: '\e627';
 @icon-gift-registry: '\e628';
 @icon-present: '\e629';
+@icon-arrow-up-thin: '\e633';
diff --git a/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.eot b/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.eot
index 9bc3197afaa63854e2a13d3f79f31488bf1fe4db..806461187aa48e9ad6e425d4308f8f93c61fe3f4 100644
Binary files a/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.eot and b/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.eot differ
diff --git a/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.svg b/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.svg
index 85f6bf6ddeca82ba961382a061b92c7b6da011b7..37d511d157533ea09dca32f6568390647d2540e4 100644
--- a/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.svg
+++ b/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg"><defs><font id="Blank-Theme-Icons" horiz-adv-x="1024"><font-face units-per-em="1024" ascent="960" descent="-64"/><missing-glyph horiz-adv-x="1024"/><glyph unicode="&#x20;" d="" horiz-adv-x="512"/><glyph unicode="&#xe600;" d="M676.571 637.696c-59.867 28.197-131.255 2.523-159.415-57.307-1.975-4.133-3.657-9.362-5.157-15.397-1.499 6.034-3.182 11.264-5.157 15.397-28.197 59.831-99.547 85.504-159.415 57.307-59.831-28.197-85.504-99.547-57.271-159.378 28.197-59.867 221.806-231.424 221.806-231.424s0 0.219 0.037 0.585c0.037-0.366 0.037-0.585 0.037-0.585s193.646 171.557 221.806 231.424c28.233 59.831 2.597 131.182-57.271 159.378z"/><glyph unicode="&#xe601;" d="M676.571 637.696c-59.831 28.197-131.218 2.523-159.451-57.307-1.938-4.133-3.657-9.362-5.157-15.397-1.463 6.034-3.182 11.264-5.157 15.397-28.16 59.831-99.547 85.504-159.378 57.307s-85.467-99.547-57.271-159.378 221.806-231.424 221.806-231.424 0 0.219 0.037 0.585c0-0.402 0-0.622 0-0.622s193.646 171.557 221.842 231.424c28.233 59.867 2.597 131.218-57.271 159.415zM690.213 479.232c-25.417-43.776-174.007-184.722-174.007-184.722l-1.573 2.999c0 0-155.465 140.398-181.211 183.991-30.61 51.822-7.753 108.946 38.949 128.439 43.52 18.176 101.888-27.319 123.502-73.143 1.499-3.182 17.627-1.463 18.798-6.107 1.134 4.645 12.727 2.926 14.226 6.107 21.577 45.824 81.042 93.989 128 72.411 46.007-21.138 66.926-72.155 33.317-129.975z"/><glyph unicode="&#xe602;" d="M512 704.11l-296.85-512.256h593.701l-296.85 512.256zM544.219 254.135h-62.757v49.92h62.757v-49.92zM528.713 343.369h-31.269l-20.809 140.654-1.207 72.704h72.521v-72.704l-19.237-140.654z"/><glyph unicode="&#xe603;" d="M628.846 588.544c-34.085 28.343-75.63 42.24-116.773 42.24-47.47 0-94.757-18.578-130.085-54.382l-32.073 29.586-0.585-102.693 110.994-0.658-39.424 41.253c25.198 24.027 58.002 36.315 91.136 36.352 29.842-0.037 59.721-9.947 84.517-30.574 31.488-26.222 47.689-63.744 47.726-101.815 0-5.449-0.366-10.971-1.024-16.457l51.383 9.874c0.073 2.231 0.146 4.425 0.146 6.619 0.037 52.37-22.491 104.521-65.938 140.654zM603.794 352.768c-25.307-24.466-58.405-37.010-91.867-37.047-29.879 0.037-59.721 9.984-84.517 30.574-31.488 26.222-47.689 63.744-47.726 101.778 0 6.327 0.475 12.617 1.353 18.871l-51.602-9.691c-0.146-3.072-0.256-6.107-0.256-9.179-0.037-52.334 22.491-104.521 65.975-140.617 34.048-28.343 75.593-42.24 116.736-42.24h0.11c47.799 0 95.378 18.907 130.743 55.223l33.938-33.829 0.219 106.094-112.055 0.293 38.949-40.229z"/><glyph unicode="&#xe604;" d="M696.942 624.933l-19.273 6.107h-74.496v38.583l-12.544 21.029-22.711 13.495h-111.141l-23.333-13.495-12.581-21.029v-38.619h-73.765l-18.761-6.656-17.189-14.153v-88.869h19.017v-0.073h17.554v-329.435h36.571v0.293h255.415v-0.293h36.571v329.435h18.286v0.073h18.286v86.601l-15.909 17.006zM457.435 667.575h109.129v-36.571h-109.129v36.571zM639.707 228.718h-255.415v292.571h255.415v-292.571zM676.279 557.934h-328.558v36.498h328.558v-36.498zM457.435 483.511h-36.571v-218.587h36.571v218.587zM530.578 483.511h-36.571v-218.587h36.571v218.587zM603.721 483.511h-36.571v-218.587h36.571v218.587z"/><glyph unicode="&#xe605;" d="M804.645 515.401c-1.499 4.681-5.888 7.899-10.789 7.899h-206.958l-64.073 196.754c-1.536 4.645-5.888 7.826-10.825 7.826-4.901 0-9.289-3.182-10.825-7.863l-64.439-196.754h-206.592c-4.901 0-9.289-3.218-10.825-7.863-1.499-4.681 0.146-9.874 4.096-12.763l167.205-121.783-64.439-197.851c-1.536-4.681 0.146-9.838 4.133-12.727 3.95-2.889 9.399-2.889 13.349 0l168.338 122.185 167.936-122.149c2.011-1.463 4.315-2.231 6.693-2.231s4.681 0.768 6.693 2.231c4.023 2.889 5.669 8.009 4.133 12.727l-64.439 197.851 167.57 121.783c3.95 2.889 5.632 8.046 4.059 12.727z"/><glyph unicode="&#xe606;" d="M807.241 415.854v67.145l-9.509 3.145-71.936 23.442-19.2 46.373 36.937 78.080-47.506 47.506-8.923-4.498-67.438-34.304-46.373 19.2-29.111 81.298h-67.182l-26.624-81.445-46.336-19.163-78.043 36.901-47.506-47.506 4.498-8.96 34.267-67.438-19.2-46.336-81.298-29.074v-67.218l9.472-3.072 71.973-23.515 19.163-46.373-36.901-78.080 47.506-47.506 8.887 4.498 67.474 34.304 46.373-19.2 29.111-81.298h67.182l3.072 9.509 23.515 71.936 46.373 19.2 78.080-36.937 47.506 47.506-4.498 8.923-34.304 67.438 19.2 46.373 81.298 29.147zM512 353.938c-51.968 0-94.062 42.13-94.062 94.062 0 52.005 42.094 94.062 94.062 94.062 51.931 0 94.098-42.057 94.098-94.062-0.037-51.931-42.167-94.062-94.098-94.062z"/><glyph unicode="&#xe607;" d="M339.602 539.941l172.398-183.881 172.398 183.881z"/><glyph unicode="&#xe608;" d="M606.939 449.938l-158.391 162.853-27.794-26.075 132.827-136.558-136.521-140.361 27.173-26.587 153.198 157.55-0.146 0.146z"/><glyph unicode="&#xe609;" d="M127.634 740.571v-73.143h768.731v73.143h-768.731zM127.634 411.429h768.731v73.143h-768.731v-73.143zM127.634 155.429h768.731v73.143h-768.731v-73.143z"/><glyph unicode="&#xe60a;" d="M512 742.217c-102.437 0-185.417-83.054-185.417-185.454 0-102.437 185.417-403.017 185.417-403.017s185.454 300.581 185.454 403.017c-0.037 102.437-83.017 185.454-185.454 185.454zM512 500.443c-31.122 0-56.357 25.198-56.357 56.357 0 31.086 25.234 56.357 56.357 56.357 31.159 0 56.393-25.271 56.393-56.357-0.037-31.159-25.271-56.357-56.393-56.357z"/><glyph unicode="&#xe60b;" d="M219.429 485.595h255.927v254.793h-255.927v-254.793zM548.571 740.389v-109.349h256v109.349h-256zM219.429 156.453h255.927v254.793h-255.927v-254.793zM548.571 484.754h256v109.349h-256v-109.349zM548.571 301.897h256v109.349h-256v-109.349zM548.571 155.611h256v109.349h-256v-109.349z"/><glyph unicode="&#xe60c;" d="M579.511 677.010c-30.793 0-57.381-25.161-57.381-55.954 0-28.635 18.907-47.579 47.579-47.579 31.415 0 58.002 23.771 58.002 55.991 0 28.709-20.224 47.543-48.201 47.543zM593.518 336.494c-9.801 0-48.311-59.502-69.266-59.502-5.595 0-8.375 4.937-8.375 9.801 0 11.227 7.68 28.709 11.849 39.205l50.322 136.375c25.198 67.84-6.985 86.016-37.047 86.016-40.558 0-76.946-20.297-104.887-46.848-9.106-9.070-39.863-38.437-39.863-51.054 0-4.133 4.169-9.070 9.106-9.070 12.544 0 46.153 60.855 72.009 60.855 5.595 0 11.886-6.29 6.985-18.871l-48.896-123.173c-4.937-11.849-28.709-69.23-28.709-102.802 0-26.587 17.518-38.437 42.679-38.437 70.656 0 152.43 86.711 152.43 107.008 0 6.29-4.864 10.496-8.338 10.496z"/><glyph unicode="&#xe60d;" d="M219.063 593.92h147.017v147.017h-147.017v-147.017zM438.491 593.92h147.017v147.017h-147.017v-147.017zM657.92 740.937v-147.017h147.017v147.017h-147.017zM219.063 374.491h147.017v147.017h-147.017v-147.017zM438.491 374.491h147.017v147.017h-147.017v-147.017zM657.92 374.491h147.017v147.017h-147.017v-147.017zM219.063 155.063h147.017v147.017h-147.017v-147.017zM438.491 155.063h147.017v147.017h-147.017v-147.017zM657.92 155.063h147.017v147.017h-147.017v-147.017z"/><glyph unicode="&#xe60e;" d="M711.607 401.591l-5.486-5.522c21.065 27.794 32.878 60.197 32.219 94.72-1.975 99.218-106.679 177.627-233.874 175.141-127.232-2.487-228.791-84.992-226.816-184.21 1.938-99.182 106.679-177.554 233.911-175.067 28.635 0.585 50.432-5.815 75.63 2.121l159.232-78.702c-0.037-0.037-71.058 124.965-34.816 171.52z"/><glyph unicode="&#xe60f;" d="M236.946 466.286h550.107v-36.571h-550.107v36.571z"/><glyph unicode="&#xe610;" d="M749.129 663.698c-152.101-93.257-262.473-210.907-312.064-269.934l-121.417 95.159-53.65-43.264 209.847-213.394c36.096 92.489 150.491 273.298 290.158 401.737l-12.873 29.696z"/><glyph unicode="&#xe611;" d="M434.871 259.95c-35.218 0-63.707-28.526-63.707-63.744 0-35.182 28.489-63.671 63.707-63.671 35.182 0 63.707 28.489 63.707 63.671 0 35.218-28.526 63.744-63.707 63.744zM654.848 259.95c-35.218 0-63.707-28.526-63.707-63.744 0-35.182 28.489-63.671 63.707-63.671 35.145 0 63.707 28.489 63.707 63.671 0 35.218-28.562 63.744-63.707 63.744zM784.274 616.741c-163.511 0-427.227 0-427.227 0s-25.929 70.071-49.957 113.371c-24.027 43.227-57.893 32.037-57.893 32.037-26.843 0-39.314-16.055-39.314-42.971 0-26.843 16.457-48.64 43.337-48.64l16.603-14.848 121.929-330.533 356.425-0.256c0 0 65.17 261.705 61.806 251.355 11.959 36.974-3.255 40.485-25.71 40.485zM392.485 492.544c-18.725 0-33.902 15.177-33.902 33.902s15.177 33.902 33.902 33.902 33.902-15.177 33.902-33.902-15.177-33.902-33.902-33.902zM464.933 379.392c-18.725 0-33.902 15.177-33.902 33.902s15.177 33.902 33.902 33.902 33.902-15.177 33.902-33.902-15.177-33.902-33.902-33.902zM502.199 492.544c-18.725 0-33.902 15.177-33.902 33.902s15.177 33.902 33.902 33.902 33.902-15.177 33.902-33.902-15.177-33.902-33.902-33.902zM574.647 379.392c-18.725 0-33.865 15.177-33.865 33.902s15.177 33.902 33.865 33.902 33.938-15.177 33.938-33.902-15.214-33.902-33.938-33.902zM611.913 492.544c-18.725 0-33.938 15.177-33.938 33.902s15.214 33.902 33.938 33.902 33.865-15.177 33.865-33.902-15.141-33.902-33.865-33.902zM684.361 379.392c-18.725 0-33.865 15.177-33.865 33.902s15.141 33.902 33.865 33.902 33.938-15.177 33.938-33.902-15.214-33.902-33.938-33.902zM721.627 492.544c-18.725 0-33.938 15.177-33.938 33.902s15.214 33.902 33.938 33.902 33.865-15.177 33.865-33.902-15.141-33.902-33.865-33.902z"/><glyph unicode="&#xe612;" d="M642.487 578.304c11.959 0 21.65 9.691 21.65 21.65v77.934c0 11.959-9.691 21.65-21.65 21.65-11.922 0-21.65-9.691-21.65-21.65v-77.934c0.037-11.959 9.728-21.65 21.65-21.65zM381.842 578.304c11.922 0 21.65 9.691 21.65 21.65v77.934c0 11.959-9.728 21.65-21.65 21.65-11.959 0-21.65-9.691-21.65-21.65v-77.934c0.037-11.959 9.691-21.65 21.65-21.65zM671.269 636.562v-0.402c8.997-7.973 14.702-19.566 14.702-32.549 0-23.991-19.456-43.447-43.483-43.447-23.991 0-43.447 19.456-43.447 43.447 0 12.946 5.705 24.576 14.702 32.549v0.402h-203.154v-0.402c8.997-7.973 14.702-19.566 14.702-32.549 0-23.991-19.456-43.447-43.447-43.447-24.027 0-43.447 19.456-43.447 43.447 0 12.946 5.669 24.576 14.665 32.549v0.402h-96.841v-440.101h511.561v440.101h-96.512zM732.087 234.569h-437.76v291.694h437.76v-291.694zM619.301 407.113h-55.15v-55.113h55.15v55.113zM619.301 490.021h-55.15v-55.113h55.15v55.113zM619.301 326.51h-55.15v-55.15h55.15v55.15zM696.942 490.021h-55.15v-55.113h55.15v55.113zM696.942 407.113h-55.15v-55.113h55.15v55.113zM386.267 326.51h-55.113v-55.15h55.113v55.15zM463.982 326.51h-55.15v-55.15h55.15v55.15zM463.982 407.113h-55.15v-55.113h55.15v55.113zM386.267 407.113h-55.113v-55.113h55.113v55.113zM541.586 407.113h-55.113v-55.113h55.113v55.113zM541.586 490.021h-55.113v-55.113h55.113v55.113zM463.982 490.021h-55.15v-55.113h55.15v55.113zM541.586 326.51h-55.113v-55.15h55.113v55.15z"/><glyph unicode="&#xe613;" d="M512 677.742l-209.006-253.257h136.338v-206.19h145.298v206.19h136.375z"/><glyph unicode="&#xe614;" d="M584.631 471.515v206.226h-145.298v-206.226h-136.338l209.006-253.221 209.006 253.221z"/><glyph unicode="&#xe615;" d="M836.462 183.918c0 0-109.641 112.677-153.381 156.233-19.054 19.017-32.073 31.927-32.073 31.927 14.848 21.211 26.405 44.361 34.633 69.339s12.361 51.237 12.361 78.848c0 35.621-6.802 69.083-20.334 100.462-13.568 31.305-32 58.697-55.406 82.030-23.369 23.442-50.725 41.874-82.066 55.406-31.305 13.605-64.768 20.37-100.389 20.37-35.584 0-69.047-6.802-100.425-20.37-31.305-13.531-58.551-31.963-81.664-55.406-23.077-23.296-41.435-50.688-54.967-81.993-13.568-31.378-20.334-64.841-20.334-100.462s6.802-69.083 20.334-100.389c13.531-31.305 31.89-58.661 54.967-82.103 23.113-23.333 50.322-41.801 81.664-55.369 31.378-13.568 64.841-20.297 100.425-20.297 27.648 0 53.943 4.023 78.885 12.288s48.091 19.858 69.303 34.706c0 0 11.922-11.959 29.696-29.806 48.421-48.603 155.026-159.159 155.026-159.159 16.018-6.985 41.728 0.439 54.455 11.337s19.858 33.682 9.289 52.407zM612.718 447.013c-9.838-22.747-23.223-42.569-40.155-59.429-16.933-16.933-36.718-30.354-59.429-40.192-22.638-9.874-46.848-14.775-72.521-14.775-26.258 0-50.688 4.937-73.362 14.775s-42.496 23.259-59.429 40.192c-16.896 16.859-30.354 36.681-40.155 59.429-9.838 22.601-14.738 47.104-14.738 73.289 0 25.673 4.901 50.030 14.738 72.997 9.838 22.93 23.259 42.898 40.155 59.794 16.933 16.969 36.754 30.354 59.429 40.155 22.674 9.911 47.104 14.738 73.362 14.738 25.673 0 49.883-4.864 72.521-14.738 22.674-9.801 42.496-23.186 59.429-40.155 16.933-16.933 30.318-36.901 40.155-59.831 9.874-22.967 14.738-47.323 14.738-72.997 0-26.149-4.901-50.651-14.738-73.253z"/><glyph unicode="&#xe616;" d="M695.845 602.661l-29.147 29.111-154.697-154.734-154.734 154.734-29.111-29.111 154.734-154.734-154.624-154.624 29.111-29.074 154.624 154.587 154.661-154.587 29.038 29.074-154.587 154.624z"/><glyph unicode="&#xe617;" d="M470.418 450.158l132.791 136.558-27.794 26.075-158.354-162.853 9.618-9.033-0.11-0.146 153.234-157.55 27.136 26.587z"/><glyph unicode="&#xe618;" d="M512 539.941l-172.398-183.881h344.795z"/><glyph unicode="&#xe619;" d="M392.119 622.043v-348.087l239.726 174.043z"/><glyph unicode="&#xe61a;" d="M392.119 448l239.726-174.043v348.087z"/><glyph unicode="&#xe61b;" d="M237.714 191.159h73.728v513.682h-73.728v-513.682zM786.286 703.086h-440.283v-292.169h440.283l-148.078 144.128 148.078 148.041z"/><glyph unicode="&#xe61c;" d="M787.054 466.359h-256.219v256.695h-36.571v-256.695h-257.317v-36.571h257.317v-256.841h36.571v256.841h256.219z"/><glyph unicode="&#xe61d;" d="M769.134 594.286v36.571h-513.17v-25.271l-1.097-1.097 1.097-1.097v-9.106h0.622v-292.571h-0.622v-8.558l-1.097-1.097 1.097-1.097v-25.819h513.17v36.571h-0.585v292.571h0.585zM703.89 301.714h-387.657l119.881 119.881-25.856 25.856-117.138-117.138v236.361l220.014-217.088 25.856 25.856-1.39 1.353 194.377 194.341v-245.87l-122.149 122.149-25.856-25.856 119.918-119.845zM317.221 594.286h386.158l-191.781-191.781-194.377 191.781z"/><glyph unicode="&#xe61e;" d="M310.747 210.359h109.166v328.485h-109.166v-328.485zM604.050 355.584v-145.225h109.202v145.225h-109.202zM457.399 210.359h109.202v475.319h-109.202v-475.319z"/><glyph unicode="&#xe61f;" d="M310.747 210.359h109.166v328.485h-109.166v-328.485zM347.941 503.625h36.864v-256.768h-36.864v256.768zM604.050 355.584v-145.225h109.202v145.225h-109.202zM677.339 246.711h-36.827v71.863h36.827v-71.863zM457.399 210.359h109.202v475.319h-109.202v-475.319zM494.263 649.838h36.827v-402.834h-36.827v402.834z"/><glyph unicode="&#xe620;" d="M519.57 665.893c-127.232 2.487-231.936-75.922-233.911-175.141-0.695-34.487 11.154-66.926 32.219-94.72l-5.486 5.522c36.242-46.519-34.816-171.52-34.816-171.52l159.232 78.702c25.161-7.936 46.994-1.536 75.63-2.121 127.232-2.487 231.973 75.886 233.911 175.067 2.011 99.255-99.511 181.723-226.779 184.21z"/><glyph unicode="&#xe621;" d="M514.158 489.582l136.558-132.791 26.075 27.794-162.853 158.354-166.729-162.743 26.587-27.136z"/><glyph unicode="&#xe622;" d="M509.842 406.418l-136.558 132.791-26.075-27.794 162.853-158.354 166.729 162.743-26.587 27.136z"/><glyph unicode="&#xe623;" d="M938.824 426.028l-0.504 106.238-426.32 426.322-426.322-426.322-0.504-106.238 389.444 389.442v-880.006h74.764v880.006z"/><glyph unicode="&#xe624;" d="M1.994 518.75h748.928l-283.278 291.206h200.254l354.108-363.956-354.108-363.956h-200.254l283.278 291.174h-748.928v145.532z"/><glyph unicode="&#xe625;" d="M1022.006 375.25h-748.928l283.278-291.206h-200.254l-354.108 363.956 354.108 363.956h200.254l-283.278-291.174h748.928v-145.532z"/><glyph unicode="&#xe626;" d="M85.174 468.026l0.504-106.238 426.322-426.324 426.32 426.324 0.504 106.238-389.444-389.444 0.002 880.006h-74.764v-880.004z"/><glyph unicode="&#xe627;" d="M511.963 831.086c-211.529 0-383.049-171.52-383.049-383.086s171.483-383.086 383.049-383.086c211.602 0 383.086 171.483 383.086 383.086s-171.483 383.086-383.086 383.086zM511.963 794.514c191.086 0 346.514-155.429 346.514-346.514 0-79.909-27.429-153.344-73.070-212.041-5.486 1.975-11.008 3.84-16.274 6.107-34.926 14.629-73.801 31.781-108.654 46.153-9.911 2.706-19.931 5.413-29.842 8.155-11.849 8.155-23.589 35.365-29.915 48.933-6.29 0.914-12.654 1.792-19.017 2.633 0.914 20.992 13.934 22.126 19.017 38.071 4.498 14.080 0.512 32.439 7.57 45.495 4.937 9.070 16.128 9.070 21.65 16.933 5.083 6.985 8.411 19.273 9.984 27.941 2.853 15.799 5.339 37.339-2.158 53.029-4.279 8.96-6.985 9.874-8.229 20.736-1.426 13.275 3.913 56.43 4.133 65.755 0.512 24.21-0.073 26.149-5.925 49.737 0 0-7.058 21.358-18.213 27.831l-22.272 3.803-13.714 12.727c-55.369 34.085-114.761 10.167-146.505-2.67-45.824-14.885-74.789-59.758-54.565-155.538 3.474-16.421-8.96-23.698-8.155-32.658 1.829-19.566 2.158-66.487 20.59-78.080 1.719-1.061 14.811-4.352 14.738-3.438 1.792-19.017 3.621-38.071 5.376-57.015 4.608-12.654 15.689-14.080 18.907-31.927l-14.153-3.438c-6.363-13.568-17.993-40.777-29.879-48.933-9.947-2.706-19.931-5.413-29.879-8.155-34.889-14.373-73.691-31.488-108.654-46.153-1.902-0.768-3.877-1.39-5.815-2.158-43.776 58.112-70.071 130.011-70.071 208.165 0 191.086 155.429 346.514 346.478 346.514z"/><glyph unicode="&#xe628;" d="M427.703 653.019c0-10.569-8.558-19.090-19.090-19.090h-11.154c-10.533 0-19.090 8.521-19.090 19.090v68.462c0 10.533 8.594 19.090 19.090 19.090h11.154c10.533 0 19.090-8.558 19.090-19.090v-68.462zM645.778 653.019c0-10.569-8.521-19.090-19.054-19.090h-11.154c-10.533 0-19.054 8.521-19.054 19.090v68.462c-0.037 10.533 8.485 19.090 19.054 19.090h11.154c10.533 0 19.054-8.558 19.054-19.090v-68.462zM675.182 481.317l-38.729 31.598-152.795-187.282-81.518 64.805-28.891-36.242 120.21-95.634zM758.784 687.982h-71.351v-29.769c0-31.634-25.746-57.344-57.271-57.344h-11.227c-31.598 0-57.271 25.71-57.271 57.344v29.769h-97.682v-29.769c0-31.634-25.71-57.344-57.307-57.344h-11.154c-31.598 0-57.307 25.71-57.307 57.344v29.769h-72.96c-10.533 0-19.090-8.521-19.090-19.054v-494.373c-0.037-10.569 8.558-19.127 19.090-19.127h493.531c10.533 0 19.054 8.558 19.054 19.090v494.409c0 10.533-8.521 19.054-19.054 19.054zM720.567 240.677c0-10.569-8.558-19.090-19.090-19.090h-378.917c-10.569 0-19.090 8.521-19.090 19.090v288.11c0 10.569 8.521 19.054 19.090 19.054h378.88c10.533 0 19.090-8.485 19.090-19.054v-288.11z"/><glyph unicode="&#xe629;" d="M391.863 554.203h-128.219c-10.35 0-18.761-8.375-18.761-18.725v-91.429c0-10.35 8.375-18.725 18.761-18.725h128.219c10.35 0 18.761 8.375 18.761 18.725v91.429c0 10.386-8.375 18.725-18.761 18.725zM391.863 387.511h-90.734c-10.35 0-18.761-8.375-18.761-18.725v-194.633c0-10.35 8.411-18.725 18.761-18.725h90.734c10.35 0 18.761 8.375 18.761 18.725v194.633c0 10.35-8.375 18.725-18.761 18.725zM760.357 554.203h-279.845c-10.35 0-18.725-8.375-18.725-18.725v-91.429c0-10.35 8.375-18.725 18.725-18.725h279.845c10.313 0 18.725 8.375 18.725 18.725v91.429c-0.037 10.386-8.411 18.725-18.725 18.725zM721.701 385.573h-240.64c-10.313 0-18.725-8.375-18.725-18.761v-192.695c0-10.35 8.375-18.725 18.725-18.725h240.64c10.35 0 18.725 8.375 18.725 18.725v192.695c0 10.35-8.375 18.761-18.725 18.761zM507.355 575.634c21.87-3.986 42.971-6.327 62.647-6.327 99.072 0 152.832 53.248 153.088 103.387 0.183 32.293-23.698 67.291-78.117 67.84-72.923 0-118.089-51.493-141.605-89.71-23.918 38.107-69.266 88.576-142.373 88.576-52.882-0.549-76.763-35.547-76.581-67.84 0.256-50.139 54.016-103.424 153.088-103.424 0.037 0 0.037 0 0.037 0 21.394 0 44.398 2.414 68.425 7.241l1.39 0.256zM645.998 693.723c9.143-0.073 30.354-2.304 30.245-20.773-0.11-23.589-33.17-56.795-106.24-56.795-10.057 0-20.553 0.658-31.525 1.938 16.567 29.294 51.566 75.63 107.52 75.63zM437.504 614.985v0c-73.106 0-106.167 33.207-106.277 56.795-0.11 18.469 21.102 20.699 31.305 20.809 55.259 0 90.039-46.373 106.496-75.666-10.935-1.28-21.467-1.938-31.525-1.938z"/></font></defs></svg>
+<svg xmlns="http://www.w3.org/2000/svg"><defs><font horiz-adv-x="1024"><font-face units-per-em="1024" ascent="960" descent="-64" /><missing-glyph horiz-adv-x="1024" /><glyph unicode="&#x20;" d="" horiz-adv-x="512" /><glyph unicode="&#xe600;" d="M676.571 637.696c-59.867 28.197-131.255 2.523-159.415-57.307-1.975-4.133-3.657-9.362-5.157-15.397-1.499 6.034-3.182 11.264-5.157 15.397-28.197 59.831-99.547 85.504-159.415 57.307-59.831-28.197-85.504-99.547-57.271-159.378 28.197-59.867 221.806-231.424 221.806-231.424s0 0.219 0.037 0.585c0.037-0.366 0.037-0.585 0.037-0.585s193.646 171.557 221.806 231.424c28.233 59.831 2.597 131.182-57.271 159.378z" /><glyph unicode="&#xe601;" d="M676.571 637.696c-59.831 28.197-131.218 2.523-159.451-57.307-1.938-4.133-3.657-9.362-5.157-15.397-1.463 6.034-3.182 11.264-5.157 15.397-28.16 59.831-99.547 85.504-159.378 57.307s-85.467-99.547-57.271-159.378 221.806-231.424 221.806-231.424 0 0.219 0.037 0.585c0-0.402 0-0.622 0-0.622s193.646 171.557 221.842 231.424c28.233 59.867 2.597 131.218-57.271 159.415zM690.213 479.232c-25.417-43.776-174.007-184.722-174.007-184.722l-1.573 2.999c0 0-155.465 140.398-181.211 183.991-30.61 51.822-7.753 108.946 38.949 128.439 43.52 18.176 101.888-27.319 123.502-73.143 1.499-3.182 17.627-1.463 18.798-6.107 1.134 4.645 12.727 2.926 14.226 6.107 21.577 45.824 81.042 93.989 128 72.411 46.007-21.138 66.926-72.155 33.317-129.975z" /><glyph unicode="&#xe602;" d="M512 704.11l-296.85-512.256h593.701l-296.85 512.256zM544.219 254.135h-62.757v49.92h62.757v-49.92zM528.713 343.369h-31.269l-20.809 140.654-1.207 72.704h72.521v-72.704l-19.237-140.654z" /><glyph unicode="&#xe603;" d="M628.846 588.544c-34.085 28.343-75.63 42.24-116.773 42.24-47.47 0-94.757-18.578-130.085-54.382l-32.073 29.586-0.585-102.693 110.994-0.658-39.424 41.253c25.198 24.027 58.002 36.315 91.136 36.352 29.842-0.037 59.721-9.947 84.517-30.574 31.488-26.222 47.689-63.744 47.726-101.815 0-5.449-0.366-10.971-1.024-16.457l51.383 9.874c0.073 2.231 0.146 4.425 0.146 6.619 0.037 52.37-22.491 104.521-65.938 140.654zM603.794 352.768c-25.307-24.466-58.405-37.010-91.867-37.047-29.879 0.037-59.721 9.984-84.517 30.574-31.488 26.222-47.689 63.744-47.726 101.778 0 6.327 0.475 12.617 1.353 18.871l-51.602-9.691c-0.146-3.072-0.256-6.107-0.256-9.179-0.037-52.334 22.491-104.521 65.975-140.617 34.048-28.343 75.593-42.24 116.736-42.24h0.11c47.799 0 95.378 18.907 130.743 55.223l33.938-33.829 0.219 106.094-112.055 0.293 38.949-40.229z" /><glyph unicode="&#xe604;" d="M696.942 624.933l-19.273 6.107h-74.496v38.583l-12.544 21.029-22.711 13.495h-111.141l-23.333-13.495-12.581-21.029v-38.619h-73.765l-18.761-6.656-17.189-14.153v-88.869h19.017v-0.073h17.554v-329.435h36.571v0.293h255.415v-0.293h36.571v329.435h18.286v0.073h18.286v86.601l-15.909 17.006zM457.435 667.575h109.129v-36.571h-109.129v36.571zM639.707 228.718h-255.415v292.571h255.415v-292.571zM676.279 557.934h-328.558v36.498h328.558v-36.498zM457.435 483.511h-36.571v-218.587h36.571v218.587zM530.578 483.511h-36.571v-218.587h36.571v218.587zM603.721 483.511h-36.571v-218.587h36.571v218.587z" /><glyph unicode="&#xe605;" d="M804.645 515.401c-1.499 4.681-5.888 7.899-10.789 7.899h-206.958l-64.073 196.754c-1.536 4.645-5.888 7.826-10.825 7.826-4.901 0-9.289-3.182-10.825-7.863l-64.439-196.754h-206.592c-4.901 0-9.289-3.218-10.825-7.863-1.499-4.681 0.146-9.874 4.096-12.763l167.205-121.783-64.439-197.851c-1.536-4.681 0.146-9.838 4.133-12.727 3.95-2.889 9.399-2.889 13.349 0l168.338 122.185 167.936-122.149c2.011-1.463 4.315-2.231 6.693-2.231s4.681 0.768 6.693 2.231c4.023 2.889 5.669 8.009 4.133 12.727l-64.439 197.851 167.57 121.783c3.95 2.889 5.632 8.046 4.059 12.727z" /><glyph unicode="&#xe606;" d="M807.241 415.854v67.145l-9.509 3.145-71.936 23.442-19.2 46.373 36.937 78.080-47.506 47.506-8.923-4.498-67.438-34.304-46.373 19.2-29.111 81.298h-67.182l-26.624-81.445-46.336-19.163-78.043 36.901-47.506-47.506 4.498-8.96 34.267-67.438-19.2-46.336-81.298-29.074v-67.218l9.472-3.072 71.973-23.515 19.163-46.373-36.901-78.080 47.506-47.506 8.887 4.498 67.474 34.304 46.373-19.2 29.111-81.298h67.182l3.072 9.509 23.515 71.936 46.373 19.2 78.080-36.937 47.506 47.506-4.498 8.923-34.304 67.438 19.2 46.373 81.298 29.147zM512 353.938c-51.968 0-94.062 42.13-94.062 94.062 0 52.005 42.094 94.062 94.062 94.062 51.931 0 94.098-42.057 94.098-94.062-0.037-51.931-42.167-94.062-94.098-94.062z" /><glyph unicode="&#xe607;" d="M339.602 539.941l172.398-183.881 172.398 183.881z" /><glyph unicode="&#xe608;" d="M606.939 449.938l-158.391 162.853-27.794-26.075 132.827-136.558-136.521-140.361 27.173-26.587 153.198 157.55-0.146 0.146z" /><glyph unicode="&#xe609;" d="M127.634 740.571v-73.143h768.731v73.143h-768.731zM127.634 411.429h768.731v73.143h-768.731v-73.143zM127.634 155.429h768.731v73.143h-768.731v-73.143z" /><glyph unicode="&#xe60a;" d="M512 742.217c-102.437 0-185.417-83.054-185.417-185.454 0-102.437 185.417-403.017 185.417-403.017s185.454 300.581 185.454 403.017c-0.037 102.437-83.017 185.454-185.454 185.454zM512 500.443c-31.122 0-56.357 25.198-56.357 56.357 0 31.086 25.234 56.357 56.357 56.357 31.159 0 56.393-25.271 56.393-56.357-0.037-31.159-25.271-56.357-56.393-56.357z" /><glyph unicode="&#xe60b;" d="M219.429 485.595h255.927v254.793h-255.927v-254.793zM548.571 740.389v-109.349h256v109.349h-256zM219.429 156.453h255.927v254.793h-255.927v-254.793zM548.571 484.754h256v109.349h-256v-109.349zM548.571 301.897h256v109.349h-256v-109.349zM548.571 155.611h256v109.349h-256v-109.349z" /><glyph unicode="&#xe60c;" d="M579.511 677.010c-30.793 0-57.381-25.161-57.381-55.954 0-28.635 18.907-47.579 47.579-47.579 31.415 0 58.002 23.771 58.002 55.991 0 28.709-20.224 47.543-48.201 47.543zM593.518 336.494c-9.801 0-48.311-59.502-69.266-59.502-5.595 0-8.375 4.937-8.375 9.801 0 11.227 7.68 28.709 11.849 39.205l50.322 136.375c25.198 67.84-6.985 86.016-37.047 86.016-40.558 0-76.946-20.297-104.887-46.848-9.106-9.070-39.863-38.437-39.863-51.054 0-4.133 4.169-9.070 9.106-9.070 12.544 0 46.153 60.855 72.009 60.855 5.595 0 11.886-6.29 6.985-18.871l-48.896-123.173c-4.937-11.849-28.709-69.23-28.709-102.802 0-26.587 17.518-38.437 42.679-38.437 70.656 0 152.43 86.711 152.43 107.008 0 6.29-4.864 10.496-8.338 10.496z" /><glyph unicode="&#xe60d;" d="M219.063 593.92h147.017v147.017h-147.017v-147.017zM438.491 593.92h147.017v147.017h-147.017v-147.017zM657.92 740.937v-147.017h147.017v147.017h-147.017zM219.063 374.491h147.017v147.017h-147.017v-147.017zM438.491 374.491h147.017v147.017h-147.017v-147.017zM657.92 374.491h147.017v147.017h-147.017v-147.017zM219.063 155.063h147.017v147.017h-147.017v-147.017zM438.491 155.063h147.017v147.017h-147.017v-147.017zM657.92 155.063h147.017v147.017h-147.017v-147.017z" /><glyph unicode="&#xe60e;" d="M711.607 401.591l-5.486-5.522c21.065 27.794 32.878 60.197 32.219 94.72-1.975 99.218-106.679 177.627-233.874 175.141-127.232-2.487-228.791-84.992-226.816-184.21 1.938-99.182 106.679-177.554 233.911-175.067 28.635 0.585 50.432-5.815 75.63 2.121l159.232-78.702c-0.037-0.037-71.058 124.965-34.816 171.52z" /><glyph unicode="&#xe60f;" d="M236.946 466.286h550.107v-36.571h-550.107v36.571z" /><glyph unicode="&#xe610;" d="M749.129 663.698c-152.101-93.257-262.473-210.907-312.064-269.934l-121.417 95.159-53.65-43.264 209.847-213.394c36.096 92.489 150.491 273.298 290.158 401.737l-12.873 29.696z" /><glyph unicode="&#xe611;" d="M434.871 259.95c-35.218 0-63.707-28.526-63.707-63.744 0-35.182 28.489-63.671 63.707-63.671 35.182 0 63.707 28.489 63.707 63.671 0 35.218-28.526 63.744-63.707 63.744zM654.848 259.95c-35.218 0-63.707-28.526-63.707-63.744 0-35.182 28.489-63.671 63.707-63.671 35.145 0 63.707 28.489 63.707 63.671 0 35.218-28.562 63.744-63.707 63.744zM784.274 616.741c-163.511 0-427.227 0-427.227 0s-25.929 70.071-49.957 113.371c-24.027 43.227-57.893 32.037-57.893 32.037-26.843 0-39.314-16.055-39.314-42.971 0-26.843 16.457-48.64 43.337-48.64l16.603-14.848 121.929-330.533 356.425-0.256c0 0 65.17 261.705 61.806 251.355 11.959 36.974-3.255 40.485-25.71 40.485zM392.485 492.544c-18.725 0-33.902 15.177-33.902 33.902s15.177 33.902 33.902 33.902 33.902-15.177 33.902-33.902-15.177-33.902-33.902-33.902zM464.933 379.392c-18.725 0-33.902 15.177-33.902 33.902s15.177 33.902 33.902 33.902 33.902-15.177 33.902-33.902-15.177-33.902-33.902-33.902zM502.199 492.544c-18.725 0-33.902 15.177-33.902 33.902s15.177 33.902 33.902 33.902 33.902-15.177 33.902-33.902-15.177-33.902-33.902-33.902zM574.647 379.392c-18.725 0-33.865 15.177-33.865 33.902s15.177 33.902 33.865 33.902 33.938-15.177 33.938-33.902-15.214-33.902-33.938-33.902zM611.913 492.544c-18.725 0-33.938 15.177-33.938 33.902s15.214 33.902 33.938 33.902 33.865-15.177 33.865-33.902-15.141-33.902-33.865-33.902zM684.361 379.392c-18.725 0-33.865 15.177-33.865 33.902s15.141 33.902 33.865 33.902 33.938-15.177 33.938-33.902-15.214-33.902-33.938-33.902zM721.627 492.544c-18.725 0-33.938 15.177-33.938 33.902s15.214 33.902 33.938 33.902 33.865-15.177 33.865-33.902-15.141-33.902-33.865-33.902z" /><glyph unicode="&#xe612;" d="M642.487 578.304c11.959 0 21.65 9.691 21.65 21.65v77.934c0 11.959-9.691 21.65-21.65 21.65-11.922 0-21.65-9.691-21.65-21.65v-77.934c0.037-11.959 9.728-21.65 21.65-21.65zM381.842 578.304c11.922 0 21.65 9.691 21.65 21.65v77.934c0 11.959-9.728 21.65-21.65 21.65-11.959 0-21.65-9.691-21.65-21.65v-77.934c0.037-11.959 9.691-21.65 21.65-21.65zM671.269 636.562v-0.402c8.997-7.973 14.702-19.566 14.702-32.549 0-23.991-19.456-43.447-43.483-43.447-23.991 0-43.447 19.456-43.447 43.447 0 12.946 5.705 24.576 14.702 32.549v0.402h-203.154v-0.402c8.997-7.973 14.702-19.566 14.702-32.549 0-23.991-19.456-43.447-43.447-43.447-24.027 0-43.447 19.456-43.447 43.447 0 12.946 5.669 24.576 14.665 32.549v0.402h-96.841v-440.101h511.561v440.101h-96.512zM732.087 234.569h-437.76v291.694h437.76v-291.694zM619.301 407.113h-55.15v-55.113h55.15v55.113zM619.301 490.021h-55.15v-55.113h55.15v55.113zM619.301 326.51h-55.15v-55.15h55.15v55.15zM696.942 490.021h-55.15v-55.113h55.15v55.113zM696.942 407.113h-55.15v-55.113h55.15v55.113zM386.267 326.51h-55.113v-55.15h55.113v55.15zM463.982 326.51h-55.15v-55.15h55.15v55.15zM463.982 407.113h-55.15v-55.113h55.15v55.113zM386.267 407.113h-55.113v-55.113h55.113v55.113zM541.586 407.113h-55.113v-55.113h55.113v55.113zM541.586 490.021h-55.113v-55.113h55.113v55.113zM463.982 490.021h-55.15v-55.113h55.15v55.113zM541.586 326.51h-55.113v-55.15h55.113v55.15z" /><glyph unicode="&#xe613;" d="M512 677.742l-209.006-253.257h136.338v-206.19h145.298v206.19h136.375z" /><glyph unicode="&#xe614;" d="M584.631 471.515v206.226h-145.298v-206.226h-136.338l209.006-253.221 209.006 253.221z" /><glyph unicode="&#xe615;" d="M836.462 183.918c0 0-109.641 112.677-153.381 156.233-19.054 19.017-32.073 31.927-32.073 31.927 14.848 21.211 26.405 44.361 34.633 69.339s12.361 51.237 12.361 78.848c0 35.621-6.802 69.083-20.334 100.462-13.568 31.305-32 58.697-55.406 82.030-23.369 23.442-50.725 41.874-82.066 55.406-31.305 13.605-64.768 20.37-100.389 20.37-35.584 0-69.047-6.802-100.425-20.37-31.305-13.531-58.551-31.963-81.664-55.406-23.077-23.296-41.435-50.688-54.967-81.993-13.568-31.378-20.334-64.841-20.334-100.462s6.802-69.083 20.334-100.389c13.531-31.305 31.89-58.661 54.967-82.103 23.113-23.333 50.322-41.801 81.664-55.369 31.378-13.568 64.841-20.297 100.425-20.297 27.648 0 53.943 4.023 78.885 12.288s48.091 19.858 69.303 34.706c0 0 11.922-11.959 29.696-29.806 48.421-48.603 155.026-159.159 155.026-159.159 16.018-6.985 41.728 0.439 54.455 11.337s19.858 33.682 9.289 52.407zM612.718 447.013c-9.838-22.747-23.223-42.569-40.155-59.429-16.933-16.933-36.718-30.354-59.429-40.192-22.638-9.874-46.848-14.775-72.521-14.775-26.258 0-50.688 4.937-73.362 14.775s-42.496 23.259-59.429 40.192c-16.896 16.859-30.354 36.681-40.155 59.429-9.838 22.601-14.738 47.104-14.738 73.289 0 25.673 4.901 50.030 14.738 72.997 9.838 22.93 23.259 42.898 40.155 59.794 16.933 16.969 36.754 30.354 59.429 40.155 22.674 9.911 47.104 14.738 73.362 14.738 25.673 0 49.883-4.864 72.521-14.738 22.674-9.801 42.496-23.186 59.429-40.155 16.933-16.933 30.318-36.901 40.155-59.831 9.874-22.967 14.738-47.323 14.738-72.997 0-26.149-4.901-50.651-14.738-73.253z" /><glyph unicode="&#xe616;" d="M695.845 602.661l-29.147 29.111-154.697-154.734-154.734 154.734-29.111-29.111 154.734-154.734-154.624-154.624 29.111-29.074 154.624 154.587 154.661-154.587 29.038 29.074-154.587 154.624z" /><glyph unicode="&#xe617;" d="M470.418 450.158l132.791 136.558-27.794 26.075-158.354-162.853 9.618-9.033-0.11-0.146 153.234-157.55 27.136 26.587z" /><glyph unicode="&#xe618;" d="M512 539.941l-172.398-183.881h344.795z" /><glyph unicode="&#xe619;" d="M392.119 622.043v-348.087l239.726 174.043z" /><glyph unicode="&#xe61a;" d="M392.119 448l239.726-174.043v348.087z" /><glyph unicode="&#xe61b;" d="M237.714 191.159h73.728v513.682h-73.728v-513.682zM786.286 703.086h-440.283v-292.169h440.283l-148.078 144.128 148.078 148.041z" /><glyph unicode="&#xe61c;" d="M787.054 466.359h-256.219v256.695h-36.571v-256.695h-257.317v-36.571h257.317v-256.841h36.571v256.841h256.219z" /><glyph unicode="&#xe61d;" d="M769.134 594.286v36.571h-513.17v-25.271l-1.097-1.097 1.097-1.097v-9.106h0.622v-292.571h-0.622v-8.558l-1.097-1.097 1.097-1.097v-25.819h513.17v36.571h-0.585v292.571h0.585zM703.89 301.714h-387.657l119.881 119.881-25.856 25.856-117.138-117.138v236.361l220.014-217.088 25.856 25.856-1.39 1.353 194.377 194.341v-245.87l-122.149 122.149-25.856-25.856 119.918-119.845zM317.221 594.286h386.158l-191.781-191.781-194.377 191.781z" /><glyph unicode="&#xe61e;" d="M310.747 210.359h109.166v328.485h-109.166v-328.485zM604.050 355.584v-145.225h109.202v145.225h-109.202zM457.399 210.359h109.202v475.319h-109.202v-475.319z" /><glyph unicode="&#xe61f;" d="M310.747 210.359h109.166v328.485h-109.166v-328.485zM347.941 503.625h36.864v-256.768h-36.864v256.768zM604.050 355.584v-145.225h109.202v145.225h-109.202zM677.339 246.711h-36.827v71.863h36.827v-71.863zM457.399 210.359h109.202v475.319h-109.202v-475.319zM494.263 649.838h36.827v-402.834h-36.827v402.834z" /><glyph unicode="&#xe620;" d="M519.57 665.893c-127.232 2.487-231.936-75.922-233.911-175.141-0.695-34.487 11.154-66.926 32.219-94.72l-5.486 5.522c36.242-46.519-34.816-171.52-34.816-171.52l159.232 78.702c25.161-7.936 46.994-1.536 75.63-2.121 127.232-2.487 231.973 75.886 233.911 175.067 2.011 99.255-99.511 181.723-226.779 184.21z" /><glyph unicode="&#xe621;" d="M514.158 489.582l136.558-132.791 26.075 27.794-162.853 158.354-166.729-162.743 26.587-27.136z" /><glyph unicode="&#xe622;" d="M509.842 406.418l-136.558 132.791-26.075-27.794 162.853-158.354 166.729 162.743-26.587 27.136z" /><glyph unicode="&#xe623;" d="M512 52.005c-218.77 0-396.032 177.298-396.032 395.995s177.262 395.995 396.032 395.995c218.661 0 396.032-177.298 396.032-395.995s-177.371-395.995-396.032-395.995zM512 796.087c-191.89 0-348.087-156.197-348.087-348.087 0-191.927 156.197-348.087 348.087-348.087s348.050 156.16 348.050 348.087c-0.037 191.927-156.16 348.087-348.050 348.087zM611.328 442.441l-24.101-18.761c-13.166-10.24-21.87-22.126-26.185-35.84-2.743-8.558-4.681-18.907-4.901-37.12h-92.343c1.353 38.473 5.413 61.842 11.301 76.581 5.925 14.592 21.102 31.488 45.531 50.578l24.795 19.383c8.192 6.181 14.738 12.91 19.785 20.187 8.997 12.471 13.495 26.222 13.495 41.216 0 17.262-5.010 32.987-15.104 47.214-10.057 14.226-28.453 21.321-55.259 21.321-26.295 0-44.946-8.777-55.918-26.295s-16.384-33.463-16.384-52.37h-98.523c2.706 64.805 25.234 108.544 67.73 135.57 26.843 17.298 59.794 25.929 98.889 25.929 51.383 0 94.025-12.288 128-36.827 34.011-24.503 53.87-74.935 53.87-123.173 0-29.55-10.24-40.338-25.051-60.599-8.558-12.288-25.125-27.941-49.627-46.994zM561.042 202.423h-98.231v98.487h98.231v-98.487z" /><glyph unicode="&#xe624;" d="M1.994 518.75h748.928l-283.278 291.206h200.254l354.108-363.956-354.108-363.956h-200.254l283.278 291.174h-748.928v145.532z" /><glyph unicode="&#xe625;" d="M1022.006 375.25h-748.928l283.278-291.206h-200.254l-354.108 363.956 354.108 363.956h200.254l-283.278-291.174h748.928v-145.532z" /><glyph unicode="&#xe626;" d="M85.174 468.026l0.504-106.238 426.322-426.324 426.32 426.324 0.504 106.238-389.444-389.444 0.002 880.006h-74.764v-880.004z" /><glyph unicode="&#xe627;" d="M511.963 831.086c-211.529 0-383.049-171.52-383.049-383.086s171.483-383.086 383.049-383.086c211.602 0 383.086 171.483 383.086 383.086s-171.483 383.086-383.086 383.086zM511.963 794.514c191.086 0 346.514-155.429 346.514-346.514 0-79.909-27.429-153.344-73.070-212.041-5.486 1.975-11.008 3.84-16.274 6.107-34.926 14.629-73.801 31.781-108.654 46.153-9.911 2.706-19.931 5.413-29.842 8.155-11.849 8.155-23.589 35.365-29.915 48.933-6.29 0.914-12.654 1.792-19.017 2.633 0.914 20.992 13.934 22.126 19.017 38.071 4.498 14.080 0.512 32.439 7.57 45.495 4.937 9.070 16.128 9.070 21.65 16.933 5.083 6.985 8.411 19.273 9.984 27.941 2.853 15.799 5.339 37.339-2.158 53.029-4.279 8.96-6.985 9.874-8.229 20.736-1.426 13.275 3.913 56.43 4.133 65.755 0.512 24.21-0.073 26.149-5.925 49.737 0 0-7.058 21.358-18.213 27.831l-22.272 3.803-13.714 12.727c-55.369 34.085-114.761 10.167-146.505-2.67-45.824-14.885-74.789-59.758-54.565-155.538 3.474-16.421-8.96-23.698-8.155-32.658 1.829-19.566 2.158-66.487 20.59-78.080 1.719-1.061 14.811-4.352 14.738-3.438 1.792-19.017 3.621-38.071 5.376-57.015 4.608-12.654 15.689-14.080 18.907-31.927l-14.153-3.438c-6.363-13.568-17.993-40.777-29.879-48.933-9.947-2.706-19.931-5.413-29.879-8.155-34.889-14.373-73.691-31.488-108.654-46.153-1.902-0.768-3.877-1.39-5.815-2.158-43.776 58.112-70.071 130.011-70.071 208.165 0 191.086 155.429 346.514 346.478 346.514z" /><glyph unicode="&#xe628;" d="M427.703 653.019c0-10.569-8.558-19.090-19.090-19.090h-11.154c-10.533 0-19.090 8.521-19.090 19.090v68.462c0 10.533 8.594 19.090 19.090 19.090h11.154c10.533 0 19.090-8.558 19.090-19.090v-68.462zM645.778 653.019c0-10.569-8.521-19.090-19.054-19.090h-11.154c-10.533 0-19.054 8.521-19.054 19.090v68.462c-0.037 10.533 8.485 19.090 19.054 19.090h11.154c10.533 0 19.054-8.558 19.054-19.090v-68.462zM675.182 481.317l-38.729 31.598-152.795-187.282-81.518 64.805-28.891-36.242 120.21-95.634zM758.784 687.982h-71.351v-29.769c0-31.634-25.746-57.344-57.271-57.344h-11.227c-31.598 0-57.271 25.71-57.271 57.344v29.769h-97.682v-29.769c0-31.634-25.71-57.344-57.307-57.344h-11.154c-31.598 0-57.307 25.71-57.307 57.344v29.769h-72.96c-10.533 0-19.090-8.521-19.090-19.054v-494.373c-0.037-10.569 8.558-19.127 19.090-19.127h493.531c10.533 0 19.054 8.558 19.054 19.090v494.409c0 10.533-8.521 19.054-19.054 19.054zM720.567 240.677c0-10.569-8.558-19.090-19.090-19.090h-378.917c-10.569 0-19.090 8.521-19.090 19.090v288.11c0 10.569 8.521 19.054 19.090 19.054h378.88c10.533 0 19.090-8.485 19.090-19.054v-288.11z" /><glyph unicode="&#xe629;" d="M391.863 554.203h-128.219c-10.35 0-18.761-8.375-18.761-18.725v-91.429c0-10.35 8.375-18.725 18.761-18.725h128.219c10.35 0 18.761 8.375 18.761 18.725v91.429c0 10.386-8.375 18.725-18.761 18.725zM391.863 387.511h-90.734c-10.35 0-18.761-8.375-18.761-18.725v-194.633c0-10.35 8.411-18.725 18.761-18.725h90.734c10.35 0 18.761 8.375 18.761 18.725v194.633c0 10.35-8.375 18.725-18.761 18.725zM760.357 554.203h-279.845c-10.35 0-18.725-8.375-18.725-18.725v-91.429c0-10.35 8.375-18.725 18.725-18.725h279.845c10.313 0 18.725 8.375 18.725 18.725v91.429c-0.037 10.386-8.411 18.725-18.725 18.725zM721.701 385.573h-240.64c-10.313 0-18.725-8.375-18.725-18.761v-192.695c0-10.35 8.375-18.725 18.725-18.725h240.64c10.35 0 18.725 8.375 18.725 18.725v192.695c0 10.35-8.375 18.761-18.725 18.761zM507.355 575.634c21.87-3.986 42.971-6.327 62.647-6.327 99.072 0 152.832 53.248 153.088 103.387 0.183 32.293-23.698 67.291-78.117 67.84-72.923 0-118.089-51.493-141.605-89.71-23.918 38.107-69.266 88.576-142.373 88.576-52.882-0.549-76.763-35.547-76.581-67.84 0.256-50.139 54.016-103.424 153.088-103.424 0.037 0 0.037 0 0.037 0 21.394 0 44.398 2.414 68.425 7.241l1.39 0.256zM645.998 693.723c9.143-0.073 30.354-2.304 30.245-20.773-0.11-23.589-33.17-56.795-106.24-56.795-10.057 0-20.553 0.658-31.525 1.938 16.567 29.294 51.566 75.63 107.52 75.63zM437.504 614.985v0c-73.106 0-106.167 33.207-106.277 56.795-0.11 18.469 21.102 20.699 31.305 20.809 55.259 0 90.039-46.373 106.496-75.666-10.935-1.28-21.467-1.938-31.525-1.938z" /><glyph unicode="&#xe633;" d="M938.824 426.028l-0.504 106.238-426.32 426.322-426.322-426.322-0.504-106.238 389.444 389.442v-880.006h74.764v880.006z" /></font></defs></svg>
\ No newline at end of file
diff --git a/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.ttf b/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.ttf
index eaec02d1df42b6b0208db02f1da2a3fb3bcae7fd..6fabe5c3e89948ff20801ea1e43e18b15c9c4da1 100644
Binary files a/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.ttf and b/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.ttf differ
diff --git a/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff b/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff
index e9e8395b2574bc6cfbb3c2606213ca204179bf51..a8e688940c486205bcbc8bb9b787af33c1a8db86 100644
Binary files a/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff and b/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff differ
diff --git a/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff2 b/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff2
index 1d60f2f95c0facb689b7a0079cfb2b2312bcab17..e1fc31afbdaf56fd0fc3cfb09180f52be6f1b569 100644
Binary files a/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff2 and b/lib/web/fonts/Blank-Theme-Icons/Blank-Theme-Icons.woff2 differ
diff --git a/lib/web/fonts/Blank-Theme-Icons/selection.json b/lib/web/fonts/Blank-Theme-Icons/selection.json
index e3a71a30c6ae96426ed01b4041c20ae392e1e909..2e8beab777f8a696acbbbb6d6b4ce523f9d2f481 100644
--- a/lib/web/fonts/Blank-Theme-Icons/selection.json
+++ b/lib/web/fonts/Blank-Theme-Icons/selection.json
@@ -1,6 +1,34 @@
 {
 	"IcoMoonType": "selection",
 	"icons": [
+		{
+			"icon": {
+				"paths": [
+					"M512 907.995c-218.77 0-396.032-177.298-396.032-395.995s177.262-395.995 396.032-395.995c218.661 0 396.032 177.298 396.032 395.995s-177.371 395.995-396.032 395.995zM512 163.913c-191.89 0-348.087 156.197-348.087 348.087 0 191.927 156.197 348.087 348.087 348.087s348.050-156.16 348.050-348.087c-0.037-191.927-156.16-348.087-348.050-348.087zM611.328 517.559l-24.101 18.761c-13.166 10.24-21.87 22.126-26.185 35.84-2.743 8.558-4.681 18.907-4.901 37.12h-92.343c1.353-38.473 5.413-61.842 11.301-76.581 5.925-14.592 21.102-31.488 45.531-50.578l24.795-19.383c8.192-6.181 14.738-12.91 19.785-20.187 8.997-12.471 13.495-26.222 13.495-41.216 0-17.262-5.010-32.987-15.104-47.214-10.057-14.226-28.453-21.321-55.259-21.321-26.295 0-44.946 8.777-55.918 26.295s-16.384 33.463-16.384 52.37h-98.523c2.706-64.805 25.234-108.544 67.73-135.57 26.843-17.298 59.794-25.929 98.889-25.929 51.383 0 94.025 12.288 128 36.827 34.011 24.503 53.87 74.935 53.87 123.173 0 29.55-10.24 40.338-25.051 60.599-8.558 12.288-25.125 27.941-49.627 46.994zM561.042 757.577h-98.231v-98.487h98.231v98.487z"
+				],
+				"attrs": [
+					{}
+				],
+				"isMulticolor": false,
+				"grid": 0,
+				"tags": [
+					"help"
+				]
+			},
+			"attrs": [
+				{}
+			],
+			"properties": {
+				"order": 44,
+				"id": 37,
+				"prevSize": 32,
+				"code": 58915,
+				"name": "help"
+			},
+			"setIdx": 0,
+			"setId": 1,
+			"iconIdx": 0
+		},
 		{
 			"icon": {
 				"paths": [
@@ -36,7 +64,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 0
+			"iconIdx": 1
 		},
 		{
 			"icon": {
@@ -76,7 +104,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 1
+			"iconIdx": 2
 		},
 		{
 			"icon": {
@@ -100,7 +128,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 2
+			"iconIdx": 3
 		},
 		{
 			"icon": {
@@ -118,13 +146,13 @@
 				"order": 36,
 				"id": 3,
 				"prevSize": 32,
-				"code": 58915,
+				"code": 58931,
 				"name": "arrow-up-thin",
 				"ligatures": ""
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 3
+			"iconIdx": 4
 		},
 		{
 			"icon": {
@@ -148,7 +176,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 4
+			"iconIdx": 5
 		},
 		{
 			"icon": {
@@ -172,7 +200,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 5
+			"iconIdx": 6
 		},
 		{
 			"icon": {
@@ -196,7 +224,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 6
+			"iconIdx": 7
 		},
 		{
 			"icon": {
@@ -220,7 +248,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 7
+			"iconIdx": 8
 		},
 		{
 			"icon": {
@@ -244,7 +272,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 8
+			"iconIdx": 9
 		},
 		{
 			"icon": {
@@ -268,7 +296,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 9
+			"iconIdx": 10
 		},
 		{
 			"icon": {
@@ -292,7 +320,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 10
+			"iconIdx": 11
 		},
 		{
 			"icon": {
@@ -316,7 +344,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 11
+			"iconIdx": 12
 		},
 		{
 			"icon": {
@@ -340,7 +368,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 12
+			"iconIdx": 13
 		},
 		{
 			"icon": {
@@ -364,7 +392,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 13
+			"iconIdx": 14
 		},
 		{
 			"icon": {
@@ -388,7 +416,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 14
+			"iconIdx": 15
 		},
 		{
 			"icon": {
@@ -412,7 +440,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 15
+			"iconIdx": 16
 		},
 		{
 			"icon": {
@@ -436,7 +464,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 16
+			"iconIdx": 17
 		},
 		{
 			"icon": {
@@ -460,7 +488,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 17
+			"iconIdx": 18
 		},
 		{
 			"icon": {
@@ -484,7 +512,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 18
+			"iconIdx": 19
 		},
 		{
 			"icon": {
@@ -508,7 +536,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 19
+			"iconIdx": 20
 		},
 		{
 			"icon": {
@@ -532,7 +560,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 20
+			"iconIdx": 21
 		},
 		{
 			"icon": {
@@ -556,7 +584,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 21
+			"iconIdx": 22
 		},
 		{
 			"icon": {
@@ -580,7 +608,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 22
+			"iconIdx": 23
 		},
 		{
 			"icon": {
@@ -604,7 +632,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 23
+			"iconIdx": 24
 		},
 		{
 			"icon": {
@@ -628,7 +656,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 24
+			"iconIdx": 25
 		},
 		{
 			"icon": {
@@ -652,7 +680,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 25
+			"iconIdx": 26
 		},
 		{
 			"icon": {
@@ -676,7 +704,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 26
+			"iconIdx": 27
 		},
 		{
 			"icon": {
@@ -700,7 +728,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 27
+			"iconIdx": 28
 		},
 		{
 			"icon": {
@@ -724,7 +752,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 28
+			"iconIdx": 29
 		},
 		{
 			"icon": {
@@ -748,7 +776,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 29
+			"iconIdx": 30
 		},
 		{
 			"icon": {
@@ -772,7 +800,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 30
+			"iconIdx": 31
 		},
 		{
 			"icon": {
@@ -796,7 +824,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 31
+			"iconIdx": 32
 		},
 		{
 			"icon": {
@@ -820,7 +848,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 32
+			"iconIdx": 33
 		},
 		{
 			"icon": {
@@ -844,7 +872,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 33
+			"iconIdx": 34
 		},
 		{
 			"icon": {
@@ -868,7 +896,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 34
+			"iconIdx": 35
 		},
 		{
 			"icon": {
@@ -892,7 +920,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 35
+			"iconIdx": 36
 		},
 		{
 			"icon": {
@@ -916,7 +944,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 36
+			"iconIdx": 37
 		},
 		{
 			"icon": {
@@ -940,7 +968,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 37
+			"iconIdx": 38
 		},
 		{
 			"icon": {
@@ -964,7 +992,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 38
+			"iconIdx": 39
 		},
 		{
 			"icon": {
@@ -988,7 +1016,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 39
+			"iconIdx": 40
 		},
 		{
 			"icon": {
@@ -1012,7 +1040,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 40
+			"iconIdx": 41
 		},
 		{
 			"icon": {
@@ -1036,7 +1064,7 @@
 			},
 			"setIdx": 0,
 			"setId": 1,
-			"iconIdx": 41
+			"iconIdx": 42
 		}
 	],
 	"height": 1024,
diff --git a/lib/web/mage/dropdown.js b/lib/web/mage/dropdown.js
index 61e44e1ee501264a5757973d94e7e6bade643118..dbf04d0da9387841fa28ab1050894fcf3b5fb236 100644
--- a/lib/web/mage/dropdown.js
+++ b/lib/web/mage/dropdown.js
@@ -36,6 +36,7 @@ define([
             autoSize: false,
             draggable: false,
             resizable: false,
+            bodyClass: '',
             buttons: [
                 {
                     'class': "action close",
@@ -111,6 +112,9 @@ define([
             if(_self.options.parentClass) {
                 $(_self.options.appendTo).addClass(_self.options.parentClass);
             }
+            if(_self.options.bodyClass) {
+                $('body').addClass(_self.options.bodyClass);
+            }
 
             if (_self.options.shadowHinter) {
                 _self._setShadowHinterPosition();
@@ -132,6 +136,9 @@ define([
             if(this.options.parentClass) {
                 $(this.options.appendTo).removeClass(this.options.parentClass);
             }
+            if(this.options.bodyClass) {
+                $('body').removeClass(this.options.bodyClass);
+            }
             if(timer) {
                 clearTimeout(timer);
             }
diff --git a/lib/web/mage/loader.js b/lib/web/mage/loader.js
index a4bfc58b7859edd2cff3c200bd37a67733fc32c7..455ba80c692df017ad30293b761036b0b54f9f56 100644
--- a/lib/web/mage/loader.js
+++ b/lib/web/mage/loader.js
@@ -194,18 +194,10 @@ define([
         },
 
         _onAjaxComplete: function (e, jqxhr, settings) {
-            var ariaSelected = $('[aria-selected="true"]');
-
             $(this.options.defaultContainer)
                 .removeClass(this.options.loadingClass)
                 .attr('aria-busy', false);
 
-            // ARIA support
-            if (ariaSelected.length) {
-                ariaSelected.first().focus();
-                $(this.options.defaultContainer).addClass('_keyfocus');
-            }
-
             if (settings && settings.showLoader) {
                 this._getJqueryObj(settings.loaderContext).trigger('processStop');
             }
diff --git a/lib/web/mage/storage.js b/lib/web/mage/storage.js
index ea0b6b432ba9d0b8316b1f714c92c50e697f3d62..3c6bd89ca1ebf0de4d964a4533cf9ffd1ff8e20d 100644
--- a/lib/web/mage/storage.js
+++ b/lib/web/mage/storage.js
@@ -2,34 +2,83 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-/*global define*/
 define(['jquery', 'mage/url'], function ($, urlBuilder) {
-    "use strict";
+    'use strict';
+
     return {
-        get: function (url, contentType) {
+        /**
+         * Perform asynchronous GET request to server.
+         * @param {String} url
+         * @param {Boolean} global
+         * @param {String} contentType
+         * @returns {Deferred}
+         */
+        get: function (url, global, contentType) {
+            global = global === undefined ? true : global;
             contentType = contentType || 'application/json';
+
             return $.ajax({
                 url: urlBuilder.build(url),
                 type: 'GET',
-                async: false,
+                global: global,
                 contentType: contentType
             });
         },
-        post: function(url, data, contentType) {
+        /**
+         * Perform asynchronous POST request to server.
+         * @param {String} url
+         * @param {String} data
+         * @param {Boolean} global
+         * @param {String} contentType
+         * @returns {Deferred}
+         */
+        post: function (url, data, global, contentType) {
+            global = global === undefined ? true : global;
             contentType = contentType || 'application/json';
+
             return $.ajax({
                 url: urlBuilder.build(url),
                 type: 'POST',
                 data: data,
+                global: global,
                 contentType: contentType
             });
         },
-        put: function(url, data, contentType) {
+        /**
+         * Perform asynchronous PUT request to server.
+         * @param {String} url
+         * @param {String} data
+         * @param {Boolean} global
+         * @param {String} contentType
+         * @returns {Deferred}
+         */
+        put: function(url, data, global, contentType) {
+            global = global === undefined ? true : global;
             contentType = contentType || 'application/json';
+
             return $.ajax({
                 url: urlBuilder.build(url),
                 type: 'PUT',
                 data: data,
+                global: global,
+                contentType: contentType
+            });
+        },
+        /**
+         * Perform asynchronous DELETE request to server.
+         * @param {String} url
+         * @param {Boolean} global
+         * @param {String} contentType
+         * @returns {Deferred}
+         */
+        delete: function(url, global, contentType) {
+            global = global === undefined ? true : global;
+            contentType = contentType || 'application/json';
+
+            return $.ajax({
+                url: urlBuilder.build(url),
+                type: 'DELETE',
+                global: global,
                 contentType: contentType
             });
         }