diff --git a/.php_cs b/.php_cs
index 8381e44cf08ffb15328333db20f5d3a9b69386dc..7f5e43f9d4f01ec44cadc22650a8bd5b3c19c154 100644
--- a/.php_cs
+++ b/.php_cs
@@ -17,7 +17,6 @@ $finder = Symfony\CS\Finder\DefaultFinder::create()
     ->exclude('dev/tests/integration/var')
     ->exclude('lib/internal/Cm')
     ->exclude('lib/internal/Credis')
-    ->exclude('lib/internal/JSMin')
     ->exclude('lib/internal/Less')
     ->exclude('lib/internal/LinLibertineFont')
     ->exclude('lib/internal/phpseclib')
diff --git a/Gruntfile.js b/Gruntfile.js
index 8dcee340ef46cdd59a9631a3d77b2155c0802e6c..5f401a8c6fe4a47dd835531195a94fbb201cf597 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -15,6 +15,9 @@ module.exports = function (grunt) {
     [
         taskDir + '/mage-minify',
         taskDir + '/deploy',
+        taskDir + '/black-list-generator',
+        taskDir + '/clean-black-list',
+        taskDir + '/static',
         'time-grunt'
     ].forEach(function (task) {
         require(task)(grunt);
diff --git a/app/code/Magento/Authorizenet/Helper/Backend/Data.php b/app/code/Magento/Authorizenet/Helper/Backend/Data.php
index 1adfc4a25d95a72f07d5ccd7f2342357d98dad09..7489262c0dcd6b504cd054760182203510302df6 100644
--- a/app/code/Magento/Authorizenet/Helper/Backend/Data.php
+++ b/app/code/Magento/Authorizenet/Helper/Backend/Data.php
@@ -28,8 +28,8 @@ class Data extends FrontendDataHelper
         OrderFactory $orderFactory,
         UrlInterface $backendUrl
     ) {
-        $this->_urlBuilder = $backendUrl;
         parent::__construct($context, $storeManager, $orderFactory);
+        $this->_urlBuilder = $backendUrl;
     }
 
     /**
@@ -85,6 +85,8 @@ class Data extends FrontendDataHelper
      *
      * @param null|int|string $storeId
      * @return string
+     * 
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function getRelayUrl($storeId = null)
     {
diff --git a/app/code/Magento/Authorizenet/view/adminhtml/web/js/direct-post.js b/app/code/Magento/Authorizenet/view/adminhtml/web/js/direct-post.js
index d6423db943e1eb5ad55bae6d7a3c61a8d27a6987..79c2a13c8451c8380f2096c79b1374bfe8b651d0 100644
--- a/app/code/Magento/Authorizenet/view/adminhtml/web/js/direct-post.js
+++ b/app/code/Magento/Authorizenet/view/adminhtml/web/js/direct-post.js
@@ -32,13 +32,11 @@ directPost.prototype = {
         this.headers = [];
         this.isValid = true;
         this.paymentRequestSent = false;
-        this.isResponse = false;
         this.orderIncrementId = false;
         this.successUrl = false;
         this.hasError = false;
         this.tmpForm = false;
 
-        this.onSaveOnepageOrderSuccess = this.saveOnepageOrderSuccess.bindAsEventListener(this);
         this.onLoadIframe = this.loadIframe.bindAsEventListener(this);
         this.onLoadOrderIframe = this.loadOrderIframe.bindAsEventListener(this);
         this.onSubmitAdminOrder = this.submitAdminOrder.bindAsEventListener(this);
@@ -80,63 +78,30 @@ directPost.prototype = {
             .off('submitOrder')
             .on('submitOrder', this.submitAdminOrder.bind(this));
         if ($(this.iframeId)) {
-            switch (this.controller) {
-                case 'onepage':
-                    this.headers = $$('#' + checkout.accordion.container.readAttribute('id') + ' .section');
-                    var button = $('review-buttons-container').down('button');
-                    button.writeAttribute('onclick', '');
-                    button.stopObserving('click');
-                    button.observe('click', function() {
-                        if ($(this.iframeId)) {
-                            if (this.validate()) {
-                                this.saveOnepageOrder();
-                            }
-                        } else {
-                            review.save();
-                        }
-                    }.bind(this));
-                    break;
-                case 'order_create':
-                case 'order_edit':
-                    // Temporary solution will be removed after refactoring Authorize.Net (sales) functionality
-                    jQuery('.scalable.save:not(disabled)').removeAttr('onclick');
-                    jQuery(document).off('click.directPost');
-                    jQuery(document).on(
-                        'click.directPost',
-                        '.scalable.save:not(disabled)',
-                        jQuery.proxy(this.onSubmitAdminOrder, this)
-                    );
-
-                    $('order-' + this.iframeId).observe('load', this.onLoadOrderIframe);
-                    break;
-            }
-
+            // Temporary solution will be removed after refactoring Authorize.Net (sales) functionality
+            jQuery('.scalable.save:not(disabled)').removeAttr('onclick');
+            jQuery(document).off('click.directPost');
+            jQuery(document).on(
+                'click.directPost',
+                '.scalable.save:not(disabled)',
+                jQuery.proxy(this.onSubmitAdminOrder, this)
+            );
+            $('order-' + this.iframeId).observe('load', this.onLoadOrderIframe);
             $(this.iframeId).observe('load', this.onLoadIframe);
         }
     },
 
     loadIframe : function() {
         if (this.paymentRequestSent) {
-            switch (this.controller) {
-                case 'onepage':
-                    this.paymentRequestSent = false;
-                    if (!this.hasError) {
-                        this.returnQuote();
-                    }
-                    break;
-                case 'order_edit':
-                case 'order_create':
-                    if (!this.orderRequestSent) {
-                        this.paymentRequestSent = false;
-                        if (!this.hasError) {
-                            this.returnQuote();
-                        } else {
-                            this.changeInputOptions('disabled', false);
-                            jQuery('body').trigger('processStop');
-                            enableElements('save');
-                        }
-                    }
-                    break;
+            if (!this.orderRequestSent) {
+                this.paymentRequestSent = false;
+                if (!this.hasError) {
+                    this.returnQuote();
+                } else {
+                    this.changeInputOptions('disabled', false);
+                    jQuery('body').trigger('processStop');
+                    enableElements('save');
+                }
             }
             if (this.tmpForm) {
                 document.body.removeChild(this.tmpForm);
@@ -167,7 +132,7 @@ directPost.prototype = {
         new Ajax.Request(url, {
             onSuccess : function(transport) {
                 try {
-                    response = eval('(' + transport.responseText + ')');
+                    response = transport.responseText.evalJSON(true);
                 } catch (e) {
                     response = {};
                 }
@@ -175,17 +140,9 @@ directPost.prototype = {
                     alert(response.error_message);
                 }
                 $(this.iframeId).show();
-                switch (this.controller) {
-                    case 'onepage':
-                        this.resetLoadWaiting();
-                        break;
-                    case 'order_edit':
-                    case 'order_create':
-                        this.changeInputOptions('disabled', false);
-                        jQuery('body').trigger('processStop');
-                        enableElements('save');
-                        break;
-                }
+                this.changeInputOptions('disabled', false);
+                jQuery('body').trigger('processStop');
+                enableElements('save');
             }.bind(this)
         });
     },
@@ -204,66 +161,6 @@ directPost.prototype = {
         checkout.setLoadWaiting(false);
     },
 
-    saveOnepageOrder : function() {
-        this.hasError = false;
-        this.setLoadWaiting();
-        var params = Form.serialize(payment.form);
-        if (review.agreementsForm) {
-            params += '&' + Form.serialize(review.agreementsForm);
-        }
-        params += '&controller=' + this.controller;
-        new Ajax.Request(this.orderSaveUrl, {
-            method : 'post',
-            parameters : params,
-            onComplete : this.onSaveOnepageOrderSuccess,
-            onFailure : function(transport) {
-                this.resetLoadWaiting();
-                if (transport.status == 403) {
-                    checkout.ajaxFailure();
-                }
-            }
-        });
-    },
-
-    saveOnepageOrderSuccess : function(transport) {
-        if (transport.status == 403) {
-            checkout.ajaxFailure();
-        }
-        try {
-            response = eval('(' + transport.responseText + ')');
-        } catch (e) {
-            response = {};
-        }
-
-        if (response.success && response.directpost) {
-            this.orderIncrementId = response.directpost.fields.x_invoice_num;
-            var paymentData = {};
-            for ( var key in response.directpost.fields) {
-                paymentData[key] = response.directpost.fields[key];
-            }
-            var preparedData = this.preparePaymentRequest(paymentData);
-            this.sendPaymentRequest(preparedData);
-        } else {
-            var msg = response.error_messages;
-            if (typeof (msg) == 'object') {
-                msg = msg.join("\n");
-            }
-            if (msg) {
-                alert(msg);
-            }
-
-            if (response.update_section) {
-                $('checkout-' + response.update_section.name + '-load').replace(response.update_section.html);
-                response.update_section.html.evalScripts();
-            }
-
-            if (response.goto_section) {
-                checkout.gotoSection(response.goto_section);
-                checkout.reloadProgressBlock();
-            }
-        }
-    },
-
     submitAdminOrder : function() {
         // Temporary solution will be removed after refactoring Authorize.Net (sales) functionality
         var editForm = jQuery('#edit_form');
@@ -324,7 +221,7 @@ directPost.prototype = {
 
     saveAdminOrderSuccess : function(data) {
         try {
-            response = eval('(' + data + ')');
+            response = data.evalJSON(true);
         } catch (e) {
             response = {};
         }
@@ -423,4 +320,4 @@ directPost.prototype = {
         }
     }
 };
-}));
\ No newline at end of file
+}));
diff --git a/app/code/Magento/Backend/Block/Cache/Additional.php b/app/code/Magento/Backend/Block/Cache/Additional.php
index f1aed57660825553a4259fa6eef6f550245c58f5..99574ad958397d53228d7c37f6b40dcfacf85df8 100644
--- a/app/code/Magento/Backend/Block/Cache/Additional.php
+++ b/app/code/Magento/Backend/Block/Cache/Additional.php
@@ -7,6 +7,16 @@ namespace Magento\Backend\Block\Cache;
 
 class Additional extends \Magento\Backend\Block\Template
 {
+    /**
+     * Check if application is in production mode
+     *
+     * @return bool
+     */
+    public function isInProductionMode()
+    {
+        return $this->_appState->getMode() === \Magento\Framework\App\State::MODE_PRODUCTION;
+    }
+
     /**
      * @return string
      */
@@ -22,4 +32,12 @@ class Additional extends \Magento\Backend\Block\Template
     {
         return $this->getUrl('*/*/cleanMedia');
     }
+
+    /**
+     * @return string
+     */
+    public function getCleanStaticFilesUrl()
+    {
+        return $this->getUrl('*/*/cleanStaticFiles');
+    }
 }
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Cache/CleanStaticFiles.php b/app/code/Magento/Backend/Controller/Adminhtml/Cache/CleanStaticFiles.php
new file mode 100644
index 0000000000000000000000000000000000000000..4ca025b3ec57fabc68dfa4814de74f68afc38608
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Cache/CleanStaticFiles.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Backend\Controller\Adminhtml\Cache;
+
+use Magento\Framework\Controller\ResultFactory;
+
+class CleanStaticFiles extends \Magento\Backend\Controller\Adminhtml\Cache
+{
+    /**
+     * Clean static files cache
+     *
+     * @return \Magento\Backend\Model\View\Result\Redirect
+     */
+    public function execute()
+    {
+        $this->_objectManager->get('Magento\Framework\App\State\CleanupFiles')->clearMaterializedViewFiles();
+        $this->_eventManager->dispatch('clean_static_files_cache_after');
+        $this->messageManager->addSuccess(__('The static files cache has been cleaned.'));
+
+        /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
+        return $resultRedirect->setPath('adminhtml/*');
+    }
+}
diff --git a/app/code/Magento/Backend/Setup/ConfigOptionsList.php b/app/code/Magento/Backend/Setup/ConfigOptionsList.php
index 2a6a39f88af73d7b2680d985971310ebe5115e9d..78ec4523435fd1e57b2e7e01d4baeb2f24fc64a8 100644
--- a/app/code/Magento/Backend/Setup/ConfigOptionsList.php
+++ b/app/code/Magento/Backend/Setup/ConfigOptionsList.php
@@ -10,6 +10,7 @@ use Magento\Framework\Config\File\ConfigFilePool;
 use Magento\Framework\Setup\ConfigOptionsListInterface;
 use Magento\Framework\Setup\Option\TextConfigOption;
 use Magento\Framework\App\DeploymentConfig;
+use \Magento\Framework\Setup\BackendFrontnameGenerator;
 
 /*
  * Deployment configuration options needed for Backend module
@@ -36,8 +37,7 @@ class ConfigOptionsList implements ConfigOptionsListInterface
                 self::INPUT_KEY_BACKEND_FRONTNAME,
                 TextConfigOption::FRONTEND_WIZARD_TEXT,
                 self::CONFIG_PATH_BACKEND_FRONTNAME,
-                'Backend frontname',
-                'admin'
+                'Backend frontname (will be autogenerated if missing)'
             )
         ];
     }
@@ -50,6 +50,10 @@ class ConfigOptionsList implements ConfigOptionsListInterface
     {
         $configData = new ConfigData(ConfigFilePool::APP_ENV);
 
+        if (!$deploymentConfig->get(self::CONFIG_PATH_BACKEND_FRONTNAME)
+            && !isset($options[self::INPUT_KEY_BACKEND_FRONTNAME])) {
+            $options[self::INPUT_KEY_BACKEND_FRONTNAME] = BackendFrontnameGenerator::generate();
+        }
         if (isset($options[self::INPUT_KEY_BACKEND_FRONTNAME])) {
             $configData->set(self::CONFIG_PATH_BACKEND_FRONTNAME, $options[self::INPUT_KEY_BACKEND_FRONTNAME]);
         }
diff --git a/app/code/Magento/Backend/Test/Unit/Block/Cache/AdditionalTest.php b/app/code/Magento/Backend/Test/Unit/Block/Cache/AdditionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..db0e91b0dd8f3adeedd8eb6f535e02ae6aec1736
--- /dev/null
+++ b/app/code/Magento/Backend/Test/Unit/Block/Cache/AdditionalTest.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Backend\Test\Unit\Block\Cache;
+
+class AdditionalTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Backend\Block\Cache\Additional
+     */
+    private $additonalBlock;
+
+    /**
+     * @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlBuilderMock;
+
+    /**
+     * @var \Magento\Framework\App\State | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $appStateMock;
+
+    protected function setUp()
+    {
+        $this->urlBuilderMock = $this->getMock('Magento\Framework\UrlInterface');
+        $this->appStateMock = $this->getMockBuilder('Magento\Framework\App\State')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $objectHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $context = $objectHelper->getObject(
+            'Magento\Backend\Block\Template\Context',
+            [
+                'urlBuilder' => $this->urlBuilderMock,
+                'appState' => $this->appStateMock,
+            ]
+        );
+
+        $this->additonalBlock = $objectHelper->getObject(
+            'Magento\Backend\Block\Cache\Additional',
+            ['context' => $context]
+        );
+    }
+
+    public function testGetCleanImagesUrl()
+    {
+        $expectedUrl = 'cleanImagesUrl';
+        $this->urlBuilderMock->expects($this->once())
+            ->method('getUrl')
+            ->with('*/*/cleanImages')
+            ->will($this->returnValue($expectedUrl));
+        $this->assertEquals($expectedUrl, $this->additonalBlock->getCleanImagesUrl());
+    }
+
+    public function testGetCleanMediaUrl()
+    {
+        $expectedUrl = 'cleanMediaUrl';
+        $this->urlBuilderMock->expects($this->once())
+            ->method('getUrl')
+            ->with('*/*/cleanMedia')
+            ->will($this->returnValue($expectedUrl));
+        $this->assertEquals($expectedUrl, $this->additonalBlock->getCleanMediaUrl());
+    }
+
+    public function testGetCleanStaticFiles()
+    {
+        $expectedUrl = 'cleanStaticFilesUrl';
+        $this->urlBuilderMock->expects($this->once())
+            ->method('getUrl')
+            ->with('*/*/cleanStaticFiles')
+            ->will($this->returnValue($expectedUrl));
+        $this->assertEquals($expectedUrl, $this->additonalBlock->getCleanStaticFilesUrl());
+    }
+
+    /**
+     * @param string $mode
+     * @param bool $expected
+     * @dataProvider isInProductionModeDataProvider
+     */
+    public function testIsInProductionMode($mode, $expected)
+    {
+        $this->appStateMock->expects($this->once())
+            ->method('getMode')
+            ->willReturn($mode);
+        $this->assertEquals($expected, $this->additonalBlock->isInProductionMode());
+    }
+
+    public function isInProductionModeDataProvider()
+    {
+        return [
+            [\Magento\Framework\App\State::MODE_DEFAULT, false],
+            [\Magento\Framework\App\State::MODE_DEVELOPER, false],
+            [\Magento\Framework\App\State::MODE_PRODUCTION, true],
+        ];
+    }
+}
diff --git a/app/code/Magento/Backend/Test/Unit/Controller/Adminhtml/Cache/CleanStaticFilesTest.php b/app/code/Magento/Backend/Test/Unit/Controller/Adminhtml/Cache/CleanStaticFilesTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0e78f533c85256eb48534c6ac877a4c31fd7e967
--- /dev/null
+++ b/app/code/Magento/Backend/Test/Unit/Controller/Adminhtml/Cache/CleanStaticFilesTest.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+// @codingStandardsIgnoreFile
+
+namespace Magento\Backend\Test\Unit\Controller\Adminhtml\Cache;
+
+class CleanStaticFilesTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $objectManagerMock;
+
+    /**
+     * @var  \Magento\Framework\Event\ManagerInterface | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $eventManagerMock;
+
+    /**
+     * @var \Magento\Framework\Message\ManagerInterface | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $messageManagerMock;
+
+    /**
+     * @var \Magento\Framework\Controller\ResultFactory | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $resultFactoryMock;
+
+    /**
+     * @var \Magento\Backend\Controller\Adminhtml\Cache\CleanStaticFiles
+     */
+    private $controller;
+
+    protected function setUp()
+    {
+        $this->objectManagerMock = $this->getMock('Magento\Framework\ObjectManagerInterface');
+        $this->eventManagerMock = $this->getMockBuilder('Magento\Framework\Event\ManagerInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->messageManagerMock = $this->getMockBuilder('Magento\Framework\Message\ManagerInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultFactoryMock = $this->getMockBuilder('Magento\Framework\Controller\ResultFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $objectHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $context = $objectHelper->getObject(
+            '\Magento\Backend\App\Action\Context',
+            [
+                'objectManager' => $this->objectManagerMock,
+                'eventManager' => $this->eventManagerMock,
+                'messageManager' => $this->messageManagerMock,
+                'resultFactory' => $this->resultFactoryMock,
+            ]
+        );
+
+        $this->controller = $objectHelper->getObject(
+            'Magento\Backend\Controller\Adminhtml\Cache\CleanStaticFiles',
+            ['context' => $context,]
+        );
+    }
+
+    public function testExecute()
+    {
+        $cleanupFilesMock = $this->getMockBuilder('Magento\Framework\App\State\CleanupFiles')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $cleanupFilesMock->expects($this->once())
+            ->method('clearMaterializedViewFiles');
+        $this->objectManagerMock->expects($this->once())->method('get')->will($this->returnValue($cleanupFilesMock));
+
+        $this->eventManagerMock->expects($this->once())
+            ->method('dispatch')
+            ->with('clean_static_files_cache_after');
+
+        $this->messageManagerMock->expects($this->once())
+            ->method('addSuccess')
+            ->with('The static files cache has been cleaned.');
+
+        $resultRedirect = $this->getMockBuilder('Magento\Backend\Model\View\Result\Redirect')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultFactoryMock->expects($this->atLeastOnce())
+            ->method('create')
+            ->with(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT)
+            ->willReturn($resultRedirect);
+        $resultRedirect->expects($this->once())
+            ->method('setPath')
+            ->with('adminhtml/*')
+            ->willReturnSelf();
+
+        // Run
+        $this->controller->execute();
+    }
+}
diff --git a/app/code/Magento/Backend/i18n/de_DE.csv b/app/code/Magento/Backend/i18n/de_DE.csv
index fddd1a2eba777c7ab248f5fd11993536cf260914..8bd82b41c2050a73b6cefcad5a4a53a280627769 100644
--- a/app/code/Magento/Backend/i18n/de_DE.csv
+++ b/app/code/Magento/Backend/i18n/de_DE.csv
@@ -412,6 +412,8 @@ Scope:,Scope:
 "Pregenerated product images files","Pregenerated product images files"
 "Flush JavaScript/CSS Cache","Flush JavaScript/CSS Cache"
 "Themes JavaScript and CSS files combined to one file.","Themes JavaScript and CSS files combined to one file."
+"Flush Static Files Cache", "Flush Static Files Cache"
+"Preprocessed view files and static files", "Preprocessed view files and static files"
 Catalog,Catalog
 JavaScript/CSS,JavaScript/CSS
 "JavaScript/CSS Cache","JavaScript/CSS Cache"
diff --git a/app/code/Magento/Backend/i18n/en_US.csv b/app/code/Magento/Backend/i18n/en_US.csv
index fddd1a2eba777c7ab248f5fd11993536cf260914..8bd82b41c2050a73b6cefcad5a4a53a280627769 100644
--- a/app/code/Magento/Backend/i18n/en_US.csv
+++ b/app/code/Magento/Backend/i18n/en_US.csv
@@ -412,6 +412,8 @@ Scope:,Scope:
 "Pregenerated product images files","Pregenerated product images files"
 "Flush JavaScript/CSS Cache","Flush JavaScript/CSS Cache"
 "Themes JavaScript and CSS files combined to one file.","Themes JavaScript and CSS files combined to one file."
+"Flush Static Files Cache", "Flush Static Files Cache"
+"Preprocessed view files and static files", "Preprocessed view files and static files"
 Catalog,Catalog
 JavaScript/CSS,JavaScript/CSS
 "JavaScript/CSS Cache","JavaScript/CSS Cache"
diff --git a/app/code/Magento/Backend/i18n/es_ES.csv b/app/code/Magento/Backend/i18n/es_ES.csv
index fddd1a2eba777c7ab248f5fd11993536cf260914..8bd82b41c2050a73b6cefcad5a4a53a280627769 100644
--- a/app/code/Magento/Backend/i18n/es_ES.csv
+++ b/app/code/Magento/Backend/i18n/es_ES.csv
@@ -412,6 +412,8 @@ Scope:,Scope:
 "Pregenerated product images files","Pregenerated product images files"
 "Flush JavaScript/CSS Cache","Flush JavaScript/CSS Cache"
 "Themes JavaScript and CSS files combined to one file.","Themes JavaScript and CSS files combined to one file."
+"Flush Static Files Cache", "Flush Static Files Cache"
+"Preprocessed view files and static files", "Preprocessed view files and static files"
 Catalog,Catalog
 JavaScript/CSS,JavaScript/CSS
 "JavaScript/CSS Cache","JavaScript/CSS Cache"
diff --git a/app/code/Magento/Backend/i18n/fr_FR.csv b/app/code/Magento/Backend/i18n/fr_FR.csv
index fddd1a2eba777c7ab248f5fd11993536cf260914..8bd82b41c2050a73b6cefcad5a4a53a280627769 100644
--- a/app/code/Magento/Backend/i18n/fr_FR.csv
+++ b/app/code/Magento/Backend/i18n/fr_FR.csv
@@ -412,6 +412,8 @@ Scope:,Scope:
 "Pregenerated product images files","Pregenerated product images files"
 "Flush JavaScript/CSS Cache","Flush JavaScript/CSS Cache"
 "Themes JavaScript and CSS files combined to one file.","Themes JavaScript and CSS files combined to one file."
+"Flush Static Files Cache", "Flush Static Files Cache"
+"Preprocessed view files and static files", "Preprocessed view files and static files"
 Catalog,Catalog
 JavaScript/CSS,JavaScript/CSS
 "JavaScript/CSS Cache","JavaScript/CSS Cache"
diff --git a/app/code/Magento/Backend/i18n/nl_NL.csv b/app/code/Magento/Backend/i18n/nl_NL.csv
index fddd1a2eba777c7ab248f5fd11993536cf260914..8bd82b41c2050a73b6cefcad5a4a53a280627769 100644
--- a/app/code/Magento/Backend/i18n/nl_NL.csv
+++ b/app/code/Magento/Backend/i18n/nl_NL.csv
@@ -412,6 +412,8 @@ Scope:,Scope:
 "Pregenerated product images files","Pregenerated product images files"
 "Flush JavaScript/CSS Cache","Flush JavaScript/CSS Cache"
 "Themes JavaScript and CSS files combined to one file.","Themes JavaScript and CSS files combined to one file."
+"Flush Static Files Cache", "Flush Static Files Cache"
+"Preprocessed view files and static files", "Preprocessed view files and static files"
 Catalog,Catalog
 JavaScript/CSS,JavaScript/CSS
 "JavaScript/CSS Cache","JavaScript/CSS Cache"
diff --git a/app/code/Magento/Backend/i18n/pt_BR.csv b/app/code/Magento/Backend/i18n/pt_BR.csv
index fddd1a2eba777c7ab248f5fd11993536cf260914..8bd82b41c2050a73b6cefcad5a4a53a280627769 100644
--- a/app/code/Magento/Backend/i18n/pt_BR.csv
+++ b/app/code/Magento/Backend/i18n/pt_BR.csv
@@ -412,6 +412,8 @@ Scope:,Scope:
 "Pregenerated product images files","Pregenerated product images files"
 "Flush JavaScript/CSS Cache","Flush JavaScript/CSS Cache"
 "Themes JavaScript and CSS files combined to one file.","Themes JavaScript and CSS files combined to one file."
+"Flush Static Files Cache", "Flush Static Files Cache"
+"Preprocessed view files and static files", "Preprocessed view files and static files"
 Catalog,Catalog
 JavaScript/CSS,JavaScript/CSS
 "JavaScript/CSS Cache","JavaScript/CSS Cache"
diff --git a/app/code/Magento/Backend/i18n/zh_CN.csv b/app/code/Magento/Backend/i18n/zh_CN.csv
index fddd1a2eba777c7ab248f5fd11993536cf260914..8bd82b41c2050a73b6cefcad5a4a53a280627769 100644
--- a/app/code/Magento/Backend/i18n/zh_CN.csv
+++ b/app/code/Magento/Backend/i18n/zh_CN.csv
@@ -412,6 +412,8 @@ Scope:,Scope:
 "Pregenerated product images files","Pregenerated product images files"
 "Flush JavaScript/CSS Cache","Flush JavaScript/CSS Cache"
 "Themes JavaScript and CSS files combined to one file.","Themes JavaScript and CSS files combined to one file."
+"Flush Static Files Cache", "Flush Static Files Cache"
+"Preprocessed view files and static files", "Preprocessed view files and static files"
 Catalog,Catalog
 JavaScript/CSS,JavaScript/CSS
 "JavaScript/CSS Cache","JavaScript/CSS Cache"
diff --git a/app/code/Magento/Backend/view/adminhtml/templates/system/cache/additional.phtml b/app/code/Magento/Backend/view/adminhtml/templates/system/cache/additional.phtml
index aa96f3db654c6b51e47cab7e548863de89be76d0..06eeedd275a76a1488c107d444d54287f1ed5f17 100644
--- a/app/code/Magento/Backend/view/adminhtml/templates/system/cache/additional.phtml
+++ b/app/code/Magento/Backend/view/adminhtml/templates/system/cache/additional.phtml
@@ -9,16 +9,28 @@
         <span><?php echo __('Additional Cache Management') ?></span>
     </div>
     <div class="field">
-        <button onclick="setLocation('<?php echo $block->getCleanImagesUrl()?>')" type="button">
+        <button onclick="setLocation('<?php echo $block->getCleanImagesUrl() ?>')" type="button">
             <?php echo __('Flush Catalog Images Cache') ?>
         </button>
-        <label class="label"><?php echo __('Pregenerated product images files')?></label>
+        <label class="label"><?php echo __('Pregenerated product images files') ?></label>
     </div>
     <div class="field">
-        <button onclick="setLocation('<?php echo $block->getCleanMediaUrl()?>')" type="button">
+        <button onclick="setLocation('<?php echo $block->getCleanMediaUrl() ?>')" type="button">
             <?php echo __('Flush JavaScript/CSS Cache') ?>
         </button>
-        <label class="label"><?php echo __('Themes JavaScript and CSS files combined to one file.')?></label>
+        <label class="label"><?php echo __('Themes JavaScript and CSS files combined to one file.') ?></label>
     </div>
+    <?php
+    if (!$block->isInProductionMode()):
+        ?>
+        <div class="field">
+            <button onclick="setLocation('<?php echo $block->getCleanStaticFilesUrl() ?>')" type="button">
+                <?php echo __('Flush Static Files Cache') ?>
+            </button>
+            <label class="label"><?php echo __('Preprocessed view files and static files') ?></label>
+        </div>
+    <?php
+    endif;
+    ?>
     <?php echo $block->getChildHtml(); ?>
 </div>
diff --git a/app/code/Magento/Checkout/Block/Onepage/Success.php b/app/code/Magento/Checkout/Block/Onepage/Success.php
index 46f85df2019ef53debf6b5583bffb9c7c264e6b0..5884c8f945a8bf12c68000fa10a195db1283a3f7 100644
--- a/app/code/Magento/Checkout/Block/Onepage/Success.php
+++ b/app/code/Magento/Checkout/Block/Onepage/Success.php
@@ -6,6 +6,7 @@
 namespace Magento\Checkout\Block\Onepage;
 
 use Magento\Customer\Model\Context;
+use Magento\Sales\Model\Order;
 
 /**
  * One page checkout success page
@@ -17,16 +18,6 @@ class Success extends \Magento\Framework\View\Element\Template
      */
     protected $_checkoutSession;
 
-    /**
-     * @var \Magento\Customer\Model\Session
-     */
-    protected $_customerSession;
-
-    /**
-     * @var \Magento\Sales\Model\OrderFactory
-     */
-    protected $_orderFactory;
-
     /**
      * @var \Magento\Sales\Model\Order\Config
      */
@@ -40,8 +31,6 @@ class Success extends \Magento\Framework\View\Element\Template
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
      * @param \Magento\Checkout\Model\Session $checkoutSession
-     * @param \Magento\Customer\Model\Session $customerSession
-     * @param \Magento\Sales\Model\OrderFactory $orderFactory
      * @param \Magento\Sales\Model\Order\Config $orderConfig
      * @param \Magento\Framework\App\Http\Context $httpContext
      * @param array $data
@@ -49,31 +38,17 @@ class Success extends \Magento\Framework\View\Element\Template
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
         \Magento\Checkout\Model\Session $checkoutSession,
-        \Magento\Customer\Model\Session $customerSession,
-        \Magento\Sales\Model\OrderFactory $orderFactory,
         \Magento\Sales\Model\Order\Config $orderConfig,
         \Magento\Framework\App\Http\Context $httpContext,
         array $data = []
     ) {
         parent::__construct($context, $data);
         $this->_checkoutSession = $checkoutSession;
-        $this->_customerSession = $customerSession;
-        $this->_orderFactory = $orderFactory;
         $this->_orderConfig = $orderConfig;
         $this->_isScopePrivate = true;
         $this->httpContext = $httpContext;
     }
 
-    /**
-     * See if the order has state, visible on frontend
-     *
-     * @return bool
-     */
-    public function isOrderVisible()
-    {
-        return (bool)$this->_getData('is_order_visible');
-    }
-
     /**
      * Render additional order information lines and return result html
      *
@@ -91,35 +66,60 @@ class Success extends \Magento\Framework\View\Element\Template
      */
     protected function _beforeToHtml()
     {
-        $this->_prepareLastOrder();
+        $this->prepareBlockData();
         return parent::_beforeToHtml();
     }
 
     /**
-     * Get last order ID from session, fetch it and check whether it can be viewed, printed etc
+     * Prepares block data
      *
      * @return void
      */
-    protected function _prepareLastOrder()
+    protected function prepareBlockData()
+    {
+        $order = $this->_checkoutSession->getLastRealOrder();
+
+        $this->addData(
+            [
+                'is_order_visible' => $this->isVisible($order),
+                'view_order_url' => $this->getUrl(
+                    'sales/order/view/',
+                    ['order_id' => $order->getEntityId()]
+                ),
+                'print_url' => $this->getUrl(
+                    'sales/order/print',
+                    ['order_id' => $order->getEntityId()]
+                ),
+                'can_print_order' => $this->isVisible($order),
+                'can_view_order'  => $this->canViewOrder($order),
+                'order_id'  => $order->getIncrementId()
+            ]
+        );
+    }
+
+    /**
+     * Is order visible
+     *
+     * @param Order $order
+     * @return bool
+     */
+    protected function isVisible(Order $order)
+    {
+        return !in_array(
+            $order->getStatus(),
+            $this->_orderConfig->getInvisibleOnFrontStatuses()
+        );
+    }
+
+    /**
+     * Can view order
+     *
+     * @param Order $order
+     * @return bool
+     */
+    protected function canViewOrder(Order $order)
     {
-        $orderId = $this->_checkoutSession->getLastOrderId();
-        if ($orderId) {
-            $incrementId = $this->_checkoutSession->getLastRealOrderId();
-            $status = $this->_checkoutSession->getLastOrderStatus();
-            if ($status && $incrementId) {
-                $isVisible = !in_array($status, $this->_orderConfig->getInvisibleOnFrontStatuses());
-                $canView = $this->httpContext->getValue(Context::CONTEXT_AUTH) && $isVisible;
-                $this->addData(
-                    [
-                        'is_order_visible' => $isVisible,
-                        'view_order_url' => $this->getUrl('sales/order/view/', ['order_id' => $orderId]),
-                        'print_url' => $this->getUrl('sales/order/print', ['order_id' => $orderId]),
-                        'can_print_order' => $isVisible,
-                        'can_view_order'  => $canView,
-                        'order_id'  => $incrementId,
-                    ]
-                );
-            }
-        }
+        return $this->httpContext->getValue(Context::CONTEXT_AUTH)
+            && $this->isVisible($order);
     }
 }
diff --git a/app/code/Magento/Checkout/Test/Unit/Block/Onepage/SuccessTest.php b/app/code/Magento/Checkout/Test/Unit/Block/Onepage/SuccessTest.php
index 54c8fee91f2c411fd470716906dc89087d403914..5d0c643d450d6cf7d64f566f4317ad35a1ec1a36 100644
--- a/app/code/Magento/Checkout/Test/Unit/Block/Onepage/SuccessTest.php
+++ b/app/code/Magento/Checkout/Test/Unit/Block/Onepage/SuccessTest.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Checkout\Test\Unit\Block\Onepage;
 
+use Magento\Sales\Model\Order;
+
 /**
  * Class SuccessTest
  * @package Magento\Checkout\Block\Onepage
@@ -32,13 +34,11 @@ class SuccessTest extends \PHPUnit_Framework_TestCase
 
         $this->orderConfig = $this->getMock('Magento\Sales\Model\Order\Config', [], [], '', false);
 
-        $this->checkoutSession = $this->getMock(
-            'Magento\Checkout\Model\Session',
-            ['getLastOrderId', 'getLastRealOrderId', 'getLastOrderStatus'],
-            [],
-            '',
-            false
-        );
+        $this->checkoutSession = $this->getMockBuilder(
+            'Magento\Checkout\Model\Session'
+        )
+            ->disableOriginalConstructor()
+            ->getMock();
 
         $this->block = $objectManager->getObject(
             'Magento\Checkout\Block\Onepage\Success',
@@ -67,28 +67,36 @@ class SuccessTest extends \PHPUnit_Framework_TestCase
 
     /**
      * @dataProvider invisibleStatusesProvider
+     *
      * @param array $invisibleStatuses
-     * @param string $orderStatus
      * @param bool $expectedResult
      */
-    public function testToHtmlOrderVisibleOnFront(array $invisibleStatuses, $orderStatus, $expectedResult)
+    public function testToHtmlOrderVisibleOnFront(array $invisibleStatuses, $expectedResult)
     {
         $orderId = 5;
         $realOrderId = 100003332;
+        $status = Order::STATE_PENDING_PAYMENT;
+
+        $order = $this->getMockBuilder('Magento\Sales\Model\Order')
+            ->disableOriginalConstructor()
+            ->getMock();
 
         $this->checkoutSession->expects($this->once())
-            ->method('getLastOrderId')
-            ->will($this->returnValue($orderId));
-        $this->checkoutSession->expects($this->once())
-            ->method('getLastRealOrderId')
-            ->will($this->returnValue($realOrderId));
-        $this->checkoutSession->expects($this->once())
-            ->method('getLastOrderStatus')
-            ->will($this->returnValue($orderStatus));
+            ->method('getLastRealOrder')
+            ->willReturn($order);
+        $order->expects($this->atLeastOnce())
+            ->method('getEntityId')
+            ->willReturn($orderId);
+        $order->expects($this->atLeastOnce())
+            ->method('getIncrementId')
+            ->willReturn($realOrderId);
+        $order->expects($this->atLeastOnce())
+            ->method('getStatus')
+            ->willReturn($status);
 
         $this->orderConfig->expects($this->any())
             ->method('getInvisibleOnFrontStatuses')
-            ->will($this->returnValue($invisibleStatuses));
+            ->willReturn($invisibleStatuses);
 
         $this->block->toHtml();
 
@@ -98,8 +106,8 @@ class SuccessTest extends \PHPUnit_Framework_TestCase
     public function invisibleStatusesProvider()
     {
         return [
-            [['status1', 'status2'], 'status1', false],
-            [['status1', 'status2'], 'status3', true]
+            [[Order::STATE_PENDING_PAYMENT, 'status2'],  false],
+            [['status1', 'status2'], true]
         ];
     }
 }
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
index 7b679f3799b38a47b07585c1e46d16323f580948..d5de7247ff4d56027db27c20cd8ce1b628c7d854 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js
@@ -209,6 +209,10 @@ define(
                     emailValidationResult = Boolean($(loginFormSelector + ' input[name=username]').valid());
                 }
 
+                if (!emailValidationResult) {
+                    $(loginFormSelector + ' input[name=username]').focus();
+                }
+
                 if (this.isFormInline) {
                     this.source.set('params.invalid', false);
                     this.source.trigger('shippingAddress.data.validate');
diff --git a/app/code/Magento/Config/Block/System/Config/Form/Field/Datetime.php b/app/code/Magento/Config/Block/System/Config/Form/Field/Datetime.php
index f6339dd68cd3149f38822875e82c25bcc15988e8..342a7307d4b647724745ca9d37ccae30bfb2432c 100644
--- a/app/code/Magento/Config/Block/System/Config/Form/Field/Datetime.php
+++ b/app/code/Magento/Config/Block/System/Config/Form/Field/Datetime.php
@@ -15,6 +15,7 @@ class Datetime extends \Magento\Config\Block\System\Config\Form\Field
     /**
      * @param AbstractElement $element
      * @return string
+     * @codeCoverageIgnore
      */
     protected function _getElementHtml(AbstractElement $element)
     {
diff --git a/app/code/Magento/Developer/Model/View/Asset/PreProcessor/DeveloperChain.php b/app/code/Magento/Developer/Model/View/Asset/PreProcessor/DeveloperChain.php
index 7ef5b31ba966c8f5b59bf5133e5e4dddbcb16d15..37d5976ea46c4b9c3a27eaff452bfaa4d1279918 100644
--- a/app/code/Magento/Developer/Model/View/Asset/PreProcessor/DeveloperChain.php
+++ b/app/code/Magento/Developer/Model/View/Asset/PreProcessor/DeveloperChain.php
@@ -14,19 +14,20 @@ class DeveloperChain extends Chain
      * @param LocalInterface $asset
      * @param string $origContent
      * @param string $origContentType
-     * @param null $origAssetPath
+     * @param string $origAssetPath
      * @codeCoverageIgnore
      */
     public function __construct(
         LocalInterface $asset,
         $origContent,
         $origContentType,
-        $origAssetPath = null
+        $origAssetPath
     ) {
         parent::__construct(
             $asset,
             $origContent,
-            $origContentType
+            $origContentType,
+            $origAssetPath
         );
 
         $this->targetContentType = $this->origContentType;
diff --git a/app/code/Magento/Developer/Model/View/Page/Config/ClientSideLessCompilation/Renderer.php b/app/code/Magento/Developer/Model/View/Page/Config/ClientSideLessCompilation/Renderer.php
index eaf588a27cc671b76d66a0d74169fe4043b14317..edfbdcb5f638db8fa730eec738b068f20251a04d 100644
--- a/app/code/Magento/Developer/Model/View/Page/Config/ClientSideLessCompilation/Renderer.php
+++ b/app/code/Magento/Developer/Model/View/Page/Config/ClientSideLessCompilation/Renderer.php
@@ -19,7 +19,6 @@ class Renderer extends Config\Renderer
 
     /**
      * @param Config $pageConfig
-     * @param \Magento\Framework\View\Asset\MinifyService $assetMinifyService
      * @param \Magento\Framework\View\Asset\MergeService $assetMergeService
      * @param \Magento\Framework\UrlInterface $urlBuilder
      * @param \Magento\Framework\Escaper $escaper
@@ -29,7 +28,6 @@ class Renderer extends Config\Renderer
      */
     public function __construct(
         Config $pageConfig,
-        \Magento\Framework\View\Asset\MinifyService $assetMinifyService,
         \Magento\Framework\View\Asset\MergeService $assetMergeService,
         \Magento\Framework\UrlInterface $urlBuilder,
         \Magento\Framework\Escaper $escaper,
@@ -41,7 +39,6 @@ class Renderer extends Config\Renderer
 
         parent::__construct(
             $pageConfig,
-            $assetMinifyService,
             $assetMergeService,
             $urlBuilder,
             $escaper,
diff --git a/app/code/Magento/Dhl/Model/Carrier.php b/app/code/Magento/Dhl/Model/Carrier.php
index 4e28283eae0edeef9c1ce24e695ab02b198227d7..498842814bd892478ebeffadf3b4b654d8d3499d 100644
--- a/app/code/Magento/Dhl/Model/Carrier.php
+++ b/app/code/Magento/Dhl/Model/Carrier.php
@@ -15,6 +15,7 @@ use Magento\Quote\Model\Quote\Address\RateRequest;
 use Magento\Quote\Model\Quote\Address\RateResult\Error;
 use Magento\Shipping\Model\Carrier\AbstractCarrier;
 use Magento\Shipping\Model\Rate\Result;
+use Magento\Framework\Xml\Security;
 
 /**
  * DHL International (API v1.4)
@@ -192,6 +193,7 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
      * @param \Psr\Log\LoggerInterface $logger
+     * @param Security $xmlSecurity
      * @param \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateFactory
      * @param \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
@@ -202,6 +204,7 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin
      * @param \Magento\Directory\Model\CountryFactory $countryFactory
      * @param \Magento\Directory\Model\CurrencyFactory $currencyFactory
      * @param \Magento\Directory\Helper\Data $directoryData
+     * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry
      * @param \Magento\Shipping\Helper\Carrier $carrierHelper
      * @param \Magento\Framework\Stdlib\DateTime\DateTime $coreDate
      * @param \Magento\Framework\Module\Dir\Reader $configReader
@@ -211,7 +214,6 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin
      * @param \Magento\Framework\Filesystem $filesystem
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
      * @param \Magento\Framework\HTTP\ZendClientFactory $httpClientFactory
-     * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry
      * @param array $data
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
@@ -219,6 +221,7 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
         \Psr\Log\LoggerInterface $logger,
+        Security $xmlSecurity,
         \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory,
         \Magento\Shipping\Model\Rate\ResultFactory $rateFactory,
         \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
@@ -254,6 +257,7 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin
             $scopeConfig,
             $rateErrorFactory,
             $logger,
+            $xmlSecurity,
             $xmlElFactory,
             $rateFactory,
             $rateMethodFactory,
diff --git a/app/code/Magento/Dhl/Test/Unit/Model/CarrierTest.php b/app/code/Magento/Dhl/Test/Unit/Model/CarrierTest.php
index 3170777d18318f1e8a3bfdeb15b8050ce3188f18..d6cb174acf25016970118222111a8656b5e7fe78 100644
--- a/app/code/Magento/Dhl/Test/Unit/Model/CarrierTest.php
+++ b/app/code/Magento/Dhl/Test/Unit/Model/CarrierTest.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Dhl\Test\Unit\Model;
 
+use Magento\Framework\Xml\Security;
+
 class CarrierTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -145,6 +147,7 @@ class CarrierTest extends \PHPUnit_Framework_TestCase
             'Magento\Dhl\Model\Carrier',
             [
                 'scopeConfig' => $scopeConfig,
+                'xmlSecurity' => new Security(),
                 'xmlElFactory' => $xmlElFactory,
                 'rateFactory' => $rateFactory,
                 'rateMethodFactory' => $rateMethodFactory,
diff --git a/app/code/Magento/Downloadable/Block/Checkout/Success.php b/app/code/Magento/Downloadable/Block/Checkout/Success.php
index 644ecc9688535b31ac5d42420568a0099677b319..65c8b92484168792700f39895e6b71a2e8e1c284 100644
--- a/app/code/Magento/Downloadable/Block/Checkout/Success.php
+++ b/app/code/Magento/Downloadable/Block/Checkout/Success.php
@@ -23,8 +23,6 @@ class Success extends \Magento\Checkout\Block\Onepage\Success
     /**
      * @param Template\Context $context
      * @param \Magento\Checkout\Model\Session $checkoutSession
-     * @param \Magento\Customer\Model\Session $customerSession
-     * @param \Magento\Sales\Model\OrderFactory $orderFactory
      * @param \Magento\Sales\Model\Order\Config $orderConfig
      * @param \Magento\Framework\App\Http\Context $httpContext
      * @param \Magento\Customer\Helper\Session\CurrentCustomer $currentCustomer
@@ -33,8 +31,6 @@ class Success extends \Magento\Checkout\Block\Onepage\Success
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
         \Magento\Checkout\Model\Session $checkoutSession,
-        \Magento\Customer\Model\Session $customerSession,
-        \Magento\Sales\Model\OrderFactory $orderFactory,
         \Magento\Sales\Model\Order\Config $orderConfig,
         \Magento\Framework\App\Http\Context $httpContext,
         \Magento\Customer\Helper\Session\CurrentCustomer $currentCustomer,
@@ -43,8 +39,6 @@ class Success extends \Magento\Checkout\Block\Onepage\Success
         parent::__construct(
             $context,
             $checkoutSession,
-            $customerSession,
-            $orderFactory,
             $orderConfig,
             $httpContext,
             $data
@@ -56,21 +50,29 @@ class Success extends \Magento\Checkout\Block\Onepage\Success
      * Return true if order(s) has one or more downloadable products
      *
      * @return bool
-     * @SuppressWarnings(PHPMD.BooleanGetMethodName)
      */
-    public function getOrderHasDownloadable()
+    private function orderHasDownloadableProducts()
     {
-        $hasDownloadableFlag = $this->_checkoutSession->getHasDownloadableProducts(true);
-        if (!$this->isOrderVisible()) {
-            return false;
-        }
-        /**
-         * if use guest checkout
-         */
-        if (!$this->currentCustomer->getCustomerId()) {
-            return false;
-        }
-        return $hasDownloadableFlag;
+        return $this->isVisible($this->_checkoutSession->getLastRealOrder())
+                && $this->currentCustomer->getCustomerId()
+            ? $this->_checkoutSession->getHasDownloadableProducts(true)
+            : false;
+    }
+
+    /**
+     * Prepares block data
+     *
+     * @return void
+     */
+    protected function prepareBlockData()
+    {
+        parent::prepareBlockData();
+
+        $this->addData(
+            [
+                'order_has_downloadable' => $this->orderHasDownloadableProducts()
+            ]
+        );
     }
 
     /**
diff --git a/app/code/Magento/Fedex/Model/Carrier.php b/app/code/Magento/Fedex/Model/Carrier.php
index db802c1912e2c9ca34d2ba5a1c89d989d11b79fd..69d52fead5bb266011b23c30efaef43086384d05 100644
--- a/app/code/Magento/Fedex/Model/Carrier.php
+++ b/app/code/Magento/Fedex/Model/Carrier.php
@@ -11,6 +11,7 @@ namespace Magento\Fedex\Model;
 use Magento\Quote\Model\Quote\Address\RateRequest;
 use Magento\Shipping\Model\Carrier\AbstractCarrierOnline;
 use Magento\Shipping\Model\Rate\Result;
+use Magento\Framework\Xml\Security;
 
 /**
  * Fedex shipping implementation
@@ -121,6 +122,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
      * @param \Psr\Log\LoggerInterface $logger
+     * @param Security $xmlSecurity
      * @param \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateFactory
      * @param \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
@@ -143,6 +145,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
         \Psr\Log\LoggerInterface $logger,
+        Security $xmlSecurity,
         \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory,
         \Magento\Shipping\Model\Rate\ResultFactory $rateFactory,
         \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
@@ -165,6 +168,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
             $scopeConfig,
             $rateErrorFactory,
             $logger,
+            $xmlSecurity,
             $xmlElFactory,
             $rateFactory,
             $rateMethodFactory,
diff --git a/app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php b/app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php
index c9100c8f451830eb20f8a01cfc4b00eec9013f92..37717163a595f11076fa23e0095c40774b121f7b 100644
--- a/app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php
+++ b/app/code/Magento/Fedex/Test/Unit/Model/CarrierTest.php
@@ -6,6 +6,7 @@
 namespace Magento\Fedex\Test\Unit\Model;
 
 use Magento\Framework\Object;
+use Magento\Framework\Xml\Security;
 
 /**
  * Class CarrierTest
@@ -79,6 +80,7 @@ class CarrierTest extends \PHPUnit_Framework_TestCase
                 'rateErrorFactory' =>
                     $this->getMock('Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory', [], [], '', false),
                 'logger' => $this->getMock('Psr\Log\LoggerInterface'),
+                'xmlSecurity' => new Security(),
                 'xmlElFactory' => $this->getMock('Magento\Shipping\Model\Simplexml\ElementFactory', [], [], '', false),
                 'rateFactory' => $rateFactory,
                 'rateMethodFactory' => $rateMethodFactory,
diff --git a/app/code/Magento/Paypal/Model/Payflow/Service/Response/Handler/FraudHandler.php b/app/code/Magento/Paypal/Model/Payflow/Service/Response/Handler/FraudHandler.php
index 4553ff54e53d8cfb5c18d261358fd0eb24062bdb..63003f7f15c0e55469ea474b02ae0ac0f7db2ed6 100644
--- a/app/code/Magento/Paypal/Model/Payflow/Service/Response/Handler/FraudHandler.php
+++ b/app/code/Magento/Paypal/Model/Payflow/Service/Response/Handler/FraudHandler.php
@@ -9,7 +9,12 @@ use Magento\Framework\Object;
 use Magento\Payment\Model\InfoInterface;
 use Magento\Paypal\Model\Info;
 use Magento\Paypal\Model\Payflowpro;
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\Xml\Security;
 
+/**
+ * Class FraudHandler
+ */
 class FraudHandler implements HandlerInterface
 {
     /**
@@ -28,11 +33,22 @@ class FraudHandler implements HandlerInterface
     private $paypalInfoManager;
 
     /**
+     * The security scanner XML document
+     *
+     * @var Security
+     */
+    private $xmlSecurity;
+
+    /**
+     * Constructor
+     *
      * @param Info $paypalInfoManager
+     * @param Security $xmlSecurity
      */
-    public function __construct(Info $paypalInfoManager)
+    public function __construct(Info $paypalInfoManager, Security $xmlSecurity)
     {
         $this->paypalInfoManager = $paypalInfoManager;
+        $this->xmlSecurity = $xmlSecurity;
     }
 
     /**
@@ -76,11 +92,16 @@ class FraudHandler implements HandlerInterface
      *
      * @param string $rulesString
      * @return array
+     * @throws LocalizedException
      */
     private function getFraudRulesDictionary($rulesString)
     {
-        libxml_use_internal_errors(true);
         $rules = [];
+
+        if (!$this->xmlSecurity->scan($rulesString)) {
+            return $rules;
+        }
+
         try {
             $rulesXml = new \SimpleXMLElement($rulesString);
             foreach ($rulesXml->{'rule'} as $rule) {
diff --git a/app/code/Magento/Paypal/Test/Unit/Model/Payflow/Service/Response/Handler/FraudHandlerTest.php b/app/code/Magento/Paypal/Test/Unit/Model/Payflow/Service/Response/Handler/FraudHandlerTest.php
index 71ed0ff7bff3c7281ca8e2f125f4106d8d6e58b2..dee2f88f42f440f73456c46283a3ce9b7404b650 100644
--- a/app/code/Magento/Paypal/Test/Unit/Model/Payflow/Service/Response/Handler/FraudHandlerTest.php
+++ b/app/code/Magento/Paypal/Test/Unit/Model/Payflow/Service/Response/Handler/FraudHandlerTest.php
@@ -44,7 +44,10 @@ class FraudHandlerTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
 
-        $this->fraudHandler = new FraudHandler($this->paypalInfoManagerMock);
+        $this->fraudHandler = new FraudHandler(
+            $this->paypalInfoManagerMock,
+            new \Magento\Framework\Xml\Security()
+        );
     }
 
     public function testHandleApprovedTransaction()
@@ -124,11 +127,12 @@ class FraudHandlerTest extends \PHPUnit_Framework_TestCase
     /**
      * Returns rules xml list as string
      *
+     * @param string $fileName
      * @return string
      */
-    private function getRulesXmlString()
+    private function getRulesXmlString($fileName = 'fps_prexmldata.xml')
     {
-        return file_get_contents(__DIR__ .'/_files/fps_prexmldata.xml');
+        return file_get_contents(__DIR__ . '/_files/' . $fileName);
     }
 
     /**
@@ -153,4 +157,45 @@ class FraudHandlerTest extends \PHPUnit_Framework_TestCase
                 'The billing address is not a valid USAddress'
         ];
     }
+
+    /**
+     * Check attempting to read invalid XML file (XXE XML)
+     */
+    public function testHandleXXEXml()
+    {
+        $file = __DIR__ . '/_files/xxe-xml.txt';
+        $rulesString = str_replace('{file}', $file, $this->getRulesXmlString('xxe_fps_prexmldata.xml'));
+
+        $this->responseMock->expects($this->atLeastOnce())
+            ->method('getData')
+            ->willReturnMap(
+                [
+                    [FraudHandler::RESPONSE_MESSAGE, null, 'New fraud message'],
+                    [FraudHandler::FRAUD_RULES_XML, null, $rulesString],
+                    ['result', null, Payflowpro::RESPONSE_CODE_FRAUDSERVICE_FILTER]
+                ]
+            );
+        $this->paymentMock->expects($this->once())
+            ->method('getAdditionalInformation')
+            ->with(Info::FRAUD_FILTERS)
+            ->willReturn(
+                [
+                    'Total Purchase Price Ceiling' => 'Existing fraud message',
+                    'RESPMSG' => 'Existing fraud message'
+                ]
+            );
+
+        $this->paypalInfoManagerMock->expects($this->once())
+            ->method('importToPayment')
+            ->with(
+                [
+                    Info::FRAUD_FILTERS => [
+                        'RESPMSG' => 'Existing fraud message',
+                        'Total Purchase Price Ceiling' => 'Existing fraud message'
+                    ]
+                ]
+            );
+
+        $this->fraudHandler->handle($this->paymentMock, $this->responseMock);
+    }
 }
diff --git a/app/code/Magento/Paypal/Test/Unit/Model/Payflow/Service/Response/Handler/_files/xxe-xml.txt b/app/code/Magento/Paypal/Test/Unit/Model/Payflow/Service/Response/Handler/_files/xxe-xml.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c6099913174aa4149bdc5f07a17ca1a13a5e6978
--- /dev/null
+++ b/app/code/Magento/Paypal/Test/Unit/Model/Payflow/Service/Response/Handler/_files/xxe-xml.txt
@@ -0,0 +1 @@
+the private content
\ No newline at end of file
diff --git a/app/code/Magento/Paypal/Test/Unit/Model/Payflow/Service/Response/Handler/_files/xxe_fps_prexmldata.xml b/app/code/Magento/Paypal/Test/Unit/Model/Payflow/Service/Response/Handler/_files/xxe_fps_prexmldata.xml
new file mode 100644
index 0000000000000000000000000000000000000000..02c3724a1caf1a982b654d55ebae2161efbc5825
--- /dev/null
+++ b/app/code/Magento/Paypal/Test/Unit/Model/Payflow/Service/Response/Handler/_files/xxe_fps_prexmldata.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<!DOCTYPE scan [<!ENTITY test SYSTEM "php://filter/read=convert.base64-encode/resource={file}">]>
+<triggeredRules>
+    <scan>&test;</scan>
+    <rule num="1">
+        <ruleId>2</ruleId>
+        <ruleAlias>CeilingAmount</ruleAlias>
+        <ruleDescription>Total Purchase Price Ceiling</ruleDescription>
+        <action>R</action>
+        <triggeredMessage>The purchase amount of 7501 is greater than the ceiling value set of 7500</triggeredMessage>
+        <rulevendorparms>
+            <ruleParameter num="1">
+                <name>CeilingValue</name>
+                <value type="USD">75.00</value>
+            </ruleParameter>
+        </rulevendorparms>
+    </rule>
+    <rule num="2">
+        <ruleId>6</ruleId>
+        <ruleAlias>HighOrderNumber</ruleAlias>
+        <ruleDescription>Total ItemCeiling</ruleDescription>
+        <action>R</action>
+        <triggeredMessage>16 items were ordered, which is overthe maximum allowed quantity of 15</triggeredMessage>
+        <rulevendorparms>
+            <ruleParameter num="1">
+                <name>Value</name>
+                <value type="Integer">15</value>
+            </ruleParameter>
+        </rulevendorparms>
+    </rule>
+    <rule num="3">
+        <ruleId>7</ruleId>
+        <ruleAlias>BillShipMismatch</ruleAlias>
+        <ruleDescription>Shipping/BillingMismatch</ruleDescription>
+        <action>R</action>
+        <triggeredMessage>Thebilling and shipping addresses did not match</triggeredMessage>
+    </rule>
+    <rule num="4">
+        <ruleId>13</ruleId>
+        <ruleAlias>HighRiskBinCheck</ruleAlias>
+        <ruleDescription>BIN Risk List Match</ruleDescription>
+        <action>R</action>
+        <triggeredMessage>The card number is in a high risk bin list</triggeredMessage>
+    </rule>
+    <rule num="5">
+        <ruleId>37</ruleId>
+        <ruleAlias>HighRiskZIPCheck</ruleAlias>
+        <ruleDescription>Zip Risk List Match</ruleDescription>
+        <action>R</action>
+        <triggeredMessage>High risk shipping zip</triggeredMessage>
+    </rule>
+    <rule num="6">
+        <ruleId>16</ruleId>
+        <ruleAlias>BillUSPostalAddressCheck</ruleAlias>
+        <ruleDescription>USPS Address Validation Failure</ruleDescription>
+        <action>R</action>
+        <triggeredMessage>The billing address is not a valid USAddress</triggeredMessage>
+        <rulevendorparms>
+            <ruleParameter num="1">
+                <name>AddressToVerify</name>
+                <value type="String">bill</value>
+            </ruleParameter>
+        </rulevendorparms>
+    </rule>
+</triggeredRules>
\ No newline at end of file
diff --git a/app/code/Magento/RequireJs/Block/Html/Head/Config.php b/app/code/Magento/RequireJs/Block/Html/Head/Config.php
index bf525dbf4034a748f4f1ea0709a71bb2778688b4..8eec827a91fdbb6c979544ec7920d853dd922b2b 100644
--- a/app/code/Magento/RequireJs/Block/Html/Head/Config.php
+++ b/app/code/Magento/RequireJs/Block/Html/Head/Config.php
@@ -7,6 +7,7 @@
 namespace Magento\RequireJs\Block\Html\Head;
 
 use Magento\Framework\RequireJs\Config as RequireJsConfig;
+use Magento\Framework\View\Asset\Minification;
 
 /**
  * Block responsible for including RequireJs config on the page
@@ -28,12 +29,18 @@ class Config extends \Magento\Framework\View\Element\AbstractBlock
      */
     protected $pageConfig;
 
+    /**
+     * @var Minification
+     */
+    protected $minification;
+
     /**
      * @param \Magento\Framework\View\Element\Context $context
      * @param RequireJsConfig $config
      * @param \Magento\RequireJs\Model\FileManager $fileManager
      * @param \Magento\Framework\View\Page\Config $pageConfig
      * @param \Magento\Framework\View\Asset\ConfigInterface $bundleConfig
+     * @param Minification $minification
      * @param array $data
      */
     public function __construct(
@@ -42,6 +49,7 @@ class Config extends \Magento\Framework\View\Element\AbstractBlock
         \Magento\RequireJs\Model\FileManager $fileManager,
         \Magento\Framework\View\Page\Config $pageConfig,
         \Magento\Framework\View\Asset\ConfigInterface $bundleConfig,
+        Minification $minification,
         array $data = []
     ) {
         parent::__construct($context, $data);
@@ -49,6 +57,7 @@ class Config extends \Magento\Framework\View\Element\AbstractBlock
         $this->fileManager = $fileManager;
         $this->pageConfig = $pageConfig;
         $this->bundleConfig = $bundleConfig;
+        $this->minification = $minification;
     }
 
     /**
@@ -58,11 +67,21 @@ class Config extends \Magento\Framework\View\Element\AbstractBlock
      */
     protected function _prepareLayout()
     {
-        $after = RequireJsConfig::REQUIRE_JS_FILE_NAME;
         $requireJsConfig = $this->fileManager->createRequireJsConfigAsset();
         $requireJsMixinsConfig = $this->fileManager->createRequireJsMixinsAsset();
         $assetCollection = $this->pageConfig->getAssetCollection();
 
+        $after = RequireJsConfig::REQUIRE_JS_FILE_NAME;
+        if ($this->minification->isEnabled('js')) {
+            $minResolver = $this->fileManager->createMinResolverAsset();
+            $assetCollection->insert(
+                $minResolver->getFilePath(),
+                $minResolver,
+                $after
+            );
+            $after = $minResolver->getFilePath();
+        }
+
         if ($this->bundleConfig->isBundlingJsFiles()) {
             $bundleAssets = $this->fileManager->createBundleJsPool();
             $staticAsset = $this->fileManager->createStaticJsAsset();
@@ -74,7 +93,7 @@ class Config extends \Magento\Framework\View\Element\AbstractBlock
                     $assetCollection->insert(
                         $bundleAsset->getFilePath(),
                         $bundleAsset,
-                        RequireJsConfig::REQUIRE_JS_FILE_NAME
+                        $after
                     );
                 }
                 $assetCollection->insert(
diff --git a/app/code/Magento/RequireJs/Model/FileManager.php b/app/code/Magento/RequireJs/Model/FileManager.php
index 6ee4aae67fa381cd89127997ec3634e73901f734..7c9dee16935ef74bf780cf13109b4b23ed70c023 100644
--- a/app/code/Magento/RequireJs/Model/FileManager.php
+++ b/app/code/Magento/RequireJs/Model/FileManager.php
@@ -6,6 +6,8 @@
 namespace Magento\RequireJs\Model;
 
 use Magento\Framework\App\Filesystem\DirectoryList;
+use Magento\Framework\App\State as AppState;
+use Magento\Framework\RequireJs\Config;
 
 /**
  * A service for handling RequireJS files in the application
@@ -13,7 +15,7 @@ use Magento\Framework\App\Filesystem\DirectoryList;
 class FileManager
 {
     /**
-     * @var \Magento\Framework\RequireJs\Config
+     * @var Config
      */
     private $config;
 
@@ -23,7 +25,7 @@ class FileManager
     private $filesystem;
 
     /**
-     * @var \Magento\Framework\App\State
+     * @var AppState
      */
     private $appState;
 
@@ -33,15 +35,15 @@ class FileManager
     private $assetRepo;
 
     /**
-     * @param \Magento\Framework\RequireJs\Config $config
+     * @param Config $config
      * @param \Magento\Framework\Filesystem $appFilesystem
-     * @param \Magento\Framework\App\State $appState
+     * @param AppState $appState
      * @param \Magento\Framework\View\Asset\Repository $assetRepo
      */
     public function __construct(
-        \Magento\Framework\RequireJs\Config $config,
+        Config $config,
         \Magento\Framework\Filesystem $appFilesystem,
-        \Magento\Framework\App\State $appState,
+        AppState $appState,
         \Magento\Framework\View\Asset\Repository $assetRepo
     ) {
         $this->config = $config;
@@ -62,6 +64,18 @@ class FileManager
         return $this->assetRepo->createArbitrary($relPath, '');
     }
 
+    /**
+     * Create '.min' files resolver asset
+     *
+     * @return \Magento\Framework\View\Asset\File
+     */
+    public function createMinResolverAsset()
+    {
+        $relPath = $this->config->getMinResolverRelativePath();
+        $this->ensureMinResolverFile($relPath);
+        return $this->assetRepo->createArbitrary($relPath, '');
+    }
+
     /**
      * Create a view asset representing the aggregated configuration file
      *
@@ -95,11 +109,25 @@ class FileManager
     private function ensureSourceFile($relPath)
     {
         $dir = $this->filesystem->getDirectoryWrite(DirectoryList::STATIC_VIEW);
-        if ($this->appState->getMode() == \Magento\Framework\App\State::MODE_DEVELOPER || !$dir->isExist($relPath)) {
+        if ($this->appState->getMode() == AppState::MODE_DEVELOPER || !$dir->isExist($relPath)) {
             $dir->writeFile($relPath, $this->config->getConfig());
         }
     }
 
+    /**
+     * Make sure the '.min' assets resolver is materialized
+     *
+     * @param string $relPath
+     * @return void
+     */
+    private function ensureMinResolverFile($relPath)
+    {
+        $dir = $this->filesystem->getDirectoryWrite(DirectoryList::STATIC_VIEW);
+        if ($this->appState->getMode() == AppState::MODE_DEVELOPER || !$dir->isExist($relPath)) {
+            $dir->writeFile($relPath, $this->config->getMinResolverCode());
+        }
+    }
+
     /**
      * Create a view asset representing the static js functionality
      *
@@ -107,11 +135,11 @@ class FileManager
      */
     public function createStaticJsAsset()
     {
-        if ($this->appState->getMode() != \Magento\Framework\App\State::MODE_PRODUCTION) {
+        if ($this->appState->getMode() != AppState::MODE_PRODUCTION) {
             return false;
         }
         $libDir = $this->filesystem->getDirectoryRead(DirectoryList::STATIC_VIEW);
-        $relPath = $libDir->getRelativePath(\Magento\Framework\RequireJs\Config::STATIC_FILE_NAME);
+        $relPath = $libDir->getRelativePath(Config::STATIC_FILE_NAME);
         /** @var $context \Magento\Framework\View\Asset\File\FallbackContext */
         $context = $this->assetRepo->getStaticViewFileContext();
 
@@ -126,12 +154,12 @@ class FileManager
     public function createBundleJsPool()
     {
         $bundles = [];
-        if ($this->appState->getMode() == \Magento\Framework\App\State::MODE_PRODUCTION) {
+        if ($this->appState->getMode() == AppState::MODE_PRODUCTION) {
             $libDir = $this->filesystem->getDirectoryRead(DirectoryList::STATIC_VIEW);
             /** @var $context \Magento\Framework\View\Asset\File\FallbackContext */
             $context = $this->assetRepo->getStaticViewFileContext();
 
-            $bundleDir = $context->getPath() . '/' .\Magento\Framework\RequireJs\Config::BUNDLE_JS_DIR;
+            $bundleDir = $context->getPath() . '/' . Config::BUNDLE_JS_DIR;
 
             if (!$libDir->isExist($bundleDir)) {
                 return [];
diff --git a/app/code/Magento/RequireJs/Test/Unit/Block/Html/Head/ConfigTest.php b/app/code/Magento/RequireJs/Test/Unit/Block/Html/Head/ConfigTest.php
index 66cf3ce50736e74c89ca2edc60593323c4ec315f..e976f7563a84539744a186bb9b2b08653e607bd1 100644
--- a/app/code/Magento/RequireJs/Test/Unit/Block/Html/Head/ConfigTest.php
+++ b/app/code/Magento/RequireJs/Test/Unit/Block/Html/Head/ConfigTest.php
@@ -36,10 +36,15 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
     protected $blockConfig;
 
     /**
-     * @var \Magento\Framework\View\Page\Config|\Magento\Framework\View\Asset\ConfigInterface
+     * @var \Magento\Framework\View\Asset\ConfigInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $bundleConfig;
 
+    /**
+     * @var \Magento\Framework\View\Asset\Minification|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $minificationMock;
+
     protected function setUp()
     {
         $this->context = $this->getMock('\Magento\Framework\View\Element\Context', [], [], '', false);
@@ -65,6 +70,11 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
             ->expects($this->atLeastOnce())
             ->method('getFilePath')
             ->willReturn('/path/to/require/require.js');
+        $minResolverAsset = $this->getMockForAbstractClass('\Magento\Framework\View\Asset\LocalInterface');
+        $minResolverAsset
+            ->expects($this->atLeastOnce())
+            ->method('getFilePath')
+            ->willReturn('/path/to/require/require-min-resolver.js');
 
         $this->fileManager
             ->expects($this->once())
@@ -82,6 +92,10 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
             ->expects($this->once())
             ->method('createBundleJsPool')
             ->will($this->returnValue([$asset]));
+        $this->fileManager
+            ->expects($this->once())
+            ->method('createMinResolverAsset')
+            ->will($this->returnValue($minResolverAsset));
 
         $layout = $this->getMock('Magento\Framework\View\LayoutInterface');
 
@@ -97,7 +111,24 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
             ->method('insert')
             ->willReturn(true);
 
-        $object = new Config($this->context, $this->config, $this->fileManager, $this->pageConfig, $this->bundleConfig);
+        $this->minificationMock = $this->getMockBuilder('Magento\Framework\View\Asset\Minification')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->minificationMock
+            ->expects($this->any())
+            ->method('isEnabled')
+            ->with('js')
+            ->willReturn(true);
+
+
+        $object = new Config(
+            $this->context,
+            $this->config,
+            $this->fileManager,
+            $this->pageConfig,
+            $this->bundleConfig,
+            $this->minificationMock
+        );
         $object->setLayout($layout);
     }
 
@@ -112,7 +143,18 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
                 $this->getMockForAbstractClass('\Magento\Framework\App\Config\ScopeConfigInterface')
             ));
         $this->config->expects($this->once())->method('getBaseConfig')->will($this->returnValue('the config data'));
-        $object = new Config($this->context, $this->config, $this->fileManager, $this->pageConfig, $this->bundleConfig);
+        $this->minificationMock = $this->getMockBuilder('Magento\Framework\View\Asset\Minification')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $object = new Config(
+            $this->context,
+            $this->config,
+            $this->fileManager,
+            $this->pageConfig,
+            $this->bundleConfig,
+            $this->minificationMock
+        );
         $html = $object->toHtml();
         $expectedFormat = <<<expected
 <script type="text/javascript">
diff --git a/app/code/Magento/RequireJs/Test/Unit/Model/FileManagerTest.php b/app/code/Magento/RequireJs/Test/Unit/Model/FileManagerTest.php
index 7905f9457db66c92c71520315c00d89c55247d4b..626db1149f1e5027c6ae75b7c7ca07174516b81c 100644
--- a/app/code/Magento/RequireJs/Test/Unit/Model/FileManagerTest.php
+++ b/app/code/Magento/RequireJs/Test/Unit/Model/FileManagerTest.php
@@ -14,7 +14,7 @@ class FileManagerTest extends \PHPUnit_Framework_TestCase
     /**
      * @var \Magento\Framework\RequireJs\Config|\PHPUnit_Framework_MockObject_MockObject
      */
-    private $config;
+    private $configMock;
 
     /**
      * @var \Magento\Framework\Filesystem|\PHPUnit_Framework_MockObject_MockObject
@@ -44,15 +44,15 @@ class FileManagerTest extends \PHPUnit_Framework_TestCase
     /**
      * @var \Magento\Framework\View\Asset\Repository|\PHPUnit_Framework_MockObject_MockObject
      */
-    private $assetRepo;
+    private $assetRepoMock;
 
     protected function setUp()
     {
-        $this->config = $this->getMock('\Magento\Framework\RequireJs\Config', [], [], '', false);
+        $this->configMock = $this->getMock('\Magento\Framework\RequireJs\Config', [], [], '', false);
         $this->fileSystem = $this->getMock('\Magento\Framework\Filesystem', [], [], '', false);
         $this->appState = $this->getMock('\Magento\Framework\App\State', [], [], '', false);
-        $this->assetRepo = $this->getMock('\Magento\Framework\View\Asset\Repository', [], [], '', false);
-        $this->object = new FileManager($this->config, $this->fileSystem, $this->appState, $this->assetRepo);
+        $this->assetRepoMock = $this->getMock('\Magento\Framework\View\Asset\Repository', [], [], '', false);
+        $this->object = new FileManager($this->configMock, $this->fileSystem, $this->appState, $this->assetRepoMock);
         $this->dir = $this->getMockForAbstractClass('\Magento\Framework\Filesystem\Directory\WriteInterface');
         $this->asset = $this->getMock('\Magento\Framework\View\Asset\File', [], [], '', false);
     }
@@ -63,14 +63,14 @@ class FileManagerTest extends \PHPUnit_Framework_TestCase
      */
     public function testCreateRequireJsConfigAsset($exists)
     {
-        $this->config->expects($this->once())
+        $this->configMock->expects($this->once())
             ->method('getConfigFileRelativePath')
             ->will($this->returnValue('requirejs/file.js'));
         $this->fileSystem->expects($this->once())
             ->method('getDirectoryWrite')
             ->with(DirectoryList::STATIC_VIEW)
             ->will($this->returnValue($this->dir));
-        $this->assetRepo->expects($this->once())
+        $this->assetRepoMock->expects($this->once())
             ->method('createArbitrary')
             ->with('requirejs/file.js', '')
             ->will($this->returnValue($this->asset));
@@ -81,11 +81,11 @@ class FileManagerTest extends \PHPUnit_Framework_TestCase
             ->with('requirejs/file.js')
             ->will($this->returnValue($exists));
         if ($exists) {
-            $this->config->expects($this->never())->method('getConfig');
+            $this->configMock->expects($this->never())->method('getConfig');
             $this->dir->expects($this->never())->method('writeFile');
         } else {
             $data = 'requirejs config data';
-            $this->config->expects($this->once())->method('getConfig')->will($this->returnValue($data));
+            $this->configMock->expects($this->once())->method('getConfig')->will($this->returnValue($data));
             $this->dir->expects($this->once())->method('writeFile')->with('requirejs/file.js', $data);
         }
         $this->assertSame($this->asset, $this->object->createRequireJsConfigAsset());
@@ -101,14 +101,14 @@ class FileManagerTest extends \PHPUnit_Framework_TestCase
 
     public function testCreateRequireJsAssetDevMode()
     {
-        $this->config->expects($this->once())
+        $this->configMock->expects($this->once())
             ->method('getConfigFileRelativePath')
             ->will($this->returnValue('requirejs/file.js'));
         $this->fileSystem->expects($this->once())
             ->method('getDirectoryWrite')
             ->with(DirectoryList::STATIC_VIEW)
             ->will($this->returnValue($this->dir));
-        $this->assetRepo->expects($this->once())
+        $this->assetRepoMock->expects($this->once())
             ->method('createArbitrary')
             ->with('requirejs/file.js', '')
             ->will($this->returnValue($this->asset));
@@ -118,14 +118,14 @@ class FileManagerTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue(\Magento\Framework\App\State::MODE_DEVELOPER));
         $this->dir->expects($this->never())->method('isExist');
         $data = 'requirejs config data';
-        $this->config->expects($this->once())->method('getConfig')->will($this->returnValue($data));
+        $this->configMock->expects($this->once())->method('getConfig')->will($this->returnValue($data));
         $this->dir->expects($this->once())->method('writeFile')->with('requirejs/file.js', $data);
         $this->assertSame($this->asset, $this->object->createRequireJsConfigAsset());
     }
 
     public function testCreateBundleJsPool()
     {
-        unset($this->config);
+        unset($this->configMock);
         $dirRead = $this->getMock('Magento\Framework\Filesystem\Directory\Read', [], [], 'libDir', false);
         $context = $this->getMock('Magento\Framework\View\Asset\File\FallbackContext', [], [], '', false);
         $assetRepo = $this->getMock('Magento\Framework\View\Asset\Repository', [], [], '', false);
@@ -189,4 +189,22 @@ class FileManagerTest extends \PHPUnit_Framework_TestCase
         $this->assertArrayHasKey('0', $result);
         $this->assertArrayHasKey('1', $result);
     }
+
+    public function testCreateMinResolverAsset()
+    {
+        $this->configMock
+            ->expects($this->any())
+            ->method('getMinResolverRelativePath')
+            ->willReturn('relative path');
+        $this->assetRepoMock
+            ->expects($this->once())
+            ->method('createArbitrary')
+            ->with('relative path');
+        $this->fileSystem->expects($this->once())
+            ->method('getDirectoryWrite')
+            ->with(DirectoryList::STATIC_VIEW)
+            ->will($this->returnValue($this->dir));
+
+        $this->object->createMinResolverAsset();
+    }
 }
diff --git a/app/code/Magento/RequireJs/etc/di.xml b/app/code/Magento/RequireJs/etc/di.xml
index 457a8c49f0c7bf8a9a0860a90e8d4e79318a9e82..305fa59d47e1840a5ee3cc1c60751d35f86ba781 100644
--- a/app/code/Magento/RequireJs/etc/di.xml
+++ b/app/code/Magento/RequireJs/etc/di.xml
@@ -33,4 +33,9 @@
             <argument name="themeFiles" xsi:type="object">Magento\Framework\View\File\Collector\Theme</argument>
         </arguments>
     </type>
+    <type name="Magento\Framework\RequireJs\Config">
+        <arguments>
+            <argument name="minifyAdapter" xsi:type="object">jsMinificationAdapter</argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php
index 99e544593f16bc73c2b191233afa2ffe99184657..047130de3eccc973abbc7708cf24e031bfcd1e19 100644
--- a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php
+++ b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php
@@ -9,6 +9,7 @@ use Magento\Framework\Exception\LocalizedException;
 use Magento\Quote\Model\Quote\Address\RateRequest;
 use Magento\Quote\Model\Quote\Address\RateResult\Error;
 use Magento\Shipping\Model\Shipment\Request;
+use Magento\Framework\Xml\Security;
 
 /**
  * Abstract online shipping carrier model
@@ -102,10 +103,18 @@ abstract class AbstractCarrierOnline extends AbstractCarrier
      */
     protected $_rawRequest = null;
 
+    /**
+     * The security scanner XML document
+     *
+     * @var Security
+     */
+    protected $xmlSecurity;
+
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
      * @param \Psr\Log\LoggerInterface $logger
+     * @param Security $xmlSecurity
      * @param \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateFactory
      * @param \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
@@ -125,6 +134,7 @@ abstract class AbstractCarrierOnline extends AbstractCarrier
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
         \Psr\Log\LoggerInterface $logger,
+        Security $xmlSecurity,
         \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory,
         \Magento\Shipping\Model\Rate\ResultFactory $rateFactory,
         \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
@@ -150,6 +160,7 @@ abstract class AbstractCarrierOnline extends AbstractCarrier
         $this->_directoryData = $directoryData;
         $this->stockRegistry = $stockRegistry;
         parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
+        $this->xmlSecurity = $xmlSecurity;
     }
 
     /**
@@ -620,12 +631,19 @@ abstract class AbstractCarrierOnline extends AbstractCarrier
      *
      * @param string $xmlContent
      * @param string $customSimplexml
-     *
      * @return \SimpleXMLElement|bool
+     * @throws LocalizedException
+     *
      * @api
      */
     public function parseXml($xmlContent, $customSimplexml = 'SimpleXMLElement')
     {
-        return simplexml_load_string($xmlContent, $customSimplexml);
+        if (!$this->xmlSecurity->scan($xmlContent)) {
+            throw new LocalizedException(__('Security validation of XML document has been failed.'));
+        }
+
+        $xmlElement = simplexml_load_string($xmlContent, $customSimplexml);
+
+        return $xmlElement;
     }
 }
diff --git a/app/code/Magento/Shipping/Test/Unit/Model/Carrier/AbstractCarrierOnline/xxe-xml.txt b/app/code/Magento/Shipping/Test/Unit/Model/Carrier/AbstractCarrierOnline/xxe-xml.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c6099913174aa4149bdc5f07a17ca1a13a5e6978
--- /dev/null
+++ b/app/code/Magento/Shipping/Test/Unit/Model/Carrier/AbstractCarrierOnline/xxe-xml.txt
@@ -0,0 +1 @@
+the private content
\ No newline at end of file
diff --git a/app/code/Magento/Shipping/Test/Unit/Model/Carrier/AbstractCarrierOnlineTest.php b/app/code/Magento/Shipping/Test/Unit/Model/Carrier/AbstractCarrierOnlineTest.php
index d6f5bd813bcb526b736e417ee8ebd6d71cc528d2..1de311ef47aaff7cbf05be0ebb8eb29ee7853402 100644
--- a/app/code/Magento/Shipping/Test/Unit/Model/Carrier/AbstractCarrierOnlineTest.php
+++ b/app/code/Magento/Shipping/Test/Unit/Model/Carrier/AbstractCarrierOnlineTest.php
@@ -52,7 +52,10 @@ class AbstractCarrierOnlineTest extends \PHPUnit_Framework_TestCase
         $objectManagerHelper = new ObjectManagerHelper($this);
         $carrierArgs = $objectManagerHelper->getConstructArguments(
             'Magento\Shipping\Model\Carrier\AbstractCarrierOnline',
-            ['stockRegistry' => $this->stockRegistry]
+            [
+                'stockRegistry' => $this->stockRegistry,
+                'xmlSecurity' => new \Magento\Framework\Xml\Security(),
+            ]
         );
         $this->carrier = $this->getMockBuilder('Magento\Shipping\Model\Carrier\AbstractCarrierOnline')
             ->setConstructorArgs($carrierArgs)
@@ -115,4 +118,36 @@ class AbstractCarrierOnlineTest extends \PHPUnit_Framework_TestCase
         $customSimpleXmlElement = $this->carrier->parseXml($xmlString, 'Magento\Shipping\Model\Simplexml\Element');
         $this->assertInstanceOf('Magento\Shipping\Model\Simplexml\Element', $customSimpleXmlElement);
     }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\LocalizedException
+     * @expectedExceptionMessage Security validation of XML document has been failed.
+     */
+    public function testParseXmlXXEXml()
+    {
+        $xmlString = '<!DOCTYPE scan [
+            <!ENTITY test SYSTEM "php://filter/read=convert.base64-encode/resource='
+            . __DIR__ . '/AbstractCarrierOnline/xxe-xml.txt">]><scan>&test;</scan>';
+
+        $xmlElement = $this->carrier->parseXml($xmlString);
+
+        echo $xmlElement->asXML();
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\LocalizedException
+     * @expectedExceptionMessage Security validation of XML document has been failed.
+     */
+    public function testParseXmlXQBXml()
+    {
+        $xmlString = '<?xml version="1.0"?>
+            <!DOCTYPE test [
+              <!ENTITY value "value">
+              <!ENTITY value1 "&value;&value;&value;&value;&value;&value;&value;&value;&value;&value;">
+              <!ENTITY value2 "&value1;&value1;&value1;&value1;&value1;&value1;&value1;&value1;&value1;&value1;">
+            ]>
+            <test>&value2;</test>';
+
+        $this->carrier->parseXml($xmlString);
+    }
 }
diff --git a/app/code/Magento/Store/etc/cache.xml b/app/code/Magento/Store/etc/cache.xml
index 45c887b58506313e06cd9a6e24b221b2bdfa9fdb..6dae6b683b09121e6bc3820d0d797fda2d7877bc 100644
--- a/app/code/Magento/Store/etc/cache.xml
+++ b/app/code/Magento/Store/etc/cache.xml
@@ -18,14 +18,6 @@
         <label>Blocks HTML output</label>
         <description>Page blocks HTML.</description>
     </type>
-    <type name="view_files_fallback" translate="label,description" instance="Magento\Framework\View\Design\FileResolution\Fallback\Cache">
-        <label>View files fallback</label>
-        <description>Paths to view files (e.g., PHTML templates, images, CSS, JS files).</description>
-    </type>
-    <type name="view_files_preprocessing" translate="label,description" instance="Magento\Framework\View\Asset\PreProcessor\Cache">
-        <label>View files pre-processing</label>
-        <description>Paths to pre-processed view files (e.g, CSS files with fixed paths or generated from LESS files).</description>
-    </type>
     <type name="collections" translate="label,description" instance="Magento\Framework\App\Cache\Type\Collection">
         <label>Collections Data</label>
         <description>Collection data files.</description>
diff --git a/app/code/Magento/Store/etc/config.xml b/app/code/Magento/Store/etc/config.xml
index 0bf0f4cdb889d4590773e402854cdeb4c1ee015c..131a73e7abba3a4b2f9423a92f0a56313e93a4e2 100644
--- a/app/code/Magento/Store/etc/config.xml
+++ b/app/code/Magento/Store/etc/config.xml
@@ -20,11 +20,15 @@
             <js>
                 <merge_files>0</merge_files>
                 <minify_files>0</minify_files>
-                <minify_adapter>Magento\Framework\Code\Minifier\Adapter\Js\Jsmin</minify_adapter>
+                <minify_exclude>
+                    /tiny_mce/
+                </minify_exclude>
             </js>
             <css>
                 <minify_files>0</minify_files>
-                <minify_adapter>Magento\Framework\Code\Minifier\Adapter\Css\CssMinifier</minify_adapter>
+                <minify_exclude>
+                    /tiny_mce/
+                </minify_exclude>
             </css>
             <image>
                 <default_adapter>GD2</default_adapter>
diff --git a/app/code/Magento/Store/etc/di.xml b/app/code/Magento/Store/etc/di.xml
index ecda7a87e6b85889b034ead1340c2426ddc1931c..1f5efd97f8bf527bd417d68a8b5ce07f00eb9fb4 100644
--- a/app/code/Magento/Store/etc/di.xml
+++ b/app/code/Magento/Store/etc/di.xml
@@ -288,6 +288,18 @@
             <argument name="modulePrefix" xsi:type="string">store</argument>
         </arguments>
     </type>
+    <virtualType name="cssMinificationAdapter" type="Magento\Framework\Code\Minifier\Adapter\Css\CSSmin" />
+    <virtualType name="jsMinificationAdapter" type="Magento\Framework\Code\Minifier\Adapter\Js\JShrink" />
+    <virtualType name="cssMinificationProcessor" type="Magento\Framework\View\Asset\PreProcessor\Minify">
+        <arguments>
+            <argument name="adapter" xsi:type="object">cssMinificationAdapter</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="jsMinificationProcessor" type="Magento\Framework\View\Asset\PreProcessor\Minify">
+        <arguments>
+            <argument name="adapter" xsi:type="object">jsMinificationAdapter</argument>
+        </arguments>
+    </virtualType>
     <type name="Magento\Framework\View\Asset\PreProcessor\Pool">
         <arguments>
             <argument name="preProcessors" xsi:type="array">
@@ -296,6 +308,7 @@
                         <item name="less_css" xsi:type="string">Magento\Framework\Css\PreProcessor\Less</item>
                         <item name="variable_notation" xsi:type="string">Magento\Framework\View\Asset\PreProcessor\VariableNotation</item>
                         <item name="module_notation" xsi:type="string">Magento\Framework\View\Asset\PreProcessor\ModuleNotation</item>
+                        <item name="css_min" xsi:type="string">cssMinificationProcessor</item>
                     </item>
                     <item name="less" xsi:type="array">
                         <item name="magento_import" xsi:type="string">Magento\Framework\Less\PreProcessor\Instruction\MagentoImport</item>
@@ -306,6 +319,12 @@
                     <item name="css" xsi:type="array">
                         <item name="variable_notation" xsi:type="string">Magento\Framework\View\Asset\PreProcessor\VariableNotation</item>
                         <item name="module_notation" xsi:type="string">Magento\Framework\View\Asset\PreProcessor\ModuleNotation</item>
+                        <item name="css_min" xsi:type="string">cssMinificationProcessor</item>
+                    </item>
+                </item>
+                <item name="js" xsi:type="array">
+                    <item name="js" xsi:type="array">
+                        <item name="js_min" xsi:type="string">jsMinificationProcessor</item>
                     </item>
                 </item>
             </argument>
diff --git a/app/code/Magento/Store/i18n/de_DE.csv b/app/code/Magento/Store/i18n/de_DE.csv
index f376d05a2c634af120f2e31c26caa9af4e97949d..e498731b13b2ca4ef3655fbedbdd1abce242bdd7 100644
--- a/app/code/Magento/Store/i18n/de_DE.csv
+++ b/app/code/Magento/Store/i18n/de_DE.csv
@@ -17,9 +17,7 @@ Layouts,Layouts
 "Layout building instructions.","Layout building instructions."
 "Blocks HTML output","Blocks HTML output"
 "Page blocks HTML.","Page blocks HTML."
-"View files fallback","View files fallback"
 "Paths to view files (e.g., PHTML templates, images, CSS, JS files).","Paths to view files (e.g., PHTML templates, images, CSS, JS files)."
-"View files pre-processing","View files pre-processing"
 "Paths to pre-processed view files (e.g, CSS files with fixed paths or generated from LESS files).","Paths to pre-processed view files (e.g, CSS files with fixed paths or generated from LESS files)."
 "Collections Data","Collections Data"
 "Collection data files.","Collection data files."
diff --git a/app/code/Magento/Store/i18n/en_US.csv b/app/code/Magento/Store/i18n/en_US.csv
index f376d05a2c634af120f2e31c26caa9af4e97949d..e498731b13b2ca4ef3655fbedbdd1abce242bdd7 100644
--- a/app/code/Magento/Store/i18n/en_US.csv
+++ b/app/code/Magento/Store/i18n/en_US.csv
@@ -17,9 +17,7 @@ Layouts,Layouts
 "Layout building instructions.","Layout building instructions."
 "Blocks HTML output","Blocks HTML output"
 "Page blocks HTML.","Page blocks HTML."
-"View files fallback","View files fallback"
 "Paths to view files (e.g., PHTML templates, images, CSS, JS files).","Paths to view files (e.g., PHTML templates, images, CSS, JS files)."
-"View files pre-processing","View files pre-processing"
 "Paths to pre-processed view files (e.g, CSS files with fixed paths or generated from LESS files).","Paths to pre-processed view files (e.g, CSS files with fixed paths or generated from LESS files)."
 "Collections Data","Collections Data"
 "Collection data files.","Collection data files."
diff --git a/app/code/Magento/Store/i18n/es_ES.csv b/app/code/Magento/Store/i18n/es_ES.csv
index f376d05a2c634af120f2e31c26caa9af4e97949d..e498731b13b2ca4ef3655fbedbdd1abce242bdd7 100644
--- a/app/code/Magento/Store/i18n/es_ES.csv
+++ b/app/code/Magento/Store/i18n/es_ES.csv
@@ -17,9 +17,7 @@ Layouts,Layouts
 "Layout building instructions.","Layout building instructions."
 "Blocks HTML output","Blocks HTML output"
 "Page blocks HTML.","Page blocks HTML."
-"View files fallback","View files fallback"
 "Paths to view files (e.g., PHTML templates, images, CSS, JS files).","Paths to view files (e.g., PHTML templates, images, CSS, JS files)."
-"View files pre-processing","View files pre-processing"
 "Paths to pre-processed view files (e.g, CSS files with fixed paths or generated from LESS files).","Paths to pre-processed view files (e.g, CSS files with fixed paths or generated from LESS files)."
 "Collections Data","Collections Data"
 "Collection data files.","Collection data files."
diff --git a/app/code/Magento/Store/i18n/fr_FR.csv b/app/code/Magento/Store/i18n/fr_FR.csv
index f376d05a2c634af120f2e31c26caa9af4e97949d..e498731b13b2ca4ef3655fbedbdd1abce242bdd7 100644
--- a/app/code/Magento/Store/i18n/fr_FR.csv
+++ b/app/code/Magento/Store/i18n/fr_FR.csv
@@ -17,9 +17,7 @@ Layouts,Layouts
 "Layout building instructions.","Layout building instructions."
 "Blocks HTML output","Blocks HTML output"
 "Page blocks HTML.","Page blocks HTML."
-"View files fallback","View files fallback"
 "Paths to view files (e.g., PHTML templates, images, CSS, JS files).","Paths to view files (e.g., PHTML templates, images, CSS, JS files)."
-"View files pre-processing","View files pre-processing"
 "Paths to pre-processed view files (e.g, CSS files with fixed paths or generated from LESS files).","Paths to pre-processed view files (e.g, CSS files with fixed paths or generated from LESS files)."
 "Collections Data","Collections Data"
 "Collection data files.","Collection data files."
diff --git a/app/code/Magento/Store/i18n/nl_NL.csv b/app/code/Magento/Store/i18n/nl_NL.csv
index f376d05a2c634af120f2e31c26caa9af4e97949d..e498731b13b2ca4ef3655fbedbdd1abce242bdd7 100644
--- a/app/code/Magento/Store/i18n/nl_NL.csv
+++ b/app/code/Magento/Store/i18n/nl_NL.csv
@@ -17,9 +17,7 @@ Layouts,Layouts
 "Layout building instructions.","Layout building instructions."
 "Blocks HTML output","Blocks HTML output"
 "Page blocks HTML.","Page blocks HTML."
-"View files fallback","View files fallback"
 "Paths to view files (e.g., PHTML templates, images, CSS, JS files).","Paths to view files (e.g., PHTML templates, images, CSS, JS files)."
-"View files pre-processing","View files pre-processing"
 "Paths to pre-processed view files (e.g, CSS files with fixed paths or generated from LESS files).","Paths to pre-processed view files (e.g, CSS files with fixed paths or generated from LESS files)."
 "Collections Data","Collections Data"
 "Collection data files.","Collection data files."
diff --git a/app/code/Magento/Store/i18n/pt_BR.csv b/app/code/Magento/Store/i18n/pt_BR.csv
index f376d05a2c634af120f2e31c26caa9af4e97949d..e498731b13b2ca4ef3655fbedbdd1abce242bdd7 100644
--- a/app/code/Magento/Store/i18n/pt_BR.csv
+++ b/app/code/Magento/Store/i18n/pt_BR.csv
@@ -17,9 +17,7 @@ Layouts,Layouts
 "Layout building instructions.","Layout building instructions."
 "Blocks HTML output","Blocks HTML output"
 "Page blocks HTML.","Page blocks HTML."
-"View files fallback","View files fallback"
 "Paths to view files (e.g., PHTML templates, images, CSS, JS files).","Paths to view files (e.g., PHTML templates, images, CSS, JS files)."
-"View files pre-processing","View files pre-processing"
 "Paths to pre-processed view files (e.g, CSS files with fixed paths or generated from LESS files).","Paths to pre-processed view files (e.g, CSS files with fixed paths or generated from LESS files)."
 "Collections Data","Collections Data"
 "Collection data files.","Collection data files."
diff --git a/app/code/Magento/Store/i18n/zh_CN.csv b/app/code/Magento/Store/i18n/zh_CN.csv
index f376d05a2c634af120f2e31c26caa9af4e97949d..e498731b13b2ca4ef3655fbedbdd1abce242bdd7 100644
--- a/app/code/Magento/Store/i18n/zh_CN.csv
+++ b/app/code/Magento/Store/i18n/zh_CN.csv
@@ -17,9 +17,7 @@ Layouts,Layouts
 "Layout building instructions.","Layout building instructions."
 "Blocks HTML output","Blocks HTML output"
 "Page blocks HTML.","Page blocks HTML."
-"View files fallback","View files fallback"
 "Paths to view files (e.g., PHTML templates, images, CSS, JS files).","Paths to view files (e.g., PHTML templates, images, CSS, JS files)."
-"View files pre-processing","View files pre-processing"
 "Paths to pre-processed view files (e.g, CSS files with fixed paths or generated from LESS files).","Paths to pre-processed view files (e.g, CSS files with fixed paths or generated from LESS files)."
 "Collections Data","Collections Data"
 "Collection data files.","Collection data files."
diff --git a/app/code/Magento/Tax/view/adminhtml/templates/rule/edit.phtml b/app/code/Magento/Tax/view/adminhtml/templates/rule/edit.phtml
index 4861e4b3bdc539fe555e6eefa3eaad39a489ecdb..ec05691741ff4da2899ef2a1b5161eaee18c9d5f 100644
--- a/app/code/Magento/Tax/view/adminhtml/templates/rule/edit.phtml
+++ b/app/code/Magento/Tax/view/adminhtml/templates/rule/edit.phtml
@@ -216,11 +216,16 @@ require([
                     of: 'body'
                 },
                 open: function () {
-                    $(this).closest('.ui-dialog').addClass('ui-dialog-active');
+                    var topMargin;
 
-                    var topMargin = $(this).closest('.ui-dialog').children('.ui-dialog-titlebar').outerHeight() + 30;
+                    $(this).closest('.ui-dialog').addClass('ui-dialog-active');
+                    topMargin = $(this).closest('.ui-dialog').children('.ui-dialog-titlebar').outerHeight() + 80;
+                    $(this).closest('.ui-dialog').css({
+                        top: '1%',
+                        position: 'absolute',
+                        left: '10%'
+                    });
                     $(this).closest('.ui-dialog').css('margin-top', topMargin);
-
                     $(this).addClass('admin__scope-old'); // ToDo UI: remove with old styles removal
                 },
                 close: function() {
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 aa415e7aeacebaf5d9ffed007bdc3cbe5a59e9fa..84074ebf9800e689fd6a900afe986c8242664ac9 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
@@ -2,17 +2,39 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
 define([
-    "jquery",
-    "underscore",
-    "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, customTpl){
-    "use strict";
+    'jquery',
+    'underscore',
+    '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, customTpl) {
+    'use strict';
+
+    /**
+     * Detect browser transition end event.
+     * @return {String|undefined} - transition event.
+     */
+    var transitionEvent =  (function () {
+        var transition,
+            elementStyle = document.body.style,
+            transitions = {
+                'transition': 'transitionend',
+                'OTransition': 'oTransitionEnd',
+                'MozTransition': 'transitionend',
+                'WebkitTransition': 'webkitTransitionEnd'
+            };
+
+        for (transition in transitions) {
+            if (elementStyle[transition] !== undefined && transitions.hasOwnProperty(transition)) {
+                return transitions[transition];
+            }
+        }
+    })();
 
     /**
      * Modal Window Widget
@@ -44,132 +66,167 @@ define([
             buttons: [{
                 text: $.mage.__('Ok'),
                 class: '',
-                click: function(){
+
+                /**
+                 * Default action on button click
+                 */
+                click: function () {
                     this.closeModal();
                 }
             }]
         },
+
         /**
          * Creates modal widget.
          */
-        _create: function() {
-            this.options.transitionEvent = this.whichTransitionEvent();
+        _create: function () {
+            this.options.transitionEvent = transitionEvent;
             this._createWrapper();
             this._renderModal();
             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));
+            this._on(this.modal.find(this.options.modalCloseBtn), {
+                'click': this.closeModal
+            });
+            this._on(this.element, {
+                'openModal': this.openModal,
+                'closeModal': this.closeModal
+            });
         },
+
         /**
          * Returns element from modal node.
          * @return {Object} - element.
          */
-        _getElem: function(elem) {
+        _getElem: function (elem) {
             return this.modal.find(elem);
         },
+
         /**
          * Gets visible modal count.
          * * @return {Number} - visible modal count.
          */
-        _getVisibleCount: function() {
-            return this.modalWrapper.find('.'+this.options.modalVisibleClass).length;
+        _getVisibleCount: function () {
+            var modals = this.modalWrapper.find(this.options.modalBlock);
+
+            return modals.filter('.' + this.options.modalVisibleClass).length;
         },
+
         /**
          * Gets count of visible modal by slide type.
          * * @return {Number} - visible modal count.
          */
-        _getVisibleSlideCount: function() {
+        _getVisibleSlideCount: function () {
             var elems = this.modalWrapper.find('[data-type="slide"]');
 
-            return elems.filter('.'+this.options.modalVisibleClass).length;
+            return elems.filter('.' + this.options.modalVisibleClass).length;
         },
-        toggleModal: function() {
-            if (this.options.isOpen == true) {
+
+        /**
+         * Toggle modal.
+         * * @return {Element} - current element.
+         */
+        toggleModal: function () {
+            if (this.options.isOpen === true) {
                 this.closeModal();
             } else {
                 this.openModal();
             }
         },
-        openModal: function() {
-            var that = this;
 
+        /**
+         * Open modal.
+         * * @return {Element} - current element.
+         */
+        openModal: function () {
             this.options.isOpen = true;
             this._createOverlay();
             this._setActive();
-            this.modal.one(this.options.transitionEvent, function() {
-                that._trigger('opened');
-            });
+            this.modal.one(this.options.transitionEvent, _.bind(this._trigger, this, 'opened'));
             this.modal.addClass(this.options.modalVisibleClass);
-            if ( !this.options.transitionEvent ) {
-                that._trigger('opened');
+
+            if (!this.options.transitionEvent) {
+                this._trigger('opened');
             }
 
             return this.element;
         },
-        closeModal: function() {
+
+        /**
+         * Close modal.
+         * * @return {Element} - current element.
+         */
+        closeModal: function () {
             var that = this;
 
             this.options.isOpen = false;
-            this.modal.one(this.options.transitionEvent, function() {
+            this.modal.one(this.options.transitionEvent, function () {
                 that._close();
             });
             this.modal.removeClass(this.options.modalVisibleClass);
-            if ( !this.options.transitionEvent ) {
+
+            if (!this.options.transitionEvent) {
                 that._close();
             }
 
             return this.element;
         },
+
         /**
          * Helper for closeModal function.
          */
-        _close: function() {
+        _close: function () {
             var trigger = _.bind(this._trigger, this, 'closed', this.modal);
 
             this._destroyOverlay();
             this._unsetActive();
             _.defer(trigger, this);
         },
+
         /**
          * Set z-index and margin for modal and overlay.
          */
-        _setActive: function() {
+        _setActive: function () {
             var zIndex = this.modal.zIndex();
 
             this.prevOverlayIndex = this.overlay.zIndex();
             this.modal.zIndex(zIndex + this._getVisibleCount());
             this.overlay.zIndex(zIndex + (this._getVisibleCount() - 1));
-            if ( this._getVisibleSlideCount() ) {
+
+            if (this._getVisibleSlideCount()) {
                 this.modal.css('marginLeft', this.options.modalLeftMargin * this._getVisibleSlideCount());
             }
         },
+
         /**
          * Unset styles for modal and set z-index for previous modal.
          */
-        _unsetActive: function() {
+        _unsetActive: function () {
             this.modal.removeAttr('style');
-            if ( this.overlay ) {
+
+            if (this.overlay) {
                 this.overlay.zIndex(this.prevOverlayIndex);
             }
         },
+
         /**
          * Creates wrapper to hold all modals.
          */
-        _createWrapper: function() {
-            this.modalWrapper = $('.'+this.options.wrapperClass);
-            if ( !this.modalWrapper.length ) {
+        _createWrapper: function () {
+            this.modalWrapper = $('.' + this.options.wrapperClass);
+
+            if (!this.modalWrapper.length) {
                 this.modalWrapper = $('<div></div>')
-                     .addClass(this.options.wrapperClass)
-                     .appendTo(this.options.appendTo);
+                    .addClass(this.options.wrapperClass)
+                    .appendTo(this.options.appendTo);
             }
         },
+
         /**
          * Compile template and append to wrapper.
          */
-        _renderModal: function() {
+        _renderModal: function () {
             $(template(
                 this.options[this.options.type + 'Tpl'],
                 {
@@ -178,74 +235,56 @@ define([
             this.modal = this.modalWrapper.find(this.options.modalBlock).last();
             this.element.show().appendTo(this._getElem(this.options.modalContent));
         },
+
         /**
          * Creates buttons pane.
          */
-        _createButtons: function() {
+        _createButtons: function () {
             var that = this;
 
             this.buttons = this._getElem(this.options.modalAction);
-            _.each(this.options.buttons, function(btn, key) {
+            _.each(this.options.buttons, function (btn, key) {
                 var button = that.buttons[key];
 
                 $(button).on('click', _.bind(btn.click, that));
             });
         },
+
         /**
          * Creates overlay, append it to wrapper, set previous click event on overlay.
          */
-        _createOverlay: function() {
+        _createOverlay: function () {
             var that = this,
                 events;
 
             this.overlay = $('.' + this.options.overlayClass);
-            if ( !this.overlay.length ) {
+
+            if (!this.overlay.length) {
                 $(this.options.appendTo).addClass(this.options.parentModalClass);
                 this.overlay = $('<div></div>')
                     .addClass(this.options.overlayClass)
                     .appendTo(this.modalWrapper);
             }
-
             events = $._data(this.overlay.get(0), 'events');
-            if ( events ) {
+
+            if (events) {
                 this.prevOverlayHandler = events.click[0].handler;
             }
-            this.overlay.unbind().on('click', function() {
+            this.overlay.unbind().on('click', function () {
                 that.closeModal();
             });
         },
+
         /**
          * Destroy overlay.
          */
-        _destroyOverlay: function() {
-            var modalCount = this.modalWrapper.find('.'+this.options.modalVisibleClass).length;
-
-            if ( !modalCount ) {
+        _destroyOverlay: function () {
+            if (this._getVisibleCount()) {
+                this.overlay.unbind().on('click', this.prevOverlayHandler);
+            } else {
                 $(this.options.appendTo).removeClass(this.options.parentModalClass);
                 this.overlay.remove();
                 this.overlay = null;
-
-            } else {
-                this.overlay.unbind().on('click', this.prevOverlayHandler);
-            }
-        },
-        /**
-         * Detects browser transition event.
-         */
-        whichTransitionEvent: function() {
-            var transition,
-                el = document.createElement('element'),
-                transitions = {
-                    'transition': 'transitionend',
-                    'OTransition': 'oTransitionEnd',
-                    'MozTransition': 'transitionend',
-                    'WebkitTransition': 'webkitTransitionEnd'
-                };
-
-            for (transition in transitions){
-                if ( el.style[transition] !== undefined && transitions.hasOwnProperty(transition) ) {
-                    return transitions[transition];
-                }
             }
         }
     });
diff --git a/app/code/Magento/Ui/view/base/web/templates/form/components/collection.html b/app/code/Magento/Ui/view/base/web/templates/form/components/collection.html
index 60e44c80be894716ba8122e6f3d413052ecb119b..0ff75fa00ea3dc784b453fbefbe10a55be96643f 100644
--- a/app/code/Magento/Ui/view/base/web/templates/form/components/collection.html
+++ b/app/code/Magento/Ui/view/base/web/templates/form/components/collection.html
@@ -15,7 +15,7 @@
                     </button>
                 </div>
                 <!-- ko template: previewTpl --><!-- /ko -->
-                <div data-bind="foreach: { data:  element.getRegion('head'), as: 'element' }, stopPropagation: true">
+                <div data-bind="foreach: { data:  element.getRegion('head'), as: 'element' }">
                     <!-- ko template: element.getTemplate() --><!-- /ko -->
                 </div>
             </li>
diff --git a/app/code/Magento/Ups/Model/Carrier.php b/app/code/Magento/Ups/Model/Carrier.php
index fca7588c0ae155c8385f87d3ab9654d9e1d45e97..fdb91b82f9dd63fc0ad260d93e3c0520eaff2bdc 100644
--- a/app/code/Magento/Ups/Model/Carrier.php
+++ b/app/code/Magento/Ups/Model/Carrier.php
@@ -14,6 +14,7 @@ use Magento\Shipping\Model\Carrier\CarrierInterface;
 use Magento\Shipping\Model\Rate\Result;
 use Magento\Shipping\Model\Simplexml\Element;
 use Magento\Ups\Helper\Config;
+use Magento\Framework\Xml\Security;
 
 /**
  * UPS shipping implementation
@@ -124,6 +125,7 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
      * @param \Psr\Log\LoggerInterface $logger
+     * @param Security $xmlSecurity
      * @param \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateFactory
      * @param \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
@@ -145,6 +147,7 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
         \Psr\Log\LoggerInterface $logger,
+        Security $xmlSecurity,
         \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory,
         \Magento\Shipping\Model\Rate\ResultFactory $rateFactory,
         \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
@@ -166,6 +169,7 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface
             $scopeConfig,
             $rateErrorFactory,
             $logger,
+            $xmlSecurity,
             $xmlElFactory,
             $rateFactory,
             $rateMethodFactory,
diff --git a/app/code/Magento/Usps/Model/Carrier.php b/app/code/Magento/Usps/Model/Carrier.php
index 2aa0517e787d4542532f33244d1454aefc40af08..eb2b5f3234288a29d0c70136387cec140a130e1b 100644
--- a/app/code/Magento/Usps/Model/Carrier.php
+++ b/app/code/Magento/Usps/Model/Carrier.php
@@ -11,6 +11,7 @@ namespace Magento\Usps\Model;
 use Magento\Shipping\Helper\Carrier as CarrierHelper;
 use Magento\Shipping\Model\Carrier\AbstractCarrierOnline;
 use Magento\Shipping\Model\Rate\Result;
+use Magento\Framework\Xml\Security;
 
 /**
  * USPS shipping
@@ -114,6 +115,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
      * @param \Psr\Log\LoggerInterface $logger
+     * @param Security $xmlSecurity
      * @param \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateFactory
      * @param \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
@@ -136,6 +138,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
         \Psr\Log\LoggerInterface $logger,
+        Security $xmlSecurity,
         \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory,
         \Magento\Shipping\Model\Rate\ResultFactory $rateFactory,
         \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
@@ -159,6 +162,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
             $scopeConfig,
             $rateErrorFactory,
             $logger,
+            $xmlSecurity,
             $xmlElFactory,
             $rateFactory,
             $rateMethodFactory,
diff --git a/app/code/Magento/Usps/Test/Unit/Model/CarrierTest.php b/app/code/Magento/Usps/Test/Unit/Model/CarrierTest.php
index 50bc4a1ae4d079231371ffb8734c483b80c8192f..ce80e36ea98f0a5ecadc074e47de940f7b633f3d 100644
--- a/app/code/Magento/Usps/Test/Unit/Model/CarrierTest.php
+++ b/app/code/Magento/Usps/Test/Unit/Model/CarrierTest.php
@@ -114,6 +114,7 @@ class CarrierTest extends \PHPUnit_Framework_TestCase
 
         $arguments = [
             'scopeConfig' => $scopeConfig,
+            'xmlSecurity' => new \Magento\Framework\Xml\Security(),
             'xmlElFactory' => $xmlElFactory,
             'rateFactory' => $rateFactory,
             'rateMethodFactory' => $rateMethodFactory,
diff --git a/app/etc/di.xml b/app/etc/di.xml
index 18e52f6b117b25b56e27c1af4dce82c164b14652..67456f362528af1e637ff4b05581c5f7c4bc2196 100644
--- a/app/etc/di.xml
+++ b/app/etc/di.xml
@@ -89,7 +89,6 @@
     <preference for="Magento\Framework\Mview\View\CollectionInterface" type="Magento\Framework\Mview\View\Collection" />
     <preference for="Magento\Framework\Mview\View\SubscriptionInterface" type="Magento\Framework\Mview\View\Subscription" />
     <preference for="Magento\Framework\Mview\View\ChangelogInterface" type="Magento\Framework\Mview\View\Changelog" />
-    <preference for="Magento\Framework\View\Design\FileResolution\Fallback\CacheDataInterface" type="Magento\Framework\View\Design\FileResolution\Fallback\CacheData\Flat"/>
     <preference for="Magento\Framework\Api\MetadataServiceInterface" type="Magento\Framework\Api\DefaultMetadataService"/>
     <preference for="Magento\Framework\Api\MetadataObjectInterface" type="Magento\Framework\Api\AttributeMetadata"/>
     <preference for="Magento\Framework\Api\SearchCriteriaInterface" type="Magento\Framework\Api\SearchCriteria"/>
@@ -213,11 +212,6 @@
             <argument name="appMode" xsi:type="init_parameter">Magento\Framework\App\State::PARAM_MODE</argument>
         </arguments>
     </type>
-    <type name="Magento\Framework\View\Asset\MinifyService">
-        <arguments>
-            <argument name="appMode" xsi:type="init_parameter">Magento\Framework\App\State::PARAM_MODE</argument>
-        </arguments>
-    </type>
     <type name="Magento\Framework\App\Cache\Frontend\Factory">
         <arguments>
             <argument name="enforcedOptions" xsi:type="init_parameter">Magento\Framework\App\Cache\Frontend\Factory::PARAM_CACHE_FORCED_OPTIONS</argument>
@@ -601,29 +595,23 @@
             <argument name="publisher" xsi:type="object">developerPublisher</argument>
         </arguments>
     </virtualType>
-    <virtualType name="fallbackResolverSimpleWithGroupedCache" type="Magento\Framework\View\Design\FileResolution\Fallback\Resolver\Simple">
-        <arguments>
-            <argument name="cache" xsi:type="object">Magento\Framework\View\Design\FileResolution\Fallback\CacheData\Grouped</argument>
-        </arguments>
-    </virtualType>
     <type name="Magento\Framework\View\Design\FileResolution\Fallback\File">
         <arguments>
-            <argument name="resolver" xsi:type="object">fallbackResolverSimpleWithGroupedCache</argument>
+            <argument name="resolver" xsi:type="object">Magento\Framework\View\Design\FileResolution\Fallback\Resolver\Simple</argument>
         </arguments>
     </type>
     <type name="Magento\Framework\View\Design\FileResolution\Fallback\TemplateFile">
         <arguments>
-            <argument name="resolver" xsi:type="object">fallbackResolverSimpleWithGroupedCache</argument>
+            <argument name="resolver" xsi:type="object">Magento\Framework\View\Design\FileResolution\Fallback\Resolver\Simple</argument>
         </arguments>
     </type>
     <type name="Magento\Framework\View\Design\FileResolution\Fallback\LocaleFile">
         <arguments>
-            <argument name="resolver" xsi:type="object">fallbackResolverSimpleWithGroupedCache</argument>
+            <argument name="resolver" xsi:type="object">Magento\Framework\View\Design\FileResolution\Fallback\Resolver\Simple</argument>
         </arguments>
     </type>
     <virtualType name="viewFileFallbackResolver" type="Magento\Framework\View\Design\FileResolution\Fallback\Resolver\Alternative">
         <arguments>
-            <argument name="cache" xsi:type="object">Magento\Framework\View\Design\FileResolution\Fallback\CacheData\Flat</argument>
             <argument name="alternativeExtensions" xsi:type="array">
                 <item name="css" xsi:type="array">
                     <item name="less" xsi:type="string">less</item>
@@ -631,9 +619,14 @@
             </argument>
         </arguments>
     </virtualType>
+    <virtualType name="viewFileMinifiedFallbackResolver" type="Magento\Framework\View\Design\FileResolution\Fallback\Resolver\Minification">
+        <arguments>
+            <argument name="fallback" xsi:type="object">viewFileFallbackResolver</argument>
+        </arguments>
+    </virtualType>
     <type name="Magento\Framework\View\Design\FileResolution\Fallback\StaticFile">
         <arguments>
-            <argument name="resolver" xsi:type="object">viewFileFallbackResolver</argument>
+            <argument name="resolver" xsi:type="object">viewFileMinifiedFallbackResolver</argument>
         </arguments>
     </type>
     <type name="Magento\Framework\Code\Generator">
diff --git a/composer.json b/composer.json
index 2f128cb5c41f6b095f54c5dc5916f2070311213d..d1688a0bf2a16475f188ea3b7013f29740b537a2 100644
--- a/composer.json
+++ b/composer.json
@@ -38,7 +38,8 @@
         "tubalmartin/cssmin": "2.4.8-p4",
         "magento/magento-composer-installer": "*",
         "braintree/braintree_php": "2.39.0",
-        "symfony/console": "~2.3 <2.7"
+        "symfony/console": "~2.3 <2.7",
+        "tedivm/jshrink": "~1.0.1"
     },
     "require-dev": {
         "phpunit/phpunit": "4.1.0",
@@ -167,7 +168,6 @@
         "trentrichardson/jquery-timepicker-addon": "1.4.3",
         "colinmollenhour/cache-backend-redis": "1.8",
         "colinmollenhour/credis": "1.5",
-        "linkorb/jsmin-php": "1.1.2",
         "phpseclib/phpseclib": "0.2.1",
         "components/jquery": "1.11.0",
         "blueimp/jquery-file-upload": "5.6.14",
@@ -180,7 +180,6 @@
             "trentrichardson/jquery-timepicker-addon": "lib/web/jquery/jquery-ui-timepicker-addon.js",
             "colinmollenhour/cache-backend-redis": "lib/internal/Cm/Cache/Backend/Redis.php",
             "colinmollenhour/credis": "lib/internal/Credis",
-            "linkorb/jsmin-php": "lib/internal/JSMin",
             "phpseclib/phpseclib": "lib/internal/phpseclib",
             "components/jquery": [
                 "lib/web/jquery.js",
diff --git a/composer.lock b/composer.lock
index da31b73ce352ce24368741ddf4321fd03d3712ec..97afe2b5a0ccdf4c08176539c5bee844fa48430c 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "08facbf9eb603e2ca8d6c0eb2f63fa5e",
+    "hash": "2213824594a29c1311ab731de9678212",
     "packages": [
         {
             "name": "braintree/braintree_php",
@@ -735,6 +735,52 @@
             "homepage": "https://symfony.com",
             "time": "2015-07-01 11:25:50"
         },
+        {
+            "name": "tedivm/jshrink",
+            "version": "v1.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/tedious/JShrink.git",
+                "reference": "7575d9d96f113bc7c1c28ec8231ee086751a9078"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/tedious/JShrink/zipball/7575d9d96f113bc7c1c28ec8231ee086751a9078",
+                "reference": "7575d9d96f113bc7c1c28ec8231ee086751a9078",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "require-dev": {
+                "fabpot/php-cs-fixer": "0.4.0",
+                "phpunit/phpunit": "4.0.*",
+                "satooshi/php-coveralls": "dev-master"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-0": {
+                    "JShrink": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Robert Hafner",
+                    "email": "tedivm@tedivm.com"
+                }
+            ],
+            "description": "Javascript Minifier built in PHP",
+            "homepage": "http://github.com/tedious/JShrink",
+            "keywords": [
+                "javascript",
+                "minifier"
+            ],
+            "time": "2014-11-11 03:54:14"
+        },
         {
             "name": "tubalmartin/cssmin",
             "version": "v2.4.8-p4",
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Cache/Additional.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Cache/Additional.php
new file mode 100644
index 0000000000000000000000000000000000000000..88955c3a9841a5bd3fece225dc021764a407ea7e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Cache/Additional.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Backend\Test\Block\Cache;
+
+use Magento\Mtf\Block\Block;
+use Magento\Mtf\Client\Locator;
+
+/**
+ * Additional Cache Management block.
+ */
+class Additional extends Block
+{
+    public function click($selector, $strategy = Locator::SELECTOR_XPATH)
+    {
+        $this->_rootElement->find($selector, $strategy)->click();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertCacheManagementAction.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertCacheManagementAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..edebf73913e7ce24032513668bdc3a847fd8fec7
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Constraint/AssertCacheManagementAction.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Backend\Test\Constraint;
+
+use Magento\Backend\Test\Fixture\GlobalSearch;
+use Magento\Backend\Test\Page\Adminhtml\AdminCache;
+use Magento\Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Assert Cache Management Action
+ */
+class AssertCacheManagementAction extends AbstractConstraint
+{
+    /**
+     * Assert that backend page has correct title and 404 Error is absent on the page.
+     *
+     * @param AdminCache $adminCache
+     * @param string $successMessage
+     * @return void
+     */
+    public function processAssert(AdminCache $adminCache, $successMessage)
+    {
+        \PHPUnit_Framework_Assert::assertEquals(
+            $successMessage,
+            $adminCache->getMessagesBlock()->getSuccessMessages(),
+            'Action is not successful'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Cache management action is successful';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/AdminCache.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/AdminCache.xml
index 5db150ec298d51e049428d2fa215ce071eac1287..1c5883a5119abc4e78591992a1e4276e9da9daab 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/AdminCache.xml
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/AdminCache.xml
@@ -5,9 +5,14 @@
  * See COPYING.txt for license details.
  */
  -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd">
-  <page name="AdminCache" area="Adminhtml" mca="admin/cache/" module="Magento_Backend">
-    <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator="#messages .messages" strategy="css selector"/>
-    <block name="actionsBlock" class="Magento\Backend\Test\Block\Cache" locator="div.page-actions" strategy="css selector"/>
-  </page>
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:noNamespaceSchemaLocation="../../../../../../../vendor/magento/mtf/etc/pages.xsd">
+    <page name="AdminCache" area="Adminhtml" mca="admin/cache/" module="Magento_Backend">
+        <block name="messagesBlock" class="Magento\Backend\Test\Block\Messages" locator="#messages .messages"
+               strategy="css selector"/>
+        <block name="actionsBlock" class="Magento\Backend\Test\Block\Cache" locator="div.page-actions"
+               strategy="css selector"/>
+        <block name="additionalBlock" class="Magento\Backend\Test\Block\Cache\Additional" locator="div.fieldset.additional-cache-management"
+               strategy="css selector"/>
+    </page>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/CacheManagementTest.php b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/CacheManagementTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e106bd9e3299a97099fbb072b10384565e3f6c0c
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/CacheManagementTest.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Backend\Test\TestCase;
+
+use Magento\Mtf\TestCase\Injectable;
+use Magento\Backend\Test\Page\Adminhtml\AdminCache;
+
+/**
+ * Steps:
+ * 1. Log in to backend.
+ * 2. Navigate throught menu to cache management page.
+ * 3. Click a button.
+ * 4. Perform asserts.
+ *
+ * @ZephyrId MAGETWO-34502 MAGETWO-34503 MAGETWO-39934
+ */
+class CacheManagementTest extends Injectable
+{
+    /* tags */
+    const MVP = 'no';
+    const DOMAIN = 'PS';
+    /* end tags */
+
+    /**
+     * Open admin cache management page
+     *
+     * @param AdminCache $adminCache
+     * @param string $button
+     * @return void
+     */
+    public function test(AdminCache $adminCache, $button)
+    {
+        $selector = "//div/button[normalize-space(.)= '" . $button . "']";
+        $adminCache->open();
+        $adminCache->getAdditionalBlock()->click($selector);
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/CacheManagementTest.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/CacheManagementTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f018b02d4daa40b4a10d08a924c1cb4e06aaf351
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/TestCase/CacheManagementTest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\Backend\Test\TestCase\CacheManagementTest">
+        <variation name="FlushCatalogImagesCacheTest">
+            <data name="button" xsi:type="string">Flush Catalog Images Cache</data>
+            <data name="successMessage" xsi:type="string">The image cache was cleaned.</data>
+            <constraint name="Magento\Backend\Test\Constraint\AssertCacheManagementAction"/>
+        </variation>
+        <variation name="FlushJavaScriptCSSCacheTest">
+            <data name="button" xsi:type="string">Flush JavaScript/CSS Cache</data>
+            <data name="successMessage" xsi:type="string">The JavaScript/CSS cache has been cleaned.</data>
+            <constraint name="Magento\Backend\Test\Constraint\AssertCacheManagementAction"/>
+        </variation>
+        <variation name="FlushStaticFilesCacheTest">
+            <data name="button" xsi:type="string">Flush Static Files Cache</data>
+            <data name="successMessage" xsi:type="string">The static files cache has been cleaned.</data>
+            <constraint name="Magento\Backend\Test\Constraint\AssertCacheManagementAction"/>
+        </variation>
+    </testCase>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Block/WebConfiguration.php b/dev/tests/functional/tests/app/Magento/Install/Test/Block/WebConfiguration.php
index 64a90917c4c0245490565f507e3def561752cd70..9d1f12a1c4c86a4162c87458d20e5c3ebb35c413 100644
--- a/dev/tests/functional/tests/app/Magento/Install/Test/Block/WebConfiguration.php
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Block/WebConfiguration.php
@@ -9,6 +9,7 @@ namespace Magento\Install\Test\Block;
 use Magento\Mtf\Block\Form;
 use Magento\Mtf\Fixture\FixtureInterface;
 use Magento\Mtf\Client\Element\SimpleElement;
+use Magento\Mtf\Client\Locator;
 
 /**
  * Web configuration block.
@@ -29,6 +30,13 @@ class WebConfiguration extends Form
      */
     protected $advancedOptions = "[ng-click*='advanced']";
 
+    /**
+     * Admin URI check.
+     *
+     * @var string
+     */
+    protected $adminUriCheck = '#admin';
+
     /**
      * Fill web configuration form.
      *
@@ -70,4 +78,9 @@ class WebConfiguration extends Form
     {
         $this->_rootElement->find($this->advancedOptions)->click();
     }
+
+    public function getAdminUriCheck()
+    {
+        return $this->_rootElement->find($this->adminUriCheck)->getAttribute('ng-init');
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertAdminUriAutogenerated.php b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertAdminUriAutogenerated.php
new file mode 100644
index 0000000000000000000000000000000000000000..a211ced5e97ad2adab155a5b2261cca109a34a80
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertAdminUriAutogenerated.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Install\Test\Constraint;
+
+use Magento\Install\Test\Page\Install;
+use Magento\Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Check that default Admin URI is generated according to the pattern
+ */
+class AssertAdminUriAutogenerated extends AbstractConstraint
+{
+    /**
+     * Admin URI pattern.
+     */
+    const ADMIN_URI_PATTERN = '/config\.address\.admin = \'admin_[a-z0-9]{1,6}/';
+
+    /**
+     * Assert that default Admin URI is generated according to the pattern.
+     *
+     * @param Install $installPage
+     * @return void
+     */
+    public function processAssert(Install $installPage)
+    {
+        \PHPUnit_Framework_Assert::assertRegExp(
+            self::ADMIN_URI_PATTERN,
+            $installPage->getWebConfigBlock()->getAdminUriCheck(),
+            'Unexpected Backend Frontname pattern.'
+        );
+    }
+
+    /**
+     * Returns a string representation of successful assertion.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return "Default Admin URI is OK.";
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php
index ccf21709a84ab2f1d5f59eaf62cb5444a49df765..49626cf4db5d0477277a14a268794aa127a011fd 100644
--- a/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php
@@ -14,6 +14,7 @@ use Magento\Mtf\Fixture\FixtureFactory;
 use Magento\Mtf\TestCase\Injectable;
 use Magento\Install\Test\Constraint\AssertAgreementTextPresent;
 use Magento\Install\Test\Constraint\AssertSuccessfulReadinessCheck;
+use Magento\Install\Test\Constraint\AssertAdminUriAutogenerated;
 
 /**
  * PLEASE ADD NECESSARY INFO BEFORE RUNNING TEST TO
@@ -108,6 +109,7 @@ class InstallTest extends Injectable
         FixtureFactory $fixtureFactory,
         AssertAgreementTextPresent $assertLicense,
         AssertSuccessfulReadinessCheck $assertReadiness,
+        AssertAdminUriAutogenerated $assertAdminUri,
         array $install = []
     ) {
         $dataConfig = array_merge($install, $configData);
@@ -131,6 +133,7 @@ class InstallTest extends Injectable
         $this->installPage->getDatabaseBlock()->fill($installConfig);
         $this->installPage->getDatabaseBlock()->clickNext();
         // Step 3: Web Configuration.
+        $assertAdminUri->processAssert($this->installPage);
         $this->installPage->getWebConfigBlock()->clickAdvancedOptions();
         $this->installPage->getWebConfigBlock()->fill($installConfig);
         $this->installPage->getWebConfigBlock()->clickNext();
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/Cache/CleanStaticFilesTest.php b/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/Cache/CleanStaticFilesTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8bd09d48a7c82d028a235a36300249ec4e58917a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Backend/Controller/Adminhtml/Cache/CleanStaticFilesTest.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Backend\Controller\Adminhtml\Cache;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Framework\App\Filesystem\DirectoryList;
+
+class CleanStaticFilesTest extends \Magento\TestFramework\TestCase\AbstractBackendController
+{
+    public function setUp()
+    {
+        $this->resource = 'Magento_Backend::cache';
+        $this->uri = 'backend/admin/cache/cleanStaticFiles';
+        parent::setUp();
+    }
+
+    public function testAclHasAccess()
+    {
+        // setup
+        /** @var \Magento\Framework\Filesystem $filesystem */
+        $filesystem = Bootstrap::getObjectManager()->get('Magento\Framework\Filesystem');
+        $dirStatic = $filesystem->getDirectoryWrite(DirectoryList::STATIC_VIEW);
+        $subStaticDir = 'subdir';
+        $dirStatic->create($subStaticDir);
+        $this->assertTrue($dirStatic->isExist($subStaticDir));
+
+        $dirVar= $filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
+        $subVarDir = DirectoryList::TMP_MATERIALIZATION_DIR . '/subdir';
+        $dirVar->create($subVarDir);
+        $this->assertTrue($dirVar->isExist($subVarDir));
+
+        // test
+        parent::testAclHasAccess();
+        $this->assertSessionMessages(
+            $this->contains("The static files cache has been cleaned."),
+            \Magento\Framework\Message\MessageInterface::TYPE_SUCCESS,
+            'Magento\Framework\Message\ManagerInterface'
+        );
+        $this->assertFalse($dirStatic->isExist($subStaticDir));
+        $this->assertTrue($dirVar->isExist(DirectoryList::TMP_MATERIALIZATION_DIR));
+        $this->assertFalse($dirVar->isExist($subVarDir));
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Framework/View/Asset/MinifierTest.php b/dev/tests/integration/testsuite/Magento/Framework/View/Asset/MinifierTest.php
index 9e64e9345c6fa2d84885c4ec01e469ed1df7277c..6fda3a8d0c2d9b9ee6f752a4fc0eb410e0c6aa65 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/View/Asset/MinifierTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/View/Asset/MinifierTest.php
@@ -6,6 +6,7 @@
 namespace Magento\Framework\View\Asset;
 
 use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Framework\App\State as AppState;
 
 /**
  * Tests for minifier
@@ -13,15 +14,31 @@ use Magento\TestFramework\Helper\Bootstrap;
 class MinifierTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\Framework\ObjectManagerInterface
+     * @var \Magento\TestFramework\ObjectManager
      */
     protected $objectManager;
 
+    /**
+     * {@inheritDoc}
+     */
     protected function setUp()
     {
+        parent::setUp();
         $this->objectManager = Bootstrap::getInstance()->getObjectManager();
-        $this->objectManager->get('Magento\Framework\App\State')->setAreaCode('frontend');
-        Bootstrap::getInstance()->reinitialize();
+        /** @var \Magento\TestFramework\App\State $appState */
+        $appState = $this->objectManager->get('Magento\TestFramework\App\State');
+        $appState->setMode(AppState::MODE_DEFAULT);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function tearDown()
+    {
+        /** @var \Magento\TestFramework\App\State $appState */
+        $appState = $this->objectManager->get('Magento\TestFramework\App\State');
+        $appState->setMode(AppState::MODE_DEVELOPER);
+        parent::tearDown();
     }
 
     /**
@@ -34,14 +51,10 @@ class MinifierTest extends \PHPUnit_Framework_TestCase
      * 4 - ensure that new minified CSS is fully workable in all supported browsers
      * 5 - replace `_files/static/css/styles.magento.min.css` with new minified css
      */
-    public function testCssMinifierLibrary()
+    public function testCSSminLibrary()
     {
-        /** @var \Magento\Framework\View\Asset\Config $config */
-        $config = $this->objectManager->get('Magento\Framework\View\Asset\Config');
-        $adapterClass = $config->getAssetMinificationAdapter('css');
-
         /** @var \Magento\Framework\Code\Minifier\AdapterInterface $adapter */
-        $adapter = $this->objectManager->get($adapterClass);
+        $adapter = $this->objectManager->get('cssMinificationAdapter');
         $this->assertEquals(
             file_get_contents(dirname(__DIR__) . '/_files/static/css/styles.magento.min.css'),
             $adapter->minify(file_get_contents(dirname(__DIR__) . '/_files/static/css/styles.css')),
@@ -51,6 +64,24 @@ class MinifierTest extends \PHPUnit_Framework_TestCase
         );
     }
 
+    /**
+     * Test JS minification library
+     * 
+     * @return void
+     */
+    public function testJshrinkLibrary()
+    {
+        /** @var \Magento\Framework\Code\Minifier\AdapterInterface $adapter */
+        $adapter = $this->objectManager->get('jsMinificationAdapter');
+        $this->assertEquals(
+            file_get_contents(dirname(__DIR__) . '/_files/static/js/test.min.js'),
+            $adapter->minify(file_get_contents(dirname(__DIR__) . '/_files/static/js/test.js')),
+            'Minified JS differs from initial minified JS snapshot. '
+            . 'Ensure that new JS is fully valid for all supported browsers '
+            . 'and replace old minified snapshot with new one.'
+        );
+    }
+
     /**
      * Test CSS minification
      *
@@ -62,50 +93,23 @@ class MinifierTest extends \PHPUnit_Framework_TestCase
      */
     protected function _testCssMinification($requestedUri, $requestedFilePath, $testFile, $assertionCallback)
     {
-        /** @var \Magento\Framework\App\State|\PHPUnit_Framework_MockObject_MockObject $appState */
-        $appState = $this->getMock('\Magento\Framework\App\State', ['getMode'], [], '', false);
-        $appState->expects($this->any())
-            ->method('getMode')
-            ->will($this->returnValue(\Magento\Framework\App\State::MODE_DEFAULT));
-
         /** @var \Magento\Framework\App\Request\Http $request */
         $request = $this->objectManager->get('Magento\Framework\App\Request\Http');
         $request->setRequestUri($requestedUri);
         $request->setParam('resource', $requestedUri);
 
-        $response = $this->getMockForAbstractClass(
-            'Magento\Framework\App\Response\FileInterface',
-            [],
-            '',
-            false,
-            false,
-            true,
-            ['setFilePath']
-        );
-        $response->expects(
-            $this->any()
-        )->method(
-            'setFilePath'
-        )->will(
-            $this->returnCallback(
-                $assertionCallback
-            )
-        );
-
-        $publisher = $this->objectManager->create(
-            'Magento\Framework\App\View\Asset\Publisher',
-            [
-                'appState' => $appState
-            ]
-        );
+        $response = $this->getMockBuilder('Magento\Framework\App\Response\FileInterface')
+            ->setMethods(['setFilePath'])
+            ->getMockForAbstractClass();
+        $response
+            ->expects($this->any())
+            ->method('setFilePath')
+            ->will($this->returnCallback($assertionCallback));
 
         /** @var \Magento\Framework\App\StaticResource $staticResourceApp */
         $staticResourceApp = $this->objectManager->create(
             'Magento\Framework\App\StaticResource',
-            [
-                'response' => $response,
-                'publisher' => $publisher
-            ]
+            ['response' => $response]
         );
         $initParams = Bootstrap::getInstance()->getAppInitParams();
         $designPath = $initParams[\Magento\Framework\App\Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS]['design']['path'];
@@ -128,7 +132,7 @@ class MinifierTest extends \PHPUnit_Framework_TestCase
     public function testCssMinification()
     {
         $this->_testCssMinification(
-            '/frontend/Magento/blank/en_US/css/styles.css',
+            '/frontend/Magento/blank/en_US/css/styles.min.css',
             '/frontend/Magento/blank/web/css/styles.css',
             dirname(__DIR__) . '/_files/static/css/styles.css',
             function ($path) {
@@ -193,7 +197,7 @@ class MinifierTest extends \PHPUnit_Framework_TestCase
 
         $staticPath = $initDirectories['static']['path'];
 
-        $fileToBePublished = $staticPath . '/frontend/Magento/blank/en_US/css/styles.css';
+        $fileToBePublished = $staticPath . '/frontend/Magento/blank/en_US/css/styles.min.css';
         $destFile = $designPath . '/frontend/Magento/blank/web/css/styles.css';
         $fileToTestPublishing = dirname(__DIR__) . '/_files/static/css/styles.css';
 
@@ -229,7 +233,7 @@ class MinifierTest extends \PHPUnit_Framework_TestCase
                 ]
             ));
 
-        /** @var \Magento\Setup\ModelDeployer $deployer */
+        /** @var \Magento\Setup\Model\Deployer $deployer */
         $deployer = $this->objectManager->create(
             'Magento\Setup\Model\Deployer',
             ['filesUtil' => $filesUtil, 'output' => $output, 'isDryRun' => false]
diff --git a/dev/tests/integration/testsuite/Magento/Framework/View/_files/static/js/test.js b/dev/tests/integration/testsuite/Magento/Framework/View/_files/static/js/test.js
new file mode 100644
index 0000000000000000000000000000000000000000..925ae9df33791441a2e54ed6457753a62cba0751
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Framework/View/_files/static/js/test.js
@@ -0,0 +1,534 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    "jquery",
+    "matchMedia",
+    "jquery/ui",
+    "jquery/jquery.mobile.custom",
+    "mage/translate"
+], function ($, mediaCheck) {
+    'use strict';
+
+    /**
+     * Menu Widget - this widget is a wrapper for the jQuery UI Menu
+     */
+    $.widget('mage.menu', $.ui.menu, {
+        options: {
+            responsive: false,
+            expanded: false,
+            delay: 300
+        },
+        _create: function () {
+            var self = this;
+
+            this._super();
+            $(window).on('resize', function () {
+                self.element.find('.submenu-reverse').removeClass('submenu-reverse');
+            });
+        },
+
+        _init: function () {
+            this._super();
+            this.delay = this.options.delay;
+
+            if (this.options.expanded === true) {
+                this.isExpanded();
+            }
+
+            if (this.options.responsive === true) {
+                mediaCheck({
+                    media: '(max-width: 640px)',
+                    entry: $.proxy(function () {
+                        this._toggleMobileMode();
+                    }, this),
+                    exit: $.proxy(function () {
+                        this._toggleDesktopMode();
+                    }, this)
+                });
+            }
+
+            this._assignControls()._listen();
+        },
+
+        _assignControls: function () {
+            this.controls = {
+                toggleBtn: $('[data-action="toggle-nav"]'),
+                swipeArea: $('.nav-sections')
+            };
+
+            return this;
+        },
+
+        _listen: function () {
+            var controls = this.controls;
+            var toggle = this.toggle;
+
+            this._on(controls.toggleBtn, {'click': toggle});
+            this._on(controls.swipeArea, {'swipeleft': toggle});
+        },
+
+        toggle: function () {
+            if ($('html').hasClass('nav-open')) {
+                $('html').removeClass('nav-open');
+                setTimeout(function () {
+                    $('html').removeClass('nav-before-open');
+                }, 300);
+            } else {
+                $('html').addClass('nav-before-open');
+                setTimeout(function () {
+                    $('html').addClass('nav-open');
+                }, 42);
+            }
+        },
+
+        //Add class for expanded option
+        isExpanded: function () {
+            var subMenus = this.element.find(this.options.menus),
+                expandedMenus = subMenus.find('ul');
+
+            expandedMenus.addClass('expanded');
+        },
+
+        _activate: function (event) {
+            window.location.href = this.active.find('> a').attr('href');
+            this.collapseAll(event);
+        },
+
+        _keydown: function (event) {
+
+            var match, prev, character, skip, regex,
+                preventDefault = true;
+
+            function escape(value) {
+                return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
+            }
+
+            if (this.active.closest('ul').attr('aria-expanded') != 'true') {
+
+                switch (event.keyCode) {
+                    case $.ui.keyCode.PAGE_UP:
+                        this.previousPage(event);
+                        break;
+                    case $.ui.keyCode.PAGE_DOWN:
+                        this.nextPage(event);
+                        break;
+                    case $.ui.keyCode.HOME:
+                        this._move("first", "first", event);
+                        break;
+                    case $.ui.keyCode.END:
+                        this._move("last", "last", event);
+                        break;
+                    case $.ui.keyCode.UP:
+                        this.previous(event);
+                        break;
+                    case $.ui.keyCode.DOWN:
+                        if (this.active && !this.active.is(".ui-state-disabled")) {
+                            this.expand(event);
+                        }
+                        break;
+                    case $.ui.keyCode.LEFT:
+                        this.previous(event);
+                        break;
+                    case $.ui.keyCode.RIGHT:
+                        this.next(event);
+                        break;
+                    case $.ui.keyCode.ENTER:
+                    case $.ui.keyCode.SPACE:
+                        this._activate(event);
+                        break;
+                    case $.ui.keyCode.ESCAPE:
+                        this.collapse(event);
+                        break;
+                    default:
+                        preventDefault = false;
+                        prev = this.previousFilter || "";
+                        character = String.fromCharCode(event.keyCode);
+                        skip = false;
+
+                        clearTimeout(this.filterTimer);
+
+                        if (character === prev) {
+                            skip = true;
+                        } else {
+                            character = prev + character;
+                        }
+
+                        regex = new RegExp("^" + escape(character), "i");
+                        match = this.activeMenu.children(".ui-menu-item").filter(function () {
+                            return regex.test($(this).children("a").text());
+                        });
+                        match = skip && match.index(this.active.next()) !== -1 ?
+                            this.active.nextAll(".ui-menu-item") :
+                            match;
+
+                        // If no matches on the current filter, reset to the last character pressed
+                        // to move down the menu to the first item that starts with that character
+                        if (!match.length) {
+                            character = String.fromCharCode(event.keyCode);
+                            regex = new RegExp("^" + escape(character), "i");
+                            match = this.activeMenu.children(".ui-menu-item").filter(function () {
+                                return regex.test($(this).children("a").text());
+                            });
+                        }
+
+                        if (match.length) {
+                            this.focus(event, match);
+                            if (match.length > 1) {
+                                this.previousFilter = character;
+                                this.filterTimer = this._delay(function () {
+                                    delete this.previousFilter;
+                                }, 1000);
+                            } else {
+                                delete this.previousFilter;
+                            }
+                        } else {
+                            delete this.previousFilter;
+                        }
+                }
+            } else {
+                switch (event.keyCode) {
+                    case $.ui.keyCode.DOWN:
+                        this.next(event);
+                        break;
+                    case $.ui.keyCode.UP:
+                        this.previous(event);
+                        break;
+                    case $.ui.keyCode.RIGHT:
+                        if (this.active && !this.active.is(".ui-state-disabled")) {
+                            this.expand(event);
+                        }
+                        break;
+                    case $.ui.keyCode.ENTER:
+                    case $.ui.keyCode.SPACE:
+                        this._activate(event);
+                        break;
+                    case $.ui.keyCode.LEFT:
+                    case $.ui.keyCode.ESCAPE:
+                        this.collapse(event);
+                        break;
+                    default:
+                        preventDefault = false;
+                        prev = this.previousFilter || "";
+                        character = String.fromCharCode(event.keyCode);
+                        skip = false;
+
+                        clearTimeout(this.filterTimer);
+
+                        if (character === prev) {
+                            skip = true;
+                        } else {
+                            character = prev + character;
+                        }
+
+                        regex = new RegExp("^" + escape(character), "i");
+                        match = this.activeMenu.children(".ui-menu-item").filter(function () {
+                            return regex.test($(this).children("a").text());
+                        });
+                        match = skip && match.index(this.active.next()) !== -1 ?
+                            this.active.nextAll(".ui-menu-item") :
+                            match;
+
+                        // If no matches on the current filter, reset to the last character pressed
+                        // to move down the menu to the first item that starts with that character
+                        if (!match.length) {
+                            character = String.fromCharCode(event.keyCode);
+                            regex = new RegExp("^" + escape(character), "i");
+                            match = this.activeMenu.children(".ui-menu-item").filter(function () {
+                                return regex.test($(this).children("a").text());
+                            });
+                        }
+
+                        if (match.length) {
+                            this.focus(event, match);
+                            if (match.length > 1) {
+                                this.previousFilter = character;
+                                this.filterTimer = this._delay(function () {
+                                    delete this.previousFilter;
+                                }, 1000);
+                            } else {
+                                delete this.previousFilter;
+                            }
+                        } else {
+                            delete this.previousFilter;
+                        }
+                }
+            }
+
+            if (preventDefault) {
+                event.preventDefault();
+            }
+        },
+
+        _toggleMobileMode: function () {
+            $(this.element).off('mouseenter mouseleave');
+            this._on({
+                "click .ui-menu-item:has(a)": function (event) {
+                    event.preventDefault();
+
+                    var target = $(event.target).closest(".ui-menu-item");
+
+                    if (!target.hasClass('level-top') || !target.has(".ui-menu").length) {
+                        window.location.href = target.find('> a').attr('href');
+                    }
+                }
+            });
+
+            var subMenus = this.element.find('.level-top');
+            $.each(subMenus, $.proxy(function (index, item) {
+                var category = $(item).find('> a span').not('.ui-menu-icon').text(),
+                    categoryUrl = $(item).find('> a').attr('href'),
+                    menu = $(item).find('> .ui-menu');
+
+                this.categoryLink = $('<a>')
+                    .attr('href', categoryUrl)
+                    .text($.mage.__('All ') + category);
+
+                this.categoryParent = $('<li>')
+                    .addClass('ui-menu-item all-category')
+                    .html(this.categoryLink);
+
+                if (menu.find('.all-category').length === 0) {
+                    menu.prepend(this.categoryParent);
+                }
+
+            }, this));
+        },
+
+        _toggleDesktopMode: function () {
+            this._on({
+                // Prevent focus from sticking to links inside menu after clicking
+                // them (focus should always stay on UL during navigation).
+                "mousedown .ui-menu-item > a": function (event) {
+                    event.preventDefault();
+                },
+                "click .ui-state-disabled > a": function (event) {
+                    event.preventDefault();
+                },
+                "click .ui-menu-item:has(a)": function (event) {
+                    var target = $(event.target).closest(".ui-menu-item");
+                    if (!this.mouseHandled && target.not(".ui-state-disabled").length) {
+                        this.select(event);
+
+                        // Only set the mouseHandled flag if the event will bubble, see #9469.
+                        if (!event.isPropagationStopped()) {
+                            this.mouseHandled = true;
+                        }
+
+                        // Open submenu on click
+                        if (target.has(".ui-menu").length) {
+                            this.expand(event);
+                        } else if (!this.element.is(":focus") && $(this.document[0].activeElement).closest(".ui-menu").length) {
+
+                            // Redirect focus to the menu
+                            this.element.trigger("focus", [true]);
+
+                            // If the active item is on the top level, let it stay active.
+                            // Otherwise, blur the active item since it is no longer visible.
+                            if (this.active && this.active.parents(".ui-menu").length === 1) {
+                                clearTimeout(this.timer);
+                            }
+                        }
+                    }
+                },
+                "mouseenter .ui-menu-item": function (event) {
+                    var target = $(event.currentTarget),
+                        ulElement,
+                        ulElementWidth,
+                        width,
+                        targetPageX,
+                        rightBound;
+
+                    if (target.has('ul')) {
+                        ulElement = target.find('ul');
+                        ulElementWidth = target.find('ul').outerWidth(true);
+                        width = target.outerWidth() * 2;
+                        targetPageX = target.offset().left;
+                        rightBound = $(window).width();
+
+                        if ((ulElementWidth + width + targetPageX) > rightBound) {
+                            ulElement.addClass('submenu-reverse');
+                        }
+                        if ((targetPageX - ulElementWidth) < 0) {
+                            ulElement.removeClass('submenu-reverse');
+                        }
+                    }
+
+                    // Remove ui-state-active class from siblings of the newly focused menu item
+                    // to avoid a jump caused by adjacent elements both having a class with a border
+                    target.siblings().children(".ui-state-active").removeClass("ui-state-active");
+                    this.focus(event, target);
+                },
+                "mouseleave": function (event) {
+                    this.collapseAll(event, true);
+                },
+                "mouseleave .ui-menu": "collapseAll"
+            });
+
+            var categoryParent = this.element.find('.all-category'),
+                html = $('html');
+
+            categoryParent.remove();
+
+            if (html.hasClass('nav-open')) {
+                html.removeClass('nav-open');
+                setTimeout(function () {
+                    html.removeClass('nav-before-open');
+                }, 300);
+            }
+        },
+        _delay: function(handler, delay) {
+            var instance = this,
+                handlerProxy = function () {
+                return (typeof handler === "string" ? instance[handler] : handler)
+                    .apply(instance, arguments);
+            };
+            
+            return setTimeout(handlerProxy, delay || 0);
+        }
+    });
+
+
+    $.widget('mage.navigation', $.mage.menu, {
+
+        options: {
+            responsiveAction: 'wrap', //option for responsive handling
+            maxItems: null, //option to set max number of menu items
+            container: '#menu', //container to check against navigation length
+            moreText: $.mage.__('more'),
+            breakpoint: 768
+        },
+
+        _init: function () {
+            this._super();
+
+            var that = this,
+                moreMenu = $('[responsive=more]'),
+                responsive = this.options.responsiveAction;
+
+            this.element
+                .addClass('ui-menu-responsive')
+                .attr('responsive', 'main');
+
+            this.setupMoreMenu();
+            this.setMaxItems();
+
+            //check responsive option
+            if (responsive == "onResize") {
+                $(window).on('resize', function () {
+                    if ($(window).width() > that.options.breakpoint) {
+                        that._responsive();
+                        $('[responsive=more]').show();
+                    } else {
+                        that.element.children().show();
+                        $('[responsive=more]').hide();
+                    }
+                });
+            } else if (responsive == "onReload") {
+                this._responsive();
+            }
+        },
+
+        setupMoreMenu: function () {
+            var moreListItems = this.element.children().clone(),
+                moreLink = $('<a>' + this.options.moreText + '</a>');
+
+            moreListItems.hide();
+
+            moreLink.attr('href', '#');
+
+            this.moreItemsList = $('<ul>')
+                .append(moreListItems);
+
+            this.moreListContainer = $('<li>')
+                .append(moreLink)
+                .append(this.moreItemsList);
+
+            this.responsiveMenu = $('<ul>')
+                .addClass('ui-menu-more')
+                .attr('responsive', 'more')
+                .append(this.moreListContainer)
+                .menu({
+                    position: {
+                        my: "right top",
+                        at: "right bottom"
+                    }
+                })
+                .insertAfter(this.element);
+        },
+
+        _responsive: function () {
+            var container = $(this.options.container),
+                containerSize = container.width(),
+                width = 0,
+                items = this.element.children('li'),
+                more = $('.ui-menu-more > li > ul > li a');
+
+
+            items = items.map(function () {
+                var item = {};
+
+                item.item = $(this);
+                item.itemSize = $(this).outerWidth();
+                return item;
+            });
+
+            $.each(items, function (index, item) {
+                var itemText = items[index].item
+                    .find('a:first')
+                    .text();
+
+                width += parseInt(items[index].itemSize, null);
+
+                if (width < containerSize) {
+                    items[index].item.show();
+
+                    more.each(function () {
+                        var text = $(this).text();
+                        if (text === itemText) {
+                            $(this).parent().hide();
+                        }
+                    });
+                } else if (width > containerSize) {
+                    items[index].item.hide();
+
+                    more.each(function () {
+                        var text = $(this).text();
+                        if (text === itemText) {
+                            $(this).parent().show();
+                        }
+                    });
+                }
+            });
+        },
+
+        setMaxItems: function () {
+            var items = this.element.children('li'),
+                itemsCount = items.length,
+                maxItems = this.options.maxItems,
+                overflow = itemsCount - maxItems,
+                overflowItems = items.slice(overflow);
+
+            overflowItems.hide();
+
+            overflowItems.each(function () {
+                var itemText = $(this).find('a:first').text();
+
+                $(this).hide();
+
+                $('.ui-menu-more > li > ul > li a').each(function () {
+                    var text = $(this).text();
+                    if (text === itemText) {
+                        $(this).parent().show();
+                    }
+                });
+            });
+        }
+    });
+
+    return {
+        menu: $.mage.menu,
+        navigation: $.mage.navigation
+    };
+});
diff --git a/dev/tests/integration/testsuite/Magento/Framework/View/_files/static/js/test.min.js b/dev/tests/integration/testsuite/Magento/Framework/View/_files/static/js/test.min.js
new file mode 100644
index 0000000000000000000000000000000000000000..c01e96760fee34bf3b7ba216a9d22dfdf9452cdd
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Framework/View/_files/static/js/test.min.js
@@ -0,0 +1,14 @@
+define(["jquery","matchMedia","jquery/ui","jquery/jquery.mobile.custom","mage/translate"],function($,mediaCheck){'use strict';$.widget('mage.menu',$.ui.menu,{options:{responsive:false,expanded:false,delay:300},_create:function(){var self=this;this._super();$(window).on('resize',function(){self.element.find('.submenu-reverse').removeClass('submenu-reverse');});},_init:function(){this._super();this.delay=this.options.delay;if(this.options.expanded===true){this.isExpanded();}
+if(this.options.responsive===true){mediaCheck({media:'(max-width: 640px)',entry:$.proxy(function(){this._toggleMobileMode();},this),exit:$.proxy(function(){this._toggleDesktopMode();},this)});}
+this._assignControls()._listen();},_assignControls:function(){this.controls={toggleBtn:$('[data-action="toggle-nav"]'),swipeArea:$('.nav-sections')};return this;},_listen:function(){var controls=this.controls;var toggle=this.toggle;this._on(controls.toggleBtn,{'click':toggle});this._on(controls.swipeArea,{'swipeleft':toggle});},toggle:function(){if($('html').hasClass('nav-open')){$('html').removeClass('nav-open');setTimeout(function(){$('html').removeClass('nav-before-open');},300);}else{$('html').addClass('nav-before-open');setTimeout(function(){$('html').addClass('nav-open');},42);}},isExpanded:function(){var subMenus=this.element.find(this.options.menus),expandedMenus=subMenus.find('ul');expandedMenus.addClass('expanded');},_activate:function(event){window.location.href=this.active.find('> a').attr('href');this.collapseAll(event);},_keydown:function(event){var match,prev,character,skip,regex,preventDefault=true;function escape(value){return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&");}
+if(this.active.closest('ul').attr('aria-expanded')!='true'){switch(event.keyCode){case $.ui.keyCode.PAGE_UP:this.previousPage(event);break;case $.ui.keyCode.PAGE_DOWN:this.nextPage(event);break;case $.ui.keyCode.HOME:this._move("first","first",event);break;case $.ui.keyCode.END:this._move("last","last",event);break;case $.ui.keyCode.UP:this.previous(event);break;case $.ui.keyCode.DOWN:if(this.active&&!this.active.is(".ui-state-disabled")){this.expand(event);}
+break;case $.ui.keyCode.LEFT:this.previous(event);break;case $.ui.keyCode.RIGHT:this.next(event);break;case $.ui.keyCode.ENTER:case $.ui.keyCode.SPACE:this._activate(event);break;case $.ui.keyCode.ESCAPE:this.collapse(event);break;default:preventDefault=false;prev=this.previousFilter||"";character=String.fromCharCode(event.keyCode);skip=false;clearTimeout(this.filterTimer);if(character===prev){skip=true;}else{character=prev+character;}
+regex=new RegExp("^"+escape(character),"i");match=this.activeMenu.children(".ui-menu-item").filter(function(){return regex.test($(this).children("a").text());});match=skip&&match.index(this.active.next())!==-1?this.active.nextAll(".ui-menu-item"):match;if(!match.length){character=String.fromCharCode(event.keyCode);regex=new RegExp("^"+escape(character),"i");match=this.activeMenu.children(".ui-menu-item").filter(function(){return regex.test($(this).children("a").text());});}
+if(match.length){this.focus(event,match);if(match.length>1){this.previousFilter=character;this.filterTimer=this._delay(function(){delete this.previousFilter;},1000);}else{delete this.previousFilter;}}else{delete this.previousFilter;}}}else{switch(event.keyCode){case $.ui.keyCode.DOWN:this.next(event);break;case $.ui.keyCode.UP:this.previous(event);break;case $.ui.keyCode.RIGHT:if(this.active&&!this.active.is(".ui-state-disabled")){this.expand(event);}
+break;case $.ui.keyCode.ENTER:case $.ui.keyCode.SPACE:this._activate(event);break;case $.ui.keyCode.LEFT:case $.ui.keyCode.ESCAPE:this.collapse(event);break;default:preventDefault=false;prev=this.previousFilter||"";character=String.fromCharCode(event.keyCode);skip=false;clearTimeout(this.filterTimer);if(character===prev){skip=true;}else{character=prev+character;}
+regex=new RegExp("^"+escape(character),"i");match=this.activeMenu.children(".ui-menu-item").filter(function(){return regex.test($(this).children("a").text());});match=skip&&match.index(this.active.next())!==-1?this.active.nextAll(".ui-menu-item"):match;if(!match.length){character=String.fromCharCode(event.keyCode);regex=new RegExp("^"+escape(character),"i");match=this.activeMenu.children(".ui-menu-item").filter(function(){return regex.test($(this).children("a").text());});}
+if(match.length){this.focus(event,match);if(match.length>1){this.previousFilter=character;this.filterTimer=this._delay(function(){delete this.previousFilter;},1000);}else{delete this.previousFilter;}}else{delete this.previousFilter;}}}
+if(preventDefault){event.preventDefault();}},_toggleMobileMode:function(){$(this.element).off('mouseenter mouseleave');this._on({"click .ui-menu-item:has(a)":function(event){event.preventDefault();var target=$(event.target).closest(".ui-menu-item");if(!target.hasClass('level-top')||!target.has(".ui-menu").length){window.location.href=target.find('> a').attr('href');}}});var subMenus=this.element.find('.level-top');$.each(subMenus,$.proxy(function(index,item){var category=$(item).find('> a span').not('.ui-menu-icon').text(),categoryUrl=$(item).find('> a').attr('href'),menu=$(item).find('> .ui-menu');this.categoryLink=$('<a>').attr('href',categoryUrl).text($.mage.__('All ')+category);this.categoryParent=$('<li>').addClass('ui-menu-item all-category').html(this.categoryLink);if(menu.find('.all-category').length===0){menu.prepend(this.categoryParent);}},this));},_toggleDesktopMode:function(){this._on({"mousedown .ui-menu-item > a":function(event){event.preventDefault();},"click .ui-state-disabled > a":function(event){event.preventDefault();},"click .ui-menu-item:has(a)":function(event){var target=$(event.target).closest(".ui-menu-item");if(!this.mouseHandled&&target.not(".ui-state-disabled").length){this.select(event);if(!event.isPropagationStopped()){this.mouseHandled=true;}
+if(target.has(".ui-menu").length){this.expand(event);}else if(!this.element.is(":focus")&&$(this.document[0].activeElement).closest(".ui-menu").length){this.element.trigger("focus",[true]);if(this.active&&this.active.parents(".ui-menu").length===1){clearTimeout(this.timer);}}}},"mouseenter .ui-menu-item":function(event){var target=$(event.currentTarget),ulElement,ulElementWidth,width,targetPageX,rightBound;if(target.has('ul')){ulElement=target.find('ul');ulElementWidth=target.find('ul').outerWidth(true);width=target.outerWidth()*2;targetPageX=target.offset().left;rightBound=$(window).width();if((ulElementWidth+width+targetPageX)>rightBound){ulElement.addClass('submenu-reverse');}
+if((targetPageX-ulElementWidth)<0){ulElement.removeClass('submenu-reverse');}}
+target.siblings().children(".ui-state-active").removeClass("ui-state-active");this.focus(event,target);},"mouseleave":function(event){this.collapseAll(event,true);},"mouseleave .ui-menu":"collapseAll"});var categoryParent=this.element.find('.all-category'),html=$('html');categoryParent.remove();if(html.hasClass('nav-open')){html.removeClass('nav-open');setTimeout(function(){html.removeClass('nav-before-open');},300);}},_delay:function(handler,delay){var instance=this,handlerProxy=function(){return(typeof handler==="string"?instance[handler]:handler).apply(instance,arguments);};return setTimeout(handlerProxy,delay||0);}});$.widget('mage.navigation',$.mage.menu,{options:{responsiveAction:'wrap',maxItems:null,container:'#menu',moreText:$.mage.__('more'),breakpoint:768},_init:function(){this._super();var that=this,moreMenu=$('[responsive=more]'),responsive=this.options.responsiveAction;this.element.addClass('ui-menu-responsive').attr('responsive','main');this.setupMoreMenu();this.setMaxItems();if(responsive=="onResize"){$(window).on('resize',function(){if($(window).width()>that.options.breakpoint){that._responsive();$('[responsive=more]').show();}else{that.element.children().show();$('[responsive=more]').hide();}});}else if(responsive=="onReload"){this._responsive();}},setupMoreMenu:function(){var moreListItems=this.element.children().clone(),moreLink=$('<a>'+this.options.moreText+'</a>');moreListItems.hide();moreLink.attr('href','#');this.moreItemsList=$('<ul>').append(moreListItems);this.moreListContainer=$('<li>').append(moreLink).append(this.moreItemsList);this.responsiveMenu=$('<ul>').addClass('ui-menu-more').attr('responsive','more').append(this.moreListContainer).menu({position:{my:"right top",at:"right bottom"}}).insertAfter(this.element);},_responsive:function(){var container=$(this.options.container),containerSize=container.width(),width=0,items=this.element.children('li'),more=$('.ui-menu-more > li > ul > li a');items=items.map(function(){var item={};item.item=$(this);item.itemSize=$(this).outerWidth();return item;});$.each(items,function(index,item){var itemText=items[index].item.find('a:first').text();width+=parseInt(items[index].itemSize,null);if(width<containerSize){items[index].item.show();more.each(function(){var text=$(this).text();if(text===itemText){$(this).parent().hide();}});}else if(width>containerSize){items[index].item.hide();more.each(function(){var text=$(this).text();if(text===itemText){$(this).parent().show();}});}});},setMaxItems:function(){var items=this.element.children('li'),itemsCount=items.length,maxItems=this.options.maxItems,overflow=itemsCount-maxItems,overflowItems=items.slice(overflow);overflowItems.hide();overflowItems.each(function(){var itemText=$(this).find('a:first').text();$(this).hide();$('.ui-menu-more > li > ul > li a').each(function(){var text=$(this).text();if(text===itemText){$(this).parent().show();}});});}});return{menu:$.mage.menu,navigation:$.mage.navigation};});
\ No newline at end of file
diff --git a/dev/tests/js/jasmine/spec_runner/index.js b/dev/tests/js/jasmine/spec_runner/index.js
index d63429aae1270559b0ef2af345d06d8dde170b8c..b4b0771a21944e10720544617c6b5407ce8e0ea5 100644
--- a/dev/tests/js/jasmine/spec_runner/index.js
+++ b/dev/tests/js/jasmine/spec_runner/index.js
@@ -19,7 +19,32 @@ function init(grunt, options) {
     config = stripJsonComments(config);
     config = JSON.parse(config);
 
-    themes = require(path.resolve(process.cwd(), config.themes));
+    //themes = require(path.resolve(process.cwd(), config.themes));
+    //TODO: MAGETWO-39843
+    themes = {
+        blank: {
+            area: 'frontend',
+            name: 'Magento/blank',
+            locale: 'en_US',
+            files: [
+                'css/styles-m',
+                'css/styles-l',
+                'css/email',
+                'css/email-inline'
+            ],
+            dsl: 'less'
+        },
+        backend: {
+            area: 'adminhtml',
+            name: 'Magento/backend',
+            locale: 'en_US',
+            files: [
+                'css/styles-old',
+                'css/styles'
+            ],
+            dsl: 'less'
+        }
+    }
 
     if (options.theme) {
         themes = _.pick(themes, options.theme);
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/core/layout.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/core/layout.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..a39203675c280520e4f5d457537697bca38e7c9a
--- /dev/null
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/core/layout.test.js
@@ -0,0 +1,21 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'underscore',
+    'Magento_Ui/js/core/renderer/layout'
+], function (_, layout) {
+    'use strict';
+
+    describe('Magento_Ui/js/core/layout', function(){
+        var layoutObj;
+
+        beforeEach(function(){
+            layoutObj = layout;
+        });
+        it('is executable', function(){
+           expect(typeof layoutObj).toEqual("function");
+        });
+    });
+});
\ No newline at end of file
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/multiselect.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/multiselect.test.js
index 0d68a9dcfa145676d90bd99803fe11ece671d5b0..e827351aa76c63aff658ccee5c2f0520a7258db9 100644
--- a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/multiselect.test.js
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/multiselect.test.js
@@ -38,10 +38,6 @@ define([
             expect(multiSelect.allSelected()).toBeFalsy();
             expect(multiSelect.excluded()).toEqual([]);
             expect(multiSelect.selected()).toEqual([]);
-            multiSelect.exportSelections();
-            //expect(multiSelect.source.set).toHaveBeenCalledWith([]);
-            expect(multiSelect.source.set.calls.argsFor(1))
-                .toEqual([]);
         });
 
         it('Select specific several rows on several pages', function () {
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/bookmarks/bookmarks.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/bookmarks/bookmarks.test.js
index 2931003459f9d41e5a5916078854ab99d4dfe160..7b3576f716618f165f1bf0147a8e071c00fe4bac 100644
--- a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/bookmarks/bookmarks.test.js
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/bookmarks/bookmarks.test.js
@@ -8,99 +8,97 @@ define([
 ], function (Bookmarks) {
     'use strict';
     describe('ui/js/grid/controls/bookmarks/bookmarks', function () {
-        var BookmarksElement, returnContextOfItself;
+        var bookmarksElement, returnContext;
+
         beforeEach(function () {
-            BookmarksElement = Bookmarks();
+            bookmarksElement = new Bookmarks({
+                index: 'index',
+                name: 'name',
+                indexField: 'id',
+                dataScope: 'scope',
+                provider: 'provider'
+            });
+
         });
-        it('has initObservable method', function () {
-            returnContextOfItself = BookmarksElement.initObservable();
-            expect(BookmarksElement.initObservable).toHaveBeenCalled();
-            expect(returnContextOfItself).toBe(BookmarksElement);
+        it('has initialize method', function () {
+            spyOn(bookmarksElement, "initialize");
+            bookmarksElement.initialize();
+            expect(bookmarksElement.initialize).toHaveBeenCalled();
         });
         it('has initStorage method', function () {
-            BookmarksElement.initStorage();
-            expect(BookmarksElement.initStorage).toHaveBeenCalled();
+            spyOn(bookmarksElement, "initStorage");
+            bookmarksElement.initStorage();
+            expect(bookmarksElement.initStorage).toHaveBeenCalled();
         });
         it('has initElement method', function () {
-            BookmarksElement.initElement();
-            expect(BookmarksElement.initElement).toHaveBeenCalled();
+            spyOn(bookmarksElement, "initElement");
+            bookmarksElement.initElement();
+            expect(bookmarksElement.initElement).toHaveBeenCalled();
         });
         it('has initViews method', function () {
-            returnContextOfItself = BookmarksElement.initViews();
-            expect(BookmarksElement.initViews).toHaveBeenCalled();
-            expect(BookmarksElement.activeIndex).toBe('');
-            expect(returnContextOfItself).toBe(BookmarksElement);
+            spyOn(bookmarksElement, "initViews");
+            bookmarksElement.initViews();
+            expect(bookmarksElement.initViews).toHaveBeenCalled();
         });
         it('has createView method', function () {
-            returnContextOfItself = BookmarksElement.createView();
-            expect(BookmarksElement.createView).toHaveBeenCalled();
-            expect(returnContextOfItself).toBe(BookmarksElement);
+            spyOn(bookmarksElement, "createView");
+            bookmarksElement.createView();
+            expect(bookmarksElement.createView).toHaveBeenCalled();
         });
         it('has createNewView method', function () {
-            returnContextOfItself = BookmarksElement.createNewView();
-            expect(BookmarksElement.createNewView).toHaveBeenCalled();
-            expect(BookmarksElement.createView).toHaveBeenCalled();
-            expect(returnContextOfItself).toBe(BookmarksElement);
+            spyOn(bookmarksElement, "createNewView");
+            bookmarksElement.createNewView();
+            expect(bookmarksElement.createNewView).toHaveBeenCalled();
         });
         it('has removeView method', function () {
-            returnContextOfItself = BookmarksElement.removeView();
-            expect(BookmarksElement.removeView).toHaveBeenCalled();
-            expect(BookmarksElement.removeStored).toHaveBeenCalled();
-            expect(returnContextOfItself).toBe(BookmarksElement);
+            spyOn(bookmarksElement, "removeView");
+            bookmarksElement.removeView();
+            expect(bookmarksElement.removeView).toHaveBeenCalled();
         });
         it('has saveView method', function () {
-            returnContextOfItself = BookmarksElement.saveView();
-            expect(BookmarksElement.saveView).toHaveBeenCalled();
-            expect(BookmarksElement.hasChanges).toHaveBeenCalled();
-            expect(BookmarksElement.store).toHaveBeenCalled();
-            expect(returnContextOfItself).toBe(BookmarksElement);
-        });
-        it('has saveCurrent method', function () {
-            returnContextOfItself = BookmarksElement.saveCurrent();
-            expect(BookmarksElement.saveCurrent).toHaveBeenCalled();
-            expect(BookmarksElement.store).toHaveBeenCalled();
-            expect(returnContextOfItself).toBe(BookmarksElement);
+            spyOn(bookmarksElement, "saveView");
+            bookmarksElement.saveView();
+            expect(bookmarksElement.saveView).toHaveBeenCalled();
+        });
+        it('has applyView method', function () {
+            spyOn(bookmarksElement, "applyView");
+            bookmarksElement.applyView();
+            expect(bookmarksElement.applyView).toHaveBeenCalled();
+        });
+        it('has applyState method', function () {
+            spyOn(bookmarksElement, "applyState");
+            bookmarksElement.applyState();
+            expect(bookmarksElement.applyState).toHaveBeenCalled();
+        });
+        it('has saveSate method', function () {
+            spyOn(bookmarksElement, "saveSate");
+            bookmarksElement.saveSate();
+            expect(bookmarksElement.saveSate).toHaveBeenCalled();
         });
         it('has checkChanges method', function () {
-            returnContextOfItself = BookmarksElement.checkChanges();
-            expect(BookmarksElement.checkChanges).toHaveBeenCalled();
-            expect(BookmarksElement.activeView).toHaveBeenCalled();
-            expect(BookmarksElement.hasChanges).toHaveBeenCalled();
-            expect(returnContextOfItself).toBe(BookmarksElement);
-        });
-        it('has getSaved method', function () {
-            returnContextOfItself = BookmarksElement.saveCurrent();
-            expect(BookmarksElement.getSaved).toHaveBeenCalled();
-            expect(BookmarksElement.activeView).toHaveBeenCalled();
-            expect(BookmarksElement.getSaved).toHaveBeenCalled();
-        });
-        it('has getDefault method', function () {
-            BookmarksElement.getDefault();
-            expect(BookmarksElement.getDefault).toHaveBeenCalled();
-        });
-        it('has defaultPolyfill method', function () {
-            BookmarksElement.saveCurrent();
-            expect(BookmarksElement.defaultPolyfill).toHaveBeenCalled();
-            expect(BookmarksElement.activeView).toHaveBeenCalled();
-            expect(BookmarksElement.checkChanges).toHaveBeenCalled();
-        });
-        it('has onActiveChange method', function () {
-            BookmarksElement.saveCurrent();
-            expect(BookmarksElement.onActiveChange).toHaveBeenCalled();
-            expect(BookmarksElement.store).toHaveBeenCalled();
-            expect(BookmarksElement.activeView).toHaveBeenCalled();
-            expect(BookmarksElement.hasChanges).toHaveBeenCalled();
-            expect(BookmarksElement.initialSet).toBeFalsy();
-        });
-        it('has onDataChange method', function () {
-            BookmarksElement.onDataChange();
-            expect(BookmarksElement.onDataChange).toHaveBeenCalled();
-            expect(BookmarksElement.saveCurrent).toHaveBeenCalled();
-            expect(BookmarksElement.activeView).toHaveBeenCalled();
+            spyOn(bookmarksElement, "checkChanges");
+            bookmarksElement.checkChanges();
+            expect(bookmarksElement.checkChanges).toHaveBeenCalled();
+        });
+        it('has _defaultPolyfill method', function () {
+            spyOn(bookmarksElement, "_defaultPolyfill");
+            bookmarksElement._defaultPolyfill();
+            expect(bookmarksElement._defaultPolyfill).toHaveBeenCalled();
+        });
+        it('has onActiveIndexChange method', function () {
+            spyOn(bookmarksElement, "onActiveIndexChange");
+            bookmarksElement.onActiveIndexChange();
+            expect(bookmarksElement.onActiveIndexChange).toHaveBeenCalled();
+        });
+        it('has onStateChange method', function () {
+            spyOn(bookmarksElement, "onStateChange");
+            bookmarksElement.onStateChange();
+            expect(bookmarksElement.onStateChange).toHaveBeenCalled();
         });
         it('has onEditingChange method', function () {
-            BookmarksElement.onEditingChange();
-            expect(BookmarksElement.onEditingChange).toHaveBeenCalled();
+            spyOn(bookmarksElement, "onEditingChange");
+            bookmarksElement.onEditingChange();
+            expect(bookmarksElement.onEditingChange).toHaveBeenCalled();
         });
     });
-});
\ No newline at end of file
+});
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/bookmarks/storage.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/bookmarks/storage.test.js
index 1fae8832c2d0bcbc4661995a68ffb9448033c768..77acad7d526229c40b5983fbd04f4bb54fe46a9c 100644
--- a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/bookmarks/storage.test.js
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/bookmarks/storage.test.js
@@ -4,41 +4,30 @@
  */
 
 define([
-    'Magento_Ui/js/grid/controls/bookmarks/storage',
-    'Magento_Ui/js/lib/storage'
-], function (bookmarkStorage,storage) {
+    'Magento_Ui/js/grid/controls/bookmarks/storage'
+], function (storage) {
     'use strict';
 
     describe('ui/js/grid/controls/bookmarks/storage', function () {
+        var storageObj;
 
-        it('has getter method', function () {
-            spyOn(storage, 'get');
-            bookmarkStorage.get();
-            expect(storage.get).toHaveBeenCalled();
-            bookmarkStorage.get(1, 2, 3);
-            expect(storage.get).toHaveBeenCalledWith(1, 2, 3);
-            bookmarkStorage.get('string');
-            expect(storage.get).toHaveBeenCalledWith('string');
+        beforeEach(function(){
+            storageObj = new storage();
         });
-
         it('has setter method', function () {
-            spyOn(storage, 'set');
-            bookmarkStorage.set();
-            expect(storage.set).toHaveBeenCalled();
-            bookmarkStorage.set(1,2);
-            expect(storage.set).toHaveBeenCalledWith(1,2);
-            bookmarkStorage.set('path', 'value');
-            expect(storage.set).toHaveBeenCalledWith('path', 'value');
+            spyOn(storageObj, 'set');
+            storageObj.set();
+            expect(storageObj.set).toHaveBeenCalled();
+        });
+        it('has getter method', function () {
+            spyOn(storageObj, 'get');
+            storageObj.get();
+            expect(storageObj.get).toHaveBeenCalled();
         });
         it('has remove method', function () {
-            spyOn(storage, 'remove');
-            bookmarkStorage.remove();
-            expect(storage.remove).toHaveBeenCalled();
-            bookmarkStorage.remove(1,2);
-            expect(storage.remove).toHaveBeenCalledWith(1,2);
-            bookmarkStorage.remove('path');
-            expect(storage.remove).toHaveBeenCalledWith('path');
+            spyOn(storageObj, 'remove');
+            storageObj.remove();
+            expect(storageObj.remove).toHaveBeenCalled();
         });
-
     });
 });
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/bookmarks/view.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/bookmarks/view.test.js
index f5a590046a723c656de1c2280fcd03f00356bb9a..3aff34a25062bf65caa3e2dcd291045dcdcecd42 100644
--- a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/bookmarks/view.test.js
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/bookmarks/view.test.js
@@ -10,56 +10,56 @@ define([
     describe('ui/js/grid/controls/bookmarks/view', function () {
         var view, returnContextOfItself;
         beforeEach(function(){
-            view = BookmarkView();
+            view = new BookmarkView({
+                index: 'index',
+                name: 'name',
+                indexField: 'id',
+                dataScope: 'scope',
+                provider: 'provider'
+            });
+        });
+        it('has initialize method', function () {
+            spyOn(view, "initialize");
+            view.initialize();
+            expect(view.initialize).toHaveBeenCalled();
         });
         it('has initObservable method', function () {
-            returnContextOfItself = view.initObservable();
+            spyOn(view, "initObservable");
+            view.initObservable();
             expect(view.initObservable).toHaveBeenCalled();
-            expect(returnContextOfItself).toBe(view);
-        });
-        it('has getSaved method', function () {
-            view.getSaved();
-            expect(view.getSaved).toHaveBeenCalled();
         });
         it('has getData method', function () {
+            spyOn(view, "getData");
             view.getData();
             expect(view.getData).toHaveBeenCalled();
         });
         it('has setData method', function () {
-            returnContextOfItself = view.setData();
+            spyOn(view, "setData");
+            view.setData();
             expect(view.setData).toHaveBeenCalled();
-            expect(returnContextOfItself).toBe(view);
         });
-        it('has setLabel method', function () {
-            returnContextOfItself = view.setLabel();
-            expect(view.setLabel).toHaveBeenCalled();
-            expect(returnContextOfItself).toBe(view);
+        it('has syncLabel method', function () {
+            spyOn(view, "syncLabel");
+            view.syncLabel();
+            expect(view.syncLabel).toHaveBeenCalled();
         });
         it('has startEdit method', function () {
-            returnContextOfItself = view.startEdit();
+            spyOn(view, "startEdit");
+            view.startEdit();
             expect(view.startEdit).toHaveBeenCalled();
-            expect(returnContextOfItself).toBe(view);
-        });
-        it('has endEdit method', function () {
-            returnContextOfItself = view.endEdit();
-            expect(view.endEdit).toHaveBeenCalled();
-            expect(returnContextOfItself).toBe(view);
-        });
-        it('has save method', function () {
-            view.save();
-            expect(view.save).toHaveBeenCalled();
-            expect(view.isNew).toBeFalsy();
         });
-        it('has checkChanges method', function () {
-            view.checkChanges();
-            expect(view.checkChanges).toHaveBeenCalled();
-            expect(view.changed).toHaveBeenCalled();
+        it('has exportView method', function () {
+            spyOn(view, "exportView");
+            view.exportView();
+            expect(view.exportView).toHaveBeenCalled();
         });
         it('has onActivate method', function () {
+            spyOn(view, "onActivate");
             view.onActivate();
             expect(view.onActivate).toHaveBeenCalled();
         });
         it('has onActiveChange method', function () {
+            spyOn(view, "onActiveChange");
             view.onActiveChange();
             expect(view.onActiveChange).toHaveBeenCalled();
         });
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/columns.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/columns.test.js
index e01b4eb1d22910908e2540a6e8b71a7a4dad7414..d93357d2679772b4603f279c1e921d5216a5e2b0 100644
--- a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/columns.test.js
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/columns.test.js
@@ -45,20 +45,6 @@ define([
             columnsInstance.viewportMaxSize = 4;
             columnsInstance.elems.push(new FakeElement());
             expect(columnsInstance.isDisabled(columnsInstance.elems()[0])).toBeTruthy();
-
-            columnsInstance.elems.push(new FakeElement());
-            expect(columnsInstance.isDisabled(columnsInstance.elems()[0])).toBeFalsy();
-
-            columnsInstance.elems.push(new FakeElement());
-            expect(columnsInstance.isDisabled(columnsInstance.elems()[0])).toBeFalsy();
-
-            columnsInstance.elems.push(new FakeElement());
-            expect(columnsInstance.isDisabled(columnsInstance.elems()[0])).toBeFalsy();
-
-            columnsInstance.elems.push(new FakeElement());
-            expect(columnsInstance.isDisabled(columnsInstance.elems()[0])).toBeTruthy();
-            expect(columnsInstance.isDisabled(columnsInstance.elems()[3])).toBeTruthy();
         });
-
     });
-});
\ No newline at end of file
+});
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/dnd.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/dnd.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..788cbf7b807831839bf025d6f503ac314871aa05
--- /dev/null
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/dnd.test.js
@@ -0,0 +1,39 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+define([
+        'Magento_Ui/js/grid/dnd'
+    ], function(dnd){
+        'use strict';
+
+        describe('Magento_Ui/js/grid/controls/grid/dnd', function(){
+            var dragAndDrop,
+                fakeElement;
+
+            beforeEach(function(){
+                spyOn(document, 'addEventListener');
+                dragAndDrop = new dnd({a:'a'});
+            });
+            it('Dragging changes <body> state on init', function(){
+                expect(document.addEventListener).toHaveBeenCalled();
+                expect(dragAndDrop.$body).toBeDefined();
+            });
+            it('specifies column as dragable', function(){
+                fakeElement = document.createElement('HTMLTableCellElement');
+                dragAndDrop.addColumn(fakeElement);
+                expect(dragAndDrop.columns.length).toBeGreaterThan(0);
+            });
+            it('has setTable method', function () {
+                fakeElement = document.createElement('HTMLTableElement');
+                dragAndDrop.setTable(fakeElement);
+                expect(dragAndDrop.table).toBeDefined();
+            });
+            it('has setDragTable method', function () {
+                fakeElement = document.createElement('HTMLTableElement');
+                dragAndDrop.setDragTable(fakeElement);
+                expect(dragAndDrop.dragTable).toBeDefined();
+            });
+        })
+    });
\ No newline at end of file
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/filters/filters.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/filters/filters.test.js
index 790bb022cf6ddee4bd68ab2f583e4578dfecddb9..a77af66929f075717af375daecbf7610f1afa071 100644
--- a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/filters/filters.test.js
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/filters/filters.test.js
@@ -166,11 +166,9 @@ define([
                 }
             };
 
-            filters.extractPreviews(filters.elems);
-            expect(filters.previews().length).toEqual(0);
             filters.elems.push(elem);
-            filters.extractPreviews(filters.elems);
-            expect(filters.previews().length).toEqual(1);
+            filters.extractActive(filters.elems);
+            expect(filters.active().length).toEqual(0);
         });
     });
 });
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/component/core.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/component/core.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..b76b1d984a646b5379c3316409eb1e03448beea9
--- /dev/null
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/component/core.test.js
@@ -0,0 +1,86 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+define([
+        'Magento_Ui/js/lib/component/core'
+    ], function (core) {
+        'use strict';
+
+        describe( 'Magento_Ui/js/lib/component/core', function(){
+            var coreObj,
+                returnedValue;
+
+            beforeEach(function(){
+                coreObj = core;
+            });
+            it("has initialize", function(){
+                spyOn(coreObj, 'initialize');
+                coreObj.initialize();
+                expect(coreObj.initialize).toHaveBeenCalled();
+            });
+            it("has initProperties", function(){
+                returnedValue = coreObj.initProperties();
+                expect(typeof returnedValue).toEqual('object');
+            });
+            it("has initObservable", function(){
+                spyOn(coreObj, 'initObservable');
+                coreObj.initObservable();
+                expect(coreObj.initObservable).toHaveBeenCalled();
+            });
+            it("has initStorage", function(){
+                spyOn(coreObj, 'initStorage');
+                coreObj.initStorage();
+                expect(coreObj.initStorage).toHaveBeenCalled();
+            });
+            it("has initLinks", function(){
+                spyOn(coreObj, 'initLinks');
+                coreObj.initLinks();
+                expect(coreObj.initLinks).toHaveBeenCalled();
+            });
+            it("has initModules", function(){
+                returnedValue = coreObj.initModules();
+                expect(typeof returnedValue).toEqual('object');
+            });
+            it("has initUnique", function(){
+                returnedValue = coreObj.initUnique();
+                expect(typeof returnedValue).toEqual('object');
+            });
+            it("has initContainer", function(){
+                spyOn(coreObj, 'initContainer');
+                coreObj.initContainer();
+                expect(coreObj.initContainer).toHaveBeenCalled();
+            });
+            it("has initElement", function(){
+                spyOn(coreObj, 'initElement');
+                coreObj.initElement();
+                expect(coreObj.initElement).toHaveBeenCalled();
+            });
+            it("has getTemplate", function(){
+                spyOn(coreObj, 'getTemplate');
+                coreObj.getTemplate();
+                expect(coreObj.getTemplate).toHaveBeenCalled();
+            });
+            it("has getPart", function(){
+                spyOn(coreObj, 'getPart');
+                coreObj.getPart();
+                expect(coreObj.getPart).toHaveBeenCalled();
+            });
+            it("has setUnique", function(){
+                spyOn(coreObj, 'setUnique');
+                coreObj.setUnique();
+                expect(coreObj.setUnique).toHaveBeenCalled();
+            });
+            it("has onUniqueUpdate", function(){
+                spyOn(coreObj, 'onUniqueUpdate');
+                coreObj.onUniqueUpdate();
+                expect(coreObj.onUniqueUpdate).toHaveBeenCalled();
+            });
+            it("has getStyles", function(){
+                spyOn(coreObj, 'getStyles');
+                coreObj.getStyles();
+                expect(coreObj.getStyles).toHaveBeenCalled();
+            })
+        });
+    });
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/component/links.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/component/links.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..a1df16bb750319d52cd4709bedf465b382e796ed
--- /dev/null
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/component/links.test.js
@@ -0,0 +1,38 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+        'Magento_Ui/js/lib/component/links'
+    ], function (links) {
+        'use strict';
+
+        describe( 'Magento_Ui/js/lib/component/links', function(){
+            var linksObj,
+                returnedValue;
+
+            beforeEach(function(){
+                linksObj = links;
+                linksObj.maps = {
+                    exports: {},
+                    imports: {}
+                };
+
+            });
+            it('has defaults', function(){
+                expect(typeof linksObj.defaults).toEqual('object');
+            });
+            it('has setLinks method', function(){
+                returnedValue = linksObj.setLinks(undefined,'imports');
+                expect(typeof returnedValue).toEqual('object');
+                spyOn(linksObj, "setLinks");
+                linksObj.setLinks(undefined,'imports');
+                expect(linksObj.setLinks).toHaveBeenCalled();
+            });
+            it('has setListners method', function(){
+                spyOn(linksObj, "setListners");
+                linksObj.setListners();
+                expect(linksObj.setListners).toHaveBeenCalled();
+            });
+        });
+    });
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/component/manip.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/component/manip.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..17a69538866dc5a9667a023e44c0b1b8b5164c97
--- /dev/null
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/component/manip.test.js
@@ -0,0 +1,67 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+        'Magento_Ui/js/lib/component/manip'
+    ], function (manip) {
+        'use strict';
+
+        describe( 'Magento_Ui/js/lib/component/manip', function(){
+            var manipObj,
+                returnedValue;
+
+            beforeEach(function(){
+                manipObj = manip;
+            });
+            it('has getRegion method', function(){
+                returnedValue = manipObj.getRegion("region");
+                expect(returnedValue).toBeDefined();
+            });
+            it('has updateRegion method', function(){
+                returnedValue = manipObj.updateRegion([],"region");
+                expect(typeof returnedValue).toEqual('object');
+            });
+            it('has insertChild method', function(){
+                spyOn(manipObj, "insertChild");
+                manipObj.insertChild();
+                expect(manipObj.insertChild).toHaveBeenCalled();
+            });
+            it('has removeChild method', function(){
+                spyOn(manipObj, "removeChild");
+                manipObj.removeChild();
+                expect(manipObj.removeChild).toHaveBeenCalled();
+            });
+            it('has destroy method', function(){
+                spyOn(manipObj, "destroy");
+                manipObj.destroy();
+                expect(manipObj.destroy).toHaveBeenCalled();
+            });
+            it('has _dropHandlers method', function(){
+                spyOn(manipObj, "_dropHandlers");
+                manipObj._dropHandlers();
+                expect(manipObj._dropHandlers).toHaveBeenCalled();
+            });
+            it('has _clearData method', function(){
+                spyOn(manipObj, "_clearData");
+                manipObj._clearData();
+                expect(manipObj._clearData).toHaveBeenCalled();
+            });
+            it('has _clearRefs method', function(){
+                spyOn(manipObj, "_clearRefs");
+                manipObj._clearRefs();
+                expect(manipObj._clearRefs).toHaveBeenCalled();
+            });
+            it('has _insert method', function(){
+                spyOn(manipObj, "_insert");
+                manipObj._insert();
+                expect(manipObj._insert).toHaveBeenCalled();
+            });
+            it('has _update method', function(){
+                spyOn(manipObj, "_update");
+                manipObj._update();
+                expect(manipObj._update).toHaveBeenCalled();
+            });
+
+        });
+    });
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/component/provider.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/component/provider.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..62b6d6865f92e3a9c8bddb2f21180196b1f7acf3
--- /dev/null
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/component/provider.test.js
@@ -0,0 +1,42 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+        'Magento_Ui/js/lib/component/provider'
+    ], function (provider) {
+        'use strict';
+
+        describe( 'Magento_Ui/js/lib/component/provider', function(){
+            var providerObj,
+                returnedValue;
+
+            beforeEach(function(){
+                providerObj = provider;
+            });
+            it('has observe method', function(){
+                returnedValue = providerObj.observe("elems");
+                expect(typeof  returnedValue).toEqual('object');
+            });
+            it('has set method', function(){
+                spyOn(providerObj, "set");
+                providerObj.set();
+                expect(providerObj.set).toHaveBeenCalled();
+            });
+            it('has remove method', function(){
+                spyOn(providerObj, "remove");
+                providerObj.remove();
+                expect(providerObj.remove).toHaveBeenCalled();
+            });
+            it('has restore method', function(){
+                spyOn(providerObj, "restore");
+                providerObj.restore();
+                expect(providerObj.restore).toHaveBeenCalled();
+            });
+            it('has removeStored method', function(){
+                spyOn(providerObj, "removeStored");
+                providerObj.removeStored();
+                expect(providerObj.removeStored).toHaveBeenCalled();
+            });
+        });
+    });
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/component/traversal.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/component/traversal.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..e87ef36e0deaf257926bbcb5a7973b28b3c3d861
--- /dev/null
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/component/traversal.test.js
@@ -0,0 +1,22 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+        'Magento_Ui/js/lib/component/traversal'
+    ], function (traversal) {
+        'use strict';
+
+        describe( 'Magento_Ui/js/lib/component/traversal', function(){
+            var traversalObj;
+
+            beforeEach(function(){
+                traversalObj = traversal;
+            });
+            it('has delegate method', function(){
+                spyOn(traversalObj, "delegate");
+                traversalObj.delegate();
+                expect(traversalObj.delegate).toHaveBeenCalled();
+            });
+        });
+    });
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/registry/events.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/registry/events.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..7499eb7e8d5dd80765ada34c410c36eddd30dbf8
--- /dev/null
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/registry/events.test.js
@@ -0,0 +1,58 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+
+define([
+    'Magento_Ui/js/lib/registry/events'
+], function (EventBus) {
+    'use strict';
+
+    describe('Magento_Ui/js/lib/registry/events', function () {
+        var storage = {
+                has : function(){
+                    return false;
+                },
+                get : function(){
+                    return [];
+                }
+            },
+            eventsClass = new EventBus(storage);
+
+        describe('"resolve" method', function () {
+            it('Check for defined ', function () {
+                expect(eventsClass.resolve()).toBeDefined();
+            });
+            it('Check answer type', function () {
+                var type = typeof(eventsClass.resolve());
+
+                expect(type).toEqual('object');
+            });
+        });
+        describe('"wait" method', function () {
+            it('Check for defined ', function () {
+                expect(eventsClass.wait([],{})).toBeDefined();
+            });
+            it('Check return object property "requests" defined', function () {
+                var thisObject = eventsClass.wait([],{}).requests;
+
+                expect(thisObject).toBeDefined();
+            });
+            it('Check return object property "requests" type', function () {
+                var thisObject = typeof(eventsClass.wait([],{}).requests);
+
+                expect(thisObject).toEqual('object');
+            });
+        });
+        describe('"_resolve" method', function () {
+            it('Check completion method', function () {
+                eventsClass.request = [{
+                    callback: function(){return true;},
+                    deps: {}
+                }];
+                expect(eventsClass._resolve(0)).toEqual(false);
+            });
+        });
+    });
+});
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/registry/registry.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/registry/registry.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..14bde78ef98664f679e99c0dfb1472c81fa47ee4
--- /dev/null
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/registry/registry.test.js
@@ -0,0 +1,169 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+
+define([
+    'Magento_Ui/js/lib/registry/registry'
+], function (registry) {
+    'use strict';
+
+    describe('Magento_Ui/js/lib/registry/registry', function () {
+        describe('"registry" object', function () {
+            it('Check for defined ', function () {
+                expect(registry).toBeDefined();
+            });
+            it('Check type', function () {
+                var type = typeof(registry);
+
+                expect(type).toEqual('object');
+            });
+        });
+        describe('"registry.set" method', function () {
+            it('Check for defined', function () {
+                expect(registry.hasOwnProperty('set')).toBeDefined();
+            });
+            it('Check type', function () {
+                var type = typeof(registry.set);
+
+                expect(type).toEqual('function');
+            });
+            it('Check returned value', function () {
+                expect(registry.set()).toBeDefined();
+            });
+            it('Check returned value type', function () {
+                var type = typeof(registry.set());
+
+                expect(type).toEqual('object');
+            });
+            it('Check assigned value after used method', function () {
+                var elem = 'test',
+                    prop = 'magento';
+                
+                registry.set(elem, prop);
+                expect(registry.storage.data[elem]).toEqual(prop);
+            });
+        });
+        describe('"registry.get" method', function () {
+            it('Check for defined', function () {
+                expect(registry.hasOwnProperty('get')).toBeDefined();
+            });
+            it('Check type', function () {
+                var type = typeof(registry.get);
+
+                expect(type).toEqual('function');
+            });
+            it('Check returned value if method called without arguments', function () {
+                expect(registry.get()).toBeDefined();
+            });
+            it('Check returned value type if method called without arguments', function () {
+                var type = registry.get() instanceof Array;
+
+                expect(type).toEqual(true);
+            });
+            it('Check called callback with arguments', function () {
+                var elems = ['magento'],
+                    callback = function(){};
+                registry.events.wait = jasmine.createSpy();
+                registry.get(elems, callback);
+                expect(registry.events.wait).toHaveBeenCalledWith(elems, callback);
+            });
+        });
+        describe('"registry.remove" method', function () {
+            it('Check for defined', function () {
+                expect(registry.hasOwnProperty('remove')).toBeDefined();
+            });
+            it('Check type', function () {
+                var type = typeof(registry.remove);
+
+                expect(type).toEqual('function');
+            });
+            it('Check returned value if method called with arguments', function () {
+                expect(registry.remove('magento')).toBeDefined();
+            });
+            it('Check returned value type if method called without arguments', function () {
+                var type = typeof registry.remove('magento');
+
+                expect(type).toEqual('object');
+            });
+            it('Check called registry.storage.remove with arguments', function () {
+                var elems = ['magento'];
+
+                registry.storage.remove = jasmine.createSpy();
+                registry.remove(elems);
+                expect(registry.storage.remove).toHaveBeenCalledWith(elems);
+            });
+        });
+        describe('"registry.has" method', function () {
+            it('Check for defined', function () {
+                expect(registry.hasOwnProperty('has')).toBeDefined();
+            });
+            it('Check type', function () {
+                var type = typeof(registry.has);
+
+                expect(type).toEqual('function');
+            });
+            it('Check returned value if registry.storage has property', function () {
+                var name = 'magento',
+                    value = 'magentoValue';
+
+                registry.storage.data[name] = value;
+                expect(registry.has(name)).toEqual(true);
+            });
+            it('Check returned value if registry.storage has not property', function () {
+                var name = 'magentoNonProperty';
+
+                expect(registry.has(name)).toEqual(false);
+            });
+            it('Check called registry.storage.has with arguments', function () {
+                var elems = ['magento'];
+
+                registry.storage.has = jasmine.createSpy();
+                registry.has(elems);
+                expect(registry.storage.has).toHaveBeenCalledWith(elems);
+            });
+        });
+        describe('"registry.async" method', function () {
+            it('Check for defined', function () {
+                expect(registry.hasOwnProperty('async')).toBeDefined();
+            });
+            it('Check type', function () {
+                var type = typeof(registry.async);
+
+                expect(type).toEqual('function');
+            })
+        });
+        describe('"registry.create" method', function () {
+            it('Check for defined', function () {
+                expect(registry.hasOwnProperty('create')).toBeDefined();
+            });
+            it('Check type', function () {
+                var type = typeof(registry.async);
+
+                expect(type).toEqual('function');
+            });
+            it('Check returned value type if method called without arguments', function () {
+                var type = typeof registry.remove('magento');
+
+                expect(type).toEqual('object');
+            });
+            it('Check registry.storage for defined', function () {
+                registry.create();
+                expect(registry.storage).toBeDefined();
+            });
+            it('Check registry.storage type', function () {
+                registry.create();
+                expect(typeof registry.storage).toEqual('object');
+            });
+            it('Check registry.events for defined', function () {
+                registry.create();
+                expect(registry.events).toBeDefined();
+            });
+            it('Check registry.events type', function () {
+                registry.create();
+                expect(typeof registry.events).toEqual('object');
+            });
+        });
+    });
+});
diff --git a/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/registry/storage.test.js b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/registry/storage.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..393892df2025a035ead1f9e264713231fe88cfe3
--- /dev/null
+++ b/dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/registry/storage.test.js
@@ -0,0 +1,121 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+
+define([
+    'Magento_Ui/js/lib/registry/storage'
+], function (Storage) {
+    'use strict';
+
+    describe('Magento_Ui/js/lib/registry/storage', function () {
+        var storage = new Storage();
+        describe('"Storage constructor"', function () {
+            it('Check for defined', function () {
+                expect(storage).toBeDefined();
+            });
+            it('Check type', function () {
+                var type = typeof(storage);
+
+                expect(type).toEqual('object');
+            });
+            it('Check storage.data for defined', function () {
+                var data = storage.data;
+
+                expect(typeof data).toEqual('object');
+            });
+        });
+        describe('"storage.get" method', function () {
+            it('Check for defined', function () {
+                expect(storage.hasOwnProperty('get')).toBeDefined();
+            });
+            it('Check type', function () {
+                var type = typeof(storage.get);
+
+                expect(type).toEqual('function');
+            });
+            it('Check returned value if argument is array values', function () {
+                var elem = 'magento',
+                    value = 'magentoValue';
+
+                storage.data[elem] = value;
+                expect(storage.get([elem])).toEqual([value]);
+            });
+            it('Check returned value if called withot arguments', function () {
+                expect(storage.get()).toEqual([]);
+            });
+        });
+        describe('"storage.set" method', function () {
+            it('Check for defined', function () {
+                expect(storage.hasOwnProperty('set')).toBeDefined();
+            });
+            it('Check type', function () {
+                var type = typeof(storage.set);
+
+                expect(type).toEqual('function');
+            });
+            it('Check returned value for defined', function () {
+                expect(storage.set()).toBeDefined();
+            });
+            it('Check returned value type', function () {
+                var type = typeof(storage.set());
+
+                expect(type).toEqual('object');
+            });
+            it('Check returned value if argument is "elem, value" ', function () {
+                var elem = 'magento',
+                    value = 'magentoValue';
+
+                storage.set(elem, value);
+                expect(storage.data[elem]).toEqual(value);
+            });
+        });
+        describe('"storage.remove" method', function () {
+            it('Check for defined', function () {
+                expect(storage.hasOwnProperty('remove')).toBeDefined();
+            });
+            it('Check type', function () {
+                var type = typeof(storage.remove);
+
+                expect(type).toEqual('function');
+            });
+            it('Check returned value for defined', function () {
+                expect(storage.remove([])).toBeDefined();
+            });
+            it('Check returned value type', function () {
+                var type = typeof(storage.remove([]));
+
+                expect(type).toEqual('object');
+            });
+            it('Check if called with argument "elem" ', function () {
+                var elem = ['magento'],
+                    value = 'magentoValue';
+
+                storage.data[elem] = value;
+                storage.remove(elem);
+                expect(storage.data[elem]).not.toBeDefined();
+            });
+        });
+        describe('"storage.has" method', function () {
+            it('Check for defined', function () {
+                expect(storage.hasOwnProperty('has')).toBeDefined();
+            });
+            it('Check type', function () {
+                var type = typeof(storage.has);
+
+                expect(type).toEqual('function');
+            });
+            it('Check returned value if data has element property', function () {
+                var elem = 'magento',
+                    value = 'magentoValue';
+
+                storage.data[elem] = value;
+                expect(storage.has([elem])).toEqual(true);
+            });
+            it('Check returned value if data has not element property', function () {
+                expect(storage.has(['value'])).toEqual(false);
+            });
+        });
+    });
+});
diff --git a/dev/tests/js/jasmine/tests/lib/mage/requirejs/static-text.test.js b/dev/tests/js/jasmine/tests/lib/mage/requirejs/static-text.test.js
index d593e224d66ca16a3e21c9368f3e94774d89dc35..b5bd195fc62016fd2a31e6e65afa0354c62fb3aa 100644
--- a/dev/tests/js/jasmine/tests/lib/mage/requirejs/static-text.test.js
+++ b/dev/tests/js/jasmine/tests/lib/mage/requirejs/static-text.test.js
@@ -27,8 +27,10 @@ define([
             require([
                 external.path
             ], function (data) {
+                var regExp = /\s+/g;
+
                 expect(text._load).toHaveBeenCalled();
-                expect(data).toEqual(external.result);
+                expect(data.replace(regExp,' ')).toEqual(external.result.replace(regExp,' '));
 
                 done();
             });
diff --git a/dev/tests/static/testsuite/Magento/Test/Js/LiveCodeTest.php b/dev/tests/static/testsuite/Magento/Test/Js/LiveCodeTest.php
index 0a1aa90f1534770d6b2997583b904029f536c0f6..3e05589de50b79c40c641999b7ba87004a7ad389 100644
--- a/dev/tests/static/testsuite/Magento/Test/Js/LiveCodeTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Js/LiveCodeTest.php
@@ -64,8 +64,8 @@ class LiveCodeTest extends \PHPUnit_Framework_TestCase
         }
         self::$_reportFile = $reportDir . '/js_report.txt';
         @unlink(self::$_reportFile);
-        $whiteList = Files::readLists(__DIR__ . '/_files/whitelist/*.txt');
-        $blackList = Files::readLists(__DIR__ . '/_files/blacklist/*.txt');
+        $whiteList = Files::readLists(__DIR__ . '/_files/jshint/whitelist/*.txt');
+        $blackList = Files::readLists(__DIR__ . '/_files/jshint/blacklist/*.txt');
         foreach ($blackList as $listFiles) {
             self::$_blackListJsFiles = array_merge(self::$_blackListJsFiles, self::_scanJsFile($listFiles));
         }
diff --git a/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/magento.txt b/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/magento.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a9b8c53a6636eb6c32994373ce2b4cd8578e7c20
--- /dev/null
+++ b/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/magento.txt
@@ -0,0 +1,564 @@
+app/code/Magento/AdminNotification/view/adminhtml/requirejs-config.js
+app/code/Magento/AdminNotification/view/adminhtml/web/system/notification.js
+app/code/Magento/AdminNotification/view/adminhtml/web/toolbar_entry.js
+app/code/Magento/Authorizenet/view/adminhtml/web/js/direct-post.js
+app/code/Magento/Authorizenet/view/frontend/requirejs-config.js
+app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/authorizenet.js
+app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/method-renderer/authorizenet-directpost.js
+app/code/Magento/Backend/view/adminhtml/web/js/bootstrap/editor.js
+app/code/Magento/Braintree/view/adminhtml/requirejs-config.js
+app/code/Magento/Braintree/view/adminhtml/web/js/cc-data.js
+app/code/Magento/Braintree/view/adminhtml/web/js/cc-form.js
+app/code/Magento/Braintree/view/frontend/requirejs-config.js
+app/code/Magento/Braintree/view/frontend/web/js/braintree-paypal-shortcut.js
+app/code/Magento/Braintree/view/frontend/web/js/cc-data.js
+app/code/Magento/Braintree/view/frontend/web/js/cc-edit-form.js
+app/code/Magento/Braintree/view/frontend/web/js/cc-form.js
+app/code/Magento/Braintree/view/frontend/web/js/view/payment/braintree-methods.js
+app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/braintree-paypal.js
+app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/cc-form.js
+app/code/Magento/Bundle/view/adminhtml/web/js/bundle-product.js
+app/code/Magento/Bundle/view/base/web/js/price-bundle.js
+app/code/Magento/Bundle/view/frontend/requirejs-config.js
+app/code/Magento/Bundle/view/frontend/web/js/float.js
+app/code/Magento/Bundle/view/frontend/web/js/product-summary.js
+app/code/Magento/Bundle/view/frontend/web/js/slide.js
+app/code/Magento/Captcha/view/frontend/requirejs-config.js
+app/code/Magento/Captcha/view/frontend/web/captcha.js
+app/code/Magento/Captcha/view/frontend/web/js/action/refresh.js
+app/code/Magento/Captcha/view/frontend/web/js/model/captcha.js
+app/code/Magento/Captcha/view/frontend/web/js/model/captchaList.js
+app/code/Magento/Captcha/view/frontend/web/js/view/checkout/defaultCaptcha.js
+app/code/Magento/Captcha/view/frontend/web/js/view/checkout/loginCaptcha.js
+app/code/Magento/Captcha/view/frontend/web/onepage.js
+app/code/Magento/Catalog/view/adminhtml/requirejs-config.js
+app/code/Magento/Catalog/view/adminhtml/web/catalog/base-image-uploader.js
+app/code/Magento/Catalog/view/adminhtml/web/catalog/category/edit.js
+app/code/Magento/Catalog/view/adminhtml/web/catalog/category/form.js
+app/code/Magento/Catalog/view/adminhtml/web/catalog/product-attributes.js
+app/code/Magento/Catalog/view/adminhtml/web/catalog/product.js
+app/code/Magento/Catalog/view/adminhtml/web/catalog/product/composite/configure.js
+app/code/Magento/Catalog/view/adminhtml/web/catalog/type-switcher.js
+app/code/Magento/Catalog/view/adminhtml/web/js/category-tree.js
+app/code/Magento/Catalog/view/adminhtml/web/js/custom-options.js
+app/code/Magento/Catalog/view/adminhtml/web/js/new-category-dialog.js
+app/code/Magento/Catalog/view/adminhtml/web/js/product-gallery.js
+app/code/Magento/Catalog/view/base/web/js/price-box.js
+app/code/Magento/Catalog/view/base/web/js/price-option-date.js
+app/code/Magento/Catalog/view/base/web/js/price-option-file.js
+app/code/Magento/Catalog/view/base/web/js/price-options.js
+app/code/Magento/Catalog/view/base/web/js/price-utils.js
+app/code/Magento/Catalog/view/base/web/js/tier-price.js
+app/code/Magento/Catalog/view/frontend/requirejs-config.js
+app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js
+app/code/Magento/Catalog/view/frontend/web/js/compare.js
+app/code/Magento/Catalog/view/frontend/web/js/gallery.js
+app/code/Magento/Catalog/view/frontend/web/js/list.js
+app/code/Magento/Catalog/view/frontend/web/js/product/list/toolbar.js
+app/code/Magento/Catalog/view/frontend/web/js/related-products.js
+app/code/Magento/Catalog/view/frontend/web/js/upsell-products.js
+app/code/Magento/Catalog/view/frontend/web/js/view/compare-products.js
+app/code/Magento/Catalog/view/frontend/web/js/view/image.js
+app/code/Magento/Catalog/view/frontend/web/js/zoom.js
+app/code/Magento/Catalog/view/frontend/web/product/view/validation.js
+app/code/Magento/CatalogSearch/view/frontend/requirejs-config.js
+app/code/Magento/Checkout/view/frontend/requirejs-config.js
+app/code/Magento/Checkout/view/frontend/web/js/action/create-billing-address.js
+app/code/Magento/Checkout/view/frontend/web/js/action/create-shipping-address.js
+app/code/Magento/Checkout/view/frontend/web/js/action/get-totals.js
+app/code/Magento/Checkout/view/frontend/web/js/action/place-order.js
+app/code/Magento/Checkout/view/frontend/web/js/action/select-billing-address.js
+app/code/Magento/Checkout/view/frontend/web/js/action/select-payment-method.js
+app/code/Magento/Checkout/view/frontend/web/js/action/select-shipping-address.js
+app/code/Magento/Checkout/view/frontend/web/js/action/select-shipping-method.js
+app/code/Magento/Checkout/view/frontend/web/js/action/set-payment-information.js
+app/code/Magento/Checkout/view/frontend/web/js/action/set-shipping-information.js
+app/code/Magento/Checkout/view/frontend/web/js/discount-codes.js
+app/code/Magento/Checkout/view/frontend/web/js/model/address-converter.js
+app/code/Magento/Checkout/view/frontend/web/js/model/error-processor.js
+app/code/Magento/Checkout/view/frontend/web/js/model/new-customer-address.js
+app/code/Magento/Checkout/view/frontend/web/js/model/payment-service.js
+app/code/Magento/Checkout/view/frontend/web/js/model/payment/method-converter.js
+app/code/Magento/Checkout/view/frontend/web/js/model/payment/method-list.js
+app/code/Magento/Checkout/view/frontend/web/js/model/payment/renderer-list.js
+app/code/Magento/Checkout/view/frontend/web/js/model/postcode-validator.js
+app/code/Magento/Checkout/view/frontend/web/js/model/quote.js
+app/code/Magento/Checkout/view/frontend/web/js/model/resource-url-manager.js
+app/code/Magento/Checkout/view/frontend/web/js/model/shipping-address/form-popup-state.js
+app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-processor/customer-address.js
+app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-processor/new-address.js
+app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-registry.js
+app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rate-service.js
+app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validation-rules.js
+app/code/Magento/Checkout/view/frontend/web/js/model/shipping-rates-validator.js
+app/code/Magento/Checkout/view/frontend/web/js/model/shipping-save-processor.js
+app/code/Magento/Checkout/view/frontend/web/js/model/shipping-save-processor/default.js
+app/code/Magento/Checkout/view/frontend/web/js/model/shipping-service.js
+app/code/Magento/Checkout/view/frontend/web/js/model/sidebar.js
+app/code/Magento/Checkout/view/frontend/web/js/model/step-loader.js
+app/code/Magento/Checkout/view/frontend/web/js/model/step-navigator.js
+app/code/Magento/Checkout/view/frontend/web/js/model/totals.js
+app/code/Magento/Checkout/view/frontend/web/js/model/url-builder.js
+app/code/Magento/Checkout/view/frontend/web/js/opc-billing-info.js
+app/code/Magento/Checkout/view/frontend/web/js/opc-checkout-method.js
+app/code/Magento/Checkout/view/frontend/web/js/opc-order-review.js
+app/code/Magento/Checkout/view/frontend/web/js/opc-payment-info.js
+app/code/Magento/Checkout/view/frontend/web/js/opc-shipping-info.js
+app/code/Magento/Checkout/view/frontend/web/js/opc-shipping-method.js
+app/code/Magento/Checkout/view/frontend/web/js/opcheckout.js
+app/code/Magento/Checkout/view/frontend/web/js/payment-authentication.js
+app/code/Magento/Checkout/view/frontend/web/js/payment.js
+app/code/Magento/Checkout/view/frontend/web/js/proceed-to-checkout.js
+app/code/Magento/Checkout/view/frontend/web/js/region-updater.js
+app/code/Magento/Checkout/view/frontend/web/js/shopping-cart.js
+app/code/Magento/Checkout/view/frontend/web/js/sidebar.js
+app/code/Magento/Checkout/view/frontend/web/js/view/authentication.js
+app/code/Magento/Checkout/view/frontend/web/js/view/beforePlaceOrder.js
+app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js
+app/code/Magento/Checkout/view/frontend/web/js/view/estimation.js
+app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js
+app/code/Magento/Checkout/view/frontend/web/js/view/payment.js
+app/code/Magento/Checkout/view/frontend/web/js/view/payment/default.js
+app/code/Magento/Checkout/view/frontend/web/js/view/payment/list.js
+app/code/Magento/Checkout/view/frontend/web/js/view/progress-bar.js
+app/code/Magento/Checkout/view/frontend/web/js/view/registration.js
+app/code/Magento/Checkout/view/frontend/web/js/view/review/actions.js
+app/code/Magento/Checkout/view/frontend/web/js/view/review/actions/default.js
+app/code/Magento/Checkout/view/frontend/web/js/view/shipping-address/address-renderer/default.js
+app/code/Magento/Checkout/view/frontend/web/js/view/shipping-address/list.js
+app/code/Magento/Checkout/view/frontend/web/js/view/shipping-information.js
+app/code/Magento/Checkout/view/frontend/web/js/view/shipping-information/address-renderer/default.js
+app/code/Magento/Checkout/view/frontend/web/js/view/shipping-information/list.js
+app/code/Magento/Checkout/view/frontend/web/js/view/shipping.js
+app/code/Magento/Checkout/view/frontend/web/js/view/sidebar.js
+app/code/Magento/Checkout/view/frontend/web/js/view/summary.js
+app/code/Magento/Checkout/view/frontend/web/js/view/summary/abstract-total.js
+app/code/Magento/Checkout/view/frontend/web/js/view/summary/cart-items.js
+app/code/Magento/Checkout/view/frontend/web/js/view/summary/grand-total.js
+app/code/Magento/Checkout/view/frontend/web/js/view/summary/item/details.js
+app/code/Magento/Checkout/view/frontend/web/js/view/summary/item/details/subtotal.js
+app/code/Magento/Checkout/view/frontend/web/js/view/summary/item/details/thumbnail.js
+app/code/Magento/Checkout/view/frontend/web/js/view/summary/shipping.js
+app/code/Magento/Checkout/view/frontend/web/js/view/summary/subtotal.js
+app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkout-agreements-link.js
+app/code/Magento/CheckoutAgreements/view/frontend/web/js/view/checkout-agreements-modal.js
+app/code/Magento/Cms/view/adminhtml/requirejs-config.js
+app/code/Magento/Cms/view/adminhtml/web/js/folder-tree.js
+app/code/Magento/ConfigurableProduct/view/adminhtml/requirejs-config.js
+app/code/Magento/ConfigurableProduct/view/adminhtml/web/catalog/product/attribute.js
+app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/configurable.js
+app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/attributes_values.js
+app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/bulk.js
+app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/select_attributes.js
+app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/summary.js
+app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js
+app/code/Magento/ConfigurableProduct/view/frontend/requirejs-config.js
+app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js
+app/code/Magento/Cookie/View/adminhtml/requirejs-config.js
+app/code/Magento/Cookie/View/frontend/requirejs-config.js
+app/code/Magento/Cookie/View/frontend/web/js/notices.js
+app/code/Magento/Cookie/View/frontend/web/js/require-cookie.js
+app/code/Magento/Customer/view/adminhtml/requirejs-config.js
+app/code/Magento/Customer/view/adminhtml/web/edit/tab/js/addresses.js
+app/code/Magento/Customer/view/frontend/requirejs-config.js
+app/code/Magento/Customer/view/frontend/web/address.js
+app/code/Magento/Customer/view/frontend/web/js/action/check-email-availability.js
+app/code/Magento/Customer/view/frontend/web/js/action/login.js
+app/code/Magento/Customer/view/frontend/web/js/checkout-balance.js
+app/code/Magento/Customer/view/frontend/web/js/customer-data.js
+app/code/Magento/Customer/view/frontend/web/js/model/address-list.js
+app/code/Magento/Customer/view/frontend/web/js/model/authentication-popup.js
+app/code/Magento/Customer/view/frontend/web/js/model/customer-addresses.js
+app/code/Magento/Customer/view/frontend/web/js/model/customer.js
+app/code/Magento/Customer/view/frontend/web/js/model/customer/address.js
+app/code/Magento/Customer/view/frontend/web/js/section-config.js
+app/code/Magento/Customer/view/frontend/web/js/view/authentication-popup.js
+app/code/Magento/Customer/view/frontend/web/js/view/customer-email.js
+app/code/Magento/Customer/view/frontend/web/js/view/customer.js
+app/code/Magento/Customer/view/frontend/web/set-password.js
+app/code/Magento/DesignEditor/view/adminhtml/requirejs-config.js
+app/code/Magento/DesignEditor/view/adminhtml/web/js/bootstrap/edit.js
+app/code/Magento/DesignEditor/view/adminhtml/web/js/bootstrap/launch.js
+app/code/Magento/DesignEditor/view/adminhtml/web/js/custom-css.js
+app/code/Magento/DesignEditor/view/adminhtml/web/js/dialog.js
+app/code/Magento/DesignEditor/view/adminhtml/web/js/image-sizing.js
+app/code/Magento/DesignEditor/view/adminhtml/web/js/infinitescroll.js
+app/code/Magento/DesignEditor/view/adminhtml/web/js/message.js
+app/code/Magento/DesignEditor/view/adminhtml/web/js/quick-style-element.js
+app/code/Magento/DesignEditor/view/adminhtml/web/js/quick-style-uploader.js
+app/code/Magento/DesignEditor/view/adminhtml/web/js/theme-assign.js
+app/code/Magento/DesignEditor/view/adminhtml/web/js/theme-delete.js
+app/code/Magento/DesignEditor/view/adminhtml/web/js/theme-edit.js
+app/code/Magento/DesignEditor/view/adminhtml/web/js/theme-revert.js
+app/code/Magento/DesignEditor/view/adminhtml/web/js/theme-save.js
+app/code/Magento/DesignEditor/view/adminhtml/web/js/theme-selector.js
+app/code/Magento/DesignEditor/view/adminhtml/web/js/tools-files.js
+app/code/Magento/DesignEditor/view/adminhtml/web/js/tools-panel.js
+app/code/Magento/DesignEditor/view/adminhtml/web/js/tools.js
+app/code/Magento/DesignEditor/view/adminhtml/web/js/vde-frame.js
+app/code/Magento/Dhl/view/frontend/web/js/model/shipping-rates-validation-rules.js
+app/code/Magento/Dhl/view/frontend/web/js/model/shipping-rates-validator.js
+app/code/Magento/Dhl/view/frontend/web/js/view/shipping-rates-validation.js
+app/code/Magento/Downloadable/view/frontend/requirejs-config.js
+app/code/Magento/Downloadable/view/frontend/web/downloadable.js
+app/code/Magento/Fedex/view/frontend/web/js/model/shipping-rates-validation-rules.js
+app/code/Magento/Fedex/view/frontend/web/js/model/shipping-rates-validator.js
+app/code/Magento/Fedex/view/frontend/web/js/view/shipping-rates-validation.js
+app/code/Magento/GiftMessage/view/frontend/requirejs-config.js
+app/code/Magento/GiftMessage/view/frontend/web/extra-options.js
+app/code/Magento/GiftMessage/view/frontend/web/gift-options.js
+app/code/Magento/GiftMessage/view/frontend/web/js/action/gift-options.js
+app/code/Magento/GiftMessage/view/frontend/web/js/model/gift-message.js
+app/code/Magento/GiftMessage/view/frontend/web/js/model/gift-options.js
+app/code/Magento/GiftMessage/view/frontend/web/js/model/url-builder.js
+app/code/Magento/GiftMessage/view/frontend/web/js/view/gift-message.js
+app/code/Magento/GroupedProduct/view/adminhtml/requirejs-config.js
+app/code/Magento/GroupedProduct/view/adminhtml/web/js/grouped-product.js
+app/code/Magento/Integration/view/adminhtml/requirejs-config.js
+app/code/Magento/Integration/view/adminhtml/web/js/integration.js
+app/code/Magento/Msrp/view/base/web/js/msrp.js
+app/code/Magento/Msrp/view/frontend/requirejs-config.js
+app/code/Magento/Multishipping/view/frontend/requirejs-config.js
+app/code/Magento/Multishipping/view/frontend/web/js/multi-shipping.js
+app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/method-renderer/banktransfer-method.js
+app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/method-renderer/cashondelivery-method.js
+app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/method-renderer/checkmo-method.js
+app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/method-renderer/purchaseorder-method.js
+app/code/Magento/OfflinePayments/view/frontend/web/js/view/payment/offline-payments.js
+app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validation-rules/flatrate.js
+app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validation-rules/freeshipping.js
+app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validation-rules/tablerate.js
+app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validator/flatrate.js
+app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validator/freeshipping.js
+app/code/Magento/OfflineShipping/view/frontend/web/js/model/shipping-rates-validator/tablerate.js
+app/code/Magento/OfflineShipping/view/frontend/web/js/view/shipping-rates-validation/flatrate.js
+app/code/Magento/OfflineShipping/view/frontend/web/js/view/shipping-rates-validation/freeshipping.js
+app/code/Magento/OfflineShipping/view/frontend/web/js/view/shipping-rates-validation/tablerate.js
+app/code/Magento/PageCache/view/frontend/requirejs-config.js
+app/code/Magento/PageCache/view/frontend/web/js/page-cache.js
+app/code/Magento/Payment/view/adminhtml/web/transparent.js
+app/code/Magento/Payment/view/frontend/requirejs-config.js
+app/code/Magento/Payment/view/frontend/web/cc-type.js
+app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/credit-card-data.js
+app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/credit-card-number-validator.js
+app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/credit-card-number-validator/credit-card-type.js
+app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/credit-card-number-validator/luhn10-validator.js
+app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/cvv-validator.js
+app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator.js
+app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator/expiration-month-validator.js
+app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator/expiration-year-validator.js
+app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/expiration-date-validator/parse-date.js
+app/code/Magento/Payment/view/frontend/web/js/model/credit-card-validation/validator.js
+app/code/Magento/Payment/view/frontend/web/js/view/payment/cc-form.js
+app/code/Magento/Payment/view/frontend/web/js/view/payment/iframe.js
+app/code/Magento/Payment/view/frontend/web/js/view/payment/method-renderer/free-method.js
+app/code/Magento/Payment/view/frontend/web/js/view/payment/payments.js
+app/code/Magento/Payment/view/frontend/web/transparent.js
+app/code/Magento/Paypal/view/adminhtml/web/js/predicate/confirm.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rule.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/conflict.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/disable.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/payflow/bml/disable-conditional-express.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/payflow/bml/disable-conditional.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/payflow/bml/disable.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/payflow/bml/enable-conditional.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/payflow/bml/enable.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/payflow/bml/lock-conditional.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/payflow/express/disable-conditional.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/payflow/express/disable.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/payflow/express/enable-conditional.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/payflow/express/enable.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/payflow/express/lock-conditional.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/paypal/bml/disable-conditional.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/paypal/bml/disable.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/paypal/bml/enable.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/paypal/express/disable.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/paypal/express/lock-configuration-conditional.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/paypal/express/lock-configuration.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/paypal/express/mark-disable.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/paypal/express/unlock-configuration.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/simple/disable.js
+app/code/Magento/Paypal/view/adminhtml/web/js/rules/simple/mark-enable.js
+app/code/Magento/Paypal/view/adminhtml/web/js/solution.js
+app/code/Magento/Paypal/view/adminhtml/web/js/solutions.js
+app/code/Magento/Paypal/view/base/requirejs-config.js
+app/code/Magento/Paypal/view/frontend/requirejs-config.js
+app/code/Magento/Paypal/view/frontend/web/js/action/set-payment-method.js
+app/code/Magento/Paypal/view/frontend/web/js/model/iframe-redirect.js
+app/code/Magento/Paypal/view/frontend/web/js/model/iframe.js
+app/code/Magento/Paypal/view/frontend/web/js/opcheckout.js
+app/code/Magento/Paypal/view/frontend/web/js/paypal-checkout.js
+app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/iframe-methods.js
+app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/payflow-express-bml.js
+app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/payflow-express.js
+app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/payflowpro-method.js
+app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/paypal-billing-agreement.js
+app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/paypal-express-abstract.js
+app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/paypal-express-bml.js
+app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/paypal-express.js
+app/code/Magento/Paypal/view/frontend/web/js/view/payment/paypal-payments.js
+app/code/Magento/Paypal/view/frontend/web/js/view/review/actions/iframe.js
+app/code/Magento/Paypal/view/frontend/web/order-review.js
+app/code/Magento/Persistent/view/frontend/web/js/view/remember-me.js
+app/code/Magento/Reports/view/frontend/requirejs-config.js
+app/code/Magento/Reports/view/frontend/web/js/recently-viewed.js
+app/code/Magento/Review/view/adminhtml/web/js/rating.js
+app/code/Magento/Review/view/frontend/web/js/view/review.js
+app/code/Magento/Rule/view/adminhtml/web/rules.js
+app/code/Magento/Sales/view/adminhtml/requirejs-config.js
+app/code/Magento/Sales/view/adminhtml/web/js/bootstrap/order-create-index.js
+app/code/Magento/Sales/view/adminhtml/web/order/create/form.js
+app/code/Magento/Sales/view/adminhtml/web/order/create/giftmessage.js
+app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js
+app/code/Magento/Sales/view/adminhtml/web/order/edit/message.js
+app/code/Magento/Sales/view/adminhtml/web/order/giftoptions_tooltip.js
+app/code/Magento/Sales/view/frontend/requirejs-config.js
+app/code/Magento/Sales/view/frontend/web/gift-message.js
+app/code/Magento/Sales/view/frontend/web/js/view/last-ordered-items.js
+app/code/Magento/Sales/view/frontend/web/orders-returns.js
+app/code/Magento/SalesRule/view/frontend/web/js/action/cancel-coupon.js
+app/code/Magento/SalesRule/view/frontend/web/js/action/set-coupon-code.js
+app/code/Magento/SalesRule/view/frontend/web/js/view/payment/discount.js
+app/code/Magento/SalesRule/view/frontend/web/js/view/summary/discount.js
+app/code/Magento/Search/view/frontend/requirejs-config.js
+app/code/Magento/Search/view/frontend/web/form-mini.js
+app/code/Magento/Shipping/view/adminhtml/web/order/packaging.js
+app/code/Magento/Shipping/view/frontend/web/js/model/config.js
+app/code/Magento/Shipping/view/frontend/web/js/view/checkout/shipping/shipping-policy.js
+app/code/Magento/Store/view/base/requirejs-config.js
+app/code/Magento/Store/view/base/web/js/listing/filter/store.js
+app/code/Magento/Tax/view/adminhtml/web/js/bootstrap.js
+app/code/Magento/Tax/view/frontend/web/js/view/checkout/minicart/subtotal/totals.js
+app/code/Magento/Tax/view/frontend/web/js/view/checkout/shipping_method/price.js
+app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/grand-total.js
+app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/item/details/subtotal.js
+app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/shipping.js
+app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/subtotal.js
+app/code/Magento/Tax/view/frontend/web/js/view/checkout/summary/tax.js
+app/code/Magento/Theme/view/adminhtml/requirejs-config.js
+app/code/Magento/Theme/view/adminhtml/web/js/bootstrap.js
+app/code/Magento/Theme/view/adminhtml/web/js/custom-js-list.js
+app/code/Magento/Theme/view/adminhtml/web/js/form.js
+app/code/Magento/Theme/view/adminhtml/web/js/sortable.js
+app/code/Magento/Theme/view/base/requirejs-config.js
+app/code/Magento/Theme/view/frontend/requirejs-config.js
+app/code/Magento/Theme/view/frontend/web/js/row-builder.js
+app/code/Magento/Theme/view/frontend/web/js/truncate.js
+app/code/Magento/Theme/view/frontend/web/js/view/messages.js
+app/code/Magento/Theme/view/frontend/web/menu.js
+app/code/Magento/Ui/view/base/requirejs-config.js
+app/code/Magento/Ui/view/base/web/js/block-loader.js
+app/code/Magento/Ui/view/base/web/js/core/app.js
+app/code/Magento/Ui/view/base/web/js/core/renderer/layout.js
+app/code/Magento/Ui/view/base/web/js/core/renderer/types.js
+app/code/Magento/Ui/view/base/web/js/form/adapter.js
+app/code/Magento/Ui/view/base/web/js/form/client.js
+app/code/Magento/Ui/view/base/web/js/form/components/area.js
+app/code/Magento/Ui/view/base/web/js/form/components/collection.js
+app/code/Magento/Ui/view/base/web/js/form/components/collection/item.js
+app/code/Magento/Ui/view/base/web/js/form/components/fieldset.js
+app/code/Magento/Ui/view/base/web/js/form/components/group.js
+app/code/Magento/Ui/view/base/web/js/form/components/html.js
+app/code/Magento/Ui/view/base/web/js/form/components/tab_group.js
+app/code/Magento/Ui/view/base/web/js/form/components/tab.js
+app/code/Magento/Ui/view/base/web/js/form/element/abstract.js
+app/code/Magento/Ui/view/base/web/js/form/element/boolean.js
+app/code/Magento/Ui/view/base/web/js/form/element/date.js
+app/code/Magento/Ui/view/base/web/js/form/element/multiselect.js
+app/code/Magento/Ui/view/base/web/js/form/element/post-code.js
+app/code/Magento/Ui/view/base/web/js/form/element/region.js
+app/code/Magento/Ui/view/base/web/js/form/element/select.js
+app/code/Magento/Ui/view/base/web/js/form/element/textarea.js
+app/code/Magento/Ui/view/base/web/js/form/form.js
+app/code/Magento/Ui/view/base/web/js/form/provider.js
+app/code/Magento/Ui/view/base/web/js/grid/columns/actions.js
+app/code/Magento/Ui/view/base/web/js/grid/columns/column.js
+app/code/Magento/Ui/view/base/web/js/grid/columns/date.js
+app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js
+app/code/Magento/Ui/view/base/web/js/grid/columns/select.js
+app/code/Magento/Ui/view/base/web/js/grid/columns/thumbnail.js
+app/code/Magento/Ui/view/base/web/js/grid/controls/bookmarks/bookmarks.js
+app/code/Magento/Ui/view/base/web/js/grid/controls/bookmarks/storage.js
+app/code/Magento/Ui/view/base/web/js/grid/controls/bookmarks/view.js
+app/code/Magento/Ui/view/base/web/js/grid/controls/columns.js
+app/code/Magento/Ui/view/base/web/js/grid/dnd.js
+app/code/Magento/Ui/view/base/web/js/grid/export.js
+app/code/Magento/Ui/view/base/web/js/grid/filters/chips.js
+app/code/Magento/Ui/view/base/web/js/grid/filters/filters.js
+app/code/Magento/Ui/view/base/web/js/grid/filters/group.js
+app/code/Magento/Ui/view/base/web/js/grid/listing.js
+app/code/Magento/Ui/view/base/web/js/grid/massactions.js
+app/code/Magento/Ui/view/base/web/js/grid/paging.js
+app/code/Magento/Ui/view/base/web/js/grid/provider.js
+app/code/Magento/Ui/view/base/web/js/grid/search/search.js
+app/code/Magento/Ui/view/base/web/js/lib/class.js
+app/code/Magento/Ui/view/base/web/js/lib/collapsible.js
+app/code/Magento/Ui/view/base/web/js/lib/component/core.js
+app/code/Magento/Ui/view/base/web/js/lib/component/links.js
+app/code/Magento/Ui/view/base/web/js/lib/component/main.js
+app/code/Magento/Ui/view/base/web/js/lib/component/manip.js
+app/code/Magento/Ui/view/base/web/js/lib/component/provider.js
+app/code/Magento/Ui/view/base/web/js/lib/component/traversal.js
+app/code/Magento/Ui/view/base/web/js/lib/events.js
+app/code/Magento/Ui/view/base/web/js/lib/i18n.js
+app/code/Magento/Ui/view/base/web/js/lib/ko/bind/after-render.js
+app/code/Magento/Ui/view/base/web/js/lib/ko/bind/class.js
+app/code/Magento/Ui/view/base/web/js/lib/ko/bind/datepicker.js
+app/code/Magento/Ui/view/base/web/js/lib/ko/bind/fadeVisible.js
+app/code/Magento/Ui/view/base/web/js/lib/ko/bind/keyboard.js
+app/code/Magento/Ui/view/base/web/js/lib/ko/bind/mage-init.js
+app/code/Magento/Ui/view/base/web/js/lib/ko/bind/optgroup.js
+app/code/Magento/Ui/view/base/web/js/lib/ko/bind/outer_click.js
+app/code/Magento/Ui/view/base/web/js/lib/ko/bind/scope.js
+app/code/Magento/Ui/view/base/web/js/lib/ko/bind/stop_propagation.js
+app/code/Magento/Ui/view/base/web/js/lib/ko/extender/observable_array.js
+app/code/Magento/Ui/view/base/web/js/lib/ko/initialize.js
+app/code/Magento/Ui/view/base/web/js/lib/ko/template/engine.js
+app/code/Magento/Ui/view/base/web/js/lib/ko/template/observable_source.js
+app/code/Magento/Ui/view/base/web/js/lib/loader.js
+app/code/Magento/Ui/view/base/web/js/lib/registry/events.js
+app/code/Magento/Ui/view/base/web/js/lib/registry/registry.js
+app/code/Magento/Ui/view/base/web/js/lib/registry/storage.js
+app/code/Magento/Ui/view/base/web/js/lib/renderer/renderer.js
+app/code/Magento/Ui/view/base/web/js/lib/spinner.js
+app/code/Magento/Ui/view/base/web/js/lib/step-registry.js
+app/code/Magento/Ui/view/base/web/js/lib/step-wizard.js
+app/code/Magento/Ui/view/base/web/js/lib/storage.js
+app/code/Magento/Ui/view/base/web/js/lib/validation/rules.js
+app/code/Magento/Ui/view/base/web/js/lib/validation/utils.js
+app/code/Magento/Ui/view/base/web/js/lib/validation/validator.js
+app/code/Magento/Ui/view/base/web/js/modal/alert.js
+app/code/Magento/Ui/view/base/web/js/modal/confirm.js
+app/code/Magento/Ui/view/base/web/js/modal/modal.js
+app/code/Magento/Ui/view/base/web/js/modal/modalToggle.js
+app/code/Magento/Ui/view/frontend/web/js/model/messageList.js
+app/code/Magento/Ui/view/frontend/web/js/view/messages.js
+app/code/Magento/Ups/view/frontend/web/js/model/shipping-rates-validation-rules.js
+app/code/Magento/Ups/view/frontend/web/js/model/shipping-rates-validator.js
+app/code/Magento/Ups/view/frontend/web/js/view/shipping-rates-validation.js
+app/code/Magento/User/view/adminhtml/requirejs-config.js
+app/code/Magento/User/view/adminhtml/web/app-config.js
+app/code/Magento/User/view/adminhtml/web/js/roles-tree.js
+app/code/Magento/Usps/view/frontend/web/js/model/shipping-rates-validation-rules.js
+app/code/Magento/Usps/view/frontend/web/js/model/shipping-rates-validator.js
+app/code/Magento/Usps/view/frontend/web/js/view/shipping-rates-validation.js
+app/code/Magento/Variable/view/adminhtml/web/variables.js
+app/code/Magento/Weee/view/adminhtml/requirejs-config.js
+app/code/Magento/Weee/view/adminhtml/web/js/fpt-attribute.js
+app/code/Magento/Weee/view/frontend/requirejs-config.js
+app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/item/price/row_excl_tax.js
+app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/item/price/row_incl_tax.js
+app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/item/price/weee.js
+app/code/Magento/Weee/view/frontend/web/js/view/checkout/summary/weee.js
+app/code/Magento/Weee/view/frontend/web/tax-toggle.js
+app/code/Magento/Wishlist/view/frontend/requirejs-config.js
+app/code/Magento/Wishlist/view/frontend/web/js/add-to-wishlist.js
+app/code/Magento/Wishlist/view/frontend/web/js/search.js
+app/code/Magento/Wishlist/view/frontend/web/js/view/wishlist.js
+app/code/Magento/Wishlist/view/frontend/web/wishlist.js
+app/design/adminhtml/Magento/backend/web/js/theme.js
+app/design/frontend/Magento/blank/web/js/navigation-menu.js
+app/design/frontend/Magento/blank/web/js/responsive.js
+app/design/frontend/Magento/blank/web/js/theme.js
+dev/tests/js/jasmine/tests/app/code/Magento/Msrp/frontend/js/msrp.test.js
+dev/tests/js/jasmine/tests/app/code/Magento/PageCache/frontend/js/page-cache.test.js
+dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/actions.test.js
+dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/columns/multiselect.test.js
+dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/bookmarks/bookmarks.test.js
+dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/bookmarks/storage.test.js
+dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/bookmarks/view.test.js
+dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/controls/columns.test.js
+dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/filters/filters.test.js
+dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/grid/filters/group.test.js
+dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/events.test.js
+dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/lib/ko/bind/datepicker.test.js
+dev/tests/js/jasmine/tests/app/code/Magento/Ui/base/js/modal/modal.test.js
+dev/tests/js/jasmine/tests/lib/mage/apply.test.js
+dev/tests/js/jasmine/tests/lib/mage/requirejs/static-jsbuild.test.js
+dev/tests/js/jasmine/tests/lib/mage/requirejs/static-text.test.js
+dev/tests/js/jasmine/tests/lib/mage/requirejs/statistician.test.js
+dev/tests/js/jasmine/tests/lib/mage/scripts.test.js
+dev/tests/js/jasmine/tests/lib/mage/template.test.js
+lib/web/mage/accordion.js
+lib/web/mage/adminhtml/accordion.js
+lib/web/mage/adminhtml/backup.js
+lib/web/mage/adminhtml/browser.js
+lib/web/mage/adminhtml/events.js
+lib/web/mage/adminhtml/form.js
+lib/web/mage/adminhtml/globals.js
+lib/web/mage/adminhtml/grid.js
+lib/web/mage/adminhtml/tools.js
+lib/web/mage/adminhtml/varienLoader.js
+lib/web/mage/adminhtml/wysiwyg/tiny_mce/plugins/magentovariable/editor_plugin.js
+lib/web/mage/adminhtml/wysiwyg/tiny_mce/plugins/magentowidget/editor_plugin.js
+lib/web/mage/adminhtml/wysiwyg/tiny_mce/setup.js
+lib/web/mage/adminhtml/wysiwyg/widget.js
+lib/web/mage/app/config.js
+lib/web/mage/apply/main.js
+lib/web/mage/apply/scripts.js
+lib/web/mage/backend/action-link.js
+lib/web/mage/backend/bootstrap.js
+lib/web/mage/backend/button.js
+lib/web/mage/backend/editablemultiselect.js
+lib/web/mage/backend/floating-header.js
+lib/web/mage/backend/form.js
+lib/web/mage/backend/menu.js
+lib/web/mage/backend/notification.js
+lib/web/mage/backend/suggest.js
+lib/web/mage/backend/tabs.js
+lib/web/mage/backend/tree-suggest.js
+lib/web/mage/backend/validation.js
+lib/web/mage/bootstrap.js
+lib/web/mage/calendar.js
+lib/web/mage/captcha.js
+lib/web/mage/collapsible.js
+lib/web/mage/common.js
+lib/web/mage/cookies.js
+lib/web/mage/dataPost.js
+lib/web/mage/decorate.js
+lib/web/mage/deletable-item.js
+lib/web/mage/dialog.js
+lib/web/mage/dropdown_old.js
+lib/web/mage/dropdown.js
+lib/web/mage/dropdowns.js
+lib/web/mage/edit-trigger.js
+lib/web/mage/fieldset-controls.js
+lib/web/mage/gallery-fullscreen.js
+lib/web/mage/gallery.js
+lib/web/mage/ie-class-fixer.js
+lib/web/mage/item-table.js
+lib/web/mage/layout.js
+lib/web/mage/list.js
+lib/web/mage/loader_old.js
+lib/web/mage/loader.js
+lib/web/mage/mage.js
+lib/web/mage/menu.js
+lib/web/mage/popup-window.js
+lib/web/mage/redirect-url.js
+lib/web/mage/requirejs/plugin/id-normalizer.js
+lib/web/mage/requirejs/resolver.js
+lib/web/mage/requirejs/static.js
+lib/web/mage/smart-keyboard-handler.js
+lib/web/mage/sticky.js
+lib/web/mage/storage.js
+lib/web/mage/tabs.js
+lib/web/mage/template.js
+lib/web/mage/terms.js
+lib/web/mage/toggle.js
+lib/web/mage/tooltip.js
+lib/web/mage/translate-inline-vde.js
+lib/web/mage/translate-inline.js
+lib/web/mage/translate.js
+lib/web/mage/url.js
+lib/web/mage/utils/arrays.js
+lib/web/mage/utils/compare.js
+lib/web/mage/utils/main.js
+lib/web/mage/utils/misc.js
+lib/web/mage/utils/objects.js
+lib/web/mage/utils/strings.js
+lib/web/mage/utils/template.js
+lib/web/mage/validation.js
+lib/web/mage/validation/validation.js
+lib/web/mage/view/composite.js
+lib/web/mage/webapi.js
+lib/web/mage/zoom.js
diff --git a/dev/tests/static/testsuite/Magento/Test/Js/_files/eslint/.eslintrc b/dev/tests/static/testsuite/Magento/Test/Js/_files/eslint/.eslintrc
new file mode 100644
index 0000000000000000000000000000000000000000..611105806dd4af5c87235ce4261821ffbecf01d8
--- /dev/null
+++ b/dev/tests/static/testsuite/Magento/Test/Js/_files/eslint/.eslintrc
@@ -0,0 +1,6 @@
+{
+    "extends": [
+    	"./.eslintrc-reset",
+    	"./.eslintrc-magento"
+    ]
+}
\ No newline at end of file
diff --git a/dev/tests/static/testsuite/Magento/Test/Js/_files/eslint/.eslintrc-magento b/dev/tests/static/testsuite/Magento/Test/Js/_files/eslint/.eslintrc-magento
new file mode 100644
index 0000000000000000000000000000000000000000..3e2ce35ce29a66bcedd0b94194b47096eb395dba
--- /dev/null
+++ b/dev/tests/static/testsuite/Magento/Test/Js/_files/eslint/.eslintrc-magento
@@ -0,0 +1,64 @@
+{
+    "env": {
+        "browser": true,
+        "node": true,
+        "jasmine": true,
+        "amd": true
+    },
+    "rules": {
+        "lines-around-comment": [2, {"beforeBlockComment": true}],
+        "eqeqeq": [2, "smart"],
+        "no-extend-native": 2,
+        "no-native-reassign": 2,
+        "no-use-before-define": 2,
+        "no-undef": 2,
+        "no-undef-init": 2,
+        "no-caller": 2,
+        "no-unused-vars": [2, {"vars": "all", "args": "after-used"}],
+        "strict": 2,
+        "max-depth": [2, 2],
+        "max-len": [2, 120, 4],
+        "no-cond-assign": 2,
+        "no-constant-condition": 2,
+        "no-ex-assign": 2,
+        "no-extra-boolean-cast": 2,
+        "no-extra-parens": 2,
+        "no-extra-semi": 2,
+        "no-func-assign": 2,
+        "no-inner-declarations": 2,
+        "no-invalid-regexp": 2,
+        "no-negated-in-lhs": 2,
+        "no-regex-spaces": 2,
+        "no-unreachable": 2,
+        "use-isnan": 2,
+        "valid-typeof": 2,
+        "guard-for-in": 2,
+        "no-else-return": 2,
+        "no-extra-bind": 2,
+        "no-fallthrough": 2,
+        "no-floating-decimal": 2,
+        "no-implied-eval": 2,
+        "no-lone-blocks": 2,
+        "no-loop-func": 2,
+        "no-multi-str": 2,
+        "no-proto": 2,
+        "no-redeclare": 2,
+        "no-return-assign": 2,
+        "no-self-compare": 2,
+        "no-with": 2,
+        "radix": 2,
+        "vars-on-top": 2,
+        "no-catch-shadow": 2,
+        "no-shadow": 2,
+        "max-nested-callbacks": [2, 3],
+        "no-array-constructor": 2,
+        "no-lonely-if": 2,
+        "no-new-object": 2,
+        "semi-spacing": 2,
+        "no-extra-parens": 2,
+        "operator-assignment": [2, "always"],
+        "semi": [2, "always"],
+        "strict": 2,
+        "consistent-return": 2
+    }
+}
diff --git a/dev/tests/static/testsuite/Magento/Test/Js/_files/eslint/.eslintrc-reset b/dev/tests/static/testsuite/Magento/Test/Js/_files/eslint/.eslintrc-reset
new file mode 100644
index 0000000000000000000000000000000000000000..ceb9a8c421c937553b7720f1c911c547b74af2f2
--- /dev/null
+++ b/dev/tests/static/testsuite/Magento/Test/Js/_files/eslint/.eslintrc-reset
@@ -0,0 +1,217 @@
+{
+  // http://eslint.org/docs/rules/
+
+  "ecmaFeatures": {
+    "binaryLiterals": false,                    // enable binary literals
+    "blockBindings": false,                     // enable let and const (aka block bindings)
+    "defaultParams": false,                     // enable default function parameters
+    "forOf": false,                             // enable for-of loops
+    "generators": false,                        // enable generators
+    "objectLiteralComputedProperties": false,   // enable computed object literal property names
+    "objectLiteralDuplicateProperties": false,  // enable duplicate object literal properties in strict mode
+    "objectLiteralShorthandMethods": false,     // enable object literal shorthand methods
+    "objectLiteralShorthandProperties": false,  // enable object literal shorthand properties
+    "octalLiterals": false,                     // enable octal literals
+    "regexUFlag": false,                        // enable the regular expression u flag
+    "regexYFlag": false,                        // enable the regular expression y flag
+    "templateStrings": false,                   // enable template strings
+    "unicodeCodePointEscapes": false,           // enable code point escapes
+    "jsx": false                                // enable JSX
+  },
+
+  "env": {
+    "browser": false,     // browser global variables.
+    "node": false,        // Node.js global variables and Node.js-specific rules.
+    "amd": false,         // defines require() and define() as global variables as per the amd spec.
+    "mocha": false,       // adds all of the Mocha testing global variables.
+    "jasmine": false,     // adds all of the Jasmine testing global variables for version 1.3 and 2.0.
+    "phantomjs": false,   // phantomjs global variables.
+    "jquery": false,      // jquery global variables.
+    "prototypejs": false, // prototypejs global variables.
+    "shelljs": false,     // shelljs global variables.
+  },
+
+  "globals": {
+    // e.g. "angular": true
+  },
+
+  "plugins": [
+    // e.g. "react" (must run `npm install eslint-plugin-react` first)
+  ],
+
+  "rules": {
+    ////////// Possible Errors //////////
+
+    "no-comma-dangle": 0,         // disallow trailing commas in object literals
+    "no-cond-assign": 0,          // disallow assignment in conditional expressions
+    "no-console": 0,              // disallow use of console (off by default in the node environment)
+    "no-constant-condition": 0,   // disallow use of constant expressions in conditions
+    "no-control-regex": 0,        // disallow control characters in regular expressions
+    "no-debugger": 0,             // disallow use of debugger
+    "no-dupe-keys": 0,            // disallow duplicate keys when creating object literals
+    "no-empty": 0,                // disallow empty statements
+    "no-empty-class": 0,          // disallow the use of empty character classes in regular expressions
+    "no-ex-assign": 0,            // disallow assigning to the exception in a catch block
+    "no-extra-boolean-cast": 0,   // disallow double-negation boolean casts in a boolean context
+    "no-extra-parens": 0,         // disallow unnecessary parentheses (off by default)
+    "no-extra-semi": 0,           // disallow unnecessary semicolons
+    "no-func-assign": 0,          // disallow overwriting functions written as function declarations
+    "no-inner-declarations": 0,   // disallow function or variable declarations in nested blocks
+    "no-invalid-regexp": 0,       // disallow invalid regular expression strings in the RegExp constructor
+    "no-irregular-whitespace": 0, // disallow irregular whitespace outside of strings and comments
+    "no-negated-in-lhs": 0,       // disallow negation of the left operand of an in expression
+    "no-obj-calls": 0,            // disallow the use of object properties of the global object (Math and JSON) as functions
+    "no-regex-spaces": 0,         // disallow multiple spaces in a regular expression literal
+    "no-reserved-keys": 0,        // disallow reserved words being used as object literal keys (off by default)
+    "no-sparse-arrays": 0,        // disallow sparse arrays
+    "no-unreachable": 0,          // disallow unreachable statements after a return, throw, continue, or break statement
+    "use-isnan": 0,               // disallow comparisons with the value NaN
+    "valid-jsdoc": 0,             // Ensure JSDoc comments are valid (off by default)
+    "valid-typeof": 0,            // Ensure that the results of typeof are compared against a valid string
+
+
+    ////////// Best Practices //////////
+
+    "block-scoped-var": 0,      // treat var statements as if they were block scoped (off by default)
+    "complexity": 0,            // specify the maximum cyclomatic complexity allowed in a program (off by default)
+    "consistent-return": 0,     // require return statements to either always or never specify values
+    "curly": 0,                 // specify curly brace conventions for all control statements
+    "default-case": 0,          // require default case in switch statements (off by default)
+    "dot-notation": 0,          // encourages use of dot notation whenever possible
+    "eqeqeq": 0,                // require the use of === and !==
+    "guard-for-in": 0,          // make sure for-in loops have an if statement (off by default)
+    "no-alert": 0,              // disallow the use of alert, confirm, and prompt
+    "no-caller": 0,             // disallow use of arguments.caller or arguments.callee
+    "no-div-regex": 0,          // disallow division operators explicitly at beginning of regular expression (off by default)
+    "no-else-return": 0,        // disallow else after a return in an if (off by default)
+    "no-empty-label": 0,        // disallow use of labels for anything other then loops and switches
+    "no-eq-null": 0,            // disallow comparisons to null without a type-checking operator (off by default)
+    "no-eval": 0,               // disallow use of eval()
+    "no-extend-native": 0,      // disallow adding to native types
+    "no-extra-bind": 0,         // disallow unnecessary function binding
+    "no-fallthrough": 0,        // disallow fallthrough of case statements
+    "no-floating-decimal": 0,   // disallow the use of leading or trailing decimal points in numeric literals (off by default)
+    "no-implied-eval": 0,       // disallow use of eval()-like methods
+    "no-iterator": 0,           // disallow usage of __iterator__ property
+    "no-labels": 0,             // disallow use of labeled statements
+    "no-lone-blocks": 0,        // disallow unnecessary nested blocks
+    "no-loop-func": 0,          // disallow creation of functions within loops
+    "no-multi-spaces": 0,       // disallow use of multiple spaces
+    "no-multi-str": 0,          // disallow use of multiline strings
+    "no-native-reassign": 0,    // disallow reassignments of native objects
+    "no-new": 0,                // disallow use of new operator when not part of the assignment or comparison
+    "no-new-func": 0,           // disallow use of new operator for Function object
+    "no-new-wrappers": 0,       // disallows creating new instances of String, Number, and Boolean
+    "no-octal": 0,              // disallow use of octal literals
+    "no-octal-escape": 0,       // disallow use of octal escape sequences in string literals, such as var foo = "Copyright \251";
+    "no-process-env": 0,        // disallow use of process.env (off by default)
+    "no-proto": 0,              // disallow usage of __proto__ property
+    "no-redeclare": 0,          // disallow declaring the same variable more then once
+    "no-return-assign": 0,      // disallow use of assignment in return statement
+    "no-script-url": 0,         // disallow use of javascript: urls.
+    "no-self-compare": 0,       // disallow comparisons where both sides are exactly the same (off by default)
+    "no-sequences": 0,          // disallow use of comma operator
+    "no-unused-expressions": 0, // disallow usage of expressions in statement position
+    "no-void": 0,               // disallow use of void operator (off by default)
+    "no-warning-comments": 0,   // disallow usage of configurable warning terms in comments, e.g. TODO or FIXME (off by default)
+    "no-with": 0,               // disallow use of the with statement
+    "radix": 0,                 // require use of the second argument for parseInt() (off by default)
+    "vars-on-top": 0,           // requires to declare all vars on top of their containing scope (off by default)
+    "wrap-iife": 0,             // require immediate function invocation to be wrapped in parentheses (off by default)
+    "yoda": 0,                  // require or disallow Yoda conditions
+
+
+    ////////// Strict Mode //////////
+
+    "global-strict": 0,   // (deprecated) require or disallow the "use strict" pragma in the global scope (off by default in the node environment)
+    "no-extra-strict": 0, // (deprecated) disallow unnecessary use of "use strict"; when already in strict mode
+    "strict": 0,          // controls location of Use Strict Directives
+
+
+    ////////// Variables //////////
+
+    "no-catch-shadow": 0,             // disallow the catch clause parameter name being the same as a variable in the outer scope (off by default in the node environment)
+    "no-delete-var": 0,               // disallow deletion of variables
+    "no-label-var": 0,                // disallow labels that share a name with a variable
+    "no-shadow": 0,                   // disallow declaration of variables already declared in the outer scope
+    "no-shadow-restricted-names": 0,  // disallow shadowing of names such as arguments
+    "no-undef": 0,                    // disallow use of undeclared variables unless mentioned in a /*global */ block
+    "no-undef-init": 0,               // disallow use of undefined when initializing variables
+    "no-undefined": 0,                // disallow use of undefined variable (off by default)
+    "no-unused-vars": 0,              // disallow declaration of variables that are not used in the code
+    "no-use-before-define": 0,        // disallow use of variables before they are defined
+
+
+    ////////// Node.js //////////
+
+    "handle-callback-err": 0,   // enforces error handling in callbacks (off by default) (on by default in the node environment)
+    "no-mixed-requires": 0,     // disallow mixing regular variable and require declarations (off by default) (on by default in the node environment)
+    "no-new-require": 0,        // disallow use of new operator with the require function (off by default) (on by default in the node environment)
+    "no-path-concat": 0,        // disallow string concatenation with __dirname and __filename (off by default) (on by default in the node environment)
+    "no-process-exit": 0,       // disallow process.exit() (on by default in the node environment)
+    "no-restricted-modules": 0, // restrict usage of specified node modules (off by default)
+    "no-sync": 0,               // disallow use of synchronous methods (off by default)
+
+
+    ////////// Stylistic Issues //////////
+
+    "brace-style": 0,               // enforce one true brace style (off by default)
+    "camelcase": 0,                 // require camel case names
+    "comma-spacing": 0,             // enforce spacing before and after comma
+    "comma-style": 0,               // enforce one true comma style (off by default)
+    "consistent-this": 0,           // enforces consistent naming when capturing the current execution context (off by default)
+    "eol-last": 0,                  // enforce newline at the end of file, with no multiple empty lines
+    "func-names": 0,                // require function expressions to have a name (off by default)
+    "func-style": 0,                // enforces use of function declarations or expressions (off by default)
+    "key-spacing": 0,               // enforces spacing between keys and values in object literal properties
+    "max-nested-callbacks": 0,      // specify the maximum depth callbacks can be nested (off by default)
+    "new-cap": 0,                   // require a capital letter for constructors
+    "new-parens": 0,                // disallow the omission of parentheses when invoking a constructor with no arguments
+    "no-array-constructor": 0,      // disallow use of the Array constructor
+    "no-inline-comments": 0,        // disallow comments inline after code (off by default)
+    "no-lonely-if": 0,              // disallow if as the only statement in an else block (off by default)
+    "no-mixed-spaces-and-tabs": 0,  // disallow mixed spaces and tabs for indentation
+    "no-multiple-empty-lines": 0,   // disallow multiple empty lines (off by default)
+    "no-nested-ternary": 0,         // disallow nested ternary expressions (off by default)
+    "no-new-object": 0,             // disallow use of the Object constructor
+    "no-space-before-semi": 0,      // disallow space before semicolon
+    "no-spaced-func": 0,            // disallow space between function identifier and application
+    "no-ternary": 0,                // disallow the use of ternary operators (off by default)
+    "no-trailing-spaces": 0,        // disallow trailing whitespace at the end of lines
+    "no-underscore-dangle": 0,      // disallow dangling underscores in identifiers
+    "no-wrap-func": 0,              // disallow wrapping of non-IIFE statements in parens
+    "one-var": 0,                   // allow just one var statement per function (off by default)
+    "operator-assignment": 0,       // require assignment operator shorthand where possible or prohibit it entirely (off by default)
+    "padded-blocks": 0,             // enforce padding within blocks (off by default)
+    "quote-props": 0,               // require quotes around object literal property names (off by default)
+    "quotes": 0,                    // specify whether double or single quotes should be used
+    "semi": 0,                      // require or disallow use of semicolons instead of ASI
+    "sort-vars": 0,                 // sort variables within the same declaration block (off by default)
+    "space-after-function-name": 0, // require a space after function names (off by default)
+    "space-after-keywords": 0,      // require a space after certain keywords (off by default)
+    "space-before-blocks": 0,       // require or disallow space before blocks (off by default)
+    "space-in-brackets": 0,         // require or disallow spaces inside brackets (off by default)
+    "space-in-parens": 0,           // require or disallow spaces inside parentheses (off by default)
+    "space-infix-ops": 0,           // require spaces around operators
+    "space-return-throw-case": 0,   // require a space after return, throw, and case
+    "space-unary-ops": 0,           // Require or disallow spaces before/after unary operators (words on by default, nonwords off by default)
+    "spaced-line-comment": 0,       // require or disallow a space immediately following the // in a line comment (off by default)
+    "wrap-regex": 0,                // require regex literals to be wrapped in parentheses (off by default)
+
+
+    ////////// ECMAScript 6 //////////
+
+    "no-var": 0,          // require let or const instead of var (off by default)
+    "generator-star": 0,  // enforce the position of the * in generator functions (off by default)
+
+
+    ////////// Legacy //////////
+
+    "max-depth": 0,       // specify the maximum depth that blocks can be nested (off by default)
+    "max-len": 0,         // specify the maximum length of a line in your program (off by default)
+    "max-params": 0,      // limits the number of parameters that can be used in the function declaration. (off by default)
+    "max-statements": 0,  // specify the maximum number of statement allowed in a function (off by default)
+    "no-bitwise": 0,      // disallow use of bitwise operators (off by default)
+    "no-plusplus": 0      // disallow use of unary operators, ++ and -- (off by default)
+  }
+}
\ No newline at end of file
diff --git a/dev/tests/static/testsuite/Magento/Test/Js/_files/jscs/.jscsrc b/dev/tests/static/testsuite/Magento/Test/Js/_files/jscs/.jscsrc
new file mode 100644
index 0000000000000000000000000000000000000000..96ea18895001fd3b195667caf2042c3b4f938f1d
--- /dev/null
+++ b/dev/tests/static/testsuite/Magento/Test/Js/_files/jscs/.jscsrc
@@ -0,0 +1,54 @@
+{
+    "preset": "crockford",
+    "plugins": [
+        "jscs-jsdoc"
+    ],
+    "requirePaddingNewlinesBeforeKeywords": [
+        "do",
+        "for",
+        "if",
+        "switch",
+        "case",
+        "try",
+        "void",
+        "while",
+        "with",
+        "return"
+    ],
+    "requireSpaceBeforeKeywords": [
+        "else",
+        "while",
+        "catch"
+    ],
+    "disallowMultipleLineStrings": true,
+    "validateQuoteMarks": "'",
+    "requireOperatorBeforeLineBreak": true,
+    "disallowYodaConditions": true,
+    "disallowMultipleLineBreaks": true,
+    "disallowSpacesInCallExpression": true,
+    "requirePaddingNewLinesInObjects": true,
+    "requireLineFeedAtFileEnd": true,
+    "disallowSpaceAfterObjectKeys": true,
+    "requireSpaceBeforeObjectValues": true,
+    "disallowSpaceAfterPrefixUnaryOperators": true,
+    "requireCamelCaseOrUpperCaseIdentifiers": true,
+    "validateParameterSeparator": ", ",
+    "disallowSpacesInsideObjectBrackets": "all",
+    "disallowSpacesInsideArrayBrackets": "all",
+    "requireLineBreakAfterVariableAssignment": true,
+    "requirePaddingNewLinesAfterUseStrict": true,
+    "disallowDanglingUnderscores": null,
+    "jsDoc": {
+        "checkAnnotations": {
+            "preset": "jsdoc3"
+        },
+        "enforceExistence": "exceptExports",
+        "requireParamTypes": true,
+        "checkRedundantParams": true,
+        "checkReturnTypes": true,
+        "checkRedundantReturns": true,
+        "checkParamNames": true,
+        "checkTypes": "capitalizedNativeCase",
+        "requireHyphenBeforeDescription": true
+    }
+}
\ No newline at end of file
diff --git a/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/core.txt b/dev/tests/static/testsuite/Magento/Test/Js/_files/jshint/blacklist/core.txt
similarity index 100%
rename from dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/core.txt
rename to dev/tests/static/testsuite/Magento/Test/Js/_files/jshint/blacklist/core.txt
diff --git a/dev/tests/static/testsuite/Magento/Test/Js/_files/whitelist/core.txt b/dev/tests/static/testsuite/Magento/Test/Js/_files/jshint/whitelist/core.txt
similarity index 100%
rename from dev/tests/static/testsuite/Magento/Test/Js/_files/whitelist/core.txt
rename to dev/tests/static/testsuite/Magento/Test/Js/_files/jshint/whitelist/core.txt
diff --git a/dev/tests/static/testsuite/Magento/Test/Js/_files/whitelist/magento.txt b/dev/tests/static/testsuite/Magento/Test/Js/_files/whitelist/magento.txt
new file mode 100644
index 0000000000000000000000000000000000000000..19aab504018b3ec043fc1fff5a28d6eb23391f89
--- /dev/null
+++ b/dev/tests/static/testsuite/Magento/Test/Js/_files/whitelist/magento.txt
@@ -0,0 +1,4 @@
+app/code/**/*.js
+app/design/**/*.js
+dev/tests/js/jasmine/tests/**/*.js
+lib/web/mage/**/*.js
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
index 942a0b23d3169d60405531afd1dd4ccd5cca4b2d..7ce25410060614b2afcc4414d5841dfc1a10314d 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
@@ -1420,6 +1420,10 @@ return [
     ['Magento\Core\Model\Design\Fallback\Rule\Simple', 'Magento\Framework\View\Design\Fallback\Rule\Simple'],
     ['Magento\Core\Model\Design\Fallback\Factory', 'Magento\Framework\View\Design\Fallback\RulePool'],
     ['Magento\Core\Model\Design\FileResolution\Strategy\Fallback\CachingProxy'],
+    ['Magento\Framework\View\Design\FileResolution\Fallback\Cache'],
+    ['Magento\Framework\View\Design\FileResolution\Fallback\CacheDataInterface'],
+    ['Magento\Framework\View\Design\FileResolution\Fallback\CacheData\Flat'],
+    ['Magento\Framework\View\Design\FileResolution\Fallback\CacheData\Grouped'],
     ['Magento\Framework\View\Design\FileResolution\Strategy\View\NotifiableInterface'],
     ['Magento\Framework\View\Design\FileResolution\Strategy\View\FileInterface'],
     ['Magento\Framework\View\Design\FileResolution\Strategy\View\LocaleInterface'],
@@ -2613,6 +2617,7 @@ return [
     ['Magento\Less\PreProcessorInterface', 'Magento\Framework\View\Asset\PreProcessorInterface'],
     ['Magento\Framework\View\Asset\PreProcessorFactory'],
     ['Magento\Framework\View\Asset\PreProcessor\Composite'],
+    ['Magento\Framework\View\Asset\PreProcessor\Cache'],
     [
         'Magento\Framework\View\Asset\PreProcessor\PreProcessorInterface',
         'Magento\Framework\View\Asset\PreProcessorInterface',
@@ -3671,6 +3676,14 @@ return [
     ['Magento\Framework\View\Element\UiComponent\JsConfigInterface'],
     ['Magento\GiftMessage\Model\Plugin\TotalsDataProcessorPlugin'],
     ['Magento\Catalog\Model\Product\Attribute\Backend\Startdate', 'Magento\Catalog\Model\Attribute\Backend\Startdate'],
+    ['Magento\Framework\View\Asset\Minified\AbstractAsset'],
+    ['Magento\Framework\View\Asset\Minified\ImmutablePathAsset'],
+    ['Magento\Framework\View\Asset\Minified\MutablePathAsset'],
+    ['Magento\Framework\View\Asset\MinifyService'],
+    ['Magento\Framework\View\Test\Unit\Asset\Minified\AbstractAssetTestCase'],
+    ['Magento\Framework\View\Test\Unit\Asset\Minified\ImmutablePathAssetTest'],
+    ['Magento\Framework\View\Test\Unit\Asset\Minified\MutablePathAssetTest'],
+    ['Magento\Framework\View\Test\Unit\Asset\MinifyServiceTest'],
     ['Magento\Authorizenet\Block\Authorizenet\Form\Cc'],
     ['Magento\Authorizenet\Block\Authorizenet\Info\Cc'],
     ['Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Payment\Cancel'],
@@ -3786,6 +3799,8 @@ return [
     ['Magento\GoogleShopping\Test\Unit\Model\MassOperationsTest'],
     ['Magento\GoogleShopping\Test\Unit\Model\ObserverTest'],
     ['Magento\GoogleShopping\Test\Unit\Model\ServiceTest'],
+    ['Magento\Framework\Code\Minifier\Adapter\Js\JSMin'],
+    ['Magento\Framework\Code\Minifier\Adapter\Css\CssMinifier'],
     ['Magento\Framework\View\Asset\ModuleNotation\Resolver', 'Magento\Framework\View\Asset\NotationResolver\Module'],
     ['Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Attribute\Price\Data'],
     ['Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Settings'],
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_config_nodes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_config_nodes.php
index af061c650f65bfbb257757b55ffb2244ebd6c524..5e29eb028e2490edf39fe60b40e0818e0a6c11e9 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_config_nodes.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_config_nodes.php
@@ -102,4 +102,6 @@ return [
     '/config/global/currency/import/services' => 'Configurations moved to DI file settings',
     '/config/global/template' => 'Use /config/template of email_templates.xml',
     '/config/default/general/file/sitemap_generate_valid_paths' => '/config/default/sitemap/file/valid_paths',
+    '/config/dev/css/minify_adapter' => 'Was replaced using di',
+    '/config/dev/js/minify_adapter' => 'Was replaced using di',
 ];
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php
index 94bbad3aa4775e041dccd1be16af20baa4db272c..56fe3f6249939c3a2b3574405b58151335aa401e 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_constants.php
@@ -731,6 +731,12 @@ return [
     ],
     ['CURRENT_CUSTOMER', 'Magento\Customer\Controller\RegistryConstants'],
     ['METHOD_WPS', 'Magento\Paypal\Model\Config'],
+    [
+        'XML_PATH_MINIFICATION_ENABLED',
+        'Magento\Framework\View\Asset\Config',
+        'Magento\Framework\View\Asset\Minification::XML_PATH_MINIFICATION_ENABLED'
+    ],
+    ['XML_PATH_MINIFICATION_ADAPTER', 'Magento\Framework\View\Asset\Config'],
     ['ERROR_INVALID_PRICE_CORRECTION', 'Magento\ConfigurableImportExport\Model\Import\Product\Type\Configurable'],
     ['EXCEPTION_CODE_NOT_SALABLE', 'Magento\Wishlist\Model\Item'],
     ['EXCEPTION_CODE_HAS_REQUIRED_OPTIONS', 'Magento\Wishlist\Model\Item'],
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
index ccb2deb9bd8e4850186a6331f980e85aabc36700..6c5dd12a4cafc7c51880cf006a85b20a076c0789 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
@@ -2338,6 +2338,8 @@ return [
     ['getChilds', 'Magento\Bundle\Block\Sales\Order\Items\Renderer', 'getChildren'],
     ['getChilds', 'Magento\Bundle\Model\Sales\Order\Pdf\Items\AbstractItems', 'getChildren'],
     ['prepareIndexdata', 'Magento\Search\Helper\Data'],
+    ['isAssetMinification', 'Magento\Framework\View\Asset\ConfigInterface', 'Magento\Framework\View\Asset\Minification::isEnabled'],
+    ['isAssetMinification', 'Magento\Framework\View\Asset\Config', 'Magento\Framework\View\Asset\Minification::isEnabled'],
     ['getPriceValues', 'Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Attribute\Collection'],
     ['getPricingValue', 'Magento\ConfigurableProduct\Model\Product\Type\Configurable\OptionValue'],
     ['getIsPercent', 'Magento\ConfigurableProduct\Model\Product\Type\Configurable\OptionValue'],
diff --git a/dev/tools/grunt/configs/eslint.js b/dev/tools/grunt/configs/eslint.js
new file mode 100644
index 0000000000000000000000000000000000000000..c72131becc6483bc3ca3b9124877e9406377fc6d
--- /dev/null
+++ b/dev/tools/grunt/configs/eslint.js
@@ -0,0 +1,26 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+'use strict';
+
+module.exports = {
+    file: {
+        options: {
+            configFile: 'dev/tests/static/testsuite/Magento/Test/Js/_files/eslint/.eslintrc',
+            reset: true
+        },
+        src: ''
+    },
+    test: {
+        options: {
+            configFile: 'dev/tests/static/testsuite/Magento/Test/Js/_files/eslint/.eslintrc',
+            reset: true,
+            outputFile: 'dev/tests/static/eslint-error-report.xml',
+            format: 'checkstyle',
+            quiet: true
+        },
+        src: ''
+    }
+};
diff --git a/dev/tools/grunt/configs/jscs.js b/dev/tools/grunt/configs/jscs.js
new file mode 100644
index 0000000000000000000000000000000000000000..8b89e0293bdb5de151a19266e8ffe5fe28d83de4
--- /dev/null
+++ b/dev/tools/grunt/configs/jscs.js
@@ -0,0 +1,23 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+'use strict';
+
+module.exports = {
+    file: {
+        options: {
+            config: 'dev/tests/static/testsuite/Magento/Test/Js/_files/jscs/.jscsrc'
+        },
+        src: ''
+    },
+    test: {
+        options: {
+            config: 'dev/tests/static/testsuite/Magento/Test/Js/_files/jscs/.jscsrc',
+            reporterOutput: 'dev/tests/static/jscs-error-report.xml',
+            reporter: 'checkstyle'
+        },
+        src: ''
+    }
+};
diff --git a/dev/tools/grunt/configs/path.js b/dev/tools/grunt/configs/path.js
index f160b35c92823e6826b518a82ea983f3cf3705b5..5021becadca7f8f21fa6d370be255a22e7ffcd16 100644
--- a/dev/tools/grunt/configs/path.js
+++ b/dev/tools/grunt/configs/path.js
@@ -25,5 +25,11 @@ module.exports = {
         legacy: 'lib/web/legacy-build.min.js'
     },
     doc: 'lib/web/css/docs',
-    spec: 'dev/tests/js/spec'
+    spec: 'dev/tests/js/spec',
+    static: {
+        dir: 'dev/tests/static/testsuite/Magento/Test/Js/_files',
+        whitelist: 'dev/tests/static/testsuite/Magento/Test/Js/_files/whitelist/',
+        blacklist: 'dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/',
+        tmp: 'validation-files.txt'
+    }
 };
diff --git a/dev/tools/grunt/tasks/black-list-generator.js b/dev/tools/grunt/tasks/black-list-generator.js
new file mode 100644
index 0000000000000000000000000000000000000000..cd98b734cf235a45de494f0bda0c75c40da3277e
--- /dev/null
+++ b/dev/tools/grunt/tasks/black-list-generator.js
@@ -0,0 +1,26 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+module.exports = function (grunt) {
+    'use strict';
+
+    var glob = require('glob'),
+        fs = require('fs'),
+        path = require('path'),
+        fst = require('../tools/fs-tools.js'),
+        pc = require('../configs/path');
+
+    grunt.registerTask('black-list-generator', function () {
+        process.chdir(grunt.option('dir') || '.');
+
+        var whiteListFile = glob.sync(pc.static.whitelist + '*.txt')[0],
+            blacklistFile = pc.static.blacklist + path.basename(whiteListFile),
+            whiteList = fst.getData(whiteListFile);
+
+        fst.arrayRead(whiteList, function (data) {
+            fst.write(blacklistFile, data);
+        });
+    });
+};
\ No newline at end of file
diff --git a/dev/tools/grunt/tasks/clean-black-list.js b/dev/tools/grunt/tasks/clean-black-list.js
new file mode 100644
index 0000000000000000000000000000000000000000..93318bd628cdfe432459a71dbdc0191bc1f2a086
--- /dev/null
+++ b/dev/tools/grunt/tasks/clean-black-list.js
@@ -0,0 +1,30 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+module.exports = function (grunt) {
+    'use strict';
+
+    var fs = require('fs'),
+        _ = require('underscore'),
+        glob = require('glob'),
+        fst = require('../tools/fs-tools'),
+        pc = require('../configs/path'),
+        removeFromFile = function (path, files) {
+            var data = _.difference(fst.getData(path), files);
+
+            fst.write(path, data);
+        };
+
+    grunt.registerTask('clean-black-list', function () {
+        process.chdir(grunt.option('dir') || '.');
+
+        var filesToRemove = grunt.option('file').split(','),
+            files = glob.sync(pc.static.blacklist + '*.txt');
+
+        _.each(files, function (file) {
+            removeFromFile(file, filesToRemove);
+        });
+    });
+};
diff --git a/dev/tools/grunt/tasks/static.js b/dev/tools/grunt/tasks/static.js
new file mode 100644
index 0000000000000000000000000000000000000000..433e7a2b161f3b758fcf383742fccc606ac1293a
--- /dev/null
+++ b/dev/tools/grunt/tasks/static.js
@@ -0,0 +1,36 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+module.exports = function (grunt) {
+    'use strict';
+
+    var pc = require('../configs/path'),
+        fs = require('fs'),
+        cvf = require('../tools/collect-validation-files'),
+        setConfig = function (task, target, data) {
+            var config = grunt.config.get(task);
+
+            config[target].src = data;
+            grunt.config.set(task, config);
+        };
+
+    grunt.registerTask('static', function (target) {
+        var currentTarget = target || 'test',
+            file = grunt.option('file'),
+            tasks = [
+                'eslint:' + currentTarget,
+                'jscs:' + currentTarget
+            ];
+
+        setConfig('eslint', currentTarget, cvf.getFiles(file));
+        setConfig('jscs', currentTarget, cvf.getFiles(file));
+        grunt.option('force', true);
+        grunt.task.run(tasks);
+
+        if (!grunt.option('path')) {
+            fs.unlinkSync(pc.static.tmp);
+        }
+    });
+};
diff --git a/dev/tools/grunt/tools/collect-validation-files.js b/dev/tools/grunt/tools/collect-validation-files.js
new file mode 100644
index 0000000000000000000000000000000000000000..a8c55f75040db2a650d53a4ac2ba091b47b232dd
--- /dev/null
+++ b/dev/tools/grunt/tools/collect-validation-files.js
@@ -0,0 +1,55 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+'use strict';
+
+var glob = require('glob'),
+    fs = require('fs'),
+    _ = require('underscore'),
+    fst = require('../tools/fs-tools'),
+    pc = require('../configs/path');
+
+module.exports = {
+    readFiles: function (paths) {
+        var data = [];
+
+        _.each(paths, function (path) {
+            data = _.union(data, fst.getData(path));
+        });
+
+        return data;
+    },
+
+    getFilesForValidate: function () {
+
+        var blackListFiles = glob.sync(pc.static.blacklist + '*.txt'),
+            whiteListFiles = glob.sync(pc.static.whitelist + '*.txt'),
+            blackList = this.readFiles(blackListFiles),
+            whiteList = this.readFiles(whiteListFiles),
+            files = [];
+
+        fst.arrayRead(whiteList, function (data) {
+            files = _.difference(data, blackList);
+        });
+
+        return files;
+    },
+
+    getFiles: function (file) {
+        if (file) {
+            return file.split(',');
+        }
+
+        if (!fs.existsSync(pc.static.tmp)) {
+            fst.write(pc.static.tmp, this.getFilesForValidate());
+        }
+
+        return fst.getData(pc.static.tmp);
+    }
+};
diff --git a/dev/tools/grunt/tools/fs-tools.js b/dev/tools/grunt/tools/fs-tools.js
new file mode 100644
index 0000000000000000000000000000000000000000..d5e6e924ef47866bd13837238a5c74ae5a17b903
--- /dev/null
+++ b/dev/tools/grunt/tools/fs-tools.js
@@ -0,0 +1,57 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+'use strict';
+
+var fs = require('fs'),
+    glob = require('glob'),
+    nl = (function () {
+        if (process.platform === 'win32') {
+            return '\r\n';
+        }
+
+        return '\n';
+    })();
+
+module.exports = {
+    getData: function (filePath) {
+        return this.parseToReadData(fs.readFileSync(filePath));
+    },
+    write: function (file, data) {
+        fs.writeFileSync(file, this.parseToWriteData(data));
+        console.log('The file was saved!');
+    },
+
+    read: function (filePath) {
+        console.log('Collect data from ' + filePath + ': Start!');
+
+        return glob.sync(filePath);
+    },
+
+    arrayRead: function (pathArr, callback) {
+        var len = pathArr.length,
+            data = [],
+            i = 0;
+
+        for (; i < len; i++) {
+            data = data.concat(this.read(pathArr[i]));
+            console.log('Collect data from ' + pathArr[i] + ': Finish!');
+        }
+        callback(data);
+    },
+
+    parseToReadData: function (data) {
+        var result = data.toString().split(nl);
+
+        result.pop();
+
+        return result;
+    },
+
+    parseToWriteData: function (data) {
+        data = data.join(nl) + nl;
+
+        return data;
+    }
+};
diff --git a/lib/internal/JSMin/jsmin.php b/lib/internal/JSMin/jsmin.php
deleted file mode 100644
index ee1b442bcecf022f67c5a80c1efdb12473b1960f..0000000000000000000000000000000000000000
--- a/lib/internal/JSMin/jsmin.php
+++ /dev/null
@@ -1,386 +0,0 @@
-<?php
-/**
- * jsmin.php - PHP implementation of Douglas Crockford's JSMin.
- *
- * This is pretty much a direct port of jsmin.c to PHP with just a few
- * PHP-specific performance tweaks. Also, whereas jsmin.c reads from stdin and
- * outputs to stdout, this library accepts a string as input and returns another
- * string as output.
- *
- * PHP 5 or higher is required.
- *
- * Permission is hereby granted to use this version of the library under the
- * same terms as jsmin.c, which has the following license:
- *
- * --
- * Copyright (c) 2002 Douglas Crockford  (www.crockford.com)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is furnished to do
- * so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * The Software shall be used for Good, not Evil.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- * --
- *
- * @package JSMin
- * @author Ryan Grove <ryan@wonko.com>
- * @copyright 2002 Douglas Crockford <douglas@crockford.com> (jsmin.c)
- * @copyright 2008 Ryan Grove <ryan@wonko.com> (PHP port)
- * @copyright 2012 Adam Goforth <aag@adamgoforth.com> (Updates)
- * @license http://opensource.org/licenses/mit-license.php MIT License
- * @version 1.1.2 (2012-05-01)
- * @link https://github.com/rgrove/jsmin-php
- */
-
-class JSMin {
-  const ORD_LF            = 10;
-  const ORD_SPACE         = 32;
-  const ACTION_KEEP_A     = 1;
-  const ACTION_DELETE_A   = 2;
-  const ACTION_DELETE_A_B = 3;
-
-  protected $a           = '';
-  protected $b           = '';
-  protected $input       = '';
-  protected $inputIndex  = 0;
-  protected $inputLength = 0;
-  protected $lookAhead   = null;
-  protected $output      = '';
-
-  // -- Public Static Methods --------------------------------------------------
-
-  /**
-   * Minify Javascript
-   *
-   * @uses __construct()
-   * @uses min()
-   * @param string $js Javascript to be minified
-   * @return string
-   */
-  public static function minify($js) {
-    $jsmin = new JSMin($js);
-    return $jsmin->min();
-  }
-
-  // -- Public Instance Methods ------------------------------------------------
-
-  /**
-   * Constructor
-   *
-   * @param string $input Javascript to be minified
-   */
-  public function __construct($input) {
-    $this->input       = str_replace("\r\n", "\n", $input);
-    $this->inputLength = strlen($this->input);
-  }
-
-  // -- Protected Instance Methods ---------------------------------------------
-
-  /**
-   * Action -- do something! What to do is determined by the $command argument.
-   *
-   * action treats a string as a single character. Wow!
-   * action recognizes a regular expression if it is preceded by ( or , or =.
-   *
-   * @uses next()
-   * @uses get()
-   * @throws JSMinException If parser errors are found:
-   *         - Unterminated string literal
-   *         - Unterminated regular expression set in regex literal
-   *         - Unterminated regular expression literal
-   * @param int $command One of class constants:
-   *      ACTION_KEEP_A      Output A. Copy B to A. Get the next B.
-   *      ACTION_DELETE_A    Copy B to A. Get the next B. (Delete A).
-   *      ACTION_DELETE_A_B  Get the next B. (Delete B).
-  */
-  protected function action($command) {
-    switch($command) {
-      case self::ACTION_KEEP_A:
-        $this->output .= $this->a;
-
-      case self::ACTION_DELETE_A:
-        $this->a = $this->b;
-
-        if ($this->a === "'" || $this->a === '"') {
-          for (;;) {
-            $this->output .= $this->a;
-            $this->a       = $this->get();
-
-            if ($this->a === $this->b) {
-              break;
-            }
-
-            if (ord($this->a) <= self::ORD_LF) {
-              throw new JSMinException('Unterminated string literal.');
-            }
-
-            if ($this->a === '\\') {
-              $this->output .= $this->a;
-              $this->a       = $this->get();
-            }
-          }
-        }
-
-      case self::ACTION_DELETE_A_B:
-        $this->b = $this->next();
-
-        if ($this->b === '/' && (
-            $this->a === '(' || $this->a === ',' || $this->a === '=' ||
-            $this->a === ':' || $this->a === '[' || $this->a === '!' ||
-            $this->a === '&' || $this->a === '|' || $this->a === '?' ||
-            $this->a === '{' || $this->a === '}' || $this->a === ';' ||
-            $this->a === "\n" )) {
-
-          $this->output .= $this->a . $this->b;
-
-          for (;;) {
-            $this->a = $this->get();
-
-            if ($this->a === '[') {
-              /*
-                inside a regex [...] set, which MAY contain a '/' itself. Example: mootools Form.Validator near line 460:
-                  return Form.Validator.getValidator('IsEmpty').test(element) || (/^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]\.?){0,63}[a-z0-9!#$%&'*+/=?^_`{|}~-]@(?:(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\])$/i).test(element.get('value'));
-              */
-              for (;;) {
-                $this->output .= $this->a;
-                $this->a = $this->get();
-
-                if ($this->a === ']') {
-                    break;
-                } elseif ($this->a === '\\') {
-                  $this->output .= $this->a;
-                  $this->a       = $this->get();
-                } elseif (ord($this->a) <= self::ORD_LF) {
-                  throw new JSMinException('Unterminated regular expression set in regex literal.');
-                }
-              }
-            } elseif ($this->a === '/') {
-              break;
-            } elseif ($this->a === '\\') {
-              $this->output .= $this->a;
-              $this->a       = $this->get();
-            } elseif (ord($this->a) <= self::ORD_LF) {
-              throw new JSMinException('Unterminated regular expression literal.');
-            }
-
-            $this->output .= $this->a;
-          }
-
-          $this->b = $this->next();
-        }
-    }
-  }
-
-  /**
-   * Get next char. Convert ctrl char to space.
-   *
-   * @return string|null
-   */
-  protected function get() {
-    $c = $this->lookAhead;
-    $this->lookAhead = null;
-
-    if ($c === null) {
-      if ($this->inputIndex < $this->inputLength) {
-        $c = substr($this->input, $this->inputIndex, 1);
-        $this->inputIndex += 1;
-      } else {
-        $c = null;
-      }
-    }
-
-    if ($c === "\r") {
-      return "\n";
-    }
-
-    if ($c === null || $c === "\n" || ord($c) >= self::ORD_SPACE) {
-      return $c;
-    }
-
-    return ' ';
-  }
-
-  /**
-   * Is $c a letter, digit, underscore, dollar sign, or non-ASCII character.
-   *
-   * @return bool
-   */
-  protected function isAlphaNum($c) {
-    return ord($c) > 126 || $c === '\\' || preg_match('/^[\w\$]$/', $c) === 1;
-  }
-
-  /**
-   * Perform minification, return result
-   *
-   * @uses action()
-   * @uses isAlphaNum()
-   * @uses get()
-   * @uses peek()
-   * @return string
-   */
-  protected function min() {
-    if (0 == strncmp($this->peek(), "\xef", 1)) {
-        $this->get();
-        $this->get();
-        $this->get();
-    } 
-
-    $this->a = "\n";
-    $this->action(self::ACTION_DELETE_A_B);
-
-    while ($this->a !== null) {
-      switch ($this->a) {
-        case ' ':
-          if ($this->isAlphaNum($this->b)) {
-            $this->action(self::ACTION_KEEP_A);
-          } else {
-            $this->action(self::ACTION_DELETE_A);
-          }
-          break;
-
-        case "\n":
-          switch ($this->b) {
-            case '{':
-            case '[':
-            case '(':
-            case '+':
-            case '-':
-            case '!':
-            case '~':
-              $this->action(self::ACTION_KEEP_A);
-              break;
-
-            case ' ':
-              $this->action(self::ACTION_DELETE_A_B);
-              break;
-
-            default:
-              if ($this->isAlphaNum($this->b)) {
-                $this->action(self::ACTION_KEEP_A);
-              }
-              else {
-                $this->action(self::ACTION_DELETE_A);
-              }
-          }
-          break;
-
-        default:
-          switch ($this->b) {
-            case ' ':
-              if ($this->isAlphaNum($this->a)) {
-                $this->action(self::ACTION_KEEP_A);
-                break;
-              }
-
-              $this->action(self::ACTION_DELETE_A_B);
-              break;
-
-            case "\n":
-              switch ($this->a) {
-                case '}':
-                case ']':
-                case ')':
-                case '+':
-                case '-':
-                case '"':
-                case "'":
-                  $this->action(self::ACTION_KEEP_A);
-                  break;
-
-                default:
-                  if ($this->isAlphaNum($this->a)) {
-                    $this->action(self::ACTION_KEEP_A);
-                  }
-                  else {
-                    $this->action(self::ACTION_DELETE_A_B);
-                  }
-              }
-              break;
-
-            default:
-              $this->action(self::ACTION_KEEP_A);
-              break;
-          }
-      }
-    }
-
-    return $this->output;
-  }
-
-  /**
-   * Get the next character, skipping over comments. peek() is used to see
-   *  if a '/' is followed by a '/' or '*'.
-   *
-   * @uses get()
-   * @uses peek()
-   * @throws JSMinException On unterminated comment.
-   * @return string
-   */
-  protected function next() {
-    $c = $this->get();
-
-    if ($c === '/') {
-      switch($this->peek()) {
-        case '/':
-          for (;;) {
-            $c = $this->get();
-
-            if (ord($c) <= self::ORD_LF) {
-              return $c;
-            }
-          }
-
-        case '*':
-          $this->get();
-
-          for (;;) {
-            switch($this->get()) {
-              case '*':
-                if ($this->peek() === '/') {
-                  $this->get();
-                  return ' ';
-                }
-                break;
-
-              case null:
-                throw new JSMinException('Unterminated comment.');
-            }
-          }
-
-        default:
-          return $c;
-      }
-    }
-
-    return $c;
-  }
-
-  /**
-   * Get next char. If is ctrl character, translate to a space or newline.
-   *
-   * @uses get()
-   * @return string|null
-   */
-  protected function peek() {
-    $this->lookAhead = $this->get();
-    return $this->lookAhead;
-  }
-}
-
-// -- Exceptions ---------------------------------------------------------------
-class JSMinException extends Exception {}
-?>
diff --git a/lib/internal/Magento/Framework/App/SetupInfo.php b/lib/internal/Magento/Framework/App/SetupInfo.php
index 06ce29f02930bbb788bc8b4ece865e46be24cb0c..cc8c53924eebc1fc7dd01b6c588821f1f4d8a22f 100644
--- a/lib/internal/Magento/Framework/App/SetupInfo.php
+++ b/lib/internal/Magento/Framework/App/SetupInfo.php
@@ -6,6 +6,8 @@
 
 namespace Magento\Framework\App;
 
+use \Magento\Framework\Setup\BackendFrontnameGenerator;
+
 /**
  * A model for determining information about setup application
  */
@@ -113,6 +115,16 @@ class SetupInfo
         return 'http://' . $this->server['HTTP_HOST'] . substr($this->projectRoot . '/', strlen($this->docRoot));
     }
 
+    /**
+     * Get the admin area path
+     *
+     * @return string
+     */
+    public function getProjectAdminPath()
+    {
+        return BackendFrontnameGenerator::generate();
+    }
+
     /**
      * Gets setup application directory path in the filesystem
      *
diff --git a/lib/internal/Magento/Framework/App/StaticResource.php b/lib/internal/Magento/Framework/App/StaticResource.php
index bad6ddc7a796b96eb801b83c59434b114665096c..62f31c0acfaeb646d98493e58520c43ee80af5b1 100644
--- a/lib/internal/Magento/Framework/App/StaticResource.php
+++ b/lib/internal/Magento/Framework/App/StaticResource.php
@@ -54,11 +54,6 @@ class StaticResource implements \Magento\Framework\AppInterface
      */
     private $configLoader;
 
-    /**
-     * @var \Magento\Framework\View\Asset\MinifyService
-     */
-    protected $minifyService;
-
     /**
      * @param State $state
      * @param Response\FileInterface $response
@@ -68,7 +63,6 @@ class StaticResource implements \Magento\Framework\AppInterface
      * @param \Magento\Framework\Module\ModuleList $moduleList
      * @param \Magento\Framework\ObjectManagerInterface $objectManager
      * @param ConfigLoaderInterface $configLoader
-     * @param \Magento\Framework\View\Asset\MinifyService $minifyService
      */
     public function __construct(
         State $state,
@@ -78,8 +72,7 @@ class StaticResource implements \Magento\Framework\AppInterface
         \Magento\Framework\View\Asset\Repository $assetRepo,
         \Magento\Framework\Module\ModuleList $moduleList,
         \Magento\Framework\ObjectManagerInterface $objectManager,
-        ConfigLoaderInterface $configLoader,
-        \Magento\Framework\View\Asset\MinifyService $minifyService
+        ConfigLoaderInterface $configLoader
     ) {
         $this->state = $state;
         $this->response = $response;
@@ -89,7 +82,6 @@ class StaticResource implements \Magento\Framework\AppInterface
         $this->moduleList = $moduleList;
         $this->objectManager = $objectManager;
         $this->configLoader = $configLoader;
-        $this->minifyService = $minifyService;
     }
 
     /**
@@ -113,7 +105,6 @@ class StaticResource implements \Magento\Framework\AppInterface
             $file = $params['file'];
             unset($params['file']);
             $asset = $this->assetRepo->createAsset($file, $params);
-            $asset = $this->minifyService->getAssets([$asset], true)[0];
             $this->response->setFilePath($asset->getSourceFile());
             $this->publisher->publish($asset);
         }
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/StaticResourceTest.php b/lib/internal/Magento/Framework/App/Test/Unit/StaticResourceTest.php
index 5dadd6a1f1716d79ddb529e1f3ffb27c822c7cd5..8cb4304875ab532633ad4a4efb414e349dfe562f 100644
--- a/lib/internal/Magento/Framework/App/Test/Unit/StaticResourceTest.php
+++ b/lib/internal/Magento/Framework/App/Test/Unit/StaticResourceTest.php
@@ -55,11 +55,6 @@ class StaticResourceTest extends \PHPUnit_Framework_TestCase
      */
     private $object;
 
-    /**
-     * @var \Magento\Framework\View\Asset\MinifyService|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $minifyService;
-
     protected function setUp()
     {
         $this->state = $this->getMock('Magento\Framework\App\State', [], [], '', false);
@@ -72,11 +67,6 @@ class StaticResourceTest extends \PHPUnit_Framework_TestCase
         $this->configLoader = $this->getMock(
             'Magento\Framework\App\ObjectManager\ConfigLoader', [], [], '', false
         );
-        $this->minifyService = $this->getMockBuilder('Magento\Framework\View\Asset\MinifyService')
-            ->disableOriginalConstructor()
-            ->setMethods(['getAssets'])
-            ->getMock();
-
         $this->object = new \Magento\Framework\App\StaticResource(
             $this->state,
             $this->response,
@@ -86,7 +76,6 @@ class StaticResourceTest extends \PHPUnit_Framework_TestCase
             $this->moduleList,
             $this->objectManager,
             $this->configLoader,
-            $this->minifyService,
             $this->getMockForAbstractClass('\Magento\Framework\View\DesignInterface')
         );
     }
@@ -153,7 +142,6 @@ class StaticResourceTest extends \PHPUnit_Framework_TestCase
         $this->response->expects($this->once())
             ->method('setFilePath')
             ->with('resource/file.css');
-        $this->minifyService->expects($this->once())->method('getAssets')->willReturnArgument(0);
         $this->object->launch();
     }
 
diff --git a/lib/internal/Magento/Framework/Code/Minifier/Adapter/Css/CssMinifier.php b/lib/internal/Magento/Framework/Code/Minifier/Adapter/Css/CSSmin.php
similarity index 78%
rename from lib/internal/Magento/Framework/Code/Minifier/Adapter/Css/CssMinifier.php
rename to lib/internal/Magento/Framework/Code/Minifier/Adapter/Css/CSSmin.php
index e1d4d01942333670ac1799df0820c589520b8118..d57873751cdf6e73575c31c660b98925eabd3e99 100644
--- a/lib/internal/Magento/Framework/Code/Minifier/Adapter/Css/CssMinifier.php
+++ b/lib/internal/Magento/Framework/Code/Minifier/Adapter/Css/CSSmin.php
@@ -6,10 +6,13 @@
 
 namespace Magento\Framework\Code\Minifier\Adapter\Css;
 
-use CSSmin;
+use CSSmin as CssMinLibrary;
 use Magento\Framework\Code\Minifier\AdapterInterface;
 
-class CssMinifier implements AdapterInterface
+/**
+ * Adapter for CSSmin library
+ */
+class CSSmin implements AdapterInterface
 {
     /**
      * 'pcre.recursion_limit' value for CSSMin minification
@@ -17,14 +20,14 @@ class CssMinifier implements AdapterInterface
     const PCRE_RECURSION_LIMIT = 1000;
 
     /**
-     * @var CSSmin
+     * @var CssMinLibrary
      */
     protected $cssMinifier;
 
     /**
-     * @param CSSmin $cssMinifier
+     * @param CssMinLibrary $cssMinifier
      */
-    public function __construct(CSSmin $cssMinifier)
+    public function __construct(CssMinLibrary $cssMinifier)
     {
         $this->cssMinifier = $cssMinifier;
     }
diff --git a/lib/internal/Magento/Framework/Code/Minifier/Adapter/Js/JShrink.php b/lib/internal/Magento/Framework/Code/Minifier/Adapter/Js/JShrink.php
new file mode 100644
index 0000000000000000000000000000000000000000..f0b0976ff559578686bed38c6da5fc967de7226a
--- /dev/null
+++ b/lib/internal/Magento/Framework/Code/Minifier/Adapter/Js/JShrink.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\Code\Minifier\Adapter\Js;
+
+use JShrink\Minifier;
+use Magento\Framework\Code\Minifier\AdapterInterface;
+
+/**
+ * Adapter for JShrink library
+ */
+class JShrink implements AdapterInterface
+{
+    /**
+     * Takes a string containing javascript and removes unneeded characters in
+     * order to shrink the code without altering it's functionality.
+     *
+     * @param string $content The raw javascript to be minified
+     * @throws \Exception
+     * @return bool|string
+     */
+    public function minify($content)
+    {
+        return Minifier::minify($content);
+    }
+}
diff --git a/lib/internal/Magento/Framework/Code/Minifier/Adapter/Js/Jsmin.php b/lib/internal/Magento/Framework/Code/Minifier/Adapter/Js/Jsmin.php
deleted file mode 100644
index fa5d3c2acb12a50be96daf65c5205b2151828a23..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/Code/Minifier/Adapter/Js/Jsmin.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Framework\Code\Minifier\Adapter\Js;
-
-if (!class_exists('JSMin')) {
-    require_once __DIR__ . '/../../../../../../JSMin/jsmin.php';
-}
-/**
- * Adapter for JSMin library
- */
-class Jsmin implements \Magento\Framework\Code\Minifier\AdapterInterface
-{
-    /**
-     * {@inheritdoc}
-     */
-    public function minify($content)
-    {
-        return \JSMin::minify($content);
-    }
-}
diff --git a/lib/internal/Magento/Framework/Code/Test/Unit/Minifier/Adapter/Js/JsminTest.php b/lib/internal/Magento/Framework/Code/Test/Unit/Minifier/Adapter/Js/JShrinkTest.php
similarity index 79%
rename from lib/internal/Magento/Framework/Code/Test/Unit/Minifier/Adapter/Js/JsminTest.php
rename to lib/internal/Magento/Framework/Code/Test/Unit/Minifier/Adapter/Js/JShrinkTest.php
index 0ebb776c2b70531bb99cbe84bb2c876e7f5a51c3..c77ded66b9ee78e7324921cb666cda47ab58b345 100644
--- a/lib/internal/Magento/Framework/Code/Test/Unit/Minifier/Adapter/Js/JsminTest.php
+++ b/lib/internal/Magento/Framework/Code/Test/Unit/Minifier/Adapter/Js/JShrinkTest.php
@@ -5,14 +5,14 @@
  */
 namespace Magento\Framework\Code\Test\Unit\Minifier\Adapter\Js;
 
-class JsminTest extends \PHPUnit_Framework_TestCase
+class JShrinkTest extends \PHPUnit_Framework_TestCase
 {
     public function testMinify()
     {
         $content = file_get_contents(__DIR__ . '/../../_files/js/original.js');
-        $minifier = new \Magento\Framework\Code\Minifier\Adapter\Js\Jsmin();
+        $minifier = new \Magento\Framework\Code\Minifier\Adapter\Js\JShrink();
         $actual = $minifier->minify($content);
-        $expected = "\nvar one='one';var two='two';";
+        $expected = "var one='one';var two='two';";
         $this->assertEquals($expected, $actual);
     }
 }
diff --git a/lib/internal/Magento/Framework/Css/Test/Unit/PreProcessor/LessTest.php b/lib/internal/Magento/Framework/Css/Test/Unit/PreProcessor/LessTest.php
index a889a4320f3639f891c117e5cfba26d6cc122d76..33a424bf562a08be19faad8466555e3c25aa52ea 100644
--- a/lib/internal/Magento/Framework/Css/Test/Unit/PreProcessor/LessTest.php
+++ b/lib/internal/Magento/Framework/Css/Test/Unit/PreProcessor/LessTest.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Framework\Css\Test\Unit\PreProcessor;
 
+use Magento\Framework\View\Asset\PreProcessor\Chain;
+
 class LessTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -18,7 +20,7 @@ class LessTest extends \PHPUnit_Framework_TestCase
     private $adapter;
 
     /**
-     * @var \Magento\Framework\View\Asset\PreProcessor\Chain
+     * @var Chain
      */
     private $chain;
 
@@ -33,7 +35,7 @@ class LessTest extends \PHPUnit_Framework_TestCase
         $this->adapter = $this->getMockForAbstractClass('\Magento\Framework\Css\PreProcessor\AdapterInterface');
         $asset = $this->getMockForAbstractClass('\Magento\Framework\View\Asset\LocalInterface');
         $asset->expects($this->once())->method('getContentType')->will($this->returnValue('origType'));
-        $this->chain = new \Magento\Framework\View\Asset\PreProcessor\Chain($asset, 'original content', 'origType');
+        $this->chain = new Chain($asset, 'original content', 'origType', 'origPath');
         $this->object = new \Magento\Framework\Css\PreProcessor\Less($this->fileGenerator, $this->adapter);
     }
 
diff --git a/lib/internal/Magento/Framework/Less/Test/Unit/PreProcessor/Instruction/ImportTest.php b/lib/internal/Magento/Framework/Less/Test/Unit/PreProcessor/Instruction/ImportTest.php
index 367963a47949af3c49ded54298d189a370a5f062..aee9a1dc9bd1b0efea81d5c2d164b0647d951306 100644
--- a/lib/internal/Magento/Framework/Less/Test/Unit/PreProcessor/Instruction/ImportTest.php
+++ b/lib/internal/Magento/Framework/Less/Test/Unit/PreProcessor/Instruction/ImportTest.php
@@ -45,7 +45,7 @@ class ImportTest extends \PHPUnit_Framework_TestCase
      */
     public function testProcess($originalContent, $foundPath, $resolvedPath, $expectedContent)
     {
-        $chain = new \Magento\Framework\View\Asset\PreProcessor\Chain($this->asset, $originalContent, 'css');
+        $chain = new \Magento\Framework\View\Asset\PreProcessor\Chain($this->asset, $originalContent, 'css', 'path');
         $this->notationResolver->expects($this->once())
             ->method('convertModuleNotationToPath')
             ->with($this->asset, $foundPath)
@@ -114,7 +114,7 @@ class ImportTest extends \PHPUnit_Framework_TestCase
         $originalContent = 'color: #000000;';
         $expectedContent = 'color: #000000;';
 
-        $chain = new \Magento\Framework\View\Asset\PreProcessor\Chain($this->asset, $originalContent, 'css');
+        $chain = new \Magento\Framework\View\Asset\PreProcessor\Chain($this->asset, $originalContent, 'css', 'path');
         $this->notationResolver->expects($this->never())
             ->method('convertModuleNotationToPath');
         $this->object->process($chain);
@@ -136,10 +136,11 @@ class ImportTest extends \PHPUnit_Framework_TestCase
         $chain = new \Magento\Framework\View\Asset\PreProcessor\Chain(
             $this->asset,
             '@import (type) "Magento_Module::something.css" media;',
-            'css'
+            'css',
+            'path'
         );
         $this->object->process($chain);
-        $chain = new \Magento\Framework\View\Asset\PreProcessor\Chain($this->asset, 'color: #000000;', 'css');
+        $chain = new \Magento\Framework\View\Asset\PreProcessor\Chain($this->asset, 'color: #000000;', 'css', 'path');
         $this->object->process($chain);
 
         $expected = [['Magento_Module::something.css', $this->asset]];
diff --git a/lib/internal/Magento/Framework/Less/Test/Unit/PreProcessor/Instruction/MagentoImportTest.php b/lib/internal/Magento/Framework/Less/Test/Unit/PreProcessor/Instruction/MagentoImportTest.php
index e8837987d1406d6ee9a78b8ea6eb946f6b0b0193..afaa1a4a6e7180fda7f2c658613e4379212efd4a 100644
--- a/lib/internal/Magento/Framework/Less/Test/Unit/PreProcessor/Instruction/MagentoImportTest.php
+++ b/lib/internal/Magento/Framework/Less/Test/Unit/PreProcessor/Instruction/MagentoImportTest.php
@@ -76,7 +76,7 @@ class MagentoImportTest extends \PHPUnit_Framework_TestCase
      */
     public function testProcess($originalContent, $foundPath, $resolvedPath, $foundFiles, $expectedContent)
     {
-        $chain = new \Magento\Framework\View\Asset\PreProcessor\Chain($this->asset, $originalContent, 'css');
+        $chain = new \Magento\Framework\View\Asset\PreProcessor\Chain($this->asset, $originalContent, 'css', 'path');
         $relatedAsset = $this->getMock('\Magento\Framework\View\Asset\File', [], [], '', false);
         $relatedAsset->expects($this->once())
             ->method('getFilePath')
@@ -163,7 +163,7 @@ class MagentoImportTest extends \PHPUnit_Framework_TestCase
     {
         $originalContent = 'color: #000000;';
         $expectedContent = 'color: #000000;';
-        $chain = new \Magento\Framework\View\Asset\PreProcessor\Chain($this->asset, $originalContent, 'css');
+        $chain = new \Magento\Framework\View\Asset\PreProcessor\Chain($this->asset, $originalContent, 'css', 'orig');
         $this->assetRepo->expects($this->never())
             ->method('createRelated');
         $this->object->process($chain);
@@ -174,7 +174,7 @@ class MagentoImportTest extends \PHPUnit_Framework_TestCase
     public function testProcessException()
     {
         $chain = new \Magento\Framework\View\Asset\PreProcessor\Chain(
-            $this->asset, '//@magento_import "some/file.css";', 'css'
+            $this->asset, '//@magento_import "some/file.css";', 'css', 'path'
         );
         $exception = new \LogicException('Error happened');
         $this->assetRepo->expects($this->once())
diff --git a/lib/internal/Magento/Framework/RequireJs/Config.php b/lib/internal/Magento/Framework/RequireJs/Config.php
index 125f39876086b0271e3691b16e42d0f8e6b0d6b9..43c80c844c173445ffa1be4b6c3cfb9eac8fa2ef 100644
--- a/lib/internal/Magento/Framework/RequireJs/Config.php
+++ b/lib/internal/Magento/Framework/RequireJs/Config.php
@@ -6,6 +6,7 @@
 namespace Magento\Framework\RequireJs;
 
 use Magento\Framework\App\Filesystem\DirectoryList;
+use Magento\Framework\View\Asset\Minification;
 
 /**
  * Provider of RequireJs config information
@@ -37,6 +38,11 @@ class Config
      */
     const STATIC_FILE_NAME = 'mage\requirejs\static.js';
 
+    /**
+     * File name of minified files resolver
+     */
+    const MIN_RESOLVER_FILENAME = 'requirejs-min-resolver.js';
+
     /**
      * File name of StaticJs
      */
@@ -85,22 +91,38 @@ config;
      */
     private $staticContext;
 
+    /**
+     * @var \Magento\Framework\Code\Minifier\AdapterInterface
+     */
+    private $minifyAdapter;
+
+    /**
+     * @var Minification
+     */
+    private $minification;
+
     /**
      * @param \Magento\Framework\RequireJs\Config\File\Collector\Aggregated $fileSource
      * @param \Magento\Framework\View\DesignInterface $design
      * @param \Magento\Framework\Filesystem $appFilesystem
      * @param \Magento\Framework\View\Asset\Repository $assetRepo
+     * @param \Magento\Framework\Code\Minifier\AdapterInterface $minifyAdapter
+     * @param Minification $minification
      */
     public function __construct(
         \Magento\Framework\RequireJs\Config\File\Collector\Aggregated $fileSource,
         \Magento\Framework\View\DesignInterface $design,
         \Magento\Framework\Filesystem $appFilesystem,
-        \Magento\Framework\View\Asset\Repository $assetRepo
+        \Magento\Framework\View\Asset\Repository $assetRepo,
+        \Magento\Framework\Code\Minifier\AdapterInterface $minifyAdapter,
+        Minification $minification
     ) {
         $this->fileSource = $fileSource;
         $this->design = $design;
         $this->baseDir = $appFilesystem->getDirectoryRead(DirectoryList::ROOT);
         $this->staticContext = $assetRepo->getStaticViewFileContext();
+        $this->minifyAdapter = $minifyAdapter;
+        $this->minification = $minification;
     }
 
     /**
@@ -128,6 +150,10 @@ config;
             self::FULL_CONFIG_TEMPLATE
         );
 
+        if ($this->minification->isEnabled('js')) {
+            $fullConfig = $this->minifyAdapter->minify($fullConfig);
+        }
+
         return $fullConfig;
     }
 
@@ -138,7 +164,7 @@ config;
      */
     public function getConfigFileRelativePath()
     {
-        return self::DIR_NAME . '/' . $this->staticContext->getConfigPath() . '/' . self::CONFIG_FILE_NAME;
+        return self::DIR_NAME . '/' . $this->staticContext->getConfigPath() . '/' . $this->getConfigFileName();
     }
 
     /**
@@ -158,7 +184,7 @@ config;
      */
     public function getRequireJsFileRelativePath()
     {
-        return $this->staticContext->getConfigPath() . '/' .self::REQUIRE_JS_FILE_NAME;
+        return $this->staticContext->getConfigPath() . '/' . self::REQUIRE_JS_FILE_NAME;
     }
 
     /**
@@ -172,6 +198,58 @@ config;
             'baseUrl' => $this->staticContext->getBaseUrl() . $this->staticContext->getPath(),
         ];
         $config = json_encode($config, JSON_UNESCAPED_SLASHES);
-        return "require.config($config);";
+        $result = "require.config($config);";
+        return $result;
+    }
+
+    /**
+     * Get path to '.min' files resolver relative to config files directory
+     *
+     * @return string
+     */
+    public function getMinResolverRelativePath()
+    {
+        return
+            $this->staticContext->getConfigPath() .
+            '/' .
+            $this->minification->addMinifiedSign(self::MIN_RESOLVER_FILENAME);
+    }
+
+    /**
+     * @return string
+     */
+    protected function getConfigFileName()
+    {
+        return $this->minification->addMinifiedSign(self::CONFIG_FILE_NAME);
+    }
+
+    /**
+     * @return string
+     */
+    public function getMinResolverCode()
+    {
+        $excludes = [];
+        foreach ($this->minification->getExcludes('js') as $expression) {
+            $excludes[] = '!url.match(/' . str_replace('/', '\/', $expression) . '/)';
+        }
+        $excludesCode = empty($excludes) ? 'true' : implode('&&', $excludes);
+
+        $result = <<<code
+    if (!require.s.contexts._.__load) {
+        require.s.contexts._.__load = require.s.contexts._.load;
+        require.s.contexts._.load = function(id, url) {
+            if ({$excludesCode}) {
+                url = url.replace(/(\.min)?\.js$/, '.min.js');
+            }
+            return require.s.contexts._.__load.apply(require.s.contexts._, [id, url]);
+        }
+    }
+
+code;
+
+        if ($this->minification->isEnabled('js')) {
+            $result = $this->minifyAdapter->minify($result);
+        }
+        return $result;
     }
 }
diff --git a/lib/internal/Magento/Framework/RequireJs/Test/Unit/ConfigTest.php b/lib/internal/Magento/Framework/RequireJs/Test/Unit/ConfigTest.php
index 7c3bbcf1214f2eb1cb0a60a027e8ff8946a6bcff..9622e03bdbf0b6b684060db935334c67ea7771e8 100644
--- a/lib/internal/Magento/Framework/RequireJs/Test/Unit/ConfigTest.php
+++ b/lib/internal/Magento/Framework/RequireJs/Test/Unit/ConfigTest.php
@@ -37,6 +37,16 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
      */
     private $object;
 
+    /**
+     * @var \Magento\Framework\View\Asset\Minification|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $minificationMock;
+
+    /**
+     * @var \Magento\Framework\Code\Minifier\AdapterInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $minifyAdapterMock;
+
     protected function setUp()
     {
         $this->fileSource = $this->getMock(
@@ -64,7 +74,21 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
             )
             ->getMock();
         $repo->expects($this->once())->method('getStaticViewFileContext')->will($this->returnValue($this->context));
-        $this->object = new \Magento\Framework\RequireJs\Config($this->fileSource, $this->design, $filesystem, $repo);
+        $this->minificationMock = $this->getMockBuilder('Magento\Framework\View\Asset\Minification')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->minifyAdapterMock = $this->getMockBuilder('Magento\Framework\Code\Minifier\AdapterInterface')
+            ->getMockForAbstractClass();
+
+        $this->object = new Config(
+            $this->fileSource,
+            $this->design,
+            $filesystem,
+            $repo,
+            $this->minifyAdapterMock,
+            $this->minificationMock
+        );
     }
 
     public function testGetConfig()
@@ -98,6 +122,11 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
             ->method('getFiles')
             ->with($theme, Config::CONFIG_FILE_NAME)
             ->will($this->returnValue([$fileOne, $fileTwo]));
+        $this->minificationMock
+            ->expects($this->atLeastOnce())
+            ->method('isEnabled')
+            ->with('js')
+            ->willReturn(true);
 
         $expected = <<<expected
 (function(require){
@@ -116,17 +145,70 @@ require.config(config);
 })(require);
 expected;
 
+        $this->minifyAdapterMock
+            ->expects($this->once())
+            ->method('minify')
+            ->with($expected)
+            ->willReturnArgument(0);
+
         $actual = $this->object->getConfig();
         $this->assertStringMatchesFormat($expected, $actual);
     }
 
+    public function testGetMinResolverCode()
+    {
+        $this->minificationMock
+            ->expects($this->once())
+            ->method('getExcludes')
+            ->with('js')
+            ->willReturn(['\.min\.']);
+        $this->minificationMock
+            ->expects($this->once())
+            ->method('isEnabled')
+            ->with('js')
+            ->willReturn(true);
+        $this->minifyAdapterMock
+            ->expects($this->once())
+            ->method('minify')
+            ->willReturnArgument(0);
+
+        $expected = <<<code
+    if (!require.s.contexts._.__load) {
+        require.s.contexts._.__load = require.s.contexts._.load;
+        require.s.contexts._.load = function(id, url) {
+            if (!url.match(/\.min\./)) {
+                url = url.replace(/(\.min)?\.js$/, '.min.js');
+            }
+            return require.s.contexts._.__load.apply(require.s.contexts._, [id, url]);
+        }
+    }
+
+code;
+        $this->assertEquals($expected, $this->object->getMinResolverCode());
+    }
+
     public function testGetConfigFileRelativePath()
     {
+        $this->minificationMock
+            ->expects($this->any())
+            ->method('addMinifiedSign')
+            ->willReturnArgument(0);
         $this->context->expects($this->once())->method('getConfigPath')->will($this->returnValue('path'));
         $actual = $this->object->getConfigFileRelativePath();
         $this->assertSame('_requirejs/path/requirejs-config.js', $actual);
     }
 
+    public function testGetMinResolverRelativePath()
+    {
+        $this->minificationMock
+            ->expects($this->any())
+            ->method('addMinifiedSign')
+            ->willReturnArgument(0);
+        $this->context->expects($this->once())->method('getConfigPath')->will($this->returnValue('path'));
+        $actual = $this->object->getMinResolverRelativePath();
+        $this->assertSame('path/requirejs-min-resolver.js', $actual);
+    }
+
     public function testGetBaseConfig()
     {
         $this->context->expects($this->once())->method('getPath')->will($this->returnValue('area/theme/locale'));
diff --git a/lib/internal/Magento/Framework/Setup/BackendFrontnameGenerator.php b/lib/internal/Magento/Framework/Setup/BackendFrontnameGenerator.php
new file mode 100644
index 0000000000000000000000000000000000000000..8a66f295175b960061782aa18278e94ab67a0b27
--- /dev/null
+++ b/lib/internal/Magento/Framework/Setup/BackendFrontnameGenerator.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\Setup;
+
+/**
+ * Class to generate random backend URI
+ */
+class BackendFrontnameGenerator
+{
+    /**
+     * Prefix for admin area path
+     */
+    const ADMIN_AREA_PATH_PREFIX = 'admin_';
+
+    /**
+     * Length of the backend frontname random part
+     */
+    const ADMIN_AREA_PATH_RANDOM_PART_LENGTH = 6;
+
+    /**
+     * Generate Backend name
+     *
+     * @return string
+     */
+    public static function generate()
+    {
+        return self::ADMIN_AREA_PATH_PREFIX
+            . substr(base_convert(rand(0, PHP_INT_MAX), 10, 36), 0, self::ADMIN_AREA_PATH_RANDOM_PART_LENGTH);
+    }
+}
diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/BackendFrontnameGeneratorTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/BackendFrontnameGeneratorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a74917e5e54f3668348232c0ba331ec903381204
--- /dev/null
+++ b/lib/internal/Magento/Framework/Setup/Test/Unit/BackendFrontnameGeneratorTest.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Setup\Test\Unit;
+
+use Magento\Framework\Setup\BackendFrontnameGenerator;
+
+class BackendFrontnameGeneratorTest extends \PHPUnit_Framework_TestCase
+{
+    public function testGenerate()
+    {
+        $regexp = '/' . BackendFrontnameGenerator::ADMIN_AREA_PATH_PREFIX
+            . '[a-z0-9]{1,' . BackendFrontnameGenerator::ADMIN_AREA_PATH_RANDOM_PART_LENGTH .'}/';
+
+        $this->assertRegExp($regexp, BackendFrontnameGenerator::generate(), 'Unexpected Backend Frontname pattern.');
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Asset/Bundle.php b/lib/internal/Magento/Framework/View/Asset/Bundle.php
index 4f9d0e68ef62b1c980a519a38a071340c5150fa2..10573664bc6c936d15aec35a80b7b5464c37c936 100644
--- a/lib/internal/Magento/Framework/View/Asset/Bundle.php
+++ b/lib/internal/Magento/Framework/View/Asset/Bundle.php
@@ -12,7 +12,7 @@ use Magento\Framework\App\Filesystem\DirectoryList;
 use Magento\Framework\View\Asset\File\FallbackContext;
 
 /**
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ * Bundle model
  */
 class Bundle
 {
@@ -37,16 +37,24 @@ class Bundle
      */
     protected $content = [];
 
+    /**
+     * @var Minification
+     */
+    protected $minification;
+
     /**
      * @param Filesystem $filesystem
      * @param Bundle\ConfigInterface $bundleConfig
+     * @param Minification $minification
      */
     public function __construct(
         Filesystem $filesystem,
-        Bundle\ConfigInterface $bundleConfig
+        Bundle\ConfigInterface $bundleConfig,
+        Minification $minification
     ) {
         $this->filesystem = $filesystem;
         $this->bundleConfig = $bundleConfig;
+        $this->minification = $minification;
     }
 
     /**
@@ -153,7 +161,9 @@ class Bundle
      */
     protected function getAssetKey(LocalInterface $asset)
     {
-        return ($asset->getModule() == '') ? $asset->getFilePath() : $asset->getModule() . '/' . $asset->getFilePath();
+        $result = (($asset->getModule() == '') ? '' : $asset->getModule() . '/') . $asset->getFilePath();
+        $result = $this->minification->addMinifiedSign($result);
+        return $result;
     }
 
     /**
@@ -228,16 +238,11 @@ class Bundle
             $this->fillContent($parts, $context);
         }
 
-        $this->content[count($this->content) > 0 ? count($this->content) - 1 : 0] .= $this->getInitJs();
+        $this->content[max(0, count($this->content) - 1)] .= $this->getInitJs();
 
-        if (count($this->content) > 1) {
-            foreach ($this->content as $partIndex => $content) {
-                $dir->writeFile($bundlePath . "$partIndex.js", $content);
-            }
-            return;
+        foreach ($this->content as $partIndex => $content) {
+            $dir->writeFile($this->minification->addMinifiedSign($bundlePath . $partIndex . '.js'), $content);
         }
-
-        $dir->writeFile($bundlePath . '0.js', $this->content[0]);
     }
 
     /**
diff --git a/lib/internal/Magento/Framework/View/Asset/Bundle/Manager.php b/lib/internal/Magento/Framework/View/Asset/Bundle/Manager.php
index 9c4b1094b23843af10d72d31997f6e1867d27a01..0b1c7f2cd5b05d20d37b951012650d3044cf7c65 100644
--- a/lib/internal/Magento/Framework/View/Asset/Bundle/Manager.php
+++ b/lib/internal/Magento/Framework/View/Asset/Bundle/Manager.php
@@ -40,23 +40,30 @@ class Manager
 
     /** @var array */
     public static $availableTypes = [self::ASSET_TYPE_JS, self::ASSET_TYPE_HTML];
+    /**
+     * @var Asset\Minification
+     */
+    private $minification;
 
     /**
      * @param Filesystem $filesystem
      * @param Bundle $bundle
      * @param Bundle\ConfigInterface $bundleConfig
      * @param Asset\ConfigInterface $assetConfig
+     * @param Asset\Minification $minification
      */
     public function __construct(
         Filesystem $filesystem,
         Bundle $bundle,
         Bundle\ConfigInterface $bundleConfig,
-        Asset\ConfigInterface $assetConfig
+        Asset\ConfigInterface $assetConfig,
+        Asset\Minification $minification
     ) {
         $this->filesystem = $filesystem;
         $this->assetConfig = $assetConfig;
         $this->bundleConfig = $bundleConfig;
         $this->bundle = $bundle;
+        $this->minification = $minification;
     }
 
     /**
@@ -186,7 +193,7 @@ class Manager
         if (in_array($asset->getFilePath(), $this->excluded)) {
             return false;
         }
-        if ($this->assetConfig->isAssetMinification($asset->getContentType())) {
+        if ($this->minification->isEnabled($asset->getContentType())) {
 
             if (strpos($sourceFile, '.min.') !== false) {
                 $this->excluded[] = str_replace('.min.', '', $sourceFile);
diff --git a/lib/internal/Magento/Framework/View/Asset/Config.php b/lib/internal/Magento/Framework/View/Asset/Config.php
index 1fa3bbde781383f5873c742fe0c358368fa61f46..9845dce1f232c92cf5a46717e52643f34970fe6c 100644
--- a/lib/internal/Magento/Framework/View/Asset/Config.php
+++ b/lib/internal/Magento/Framework/View/Asset/Config.php
@@ -8,6 +8,7 @@ namespace Magento\Framework\View\Asset;
 
 use Magento\Store\Model\ScopeInterface;
 use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Framework\App\State;
 
 /**
  * View asset configuration interface
@@ -24,16 +25,6 @@ class Config implements \Magento\Framework\View\Asset\ConfigInterface
      */
     const XML_PATH_MERGE_JS_FILES = 'dev/js/merge_files';
 
-    /**
-     * XML path for asset minification configuration
-     */
-    const XML_PATH_MINIFICATION_ENABLED = 'dev/%s/minify_files';
-
-    /**
-     * XML path for asset minification adapter configuration
-     */
-    const XML_PATH_MINIFICATION_ADAPTER = 'dev/%s/minify_adapter';
-
     /**
      * XML path for asset minification adapter configuration
      */
@@ -96,34 +87,6 @@ class Config implements \Magento\Framework\View\Asset\ConfigInterface
         );
     }
 
-    /**
-     * Check whether asset minification is on for specified content type
-     *
-     * @param string $contentType
-     * @return bool
-     */
-    public function isAssetMinification($contentType)
-    {
-        return (bool)$this->scopeConfig->isSetFlag(
-            sprintf(self::XML_PATH_MINIFICATION_ENABLED, $contentType),
-            ScopeInterface::SCOPE_STORE
-        );
-    }
-
-    /**
-     * Get asset minification adapter for specified content type
-     *
-     * @param string $contentType
-     * @return string
-     */
-    public function getAssetMinificationAdapter($contentType)
-    {
-        return (string)$this->scopeConfig->getValue(
-            sprintf(self::XML_PATH_MINIFICATION_ADAPTER, $contentType),
-            ScopeInterface::SCOPE_STORE
-        );
-    }
-
     /**
      * Check whether minify of HTML is on
      *
diff --git a/lib/internal/Magento/Framework/View/Asset/ConfigInterface.php b/lib/internal/Magento/Framework/View/Asset/ConfigInterface.php
index f099082ce4442631f9690cca216309906362fe81..607bb10e9aacf0569f5f0a57943b39839c62f633 100644
--- a/lib/internal/Magento/Framework/View/Asset/ConfigInterface.php
+++ b/lib/internal/Magento/Framework/View/Asset/ConfigInterface.php
@@ -31,22 +31,6 @@ interface ConfigInterface
      */
     public function isBundlingJsFiles();
 
-    /**
-     * Check whether asset minification is on for specified content type
-     *
-     * @param string $contentType
-     * @return bool
-     */
-    public function isAssetMinification($contentType);
-
-    /**
-     * Get asset minification adapter for specified content type
-     *
-     * @param string $contentType
-     * @return string
-     */
-    public function getAssetMinificationAdapter($contentType);
-
     /**
      * Check whether minify of HTML is on
      *
diff --git a/lib/internal/Magento/Framework/View/Asset/File.php b/lib/internal/Magento/Framework/View/Asset/File.php
index 09541945b0e03efad1408fef51b477faef45b6aa..4186a5b066f6cec7a37d4c00848199a4b05021c8 100644
--- a/lib/internal/Magento/Framework/View/Asset/File.php
+++ b/lib/internal/Magento/Framework/View/Asset/File.php
@@ -6,6 +6,8 @@
 
 namespace Magento\Framework\View\Asset;
 
+use Magento\Framework\View\Asset\ConfigInterface as AssetConfigInterface;
+
 /**
  * A locally available static view file asset that can be referred with a file path
  *
@@ -43,20 +45,33 @@ class File implements MergeableInterface
      */
     private $resolvedFile;
 
+    /**
+     * @var Minification
+     */
+    private $minification;
+
     /**
      * @param Source $source
      * @param ContextInterface $context
      * @param string $filePath
      * @param string $module
      * @param string $contentType
-     */
-    public function __construct(Source $source, ContextInterface $context, $filePath, $module, $contentType)
-    {
+     * @param Minification $minification
+     */
+    public function __construct(
+        Source $source,
+        ContextInterface $context,
+        $filePath,
+        $module,
+        $contentType,
+        Minification $minification
+    ) {
         $this->source = $source;
         $this->context = $context;
         $this->filePath = $filePath;
         $this->module = $module;
         $this->contentType = $contentType;
+        $this->minification = $minification;
     }
 
     /**
@@ -92,6 +107,7 @@ class File implements MergeableInterface
         $result = $this->join($result, $this->context->getPath());
         $result = $this->join($result, $this->module);
         $result = $this->join($result, $this->filePath);
+        $result = $this->minification->addMinifiedSign($result);
         return $result;
     }
 
diff --git a/lib/internal/Magento/Framework/View/Asset/File/ContextFactory.php b/lib/internal/Magento/Framework/View/Asset/File/ContextFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..fb375b886f31613d18233fc2c4204538d77461bf
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Asset/File/ContextFactory.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Asset\File;
+
+use Magento\Framework\ObjectManagerInterface;
+
+/**
+ * Factory class for \Magento\Framework\View\Asset\File\Context
+ */
+class ContextFactory
+{
+    /**
+     * @var ObjectManagerInterface
+     */
+    private $objectManager;
+
+    /**
+     * @param ObjectManagerInterface $objectManager
+     */
+    public function __construct(ObjectManagerInterface $objectManager)
+    {
+        $this->objectManager = $objectManager;
+    }
+
+    /**
+     * Create class instance with specified parameters
+     *
+     * @param array $data
+     * @return \Magento\Framework\View\Asset\File\Context
+     */
+    public function create(array $data = [])
+    {
+        return $this->objectManager->create(Context::class, $data);
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Asset/File/FallbackContextFactory.php b/lib/internal/Magento/Framework/View/Asset/File/FallbackContextFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..4d2b7d2cffb5d8c9b11c628212a8f4646191f132
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Asset/File/FallbackContextFactory.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Asset\File;
+
+use Magento\Framework\ObjectManagerInterface;
+
+/**
+ * Factory class for \Magento\Framework\View\Asset\File\FallbackContext
+ */
+class FallbackContextFactory
+{
+    /**
+     * @var ObjectManagerInterface
+     */
+    private $objectManager;
+
+    /**
+     * @param ObjectManagerInterface $objectManager
+     */
+    public function __construct(ObjectManagerInterface $objectManager)
+    {
+        $this->objectManager = $objectManager;
+    }
+
+    /**
+     * Create class instance with specified parameters
+     *
+     * @param array $data
+     * @return \Magento\Framework\View\Asset\File\FallbackContext
+     */
+    public function create(array $data = [])
+    {
+        return $this->objectManager->create(FallbackContext::class, $data);
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Asset/FileFactory.php b/lib/internal/Magento/Framework/View/Asset/FileFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..13f355c8efe368a5d3f41855bfa539235bacc794
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Asset/FileFactory.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Asset;
+
+use Magento\Framework\ObjectManagerInterface;
+
+/**
+ * Factory class for \Magento\Framework\View\Asset\File
+ */
+class FileFactory
+{
+    /**
+     * @var ObjectManagerInterface
+     */
+    private $objectManager;
+
+    /**
+     * @param ObjectManagerInterface $objectManager
+     */
+    public function __construct(ObjectManagerInterface $objectManager)
+    {
+        $this->objectManager = $objectManager;
+    }
+
+    /**
+     * Create class instance with specified parameters
+     *
+     * @param array $data
+     * @return \Magento\Framework\View\Asset\File
+     */
+    public function create(array $data = [])
+    {
+        return $this->objectManager->create(File::class, $data);
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Asset/Merged.php b/lib/internal/Magento/Framework/View/Asset/Merged.php
index 796af0be5cff413d2027a72714582ae1b221230b..c52e0daa8fb5e62ef6320d005c4ea8da6ff84033 100644
--- a/lib/internal/Magento/Framework/View/Asset/Merged.php
+++ b/lib/internal/Magento/Framework/View/Asset/Merged.php
@@ -10,6 +10,11 @@ namespace Magento\Framework\View\Asset;
  */
 class Merged implements \Iterator
 {
+    /**
+     * Directory for dynamically generated public view files, relative to STATIC_VIEW
+     */
+    const CACHE_VIEW_REL = '_cache';
+
     /**
      * @var \Psr\Log\LoggerInterface
      */
@@ -169,6 +174,6 @@ class Merged implements \Iterator
      */
     public static function getRelativeDir()
     {
-        return Minified\AbstractAsset::CACHE_VIEW_REL . '/merged';
+        return self::CACHE_VIEW_REL . '/merged';
     }
 }
diff --git a/lib/internal/Magento/Framework/View/Asset/Minification.php b/lib/internal/Magento/Framework/View/Asset/Minification.php
new file mode 100644
index 0000000000000000000000000000000000000000..27afca110ddcbb276addbb14a8ca577793f2b82f
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Asset/Minification.php
@@ -0,0 +1,145 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Asset;
+
+use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Framework\App\State;
+
+class Minification
+{
+    /**
+     * XML path for asset minification configuration
+     */
+    const XML_PATH_MINIFICATION_ENABLED = 'dev/%s/minify_files';
+
+    const XML_PATH_MINIFICATION_EXCLUDES = 'dev/%s/minify_exclude';
+
+    /**
+     * @var ScopeConfigInterface
+     */
+    private $scopeConfig;
+    /**
+     * @var State
+     */
+    private $appState;
+    /**
+     * @var string
+     */
+    private $scope;
+    /**
+     * @var array
+     */
+    private $excludes = [];
+
+    /**
+     * @param ScopeConfigInterface $scopeConfig
+     * @param State $appState
+     * @param string $scope
+     */
+    public function __construct(ScopeConfigInterface $scopeConfig, State $appState, $scope = 'store')
+    {
+        $this->scopeConfig = $scopeConfig;
+        $this->appState = $appState;
+        $this->scope = $scope;
+    }
+
+    /**
+     * Check whether asset minification is on for specified content type
+     *
+     * @param string $contentType
+     * @return bool
+     */
+    public function isEnabled($contentType)
+    {
+        return
+            $this->appState->getMode() != State::MODE_DEVELOPER &&
+            (bool)$this->scopeConfig->isSetFlag(
+                sprintf(self::XML_PATH_MINIFICATION_ENABLED, $contentType),
+                $this->scope
+            );
+    }
+
+    /**
+     * Add 'min' suffix if minification is enabled and $filename has no one.
+     *
+     * @param string $filename
+     * @return string
+     */
+    public function addMinifiedSign($filename)
+    {
+        $extension = pathinfo($filename, PATHINFO_EXTENSION);
+
+        if (
+            $this->isEnabled($extension) &&
+            !$this->isExcluded($filename) &&
+            !$this->isMinifiedFilename($filename)
+        ) {
+            $filename = substr($filename, 0, -strlen($extension)) . 'min.' . $extension;
+        }
+        return $filename;
+    }
+
+    /**
+     * Remove 'min' suffix if exists and minification is enabled
+     *
+     * @param string $filename
+     * @return string
+     */
+    public function removeMinifiedSign($filename)
+    {
+        $extension = pathinfo($filename, PATHINFO_EXTENSION);
+
+        if (
+            $this->isEnabled($extension) &&
+            !$this->isExcluded($filename) &&
+            $this->isMinifiedFilename($filename)
+        ) {
+            $filename = substr($filename, 0, -strlen($extension) - 4) . $extension;
+        }
+        return $filename;
+    }
+
+    /**
+     * @param string $filename
+     * @return bool
+     */
+    public function isMinifiedFilename($filename)
+    {
+        return substr($filename, strrpos($filename, '.') - 4, 5) == '.min.';
+    }
+
+    /**
+     * @param string $filename
+     * @return boolean
+     */
+    public function isExcluded($filename)
+    {
+        foreach ($this->getExcludes(pathinfo($filename, PATHINFO_EXTENSION)) as $exclude) {
+            if (preg_match('/' . str_replace('/', '\/', $exclude) . '/', $filename)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @param string $contentType
+     * @return string[]
+     */
+    public function getExcludes($contentType)
+    {
+        if (!isset($this->excludes[$contentType])) {
+            $this->excludes[$contentType] = [];
+            $key = sprintf(self::XML_PATH_MINIFICATION_EXCLUDES, $contentType);
+            foreach (explode("\n", $this->scopeConfig->getValue($key, $this->scope)) as $exclude) {
+                if (trim($exclude) != '') {
+                    $this->excludes[$contentType][] = trim($exclude);
+                }
+            };
+        }
+        return $this->excludes[$contentType];
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Asset/Minified/AbstractAsset.php b/lib/internal/Magento/Framework/View/Asset/Minified/AbstractAsset.php
deleted file mode 100644
index bbfa28664ed345a80e178071ee967ecbe281aca3..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Asset/Minified/AbstractAsset.php
+++ /dev/null
@@ -1,336 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Framework\View\Asset\Minified;
-
-use Magento\Framework\App\Filesystem\DirectoryList;
-use Magento\Framework\View\Asset\MergeableInterface;
-use Magento\Framework\View\Asset\LocalInterface;
-use \Magento\Framework\Phrase;
-
-/**
- * Minified page asset
- */
-abstract class AbstractAsset implements MergeableInterface
-{
-    /**#@+
-     * Strategies for verifying whether the files need to be minified
-     */
-    const FILE_EXISTS = 'file_exists';
-    const MTIME = 'mtime';
-    /**#@-*/
-
-    /**
-     * Directory for dynamically generated public view files, relative to STATIC_VIEW
-     */
-    const CACHE_VIEW_REL = '_cache';
-
-    /**
-     * LocalInterface
-     *
-     * @var LocalInterface
-     */
-    protected $originalAsset;
-
-    /**
-     * @var string
-     */
-    protected $strategy;
-
-    /**
-     * File
-     *
-     * @var string
-     */
-    protected $file;
-
-    /**
-     * Relative path to the file
-     *
-     * @var string
-     */
-    protected $path;
-
-    /**
-     * @var string
-     */
-    protected $filePath;
-
-    /**
-     * @var \Magento\Framework\View\Asset\File\Context
-     */
-    protected $context;
-
-    /**
-     * URL
-     *
-     * @var string
-     */
-    protected $url;
-
-    /**
-     * @var \Magento\Framework\Code\Minifier\AdapterInterface
-     */
-    protected $adapter;
-
-    /**
-     * Logger
-     *
-     * @var \Psr\Log\LoggerInterface
-     */
-    protected $logger;
-
-    /**
-     * Directory object for root directory
-     *
-     * @var \Magento\Framework\Filesystem\Directory\ReadInterface
-     */
-    protected $rootDir;
-
-    /**
-     * Directory object for static view directory
-     *
-     * @var \Magento\Framework\Filesystem\Directory\ReadInterface
-     */
-    protected $staticViewDir;
-
-    /**
-     * Url configuration
-     *
-     * @var \Magento\Framework\UrlInterface
-     */
-    protected $baseUrl;
-
-    /**
-     * Constructor
-     *
-     * @param LocalInterface $asset
-     * @param \Psr\Log\LoggerInterface $logger
-     * @param \Magento\Framework\Filesystem $filesystem
-     * @param \Magento\Framework\UrlInterface $baseUrl
-     * @param \Magento\Framework\Code\Minifier\AdapterInterface $adapter
-     * @param string $strategy
-     */
-    public function __construct(
-        LocalInterface $asset,
-        \Psr\Log\LoggerInterface $logger,
-        \Magento\Framework\Filesystem $filesystem,
-        \Magento\Framework\UrlInterface $baseUrl,
-        \Magento\Framework\Code\Minifier\AdapterInterface $adapter,
-        $strategy = self::FILE_EXISTS
-    ) {
-        $this->originalAsset = $asset;
-        $this->strategy = $strategy;
-        $this->logger = $logger;
-        $this->rootDir = $filesystem->getDirectoryRead(DirectoryList::ROOT);
-        $this->staticViewDir = $filesystem->getDirectoryWrite(DirectoryList::STATIC_VIEW);
-        $this->baseUrl = $baseUrl;
-        $this->adapter = $adapter;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getUrl()
-    {
-        if (empty($this->url)) {
-            $this->process();
-        }
-        return $this->url;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getContentType()
-    {
-        return $this->originalAsset->getContentType();
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getSourceFile()
-    {
-        if (empty($this->file)) {
-            $this->process();
-        }
-        return $this->file;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getPath()
-    {
-        if (empty($this->path)) {
-            $this->process();
-        }
-        return $this->path;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getFilePath()
-    {
-        if (null === $this->filePath) {
-            $this->process();
-        }
-        return $this->filePath;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getContext()
-    {
-        if (null === $this->context) {
-            $this->process();
-        }
-        return $this->context;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getModule()
-    {
-        return $this->originalAsset->getModule();
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getContent()
-    {
-        return $this->staticViewDir->readFile($this->getPath());
-    }
-
-    /**
-     * Minify content of child asset
-     *
-     * @return void
-     */
-    protected function process()
-    {
-        if ($this->isFileMinified($this->originalAsset->getPath())) {
-            $this->fillPropertiesByOriginalAsset();
-        } elseif ($this->hasPreminifiedFile($this->originalAsset->getSourceFile())) {
-            $this->fillPropertiesByOriginalAssetWithMin();
-        } else {
-            try {
-                $this->fillPropertiesByMinifyingAsset();
-            } catch (\Exception $e) {
-                $this->logger->critical(
-                    new \Magento\Framework\Exception\LocalizedException(
-                        new Phrase('Could not minify file: %1', [$this->originalAsset->getSourceFile()]),
-                        $e
-                    )
-                );
-                $this->fillPropertiesByOriginalAsset();
-            }
-        }
-    }
-
-    /**
-     * Check, whether file is already minified
-     *
-     * @param string $fileName
-     * @return bool
-     */
-    protected function isFileMinified($fileName)
-    {
-        return (bool)preg_match('#\.min\.\w+$#', $fileName);
-    }
-
-    /**
-     * Check, whether the file has its preminified version in the same directory
-     *
-     * @param string $fileName
-     * @return bool
-     */
-    protected function hasPreminifiedFile($fileName)
-    {
-        $minifiedFile = $this->composeMinifiedName($fileName);
-        return $this->rootDir->isExist($this->rootDir->getRelativePath($minifiedFile));
-    }
-
-    /**
-     * Compose path to a preminified file in the same folder out of path to an original file
-     *
-     * @param string $fileName
-     * @return string
-     */
-    protected function composeMinifiedName($fileName)
-    {
-        return preg_replace('/\\.([^.]*)$/', '.min.$1', $fileName);
-    }
-
-    /**
-     * Fill the properties by bare copying properties from original asset
-     *
-     * @return void
-     */
-    protected function fillPropertiesByOriginalAsset()
-    {
-        $this->file = $this->originalAsset->getSourceFile();
-        $this->path = $this->originalAsset->getPath();
-        $this->filePath = $this->originalAsset->getFilePath();
-        $this->context = $this->originalAsset->getContext();
-        $this->url = $this->originalAsset->getUrl();
-
-        $isExists = $this->staticViewDir->isExist($this->originalAsset->getPath());
-        if (!$isExists) {
-            $this->staticViewDir->writeFile($this->originalAsset->getPath(), $this->originalAsset->getContent());
-        }
-    }
-
-    /**
-     * Fill the properties by copying properties from original asset and adding '.min' inside them
-     *
-     * @return void
-     */
-    protected function fillPropertiesByOriginalAssetWithMin()
-    {
-        $this->file = $this->composeMinifiedName($this->originalAsset->getSourceFile());
-        $this->path = $this->composeMinifiedName($this->originalAsset->getPath());
-        $this->filePath = $this->composeMinifiedName($this->originalAsset->getFilePath());
-        $this->context = $this->originalAsset->getContext();
-        $this->url = $this->composeMinifiedName($this->originalAsset->getUrl());
-    }
-
-    /**
-     * Perform actual minification
-     *
-     * @return void
-     */
-    protected function minify()
-    {
-        $isExists = $this->staticViewDir->isExist($this->path);
-        if (!$isExists) {
-            $shouldMinify = true;
-        } elseif ($this->strategy == self::FILE_EXISTS) {
-            $shouldMinify = false;
-        } else {
-            $origlFile = $this->rootDir->getRelativePath($this->originalAsset->getSourceFile());
-            $origMtime = $this->rootDir->stat($origlFile)['mtime'];
-            $minMtime = $this->staticViewDir->stat($this->path)['mtime'];
-            $shouldMinify = $origMtime != $minMtime;
-        }
-        if ($shouldMinify) {
-            $content = $this->adapter->minify($this->originalAsset->getContent());
-            $this->staticViewDir->writeFile($this->path, $content);
-        }
-    }
-
-    /**
-     * Generate minified file and fill the properties to reference that file
-     *
-     * @return void
-     */
-    abstract protected function fillPropertiesByMinifyingAsset();
-}
diff --git a/lib/internal/Magento/Framework/View/Asset/Minified/ImmutablePathAsset.php b/lib/internal/Magento/Framework/View/Asset/Minified/ImmutablePathAsset.php
deleted file mode 100644
index b3e298892bfc4a4a2bbf8c1f5a9119b13c9c03c0..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Asset/Minified/ImmutablePathAsset.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Framework\View\Asset\Minified;
-
-class ImmutablePathAsset extends AbstractAsset
-{
-
-    /**
-     * Generate minified file and fill the properties to reference that file
-     *
-     * @return void
-     */
-    protected function fillPropertiesByMinifyingAsset()
-    {
-        $this->context = $this->originalAsset->getContext();
-        $this->filePath = $this->originalAsset->getFilePath();
-        $this->path = $this->originalAsset->getPath();
-        $this->minify();
-        $this->file = $this->staticViewDir->getAbsolutePath($this->path);
-        $this->url = $this->context->getBaseUrl() . $this->path;
-    }
-}
diff --git a/lib/internal/Magento/Framework/View/Asset/Minified/MutablePathAsset.php b/lib/internal/Magento/Framework/View/Asset/Minified/MutablePathAsset.php
deleted file mode 100644
index f31e2ef7a0b2ab62429ded00542ba28f2876e5d9..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Asset/Minified/MutablePathAsset.php
+++ /dev/null
@@ -1,32 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Framework\View\Asset\Minified;
-
-use Magento\Framework\App\Filesystem\DirectoryList;
-
-class MutablePathAsset extends AbstractAsset
-{
-    /**
-     * Generate minified file and fill the properties to reference that file
-     *
-     * @return void
-     */
-    protected function fillPropertiesByMinifyingAsset()
-    {
-        $path = $this->originalAsset->getPath();
-        $this->context = new \Magento\Framework\View\Asset\File\Context(
-            $this->baseUrl->getBaseUrl(['_type' => \Magento\Framework\UrlInterface::URL_TYPE_STATIC]),
-            DirectoryList::STATIC_VIEW,
-            self::CACHE_VIEW_REL . '/minified'
-        );
-        $this->filePath = md5($path) . '_' . $this->composeMinifiedName(basename($path));
-        $this->path = $this->context->getPath() . '/' . $this->filePath;
-        $this->minify();
-        $this->file = $this->staticViewDir->getAbsolutePath($this->path);
-        $this->url = $this->context->getBaseUrl() . $this->path;
-    }
-}
diff --git a/lib/internal/Magento/Framework/View/Asset/MinifyService.php b/lib/internal/Magento/Framework/View/Asset/MinifyService.php
deleted file mode 100644
index 7d5720fb4a8d618c5056106df90c30638da18efb..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Asset/MinifyService.php
+++ /dev/null
@@ -1,170 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Framework\View\Asset;
-
-/**
- * Service model responsible for configuration of minified asset
- */
-class MinifyService
-{
-    /**
-     * Config
-     *
-     * @var ConfigInterface
-     */
-    protected $config;
-
-    /**
-     * ObjectManager
-     *
-     * @var \Magento\Framework\ObjectManagerInterface
-     */
-    protected $objectManager;
-
-    /**
-     * Enabled
-     *
-     * @var array
-     */
-    protected $enabled = [];
-
-    /**
-     * @var \Magento\Framework\Code\Minifier\AdapterInterface[]
-     */
-    protected $adapters = [];
-
-    /**
-     * @var string
-     */
-    protected $appMode;
-
-    /**
-     * Constructor
-     *
-     * @param ConfigInterface $config
-     * @param \Magento\Framework\ObjectManagerInterface $objectManager
-     * @param string $appMode
-     */
-    public function __construct(
-        ConfigInterface $config,
-        \Magento\Framework\ObjectManagerInterface $objectManager,
-        $appMode = \Magento\Framework\App\State::MODE_DEFAULT
-    ) {
-        $this->config = $config;
-        $this->objectManager = $objectManager;
-        $this->appMode = $appMode;
-    }
-
-    /**
-     * Get filtered assets
-     * Assets applicable for minification are wrapped with the minified asset
-     *
-     * @param array|\Iterator $assets
-     * @param bool $isDirectRequest
-     * @return Minified\AbstractAsset[]
-     */
-    public function getAssets($assets, $isDirectRequest = false)
-    {
-        $resultAssets = [];
-        $strategy = $this->appMode == \Magento\Framework\App\State::MODE_PRODUCTION
-            ? Minified\AbstractAsset::FILE_EXISTS : Minified\AbstractAsset::MTIME;
-        /** @var $asset AssetInterface */
-        foreach ($assets as $asset) {
-            if ($this->isEnabled($asset->getContentType())) {
-                $asset = $this->getAssetDecorated($asset, $strategy, $isDirectRequest);
-            }
-            $resultAssets[] = $asset;
-        }
-        return $resultAssets;
-    }
-
-    /**
-     * Check if minification is enabled for specified content type
-     *
-     * @param string $contentType
-     * @return bool
-     */
-    protected function isEnabled($contentType)
-    {
-        if (!isset($this->enabled[$contentType])) {
-            $this->enabled[$contentType] = $this->config->isAssetMinification($contentType);
-        }
-        return $this->enabled[$contentType];
-    }
-
-    /**
-     * Get minification adapter by specified content type
-     *
-     * @param string $contentType
-     * @return \Magento\Framework\Code\Minifier\AdapterInterface
-     * @throws \Magento\Framework\Exception\LocalizedException
-     */
-    protected function getAdapter($contentType)
-    {
-        if (!isset($this->adapters[$contentType])) {
-            $adapterClass = $this->config->getAssetMinificationAdapter($contentType);
-            if (!$adapterClass) {
-                throw new \Magento\Framework\Exception\LocalizedException(
-                    new \Magento\Framework\Phrase(
-                        "Minification adapter is not specified for '%1' content type",
-                        [$contentType]
-                    )
-                );
-            }
-            $adapter = $this->objectManager->get($adapterClass);
-            if (!($adapter instanceof \Magento\Framework\Code\Minifier\AdapterInterface)) {
-                $type = get_class($adapter);
-                throw new \Magento\Framework\Exception\LocalizedException(
-                    new \Magento\Framework\Phrase(
-                        "Invalid adapter: '%1'. Expected: \\Magento\\Framework\\Code\\Minifier\\AdapterInterface",
-                        [$type]
-                    )
-                );
-            }
-            $this->adapters[$contentType] = $adapter;
-        }
-        return $this->adapters[$contentType];
-    }
-
-    /**
-     * Returns asset decorated by corresponding minifier
-     *
-     * @param AssetInterface $asset
-     * @param string $strategy
-     * @param bool $isDirectRequest
-     * @return AssetInterface
-     * @throws \Magento\Framework\Exception\LocalizedException
-     */
-    protected function getAssetDecorated(AssetInterface $asset, $strategy, $isDirectRequest)
-    {
-        return
-            $this->objectManager->create(
-                $this->getDecoratorClass($asset, $isDirectRequest),
-                [
-                    'asset' => $asset,
-                    'strategy' => $strategy,
-                    'adapter' => $this->getAdapter($asset->getContentType())
-                ]
-            );
-    }
-
-    /**
-     * Returns minifier decorator class name for given asset
-     *
-     * @param AssetInterface $asset
-     * @param bool $isDirectRequest
-     * @return string
-     */
-    protected function getDecoratorClass(AssetInterface $asset, $isDirectRequest)
-    {
-        if ($isDirectRequest || $asset->getContentType() == 'css') {
-            $result = 'Magento\Framework\View\Asset\Minified\ImmutablePathAsset';
-        } else {
-            $result = 'Magento\Framework\View\Asset\Minified\MutablePathAsset';
-        }
-        return $result;
-    }
-}
diff --git a/lib/internal/Magento/Framework/View/Asset/PreProcessor/Cache.php b/lib/internal/Magento/Framework/View/Asset/PreProcessor/Cache.php
deleted file mode 100644
index 0228df175380c3d3f5de2484ab0a9e82b1827f11..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Asset/PreProcessor/Cache.php
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Framework\View\Asset\PreProcessor;
-
-class Cache extends \Magento\Framework\Cache\Frontend\Decorator\TagScope
-{
-    /**
-     * Cache type code unique among all cache types
-     */
-    const TYPE_IDENTIFIER = 'view_files_preprocessing';
-
-    /**
-     * Cache tag used to distinguish the cache type from all other cache
-     */
-    const CACHE_TAG = 'VIEW_FILES_PREPROCESSING';
-
-    /**
-     * @param \Magento\Framework\App\Cache\Type\FrontendPool $cacheFrontendPool
-     */
-    public function __construct(\Magento\Framework\App\Cache\Type\FrontendPool $cacheFrontendPool)
-    {
-        parent::__construct($cacheFrontendPool->get(self::TYPE_IDENTIFIER), self::CACHE_TAG);
-    }
-}
diff --git a/lib/internal/Magento/Framework/View/Asset/PreProcessor/Chain.php b/lib/internal/Magento/Framework/View/Asset/PreProcessor/Chain.php
index cf7a30b161a7b27986eba272d084eafb418732eb..eba9cad8083ca00a878e49addd780350cd791300 100644
--- a/lib/internal/Magento/Framework/View/Asset/PreProcessor/Chain.php
+++ b/lib/internal/Magento/Framework/View/Asset/PreProcessor/Chain.php
@@ -49,15 +49,22 @@ class Chain
      */
     protected $targetAssetPath;
 
+    /**
+     * @var string
+     */
+    protected $origAssetPath;
+
     /**
      * @param LocalInterface $asset
      * @param string $origContent
      * @param string $origContentType
+     * @param string $origAssetPath
      */
     public function __construct(
         LocalInterface $asset,
         $origContent,
-        $origContentType
+        $origContentType,
+        $origAssetPath
     ) {
         $this->asset = $asset;
         $this->origContent = $origContent;
@@ -66,6 +73,7 @@ class Chain
         $this->contentType = $origContentType;
         $this->targetContentType = $asset->getContentType();
         $this->targetAssetPath = $asset->getPath();
+        $this->origAssetPath = $origAssetPath;
     }
 
     /**
@@ -186,4 +194,13 @@ class Chain
     {
         return $this->origContentType != $this->contentType || $this->origContent != $this->content;
     }
+
+    /**
+     * @return string
+     * @codeCoverageIgnore
+     */
+    public function getOrigAssetPath()
+    {
+        return $this->origAssetPath;
+    }
 }
diff --git a/lib/internal/Magento/Framework/View/Asset/PreProcessor/ChainFactory.php b/lib/internal/Magento/Framework/View/Asset/PreProcessor/ChainFactory.php
index e817380eff140e92907eb8ffdc453495e0158d86..65fcceecb20696f9e6dde3d044712e0c7421b242 100644
--- a/lib/internal/Magento/Framework/View/Asset/PreProcessor/ChainFactory.php
+++ b/lib/internal/Magento/Framework/View/Asset/PreProcessor/ChainFactory.php
@@ -7,6 +7,10 @@ namespace Magento\Framework\View\Asset\PreProcessor;
 
 use Magento\Framework\ObjectManagerInterface;
 
+/**
+ * Factory for Magento\Framework\View\Asset\PreProcessor\Chain
+ * @codeCoverageIgnore
+ */
 class ChainFactory implements ChainFactoryInterface
 {
     /**
@@ -14,30 +18,21 @@ class ChainFactory implements ChainFactoryInterface
      *
      * @var ObjectManagerInterface
      */
-    private $_objectManager;
+    private $objectManager;
 
     /**
      * @param ObjectManagerInterface $objectManager
      */
-    public function __construct(
-        ObjectManagerInterface $objectManager
-    ) {
-        $this->_objectManager = $objectManager;
+    public function __construct(ObjectManagerInterface $objectManager)
+    {
+        $this->objectManager = $objectManager;
     }
 
     /**
-     * {inheritdoc}
+     * {@inheritdoc}
      */
     public function create(array $arguments = [])
     {
-        $arguments = array_intersect_key(
-            $arguments,
-            [
-                'asset' => 'asset',
-                'origContent' => 'origContent',
-                'origContentType' => 'origContentType'
-            ]
-        );
-        return $this->_objectManager->create('Magento\Framework\View\Asset\PreProcessor\Chain', $arguments);
+        return $this->objectManager->create(Chain::class, $arguments);
     }
 }
diff --git a/lib/internal/Magento/Framework/View/Asset/PreProcessor/Minify.php b/lib/internal/Magento/Framework/View/Asset/PreProcessor/Minify.php
new file mode 100644
index 0000000000000000000000000000000000000000..8a023237601c3111e488dd936699dee035f79c21
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Asset/PreProcessor/Minify.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Asset\PreProcessor;
+
+use Magento\Framework\Code\Minifier\AdapterInterface;
+use Magento\Framework\View\Asset\Minification;
+use Magento\Framework\View\Asset\PreProcessor;
+use Magento\Framework\View\Asset\PreProcessorInterface;
+
+/**
+ * Assets minification pre-processor
+ */
+class Minify implements PreProcessorInterface
+{
+    /**
+     * @var AdapterInterface
+     */
+    protected $adapter;
+
+    /**
+     * @var Minification
+     */
+    protected $minification;
+
+    /**
+     * @param AdapterInterface $adapter
+     * @param Minification $minification
+     */
+    public function __construct(AdapterInterface $adapter, Minification $minification)
+    {
+        $this->adapter = $adapter;
+        $this->minification = $minification;
+    }
+
+    /**
+     * Transform content and/or content type for the specified preprocessing chain object
+     *
+     * @param PreProcessor\Chain $chain
+     * @return void
+     */
+    public function process(PreProcessor\Chain $chain)
+    {
+        if (
+            $this->minification->isEnabled(pathinfo($chain->getTargetAssetPath(), PATHINFO_EXTENSION)) &&
+            $this->minification->isMinifiedFilename($chain->getTargetAssetPath()) &&
+            !$this->minification->isMinifiedFilename($chain->getOrigAssetPath())
+        ) {
+            $content = $this->adapter->minify($chain->getContent());
+            $chain->setContent($content);
+        }
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Asset/RemoteFactory.php b/lib/internal/Magento/Framework/View/Asset/RemoteFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..854fdbc5114c228e31d56161bd27d55b007956fc
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Asset/RemoteFactory.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Asset;
+
+use Magento\Framework\ObjectManagerInterface;
+
+/**
+ * Factory class for \Magento\Framework\View\Asset\Remote
+ */
+class RemoteFactory
+{
+    /**
+     * @var ObjectManagerInterface
+     */
+    private $objectManager;
+
+    /**
+     * @param ObjectManagerInterface $objectManager
+     */
+    public function __construct(ObjectManagerInterface $objectManager)
+    {
+        $this->objectManager = $objectManager;
+    }
+
+    /**
+     * Create class instance with specified parameters
+     *
+     * @param array $data
+     * @return \Magento\Framework\View\Asset\Remote
+     */
+    public function create(array $data = [])
+    {
+        return $this->objectManager->create(Remote::class, $data);
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Asset/Repository.php b/lib/internal/Magento/Framework/View/Asset/Repository.php
index 4b6801310a3758ad679dba0cefa1128d7c24e47d..d227c5856e0bd68b70aa789dbe0e93442a827480 100644
--- a/lib/internal/Magento/Framework/View/Asset/Repository.php
+++ b/lib/internal/Magento/Framework/View/Asset/Repository.php
@@ -56,25 +56,56 @@ class Repository
      */
     private $defaults = null;
 
+    /**
+     * @var FileFactory
+     */
+    private $fileFactory;
+
+    /**
+     * @var File\FallbackContextFactory
+     */
+    private $fallbackContextFactory;
+
+    /**
+     * @var File\ContextFactory
+     */
+    private $contextFactory;
+    /**
+     * @var RemoteFactory
+     */
+    private $remoteFactory;
+
     /**
      * @param \Magento\Framework\UrlInterface $baseUrl
      * @param \Magento\Framework\View\DesignInterface $design
      * @param \Magento\Framework\View\Design\Theme\ListInterface $themeList
      * @param \Magento\Framework\View\Asset\Source $assetSource
      * @param \Magento\Framework\App\Request\Http $request
+     * @param FileFactory $fileFactory
+     * @param File\FallbackContextFactory $fallbackContextFactory
+     * @param File\ContextFactory $contextFactory
+     * @param RemoteFactory $remoteFactory
      */
     public function __construct(
         \Magento\Framework\UrlInterface $baseUrl,
         \Magento\Framework\View\DesignInterface $design,
         \Magento\Framework\View\Design\Theme\ListInterface $themeList,
         \Magento\Framework\View\Asset\Source $assetSource,
-        \Magento\Framework\App\Request\Http $request
+        \Magento\Framework\App\Request\Http $request,
+        FileFactory $fileFactory,
+        File\FallbackContextFactory $fallbackContextFactory,
+        File\ContextFactory $contextFactory,
+        RemoteFactory $remoteFactory
     ) {
         $this->baseUrl = $baseUrl;
         $this->design = $design;
         $this->themeList = $themeList;
         $this->assetSource = $assetSource;
         $this->request = $request;
+        $this->fileFactory = $fileFactory;
+        $this->fallbackContextFactory = $fallbackContextFactory;
+        $this->contextFactory = $contextFactory;
+        $this->remoteFactory = $remoteFactory;
     }
 
     /**
@@ -160,12 +191,14 @@ class Repository
             $themePath,
             $params['locale']
         );
-        return new File(
-            $this->assetSource,
-            $context,
-            $filePath,
-            $module,
-            $this->assetSource->getContentType($filePath)
+        return $this->fileFactory->create(
+            [
+                'source' => $this->assetSource,
+                'context' => $context,
+                'filePath' => $filePath,
+                'module' => $module,
+                'contentType' => $this->assetSource->getContentType($filePath)
+            ]
         );
     }
 
@@ -208,12 +241,14 @@ class Repository
         $id = implode('|', [$baseDirType, $urlType, $secureKey, $area, $themePath, $locale]);
         if (!isset($this->fallbackContext[$id])) {
             $url = $this->baseUrl->getBaseUrl(['_type' => $urlType, '_secure' => $isSecure]);
-            $this->fallbackContext[$id] = new \Magento\Framework\View\Asset\File\FallbackContext(
-                $url,
-                $area,
-                $themePath,
-                $locale,
-                $isSecure
+            $this->fallbackContext[$id] = $this->fallbackContextFactory->create(
+                [
+                    'baseUrl' => $url,
+                    'areaType' => $area,
+                    'themePath' => $themePath,
+                    'localeCode' => $locale,
+                    'isSecure' => $isSecure
+                ]
             );
         }
         return $this->fallbackContext[$id];
@@ -232,12 +267,14 @@ class Repository
         if (!$module) {
             $module = $similarTo->getModule();
         }
-        return new File(
-            $this->assetSource,
-            $similarTo->getContext(),
-            $filePath,
-            $module,
-            $this->assetSource->getContentType($filePath)
+        return $this->fileFactory->create(
+            [
+                'source' => $this->assetSource,
+                'context' => $similarTo->getContext(),
+                'filePath' => $filePath,
+                'module' => $module,
+                'contentType' => $this->assetSource->getContentType($filePath)
+            ]
         );
     }
 
@@ -261,7 +298,15 @@ class Repository
     ) {
         $context = $this->getFileContext($baseDirType, $baseUrlType, $dirPath);
         $contentType = $this->assetSource->getContentType($filePath);
-        return new File($this->assetSource, $context, $filePath, '', $contentType);
+        return $this->fileFactory->create(
+            [
+                'source' => $this->assetSource,
+                'context' => $context,
+                'filePath' => $filePath,
+                'module' => '',
+                'contentType' => $contentType
+            ]
+        );
     }
 
     /**
@@ -279,7 +324,9 @@ class Repository
         $id = implode('|', [$baseDirType, $urlType, $dirPath]);
         if (!isset($this->fileContext[$id])) {
             $url = $this->baseUrl->getBaseUrl(['_type' => $urlType]);
-            $this->fileContext[$id] = new \Magento\Framework\View\Asset\File\Context($url, $baseDirType, $dirPath);
+            $this->fileContext[$id] = $this->contextFactory->create(
+                ['baseUrl' => $url, 'baseDirType' => $baseDirType, 'contextPath' => $dirPath]
+            );
         }
         return $this->fileContext[$id];
     }
@@ -307,10 +354,11 @@ class Repository
      * @param string $url
      * @param string $contentType
      * @return Remote
+     * @codeCoverageIgnore
      */
     public function createRemoteAsset($url, $contentType)
     {
-        return new Remote($url, $contentType);
+        return $this->remoteFactory->create(['url' => $url, 'contentType' => $contentType]);
     }
 
     /**
diff --git a/lib/internal/Magento/Framework/View/Asset/Source.php b/lib/internal/Magento/Framework/View/Asset/Source.php
index 0137d64d7b66239f8658dbc199d7c5740c723685..f3518c2fc3022994c9e14f9280908b5ad01d669b 100644
--- a/lib/internal/Magento/Framework/View/Asset/Source.php
+++ b/lib/internal/Magento/Framework/View/Asset/Source.php
@@ -22,11 +22,6 @@ class Source
      */
     private $filesystem;
 
-    /**
-     * @var \Magento\Framework\View\Asset\PreProcessor\Cache
-     */
-    protected $cache;
-
     /**
      * @var \Magento\Framework\Filesystem\Directory\ReadInterface
      */
@@ -58,7 +53,6 @@ class Source
     private $chainFactory;
 
     /**
-     * @param PreProcessor\Cache $cache
      * @param \Magento\Framework\Filesystem $filesystem
      * @param PreProcessor\Pool $preProcessorPool
      * @param \Magento\Framework\View\Design\FileResolution\Fallback\StaticFile $fallback
@@ -66,14 +60,12 @@ class Source
      * @param ChainFactoryInterface $chainFactory
      */
     public function __construct(
-        PreProcessor\Cache $cache,
         \Magento\Framework\Filesystem $filesystem,
         PreProcessor\Pool $preProcessorPool,
         \Magento\Framework\View\Design\FileResolution\Fallback\StaticFile $fallback,
         \Magento\Framework\View\Design\Theme\ListInterface $themeList,
         ChainFactoryInterface $chainFactory
     ) {
-        $this->cache = $cache;
         $this->filesystem = $filesystem;
         $this->rootDir = $filesystem->getDirectoryRead(DirectoryList::ROOT);
         $this->varDir = $filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
@@ -122,7 +114,7 @@ class Source
      * - directory code where the file is supposed to be found
      * - relative path to the file
      *
-     * Automatically caches the obtained successful results or returns false if source file was not found
+     * returns false if source file was not found
      *
      * @param LocalInterface $asset
      * @return array|bool
@@ -130,17 +122,8 @@ class Source
     private function preProcess(LocalInterface $asset)
     {
         $sourceFile = $this->findSourceFile($asset);
-        if ($sourceFile !== false) {
-            $path = $this->rootDir->getRelativePath($sourceFile);
-        } else {
-            // No original file, the resulting file may be generated by a pre-processor
-            $path = false;
-        }
-        $cacheId = $path . ':' . $asset->getPath();
-        $cached = $this->cache->load($cacheId);
-        if ($cached) {
-            return unserialize($cached);
-        }
+        $dirCode = DirectoryList::ROOT;
+        $path = $this->rootDir->getRelativePath($sourceFile);
 
         $chain = $this->createChain($asset, $path);
         $this->preProcessorPool->process($chain);
@@ -152,7 +135,6 @@ class Source
             $this->varDir->writeFile($path, $chain->getContent());
         }
         $result = [$dirCode, $path];
-        $this->cache->save(serialize($result), $cacheId);
         return $result;
     }
 
diff --git a/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/Cache.php b/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/Cache.php
deleted file mode 100644
index b68048f05c1c2641aa0b143ee1378be843257f11..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/Cache.php
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Framework\View\Design\FileResolution\Fallback;
-
-class Cache extends \Magento\Framework\Cache\Frontend\Decorator\TagScope
-{
-    /**
-     * Cache type code unique among all cache types
-     */
-    const TYPE_IDENTIFIER = 'view_files_fallback';
-
-    /**
-     * Cache tag used to distinguish the cache type from all other cache
-     */
-    const CACHE_TAG = 'VIEW_FILES_FALLBACK';
-
-    /**
-     * @param \Magento\Framework\App\Cache\Type\FrontendPool $cacheFrontendPool
-     */
-    public function __construct(\Magento\Framework\App\Cache\Type\FrontendPool $cacheFrontendPool)
-    {
-        parent::__construct($cacheFrontendPool->get(self::TYPE_IDENTIFIER), self::CACHE_TAG);
-    }
-}
diff --git a/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/CacheData/Flat.php b/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/CacheData/Flat.php
deleted file mode 100644
index f221a84dd78ef57dec894e12aa47549847dae7dc..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/CacheData/Flat.php
+++ /dev/null
@@ -1,67 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Framework\View\Design\FileResolution\Fallback\CacheData;
-
-use Magento\Framework\View\Design\FileResolution\Fallback;
-
-class Flat implements Fallback\CacheDataInterface
-{
-    /**
-     * @var Fallback\Cache
-     */
-    private $cache;
-
-    /**
-     * @param Fallback\Cache $cache
-     */
-    public function __construct(Fallback\Cache $cache)
-    {
-        $this->cache = $cache;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getFromCache($type, $file, $area, $themePath, $locale, $module)
-    {
-        $cacheId = $this->getCacheId($type, $file, $area, $themePath, $locale, $module);
-        return $this->cache->load($cacheId);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function saveToCache($value, $type, $file, $area, $themePath, $locale, $module)
-    {
-        $cacheId = $this->getCacheId($type, $file, $area, $themePath, $locale, $module);
-        return $this->cache->save($value, $cacheId);
-    }
-
-    /**
-     * Generate cache ID
-     *
-     * @param string $type
-     * @param string $file
-     * @param string $area
-     * @param string $themePath
-     * @param string $locale
-     * @param string $module
-     * @return string
-     */
-    protected function getCacheId($type, $file, $area, $themePath, $locale, $module)
-    {
-        return sprintf(
-            "type:%s|area:%s|theme:%s|locale:%s|module:%s|file:%s",
-            $type,
-            $area,
-            $themePath,
-            $locale,
-            $module,
-            $file
-        );
-    }
-}
diff --git a/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/CacheData/Grouped.php b/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/CacheData/Grouped.php
deleted file mode 100644
index f53376f99f4064cf364d9c1ccbd898acf8600ebb..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/CacheData/Grouped.php
+++ /dev/null
@@ -1,125 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Framework\View\Design\FileResolution\Fallback\CacheData;
-
-use Magento\Framework\View\Design\FileResolution\Fallback;
-
-class Grouped implements Fallback\CacheDataInterface
-{
-    /**
-     * @var Fallback\Cache
-     */
-    private $cache;
-
-    /**
-     * @var string[]
-     */
-    private $isDirty = [];
-
-    /**
-     * @var array
-     */
-    private $cacheSections = [];
-
-    /**
-     * @param Fallback\Cache $cache
-     */
-    public function __construct(Fallback\Cache $cache)
-    {
-        $this->cache = $cache;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getFromCache($type, $file, $area, $themePath, $locale, $module)
-    {
-        $sectionId = $this->getCacheSectionId($type, $area, $themePath, $locale);
-        $this->loadSection($sectionId);
-        $recordId = $this->getCacheRecordId($file, $module);
-        if (!isset($this->cacheSections[$sectionId][$recordId])) {
-            $this->cacheSections[$sectionId][$recordId] = false;
-        }
-        return $this->cacheSections[$sectionId][$recordId];
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function saveToCache($value, $type, $file, $area, $themePath, $locale, $module)
-    {
-        $sectionId = $this->getCacheSectionId($type, $area, $themePath, $locale);
-        $this->loadSection($sectionId);
-        $recordId = $this->getCacheRecordId($file, $module);
-        if (!isset($this->cacheSections[$sectionId][$recordId])
-            || $this->cacheSections[$sectionId][$recordId] !== $value) {
-            $this->isDirty[$sectionId] = $sectionId;
-            $this->cacheSections[$sectionId][$recordId] = $value;
-        }
-        return true;
-    }
-
-    /**
-     * @param string $sectionId
-     * @return void
-     */
-    private function loadSection($sectionId)
-    {
-        if (!isset($this->cacheSections[$sectionId])) {
-            $value = $this->cache->load($sectionId);
-            if ($value) {
-                $this->cacheSections[$sectionId] = json_decode($value, true);
-            } else {
-                $this->cacheSections[$sectionId] = [];
-            }
-        }
-    }
-
-    /**
-     * Generate section ID
-     *
-     * @param string $type
-     * @param string $area
-     * @param string $themePath
-     * @param string $locale
-     *
-     * @return string
-     */
-    protected function getCacheSectionId($type, $area, $themePath, $locale)
-    {
-        return sprintf(
-            "type:%s|area:%s|theme:%s|locale:%s",
-            $type,
-            $area,
-            $themePath,
-            $locale
-        );
-    }
-
-    /**
-     * Generate record ID
-     *
-     * @param string $file
-     * @param string $module
-     * @return string
-     */
-    protected function getCacheRecordId($file, $module)
-    {
-        return sprintf("module:%s|file:%s", $module, $file);
-    }
-
-    /**
-     * Save cache
-     */
-    public function __destruct()
-    {
-        foreach ($this->isDirty as $sectionId) {
-            $value = json_encode($this->cacheSections[$sectionId]);
-            $this->cache->save($value, $sectionId);
-        }
-    }
-}
diff --git a/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/CacheDataInterface.php b/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/CacheDataInterface.php
deleted file mode 100644
index 31982b9da6e6f99fa4aca88f162a2c7d9a4c5be8..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/CacheDataInterface.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Framework\View\Design\FileResolution\Fallback;
-
-interface CacheDataInterface
-{
-    /**
-     * Retrieve cached value by file name and parameters
-     *
-     * @param string $type
-     * @param string $file
-     * @param string $area
-     * @param string $themePath
-     * @param string $locale
-     * @param string $module
-     * @return string
-     */
-    public function getFromCache($type, $file, $area, $themePath, $locale, $module);
-
-    /**
-     * Save value to cache as unique to file name and parameters
-     *
-     * @param string $value
-     * @param string $type
-     * @param string $file
-     * @param string $area
-     * @param string $themePath
-     * @param string $locale
-     * @param string $module
-     * @return bool
-     */
-    public function saveToCache($value, $type, $file, $area, $themePath, $locale, $module);
-}
diff --git a/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/Resolver/Alternative.php b/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/Resolver/Alternative.php
index a7bb4b7e2e041c2d8f24fb31d4688553fa863325..f943656b1cd92a2a0da9803d84a129a3593b3c6e 100644
--- a/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/Resolver/Alternative.php
+++ b/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/Resolver/Alternative.php
@@ -25,14 +25,11 @@ class Alternative extends Simple
      *
      * @param Filesystem $filesystem
      * @param \Magento\Framework\View\Design\Fallback\RulePool $rulePool
-     * @param Fallback\CacheDataInterface $cache
      * @param array $alternativeExtensions
-     * @throws \InvalidArgumentException
      */
     public function __construct(
         Filesystem $filesystem,
         \Magento\Framework\View\Design\Fallback\RulePool $rulePool,
-        Fallback\CacheDataInterface $cache,
         array $alternativeExtensions
     ) {
         foreach ($alternativeExtensions as $extension => $newExtensions) {
@@ -44,7 +41,7 @@ class Alternative extends Simple
             }
         }
         $this->alternativeExtensions = $alternativeExtensions;
-        parent::__construct($filesystem, $rulePool, $cache);
+        parent::__construct($filesystem, $rulePool);
     }
 
     /**
diff --git a/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/Resolver/Minification.php b/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/Resolver/Minification.php
new file mode 100644
index 0000000000000000000000000000000000000000..277342b01bbcf627d22c8ed962b2cb121db7fb95
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/Resolver/Minification.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\View\Design\FileResolution\Fallback\Resolver;
+
+use Magento\Framework\View\Asset\Minification as AssetMinification;
+use Magento\Framework\View\Design\FileResolution\Fallback\ResolverInterface;
+use Magento\Framework\View\Design\ThemeInterface;
+
+/**
+ * Resolver for minified asset, when minified is requested but not found
+ */
+class Minification implements ResolverInterface
+{
+    /**
+     * @var ResolverInterface
+     */
+    protected $fallback;
+
+    /**
+     * @var array
+     */
+    protected $extensions;
+
+    /**
+     * @var AssetMinification
+     */
+    private $minification;
+
+    /**
+     * @param ResolverInterface $fallback
+     * @param AssetMinification $minification
+     */
+    public function __construct(ResolverInterface $fallback, AssetMinification $minification)
+    {
+        $this->fallback = $fallback;
+        $this->minification = $minification;
+    }
+    /**
+     * Get path of file after using fallback rules
+     *
+     * @param string $type
+     * @param string $file
+     * @param string|null $area
+     * @param ThemeInterface|null $theme
+     * @param string|null $locale
+     * @param string|null $module
+     * @return string|false
+     */
+    public function resolve($type, $file, $area = null, ThemeInterface $theme = null, $locale = null, $module = null)
+    {
+        $path = $this->fallback->resolve($type, $file, $area, $theme, $locale, $module);
+        if (!$path && $file != ($newFile = $this->minification->removeMinifiedSign($file))) {
+            $path = $this->fallback->resolve($type, $newFile, $area, $theme, $locale, $module);
+        }
+        return $path;
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/Resolver/Simple.php b/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/Resolver/Simple.php
index 12c9195c179da84d743067a49373f362cdc91a56..89f5f45fd1ba3d07bcb823889c316e13cf2dae8d 100644
--- a/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/Resolver/Simple.php
+++ b/lib/internal/Magento/Framework/View/Design/FileResolution/Fallback/Resolver/Simple.php
@@ -36,13 +36,11 @@ class Simple implements Fallback\ResolverInterface
      *
      * @param Filesystem $filesystem
      * @param RulePool $rulePool
-     * @param Fallback\CacheDataInterface $cache
      */
-    public function __construct(Filesystem $filesystem, RulePool $rulePool, Fallback\CacheDataInterface $cache)
+    public function __construct(Filesystem $filesystem, RulePool $rulePool)
     {
         $this->rootDirectory = $filesystem->getDirectoryRead(DirectoryList::ROOT);
         $this->rulePool = $rulePool;
-        $this->cache = $cache;
     }
 
     /**
@@ -51,25 +49,18 @@ class Simple implements Fallback\ResolverInterface
     public function resolve($type, $file, $area = null, ThemeInterface $theme = null, $locale = null, $module = null)
     {
         self::assertFilePathFormat($file);
-        $themePath = $theme ? $theme->getThemePath() : '';
-        $path = $this->cache->getFromCache($type, $file, $area, $themePath, $locale, $module);
-        if (false !== $path) {
-            $path = $path ? $this->rootDirectory->getAbsolutePath($path) : false;
-        } else {
-            $params = ['area' => $area, 'theme' => $theme, 'locale' => $locale];
-            foreach ($params as $key => $param) {
-                if ($param === null) {
-                    unset($params[$key]);
-                }
-            }
-            if (!empty($module)) {
-                list($params['namespace'], $params['module']) = explode('_', $module, 2);
-            }
-            $path = $this->resolveFile($this->rulePool->getRule($type), $file, $params);
-            $cachedValue = $path ? $this->rootDirectory->getRelativePath($path) : '';
 
-            $this->cache->saveToCache($cachedValue, $type, $file, $area, $themePath, $locale, $module);
+        $params = ['area' => $area, 'theme' => $theme, 'locale' => $locale];
+        foreach ($params as $key => $param) {
+            if ($param === null) {
+                unset($params[$key]);
+            }
         }
+        if (!empty($module)) {
+            list($params['namespace'], $params['module']) = explode('_', $module, 2);
+        }
+        $path = $this->resolveFile($this->rulePool->getRule($type), $file, $params);
+
         return $path;
     }
 
diff --git a/lib/internal/Magento/Framework/View/Page/Config/Renderer.php b/lib/internal/Magento/Framework/View/Page/Config/Renderer.php
index 0f3b7cdf09f8d87cfc17acb8591a5e146a86bc34..590ad0369e25cb80dacb3f65fce4b6082639e539 100644
--- a/lib/internal/Magento/Framework/View/Page/Config/Renderer.php
+++ b/lib/internal/Magento/Framework/View/Page/Config/Renderer.php
@@ -25,11 +25,6 @@ class Renderer implements RendererInterface
      */
     protected $pageConfig;
 
-    /**
-     * @var \Magento\Framework\View\Asset\MinifyService
-     */
-    protected $assetMinifyService;
-
     /**
      * @var \Magento\Framework\View\Asset\MergeService
      */
@@ -57,7 +52,6 @@ class Renderer implements RendererInterface
 
     /**
      * @param \Magento\Framework\View\Page\Config $pageConfig
-     * @param \Magento\Framework\View\Asset\MinifyService $assetMinifyService
      * @param \Magento\Framework\View\Asset\MergeService $assetMergeService
      * @param \Magento\Framework\UrlInterface $urlBuilder
      * @param \Magento\Framework\Escaper $escaper
@@ -66,7 +60,6 @@ class Renderer implements RendererInterface
      */
     public function __construct(
         Config $pageConfig,
-        \Magento\Framework\View\Asset\MinifyService $assetMinifyService,
         \Magento\Framework\View\Asset\MergeService $assetMergeService,
         \Magento\Framework\UrlInterface $urlBuilder,
         \Magento\Framework\Escaper $escaper,
@@ -74,7 +67,6 @@ class Renderer implements RendererInterface
         \Psr\Log\LoggerInterface $logger
     ) {
         $this->pageConfig = $pageConfig;
-        $this->assetMinifyService = $assetMinifyService;
         $this->assetMergeService = $assetMergeService;
         $this->urlBuilder = $urlBuilder;
         $this->escaper = $escaper;
@@ -240,8 +232,7 @@ class Renderer implements RendererInterface
      */
     protected function renderAssetGroup(\Magento\Framework\View\Asset\PropertyGroup $group)
     {
-        $groupAssets = $this->assetMinifyService->getAssets($group->getAll());
-        $groupAssets = $this->processMerge($groupAssets, $group);
+        $groupAssets = $this->processMerge($group->getAll(), $group);
 
         $attributes = $this->getGroupAttributes($group);
         $attributes = $this->addDefaultAttributes(
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Asset/Bundle/ManagerTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Asset/Bundle/ManagerTest.php
index a6a5c9eeab3932abdfefa91d8d42a478721fa8d3..30d80e64d0ac96796e7c301a42913b19d8f630ed 100644
--- a/lib/internal/Magento/Framework/View/Test/Unit/Asset/Bundle/ManagerTest.php
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Asset/Bundle/ManagerTest.php
@@ -27,6 +27,9 @@ class ManagerTest extends \PHPUnit_Framework_TestCase
     /** @var  \Magento\Framework\View\Asset\LocalInterface|\PHPUnit_Framework_MockObject_MockObject */
     protected $asset;
 
+    /** @var \Magento\Framework\View\Asset\Minification|\PHPUnit_Framework_MockObject_MockObject */
+    private $minificationMock;
+
     public function setUp()
     {
         $this->filesystem = $this->getMockBuilder('Magento\Framework\Filesystem')
@@ -52,7 +55,17 @@ class ManagerTest extends \PHPUnit_Framework_TestCase
             ['getContentType']
         );
 
-        $this->manager = new Manager($this->filesystem, $this->bundle, $this->bundleConfig, $this->assetConfig);
+        $this->minificationMock = $this->getMockBuilder('Magento\Framework\View\Asset\Minification')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->manager = new Manager(
+            $this->filesystem,
+            $this->bundle,
+            $this->bundleConfig,
+            $this->assetConfig,
+            $this->minificationMock
+        );
     }
 
     public function testAddAssetWithInvalidType()
@@ -97,9 +110,6 @@ class ManagerTest extends \PHPUnit_Framework_TestCase
         $this->asset->expects($this->atLeastOnce())
             ->method('getFilePath')
             ->willReturn('file/path.js');
-        $this->assetConfig->expects($this->once())
-            ->method('isAssetMinification')
-            ->willReturn(false);
         $this->asset->expects($this->atLeastOnce())
             ->method('getContext')
             ->willReturn($context);
@@ -136,9 +146,6 @@ class ManagerTest extends \PHPUnit_Framework_TestCase
         $this->asset->expects($this->atLeastOnce())
             ->method('getFilePath')
             ->willReturn('file/path.js');
-        $this->assetConfig->expects($this->once())
-            ->method('isAssetMinification')
-            ->willReturn(false);
         $this->asset->expects($this->atLeastOnce())
             ->method('getContext')
             ->willReturn($context);
@@ -175,9 +182,6 @@ class ManagerTest extends \PHPUnit_Framework_TestCase
         $this->asset->expects($this->atLeastOnce())
             ->method('getFilePath')
             ->willReturn('file/path.js');
-        $this->assetConfig->expects($this->once())
-            ->method('isAssetMinification')
-            ->willReturn(false);
         $this->asset->expects($this->atLeastOnce())
             ->method('getContext')
             ->willReturn($context);
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Asset/BundleTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Asset/BundleTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d49267b46619172e4c2b12269a7eac408bfad89f
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Asset/BundleTest.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\View\Test\Unit\Asset;
+
+use Magento\Framework\View\Asset\Bundle;
+
+/**
+ * Unit test for Magento\Framework\View\Asset\Bundle
+ */
+class BundleTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\View\Asset\Bundle
+     */
+    protected $bundle;
+
+    /**
+     * @var \Magento\Framework\Filesystem|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $filesystemMock;
+
+    /**
+     * @var \Magento\Framework\View\Asset\Bundle\ConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $bundleConfigMock;
+
+    /**
+     * @var \Magento\Framework\View\Asset\Minification|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $minificationMock;
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function setUp()
+    {
+        $this->filesystemMock = $this->getMockBuilder('Magento\Framework\Filesystem')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->bundleConfigMock = $this->getMockBuilder('Magento\Framework\View\Asset\Bundle\ConfigInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->minificationMock = $this->getMockBuilder('Magento\Framework\View\Asset\Minification')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->bundle = new Bundle(
+            $this->filesystemMock,
+            $this->bundleConfigMock,
+            $this->minificationMock
+        );
+    }
+
+    /**
+     * @return void
+     * @covers \Magento\Framework\View\Asset\Bundle::getAssetKey
+     * @covers \Magento\Framework\View\Asset\Bundle::save
+     */
+    public function testMinSuffix()
+    {
+        $this->minificationMock
+            ->expects($this->any())
+            ->method('addMinifiedSign')
+            ->withConsecutive(
+                ['onefile.js'],
+                ['/js/bundle/bundle0.js']
+            )
+            ->willReturnOnConsecutiveCalls(
+                'onefile.min.js',
+                '/js/bundle/bundle0.min.js'
+            );
+
+        $contextMock = $this->getMockBuilder('Magento\Framework\View\Asset\File\FallbackContext')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $contextMock
+            ->expects($this->any())
+            ->method('getAreaCode')
+            ->willReturn('area');
+        $contextMock
+            ->expects($this->any())
+            ->method('getThemePath')
+            ->willReturn('theme-path');
+        $contextMock
+            ->expects($this->any())
+            ->method('getLocale')
+            ->willReturn('locale');
+
+        $assetMock = $this->getMockBuilder('Magento\Framework\View\Asset\LocalInterface')
+            ->setMethods(['getContentType', 'getContext'])
+            ->getMockForAbstractClass();
+        $assetMock
+            ->expects($this->any())
+            ->method('getContext')
+            ->willReturn($contextMock);
+        $assetMock
+            ->expects($this->any())
+            ->method('getContentType')
+            ->willReturn('js');
+        $assetMock
+            ->expects($this->any())
+            ->method('getFilePath')
+            ->willReturn('onefile.js');
+
+        $writeMock = $this->getMockBuilder('Magento\Framework\Filesystem\Directory\WriteInterface')
+            ->getMockForAbstractClass();
+        $writeMock
+            ->expects($this->once())
+            ->method('writeFile')
+            ->with('/js/bundle/bundle0.min.js', $this->stringContains('onefile.min.js'));
+
+        $this->filesystemMock
+            ->expects($this->any())
+            ->method('getDirectoryWrite')
+            ->willReturn($writeMock);
+
+        $this->bundle->addAsset($assetMock);
+        $this->bundle->flush();
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Asset/ConfigTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Asset/ConfigTest.php
index 891818edefe9c22d1c7d930d28fbc36c4e855775..e4c9febb485357471ca69f8317ddb3985fff3bc2 100644
--- a/lib/internal/Magento/Framework/View/Test/Unit/Asset/ConfigTest.php
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Asset/ConfigTest.php
@@ -1,17 +1,18 @@
 <?php
 /**
- * Tests Magento\Framework\View\Asset\Config
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 
-// @codingStandardsIgnoreFile
-
 namespace Magento\Framework\View\Test\Unit\Asset;
 
-use \Magento\Framework\View\Asset\Config;
+use Magento\Framework\App\State;
+use Magento\Framework\View\Asset\Config;
+use Magento\Store\Model\ScopeInterface;
 
+/**
+ * Tests Magento\Framework\View\Asset\Config
+ */
 class ConfigTest extends \Magento\Framework\TestFramework\Unit\BaseTestCase
 {
     /**
@@ -19,66 +20,54 @@ class ConfigTest extends \Magento\Framework\TestFramework\Unit\BaseTestCase
      */
     private $scopeConfigMock;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\State
+     */
+    private $appStateMock;
+
     /**
      * @var \Magento\Framework\View\Asset\Config
      */
     private $model;
 
+    /**
+     * {@inheritDoc}
+     */
     public function setUp()
     {
-        parent::setUp();
-        $this->scopeConfigMock = $this->basicMock('Magento\Framework\App\Config\ScopeConfigInterface');
-        $this->model = $this->objectManager->getObject('Magento\Framework\View\Asset\Config',
-            ['scopeConfig' => $this->scopeConfigMock]
-        );
+        $this->scopeConfigMock = $this->getMockBuilder('Magento\Framework\App\Config\ScopeConfigInterface')
+            ->getMockForAbstractClass();
+        $this->appStateMock = $this->getMockBuilder('Magento\Framework\App\State')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->model = new Config($this->scopeConfigMock, $this->appStateMock);
     }
 
     /**
+     * @param bool $booleanData
      * @dataProvider booleanDataProvider
+     * @return void
      */
     public function testIsMergeCssFiles($booleanData)
     {
         $this->scopeConfigMock->expects($this->once())
             ->method('isSetFlag')
-            ->with(Config::XML_PATH_MERGE_CSS_FILES, \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->with(Config::XML_PATH_MERGE_CSS_FILES, ScopeInterface::SCOPE_STORE)
             ->willReturn($booleanData);
         $this->assertSame($booleanData, $this->model->isMergeCssFiles());
     }
 
     /**
+     * @param bool $booleanData
      * @dataProvider booleanDataProvider
+     * @return void
      */
     public function testIsMergeJsFiles($booleanData)
     {
         $this->scopeConfigMock->expects($this->once())
             ->method('isSetFlag')
-            ->with(Config::XML_PATH_MERGE_JS_FILES, \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->with(Config::XML_PATH_MERGE_JS_FILES, ScopeInterface::SCOPE_STORE)
             ->willReturn($booleanData);
         $this->assertSame($booleanData, $this->model->isMergeJsFiles());
     }
-
-    public function testIsAssetMinification()
-    {
-        $contentType = 'content type';
-        $this->scopeConfigMock->expects($this->once())
-            ->method('isSetFlag')
-            ->with(
-                sprintf(Config::XML_PATH_MINIFICATION_ENABLED, $contentType),
-                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-            )->willReturn(true);
-        $this->assertTrue($this->model->isAssetMinification($contentType));
-    }
-
-    public function testGetAssetMinificationAdapter()
-    {
-        $contentType = 'content type';
-        $adapter = 'adapter';
-        $this->scopeConfigMock->expects($this->once())
-            ->method('getValue')
-            ->with(
-                sprintf(Config::XML_PATH_MINIFICATION_ADAPTER, $contentType),
-                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-            )->willReturn($adapter);
-        $this->assertSame($adapter, $this->model->getAssetMinificationAdapter($contentType));
-    }
 }
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Asset/FileTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Asset/FileTest.php
index 7b9f17651227a1cb146c814efa20e6d0af40f569..128081901a5c97d0cee7f901429ac1cf6466feb5 100644
--- a/lib/internal/Magento/Framework/View/Test/Unit/Asset/FileTest.php
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Asset/FileTest.php
@@ -11,7 +11,7 @@ use \Magento\Framework\View\Asset\File;
 class FileTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var Source|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\View\Asset\Source|\PHPUnit_Framework_MockObject_MockObject
      */
     private $source;
 
@@ -20,6 +20,11 @@ class FileTest extends \PHPUnit_Framework_TestCase
      */
     private $context;
 
+    /**
+     * @var \Magento\Framework\View\Asset\Minification|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $minificationMock;
+
     /**
      * @var File
      */
@@ -29,7 +34,23 @@ class FileTest extends \PHPUnit_Framework_TestCase
     {
         $this->source = $this->getMock('Magento\Framework\View\Asset\Source', [], [], '', false);
         $this->context = $this->getMockForAbstractClass('\Magento\Framework\View\Asset\ContextInterface');
-        $this->object = new File($this->source, $this->context, 'dir/file.css', 'Magento_Module', 'css');
+        $this->minificationMock = $this->getMockBuilder('Magento\Framework\View\Asset\Minification')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->minificationMock
+            ->expects($this->any())
+            ->method('addMinifiedSign')
+            ->willReturnArgument(0);
+
+        $this->object = new File(
+            $this->source,
+            $this->context,
+            'dir/file.css',
+            'Magento_Module',
+            'css',
+            $this->minificationMock
+        );
     }
 
     public function testGetUrl()
@@ -42,7 +63,7 @@ class FileTest extends \PHPUnit_Framework_TestCase
     public function testGetContentType()
     {
         $this->assertEquals('css', $this->object->getContentType());
-        $object = new File($this->source, $this->context, '', '', 'type');
+        $object = new File($this->source, $this->context, '', '', 'type', $this->minificationMock);
         $this->assertEquals('type', $object->getContentType());
     }
 
@@ -56,7 +77,7 @@ class FileTest extends \PHPUnit_Framework_TestCase
     public function testGetPath($contextPath, $module, $filePath, $expected)
     {
         $this->context->expects($this->once())->method('getPath')->will($this->returnValue($contextPath));
-        $object = new File($this->source, $this->context, $filePath, $module, '');
+        $object = new File($this->source, $this->context, $filePath, $module, '', $this->minificationMock);
         $this->assertEquals($expected, $object->getPath());
     }
 
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Asset/MinificationTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Asset/MinificationTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a5e1d4ca4389c491ce3272be720d1e603ccb26a6
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Asset/MinificationTest.php
@@ -0,0 +1,217 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\View\Test\Unit\Asset;
+
+use Magento\Framework\App\State;
+use Magento\Framework\View\Asset\Minification;
+use Magento\Store\Model\ScopeInterface;
+
+/**
+ * Unit test for Magento\Framework\View\Asset\Minification
+ */
+class MinificationTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\View\Asset\Minification
+     */
+    protected $minification;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $scopeConfigMock;
+
+    /**
+     * @var \Magento\Framework\App\State|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $appStateMock;
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function setUp()
+    {
+        $this->scopeConfigMock = $this->getMockBuilder('Magento\Framework\App\Config\ScopeConfigInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->appStateMock = $this->getMockBuilder('Magento\Framework\App\State')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->minification = new Minification(
+            $this->scopeConfigMock,
+            $this->appStateMock
+        );
+    }
+
+    /**
+     * @return void
+     */
+    public function testIsEnabled()
+    {
+
+    }
+
+    /**
+     * @param bool $configFlag
+     * @param string $appMode
+     * @param bool $result
+     * @dataProvider isEnabledDataProvider
+     * @return void
+     */
+    public function testIsAssetMinification($configFlag, $appMode, $result)
+    {
+        $contentType = 'content type';
+        $this->scopeConfigMock
+            ->expects($this->any())
+            ->method('isSetFlag')
+            ->with(
+                sprintf(Minification::XML_PATH_MINIFICATION_ENABLED, $contentType),
+                ScopeInterface::SCOPE_STORE
+            )
+            ->willReturn($configFlag);
+        $this->appStateMock
+            ->expects($this->any())
+            ->method('getMode')
+            ->willReturn($appMode);
+
+        $this->assertEquals($result, $this->minification->isEnabled($contentType));
+    }
+
+    /**
+     * @return array
+     */
+    public function isEnabledDataProvider()
+    {
+        return [
+            [false, State::MODE_DEFAULT, false],
+            [false, State::MODE_PRODUCTION, false],
+            [false, State::MODE_DEVELOPER, false],
+            [true, State::MODE_DEFAULT, true],
+            [true, State::MODE_PRODUCTION, true],
+            [true, State::MODE_DEVELOPER, false]
+        ];
+    }
+
+    /**
+     * @param string $filename
+     * @param bool $isEnabled
+     * @param string $expected
+     * @dataProvider addMinifiedSignDataProvider
+     */
+    public function testAddMinifiedSign($filename, $isEnabled, $expected)
+    {
+        $this->scopeConfigMock
+            ->expects($this->any())
+            ->method('isSetFlag')
+            ->willReturn($isEnabled);
+        $this->appStateMock
+            ->expects($this->any())
+            ->method('getMode')
+            ->willReturn(State::MODE_DEFAULT);
+
+        $this->assertEquals(
+            $expected,
+            $this->minification->addMinifiedSign($filename)
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function addMinifiedSignDataProvider()
+    {
+        return [
+            ['test.css', true, 'test.min.css'],
+            ['test.css', false, 'test.css'],
+            ['test.min.css', true, 'test.min.css']
+        ];
+    }
+
+    /**
+     * @param string $filename
+     * @param bool $isEnabled
+     * @param string $expected
+     * @dataProvider removeMinifiedSignDataProvider
+     */
+    public function testRemoveMinifiedSign($filename, $isEnabled, $expected)
+    {
+        $this->scopeConfigMock
+            ->expects($this->any())
+            ->method('isSetFlag')
+            ->willReturn($isEnabled);
+        $this->appStateMock
+            ->expects($this->any())
+            ->method('getMode')
+            ->willReturn(State::MODE_DEFAULT);
+
+        $this->assertEquals(
+            $expected,
+            $this->minification->removeMinifiedSign($filename)
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function removeMinifiedSignDataProvider()
+    {
+        return [
+            ['test.css', true, 'test.css'],
+            ['test.min.css', true, 'test.css'],
+            ['test.min.css', false, 'test.min.css']
+        ];
+    }
+
+    /**
+     * @param string $filename
+     * @param bool $result
+     * @return void
+     * @dataProvider isMinifiedFilenameDataProvider
+     */
+    public function testIsMinifiedFilename($filename, $result)
+    {
+        $this->assertEquals(
+            $result,
+            $this->minification->isMinifiedFilename($filename)
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function isMinifiedFilenameDataProvider()
+    {
+        return [
+            ['test.min.css', true],
+            ['test.mincss', false],
+            ['testmin.css', false],
+            ['test.css', false],
+            ['test.min', false]
+        ];
+    }
+
+    /**
+     * @return void
+     */
+    public function testGetExcludes()
+    {
+        $this->scopeConfigMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->with('dev/js/minify_exclude')
+            ->willReturn(
+                "    /tiny_mce/  \n" .
+                "  /tiny_mce2/  "
+            );
+
+        $expected = ['/tiny_mce/', '/tiny_mce2/'];
+        $this->assertEquals($expected, $this->minification->getExcludes('js'));
+        /** check cache: */
+        $this->assertEquals($expected, $this->minification->getExcludes('js'));
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Asset/Minified/AbstractAssetTestCase.php b/lib/internal/Magento/Framework/View/Test/Unit/Asset/Minified/AbstractAssetTestCase.php
deleted file mode 100644
index 67344819062e006acbe29bcf941e26e72b013e6b..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Test/Unit/Asset/Minified/AbstractAssetTestCase.php
+++ /dev/null
@@ -1,94 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Framework\View\Test\Unit\Asset\Minified;
-
-use Magento\Framework\App\Filesystem\DirectoryList;
-use Magento\Framework\Filesystem\DriverPool;
-
-class AbstractAssetTestCase extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Framework\View\Asset\LocalInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $asset;
-
-    /**
-     * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $logger;
-
-    /**
-     * @var \Magento\Framework\Filesystem\Directory\ReadInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $staticViewDir;
-
-    /**
-     * @var \Magento\Framework\Filesystem\Directory\ReadInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $rootDir;
-
-    /**
-     * @var \Magento\Framework\Url|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $baseUrl;
-
-    /**
-     * @var \Magento\Framework\Filesystem|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $filesystem;
-
-    /**
-     * @var \Magento\Framework\Code\Minifier\AdapterInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $adapter;
-
-    protected function setUp()
-    {
-        $this->asset = $this->getMockForAbstractClass('\Magento\Framework\View\Asset\LocalInterface');
-        $this->logger = $this->getMock('\Psr\Log\LoggerInterface', [], [], '', false);
-        $this->baseUrl = $this->getMock('\Magento\Framework\Url', [], [], '', false);
-        $this->staticViewDir = $this->getMockForAbstractClass(
-            '\Magento\Framework\Filesystem\Directory\WriteInterface'
-        );
-        $this->rootDir = $this->getMockForAbstractClass('\Magento\Framework\Filesystem\Directory\ReadInterface');
-        $this->filesystem = $this->getMock('\Magento\Framework\Filesystem', [], [], '', false);
-        $this->filesystem->expects($this->any())
-            ->method('getDirectoryRead')
-            ->will($this->returnValueMap([
-                [DirectoryList::STATIC_VIEW, DriverPool::FILE, $this->staticViewDir],
-                [DirectoryList::ROOT, DriverPool::FILE, $this->rootDir],
-            ]));
-        $this->filesystem->expects($this->any())
-            ->method('getDirectoryWrite')
-            ->with(DirectoryList::STATIC_VIEW)
-            ->will($this->returnValue($this->staticViewDir));
-        $this->adapter = $this->getMockForAbstractClass('Magento\Framework\Code\Minifier\AdapterInterface');
-    }
-
-    protected function prepareAttemptToMinifyMock($fileExists, $rootDirExpectations = true, $originalExists = true)
-    {
-        $this->asset->expects($this->atLeastOnce())->method('getPath')->will($this->returnValue('test/admin.js'));
-        $this->asset->expects($this->atLeastOnce())
-            ->method('getSourceFile')
-            ->will($this->returnValue('/foo/bar/test/admin.js'));
-        if ($rootDirExpectations) {
-            $this->rootDir->expects($this->once())
-                ->method('getRelativePath')
-                ->with('/foo/bar/test/admin.min.js')
-                ->will($this->returnValue('test/admin.min.js'));
-            $this->rootDir->expects($this->once())
-                ->method('isExist')
-                ->with('test/admin.min.js')
-                ->will($this->returnValue(false));
-        }
-        $this->baseUrl->expects($this->once())->method('getBaseUrl')->will($this->returnValue('http://example.com/'));
-        $this->staticViewDir
-            ->expects($this->exactly(2-intval($originalExists)))
-            ->method('isExist')
-            ->will($this->returnValue($fileExists));
-    }
-}
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Asset/Minified/ImmutablePathAssetTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Asset/Minified/ImmutablePathAssetTest.php
deleted file mode 100644
index def044ac71c7f4cf3f1391c41f864a611802abb4..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Test/Unit/Asset/Minified/ImmutablePathAssetTest.php
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Framework\View\Test\Unit\Asset\Minified;
-
-use Magento\Framework\View\Asset\Minified\ImmutablePathAsset;
-use Magento\Framework\Object;
-
-class ImmutablePathAssetTest extends AbstractAssetTestCase
-{
-    /**
-     * @var ImmutablePathAsset
-     */
-    protected $model;
-
-    protected function setUp()
-    {
-        parent::setUp();
-
-        $this->model = new ImmutablePathAsset(
-            $this->asset,
-            $this->logger,
-            $this->filesystem,
-            $this->baseUrl,
-            $this->adapter
-        );
-    }
-
-    public function testImmutableFilePath()
-    {
-        $this->asset->expects($this->atLeastOnce())->method('getPath')->will($this->returnValue('test/admin.js'));
-        $this->asset->expects($this->atLeastOnce())->method('getFilePath')->will($this->returnValue('test/admin.js'));
-        $this->asset->expects($this->atLeastOnce())
-            ->method('getSourceFile')
-            ->will($this->returnValue('/foo/bar/test/admin.js'));
-        if (true) {
-            $this->rootDir->expects($this->once())
-                ->method('getRelativePath')
-                ->with('/foo/bar/test/admin.min.js')
-                ->will($this->returnValue('test/admin.min.js'));
-            $this->rootDir->expects($this->once())
-                ->method('isExist')
-                ->with('test/admin.min.js')
-                ->will($this->returnValue(false));
-        }
-        $this->baseUrl->expects($this->once())->method('getBaseUrl')->will($this->returnValue('http://example.com/'));
-        $this->staticViewDir
-            ->expects($this->exactly(2-intval(true)))
-            ->method('isExist')
-            ->will($this->returnValue(false));
-
-        $this->asset->method('getContext')->willReturn($this->baseUrl);
-        $this->asset->expects($this->once())->method('getContent')->will($this->returnValue('content'));
-        $this->adapter->expects($this->once())->method('minify')->with('content')->will($this->returnValue('mini'));
-        $this->staticViewDir->expects($this->once())->method('writeFile')->with($this->anything(), 'mini');
-        $this->assertEquals('test/admin.js', $this->model->getFilePath());
-        $this->assertEquals('http://example.com/test/admin.js', $this->model->getUrl());
-    }
-}
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Asset/Minified/MutablePathAssetTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Asset/Minified/MutablePathAssetTest.php
deleted file mode 100644
index df652279e5805a8c0999d0541bbcbaeacb11ba7b..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Test/Unit/Asset/Minified/MutablePathAssetTest.php
+++ /dev/null
@@ -1,217 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Framework\View\Test\Unit\Asset\Minified;
-
-use \Magento\Framework\View\Asset\Minified\MutablePathAsset;
-use \Magento\Framework\View\Asset\Minified\AbstractAsset;
-
-class MutablePathAssetTest extends AbstractAssetTestCase
-{
-    /**
-     * @var MutablePathAsset
-     */
-    protected $_model;
-
-    protected function setUp()
-    {
-        parent::setUp();
-
-        $this->_model = new MutablePathAsset(
-            $this->asset,
-            $this->logger,
-            $this->filesystem,
-            $this->baseUrl,
-            $this->adapter
-        );
-    }
-
-    /**
-     * @param string $method
-     * @param string $expected
-     * @dataProvider inMemoryDecoratorDataProvider
-     */
-    public function testInMemoryDecorator($method, $expected)
-    {
-        $this->prepareRequestedAsMinifiedMock();
-        $this->adapter->expects($this->never())->method('minify');
-        $this->assertSame($expected, $this->_model->$method());
-        $this->assertSame($expected, $this->_model->$method()); // invoke second time to test in-memory caching
-    }
-
-    /**
-     * Prepare case when an asset is requested explicitly with ".min" suffix
-     *
-     * In this case the minification is not supposed to occur
-     */
-    private function prepareRequestedAsMinifiedMock()
-    {
-        $this->asset->expects($this->any())->method('getPath')->will($this->returnValue('test/admin.min.js'));
-        $this->asset->expects($this->once())->method('getSourceFile')->will($this->returnValue('source_file'));
-        $this->asset->expects($this->once())->method('getFilePath')->will($this->returnValue('file_path'));
-        $this->asset->expects($this->once())->method('getContext')->will($this->returnValue('context'));
-        $this->asset->expects($this->once())->method('getUrl')->will($this->returnValue('url'));
-    }
-
-    /**
-     * @return array
-     */
-    public function inMemoryDecoratorDataProvider()
-    {
-        return [
-            ['getUrl', 'url'],
-            ['getSourceFile', 'source_file'],
-            ['getPath', 'test/admin.min.js'],
-            ['getFilePath', 'file_path'],
-            ['getContext', 'context'],
-        ];
-    }
-
-    /**
-     * @param string $method
-     * @param string $expected
-     * @dataProvider assetDecoratorDataProvider
-     */
-    public function testAssetDecorator($method, $expected)
-    {
-        $this->asset->expects($this->exactly(2))->method($method)->will($this->returnValue($expected));
-        $this->assertSame($expected, $this->_model->$method());
-        $this->assertSame($expected, $this->_model->$method()); // 2 times to ensure asset is invoked every time
-    }
-
-    /**
-     * @return array
-     */
-    public function assetDecoratorDataProvider()
-    {
-        return [
-            ['getContentType', 'content_type'],
-            ['getModule', 'module'],
-        ];
-    }
-
-    public function testGetContent()
-    {
-        $this->prepareRequestedAsMinifiedMock();
-        $this->adapter->expects($this->never())->method('minify');
-        $this->staticViewDir->expects($this->exactly(2))
-            ->method('readFile')
-            ->with('test/admin.min.js')
-            ->will($this->returnValue('content'));
-        $this->assertEquals('content', $this->_model->getContent());
-        $this->assertEquals('content', $this->_model->getContent());
-    }
-
-    public function testHasPreminifiedFile()
-    {
-        $this->asset->expects($this->exactly(2))->method('getPath')->will($this->returnValue('test/admin.js'));
-        $this->asset->expects($this->atLeastOnce())
-            ->method('getSourceFile')
-            ->will($this->returnValue('/foo/bar/test/admin.js'));
-        $this->asset->expects($this->once())->method('getFilePath')->will($this->returnValue('file_path'));
-        $this->asset->expects($this->once())->method('getContext')->will($this->returnValue('context'));
-        $this->asset->expects($this->once())->method('getUrl')->will($this->returnValue('url'));
-        $this->rootDir->expects($this->once())
-            ->method('getRelativePath')
-            ->with('/foo/bar/test/admin.min.js')
-            ->will($this->returnValue('test/admin.min.js'));
-        $this->rootDir->expects($this->once())
-            ->method('isExist')
-            ->with('test/admin.min.js')
-            ->will($this->returnValue(true));
-        $this->adapter->expects($this->never())->method('minify');
-        $this->assertEquals('test/admin.min.js', $this->_model->getPath());
-    }
-
-    public function testMinify()
-    {
-        $this->prepareAttemptToMinifyMock(false, true, true, 0);
-        $this->asset->expects($this->once())->method('getContent')->will($this->returnValue('content'));
-        $this->adapter->expects($this->once())->method('minify')->with('content')->will($this->returnValue('mini'));
-        $this->staticViewDir->expects($this->once())->method('writeFile')->with($this->anything(), 'mini');
-        $this->assertStringMatchesFormat('%s_admin.min.js', $this->_model->getFilePath());
-    }
-
-    public function testMinificationFailed()
-    {
-        $this->prepareAttemptToMinifyMock(false, true, false);
-        $this->asset->expects($this->exactly(2))->method('getContent')->will($this->returnValue('content'));
-        $e = new \Exception('test');
-        $this->adapter->expects($this->once())->method('minify')->with('content')->will($this->throwException($e));
-        $this->logger->expects($this->once())->method('critical');
-        $this->staticViewDir->expects($this->once())->method('writeFile');
-        $this->asset->expects($this->once())->method('getFilePath')->will($this->returnValue('file_path'));
-        $this->asset->expects($this->once())->method('getContext')->will($this->returnValue('context'));
-        $this->asset->expects($this->once())->method('getUrl')->will($this->returnValue('url'));
-        $this->assertEquals('test/admin.js', $this->_model->getPath());
-    }
-
-    public function testShouldNotMinifyCozExists()
-    {
-        $this->prepareAttemptToMinifyMock(true, 0);
-        // IS_EXISTS is assumed by default, so nothing to mock here
-        $this->adapter->expects($this->never())->method('minify');
-        $this->assertStringMatchesFormat('%s_admin.min.js', $this->_model->getFilePath());
-    }
-
-    /**
-     * @param int $mtimeOrig
-     * @param int $mtimeMinified
-     * @param bool $isMinifyExpected
-     * @dataProvider minifyMtimeDataProvider
-     */
-    public function testMinifyMtime($mtimeOrig, $mtimeMinified, $isMinifyExpected)
-    {
-        $this->prepareAttemptToMinifyMock(true, false);
-        $model = new MutablePathAsset(
-            $this->asset,
-            $this->logger,
-            $this->filesystem,
-            $this->baseUrl,
-            $this->adapter,
-            AbstractAsset::MTIME
-        );
-        $this->rootDir->expects($this->any())
-            ->method('getRelativePath')
-            ->will($this->returnValueMap([
-                ['/foo/bar/test/admin.min.js', 'test/admin.min.js'],
-                ['/foo/bar/test/admin.js', 'test/admin.js'],
-            ]));
-        $this->rootDir->expects($this->once())
-            ->method('isExist')
-            ->with('test/admin.min.js')
-            ->will($this->returnValue(false));
-        $this->rootDir->expects($this->once())
-            ->method('stat')
-            ->with('test/admin.js')
-            ->will($this->returnValue(['mtime' => $mtimeOrig]));
-        $this->staticViewDir->expects($this->once())
-            ->method('stat')
-            ->with($this->anything())
-            ->will($this->returnValue(['mtime' => $mtimeMinified]));
-        if ($isMinifyExpected) {
-            $this->asset->expects($this->once())->method('getContent')->will($this->returnValue('content'));
-            $this->adapter->expects($this->once())
-                ->method('minify')
-                ->with('content')
-                ->will($this->returnValue('mini'));
-            $this->staticViewDir->expects($this->once())->method('writeFile')->with($this->anything(), 'mini');
-        } else {
-            $this->adapter->expects($this->never())->method('minify');
-        }
-        $this->assertStringMatchesFormat('%s_admin.min.js', $model->getFilePath());
-    }
-
-    /**
-     * @return array
-     */
-    public function minifyMtimeDataProvider()
-    {
-        return [
-            [1, 2, true],
-            [3, 3, false],
-        ];
-    }
-}
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Asset/MinifyServiceTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Asset/MinifyServiceTest.php
deleted file mode 100644
index 2e31f4d67733e308603855cac3dc43dd3d7e7514..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Test/Unit/Asset/MinifyServiceTest.php
+++ /dev/null
@@ -1,174 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Framework\View\Test\Unit\Asset;
-
-use \Magento\Framework\View\Asset\MinifyService;
-use \Magento\Framework\View\Asset\Minified\AbstractAsset;
-
-class MinifyServiceTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Framework\View\Asset\ConfigInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_config;
-
-    /**
-     * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_objectManager;
-
-    /**
-     * @var \Magento\Framework\View\Asset\MinifyService
-     */
-    protected $_model;
-
-    protected function setUp()
-    {
-        $this->_config = $this->getMock('Magento\Framework\View\Asset\ConfigInterface', [], [], '', false);
-        $this->_objectManager = $this->getMock('Magento\Framework\ObjectManagerInterface');
-        $this->_model = new MinifyService($this->_config, $this->_objectManager);
-    }
-
-    /**
-     * @param $appMode
-     * @param $expectedStrategy
-     * @dataProvider getAssetsDataProvider
-     */
-    public function testGetAssets($appMode, $expectedStrategy)
-    {
-        $assetOne = $this->getMockForAbstractClass('Magento\Framework\View\Asset\LocalInterface');
-        $assetOne->expects($this->any())
-            ->method('getContentType')
-            ->will($this->returnValue('js'));
-        $resultOne = $this->getMock('Magento\Framework\View\Asset\Minified\MutablePathAsset', [], [], '', false);
-        $assetTwo = $this->getMockForAbstractClass('Magento\Framework\View\Asset\LocalInterface');
-        $assetTwo->expects($this->any())
-            ->method('getContentType')
-            ->will($this->returnValue('js'));
-        $resultTwo = $this->getMock('Magento\Framework\View\Asset\Minified\MutablePathAsset', [], [], '', false);
-        $this->_config->expects($this->once())
-            ->method('isAssetMinification')
-            ->with('js')
-            ->will($this->returnValue(true));
-        $minifier = $this->getMockForAbstractClass('Magento\Framework\Code\Minifier\AdapterInterface');
-        $this->_config->expects($this->once())
-            ->method('getAssetMinificationAdapter')
-            ->with('js')
-            ->will($this->returnValue('Magento\Framework\Code\Minifier\AdapterInterface'));
-        $this->_objectManager->expects($this->once())
-            ->method('get')
-            ->with('Magento\Framework\Code\Minifier\AdapterInterface')
-            ->will($this->returnValue($minifier));
-        $this->_objectManager->expects($this->exactly(2))
-            ->method('create')
-            ->will($this->returnValueMap(
-                [
-                    [
-                        'Magento\Framework\View\Asset\Minified\MutablePathAsset',
-                        ['asset' => $assetOne, 'strategy' => $expectedStrategy, 'adapter' => $minifier],
-                        $resultOne,
-                    ],
-                    [
-                        'Magento\Framework\View\Asset\Minified\MutablePathAsset',
-                        ['asset' => $assetTwo, 'strategy' => $expectedStrategy, 'adapter' => $minifier],
-                        $resultTwo
-                    ],
-                ]
-            ));
-        $model = new MinifyService($this->_config, $this->_objectManager, $appMode);
-        $result = $model->getAssets([$assetOne, $assetTwo]);
-        $this->assertArrayHasKey(0, $result);
-        $this->assertSame($resultOne, $result[0]);
-        $this->assertArrayHasKey(1, $result);
-        $this->assertSame($resultTwo, $result[1]);
-    }
-
-    /**
-     * @return array
-     */
-    public function getAssetsDataProvider()
-    {
-        return [
-            'production' => [
-                \Magento\Framework\App\State::MODE_PRODUCTION,
-                AbstractAsset::FILE_EXISTS,
-            ],
-            'default'    => [
-                \Magento\Framework\App\State::MODE_DEFAULT,
-                AbstractAsset::MTIME,
-            ],
-            'developer'  => [
-                \Magento\Framework\App\State::MODE_DEVELOPER,
-                AbstractAsset::MTIME,
-            ],
-        ];
-    }
-
-    public function testGetAssetsDisabled()
-    {
-        $asset = $this->getMockForAbstractClass('Magento\Framework\View\Asset\LocalInterface');
-        $asset->expects($this->once())
-            ->method('getContentType')
-            ->will($this->returnValue('js'));
-
-        $this->_config->expects($this->once())
-            ->method('isAssetMinification')
-            ->with('js')
-            ->will($this->returnValue(false));
-        $this->_config->expects($this->never())
-            ->method('getAssetMinificationAdapter');
-
-        $minifiedAssets = $this->_model->getAssets([$asset]);
-        $this->assertCount(1, $minifiedAssets);
-        $this->assertSame($asset, $minifiedAssets[0]);
-    }
-
-    /**
-     * @expectedException \Magento\Framework\Exception\LocalizedException
-     * @expectedExceptionMessage Minification adapter is not specified for 'js' content type
-     */
-    public function testGetAssetsNoAdapterDefined()
-    {
-        $asset = $this->getMockForAbstractClass('Magento\Framework\View\Asset\LocalInterface');
-        $asset->expects($this->any())
-            ->method('getContentType')
-            ->will($this->returnValue('js'));
-
-        $this->_config->expects($this->once())
-            ->method('isAssetMinification')
-            ->with('js')
-            ->will($this->returnValue(true));
-        $this->_config->expects($this->once())
-            ->method('getAssetMinificationAdapter')
-            ->with('js');
-
-        $this->_model->getAssets([$asset]);
-    }
-
-    public function testGetAssetsInvalidAdapter()
-    {
-        $this->setExpectedException(
-            '\Magento\Framework\Exception\LocalizedException',
-            'Invalid adapter: \'stdClass\'. Expected: \Magento\Framework\Code\Minifier\AdapterInterface'
-        );
-        $asset = $this->getMockForAbstractClass('Magento\Framework\View\Asset\LocalInterface');
-        $asset->expects($this->any())
-            ->method('getContentType')
-            ->will($this->returnValue('js'));
-        $this->_config->expects($this->once())
-            ->method('isAssetMinification')
-            ->with('js')
-            ->will($this->returnValue(true));
-        $this->_config->expects($this->once())
-            ->method('getAssetMinificationAdapter')
-            ->with('js')
-            ->will($this->returnValue('StdClass'));
-        $obj = new \StdClass();
-        $this->_objectManager->expects($this->once())->method('get')->with('StdClass')->will($this->returnValue($obj));
-
-        $this->_model->getAssets([$asset]);
-    }
-}
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Asset/PreProcessor/ChainTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Asset/PreProcessor/ChainTest.php
index e0c4e8b4d7003c5a88e7d6194e8117574be2bc9c..b5e0562c7b415784d14d3223792a19c2076b9316 100644
--- a/lib/internal/Magento/Framework/View/Test/Unit/Asset/PreProcessor/ChainTest.php
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Asset/PreProcessor/ChainTest.php
@@ -29,7 +29,7 @@ class ChainTest extends \PHPUnit_Framework_TestCase
     {
         $this->asset = $this->getMockForAbstractClass('\Magento\Framework\View\Asset\LocalInterface');
         $this->asset->expects($this->once())->method('getContentType')->will($this->returnValue('assetType'));
-        $this->object = new Chain($this->asset, 'origContent', 'origType');
+        $this->object = new Chain($this->asset, 'origContent', 'origType', 'origPath');
     }
 
     public function testGetAsset()
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Asset/PreProcessor/MinifyTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Asset/PreProcessor/MinifyTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e1a6855872dfbff588900e31fa2355dd15076484
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Asset/PreProcessor/MinifyTest.php
@@ -0,0 +1,121 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\View\Test\Unit\Asset\PreProcessor;
+
+use Magento\Framework\View\Asset\PreProcessor\Minify;
+
+/**
+ * Unit test for Magento\Framework\View\Asset\PreProcessor\Minify
+ */
+class MinifyTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\View\Asset\PreProcessor\Minify
+     */
+    protected $minify;
+
+    /**
+     * @var \Magento\Framework\Code\Minifier\AdapterInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $adapterMock;
+
+    /**
+     * @var \Magento\Framework\View\Asset\Minification|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $minificationMock;
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function setUp()
+    {
+        $this->adapterMock = $this->getMockBuilder('Magento\Framework\Code\Minifier\AdapterInterface')
+            ->setMethods(['minify'])
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $this->minificationMock = $this->getMockBuilder('Magento\Framework\View\Asset\Minification')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->minify = new Minify(
+            $this->adapterMock,
+            $this->minificationMock
+        );
+    }
+
+    /**
+     * @param string $targetPath
+     * @param string $originalPath
+     * @param int $minifyCalls
+     * @param int $setContentCalls
+     * @param bool $isEnabled
+     * @return void
+     * @dataProvider processDataProvider
+     */
+    public function testProcess($targetPath, $originalPath, $minifyCalls, $setContentCalls, $isEnabled)
+    {
+        $chainMock = $this->getMockBuilder('Magento\Framework\View\Asset\PreProcessor\Chain')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $chainMock
+            ->expects($this->any())
+            ->method('getTargetAssetPath')
+            ->willReturn($targetPath);
+        $chainMock
+            ->expects($this->exactly($setContentCalls))
+            ->method('setContent')
+            ->with('minified content');
+        $chainMock
+            ->expects($this->any())
+            ->method('getContent')
+            ->willReturn('original content');
+        $chainMock
+            ->expects($this->any())
+            ->method('getOrigAssetPath')
+            ->willReturn($originalPath);
+
+        $this->adapterMock
+            ->expects($this->exactly($minifyCalls))
+            ->method('minify')
+            ->with('original content')
+            ->willReturn('minified content');
+
+        $this->minificationMock
+            ->expects($this->any())
+            ->method('isEnabled')
+            ->willReturnMap([['css', $isEnabled]]);
+
+        $this->minificationMock
+            ->expects($this->any())
+            ->method('isMinifiedFilename')
+            ->willReturnMap(
+                [
+                    ['test.min.css', true],
+                    ['test.jpeg', false],
+                    ['test.css', false]
+                ]
+            );
+
+        $this->minify->process($chainMock);
+    }
+
+    /**
+     * @return array
+     */
+    public function processDataProvider()
+    {
+        return [
+            ['test.min.css', 'test.css', 1, 1, true],
+            ['test.min.css', 'test.min.css', 0, 0, true],
+            ['test.jpeg', 'test.jpeg', 0, 0, true],
+            ['test.css', 'test.css', 0, 0, true],
+            ['test.jpeg', 'test.jpeg', 0, 0, true],
+            ['test.css', 'test.css', 0, 0, true],
+            ['test.css', 'test.css', 0, 0, false]
+        ];
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Asset/RepositoryTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Asset/RepositoryTest.php
index 60a2d297e4b5ba5a56bff218941ed1ea2fa7884c..1e22d37bb68169cb3cfcf804a6ffb743db4437ed 100644
--- a/lib/internal/Magento/Framework/View/Test/Unit/Asset/RepositoryTest.php
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Asset/RepositoryTest.php
@@ -4,226 +4,305 @@
  * See COPYING.txt for license details.
  */
 
-// @codingStandardsIgnoreFile
-
 namespace Magento\Framework\View\Test\Unit\Asset;
 
-use \Magento\Framework\View\Asset\Repository;
+use Magento\Framework\View\Asset\Repository;
 
+/**
+ * Unit test for Magento\Framework\View\Asset\Repository
+ */
 class RepositoryTest extends \PHPUnit_Framework_TestCase
 {
+    /**
+     * @var \Magento\Framework\View\Asset\Repository
+     */
+    private $repository;
+
     /**
      * @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject
      */
-    private $baseUrl;
+    private $urlMock;
 
     /**
      * @var \Magento\Framework\View\DesignInterface|\PHPUnit_Framework_MockObject_MockObject
      */
-    private $design;
+    private $designMock;
 
     /**
      * @var \Magento\Framework\View\Design\Theme\ListInterface|\PHPUnit_Framework_MockObject_MockObject
      */
-    private $themeList;
+    private $listMock;
 
     /**
      * @var \Magento\Framework\View\Asset\Source|\PHPUnit_Framework_MockObject_MockObject
      */
-    private $source;
+    private $sourceMock;
 
     /**
-     * @var \Magento\Framework\View\Design\ThemeInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject
      */
-    private $theme;
+    private $httpMock;
 
     /**
-     * @var Repository
+     * @var \Magento\Framework\View\Asset\FileFactory|\PHPUnit_Framework_MockObject_MockObject
      */
-    private $object;
+    private $fileFactoryMock;
 
     /**
-     * @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\View\Asset\File\FallbackContextFactory|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $requestMock;
+    private $fallbackFactoryMock;
 
+    /**
+     * @var \Magento\Framework\View\Asset\File\ContextFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $contextFactoryMock;
+
+    /**
+     * @var \Magento\Framework\View\Asset\RemoteFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $remoteFactoryMock;
+
+    /**
+     * {@inheritDoc}
+     */
     protected function setUp()
     {
-        $this->themeList = $this->getMockForAbstractClass('\Magento\Framework\View\Design\Theme\ListInterface');
-        $this->source = $this->getMock(
-            'Magento\Framework\View\Asset\Source',
-            ['getFile', 'getContent'],
-            [],
-            '',
-            false
-        );
-        $this->baseUrl = $this->getMockForAbstractClass('Magento\Framework\UrlInterface');
-        $this->design = $this->getMockForAbstractClass('Magento\Framework\View\DesignInterface');
-        $this->theme = $this->getMockForAbstractClass('Magento\Framework\View\Design\ThemeInterface');
-        $this->requestMock = $this->getMockBuilder('Magento\Framework\App\Request\Http')
+        $this->urlMock = $this->getMockBuilder('Magento\Framework\UrlInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->designMock = $this->getMockBuilder('Magento\Framework\View\DesignInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->listMock = $this->getMockBuilder('Magento\Framework\View\Design\Theme\ListInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->sourceMock = $this->getMockBuilder('Magento\Framework\View\Asset\Source')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->httpMock = $this->getMockBuilder('Magento\Framework\App\Request\Http')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->fileFactoryMock = $this->getMockBuilder('Magento\Framework\View\Asset\FileFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->fallbackFactoryMock = $this->getMockBuilder('Magento\Framework\View\Asset\File\FallbackContextFactory')
+            ->setMethods(['create'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->contextFactoryMock = $this->getMockBuilder('Magento\Framework\View\Asset\File\ContextFactory')
+            ->setMethods(['create'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->remoteFactoryMock = $this->getMockBuilder('Magento\Framework\View\Asset\RemoteFactory')
+            ->setMethods(['create'])
             ->disableOriginalConstructor()
             ->getMock();
-        $this->object = new Repository(
-            $this->baseUrl,
-            $this->design,
-            $this->themeList,
-            $this->source,
-            $this->requestMock
+
+        $this->repository = new Repository(
+            $this->urlMock,
+            $this->designMock,
+            $this->listMock,
+            $this->sourceMock,
+            $this->httpMock,
+            $this->fileFactoryMock,
+            $this->fallbackFactoryMock,
+            $this->contextFactoryMock,
+            $this->remoteFactoryMock
         );
     }
 
     /**
      * @expectedException \UnexpectedValueException
      * @expectedExceptionMessage Could not find theme 'nonexistent_theme' for area 'area'
+     * @return void
      */
     public function testUpdateDesignParamsWrongTheme()
     {
         $params = ['area' => 'area', 'theme' => 'nonexistent_theme'];
-        $this->themeList->expects($this->once())
+        $this->listMock->expects($this->once())
             ->method('getThemeByFullPath')
             ->with('area/nonexistent_theme')
             ->will($this->returnValue(null));
-        $this->object->updateDesignParams($params);
-    }
-
-    public function testCreateAsset()
-    {
-        $this->mockDesign();
-        $this->baseUrl->expects($this->once())
-            ->method('getBaseUrl')
-            ->will($this->returnValue('http://example.com/static/'));
-        $asset = $this->object->createAsset('test/file.js');
-        $this->assertInstanceOf('\Magento\Framework\View\Asset\File', $asset);
-        $this->assertEquals('area/theme/locale/test/file.js', $asset->getPath());
-        $this->assertEquals('test/file.js', $asset->getFilePath());
-        $this->assertEquals('js', $asset->getContentType());
-        $this->assertInstanceOf('\Magento\Framework\View\Asset\File\FallbackContext', $asset->getContext());
-        $this->assertEquals('', $asset->getModule());
-        $this->assertEquals('http://example.com/static/area/theme/locale/test/file.js', $asset->getUrl());
-
-        $this->source->expects($this->once())->method('getFile')->with($asset)->will($this->returnValue('source'));
-        $this->source->expects($this->once())->method('getContent')->with($asset)->will($this->returnValue('content'));
-        $this->assertEquals('source', $asset->getSourceFile());
-        $this->assertEquals('content', $asset->getContent());
-
-        $anotherAsset = $this->object->createAsset('another/file.id');
-        $this->assertSame($anotherAsset->getContext(), $asset->getContext());
-    }
-
-    public function testCreateAssetModular()
-    {
-        $this->mockDesign();
-        $asset = $this->object->createAsset('Module_Name::test/file.js');
-        $this->assertEquals('Module_Name', $asset->getModule());
-        $this->assertEquals('test/file.js', $asset->getFilePath());
-    }
-
-    public function testGetStaticViewFileContext()
-    {
-        $this->mockDesign();
-        $context = $this->object->getStaticViewFileContext();
-        $this->assertInstanceOf('\Magento\Framework\View\Asset\ContextInterface', $context);
-        $this->assertSame($context, $this->object->getStaticViewFileContext()); // to ensure in-memory caching
-        $asset = $this->object->createAsset('test/file.js');
-        $this->assertSame($context, $asset->getContext()); // and once again to ensure in-memory caching for real
+        $this->repository->updateDesignParams($params);
     }
 
     /**
-     * @param string $fileId
-     * @param string $similarToModule
-     * @param string $expectedPath
-     * @param string $expectedType
-     * @param string $expectedModule
-     * @dataProvider createSimilarDataProvider
+     * @param array $params
+     * @param array $result
+     * @return void
+     * @dataProvider updateDesignParamsDataProvider
      */
-    public function testCreateSimilar($fileId, $similarToModule, $expectedPath, $expectedType, $expectedModule)
+    public function testUpdateDesignParams($params, $result)
     {
-        $similarTo = $this->getMockForAbstractClass('\Magento\Framework\View\Asset\LocalInterface');
-        $context = $this->getMockForAbstractClass('\Magento\Framework\View\Asset\ContextInterface');
-        $similarTo->expects($this->once())->method('getContext')->will($this->returnValue($context));
-        $similarTo->expects($this->any())->method('getModule')->will($this->returnValue($similarToModule));
-        $asset = $this->object->createSimilar($fileId, $similarTo);
-        $this->assertInstanceOf('\Magento\Framework\View\Asset\File', $asset);
-        $this->assertSame($context, $asset->getContext());
-        $this->assertEquals($expectedPath, $asset->getFilePath());
-        $this->assertEquals($expectedType, $asset->getContentType());
-        $this->assertEquals($expectedModule, $asset->getModule());
+        $this->listMock
+            ->expects($this->any())
+            ->method('getThemeByFullPath')
+            ->willReturn('ThemeID');
+
+        $this->repository->updateDesignParams($params);
+        $this->assertEquals($result, $params);
     }
 
     /**
      * @return array
      */
-    public function createSimilarDataProvider()
+    public function updateDesignParamsDataProvider()
     {
         return [
-            ['test/file.css', '', 'test/file.css', 'css', ''],
-            ['test/file.js', '', 'test/file.js', 'js', ''],
-            ['test/file.css', 'Module_Name', 'test/file.css', 'css', 'Module_Name'],
-            ['Module_Name::test/file.css', 'Module_Two', 'test/file.css', 'css', 'Module_Name'],
+            [
+                ['area' => 'AREA'],
+                ['area' => 'AREA', 'themeModel' => '', 'module' => '', 'locale' => '']],
+            [
+                ['themeId' => 'ThemeID'],
+                ['area' => '', 'themeId' => 'ThemeID', 'themeModel' => 'ThemeID', 'module' => '', 'locale' => '']
+            ]
         ];
     }
 
     /**
-     * @param string $filePath
-     * @param string $dirPath
-     * @param string $baseUrlType
-     * @param string $expectedType
-     * @param string $expectedUrl
-     * @dataProvider createArbitraryDataProvider
+     * @return void
      */
-    public function testCreateArbitrary($filePath, $dirPath, $baseUrlType, $expectedType, $expectedUrl)
+    public function testCreateAsset()
     {
-        $this->baseUrl->expects($this->once())
-            ->method('getBaseUrl')
-            ->will($this->returnValueMap([
-                [['_type' => 'static'], 'http://example.com/static/'],
-                [['_type' => 'media'], 'http://example.com/media/'],
-            ]));
-        $dirType = 'dirType';
-        $asset = $this->object->createArbitrary($filePath, $dirPath, $dirType, $baseUrlType);
-        $this->assertInstanceOf('\Magento\Framework\View\Asset\File', $asset);
-        $this->assertEquals($expectedType, $asset->getContentType());
-        $this->assertEquals($expectedUrl, $asset->getUrl());
-        $this->assertEquals($dirType, $asset->getContext()->getBaseDirType());
-
-        $anotherAsset = $this->object->createArbitrary('another/path.js', $dirPath, $dirType, $baseUrlType);
-        $this->assertSame($anotherAsset->getContext(), $asset->getContext());
+        $this->listMock
+            ->expects($this->any())
+            ->method('getThemeByFullPath')
+            ->willReturnArgument(0);
+
+        $fallbackContextMock = $this->getMockBuilder('Magento\Framework\View\Asset\File\FallbackContex')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->fallbackFactoryMock
+            ->expects($this->once())
+            ->method('create')
+            ->with(
+                [
+                    'baseUrl' => '',
+                    'areaType' => '',
+                    'themePath' => 'Default',
+                    'localeCode' => '',
+                    'isSecure' => '',
+                ]
+            )
+            ->willReturn($fallbackContextMock);
+
+        $assetMock = $this->getMockBuilder('Magento\Framework\View\Asset\File')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->fileFactoryMock
+            ->expects($this->once())
+            ->method('create')
+            ->with(
+                [
+                    'source' => $this->sourceMock,
+                    'context' => $fallbackContextMock,
+                    'filePath' => 'test/file.js',
+                    'module' => 'Test',
+                    'contentType' => ''
+                ]
+            )
+            ->willReturn($assetMock);
+
+        $this->assertEquals(
+            $assetMock,
+            $this->repository->createAsset('test/file.js', ['module' => 'Test', 'theme' => 'Default'])
+        );
     }
 
     /**
-     * @return array
+     * @return void
      */
-    public function createArbitraryDataProvider()
+    public function testGetStaticViewFileContext()
     {
-        return [
-            ['test/example.js', 'dir/path', 'static', 'js', 'http://example.com/static/dir/path/test/example.js'],
-            ['test/example.css', '', 'media', 'css', 'http://example.com/media/test/example.css'],
-            ['img/logo.gif', 'uploaded', 'media', 'gif', 'http://example.com/media/uploaded/img/logo.gif'],
-        ];
+        $themeMock = $this->getMock('Magento\Framework\View\Design\ThemeInterface', [], [], '', false);
+        $this->designMock
+            ->expects($this->any())
+            ->method('getDesignParams')
+            ->willReturn(
+                [
+                    'themeModel' => $themeMock,
+                    'area' => 'area',
+                    'locale' => 'locale'
+                ]
+            );
+        $this->listMock
+            ->expects($this->any())
+            ->method('getThemeByFullPath')
+            ->willReturnArgument(0);
+        $this->httpMock
+            ->expects($this->any())
+            ->method('isSecure')
+            ->willReturn(false);
+
+        $fallbackContextMock = $this->getMockBuilder('Magento\Framework\View\Asset\File\FallbackContex')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->fallbackFactoryMock
+            ->expects($this->once())
+            ->method('create')
+            ->with(
+                [
+                    'baseUrl' => '',
+                    'areaType' => 'area',
+                    'themePath' => '',
+                    'localeCode' => 'locale',
+                    'isSecure' => '',
+                ]
+            )
+            ->willReturn($fallbackContextMock);
+
+        $this->assertEquals(
+            $fallbackContextMock,
+            $this->repository->getStaticViewFileContext()
+        );
     }
 
     /**
-     * @param string $fileId
-     * @param string $relFilePath
-     * @param string $relModule
-     * @param string $expFilePath
-     * @param string $expType
-     * @param string $expModule
+     * @param string $filePath
+     * @param string $resultFilePath
+     * @param string $module
+     * @return void
      * @dataProvider createRelatedDataProvider
      */
-    public function testCreateRelated($fileId, $relFilePath, $relModule, $expFilePath, $expType, $expModule)
+    public function testCreateRelated($filePath, $resultFilePath, $module)
     {
-        $relativeTo = $this->getMockForAbstractClass('\Magento\Framework\View\Asset\LocalInterface');
-        $context = $this->getMockForAbstractClass('\Magento\Framework\View\Asset\ContextInterface');
-        $relativeTo->expects($this->once())->method('getContext')->will($this->returnValue($context));
-        $relativeTo->expects($this->any())->method('getModule')->will($this->returnValue($relModule));
-        $relativeTo->expects($this->any())->method('getFilePath')->will($this->returnValue($relFilePath));
-        $asset = $this->object->createRelated($fileId, $relativeTo);
-        $this->assertInstanceOf('\Magento\Framework\View\Asset\File', $asset);
-        $this->assertSame($context, $asset->getContext());
-        $this->assertEquals($expFilePath, $asset->getFilePath());
-        $this->assertEquals($expType, $asset->getContentType());
-        $this->assertEquals($expModule, $asset->getModule());
+        $originalContextMock = $this->getMockBuilder('Magento\Framework\View\Asset\ContextInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $originalAssetMock = $this->getMockBuilder('Magento\Framework\View\Asset\File')
+            ->disableOriginalConstructor()
+            ->setMethods(['getModule', 'getContext'])
+            ->getMock();
+        $originalAssetMock
+            ->expects($this->any())
+            ->method('getContext')
+            ->willReturn($originalContextMock);
+
+        $assetMock = $this->getMockBuilder('Magento\Framework\View\Asset\File')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->fileFactoryMock
+            ->expects($this->once())
+            ->method('create')
+            ->with(
+                [
+                    'source' => $this->sourceMock,
+                    'context' => $originalContextMock,
+                    'filePath' => $resultFilePath,
+                    'module' => $module,
+                    'contentType' => ''
+                ]
+            )
+            ->willReturn($assetMock);
+
+        $this->assertEquals(
+            $assetMock,
+            $this->repository->createRelated($filePath, $originalAssetMock)
+        );
     }
 
     /**
@@ -232,98 +311,119 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
     public function createRelatedDataProvider()
     {
         return [
-            ['test/file.ext', 'rel/file.ext2', '', 'rel/test/file.ext', 'ext', ''],
-            ['test/file.ext', 'rel/file.ext2', 'Module_Name', 'rel/test/file.ext', 'ext', 'Module_Name'],
-            ['Module_One::test/file.ext', 'rel/file.ext2', 'Module_Two', 'test/file.ext', 'ext', 'Module_One'],
-            ['Module_Name::test/file.ext', '', '', 'test/file.ext', 'ext', 'Module_Name'],
+            ['test/file.js', '/test/file.js', ''],
+            ['test::file.js', 'file.js', 'test'],
         ];
     }
 
-    public function testCreateRemoteAsset()
+    /**
+     * @return void
+     */
+    public function testCreateArbitrary()
     {
-        $asset = $this->object->createRemoteAsset('url', 'type');
-        $this->assertInstanceOf('\Magento\Framework\View\Asset\Remote', $asset);
-        $this->assertEquals('url', $asset->getUrl());
-        $this->assertEquals('type', $asset->getContentType());
-    }
+        $contextMock = $this->getMockBuilder('Magento\Framework\View\Asset\ContextInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->contextFactoryMock
+            ->expects($this->once())
+            ->method('create')
+            ->with(
+                [
+                    'baseUrl' => '',
+                    'baseDirType' => 'dirType',
+                    'contextPath' => 'dir/path'
+                ]
+            )
+            ->willReturn($contextMock);
+
+        $assetMock = $this->getMockBuilder('Magento\Framework\View\Asset\File')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->fileFactoryMock
+            ->expects($this->once())
+            ->method('create')
+            ->with(
+                [
+                    'source' => $this->sourceMock,
+                    'context' => $contextMock,
+                    'filePath' => 'test/file.js',
+                    'module' => '',
+                    'contentType' => ''
+                ]
+            )
+            ->willReturn($assetMock);
 
-    public function testGetUrl()
-    {
-        $this->mockDesign();
-        $this->baseUrl->expects($this->once())
-            ->method('getBaseUrl')
-            ->will($this->returnValue('http://example.com/static/'));
-        $result = $this->object->getUrl('Module_Name::img/product/placeholder.png');
         $this->assertEquals(
-            'http://example.com/static/area/theme/locale/Module_Name/img/product/placeholder.png',
-            $result
+            $assetMock,
+            $this->repository->createArbitrary('test/file.js', 'dir/path', 'dirType', 'static')
         );
     }
 
-    public function testGetUrlWithParams()
+    /**
+     * @return void
+     */
+    public function testCreateRemoteAsset()
     {
-        $defaultTheme = $this->getMockForAbstractClass('Magento\Framework\View\Design\ThemeInterface');
-        $defaults = [
-            'area' => 'area',
-            'themeModel' => $defaultTheme,
-            'locale' => 'locale',
-        ];
-        $this->design->expects($this->atLeastOnce())->method('getDesignParams')->will($this->returnValue($defaults));
-        $this->design->expects($this->once())
-            ->method('getConfigurationDesignTheme')
-            ->with('custom_area')
-            ->will($this->returnValue(false));
-        $this->design->expects($this->any())
-            ->method('getThemePath')
-            ->with($this->theme)
-            ->will($this->returnValue('custom_theme'));
-        $this->baseUrl->expects($this->once())
-            ->method('getBaseUrl')
-            ->will($this->returnValue('http://example.com/static/'));
-        $params = [
-            'area' => 'custom_area',
-            'locale' => 'en_US',
-            'module' => 'This_Shall_Not_Be_Used',
-        ];
-        $result = $this->object->getUrlWithParams('Module_Name::file.ext', $params);
-        $this->assertEquals('http://example.com/static/custom_area/custom_theme/en_US/Module_Name/file.ext', $result);
     }
 
-    private function mockDesign()
+    /**
+     * @return void
+     */
+    public function testGetUrl()
     {
-        $params = [
-            'area'       => 'area',
-            'themeModel' => $this->theme,
-            'locale'     => 'locale',
-        ];
-        $this->design->expects($this->atLeastOnce())->method('getDesignParams')->will($this->returnValue($params));
-        $this->design->expects($this->any())
-            ->method('getConfigurationDesignTheme')
-            ->with('area')
-            ->will($this->returnValue($this->theme));
-        $this->design->expects($this->any())
-            ->method('getThemePath')
-            ->with($this->theme)
-            ->will($this->returnValue('theme'));
-        $this->themeList->expects($this->any())->method('getThemeByFullPath')->will($this->returnValue($this->theme));
+        $themeMock = $this->getMock('Magento\Framework\View\Design\ThemeInterface', [], [], '', false);
+        $this->designMock
+            ->expects($this->any())
+            ->method('getDesignParams')
+            ->willReturn(
+                [
+                    'themeModel' => $themeMock,
+                    'area' => 'area',
+                    'locale' => 'locale'
+                ]
+            );
+
+        $assetMock = $this->getMockBuilder('Magento\Framework\View\Asset\File')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $assetMock
+            ->expects($this->any())
+            ->method('getUrl')
+            ->willReturn('some url');
+
+        $this->fileFactoryMock
+            ->expects($this->exactly(2))
+            ->method('create')
+            ->with(
+                [
+                    'source' => $this->sourceMock,
+                    'context' => '',
+                    'filePath' => 'test/file.js',
+                    'module' => '',
+                    'contentType' => ''
+                ]
+            )
+            ->willReturn($assetMock);
+
+        $this->assertEquals(
+            'some url',
+            $this->repository->getUrl('test/file.js')
+        );
+        $this->assertEquals(
+            'some url',
+            $this->repository->getUrlWithParams('test/file.js', [])
+        );
     }
 
     /**
      * @expectedException \Magento\Framework\Exception\LocalizedException
      * @expectedExceptionMessage Scope separator "::" cannot be used without scope identifier.
+     * @return void
      */
     public function testExtractModuleException()
     {
-        Repository::extractModule('::no_scope.ext');
-    }
-
-    public function testExtractModule()
-    {
-        $this->assertEquals(['Module_One', 'File'], Repository::extractModule('Module_One::File'));
-        $this->assertEquals(['', 'File'], Repository::extractModule('File'));
-        $this->assertEquals(
-            ['Module_One', 'File::SomethingElse'],
-            Repository::extractModule('Module_One::File::SomethingElse')
-        );
+        $this->repository->extractModule('::asdsad');
     }
-} 
+}
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Asset/SourceTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Asset/SourceTest.php
index 4db38ebb9c55a2e78dd179a4e8ff94d25b3c1620..6901f2d06062e08ca7ab1cea51cbd9caa6b8a00c 100644
--- a/lib/internal/Magento/Framework/View/Test/Unit/Asset/SourceTest.php
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Asset/SourceTest.php
@@ -39,11 +39,6 @@ class SourceTest extends \PHPUnit_Framework_TestCase
      */
     private $staticDirRead;
 
-    /**
-     * @var \Magento\Framework\View\Asset\PreProcessor\Cache|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $cache;
-
     /**
      * @var \Magento\Framework\View\Asset\PreProcessor\Pool|\PHPUnit_Framework_MockObject_MockObject
      */
@@ -76,9 +71,6 @@ class SourceTest extends \PHPUnit_Framework_TestCase
 
     protected function setUp()
     {
-        $this->cache = $this->getMock(
-            'Magento\Framework\View\Asset\PreProcessor\Cache', [], [], '', false
-        );
         $this->preProcessorPool = $this->getMock(
             'Magento\Framework\View\Asset\PreProcessor\Pool', [], [], '', false
         );
@@ -107,39 +99,10 @@ class SourceTest extends \PHPUnit_Framework_TestCase
         $this->initFilesystem();
 
         $this->object = new Source(
-            $this->cache,
-            $this->filesystem,
-            $this->preProcessorPool,
-            $this->viewFileResolution,
-            $themeList,
-            $this->chainFactory
+            $this->filesystem, $this->preProcessorPool, $this->viewFileResolution, $themeList, $this->chainFactory
         );
     }
 
-    public function testGetFileCached()
-    {
-        $root = '/root/some/file.ext';
-        $expected = '/var/some/file.ext';
-        $filePath = 'some/file.ext';
-        $this->viewFileResolution->expects($this->once())
-            ->method('getFile')
-            ->with('frontend', $this->theme, 'en_US', $filePath, 'Magento_Module')
-            ->will($this->returnValue($root));
-        $this->rootDirRead->expects($this->once())
-            ->method('getRelativePath')
-            ->with($root)
-            ->will($this->returnValue($filePath));
-        $this->cache->expects($this->once())
-            ->method('load')
-            ->with("some/file.ext:{$filePath}")
-            ->will($this->returnValue(serialize([DirectoryList::VAR_DIR, $filePath])));
-
-        $this->varDir->expects($this->once())->method('getAbsolutePath')
-            ->with($filePath)
-            ->will($this->returnValue($expected));
-        $this->assertSame($expected, $this->object->getFile($this->getAsset()));
-    }
-
     /**
      * @param $origFile
      * @param $origPath
@@ -151,7 +114,6 @@ class SourceTest extends \PHPUnit_Framework_TestCase
     public function testGetFile($origFile, $origPath, $origContent, $isMaterialization)
     {
         $filePath = 'some/file.ext';
-        $cacheValue = "{$origPath}:{$filePath}";
         $this->viewFileResolution->expects($this->once())
             ->method('getFile')
             ->with('frontend', $this->theme, 'en_US', $filePath, 'Magento_Module')
@@ -160,9 +122,6 @@ class SourceTest extends \PHPUnit_Framework_TestCase
             ->method('getRelativePath')
             ->with($origFile)
             ->will($this->returnValue($origPath));
-        $this->cache->expects($this->once())
-            ->method('load')
-            ->will($this->returnValue(false));
         $this->rootDirRead->expects($this->once())
             ->method('readFile')
             ->with($origPath)
@@ -186,20 +145,11 @@ class SourceTest extends \PHPUnit_Framework_TestCase
             $this->varDir->expects($this->once())
                 ->method('writeFile')
                 ->with('view_preprocessed/source/some/file.ext', 'processed');
-            $this->cache->expects($this->once())
-                ->method('save')
-                ->with(
-                    serialize([DirectoryList::VAR_DIR, 'view_preprocessed/source/some/file.ext']),
-                    $cacheValue
-                );
             $this->varDir->expects($this->once())
                 ->method('getAbsolutePath')
                 ->with('view_preprocessed/source/some/file.ext')->will($this->returnValue('result'));
         } else {
             $this->varDir->expects($this->never())->method('writeFile');
-            $this->cache->expects($this->once())
-                ->method('save')
-                ->with(serialize([DirectoryList::ROOT, 'source/some/file.ext']), $cacheValue);
             $this->rootDirRead->expects($this->once())
                 ->method('getAbsolutePath')
                 ->with('source/some/file.ext')
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Design/FileResolution/Fallback/CacheData/FlatTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Design/FileResolution/Fallback/CacheData/FlatTest.php
deleted file mode 100644
index f3d577e22c89e7873c1d05883a92640c7224362d..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Test/Unit/Design/FileResolution/Fallback/CacheData/FlatTest.php
+++ /dev/null
@@ -1,136 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-// @codingStandardsIgnoreFile
-
-namespace Magento\Framework\View\Test\Unit\Design\FileResolution\Fallback\CacheData;
-
-use \Magento\Framework\View\Design\FileResolution\Fallback\CacheData\Flat;
-
-class FlatTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Framework\View\Design\FileResolution\Fallback\Cache|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $cache;
-
-    /**
-     * @var \Magento\Framework\View\Design\ThemeInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $theme;
-
-    /**
-     * @var Flat
-     */
-    private $object;
-
-    protected function setUp()
-    {
-        $this->cache = $this->getMock(
-            '\Magento\Framework\View\Design\FileResolution\Fallback\Cache', [], [], '', false
-        );
-
-        $this->theme = $this->getMockForAbstractClass('\Magento\Framework\View\Design\ThemeInterface');
-
-        $this->object = new \Magento\Framework\View\Design\FileResolution\Fallback\CacheData\Flat($this->cache);
-    }
-
-    /**
-     * @param string $area
-     * @param string $themePath
-     * @param string $locale
-     * @param string $module
-     * @param string $expectedId
-     * @param string $expectedValue
-     *
-     * @dataProvider cacheDataProvider
-     */
-    public function testGetFromCache($area, $themePath, $locale, $module, $expectedId, $expectedValue)
-    {
-        if (isset($params['theme'])) {
-            $this->theme->expects($this->any())
-                ->method('getThemePath')
-                ->will($this->returnValue($params['theme']));
-            $params['theme'] = $this->theme;
-        } else {
-            $this->theme->expects($this->never())
-                ->method('getThemePath');
-        }
-
-        $this->cache->expects($this->once())
-            ->method('load')
-            ->with($expectedId)
-            ->will($this->returnValue($expectedValue));
-
-        $actual = $this->object->getFromCache('file', 'file.ext', $area, $themePath, $locale, $module);
-        $this->assertSame($expectedValue, $actual);
-    }
-
-    /**
-     * @param string $area
-     * @param string $themePath
-     * @param string $locale
-     * @param string $module
-     * @param string $expectedId
-     * @param string $savedValue
-     *
-     * @dataProvider cacheDataProvider
-     */
-    public function testSaveToCache($area, $themePath, $locale, $module, $expectedId, $savedValue)
-    {
-        if (isset($params['theme'])) {
-            $this->theme->expects($this->any())
-                ->method('getThemePath')
-                ->will($this->returnValue($params['theme']));
-            $params['theme'] = $this->theme;
-        } else {
-            $this->theme->expects($this->never())
-                ->method('getThemePath');
-        }
-
-        $this->cache->expects($this->once())
-            ->method('save')
-            ->with($savedValue, $expectedId)
-            ->will($this->returnValue(true));
-
-        $actual = $this->object->saveToCache($savedValue, 'file', 'file.ext', $area, $themePath, $locale, $module);
-        $this->assertTrue($actual);
-    }
-
-    /**
-     * @return array
-     */
-    public function cacheDataProvider()
-    {
-        return [
-            'all params' => [
-                'frontend', 'magento_theme', 'en_US', 'Magento_Module',
-                'type:file|area:frontend|theme:magento_theme|locale:en_US|module:Magento_Module|file:file.ext',
-                'one/file.ext',
-            ],
-            'no area' => [
-                null, 'magento_theme', 'en_US', 'Magento_Module',
-                'type:file|area:|theme:magento_theme|locale:en_US|module:Magento_Module|file:file.ext',
-                'two/file.ext',
-            ],
-            'no theme' => [
-                'frontend', null, 'en_US', 'Magento_Module',
-                'type:file|area:frontend|theme:|locale:en_US|module:Magento_Module|file:file.ext',
-                'three/file.ext',
-            ],
-            'no locale' => [
-                'frontend', 'magento_theme', null, 'Magento_Module',
-                'type:file|area:frontend|theme:magento_theme|locale:|module:Magento_Module|file:file.ext',
-                'four/file.ext',
-            ],
-            'no module' => [
-                'frontend', 'magento_theme', 'en_US', null,
-                'type:file|area:frontend|theme:magento_theme|locale:en_US|module:|file:file.ext',
-                'five/file.ext',
-            ],
-        ];
-    }
-}
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Design/FileResolution/Fallback/CacheData/GroupedTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Design/FileResolution/Fallback/CacheData/GroupedTest.php
deleted file mode 100644
index e233a9b0e3abf56c79492495997140a4439ffa5b..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/View/Test/Unit/Design/FileResolution/Fallback/CacheData/GroupedTest.php
+++ /dev/null
@@ -1,200 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-// @codingStandardsIgnoreFile
-
-namespace Magento\Framework\View\Test\Unit\Design\FileResolution\Fallback\CacheData;
-
-use \Magento\Framework\View\Design\FileResolution\Fallback\CacheData\Grouped;
-
-class GroupedTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Framework\View\Design\FileResolution\Fallback\Cache|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $cache;
-
-    /**
-     * @var \Magento\Framework\View\Design\ThemeInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    private $theme;
-
-    /**
-     * @var Grouped
-     */
-    private $object;
-
-    protected function setUp()
-    {
-        $this->cache = $this->getMock(
-            '\Magento\Framework\View\Design\FileResolution\Fallback\Cache', [], [], '', false
-        );
-
-        $this->theme = $this->getMockForAbstractClass('\Magento\Framework\View\Design\ThemeInterface');
-
-        $this->object = new \Magento\Framework\View\Design\FileResolution\Fallback\CacheData\Grouped($this->cache);
-    }
-
-    /**
-     * @param string $area
-     * @param string $themePath
-     * @param string $locale
-     * @param string $module
-     * @param array $files
-     *
-     * @dataProvider getFromCacheDataProvider
-     */
-    public function testGetFromCache($area, $themePath, $locale, $module, array $files)
-    {
-        if (isset($params['theme'])) {
-            $this->theme->expects($this->any())
-                ->method('getThemePath')
-                ->will($this->returnValue($params['theme']));
-            $params['theme'] = $this->theme;
-        } else {
-            $this->theme->expects($this->never())
-                ->method('getThemePath');
-        }
-
-        $cachedSections = [
-            'type:file|area:frontend|theme:magento_theme|locale:en_US' => [
-                'module:Magento_Module|file:file.ext' => 'one/file.ext',
-                'module:Magento_Module|file:other_file.ext' => 'one/other_file.ext',
-                'module:|file:file.ext' => 'two/file.ext',
-                'module:|file:other_file.ext' => 'two/other_file.ext',
-            ],
-            'type:file|area:frontend|theme:magento_theme|locale:' => [
-                'module:Magento_Module|file:file.ext' => 'three/file.ext',
-                'module:Magento_Module|file:other_file.ext' => 'four/other_file.ext',
-            ],
-            'type:file|area:frontend|theme:|locale:en_US' => [
-                'module:Magento_Module|file:file.ext' => 'five/file.ext',
-                'module:Magento_Module|file:other_file.ext' => 'five/other_file.ext',
-            ],
-            'type:file|area:|theme:magento_theme|locale:en_US' => [
-                'module:Magento_Module|file:file.ext' => 'seven/file.ext',
-                'module:Magento_Module|file:other_file.ext' => 'other_file.ext',
-            ],
-        ];
-
-        $this->cache->expects($this->once())
-            ->method('load')
-            ->will($this->returnCallback(function ($sectionId) use ($cachedSections) {
-                if (!isset($cachedSections[$sectionId])) {
-                    return false;
-                }
-                return json_encode($cachedSections[$sectionId]);
-            }));
-
-        foreach ($files as $requested => $expected) {
-            $actual = $this->object->getFromCache('file', $requested, $area, $themePath, $locale, $module);
-            $this->assertSame($expected, $actual);
-        }
-    }
-
-    /**
-     * @return array
-     */
-    public function getFromCacheDataProvider()
-    {
-        return [
-            'all params' => [
-                'frontend', 'magento_theme', 'en_US', 'Magento_Module',
-                ['file.ext' => 'one/file.ext', 'other_file.ext' => 'one/other_file.ext'],
-            ],
-            'no area' => [
-                null, 'magento_theme', 'en_US', 'Magento_Module',
-                ['file.ext' => 'seven/file.ext', 'other_file.ext' => 'other_file.ext'],
-            ],
-            'no theme' => [
-                'frontend', null, 'en_US', 'Magento_Module',
-                ['file.ext' => 'five/file.ext', 'other_file.ext' => 'five/other_file.ext'],
-            ],
-            'no locale' => [
-                'frontend', 'magento_theme', null, 'Magento_Module',
-                ['file.ext' => 'three/file.ext', 'other_file.ext' => 'four/other_file.ext'],
-            ],
-            'no module' => [
-                'frontend', 'magento_theme', 'en_US', null,
-                ['file.ext' => 'two/file.ext', 'other_file.ext' => 'two/other_file.ext'],
-            ],
-        ];
-    }
-
-    /**
-     * Verify that one and only one attempt to load cache is done even in case of cache absence
-     */
-    public function testGetFromCacheNothing()
-    {
-        $this->cache->expects($this->once())
-            ->method('load');
-        $this->assertFalse($this->object->getFromCache('type', 'file.ext',
-            'frontend', 'magento_theme', 'en_US', 'Magento_Module'));
-        $this->assertFalse($this->object->getFromCache('type', 'file.ext',
-            'frontend', 'magento_theme', 'en_US', 'Magento_Module'));
-    }
-
-    /**
-     * Ensure that cache is saved once and only once per section
-     */
-    public function testSaveToCache()
-    {
-        $this->cache->expects($this->exactly(2))
-            ->method('save')
-            ->will($this->returnValueMap([
-                [
-                    json_encode([
-                        'module:Magento_Module|file:file.ext' => 'some/file.ext',
-                        'module:Magento_Module|file:other_file.ext' => 'some/other_file.ext',
-                    ]),
-                    'type:file|area:frontend|theme:|locale:en_US',
-                    true,
-                ],
-                [
-                    json_encode(['module:Magento_Module|file:file.ext' => 'some/other/file.ext']),
-                    'type:view|area:backend|theme:|locale:en_US',
-                    true,
-                ],
-            ]));
-
-        $this->object->saveToCache('some/file.ext', 'file', 'file.ext',
-            'frontend', 'magento_theme', 'en_US', 'Magento_Module');
-        $this->object->saveToCache('some/other_file.ext', 'file', 'other_file.ext',
-            'frontend', 'magento_theme', 'en_US', 'Magento_Module');
-        $this->object->saveToCache('some/other/file.ext', 'view', 'file.ext',
-            'backend', 'magento_theme', 'en_US', 'Magento_Module');
-
-        $this->object = null;
-    }
-
-    /**
-     * Verify that no attempt to save cache is done, when nothing is updated
-     */
-    public function testSaveToCacheNothing()
-    {
-        $this->cache->expects($this->never())
-            ->method('save');
-        $this->object = null;
-    }
-
-    /**
-     * Ensure that same data is not saved again
-     */
-    public function testSaveToCacheNotDirty()
-    {
-        $this->cache->expects($this->never())
-            ->method('save');
-        $this->cache->expects($this->once())
-            ->method('load')
-            ->with('type:file|area:frontend|theme:magento_theme|locale:en_US')
-            ->will($this->returnValue(json_encode(['module:Magento_Module|file:file.ext' => 'some/file.ext'])));
-
-        $this->object->saveToCache('some/file.ext', 'file', 'file.ext',
-            'frontend', 'magento_theme', 'en_US', 'Magento_Module');
-
-        $this->object = null;
-    }
-}
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Design/FileResolution/Fallback/Resolver/AlternativeTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Design/FileResolution/Fallback/Resolver/AlternativeTest.php
index c7535bcafa118024c052c4bed6cbc5f8e504755a..2dbaa2e6c60668b0c5be4fbfef55d593116f8393 100644
--- a/lib/internal/Magento/Framework/View/Test/Unit/Design/FileResolution/Fallback/Resolver/AlternativeTest.php
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Design/FileResolution/Fallback/Resolver/AlternativeTest.php
@@ -48,13 +48,7 @@ class AlternativeTest extends \PHPUnit_Framework_TestCase
             ->method('getRule')
             ->with('type')
             ->will($this->returnValue($this->rule));
-        $cache = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Design\FileResolution\Fallback\CacheDataInterface'
-        );
-        $cache->expects($this->any())
-            ->method('getFromCache')
-            ->will($this->returnValue(false));
-        $this->object = new Alternative($filesystem, $rulePool, $cache, ['css' => ['less']]);
+        $this->object = new Alternative($filesystem, $rulePool, ['css' => ['less']]);
     }
 
     /**
@@ -69,10 +63,7 @@ class AlternativeTest extends \PHPUnit_Framework_TestCase
 
         $filesystem = $this->getMock('Magento\Framework\Filesystem', [], [], '', false);
         $rulePool = $this->getMock('Magento\Framework\View\Design\Fallback\RulePool', [], [], '', false);
-        $cache = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Design\FileResolution\Fallback\CacheDataInterface'
-        );
-        new Alternative($filesystem, $rulePool, $cache, $alternativeExtensions);
+        new Alternative($filesystem, $rulePool, $alternativeExtensions);
     }
 
     /**
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Design/FileResolution/Fallback/Resolver/MinificationTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Design/FileResolution/Fallback/Resolver/MinificationTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..87368463845b035a39d88e6be8b652523b2989c8
--- /dev/null
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Design/FileResolution/Fallback/Resolver/MinificationTest.php
@@ -0,0 +1,101 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\View\Test\Unit\Design\FileResolution\Fallback\Resolver;
+
+use Magento\Framework\View\Design\FileResolution\Fallback\Resolver\Minification;
+use Magento\Framework\View\Design\FileResolution\Fallback\ResolverInterface;
+
+/**
+ * Unit test for Magento\Framework\View\Design\FileResolution\Fallback\Resolver\Minification
+ */
+class MinificationTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\View\Design\FileResolution\Fallback\Resolver\Minification
+     */
+    protected $minification;
+
+    /**
+     * @var ResolverInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resolverMock;
+
+    /**
+     * @var \Magento\Framework\View\Asset\Minification|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $assetMinificationMock;
+    /**
+     * {@inheritDoc}
+     */
+    protected function setUp()
+    {
+        $this->resolverMock = $this
+            ->getMockBuilder('Magento\Framework\View\Design\FileResolution\Fallback\ResolverInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->assetMinificationMock = $this->getMockBuilder('Magento\Framework\View\Asset\Minification')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->minification = new Minification(
+            $this->resolverMock,
+            $this->assetMinificationMock
+        );
+    }
+
+    /**
+     * @param bool $isEnabled
+     * @param string $requested
+     * @param string $alternative
+     * @param string $expected
+     * @param string $resolvedOriginal
+     * @param string $resolvedAlternative
+     * @return void
+     * @dataProvider resolveDataProvider
+     */
+    public function testResolve(
+        $isEnabled,
+        $requested,
+        $alternative,
+        $expected,
+        $resolvedOriginal,
+        $resolvedAlternative
+    ) {
+        $this->assetMinificationMock
+            ->expects($this->any())
+            ->method('isEnabled')
+            ->willReturnMap([['css', $isEnabled]]);
+        $this->assetMinificationMock
+            ->expects($this->any())
+            ->method('removeMinifiedSign')
+            ->with($requested)
+            ->willReturn($alternative);
+
+        $this->resolverMock
+            ->expects($this->any())
+            ->method('resolve')
+            ->withConsecutive(
+                ['', $requested, null, null, null, null],
+                ['', $alternative, null, null, null, null]
+            )
+            ->willReturnOnConsecutiveCalls($resolvedOriginal, $resolvedAlternative);
+
+        $this->assertEquals($expected, $this->minification->resolve('', $requested));
+    }
+
+    /**
+     * @return array
+     */
+    public function resolveDataProvider()
+    {
+        return [
+            [true, 'file.min.css', 'file.css', 'found.css', false, 'found.css'],
+            [false, 'file.min.css', 'file.min.css', false, false, 'found.css']
+        ];
+    }
+}
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Design/FileResolution/Fallback/Resolver/SimpleTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Design/FileResolution/Fallback/Resolver/SimpleTest.php
index 1c3ce3d36f93f702ae43223409c3a6b77d30c20c..35f55d4d69ae5c184cc7b4cab18d8d414d4482df 100644
--- a/lib/internal/Magento/Framework/View/Test/Unit/Design/FileResolution/Fallback/Resolver/SimpleTest.php
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Design/FileResolution/Fallback/Resolver/SimpleTest.php
@@ -24,11 +24,6 @@ class SimpleTest extends \PHPUnit_Framework_TestCase
      */
     private $rule;
 
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    private $cache;
-
     /**
      * @var \Magento\Framework\View\Design\FileResolution\Fallback\Resolver\Simple
      */
@@ -53,15 +48,11 @@ class SimpleTest extends \PHPUnit_Framework_TestCase
             ->method('getRule')
             ->with('type')
             ->will($this->returnValue($this->rule));
-        $this->cache = $this->getMockForAbstractClass(
-            'Magento\Framework\View\Design\FileResolution\Fallback\CacheDataInterface'
-        );
-        $this->object = new Simple($filesystem, $rulePool, $this->cache);
+
+        $this->object = new Simple($filesystem, $rulePool);
     }
 
     /**
-     * Cache is empty
-     *
      * @param string $area
      * @param string $themePath
      * @param string $locale
@@ -78,10 +69,6 @@ class SimpleTest extends \PHPUnit_Framework_TestCase
             $expectedParams['theme'] = $this->getMockForTheme($expectedParams['theme']);
         }
 
-        $this->cache->expects($this->once())
-            ->method('getFromCache')
-            ->with('type', 'file.ext', $area, $themePath, $locale, $module)
-            ->will($this->returnValue(false));
         $this->directory->expects($this->never())
             ->method('getAbsolutePath');
         $this->rule->expects($this->once())
@@ -92,10 +79,7 @@ class SimpleTest extends \PHPUnit_Framework_TestCase
             ->method('isExist')
             ->with($expectedPath)
             ->will($this->returnValue(true));
-        $this->cache->expects($this->once())
-            ->method('saveToCache')
-            ->with($expectedPath, 'type', 'file.ext', $area, $themePath, $locale, $module);
-        $actualPath = $this->object->resolve(
+       $actualPath = $this->object->resolve(
             'type', 'file.ext', $area, $theme, $locale, $module
         );
         $this->assertSame($expectedPath, $actualPath);
@@ -166,16 +150,10 @@ class SimpleTest extends \PHPUnit_Framework_TestCase
 
     public function testResolveNoPatterns()
     {
-        $this->cache->expects($this->once())
-            ->method('getFromCache')
-            ->with('type', 'file.ext', 'frontend', 'magento_theme', 'en_US', 'Magento_Module')
-            ->will($this->returnValue(false));
         $this->rule->expects($this->once())
             ->method('getPatternDirs')
             ->will($this->returnValue([]));
-        $this->cache->expects($this->once())
-            ->method('saveToCache')
-            ->with('', 'type', 'file.ext', 'frontend', 'magento_theme', 'en_US', 'Magento_Module');
+
         $this->assertFalse(
             $this->object->resolve(
                 'type', 'file.ext', 'frontend', $this->getMockForTheme('magento_theme'), 'en_US', 'Magento_Module'
@@ -185,19 +163,12 @@ class SimpleTest extends \PHPUnit_Framework_TestCase
 
     public function testResolveNonexistentFile()
     {
-        $this->cache->expects($this->once())
-            ->method('getFromCache')
-            ->with('type', 'file.ext', 'frontend', 'magento_theme', 'en_US', 'Magento_Module')
-            ->will($this->returnValue(false));
         $this->rule->expects($this->once())
             ->method('getPatternDirs')
             ->will($this->returnValue(['some/dir']));
         $this->directory->expects($this->once())
             ->method('isExist')
             ->will($this->returnValue(false));
-        $this->cache->expects($this->once())
-            ->method('saveToCache')
-            ->with('', 'type', 'file.ext', 'frontend', 'magento_theme', 'en_US', 'Magento_Module');
         $this->assertFalse(
             $this->object->resolve(
                 'type', 'file.ext', 'frontend', $this->getMockForTheme('magento_theme'), 'en_US', 'Magento_Module'
@@ -205,28 +176,6 @@ class SimpleTest extends \PHPUnit_Framework_TestCase
         );
     }
 
-    public function testResolveFromCache()
-    {
-        $expectedPath = '/some/dir/file.ext';
-
-        $this->cache->expects($this->once())
-            ->method('getFromCache')
-            ->with('type', 'file.ext', 'frontend', 'magento_theme', 'en_US', 'Magento_Module')
-            ->will($this->returnValue($expectedPath));
-        $this->directory->expects($this->once())
-            ->method('getAbsolutePath')
-            ->with($expectedPath)
-            ->will($this->returnValue($expectedPath));
-        $this->rule->expects($this->never())
-            ->method('getPatternDirs');
-        $this->cache->expects($this->never())
-            ->method('saveToCache');
-        $actualPath = $this->object->resolve(
-            'type', 'file.ext', 'frontend', $this->getMockForTheme('magento_theme'), 'en_US', 'Magento_Module'
-        );
-        $this->assertSame($expectedPath, $actualPath);
-    }
-
     /**
      * @param string $themePath
      * @return \Magento\Framework\View\Design\ThemeInterface|\PHPUnit_Framework_MockObject_MockObject
diff --git a/lib/internal/Magento/Framework/View/Test/Unit/Page/Config/RendererTest.php b/lib/internal/Magento/Framework/View/Test/Unit/Page/Config/RendererTest.php
index 2917b75f726441b8b1b9f1e0e643c02ea19f3f12..cd938b2bce90086d33788ac06d609ff8955894f5 100644
--- a/lib/internal/Magento/Framework/View/Test/Unit/Page/Config/RendererTest.php
+++ b/lib/internal/Magento/Framework/View/Test/Unit/Page/Config/RendererTest.php
@@ -28,11 +28,6 @@ class RendererTest extends \PHPUnit_Framework_TestCase
      */
     protected $pageConfigMock;
 
-    /**
-     * @var \Magento\Framework\View\Asset\MinifyService|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $assetMinifyServiceMock;
-
     /**
      * @var \Magento\Framework\View\Asset\AssetInterface|\PHPUnit_Framework_MockObject_MockObject
      */
@@ -84,11 +79,6 @@ class RendererTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
 
-        $this->assetMinifyServiceMock = $this->getMockBuilder('Magento\Framework\View\Asset\MinifyService')
-            ->setMethods(['getAssets'])
-            ->disableOriginalConstructor()
-            ->getMock();
-
         $this->assetMergeServiceMock = $this->getMockBuilder('Magento\Framework\View\Asset\MergeService')
             ->disableOriginalConstructor()
             ->getMock();
@@ -126,7 +116,6 @@ class RendererTest extends \PHPUnit_Framework_TestCase
             'Magento\Framework\View\Page\Config\Renderer',
             [
                 'pageConfig' => $this->pageConfigMock,
-                'assetMinifyService' => $this->assetMinifyServiceMock,
                 'assetMergeService' => $this->assetMergeServiceMock,
                 'urlBuilder' => $this->urlBuilderMock,
                 'escaper' => $this->escaperMock,
@@ -318,10 +307,6 @@ class RendererTest extends \PHPUnit_Framework_TestCase
             ->method('getGroups')
             ->willReturn([$groupMockOne, $groupMockTwo]);
 
-        $this->assetMinifyServiceMock->expects($this->exactly(2))
-            ->method('getAssets')
-            ->willReturnArgument(0);
-
         $this->assetMergeServiceMock->expects($this->exactly(1))
             ->method('getMergedAssets')
             ->willReturnArgument(0);
diff --git a/lib/internal/Magento/Framework/Xml/Security.php b/lib/internal/Magento/Framework/Xml/Security.php
new file mode 100644
index 0000000000000000000000000000000000000000..1fade0a2aec7e0a48389168536a452559f1f0222
--- /dev/null
+++ b/lib/internal/Magento/Framework/Xml/Security.php
@@ -0,0 +1,95 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Xml;
+
+use DOMDocument;
+use Magento\Framework\Phrase;
+
+/**
+ * Class Security
+ */
+class Security
+{
+    /**
+     * Heuristic scan to detect entity in XML
+     *
+     * @param string $xmlContent
+     * @return bool
+     */
+    private function heuristicScan($xmlContent)
+    {
+        return strpos($xmlContent, '<!ENTITY') !== false;
+    }
+
+    /**
+     * Return true if PHP is running with PHP-FPM
+     *
+     * @return bool
+     */
+    private function isPhpFpm()
+    {
+        return substr(php_sapi_name(), 0, 3) === 'fpm';
+    }
+
+    /**
+     * Security check loaded XML document
+     *
+     * @param string $xmlContent
+     * @return bool
+     *
+     * @SuppressWarnings(PHPMD.UnusedLocalVariable)
+     */
+    public function scan($xmlContent)
+    {
+        /**
+         * If running with PHP-FPM we perform an heuristic scan
+         * We cannot use libxml_disable_entity_loader because of this bug
+         * @see https://bugs.php.net/bug.php?id=64938
+         */
+        if ($this->isPhpFpm()) {
+            return $this->heuristicScan($xmlContent);
+        }
+
+        $document = new DOMDocument();
+
+        $loadEntities = libxml_disable_entity_loader(true);
+        $useInternalXmlErrors = libxml_use_internal_errors(true);
+
+        /**
+         * Load XML with network access disabled (LIBXML_NONET)
+         * error disabled with @ for PHP-FPM scenario
+         */
+        set_error_handler(
+            function ($errno, $errstr) {
+                if (substr_count($errstr, 'DOMDocument::loadXML()') > 0) {
+                    return true;
+                }
+                return false;
+            },
+            E_WARNING
+        );
+
+        $result = (bool)$document->loadXml($xmlContent, LIBXML_NONET);
+        restore_error_handler();
+        // Entity load to previous setting
+        libxml_disable_entity_loader($loadEntities);
+        libxml_use_internal_errors($useInternalXmlErrors);
+
+        if (!$result) {
+            return false;
+        }
+
+        foreach ($document->childNodes as $child) {
+            if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
+                if ($child->entities->length > 0) {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+}
diff --git a/lib/internal/Magento/Framework/Xml/Test/Unit/SecurityTest.php b/lib/internal/Magento/Framework/Xml/Test/Unit/SecurityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..afa5c86c1b44e74527614487e8c15cc6a6072cf0
--- /dev/null
+++ b/lib/internal/Magento/Framework/Xml/Test/Unit/SecurityTest.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Xml\Test\Unit;
+
+use Magento\Framework\Xml\Security;
+
+/**
+ * Class SecurityTest
+ *
+ * Test for class \Magento\Framework\Xml\Security
+ */
+class SecurityTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Security
+     */
+    protected $security;
+
+    /**
+     * Set up
+     *
+     * @return void
+     */
+    protected function setUp()
+    {
+        $this->security = new Security();
+    }
+
+    /**
+     * Run test scan method
+     *
+     * @param string $xmlContent
+     * @param bool $expectedResult
+     *
+     * @dataProvider dataProviderTestScan
+     */
+    public function testScan($xmlContent, $expectedResult)
+    {
+        $this->assertEquals($expectedResult, $this->security->scan($xmlContent));
+    }
+
+    /**
+     * Data provider for testScan
+     *
+     * @return array
+     */
+    public function dataProviderTestScan()
+    {
+        return [
+            [
+                'xmlContent' => '<?xml version="1.0"?><test></test>',
+                'expectedResult' => true
+            ],
+            [
+                'xmlContent' => '<!DOCTYPE note SYSTEM "Note.dtd"><?xml version="1.0"?><test></test>',
+                'expectedResult' => false
+            ],
+            [
+                'xmlContent' => '<?xml version="1.0"?>
+            <!DOCTYPE test [
+              <!ENTITY value "value">
+              <!ENTITY value1 "&value;&value;&value;&value;&value;&value;&value;&value;&value;&value;">
+              <!ENTITY value2 "&value1;&value1;&value1;&value1;&value1;&value1;&value1;&value1;&value1;&value1;">
+            ]>
+            <test>&value2;</test>',
+                'expectedResult' => false
+            ],
+            [
+                'xmlContent' => '<!DOCTYPE html><?xml version="1.0"?><test></test>',
+                'expectedResult' => false
+            ],
+            [
+                'xmlContent' => '',
+                'expectedResult' => false
+            ]
+        ];
+    }
+}
diff --git a/lib/web/mage/validation.js b/lib/web/mage/validation.js
index 78cc93607e66e6b1052a2590e28305a118c4253d..98240eb8cfa40797c4efd0e6c222397857ddb7bd 100644
--- a/lib/web/mage/validation.js
+++ b/lib/web/mage/validation.js
@@ -22,16 +22,16 @@
             /**
              * Check if string is empty with trim
              * @param {string} value
-                */
-            isEmpty: function(value) {
-                return (value === ''  || value === undefined || (value == null) || (value.length === 0) || /^\s+$/.test(value));
+             */
+            isEmpty: function (value) {
+                return (value === '' || value === undefined || (value == null) || (value.length === 0) || /^\s+$/.test(value));
             },
 
             /**
              * Check if string is empty no trim
              * @param {string} value
-                */
-            isEmptyNoTrim: function(value) {
+             */
+            isEmptyNoTrim: function (value) {
                 return (value === '' || (value == null) || (value.length === 0));
             },
 
@@ -43,16 +43,16 @@
              * @param {string} to
              * @returns {boolean}
              */
-            isBetween: function(value, from, to){
+            isBetween: function (value, from, to) {
                 return ($.mage.isEmpty(from) || value >= $.mage.parseNumber(from)) &&
-                       ($.mage.isEmpty(to) || value <= $.mage.parseNumber(to));
+                    ($.mage.isEmpty(to) || value <= $.mage.parseNumber(to));
             },
 
             /**
              * Parse price string
              * @param {string} value
-                */
-            parseNumber: function(value) {
+             */
+            parseNumber: function (value) {
                 if (typeof value !== 'string') {
                     return parseFloat(value);
                 }
@@ -75,7 +75,7 @@
              * @param value Value being stripped.
              * @return {*}
              */
-            stripHtml: function(value) {
+            stripHtml: function (value) {
                 return value.replace(/<.[^<>]*?>/g, ' ').replace(/&nbsp;|&#160;/gi, ' ')
                     .replace(/[0-9.(),;:!?%#$'"_+=\/-]*/g, '');
             }
@@ -85,7 +85,7 @@
     $.validator.addMethod = function (name, method, message, dontSkip) {
         $.validator.methods[name] = method;
         $.validator.messages[name] = message !== undefined ? message : $.validator.messages[name];
-        
+
         if (method.length < 3 || dontSkip) {
             $.validator.addClassRules(name, $.validator.normalizeRule(name));
         }
@@ -146,63 +146,63 @@
      */
     var rules = {
         "max-words": [
-            function(value, element, params) {
+            function (value, element, params) {
                 return this.optional(element) || $.mage.stripHtml(value).match(/\b\w+\b/g).length < params;
             },
             'Please enter {0} words or less.'
         ],
         "min-words": [
-            function(value, element, params) {
+            function (value, element, params) {
                 return this.optional(element) || $.mage.stripHtml(value).match(/\b\w+\b/g).length >= params;
             },
             'Please enter at least {0} words.'
         ],
         "range-words": [
-            function(value, element, params) {
+            function (value, element, params) {
                 return this.optional(element) ||
                     $.mage.stripHtml(value).match(/\b\w+\b/g).length >= params[0] &&
-                        value.match(/bw+b/g).length < params[1];
+                    value.match(/bw+b/g).length < params[1];
             },
             'Please enter between {0} and {1} words.'
         ],
         "letters-with-basic-punc": [
-            function(value, element) {
+            function (value, element) {
                 return this.optional(element) || /^[a-z\-.,()'\"\s]+$/i.test(value);
             },
             'Letters or punctuation only please'
         ],
         "alphanumeric": [
-            function(value, element) {
+            function (value, element) {
                 return this.optional(element) || /^\w+$/i.test(value);
             },
             'Letters, numbers, spaces or underscores only please'
         ],
         "letters-only": [
-            function(value, element) {
+            function (value, element) {
                 return this.optional(element) || /^[a-z]+$/i.test(value);
             },
             'Letters only please'
         ],
         "no-whitespace": [
-            function(value, element) {
+            function (value, element) {
                 return this.optional(element) || /^\S+$/i.test(value);
             },
             'No white space please'
         ],
         "zip-range": [
-            function(value, element) {
+            function (value, element) {
                 return this.optional(element) || /^90[2-5]-\d{2}-\d{4}$/.test(value);
             },
             'Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx'
         ],
         "integer": [
-            function(value, element) {
+            function (value, element) {
                 return this.optional(element) || /^-?\d+$/.test(value);
             },
             'A positive or negative non-decimal number please'
         ],
         "vinUS": [
-            function(v) {
+            function (v) {
                 if (v.length !== 17) {
                     return false;
                 }
@@ -245,7 +245,7 @@
             'The specified vehicle identification number (VIN) is invalid.'
         ],
         "dateITA": [
-            function(value, element) {
+            function (value, element) {
                 var check = false;
                 var re = /^\d{1,2}\/\d{1,2}\/\d{4}$/;
                 if (re.test(value)) {
@@ -268,25 +268,25 @@
             'Please enter a correct date'
         ],
         "dateNL": [
-            function(value, element) {
+            function (value, element) {
                 return this.optional(element) || /^\d\d?[\.\/-]\d\d?[\.\/-]\d\d\d?\d?$/.test(value);
             },
             'Vul hier een geldige datum in.'
         ],
         "time": [
-            function(value, element) {
+            function (value, element) {
                 return this.optional(element) || /^([01]\d|2[0-3])(:[0-5]\d){0,2}$/.test(value);
             },
             'Please enter a valid time, between 00:00 and 23:59'
         ],
         "time12h": [
-            function(value, element) {
+            function (value, element) {
                 return this.optional(element) || /^((0?[1-9]|1[012])(:[0-5]\d){0,2}(\ [AP]M))$/i.test(value);
             },
             'Please enter a valid time, between 00:00 am and 12:00 pm'
         ],
         "phoneUS": [
-            function(phone_number, element) {
+            function (phone_number, element) {
                 phone_number = phone_number.replace(/\s+/g, "");
                 return this.optional(element) || phone_number.length > 9 &&
                     phone_number.match(/^(1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/);
@@ -294,39 +294,39 @@
             'Please specify a valid phone number'
         ],
         "phoneUK": [
-            function(phone_number, element) {
+            function (phone_number, element) {
                 return this.optional(element) || phone_number.length > 9 &&
                     phone_number.match(/^(\(?(0|\+44)[1-9]{1}\d{1,4}?\)?\s?\d{3,4}\s?\d{3,4})$/);
             },
             'Please specify a valid phone number'
         ],
         "mobileUK": [
-            function(phone_number, element) {
+            function (phone_number, element) {
                 return this.optional(element) || phone_number.length > 9 &&
                     phone_number.match(/^((0|\+44)7(5|6|7|8|9){1}\d{2}\s?\d{6})$/);
             },
             'Please specify a valid mobile number'
         ],
         "stripped-min-length": [
-            function(value, element, param) {
+            function (value, element, param) {
                 return $(value).text().length >= param;
             },
             'Please enter at least {0} characters'
         ],
         "email2": [
-            function(value, element) {
+            function (value, element) {
                 return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value);
             },
             $.validator.messages.email
         ],
         "url2": [
-            function(value, element) {
+            function (value, element) {
                 return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
             },
             $.validator.messages.url
         ],
         "credit-card-types": [
-            function(value, element, param) {
+            function (value, element, param) {
                 if (/[^0-9-]+/.test(value)) {
                     return false;
                 }
@@ -393,25 +393,25 @@
             'Please enter a valid credit card number.'
         ],
         "ipv4": [
-            function(value, element) {
+            function (value, element) {
                 return this.optional(element) || /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i.test(value);
             },
             'Please enter a valid IP v4 address.'
         ],
         "ipv6": [
-            function(value, element) {
+            function (value, element) {
                 return this.optional(element) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(value);
             },
             'Please enter a valid IP v6 address.'
         ],
         "pattern": [
-            function(value, element, param) {
+            function (value, element, param) {
                 return this.optional(element) || param.test(value);
             },
             'Invalid format.'
         ],
         "allow-container-className": [
-            function(element) {
+            function (element) {
                 if (element.type === 'radio' || element.type === 'checkbox') {
                     return $(element).hasClass('change-container-classname');
                 }
@@ -419,73 +419,73 @@
             ''
         ],
         "validate-no-html-tags": [
-            function(value) {
+            function (value) {
                 return !/<(\/)?\w+/.test(value);
             },
             'HTML tags are not allowed.'
         ],
         "validate-select": [
-            function(value) {
+            function (value) {
                 return ((value !== "none") && (value != null) && (value.length !== 0));
             },
             'Please select an option.'
         ],
         "validate-no-empty": [
-            function(value) {
+            function (value) {
                 return !$.mage.isEmpty(value);
             },
             'Empty Value.'
         ],
         "validate-alphanum-with-spaces": [
-            function(v) {
+            function (v) {
                 return $.mage.isEmptyNoTrim(v) || /^[a-zA-Z0-9 ]+$/.test(v);
             },
             'Please use only letters (a-z or A-Z), numbers (0-9) or spaces only in this field.'
         ],
         "validate-data": [
-            function(v) {
+            function (v) {
                 return $.mage.isEmptyNoTrim(v) || /^[A-Za-z]+[A-Za-z0-9_]+$/.test(v);
             },
             'Please use only letters (a-z or A-Z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.'
         ],
         "validate-street": [
-            function(v) {
+            function (v) {
                 return $.mage.isEmptyNoTrim(v) || /^[ \w]{3,}([A-Za-z]\.)?([ \w]*\#\d+)?(\r\n| )[ \w]{3,}/.test(v);
             },
             'Please use only letters (a-z or A-Z), numbers (0-9), spaces and "#" in this field.'
         ],
         "validate-phoneStrict": [
-            function(v) {
+            function (v) {
                 return $.mage.isEmptyNoTrim(v) || /^(\()?\d{3}(\))?(-|\s)?\d{3}(-|\s)\d{4}$/.test(v);
             },
             'Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.'
         ],
         "validate-phoneLax": [
-            function(v) {
+            function (v) {
                 return $.mage.isEmptyNoTrim(v) || /^((\d[\-. ]?)?((\(\d{3}\))|\d{3}))?[\-. ]?\d{3}[\-. ]?\d{4}$/.test(v);
             },
             'Please enter a valid phone number. For example (123) 456-7890 or 123-456-7890.'
         ],
         "validate-fax": [
-            function(v) {
+            function (v) {
                 return $.mage.isEmptyNoTrim(v) || /^(\()?\d{3}(\))?(-|\s)?\d{3}(-|\s)\d{4}$/.test(v);
             },
             'Please enter a valid fax number (Ex: 123-456-7890).'
         ],
         "validate-email": [
-            function(v) {
+            function (v) {
                 return $.mage.isEmptyNoTrim(v) || /^([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*@([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*\.(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]){2,})$/i.test(v);
             },
             'Please enter a valid email address (Ex: johndoe@domain.com).'
         ],
         "validate-emailSender": [
-            function(v) {
+            function (v) {
                 return $.mage.isEmptyNoTrim(v) || /^[\S ]+$/.test(v);
             },
             'Please enter a valid email address (Ex: johndoe@domain.com).'
         ],
         "validate-password": [
-            function(v) {
+            function (v) {
                 if (v == null) {
                     return false;
                 }
@@ -499,7 +499,7 @@
             'Please enter 6 or more characters. Leading or trailing spaces will be ignored.'
         ],
         "validate-admin-password": [
-            function(v) {
+            function (v) {
                 if (v == null) {
                     return false;
                 }
@@ -519,7 +519,7 @@
             'Please enter 7 or more characters, using both numeric and alphabetic.'
         ],
         "validate-url": [
-            function(v) {
+            function (v) {
                 if ($.mage.isEmptyNoTrim(v)) {
                     return true;
                 }
@@ -530,35 +530,35 @@
             'Please enter a valid URL. Protocol is required (http://, https:// or ftp://).'
         ],
         "validate-clean-url": [
-            function(v) {
+            function (v) {
                 return $.mage.isEmptyNoTrim(v) || /^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\d+))?\/?/i.test(v) || /^(www)((\.[A-Z0-9][A-Z0-9_-]*)+.(com|org|net|dk|at|us|tv|info|uk|co.uk|biz|se)$)(:(\d+))?\/?/i.test(v);
 
             },
             'Please enter a valid URL. For example http://www.example.com or www.example.com.'
         ],
         "validate-xml-identifier": [
-            function(v) {
+            function (v) {
                 return $.mage.isEmptyNoTrim(v) || /^[A-Z][A-Z0-9_\/-]*$/i.test(v);
 
             },
             'Please enter a valid XML-identifier (Ex: something_1, block5, id-4).'
         ],
         "validate-ssn": [
-            function(v) {
+            function (v) {
                 return $.mage.isEmptyNoTrim(v) || /^\d{3}-?\d{2}-?\d{4}$/.test(v);
 
             },
             'Please enter a valid social security number (Ex: 123-45-6789).'
         ],
         "validate-zip-us": [
-            function(v) {
+            function (v) {
                 return $.mage.isEmptyNoTrim(v) || /(^\d{5}$)|(^\d{5}-\d{4}$)/.test(v);
 
             },
             'Please enter a valid zip code (Ex: 90602 or 90602-1234).'
         ],
         "validate-date-au": [
-            function(v) {
+            function (v) {
                 if ($.mage.isEmptyNoTrim(v)) {
                     return true;
                 }
@@ -575,14 +575,14 @@
             'Please use this date format: dd/mm/yyyy. For example 17/03/2006 for the 17th of March, 2006.'
         ],
         "validate-currency-dollar": [
-            function(v) {
+            function (v) {
                 return $.mage.isEmptyNoTrim(v) || /^\$?\-?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}\d*(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/.test(v);
 
             },
             'Please enter a valid $ amount. For example $100.00.'
         ],
         "validate-not-negative-number": [
-            function(v) {
+            function (v) {
                 if ($.mage.isEmptyNoTrim(v)) {
                     return true;
                 }
@@ -594,7 +594,7 @@
         ],
         // validate-not-negative-number should be replaced in all places with this one and then removed
         "validate-zero-or-greater": [
-            function(v) {
+            function (v) {
                 if ($.mage.isEmptyNoTrim(v)) {
                     return true;
                 }
@@ -605,7 +605,7 @@
             'Please enter a number 0 or greater in this field.'
         ],
         "validate-greater-than-zero": [
-            function(v) {
+            function (v) {
                 if ($.mage.isEmptyNoTrim(v)) {
                     return true;
                 }
@@ -615,7 +615,7 @@
             'Please enter a number greater than 0 in this field.'
         ],
         "validate-css-length": [
-            function(v) {
+            function (v) {
                 if (v !== '') {
                     return (/^[0-9]*\.*[0-9]+(px|pc|pt|ex|em|mm|cm|in|%)?$/).test(v);
                 }
@@ -625,19 +625,19 @@
         ],
         /** @description Additional methods */
         "validate-number": [
-            function(v) {
+            function (v) {
                 return $.mage.isEmptyNoTrim(v) || (!isNaN($.mage.parseNumber(v)) && /^\s*-?\d*(\.\d*)?\s*$/.test(v));
             },
             'Please enter a valid number in this field.'
         ],
         "required-number": [
-            function(v){
+            function (v) {
                 return !!v.length;
             },
             'Please enter a valid number in this field.'
         ],
         "validate-number-range": [
-            function(v, elm, param) {
+            function (v, elm, param) {
                 if ($.mage.isEmptyNoTrim(v)) {
                     return true;
                 }
@@ -658,7 +658,7 @@
                     if (m) {
                         result = result && $.mage.isBetween(numValue, m[1], m[2]);
                     }
-                } else if (elm && elm.className ) {
+                } else if (elm && elm.className) {
                     classes = elm.className.split(" ");
                     ii = classes.length;
 
@@ -678,13 +678,13 @@
             true
         ],
         "validate-digits": [
-            function(v) {
+            function (v) {
                 return $.mage.isEmptyNoTrim(v) || !/[^\d]/.test(v);
             },
             'Please enter a valid number in this field.'
         ],
         "validate-digits-range": [
-            function(v, elm, param) {
+            function (v, elm, param) {
                 if ($.mage.isEmptyNoTrim(v)) {
                     return true;
                 }
@@ -699,13 +699,13 @@
                     result = true,
                     range, m, classes, ii;
                 range = param;
-                
+
                 if (typeof range === 'object') {
                     m = dataAttrRange.exec(range);
                     if (m) {
                         result = result && $.mage.isBetween(numValue, m[1], m[2]);
                     }
-                } else if (elm && elm.className ) {
+                } else if (elm && elm.className) {
                     classes = elm.className.split(" ");
                     ii = classes.length;
 
@@ -725,7 +725,7 @@
             true
         ],
         'validate-range': [
-            function(v, elm) {
+            function (v, elm) {
                 var minValue, maxValue;
                 if ($.mage.isEmptyNoTrim(v)) {
                     return true;
@@ -756,8 +756,8 @@
                         var minValidRange = $.mage.parseNumber(validRange[1]);
                         var maxValidRange = $.mage.parseNumber(validRange[2]);
                         result = result &&
-                            (isNaN(minValidRange) || minValue >= minValidRange) &&
-                            (isNaN(maxValidRange) || maxValue <= maxValidRange);
+                        (isNaN(minValidRange) || minValue >= minValidRange) &&
+                        (isNaN(maxValidRange) || maxValue <= maxValidRange);
                     }
                 }
                 return result;
@@ -765,39 +765,39 @@
             'The value is not within the specified range.'
         ],
         "validate-alpha": [
-            function(v) {
+            function (v) {
                 return $.mage.isEmptyNoTrim(v) || /^[a-zA-Z]+$/.test(v);
             },
             'Please use letters only (a-z or A-Z) in this field.'
         ],
         "validate-code": [
-            function(v) {
+            function (v) {
                 return $.mage.isEmptyNoTrim(v) || /^[a-z]+[a-z0-9_]+$/.test(v);
             },
             'Please use only letters (a-z), numbers (0-9) or underscore (_) in this field, and the first character should be a letter.'
         ],
         "validate-alphanum": [
-            function(v) {
+            function (v) {
                 return $.mage.isEmptyNoTrim(v) || /^[a-zA-Z0-9]+$/.test(v);
             },
             'Please use only letters (a-z or A-Z) or numbers (0-9) in this field. No spaces or other characters are allowed.'
         ],
         "validate-date": [
-            function(v) {
+            function (v) {
                 var test = new Date(v);
                 return $.mage.isEmptyNoTrim(v) || !isNaN(test);
-            },'Please enter a valid date.'
+            }, 'Please enter a valid date.'
 
         ],
         "validate-date-range": [
-            function(v, elm) {
+            function (v, elm) {
                 var m = /\bdate-range-(\w+)-(\w+)\b/.exec(elm.className);
                 if (!m || m[2] === 'to' || $.mage.isEmptyNoTrim(v)) {
                     return true;
                 }
 
                 var currentYear = new Date().getFullYear() + '';
-                var normalizedTime = function(v) {
+                var normalizedTime = function (v) {
                     v = v.split(/[.\/]/);
                     if (v[2] && v[2].length < 4) {
                         v[2] = currentYear.substr(0, v[2].length) + v[2];
@@ -812,7 +812,7 @@
             'Make sure the To Date is later than or the same as the From Date.'
         ],
         "validate-cpassword": [
-            function() {
+            function () {
                 var conf = $('#confirmation').length > 0 ? $('#confirmation') : $($('.validate-cpassword')[0]);
                 var pass = false;
                 if ($('#password')) {
@@ -833,7 +833,7 @@
             'Please make sure your passwords match.'
         ],
         "validate-identifier": [
-            function(v) {
+            function (v) {
                 return $.mage.isEmptyNoTrim(v) || /^[a-z0-9][a-z0-9_\/-]+(\.[a-z0-9_-]+)?$/.test(v);
             },
             'Please enter a valid URL Key (Ex: "example-page", "example-page.html" or "anotherlevel/example-page").'
@@ -843,29 +843,29 @@
              // @TODO: Cleanup
              return Validation.get('IsEmpty').test(v) || /(^[A-z0-9]{2,10}([\s]{0,1}|[\-]{0,1})[A-z0-9]{2,10}$)/.test(v);
              }*/
-            function() {
+            function () {
                 return true;
             },
             'Please enter a valid zip code.'
         ],
         "validate-one-required": [
-            function(v, elm) {
+            function (v, elm) {
                 var p = $(elm).parent();
                 var options = p.find('input');
-                return options.map(function(elm) {
-                    return $(elm).val();
-                }).length > 0;
+                return options.map(function (elm) {
+                        return $(elm).val();
+                    }).length > 0;
             },
             'Please select one of the options above.'
         ],
         "validate-state": [
-            function(v) {
+            function (v) {
                 return (v !== 0 || v === '');
             },
             'Please select State/Province.'
         ],
         "required-file": [
-            function(v, elm) {
+            function (v, elm) {
                 var result = !$.mage.isEmptyNoTrim(v);
                 if (!result) {
                     var ovId = $(elm).attr('id') + '_value';
@@ -878,9 +878,9 @@
             'Please select a file.'
         ],
         "validate-ajax-error": [
-            function(v, element) {
+            function (v, element) {
                 element = $(element);
-                element.on('change.ajaxError', function() {
+                element.on('change.ajaxError', function () {
                     element.removeClass('validate-ajax-error');
                     element.off('change.ajaxError');
                 });
@@ -889,7 +889,7 @@
             ''
         ],
         "validate-optional-datetime": [
-            function(v, elm, param) {
+            function (v, elm, param) {
                 var dateTimeParts = $('.datetime-picker[id^="options_' + param + '"]'),
                     hasWithValue = false, hasWithNoValue = false,
                     pattern = /day_part$/i;
@@ -907,7 +907,7 @@
             'The field isn\'t complete.'
         ],
         "validate-required-datetime": [
-            function(v, elm, param) {
+            function (v, elm, param) {
                 var dateTimeParts = $('.datetime-picker[id^="options_' + param + '"]');
                 for (var i = 0; i < dateTimeParts.length; i++) {
                     if (dateTimeParts[i].value === "") {
@@ -919,43 +919,43 @@
             'This is a required field.'
         ],
         "validate-one-required-by-name": [
-            function(v, elm, selector) {
-                var name        = elm.name.replace(/([\\"])/g, '\\$1'),
-                    container   = this.currentForm,
-                    selector    = selector === true ? 'input[name="' + name + '"]:checked' : selector;
-                
+            function (v, elm, selector) {
+                var name = elm.name.replace(/([\\"])/g, '\\$1'),
+                    container = this.currentForm,
+                    selector = selector === true ? 'input[name="' + name + '"]:checked' : selector;
+
                 return !!container.querySelectorAll(selector).length;
             },
             'Please select one of the options.'
         ],
         "less-than-equals-to": [
-            function(value, element, params) {
+            function (value, element, params) {
                 if ($.isNumeric($(params).val()) && $.isNumeric(value)) {
                     this.lteToVal = $(params).val();
                     return parseFloat(value) <= parseFloat($(params).val());
                 }
                 return true;
             },
-            function() {
+            function () {
                 var message = $.mage.__('Please enter a value less than or equal to %s.');
                 return message.replace('%s', this.lteToVal);
             }
         ],
         "greater-than-equals-to": [
-            function(value, element, params) {
+            function (value, element, params) {
                 if ($.isNumeric($(params).val()) && $.isNumeric(value)) {
                     this.gteToVal = $(params).val();
                     return parseFloat(value) >= parseFloat($(params).val());
                 }
                 return true;
             },
-            function() {
+            function () {
                 var message = $.mage.__('Please enter a value greater than or equal to %s.');
                 return message.replace('%s', this.gteToVal);
             }
         ],
         "validate-emails": [
-            function(value) {
+            function (value) {
                 if ($.mage.isEmpty(value)) {
                     return true;
                 }
@@ -978,7 +978,7 @@
              * @param params - selector for credit card number
              * @return {boolean}
              */
-                function(value, element, params) {
+                function (value, element, params) {
                 if (value && params && creditCartTypes[value]) {
                     return creditCartTypes[value][0].test($(params).val().replace(/\s+/g, ''));
                 }
@@ -991,7 +991,7 @@
              * @param value - credit card number
              * @return {boolean}
              */
-                function(value) {
+                function (value) {
                 if (value) {
                     return validateCreditCard(value);
                 }
@@ -1006,7 +1006,7 @@
              * @param params - selector for credit card type
              * @return {boolean}
              */
-                function(value, element, params) {
+                function (value, element, params) {
                 if (value && params) {
                     var ccType = $(params).val();
                     value = value.replace(/\s/g, '').replace(/\-/g, '');
@@ -1027,7 +1027,7 @@
              * @param params - year selector
              * @return {Boolean}
              */
-                function(value, element, params) {
+                function (value, element, params) {
                 var isValid = false;
                 if (value && params) {
                     var month = value,
@@ -1048,7 +1048,7 @@
              * @param params - credit card type selector
              * @return {*}
              */
-                function(value, element, params) {
+                function (value, element, params) {
                 if (value && params) {
                     var ccType = $(params).val();
                     if (creditCartTypes[ccType] && creditCartTypes[ccType][0]) {
@@ -1064,19 +1064,19 @@
              * @param value - input field value
              * @return {*}
              */
-                function(value) {
+                function (value) {
                 return value;
             }, 'Please enter issue number or start date for switch/solo card type.'
         ],
 
         "validate-length": [
-            function(v, elm) {
+            function (v, elm) {
                 var reMax = new RegExp(/^maximum-length-[0-9]+$/),
                     reMin = new RegExp(/^minimum-length-[0-9]+$/),
                     validator = this,
                     result = true,
                     length = 0;
-                $.each(elm.className.split(' '), function(index, name) {
+                $.each(elm.className.split(' '), function (index, name) {
                     if (name.match(reMax) && result) {
                         length = name.split('-')[2];
                         validator.attrLength = length;
@@ -1088,18 +1088,18 @@
                     }
                 });
                 return result;
-            }, function() {
+            }, function () {
                 return $.mage.__("Maximum length of this field must be equal or less than %1 symbols.")
                     .replace('%1', this.attrLength);
             }
         ],
         'required-entry': [
-            function(value) {
+            function (value) {
                 return !$.mage.isEmpty(value);
             }, $.mage.__('This is a required field.')
         ],
         'not-negative-amount': [
-            function(v) {
+            function (v) {
                 if (v.length)
                     return (/^\s*\d+([,.]\d+)*\s*%?\s*$/).test(v);
                 else
@@ -1108,7 +1108,7 @@
             'Please enter positive number in this field.'
         ],
         'validate-per-page-value-list': [
-            function(v) {
+            function (v) {
                 var isValid = !$.mage.isEmpty(v);
                 var values = v.split(',');
                 for (var i = 0; i < values.length; i++) {
@@ -1121,7 +1121,7 @@
             'Please enter a valid value, ex: 10,20,30'
         ],
         'validate-per-page-value': [
-            function(v, elm) {
+            function (v, elm) {
                 if ($.mage.isEmpty(v)) {
                     return false;
                 }
@@ -1131,10 +1131,9 @@
             'Please enter a valid value from list'
         ],
         'validate-new-password': [
-            function(v) {
+            function (v) {
 
-                if ($.validator.methods['validate-password'] &&
-                    !$.validator.methods['validate-password'](v)) {
+                if ($.validator.methods['validate-password'] && !$.validator.methods['validate-password'](v)) {
                     return false;
                 }
                 if ($.mage.isEmpty(v) && v !== '') {
@@ -1168,6 +1167,19 @@
             },
             'This is a required field.'
         ],
+        'required-if-all-sku-empty': [
+            function (value, element, params) {
+                var valid = false;
+
+                $('input[' + params + '=true]').each(function () {
+                    if ($(this).val() !== '') {
+                        valid = true;
+                    }
+                });
+
+                return valid;
+            }, 'Enter valid SKU key'
+        ],
         'required-if-specified': [
             function (value, element, params) {
                 var valid = true;
@@ -1194,9 +1206,9 @@
             'This is a required field.'
         ],
         'required-number-if-specified': [
-             function (value, element, params) {
-                var valid       = true,
-                    dependent   = $(params),
+            function (value, element, params) {
+                var valid = true,
+                    dependent = $(params),
                     depeValue;
 
                 if (dependent.length) {
@@ -1219,8 +1231,8 @@
 
                 // validate quantity
                 var isMinAllowedValid = typeof params.minAllowed === 'undefined' || (qty >= $.mage.parseNumber(params.minAllowed));
-                var isMaxAllowedValid = typeof params.maxAllowed === 'undefined'  || (qty <= $.mage.parseNumber(params.maxAllowed));
-                var isQtyIncrementsValid = typeof params.qtyIncrements === 'undefined'  || (qty % $.mage.parseNumber(params.qtyIncrements) === 0);
+                var isMaxAllowedValid = typeof params.maxAllowed === 'undefined' || (qty <= $.mage.parseNumber(params.maxAllowed));
+                var isQtyIncrementsValid = typeof params.qtyIncrements === 'undefined' || (qty % $.mage.parseNumber(params.qtyIncrements) === 0);
 
                 return isMaxAllowedValid && isMinAllowedValid && isQtyIncrementsValid && qty > 0;
             },
@@ -1228,7 +1240,7 @@
         ]
     };
 
-    $.each(rules, function(i, rule) {
+    $.each(rules, function (i, rule) {
         rule.unshift(i);
         $.validator.addMethod.apply($.validator, rule);
     });
@@ -1254,7 +1266,7 @@
 
     var showLabel = $.validator.prototype.showLabel;
     $.extend(true, $.validator.prototype, {
-        showLabel: function(element, message) {
+        showLabel: function (element, message) {
             showLabel.call(this, element, message);
 
             // ARIA (adding aria-invalid & aria-describedby)
@@ -1262,7 +1274,7 @@
                 elem = $(element);
 
             if (!label.attr('id')) {
-                label.attr('id', this.idOrName(element)+'-error');
+                label.attr('id', this.idOrName(element) + '-error');
             }
             elem.attr('aria-invalid', 'true')
                 .attr('aria-describedby', label.attr('id'));
@@ -1274,7 +1286,7 @@
      * @param {Element||String} element - DOM element or selector
      * @return {Boolean} validation result
      */
-    $.validator.validateElement = function(element) {
+    $.validator.validateElement = function (element) {
         element = $(element);
         var form = element.get(0).form,
             validator = form ? $(form).data('validator') : null;
@@ -1284,7 +1296,7 @@
         } else {
             var valid = true,
                 classes = element.prop('class').split(' ');
-            $.each(classes, $.proxy(function(i, className) {
+            $.each(classes, $.proxy(function (i, className) {
                 if (this.methods[className] && !this.methods[className](element.val(), element.get(0))) {
                     valid = false;
                     return valid;
@@ -1303,7 +1315,7 @@
             ignoreTitle: true,
             errorClass: 'mage-error',
             errorElement: 'div',
-            errorPlacement: function(error, element) {
+            errorPlacement: function (error, element) {
                 var errorPlacement = element;
                 // logic for date-picker error placement
                 if (element.hasClass('hasDatepicker')) {
@@ -1325,16 +1337,16 @@
          * Check if form pass validation rules without submit
          * @return boolean
          */
-        isValid: function() {
+        isValid: function () {
             return this.element.valid();
         },
 
         /**
          * Remove validation error messages
          */
-        clearError: function() {
+        clearError: function () {
             if (arguments.length) {
-                $.each(arguments, $.proxy(function(index, item) {
+                $.each(arguments, $.proxy(function (index, item) {
                     this.validate.prepareElement(item);
                     this.validate.hideErrors();
                 }, this));
@@ -1346,7 +1358,7 @@
          * Validation creation
          * @protected
          */
-        _create: function() {
+        _create: function () {
             this.validate = this.element.validate(this.options);
 
             // ARIA (adding aria-required attribute)
@@ -1362,7 +1374,7 @@
          * Validation listening
          * @protected
          */
-        _listenFormValidate: function() {
+        _listenFormValidate: function () {
             $('form').on('invalid-form.validate', function (event, validation) {
                 var firstActive = $(validation.errorList[0].element || []),
                     lastActive = $(validation.findLastActive() || validation.errorList.length && validation.errorList[0].element || []);
@@ -1378,7 +1390,7 @@
                 // ARIA (removing aria attributes if success)
                 var successList = validation.successList;
                 if (successList.length) {
-                    $.each(successList, function() {
+                    $.each(successList, function () {
                         $(this)
                             .removeAttr('aria-describedby')
                             .removeAttr('aria-invalid');
diff --git a/package.json b/package.json
index c2f3cb1eaaf9edd5e19767c82f75782f022f1373..d65941df608b479bd6f769eae99ca0dc84166fd5 100644
--- a/package.json
+++ b/package.json
@@ -2,13 +2,14 @@
   "name": "Magento2",
   "author": "Magento, an eBay Inc. company",
   "description": "Magento2 node modules dependencies for local development",
-  "version": "0.74.0-beta7",
+  "version": "1.0.0-beta",
   "repository": {
     "type": "git",
     "url": "https://github.com/magento/magento2.git"
   },
   "homepage": "http://magento.com/",
   "devDependencies": {
+    "glob": "^5.0.14",
     "grunt": "^0.4.5",
     "grunt-autoprefixer": "^2.0.0",
     "grunt-banner": "^0.4.0",
@@ -19,15 +20,19 @@
     "grunt-contrib-jasmine": "^0.8.1",
     "grunt-contrib-less": "^0.12.0",
     "grunt-contrib-watch": "^0.6.1",
+    "grunt-eslint": "^16.0.0",
     "grunt-exec": "^0.4.6",
+    "grunt-jscs": "^1.8.0",
     "grunt-replace": "^0.9.2",
     "grunt-styledocco": "^0.1.4",
     "grunt-template-jasmine-requirejs": "^0.2.3",
     "grunt-text-replace": "^0.4.0",
     "imagemin-svgo": "^4.0.1",
+    "jscs-jsdoc": "^1.1.0",
     "load-grunt-config": "^0.16.0",
     "morgan": "^1.5.0",
     "node-minify": "^1.0.1",
+    "path": "^0.11.14",
     "serve-static": "^1.7.1",
     "strip-json-comments": "^1.0.2",
     "time-grunt": "^1.0.0",
diff --git a/setup/pub/magento/setup/web-configuration.js b/setup/pub/magento/setup/web-configuration.js
index 79170d6cbf1f3d8adac23d12e63ded7957ccf1e7..13ff2e05fe666c6a6bd90e62eb5e632f5bf83def 100644
--- a/setup/pub/magento/setup/web-configuration.js
+++ b/setup/pub/magento/setup/web-configuration.js
@@ -11,7 +11,7 @@ angular.module('web-configuration', ['ngStorage'])
                 base_url: '',
                 auto_base_url: '',
                 actual_base_url: '',
-                admin: 'admin'
+                admin: ''
             },
             https: {
                 front: false,
@@ -40,13 +40,13 @@ angular.module('web-configuration', ['ngStorage'])
 
         $scope.updateOnExpand = function(obj) {
             obj.expanded = !obj.expanded;
-        }
+        };
 
         $scope.fillBaseURL = function() {
             if (angular.equals($scope.config.address.base_url, '')) {
                 $scope.config.address.base_url = $scope.config.address.auto_base_url;
             }
-        }
+        };
 
         $scope.$watch('config.address.base_url', function() {
             if (angular.equals($scope.config.address.base_url, '')) {
@@ -74,11 +74,11 @@ angular.module('web-configuration', ['ngStorage'])
 
         $scope.showEncryptKey = function() {
             return angular.equals($scope.config.encrypt.type, 'user');
-        }
+        };
 
         $scope.showHttpsField = function() {
             return ($scope.config.https.front || $scope.config.https.admin);
-        }
+        };
 
         $scope.addSlash = function() {
             if (angular.isUndefined($scope.config.address.base_url)) {
@@ -107,7 +107,7 @@ angular.module('web-configuration', ['ngStorage'])
                 $scope.$emit('validation-response', false);
                 $scope.webconfig.submitted = true;
             }
-        }
+        };
 
         // Update 'submitted' flag
         $scope.$watch(function() { return $scope.webconfig.$valid }, function(valid) {
diff --git a/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php b/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php
index 7606a2e17bf0b902394ea8bb3c583d8ab22136c2..707c8ee9dae3296836b2a16a000298fded1c9359 100644
--- a/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php
+++ b/setup/src/Magento/Setup/Console/Command/DiCompileCommand.php
@@ -14,12 +14,15 @@ use Magento\Setup\Model\ObjectManagerProvider;
 use Magento\Setup\Module\Di\App\Task\Manager;
 use Magento\Setup\Module\Di\App\Task\OperationFactory;
 use Magento\Setup\Module\Di\App\Task\OperationException;
+use Magento\Setup\Module\Di\App\Task\OperationInterface;
 use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Helper\ProgressBar;
 use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Output\OutputInterface;
 
 /**
  * Command to run compile in single-tenant mode
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class DiCompileCommand extends Command
 {
@@ -104,39 +107,10 @@ class DiCompileCommand extends Command
         ];
         $this->configureObjectManager($output);
 
-        $operations = [
-            OperationFactory::REPOSITORY_GENERATOR => [
-                'path' => $compiledPathsList['application'],
-                'filePatterns' => ['di' => '/\/etc\/([a-zA-Z_]*\/di|di)\.xml$/']
-            ],
-            OperationFactory::DATA_ATTRIBUTES_GENERATOR => [
-                'path' => $compiledPathsList['application'],
-                'filePatterns' => $dataAttributesIncludePattern
-            ],
-            OperationFactory::APPLICATION_CODE_GENERATOR => [
-                $compiledPathsList['application'],
-                $compiledPathsList['library'],
-                $compiledPathsList['generated_helpers'],
-            ],
-            OperationFactory::INTERCEPTION => [
-                    'intercepted_paths' => [
-                        $compiledPathsList['application'],
-                        $compiledPathsList['library'],
-                        $compiledPathsList['generated_helpers'],
-                    ],
-                    'path_to_store' => $compiledPathsList['generated_helpers'],
-            ],
-            OperationFactory::AREA_CONFIG_GENERATOR => [
-                $compiledPathsList['application'],
-                $compiledPathsList['library'],
-                $compiledPathsList['generated_helpers'],
-            ],
-            OperationFactory::INTERCEPTION_CACHE => [
-                $compiledPathsList['application'],
-                $compiledPathsList['library'],
-                $compiledPathsList['generated_helpers'],
-            ]
-        ];
+        $operations = $this->getOperationsConfiguration(
+            $compiledPathsList,
+            $dataAttributesIncludePattern
+        );
 
         try {
             $this->cleanupFilesystem(
@@ -152,7 +126,34 @@ class DiCompileCommand extends Command
                     $arguments
                 );
             }
-            $this->taskManager->process();
+
+            /** @var ProgressBar $progressBar */
+            $progressBar = $this->objectManager->create(
+                'Symfony\Component\Console\Helper\ProgressBar',
+                [
+                    'output' => $output,
+                    'max' => count($operations)
+                ]
+            );
+            $progressBar->setFormat(
+                '<info>%message%</info> %current%/%max% [%bar%] %percent:3s%% %elapsed% %memory:6s%'
+            );
+            $output->writeln('<info>Compilation was started.</info>');
+            $progressBar->start();
+            $progressBar->display();
+
+            $this->taskManager->process(
+                function (OperationInterface $operation) use ($progressBar) {
+                    $progressBar->setMessage($operation->getName() . '...');
+                    $progressBar->display();
+                },
+                function (OperationInterface $operation) use ($progressBar) {
+                    $progressBar->advance();
+                }
+            );
+
+            $progressBar->finish();
+            $output->writeln('');
             $output->writeln('<info>Generated code and dependency injection configuration successfully.</info>');
         } catch (OperationException $e) {
             $output->writeln('<error>' . $e->getMessage() . '</error>');
@@ -222,4 +223,52 @@ class DiCompileCommand extends Command
             ]
         );
     }
+
+    /**
+     * Returns operations configuration
+     *
+     * @param array $compiledPathsList
+     * @param array $dataAttributesIncludePattern
+     * @return array
+     */
+    private function getOperationsConfiguration(
+        array $compiledPathsList,
+        array $dataAttributesIncludePattern
+    ) {
+        $operations = [
+            OperationFactory::REPOSITORY_GENERATOR => [
+                'path' => $compiledPathsList['application'],
+                'filePatterns' => ['di' => '/\/etc\/([a-zA-Z_]*\/di|di)\.xml$/']
+            ],
+            OperationFactory::DATA_ATTRIBUTES_GENERATOR => [
+                'path' => $compiledPathsList['application'],
+                'filePatterns' => $dataAttributesIncludePattern
+            ],
+            OperationFactory::APPLICATION_CODE_GENERATOR => [
+                $compiledPathsList['application'],
+                $compiledPathsList['library'],
+                $compiledPathsList['generated_helpers'],
+            ],
+            OperationFactory::INTERCEPTION => [
+                'intercepted_paths' => [
+                    $compiledPathsList['application'],
+                    $compiledPathsList['library'],
+                    $compiledPathsList['generated_helpers'],
+                ],
+                'path_to_store' => $compiledPathsList['generated_helpers'],
+            ],
+            OperationFactory::AREA_CONFIG_GENERATOR => [
+                $compiledPathsList['application'],
+                $compiledPathsList['library'],
+                $compiledPathsList['generated_helpers'],
+            ],
+            OperationFactory::INTERCEPTION_CACHE => [
+                $compiledPathsList['application'],
+                $compiledPathsList['library'],
+                $compiledPathsList['generated_helpers'],
+            ]
+        ];
+
+        return $operations;
+    }
 }
diff --git a/setup/src/Magento/Setup/Console/Command/InfoAdminUriCommand.php b/setup/src/Magento/Setup/Console/Command/InfoAdminUriCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..5bdc0333121f23cd7def4ca976792d07102e94b5
--- /dev/null
+++ b/setup/src/Magento/Setup/Console/Command/InfoAdminUriCommand.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Console\Command;
+
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Command\Command;
+use \Magento\Backend\Setup\ConfigOptionsList as BackendConfigOptionsList;
+
+class InfoAdminUriCommand extends Command
+{
+    /**
+     * @var \Magento\Framework\App\DeploymentConfig
+     */
+    private $deploymentConfig;
+
+    /**
+     * Constructor
+     *
+     * @param \Magento\Framework\App\DeploymentConfig $deploymentConfig
+     *
+     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
+     */
+    public function __construct(\Magento\Framework\App\DeploymentConfig $deploymentConfig)
+    {
+        $this->deploymentConfig = $deploymentConfig;
+        parent::__construct();
+    }
+
+    /**
+     * Initialization of the command
+     *
+     * @return void
+     */
+    protected function configure()
+    {
+        $this->setName('info:adminuri')
+            ->setDescription('Displays the Magento Admin URI');
+        parent::configure();
+    }
+
+     /**
+      * {@inheritdoc}
+      */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        $output->writeln(
+            "\nAdmin URI: /"
+            . $this->deploymentConfig->get(BackendConfigOptionsList::CONFIG_PATH_BACKEND_FRONTNAME)
+            . "\n"
+        );
+    }
+}
diff --git a/setup/src/Magento/Setup/Console/CommandList.php b/setup/src/Magento/Setup/Console/CommandList.php
index 590e2c9789a1c257a13a796fd4b34087c2b4998b..a977de25c51534108d115a3817f70eddd6255fa0 100644
--- a/setup/src/Magento/Setup/Console/CommandList.php
+++ b/setup/src/Magento/Setup/Console/CommandList.php
@@ -53,6 +53,7 @@ class CommandList
             'Magento\Setup\Console\Command\GenerateFixturesCommand',
             'Magento\Setup\Console\Command\I18nCollectPhrasesCommand',
             'Magento\Setup\Console\Command\I18nPackCommand',
+            'Magento\Setup\Console\Command\InfoAdminUriCommand',
             'Magento\Setup\Console\Command\InfoBackupsListCommand',
             'Magento\Setup\Console\Command\InfoCurrencyListCommand',
             'Magento\Setup\Console\Command\InfoLanguageListCommand',
diff --git a/setup/src/Magento/Setup/Controller/WebConfiguration.php b/setup/src/Magento/Setup/Controller/WebConfiguration.php
index 7ffcb4e6120a2ccd7e623bebeab800c746db7e42..1197a234c0ad9858e588106ddaa541cbefab104a 100644
--- a/setup/src/Magento/Setup/Controller/WebConfiguration.php
+++ b/setup/src/Magento/Setup/Controller/WebConfiguration.php
@@ -19,7 +19,12 @@ class WebConfiguration extends AbstractActionController
     public function indexAction()
     {
         $setupInfo = new SetupInfo($_SERVER);
-        $view = new ViewModel(['autoBaseUrl' => $setupInfo->getProjectUrl()]);
+        $view = new ViewModel(
+            [
+                'autoBaseUrl'   => $setupInfo->getProjectUrl(),
+                'autoAdminPath' => $setupInfo->getProjectAdminPath()
+            ]
+        );
         $view->setTerminal(true);
         return $view;
     }
diff --git a/setup/src/Magento/Setup/Model/ConfigModel.php b/setup/src/Magento/Setup/Model/ConfigModel.php
index f812279bd6a3cbd61c8475c2a08f8509ed8ca68b..5f481a0f5db806f44097a196028f65455ff7cf90 100644
--- a/setup/src/Magento/Setup/Model/ConfigModel.php
+++ b/setup/src/Magento/Setup/Model/ConfigModel.php
@@ -153,7 +153,7 @@ class ConfigModel
 
         return $errors;
     }
-    
+
     /**
      * Check permissions of directories that are expected to be writable for installation
      *
@@ -164,7 +164,7 @@ class ConfigModel
     {
         $results = $this->filePermissions->getMissingWritableDirectoriesForInstallation();
         if ($results) {
-            $errorMsg = "Missing writing permissions to the following directories: '" . implode("', '", $results) . "'";
+            $errorMsg = "Missing write permissions to the following directories: '" . implode("', '", $results) . "'";
             throw new \Exception($errorMsg);
         }
     }
diff --git a/setup/src/Magento/Setup/Model/Deployer.php b/setup/src/Magento/Setup/Model/Deployer.php
index dfd2b05952f6ec38423e12ee8ed796cf50483ce4..8ab1b0da5742ea147a971f11d90b805cef8fa019 100644
--- a/setup/src/Magento/Setup/Model/Deployer.php
+++ b/setup/src/Magento/Setup/Model/Deployer.php
@@ -55,9 +55,6 @@ class Deployer
     /** @var \Magento\Framework\View\Template\Html\MinifierInterface */
     private $htmlMinifier;
 
-    /** @var \Magento\Framework\View\Asset\MinifyService */
-    protected $minifyService;
-
     /**
      * @var ObjectManagerInterface
      */
@@ -72,7 +69,6 @@ class Deployer
      * @param Files $filesUtil
      * @param OutputInterface $output
      * @param Version\StorageInterface $versionStorage
-     * @param \Magento\Framework\View\Asset\MinifyService $minifyService
      * @param JsTranslationConfig $jsTranslationConfig
      * @param bool $isDryRun
      */
@@ -80,7 +76,6 @@ class Deployer
         Files $filesUtil,
         OutputInterface $output,
         Version\StorageInterface $versionStorage,
-        \Magento\Framework\View\Asset\MinifyService $minifyService,
         JsTranslationConfig $jsTranslationConfig,
         $isDryRun = false
     ) {
@@ -88,7 +83,6 @@ class Deployer
         $this->output = $output;
         $this->versionStorage = $versionStorage;
         $this->isDryRun = $isDryRun;
-        $this->minifyService = $minifyService;
         $this->jsTranslationConfig = $jsTranslationConfig;
         $this->parentTheme = [];
     }
@@ -275,7 +269,6 @@ class Deployer
                 $requestedPath,
                 ['area' => $area, 'theme' => $themePath, 'locale' => $locale, 'module' => $module]
             );
-            $asset = $this->minifyService->getAssets([$asset], true)[0];
             if ($this->output->isVeryVerbose()) {
                 $this->output->writeln("\tDeploying the file to '{$asset->getPath()}'");
             } else {
diff --git a/setup/src/Magento/Setup/Model/Installer.php b/setup/src/Magento/Setup/Model/Installer.php
index b3cdd3ee191891466f70e8f8df4376b768c5825e..0e822e56f2dd5c84e307a63ff9baf474b65b6780 100644
--- a/setup/src/Magento/Setup/Model/Installer.php
+++ b/setup/src/Magento/Setup/Model/Installer.php
@@ -33,6 +33,7 @@ use Magento\Framework\Config\File\ConfigFilePool;
 use Magento\Framework\App\State\CleanupFiles;
 use Magento\Setup\Console\Command\InstallCommand;
 use Magento\Setup\Validator\DbValidator;
+use \Magento\Backend\Setup\ConfigOptionsList as BackendConfigOptionsList;
 
 /**
  * Class Installer contains the logic to install Magento application.
@@ -300,6 +301,10 @@ class Installer
         }
 
         $this->log->logSuccess('Magento installation complete.');
+        $this->log->logSuccess(
+            'Magento Admin URI: /'
+            . $this->deploymentConfig->get(BackendConfigOptionsList::CONFIG_PATH_BACKEND_FRONTNAME)
+        );
 
         if ($this->progress->getCurrent() != $this->progress->getTotal()) {
             throw new \LogicException('Installation progress did not finish properly.');
@@ -394,7 +399,7 @@ class Installer
     {
         $results = $this->filePermissions->getMissingWritableDirectoriesForInstallation();
         if ($results) {
-            $errorMsg = "Missing writing permissions to the following directories: '" . implode("' '", $results) . "'";
+            $errorMsg = "Missing write permissions to the following directories: '" . implode("' '", $results) . "'";
             throw new \Exception($errorMsg);
         }
     }
diff --git a/setup/src/Magento/Setup/Module/Di/App/Task/Manager.php b/setup/src/Magento/Setup/Module/Di/App/Task/Manager.php
index 7e4171c0873d2bef4bbd23ad558980c051e55622..e981497eb73bee1fae0182c2b990000023694ec4 100644
--- a/setup/src/Magento/Setup/Module/Di/App/Task/Manager.php
+++ b/setup/src/Magento/Setup/Module/Di/App/Task/Manager.php
@@ -20,8 +20,9 @@ class Manager
     /**
      * @param OperationFactory $operationFactory
      */
-    public function __construct(OperationFactory $operationFactory)
-    {
+    public function __construct(
+        OperationFactory $operationFactory
+    ) {
         $this->operationFactory = $operationFactory;
     }
 
@@ -40,13 +41,23 @@ class Manager
     /**
      * Processes list of operations
      *
+     * @param callable $beforeCallback
+     * @param callable $afterCallback
      * @return void
      */
-    public function process()
+    public function process(\Closure $beforeCallback = null, \Closure $afterCallback = null)
     {
         /** @var OperationInterface $operation */
         foreach ($this->operationsList as $operation) {
+            if (is_callable($beforeCallback)) {
+                $beforeCallback($operation);
+            }
+
             $operation->doOperation();
+
+            if (is_callable($afterCallback)) {
+                $afterCallback($operation);
+            }
         }
         $this->operationsList = [];
     }
diff --git a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/ApplicationCodeGenerator.php b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/ApplicationCodeGenerator.php
index 1228703ab08fd6e99af5e1c5e18715a4d3783e91..82c13934833e18508cc61e4e20704d8d51703f97 100644
--- a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/ApplicationCodeGenerator.php
+++ b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/ApplicationCodeGenerator.php
@@ -45,4 +45,14 @@ class ApplicationCodeGenerator implements OperationInterface
             $this->classesScanner->getList($path);
         }
     }
+
+    /**
+     * Returns operation name
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return 'Application code generator';
+    }
 }
diff --git a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/Area.php b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/Area.php
index f129e56dc8d8c67afa7d971393fb60d987585df5..79c985af01d71c24b94c065115ff068122b80a54 100644
--- a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/Area.php
+++ b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/Area.php
@@ -106,4 +106,14 @@ class Area implements OperationInterface
         }
         return $definitions;
     }
+
+    /**
+     * Returns operation name
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return 'Area configuration aggregation';
+    }
 }
diff --git a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/Interception.php b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/Interception.php
index 6d5d9ae3502a806f22bb4c58e04ed2105b2755aa..bfd3cfcf5e09d8abede8986852b85cbb24d3571f 100644
--- a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/Interception.php
+++ b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/Interception.php
@@ -94,4 +94,14 @@ class Interception implements OperationInterface
         $configuration = $this->interceptionConfigurationBuilder->getInterceptionConfiguration($classesList);
         $generator->generateList($configuration);
     }
+
+    /**
+     * Returns operation name
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return 'Interceptors generation';
+    }
 }
diff --git a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/InterceptionCache.php b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/InterceptionCache.php
index b37f329ebfc78a57a6ce41b0e63358a7b04c411d..e99a15a9130620ec4d45e5f00e4ea83d515d30ae 100644
--- a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/InterceptionCache.php
+++ b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/InterceptionCache.php
@@ -57,4 +57,14 @@ class InterceptionCache implements OperationInterface
 
         $this->configInterface->initialize($definitions);
     }
+
+    /**
+     * Returns operation name
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return 'Interception cache generation';
+    }
 }
diff --git a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/RepositoryGenerator.php b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/RepositoryGenerator.php
index 41e9e80e5fe4e04628af960d4bf2b25f1eb89936..22c57aea87fedd77b04b9fee03b2df78c18aa45e 100644
--- a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/RepositoryGenerator.php
+++ b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/RepositoryGenerator.php
@@ -70,4 +70,14 @@ class RepositoryGenerator implements OperationInterface
             class_exists($entityName);
         }
     }
+
+    /**
+     * Returns operation name
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return 'Repositories code generation';
+    }
 }
diff --git a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/ServiceDataAttributesGenerator.php b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/ServiceDataAttributesGenerator.php
index 3e8ee94b8bd28a6dffd8cd363fe4a22fd494ef28..46b75bf10efeffef190264e3ff7fdfa37fe3492e 100644
--- a/setup/src/Magento/Setup/Module/Di/App/Task/Operation/ServiceDataAttributesGenerator.php
+++ b/setup/src/Magento/Setup/Module/Di/App/Task/Operation/ServiceDataAttributesGenerator.php
@@ -64,4 +64,14 @@ class ServiceDataAttributesGenerator implements OperationInterface
             class_exists($entityName);
         }
     }
+
+    /**
+     * Returns operation name
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return 'Service data attributes generation';
+    }
 }
diff --git a/setup/src/Magento/Setup/Module/Di/App/Task/OperationInterface.php b/setup/src/Magento/Setup/Module/Di/App/Task/OperationInterface.php
index 0ce7cd3344c4684d5455a0c2044c8f254468862e..46bbce3d7ec591737d3e3c60ee1cf35a2b757f7b 100644
--- a/setup/src/Magento/Setup/Module/Di/App/Task/OperationInterface.php
+++ b/setup/src/Magento/Setup/Module/Di/App/Task/OperationInterface.php
@@ -13,4 +13,11 @@ interface OperationInterface
      * @return void
      */
     public function doOperation();
+
+    /**
+     * Returns operation name
+     *
+     * @return string
+     */
+    public function getName();
 }
diff --git a/setup/src/Magento/Setup/Module/Di/Compiler/Config/Chain/PreferencesResolving.php b/setup/src/Magento/Setup/Module/Di/Compiler/Config/Chain/PreferencesResolving.php
index 9d58a69cd6ebf5fea3a41f70bf0f1f9ffa1cb0f4..6c7dc8b6d47195e807ac875b4bc1ba3cdb28db9c 100644
--- a/setup/src/Magento/Setup/Module/Di/Compiler/Config/Chain/PreferencesResolving.php
+++ b/setup/src/Magento/Setup/Module/Di/Compiler/Config/Chain/PreferencesResolving.php
@@ -18,7 +18,7 @@ class PreferencesResolving implements ModificationInterface
      */
     public function modify(array $config)
     {
-        if (!isset($config['arguments']) || !isset($config['preferences'])) {
+        if (!isset($config['arguments'], $config['preferences'])) {
             return $config;
         }
 
@@ -42,7 +42,7 @@ class PreferencesResolving implements ModificationInterface
 
         foreach ($argument as $key => &$value) {
             if (in_array($key, ['_i_', '_ins_'])) {
-                $value = isset($preferences[$value]) ? $preferences[$value] : $value;
+                $value = $this->resolvePreferenceRecursive($value, $preferences);
                 continue;
             }
 
@@ -50,6 +50,20 @@ class PreferencesResolving implements ModificationInterface
                 $this->resolvePreferences($value, $preferences);
             }
         }
-        return;
+    }
+
+    /**
+     * Resolves preference recursively
+     *
+     * @param string $value
+     * @param array $preferences
+     *
+     * @return string
+     */
+    private function resolvePreferenceRecursive(&$value, &$preferences)
+    {
+        return isset($preferences[$value])
+            ? $this->resolvePreferenceRecursive($preferences[$value], $preferences)
+            : $value;
     }
 }
diff --git a/setup/src/Magento/Setup/Module/Di/Compiler/Config/ModificationChain.php b/setup/src/Magento/Setup/Module/Di/Compiler/Config/ModificationChain.php
index 666ee682c05cd71232cb68432d4584eac26a02b4..e8b316562485239ea54b71f70abfc0e28aac42ed 100644
--- a/setup/src/Magento/Setup/Module/Di/Compiler/Config/ModificationChain.php
+++ b/setup/src/Magento/Setup/Module/Di/Compiler/Config/ModificationChain.php
@@ -29,7 +29,6 @@ class ModificationChain implements ModificationInterface
         $this->modificationsList = $modificationsList;
     }
 
-
     /**
      * Modifies input config
      *
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/DiCompileCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/DiCompileCommandTest.php
index 450c74b14fb9bf372b4eb35131ca06d8e67b806c..2b9381b4783a495e0a179e6221734c0ac34e5895 100644
--- a/setup/src/Magento/Setup/Test/Unit/Console/Command/DiCompileCommandTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/DiCompileCommandTest.php
@@ -90,14 +90,25 @@ class DiCompileCommandTest extends \PHPUnit_Framework_TestCase
         $this->filesystem->expects($this->atLeastOnce())->method('getDirectoryWrite')->willReturn($writeDirectory);
 
         $this->deploymentConfig->expects($this->once())->method('isAvailable')->willReturn(true);
+        $progressBar = $this->getMockBuilder(
+            'Symfony\Component\Console\Helper\ProgressBar'
+        )
+            ->disableOriginalConstructor()
+            ->getMock();
+
         $this->objectManager->expects($this->once())->method('configure');
+        $this->objectManager
+            ->expects($this->once())
+            ->method('create')
+            ->with('Symfony\Component\Console\Helper\ProgressBar')
+            ->willReturn($progressBar);
         $this->manager->expects($this->exactly(6))->method('addOperation');
         $this->manager->expects($this->once())->method('process');
         $tester = new CommandTester($this->command);
         $tester->execute([]);
-        $this->assertEquals(
-            'Generated code and dependency injection configuration successfully.' . PHP_EOL,
-            $tester->getDisplay()
+        $this->assertContains(
+            'Generated code and dependency injection configuration successfully.',
+            explode(PHP_EOL, $tester->getDisplay())
         );
     }
 }
diff --git a/setup/src/Magento/Setup/Test/Unit/Console/Command/InfoAdminUriCommandTest.php b/setup/src/Magento/Setup/Test/Unit/Console/Command/InfoAdminUriCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..3c38aae8a914388c93542466ee740966a57c8c82
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Console/Command/InfoAdminUriCommandTest.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Setup\Test\Unit\Console\Command;
+
+use Magento\Setup\Console\Command\InfoAdminUriCommand;
+use Symfony\Component\Console\Tester\CommandTester;
+use Magento\Framework\Setup\BackendFrontnameGenerator;
+
+class InfoAdminUriCommandTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\App\DeploymentConfig|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $deploymentConfig;
+
+    protected function setup()
+    {
+        $this->deploymentConfig = $this->getMock('Magento\Framework\App\DeploymentConfig', [], [], '', false);
+    }
+
+    public function testExecute()
+    {
+        $this->deploymentConfig->expects($this->once())->method('get')->willReturn('admin_qw12er');
+
+        $commandTester = new CommandTester(new InfoAdminUriCommand($this->deploymentConfig));
+        $commandTester->execute([]);
+
+        $regexp = '/' . BackendFrontnameGenerator::ADMIN_AREA_PATH_PREFIX
+            . '[a-z0-9]{1,' . BackendFrontnameGenerator::ADMIN_AREA_PATH_RANDOM_PART_LENGTH .'}/';
+
+        $this->assertRegExp($regexp, $commandTester->getDisplay(), 'Unexpected Backend Frontname pattern.');
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Model/ConfigModelTest.php b/setup/src/Magento/Setup/Test/Unit/Model/ConfigModelTest.php
index 00a756da206f57a32f4315f799f214129bd1b941..66c1c46c8ed6220f2a6605a14a421f2c3a737d1c 100644
--- a/setup/src/Magento/Setup/Test/Unit/Model/ConfigModelTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Model/ConfigModelTest.php
@@ -166,7 +166,7 @@ class ConfigModelTest extends \PHPUnit_Framework_TestCase
 
     /**
      * @expectedException \Exception
-     * @expectedExceptionMessage Missing writing permissions to the following directories: '/a/ro/dir', '/media'
+     * @expectedExceptionMessage Missing write permissions to the following directories: '/a/ro/dir', '/media'
      */
     public function testWritePermissionErrors()
     {
diff --git a/setup/src/Magento/Setup/Test/Unit/Model/InstallerTest.php b/setup/src/Magento/Setup/Test/Unit/Model/InstallerTest.php
index 1028606309a13b89848b4f42d4a6560774278493..295c572b9b55021b4b138333916afce2049abbcf 100644
--- a/setup/src/Magento/Setup/Test/Unit/Model/InstallerTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Model/InstallerTest.php
@@ -272,7 +272,7 @@ class InstallerTest extends \PHPUnit_Framework_TestCase
         $this->logger->expects($this->at(31))->method('log')->with('Current status:');
         $this->logger->expects($this->at(34))->method('log')->with('Disabling Maintenance Mode:');
         $this->logger->expects($this->at(36))->method('log')->with('Post installation file permissions check...');
-        $this->logger->expects($this->once())->method('logSuccess')->with('Magento installation complete.');
+        $this->logger->expects($this->at(38))->method('logSuccess')->with('Magento installation complete.');
         $this->object->install($request);
     }
 
@@ -287,7 +287,7 @@ class InstallerTest extends \PHPUnit_Framework_TestCase
 
     /**
      * @expectedException \Exception
-     * @expectedExceptionMessage Missing writing permissions to the following directories: 'foo' 'bar'
+     * @expectedExceptionMessage Missing write permissions to the following directories: 'foo' 'bar'
      */
     public function testCheckInstallationFilePermissionsError()
     {
diff --git a/setup/src/Magento/Setup/Test/Unit/Module/Di/Compiler/Config/Chain/PreferencesResolvingTest.php b/setup/src/Magento/Setup/Test/Unit/Module/Di/Compiler/Config/Chain/PreferencesResolvingTest.php
index c73ff5109d07ad3047aa7c01cd2cd3dc225a1504..b2e02078082a0865a7a7acfee7fd89e180f667e9 100644
--- a/setup/src/Magento/Setup/Test/Unit/Module/Di/Compiler/Config/Chain/PreferencesResolvingTest.php
+++ b/setup/src/Magento/Setup/Test/Unit/Module/Di/Compiler/Config/Chain/PreferencesResolvingTest.php
@@ -57,6 +57,9 @@ class PreferencesResolvingTest extends \PHPUnit_Framework_TestCase
                 'value_null' => [
                     '_vn_' => true,
                 ],
+                'virtual_preferece' => [
+                    '_i_' => 'Type\DependencyInterface2'
+                ]
             ],
             'ComplexClass' => [
                 'type_dependency_configured' => [
@@ -123,6 +126,9 @@ class PreferencesResolvingTest extends \PHPUnit_Framework_TestCase
                 'value_null' => [
                     '_vn_' => true,
                 ],
+                'virtual_preferece' => [
+                    '_i_' => 'Type\DependencyVirtual3'
+                ]
             ],
             'ComplexClass' => [
                 'type_dependency_configured' => [
@@ -178,6 +184,9 @@ class PreferencesResolvingTest extends \PHPUnit_Framework_TestCase
             'Type\Dependency\ConfiguredInterface' => 'Type\Dependency\Configured',
             'Type\Dependency\Shared\ConfiguredInterface' => 'Type\Dependency\Shared\ConfiguredPreference',
             'Type\Dependency\Shared\Configured' => 'Type\Dependency\Shared\ConfiguredPreference',
+            'Type\DependencyInterface2' => 'Type\DependencyVirtual',
+            'Type\DependencyVirtual' => 'Type\DependencyVirtual2',
+            'Type\DependencyVirtual2' => 'Type\DependencyVirtual3'
         ];
     }
 }
diff --git a/setup/view/magento/setup/success.phtml b/setup/view/magento/setup/success.phtml
index c75cacc1a28516be1606d480a1938a0483f4be91..d24a2492f23956840b0d72389cf9f3d737235684 100644
--- a/setup/view/magento/setup/success.phtml
+++ b/setup/view/magento/setup/success.phtml
@@ -38,6 +38,12 @@
             <a href="{{url.admin}}" target="_blank">{{url.admin}}</a>
         </dd>
 
+        <div class="message message-notice">
+        <span class="message-text">
+            Be sure to bookmark your unique URL and record it offline.
+        </span>
+        </div>
+
         <dt>Encryption Key:</dt>
         <dd>{{config.encrypt.key}}</dd>
     </dl>
diff --git a/setup/view/magento/setup/web-configuration.phtml b/setup/view/magento/setup/web-configuration.phtml
index 282c1068bc34f863eb7d9d5b959c977b92658d9c..d2c15d9426cc08d5a7f7fc64102969467611e63e 100644
--- a/setup/view/magento/setup/web-configuration.phtml
+++ b/setup/view/magento/setup/web-configuration.phtml
@@ -18,6 +18,10 @@ $hints = [
         '<p>%s</p>',
         'Key to encrypt sensitive data such as passwords and personally identifiable customer information in the Magento database. The encryption key is stored in [your Magento install dir]/app/etc/env.php'
     ),
+    'admin' => sprintf(
+        '<p>%s</p>',
+        'A unique URL helps keep store and customer info safer.'
+    )
 ];
 ?>
 
@@ -99,7 +103,12 @@ $hints = [
                         name="admin"
                         ng-model="config.address.admin"
                         ng-class="{'invalid' : webconfig.admin.$invalid && webconfig.submitted }"
+                        ng-init="config.address.admin = '<?php echo $this->autoAdminPath ?>';"
                         required
+                        tooltip-placement="right"
+                        tooltip-html-unsafe="<?php echo $hints['admin']; ?>"
+                        tooltip-trigger="focus"
+                        tooltip-append-to-body="true"
                         >
                     <div class="error-container">
                         <span ng-show="webconfig.admin.$error.required">