diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type/File.php b/app/code/Magento/Catalog/Model/Product/Option/Type/File.php
index 058e6bea09a619b5859de0b3fa6da3f2eff23d33..d89d038144e44b449eaf3430baf382525207da13 100644
--- a/app/code/Magento/Catalog/Model/Product/Option/Type/File.php
+++ b/app/code/Magento/Catalog/Model/Product/Option/Type/File.php
@@ -497,7 +497,6 @@ class File extends \Magento\Catalog\Model\Product\Option\Type\DefaultType
         $sizes = '';
         if (!empty($value['width']) && !empty($value['height']) && $value['width'] > 0 && $value['height'] > 0) {
             $sizes = $value['width'] . ' x ' . $value['height'] . ' ' . __('px.');
-            return [$value, $sizes];
         }
         return $sizes;
     }
diff --git a/app/code/Magento/Catalog/Model/Resource/Eav/Attribute.php b/app/code/Magento/Catalog/Model/Resource/Eav/Attribute.php
index 2d920c212f2c640e73d55c3a8e72974ad2f6bd05..0a0800ce27bcd3617a68ead274a74662adcbf419 100644
--- a/app/code/Magento/Catalog/Model/Resource/Eav/Attribute.php
+++ b/app/code/Magento/Catalog/Model/Resource/Eav/Attribute.php
@@ -784,4 +784,13 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute implements
             return $this;
         }
     }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function afterDelete()
+    {
+        $this->_eavConfig->clear();
+        return parent::afterDelete();
+    }
 }
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Entity/AttributeTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Entity/AttributeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0ecf9b024aa0704ace1dfca1bdca098d9e8a5402
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Entity/AttributeTest.php
@@ -0,0 +1,210 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Catalog\Test\Unit\Model\Entity;
+
+use Magento\Catalog\Model\Entity\Attribute;
+
+/**
+ * @SuppressWarnings(PHPMD.TooManyFields)
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class AttributeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Model\Entity\Attribute
+     */
+    protected $attribute;
+
+    /**
+     * @var \Magento\Framework\Model\Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $contextMock;
+
+    /**
+     * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $registryMock;
+
+    /**
+     * @var \Magento\Framework\Api\MetadataServiceInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $metadataServiceMock;
+
+    /**
+     * @var \Magento\Framework\Api\AttributeValueFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $attributeValueFactoryMock;
+
+    /**
+     * @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $configMock;
+
+    /**
+     * @var \Magento\Eav\Model\Entity\TypeFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $typeFactoryMock;
+
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManagerMock;
+
+    /**
+     * @var \Magento\Eav\Model\Resource\Helper|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $helperMock;
+
+    /**
+     * @var \Magento\Framework\Validator\UniversalFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $universalFactoryMock;
+
+    /**
+     * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $timezoneMock;
+
+    /**
+     * @var \Magento\Catalog\Model\Product\ReservedAttributeList|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $reservedAttributeListMock;
+
+    /**
+     * @var \Magento\Framework\Locale\ResolverInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resolverMock;
+
+    /**
+     * @var \Magento\Catalog\Model\Attribute\LockValidatorInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $lockValidatorMock;
+
+    /**
+     * @var \Magento\Framework\Model\Resource\AbstractResource|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $resourceMock;
+
+    /**
+     * @var \Magento\Framework\App\CacheInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $cacheManager;
+
+    /**
+     * @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $eventDispatcher;
+
+    /**
+     * @var \Magento\Eav\Api\Data\AttributeOptionInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $attributeOptionFactoryMock;
+
+    /**
+     * @var \Magento\Framework\Reflection\DataObjectProcessor|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $dataObjectProcessorMock;
+
+    /**
+     * @var \Magento\Framework\Api\DataObjectHelper|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $dataObjectHelperMock;
+
+    protected function setUp()
+    {
+        $this->contextMock = $this->getMockBuilder('Magento\Framework\Model\Context')
+            ->setMethods(['getCacheManager', 'getEventDispatcher'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->registryMock = $this->getMockBuilder('Magento\Framework\Registry')
+            ->getMock();
+        $this->metadataServiceMock = $this->getMockBuilder('Magento\Framework\Api\MetadataServiceInterface')
+            ->getMock();
+        $this->attributeValueFactoryMock = $this->getMockBuilder('Magento\Framework\Api\AttributeValueFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->configMock = $this->getMockBuilder('Magento\Eav\Model\Config')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->typeFactoryMock = $this->getMockBuilder('Magento\Eav\Model\Entity\TypeFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->storeManagerMock = $this->getMockBuilder('Magento\Store\Model\StoreManagerInterface')
+            ->getMock();
+        $this->helperMock = $this->getMockBuilder('Magento\Eav\Model\Resource\Helper')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->universalFactoryMock = $this->getMockBuilder('Magento\Framework\Validator\UniversalFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->attributeOptionFactoryMock =
+            $this->getMockBuilder('Magento\Eav\Api\Data\AttributeOptionInterfaceFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->dataObjectProcessorMock = $this->getMockBuilder('Magento\Framework\Reflection\DataObjectProcessor')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->dataObjectHelperMock = $this->getMockBuilder('Magento\Framework\Api\DataObjectHelper')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->timezoneMock = $this->getMockBuilder('Magento\Framework\Stdlib\DateTime\TimezoneInterface')
+            ->getMock();
+        $this->reservedAttributeListMock = $this->getMockBuilder('Magento\Catalog\Model\Product\ReservedAttributeList')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resolverMock = $this->getMockBuilder('Magento\Framework\Locale\ResolverInterface')
+            ->getMock();
+        $this->lockValidatorMock = $this->getMockBuilder('Magento\Catalog\Model\Attribute\LockValidatorInterface')
+            ->getMock();
+
+        $this->resourceMock = $this->getMockBuilder('Magento\Framework\Model\Resource\AbstractResource')
+            ->setMethods(['_construct', '_getReadAdapter', '_getWriteAdapter', 'getIdFieldName', 'saveInSetIncluding'])
+            ->getMock();
+        $this->cacheManager = $this->getMockBuilder('Magento\Framework\App\CacheInterface')
+            ->getMock();
+        $this->eventDispatcher = $this->getMockBuilder('Magento\Framework\Event\ManagerInterface')
+            ->getMock();
+
+        $this->contextMock
+            ->expects($this->any())
+            ->method('getCacheManager')
+            ->willReturn($this->cacheManager);
+        $this->contextMock
+            ->expects($this->any())
+            ->method('getEventDispatcher')
+            ->willReturn($this->eventDispatcher);
+
+        $this->attribute = new Attribute(
+            $this->contextMock,
+            $this->registryMock,
+            $this->metadataServiceMock,
+            $this->attributeValueFactoryMock,
+            $this->configMock,
+            $this->typeFactoryMock,
+            $this->storeManagerMock,
+            $this->helperMock,
+            $this->universalFactoryMock,
+            $this->attributeOptionFactoryMock,
+            $this->dataObjectProcessorMock,
+            $this->dataObjectHelperMock,
+            $this->timezoneMock,
+            $this->reservedAttributeListMock,
+            $this->resolverMock,
+            $this->lockValidatorMock,
+            $this->resourceMock
+        );
+    }
+
+    public function testAfterSaveEavCache()
+    {
+        $this->configMock
+            ->expects($this->once())
+            ->method('clear');
+
+        $this->attribute->afterSave();
+    }
+}
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Resource/Eav/AttributeTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Resource/Eav/AttributeTest.php
index 7c4a802f0ea9b3e581691a371b812267eac6777a..30d400ca8ef2a7317ae56287e729b7e8feb1ec85 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Resource/Eav/AttributeTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Resource/Eav/AttributeTest.php
@@ -37,6 +37,11 @@ class AttributeTest extends \PHPUnit_Framework_TestCase
      */
     protected $resourceMock;
 
+    /**
+     * @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $eavConfigMock;
+
     public function setUp()
     {
         $this->_processor = $this->getMock(
@@ -89,6 +94,11 @@ class AttributeTest extends \PHPUnit_Framework_TestCase
             [], '', false
         );
 
+        $this->eavConfigMock = $this->getMockBuilder('Magento\Eav\Model\Config')
+            ->setMethods(['clear'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
         $this->resourceMock->expects($this->any())
             ->method('_getWriteAdapter')
             ->will($this->returnValue($dbAdapterMock));
@@ -101,7 +111,8 @@ class AttributeTest extends \PHPUnit_Framework_TestCase
                     'productFlatIndexerProcessor' => $this->_processor,
                     'indexerEavProcessor' => $this->_eavProcessor,
                     'resource' => $this->resourceMock,
-                    'data' => ['id' => 1]
+                    'data' => ['id' => 1],
+                    'eavConfig' => $this->eavConfigMock
                 ]
         );
     }
@@ -125,6 +136,14 @@ class AttributeTest extends \PHPUnit_Framework_TestCase
         $this->_model->afterSave();
     }
 
+    public function testAfterSaveEavCache()
+    {
+        $this->eavConfigMock
+            ->expects($this->once())
+            ->method('clear');
+        $this->_model->afterSave();
+    }
+
     public function testIndexerAfterDeleteAttribute()
     {
         $this->_processor->expects($this->once())->method('markIndexerAsInvalid');
@@ -133,6 +152,14 @@ class AttributeTest extends \PHPUnit_Framework_TestCase
         $this->_model->afterDeleteCommit();
     }
 
+    public function testAfterDeleteEavCache()
+    {
+        $this->eavConfigMock
+            ->expects($this->once())
+            ->method('clear');
+        $this->_model->afterDelete();
+    }
+
     public function testGetScopeGlobal()
     {
         $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
diff --git a/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js b/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js
index 74e1566a8dc5ba6f4691574491bbb6b7b65dcc43..faf107ba5487008c6652a589ae45f10571d235db 100644
--- a/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js
+++ b/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js
@@ -38,6 +38,16 @@ define([
         },
 
         submitForm: function(form) {
+            var self = this;
+            if (form.has('input[type="file"]').length) {
+                self.element.off('submit');
+                form.submit();
+            } else {
+                self.ajaxSubmit(form);
+            }
+        },
+
+        ajaxSubmit: function(form) {
             var self = this;
             $.ajax({
                 url: form.attr('action'),
diff --git a/app/code/Magento/Customer/Model/Customer.php b/app/code/Magento/Customer/Model/Customer.php
index cb0e6f90dc16b29fbf8b0eac2641dcdc346ce61f..49917e246c52a0f90991a8d4e5c27897a9ee9f04 100644
--- a/app/code/Magento/Customer/Model/Customer.php
+++ b/app/code/Magento/Customer/Model/Customer.php
@@ -159,11 +159,6 @@ class Customer extends \Magento\Framework\Model\AbstractExtensibleModel
      */
     protected $_transportBuilder;
 
-    /**
-     * @var AttributeFactory
-     */
-    protected $_attributeFactory;
-
     /**
      * @var GroupRepositoryInterface
      */
@@ -237,7 +232,6 @@ class Customer extends \Magento\Framework\Model\AbstractExtensibleModel
         \Magento\Customer\Model\Resource\Address\CollectionFactory $addressesFactory,
         \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder,
         GroupRepositoryInterface $groupRepository,
-        AttributeFactory $attributeFactory,
         \Magento\Framework\Encryption\EncryptorInterface $encryptor,
         \Magento\Framework\Stdlib\DateTime $dateTime,
         CustomerInterfaceFactory $customerDataFactory,
@@ -254,7 +248,6 @@ class Customer extends \Magento\Framework\Model\AbstractExtensibleModel
         $this->_addressesFactory = $addressesFactory;
         $this->_transportBuilder = $transportBuilder;
         $this->_groupRepository = $groupRepository;
-        $this->_attributeFactory = $attributeFactory;
         $this->_encryptor = $encryptor;
         $this->dateTime = $dateTime;
         $this->customerDataFactory = $customerDataFactory;
@@ -1015,18 +1008,15 @@ class Customer extends \Magento\Framework\Model\AbstractExtensibleModel
         }
 
         $entityType = $this->_config->getEntityType('customer');
-        $attribute = $this->_createCustomerAttribute();
-        $attribute->loadByCode($entityType, 'dob');
+        $attribute = $this->_config->getAttribute($entityType, 'dob');
         if ($attribute->getIsRequired() && '' == trim($this->getDob())) {
             $errors[] = __('The Date of Birth is required.');
         }
-        $attribute = $this->_createCustomerAttribute();
-        $attribute->loadByCode($entityType, 'taxvat');
+        $attribute = $this->_config->getAttribute($entityType, 'taxvat');
         if ($attribute->getIsRequired() && '' == trim($this->getTaxvat())) {
             $errors[] = __('The TAX/VAT number is required.');
         }
-        $attribute = $this->_createCustomerAttribute();
-        $attribute->loadByCode($entityType, 'gender');
+        $attribute = $this->_config->getAttribute($entityType, 'gender');
         if ($attribute->getIsRequired() && '' == trim($this->getGender())) {
             $errors[] = __('Gender is required.');
         }
@@ -1321,14 +1311,6 @@ class Customer extends \Magento\Framework\Model\AbstractExtensibleModel
         return $this->_addressesFactory->create();
     }
 
-    /**
-     * @return \Magento\Customer\Model\Attribute
-     */
-    protected function _createCustomerAttribute()
-    {
-        return $this->_attributeFactory->create();
-    }
-
     /**
      * @return array
      */
diff --git a/app/code/Magento/Customer/Test/Unit/Model/AttributeTest.php b/app/code/Magento/Customer/Test/Unit/Model/AttributeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..aed47c9e45898f0b9e4ea6dc6877c06c87f92d1f
--- /dev/null
+++ b/app/code/Magento/Customer/Test/Unit/Model/AttributeTest.php
@@ -0,0 +1,210 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Customer\Test\Unit\Model;
+
+use Magento\Customer\Model\Attribute;
+
+/**
+ * @SuppressWarnings(PHPMD.TooManyFields)
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class AttributeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Customer\Model\Attribute
+     */
+    protected $attribute;
+
+    /**
+     * @var \Magento\Framework\Model\Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $contextMock;
+
+    /**
+     * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $registryMock;
+
+    /**
+     * @var \Magento\Framework\Api\MetadataServiceInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $metadataServiceMock;
+
+    /**
+     * @var \Magento\Framework\Api\AttributeValueFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $attributeValueFactoryMock;
+
+    /**
+     * @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $configMock;
+
+    /**
+     * @var \Magento\Eav\Model\Entity\TypeFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $typeFactoryMock;
+
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManagerMock;
+
+    /**
+     * @var \Magento\Eav\Model\Resource\Helper|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $helperMock;
+
+    /**
+     * @var \Magento\Framework\Validator\UniversalFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $universalFactoryMock;
+
+    /**
+     * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $timezoneMock;
+
+    /**
+     * @var \Magento\Framework\Model\Resource\AbstractResource|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $resourceMock;
+
+    /**
+     * @var \Magento\Catalog\Model\Product\ReservedAttributeList|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $reservedAttributeListMock;
+
+    /**
+     * @var \Magento\Framework\Locale\ResolverInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resolverMock;
+
+    /**
+     * @var \Magento\Framework\App\CacheInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $cacheManager;
+
+    /**
+     * @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $eventDispatcher;
+
+    /**
+     * @var \Magento\Eav\Api\Data\AttributeOptionInterfaceFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $attributeOptionFactoryMock;
+
+    /**
+     * @var \Magento\Framework\Reflection\DataObjectProcessor|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $dataObjectProcessorMock;
+
+    /**
+     * @var \Magento\Framework\Api\DataObjectHelper|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $dataObjectHelperMock;
+
+    protected function setUp()
+    {
+        $this->contextMock = $this->getMockBuilder('Magento\Framework\Model\Context')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->registryMock = $this->getMockBuilder('Magento\Framework\Registry')
+            ->getMock();
+        $this->metadataServiceMock = $this->getMockBuilder('Magento\Framework\Api\MetadataServiceInterface')
+            ->getMock();
+        $this->attributeValueFactoryMock = $this->getMockBuilder('Magento\Framework\Api\AttributeValueFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->configMock = $this->getMockBuilder('Magento\Eav\Model\Config')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->typeFactoryMock = $this->getMockBuilder('Magento\Eav\Model\Entity\TypeFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->storeManagerMock = $this->getMockBuilder('Magento\Store\Model\StoreManagerInterface')
+            ->getMock();
+        $this->helperMock = $this->getMockBuilder('Magento\Eav\Model\Resource\Helper')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->universalFactoryMock = $this->getMockBuilder('Magento\Framework\Validator\UniversalFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->attributeOptionFactoryMock =
+            $this->getMockBuilder('Magento\Eav\Api\Data\AttributeOptionInterfaceFactory')
+                ->disableOriginalConstructor()
+                ->getMock();
+        $this->dataObjectProcessorMock = $this->getMockBuilder('Magento\Framework\Reflection\DataObjectProcessor')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->dataObjectHelperMock = $this->getMockBuilder('Magento\Framework\Api\DataObjectHelper')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->timezoneMock = $this->getMockBuilder('Magento\Framework\Stdlib\DateTime\TimezoneInterface')
+            ->getMock();
+        $this->reservedAttributeListMock = $this->getMockBuilder('Magento\Catalog\Model\Product\ReservedAttributeList')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resolverMock = $this->getMockBuilder('Magento\Framework\Locale\ResolverInterface')
+            ->getMock();
+
+        $this->resourceMock = $this->getMockBuilder('Magento\Framework\Model\Resource\AbstractResource')
+            ->setMethods(['_construct', '_getReadAdapter', '_getWriteAdapter', 'getIdFieldName', 'saveInSetIncluding'])
+            ->getMock();
+        $this->cacheManager = $this->getMockBuilder('Magento\Framework\App\CacheInterface')
+            ->getMock();
+        $this->eventDispatcher = $this->getMockBuilder('Magento\Framework\Event\ManagerInterface')
+            ->getMock();
+
+        $this->contextMock
+            ->expects($this->any())
+            ->method('getCacheManager')
+            ->willReturn($this->cacheManager);
+        $this->contextMock
+            ->expects($this->any())
+            ->method('getEventDispatcher')
+            ->willReturn($this->eventDispatcher);
+
+        $this->attribute = new Attribute(
+            $this->contextMock,
+            $this->registryMock,
+            $this->metadataServiceMock,
+            $this->attributeValueFactoryMock,
+            $this->configMock,
+            $this->typeFactoryMock,
+            $this->storeManagerMock,
+            $this->helperMock,
+            $this->universalFactoryMock,
+            $this->attributeOptionFactoryMock,
+            $this->dataObjectProcessorMock,
+            $this->dataObjectHelperMock,
+            $this->timezoneMock,
+            $this->reservedAttributeListMock,
+            $this->resolverMock,
+            $this->resourceMock
+        );
+    }
+
+    public function testAfterSaveEavCache()
+    {
+        $this->configMock
+            ->expects($this->once())
+            ->method('clear');
+
+        $this->attribute->afterSave();
+    }
+
+    public function testAfterDeleteEavCache()
+    {
+        $this->configMock
+            ->expects($this->once())
+            ->method('clear');
+
+        $this->attribute->afterDelete();
+    }
+}
diff --git a/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php b/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php
index 9461432d15cf1ba38b99a0e9e05f985ef93c096e..5f91793ec706725c0ce7b0123a5479408623571d 100644
--- a/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Model/CustomerTest.php
@@ -143,12 +143,9 @@ class CustomerTest extends \PHPUnit_Framework_TestCase
      */
     public function testValidate($data, $expected)
     {
-        $this->attributeFactoryMock->expects($this->exactly(3))
-            ->method('create')
+        $this->_config->expects($this->exactly(3))
+            ->method('getAttribute')
             ->will($this->returnValue($this->attributeCustomerMock));
-        $this->attributeCustomerMock->expects($this->exactly(3))
-            ->method('loadByCode')
-            ->will($this->returnSelf());
         $this->attributeCustomerMock->expects($this->exactly(3))
             ->method('getIsRequired')
             ->will($this->returnValue(true));
diff --git a/app/code/Magento/Eav/Model/Attribute.php b/app/code/Magento/Eav/Model/Attribute.php
index d6a034e9bbebb4d7ff5629f257cdde3e27df70c8..7cde5a2bb7797a6c6f01a63a3a8e4fe34a27669d 100644
--- a/app/code/Magento/Eav/Model/Attribute.php
+++ b/app/code/Magento/Eav/Model/Attribute.php
@@ -179,4 +179,13 @@ abstract class Attribute extends \Magento\Eav\Model\Entity\Attribute
     {
         return $this->_getScopeValue('multiline_count');
     }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function afterDelete()
+    {
+        $this->_eavConfig->clear();
+        return parent::afterDelete();
+    }
 }
diff --git a/app/code/Magento/Eav/Model/Config.php b/app/code/Magento/Eav/Model/Config.php
index 0b19787babb92c03a525f62cee9931cec188cbac..90c6560658f09b01ee0cd9d41b3085db0280e1d7 100644
--- a/app/code/Magento/Eav/Model/Config.php
+++ b/app/code/Magento/Eav/Model/Config.php
@@ -69,13 +69,6 @@ class Config
      */
     protected $_isCacheEnabled = null;
 
-    /**
-     * Array of attributes objects used in collections
-     *
-     * @var array
-     */
-    protected $_collectionAttributes = [];
-
     /**
      * @var \Magento\Framework\App\CacheInterface
      */
@@ -120,6 +113,16 @@ class Config
         $this->_universalFactory = $universalFactory;
     }
 
+    /**
+     * Get cache interface
+     *
+     * @return \Magento\Framework\App\CacheInterface
+     */
+    public function getCache()
+    {
+        return $this->_cache;
+    }
+
     /**
      * Reset object state
      *
@@ -246,7 +249,7 @@ class Config
      *
      * @return bool
      */
-    protected function _isCacheEnabled()
+    public function isCacheEnabled()
     {
         if ($this->_isCacheEnabled === null) {
             $this->_isCacheEnabled = $this->_cacheState->isEnabled(\Magento\Eav\Model\Cache\Type::TYPE_IDENTIFIER);
@@ -266,7 +269,7 @@ class Config
         }
         \Magento\Framework\Profiler::start('EAV: ' . __METHOD__, ['group' => 'EAV', 'method' => __METHOD__]);
 
-        if ($this->_isCacheEnabled() && ($cache = $this->_cache->load(self::ENTITIES_CACHE_ID))) {
+        if ($this->isCacheEnabled() && ($cache = $this->_cache->load(self::ENTITIES_CACHE_ID))) {
             $this->_entityTypeData = unserialize($cache);
             foreach ($this->_entityTypeData as $typeCode => $data) {
                 $typeId = $data['entity_type_id'];
@@ -289,7 +292,7 @@ class Config
             $this->_entityTypeData[$typeCode] = $typeData;
         }
 
-        if ($this->_isCacheEnabled()) {
+        if ($this->isCacheEnabled()) {
             $this->_cache->save(
                 serialize($this->_entityTypeData),
                 self::ENTITIES_CACHE_ID,
@@ -306,7 +309,7 @@ class Config
     /**
      * Get entity type object by entity type code/identifier
      *
-     * @param int|string $code
+     * @param int|string|Type $code
      * @return Type
      * @throws \Magento\Framework\Exception\LocalizedException
      */
@@ -360,7 +363,7 @@ class Config
             return $this;
         }
         $cacheKey = self::ATTRIBUTES_CACHE_ID . $entityTypeCode;
-        if ($this->_isCacheEnabled() && ($attributes = $this->_cache->load($cacheKey))) {
+        if ($this->isCacheEnabled() && ($attributes = $this->_cache->load($cacheKey))) {
             $attributes = unserialize($attributes);
             if ($attributes) {
                 foreach ($attributes as $attribute) {
@@ -383,10 +386,13 @@ class Config
             if (empty($attribute['attribute_model'])) {
                 $attribute['attribute_model'] = $entityType->getAttributeModel();
             }
-            $this->_createAttribute($entityType, $attribute);
-            $this->_attributeData[$entityTypeCode][$attribute['attribute_code']] = $attribute;
+            // attributes should be reloaded via model to be processed by custom resource model
+            $attributeObject = $this->_createAttribute($entityType, $attribute);
+            $this->_attributeData[$entityTypeCode][$attribute['attribute_code']] = $attributeObject->load(
+                $attributeObject->getId()
+            )->toArray();
         }
-        if ($this->_isCacheEnabled()) {
+        if ($this->isCacheEnabled()) {
             $this->_cache->save(
                 serialize($this->_attributeData[$entityTypeCode]),
                 $cacheKey,
@@ -430,6 +436,7 @@ class Config
         if (!$attribute) {
             // TODO: refactor wrong method usage in: addAttributeToSelect, joinAttribute
             $entityType = $this->getEntityType($entityType);
+            /** @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute $attribute */
             $attribute = $this->_universalFactory->create($entityType->getAttributeModel());
             $attribute->setAttributeCode($code);
             $entity = $entityType->getEntity();
@@ -470,7 +477,7 @@ class Config
             return $this->_attributeCodes[$cacheKey];
         }
 
-        if ($this->_isCacheEnabled() && ($attributes = $this->_cache->load($cacheKey))) {
+        if ($this->isCacheEnabled() && ($attributes = $this->_cache->load($cacheKey))) {
             $this->_attributeCodes[$cacheKey] = unserialize($attributes);
             return $this->_attributeCodes[$cacheKey];
         }
@@ -496,7 +503,7 @@ class Config
         }
 
         $this->_attributeCodes[$cacheKey] = $attributes;
-        if ($this->_isCacheEnabled()) {
+        if ($this->isCacheEnabled()) {
             $this->_cache->save(
                 serialize($attributes),
                 $cacheKey,
@@ -510,82 +517,6 @@ class Config
         return $attributes;
     }
 
-    /**
-     * Get attribute object for colection usage
-     *
-     * @param   mixed $entityType
-     * @param   string $attribute
-     * @return  \Magento\Eav\Model\Entity\Attribute\AbstractAttribute|null
-     */
-    public function getCollectionAttribute($entityType, $attribute)
-    {
-        $entityType = $this->getEntityType($entityType);
-        $entityTypeCode = $entityType->getEntityTypeCode();
-
-        if (is_numeric($attribute)) {
-            $attribute = $this->_getAttributeReference($attribute, $entityTypeCode);
-            if (!$attribute) {
-                return null;
-            }
-        }
-
-        $attributeKey = $this->_getAttributeKey($entityTypeCode, $attribute);
-        $attributeObject = $this->_load($attributeKey);
-        if ($attributeObject) {
-            return $attributeObject;
-        }
-
-        return $this->getAttribute($entityType, $attribute);
-    }
-
-    /**
-     * Prepare attributes for usage in EAV collection
-     *
-     * @param   mixed $entityType
-     * @param   array $attributes
-     * @return $this
-     */
-    public function loadCollectionAttributes($entityType, $attributes)
-    {
-        $entityType = $this->getEntityType($entityType);
-        $entityTypeCode = $entityType->getEntityTypeCode();
-
-        if (!isset($this->_collectionAttributes[$entityTypeCode])) {
-            $this->_collectionAttributes[$entityTypeCode] = [];
-        }
-        $loadedAttributes = array_keys($this->_collectionAttributes[$entityTypeCode]);
-        $attributes = array_diff($attributes, $loadedAttributes);
-
-        foreach ($attributes as $k => $attribute) {
-            if (is_numeric($attribute)) {
-                $attribute = $this->_getAttributeReference($attribute, $entityTypeCode);
-            }
-            $attributeKey = $this->_getAttributeKey($entityTypeCode, $attribute);
-            if ($this->_load($attributeKey)) {
-                unset($attributes[$k]);
-            }
-        }
-
-        if (empty($attributes)) {
-            return $this;
-        }
-        $attributeCollection = $entityType->getEntityAttributeCollection();
-        $attributesInfo = $this->_universalFactory->create(
-            $attributeCollection
-        )->useLoadDataFields()->setEntityTypeFilter(
-            $entityType
-        )->setCodeFilter(
-            $attributes
-        )->getData();
-
-        foreach ($attributesInfo as $attributeData) {
-            $attribute = $this->_createAttribute($entityType, $attributeData);
-            $this->_collectionAttributes[$entityTypeCode][$attribute->getAttributeCode()] = $attribute;
-        }
-
-        return $this;
-    }
-
     /**
      * Create attribute from attribute data array
      *
@@ -614,6 +545,7 @@ class Config
         } else {
             $model = $entityType->getAttributeModel();
         }
+        /** @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute $attribute */
         $attribute = $this->_universalFactory->create($model)->setData($attributeData);
         $this->_addAttributeReference(
             $attributeData['attribute_id'],
diff --git a/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php b/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php
index 7f2680769a2dc29da58ca9340a32a93f5fd26a89..6cd6cf0e6d018dc745d1d4f66a73581ae593a915 100644
--- a/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php
+++ b/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php
@@ -454,7 +454,6 @@ abstract class AbstractCollection extends \Magento\Framework\Data\Collection\Db
     public function addAttributeToSelect($attribute, $joinType = false)
     {
         if (is_array($attribute)) {
-            $this->_eavConfig->loadCollectionAttributes($this->getEntity()->getType(), $attribute);
             foreach ($attribute as $a) {
                 $this->addAttributeToSelect($a, $joinType);
             }
@@ -472,7 +471,7 @@ abstract class AbstractCollection extends \Magento\Framework\Data\Collection\Db
             if (isset($this->_joinAttributes[$attribute])) {
                 $attrInstance = $this->_joinAttributes[$attribute]['attribute'];
             } else {
-                $attrInstance = $this->_eavConfig->getCollectionAttribute($this->getEntity()->getType(), $attribute);
+                $attrInstance = $this->_eavConfig->getAttribute($this->getEntity()->getType(), $attribute);
             }
             if (empty($attrInstance)) {
                 throw new EavException(__('Invalid attribute requested: %1', (string)$attribute));
@@ -1121,7 +1120,7 @@ abstract class AbstractCollection extends \Magento\Framework\Data\Collection\Db
             if (!$attributeId) {
                 continue;
             }
-            $attribute = $this->_eavConfig->getCollectionAttribute($entity->getType(), $attributeCode);
+            $attribute = $this->_eavConfig->getAttribute($entity->getType(), $attributeCode);
             if ($attribute && !$attribute->isStatic()) {
                 $tableAttributes[$attribute->getBackendTable()][] = $attributeId;
                 if (!isset($attributeTypes[$attribute->getBackendTable()])) {
@@ -1226,7 +1225,7 @@ abstract class AbstractCollection extends \Magento\Framework\Data\Collection\Db
         }
         $attributeCode = array_search($valueInfo['attribute_id'], $this->_selectAttributes);
         if (!$attributeCode) {
-            $attribute = $this->_eavConfig->getCollectionAttribute(
+            $attribute = $this->_eavConfig->getAttribute(
                 $this->getEntity()->getType(),
                 $valueInfo['attribute_id']
             );
diff --git a/app/code/Magento/Eav/Model/Resource/Entity/Attribute/Set.php b/app/code/Magento/Eav/Model/Resource/Entity/Attribute/Set.php
index 2dab1d5aae67cc30486212bf696da19a7a95075f..0c083a7d88c9ca12325e9bca91d3ab870debac6f 100644
--- a/app/code/Magento/Eav/Model/Resource/Entity/Attribute/Set.php
+++ b/app/code/Magento/Eav/Model/Resource/Entity/Attribute/Set.php
@@ -12,6 +12,11 @@ namespace Magento\Eav\Model\Resource\Entity\Attribute;
  */
 class Set extends \Magento\Framework\Model\Resource\Db\AbstractDb
 {
+    /**
+     * EAV cache ids
+     */
+    const ATTRIBUTES_CACHE_ID = 'EAV_ENTITY_ATTRIBUTES_BY_SET_ID';
+
     /**
      * @var \Magento\Eav\Model\Resource\Entity\Attribute\GroupFactory
      */
@@ -140,43 +145,38 @@ class Set extends \Magento\Framework\Model\Resource\Db\AbstractDb
      */
     public function getSetInfo(array $attributeIds, $setId = null)
     {
-        $adapter = $this->_getReadAdapter();
-        $setInfo = [];
-        $attributeToSetInfo = [];
-
-        if (count($attributeIds) > 0) {
-            $select = $adapter->select()->from(
-                ['entity' => $this->getTable('eav_entity_attribute')],
-                ['attribute_id', 'attribute_set_id', 'attribute_group_id', 'sort_order']
-            )->joinLeft(
-                ['attribute_group' => $this->getTable('eav_attribute_group')],
-                'entity.attribute_group_id = attribute_group.attribute_group_id',
-                ['group_sort_order' => 'sort_order']
-            )->where(
-                'entity.attribute_id IN (?)',
-                $attributeIds
-            );
-            $bind = [];
-            if (is_numeric($setId)) {
-                $bind[':attribute_set_id'] = $setId;
-                $select->where('entity.attribute_set_id = :attribute_set_id');
-            }
-            $result = $adapter->fetchAll($select, $bind);
+        $cacheKey = self::ATTRIBUTES_CACHE_ID . $setId;
 
-            foreach ($result as $row) {
+        if ($this->eavConfig->isCacheEnabled() && ($cache = $this->eavConfig->getCache()->load($cacheKey))) {
+            $setInfoData = unserialize($cache);
+        } else {
+            $attributeSetData = $this->fetchAttributeSetData($setId);
+
+            $setInfoData = [];
+            foreach ($attributeSetData as $row) {
                 $data = [
                     'group_id' => $row['attribute_group_id'],
                     'group_sort' => $row['group_sort_order'],
                     'sort' => $row['sort_order'],
                 ];
-                $attributeToSetInfo[$row['attribute_id']][$row['attribute_set_id']] = $data;
+                $setInfoData[$row['attribute_id']][$row['attribute_set_id']] = $data;
+            }
+
+            if ($this->eavConfig->isCacheEnabled()) {
+                $this->eavConfig->getCache()->save(
+                    serialize($setInfoData),
+                    $cacheKey,
+                    [
+                        \Magento\Eav\Model\Cache\Type::CACHE_TAG,
+                        \Magento\Eav\Model\Entity\Attribute::CACHE_TAG
+                    ]
+                );
             }
         }
 
-        foreach ($attributeIds as $atttibuteId) {
-            $setInfo[$atttibuteId] = isset(
-                $attributeToSetInfo[$atttibuteId]
-            ) ? $attributeToSetInfo[$atttibuteId] : [];
+        $setInfo = [];
+        foreach ($attributeIds as $attributeId) {
+            $setInfo[$attributeId] = isset($setInfoData[$attributeId]) ? $setInfoData[$attributeId] : [];
         }
 
         return $setInfo;
@@ -204,4 +204,29 @@ class Set extends \Magento\Framework\Model\Resource\Db\AbstractDb
         );
         return $adapter->fetchOne($select, $bind);
     }
+
+    /**
+     * Returns data from eav_entity_attribute table for given $setId (or all if $setId is null)
+     *
+     * @param int $setId
+     * @return array
+     */
+    protected function fetchAttributeSetData($setId = null)
+    {
+        $adapter = $this->_getReadAdapter();
+        $select = $adapter->select()->from(
+            ['entity' => $this->getTable('eav_entity_attribute')],
+            ['attribute_id', 'attribute_set_id', 'attribute_group_id', 'sort_order']
+        )->joinLeft(
+            ['attribute_group' => $this->getTable('eav_attribute_group')],
+            'entity.attribute_group_id = attribute_group.attribute_group_id',
+            ['group_sort_order' => 'sort_order']
+        );
+        $bind = [];
+        if (is_numeric($setId)) {
+            $bind[':attribute_set_id'] = $setId;
+            $select->where('entity.attribute_set_id = :attribute_set_id');
+        }
+        return $adapter->fetchAll($select, $bind);
+    }
 }
diff --git a/app/code/Magento/Eav/Test/Unit/Model/ConfigTest.php b/app/code/Magento/Eav/Test/Unit/Model/ConfigTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e9d0fdc69cb0148ee5d5b412533564e40ad8fdc7
--- /dev/null
+++ b/app/code/Magento/Eav/Test/Unit/Model/ConfigTest.php
@@ -0,0 +1,194 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Eav\Test\Unit\Model;
+
+use Magento\Framework\Object;
+use Magento\Eav\Model\Config;
+
+class ConfigTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Eav\Model\Config
+     */
+    protected $config;
+
+    /**
+     * @var \Magento\Framework\App\CacheInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $cacheMock;
+
+    /**
+     * @var \Magento\Eav\Model\Entity\TypeFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $typeFactoryMock;
+
+    /**
+     * @var \Magento\Eav\Model\Resource\Entity\Type\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $collectionFactoryMock;
+
+    /**
+     * @var \Magento\Framework\App\Cache\StateInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $stateMock;
+
+    /**
+     * @var \Magento\Framework\Validator\UniversalFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $universalFactoryMock;
+
+    protected function setUp()
+    {
+        $this->cacheMock = $this->getMockBuilder('Magento\Framework\App\CacheInterface')
+            ->disableOriginalConstructor()
+            ->setMethods(['load', 'getFrontend', 'save', 'remove', 'clean'])
+            ->getMock();
+        $this->typeFactoryMock = $this->getMockBuilder('Magento\Eav\Model\Entity\TypeFactory')
+            ->setMethods(['create'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->collectionFactoryMock = $this->getMockBuilder('Magento\Eav\Model\Resource\Entity\Type\CollectionFactory')
+            ->setMethods(['create'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->stateMock = $this->getMockBuilder('Magento\Framework\App\Cache\StateInterface')
+            ->setMethods(['isEnabled', 'setEnabled', 'persist'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->universalFactoryMock = $this->getMockBuilder('Magento\Framework\Validator\UniversalFactory')
+            ->setMethods(['create'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->config = new Config(
+            $this->cacheMock,
+            $this->typeFactoryMock,
+            $this->collectionFactoryMock,
+            $this->stateMock,
+            $this->universalFactoryMock
+        );
+    }
+
+    /**
+     * @param boolean $cacheEnabled
+     * @param int $loadCalls
+     * @param string $cachedValue
+     * @param array $factoryCalls
+     * @dataProvider getAttributeCacheDataProvider
+     * @return void
+     */
+    public function testGetAttributeCache($cacheEnabled, $loadCalls, $cachedValue, $factoryCalls)
+    {
+        $this->stateMock
+            ->expects($this->atLeastOnce())
+            ->method('isEnabled')
+            ->with(\Magento\Eav\Model\Cache\Type::TYPE_IDENTIFIER)
+            ->willReturn($cacheEnabled);
+        $this->cacheMock
+            ->expects($this->exactly($loadCalls))
+            ->method('load')
+            ->with(Config::ATTRIBUTES_CACHE_ID)
+            ->willReturn($cachedValue);
+
+        $collectionStub = new Object([
+            ['entity_type_code' => 'type_code_1', 'entity_type_id' => 1]
+        ]);
+        $this->collectionFactoryMock
+            ->expects($this->any())
+            ->method('create')
+            ->willReturn($collectionStub);
+
+        $this->typeFactoryMock
+            ->expects($this->any())
+            ->method('create')
+            ->willReturn(new Object(['id' => 101]));
+
+        $this->universalFactoryMock
+            ->expects($this->exactly(count($factoryCalls)))
+            ->method('create')
+            ->will($this->returnValueMap($factoryCalls));
+
+        $entityType = $this->getMockBuilder('\Magento\Eav\Model\Entity\Type')
+            ->setMethods(['getEntity'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->config->getAttribute($entityType, 'attribute_code_1');
+    }
+
+    /**
+     * @return array
+     */
+    public function getAttributeCacheDataProvider()
+    {
+        $attributeCollectionMock = $this->getMockBuilder('Magento\Eav\Model\Resource\Entity\Attribute\Collection')
+            ->disableOriginalConstructor()
+            ->setMethods(['getData', 'setEntityTypeFilter'])
+            ->getMock();
+        $attributeCollectionMock
+            ->expects($this->any())
+            ->method('setEntityTypeFilter')
+            ->will($this->returnSelf());
+        $attributeCollectionMock
+            ->expects($this->any())
+            ->method('getData')
+            ->willReturn([]);
+        $entityAttributeMock = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute')
+            ->setMethods(['dummy'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        return [
+            'cache-disabled' => [
+                false,
+                0,
+                false,
+                [
+                    ['Magento\Eav\Model\Resource\Entity\Attribute\Collection', [], $attributeCollectionMock],
+                    ['Magento\Eav\Model\Entity\Attribute', [], $entityAttributeMock]
+                ]
+            ],
+            'cache-miss' => [
+                true,
+                1,
+                false,
+                [
+                    ['Magento\Eav\Model\Resource\Entity\Attribute\Collection', [], $attributeCollectionMock],
+                    ['Magento\Eav\Model\Entity\Attribute', [], $entityAttributeMock]
+                ]
+            ],
+            'cached' => [
+                true,
+                1,
+                serialize(
+                    [
+                        ['attribute_code' => 'attribute_code_1', 'attribute_id' => 1]
+                    ]
+                ),
+                [
+                    ['Magento\Eav\Model\Entity\Attribute', [], $entityAttributeMock]
+                ]
+            ]
+        ];
+    }
+
+    public function testClear()
+    {
+        $this->cacheMock
+            ->expects($this->once())
+            ->method('clean')
+            ->with(
+                $this->equalTo(
+                    [
+                        \Magento\Eav\Model\Cache\Type::CACHE_TAG,
+                        \Magento\Eav\Model\Entity\Attribute::CACHE_TAG
+                    ]
+                )
+            );
+        $this->config->clear();
+    }
+}
diff --git a/app/code/Magento/Eav/Test/Unit/Model/Resource/Entity/Attribute/SetTest.php b/app/code/Magento/Eav/Test/Unit/Model/Resource/Entity/Attribute/SetTest.php
index 47c87ff760354073d3df6893aff4e9f671d54a12..bb02ce4be05e5386c08224f321a42cc928328e26 100644
--- a/app/code/Magento/Eav/Test/Unit/Model/Resource/Entity/Attribute/SetTest.php
+++ b/app/code/Magento/Eav/Test/Unit/Model/Resource/Entity/Attribute/SetTest.php
@@ -6,11 +6,13 @@
  */
 
 namespace Magento\Eav\Test\Unit\Model\Resource\Entity\Attribute;
+
+use Magento\Eav\Model\Resource\Entity\Attribute\Set;
  
 class SetTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
+     * @var \PHPUnit_Framework_MockObject_MockObject|Set
      */
     protected $model;
 
@@ -44,9 +46,15 @@ class SetTest extends \PHPUnit_Framework_TestCase
      */
     protected $relationProcessor;
 
+    /**
+     * {@inheritdoc}
+     */
     protected function setUp()
     {
-        $this->resourceMock = $this->getMock('\Magento\Framework\App\Resource', ['getConnection'], [], '', false);
+        $this->resourceMock = $this->getMockBuilder('Magento\Framework\App\Resource')
+            ->disableOriginalConstructor()
+            ->setMethods(['getConnection', 'getTableName'])
+            ->getMock();
         $this->transactionManagerMock = $this->getMock(
             '\Magento\Framework\Model\Resource\Db\TransactionManagerInterface'
         );
@@ -66,7 +74,10 @@ class SetTest extends \PHPUnit_Framework_TestCase
             ->willReturn($this->relationProcessor);
         $contextMock->expects($this->once())->method('getResources')->willReturn($this->resourceMock);
 
-        $this->eavConfigMock = $this->getMock('Magento\Eav\Model\Config', [], [], '', false);
+        $this->eavConfigMock = $this->getMockBuilder('Magento\Eav\Model\Config')
+            ->setMethods(['isCacheEnabled', 'getEntityType', 'getCache'])
+            ->disableOriginalConstructor()
+            ->getMock();
         $this->model = $this->getMock(
             'Magento\Eav\Model\Resource\Entity\Attribute\Set',
             [
@@ -109,6 +120,7 @@ class SetTest extends \PHPUnit_Framework_TestCase
     /**
      * @expectedException \Magento\Framework\Exception\StateException
      * @expectedExceptionMessage Default attribute set can not be deleted
+     * @return void
      */
     public function testBeforeDeleteStateException()
     {
@@ -132,6 +144,7 @@ class SetTest extends \PHPUnit_Framework_TestCase
     /**
      * @expectedException \Exception
      * @expectedExceptionMessage test exception
+     * @return void
      */
     public function testBeforeDelete()
     {
@@ -154,4 +167,129 @@ class SetTest extends \PHPUnit_Framework_TestCase
 
         $this->model->delete($this->objectMock);
     }
+
+    /**
+     * @return void
+     */
+    public function testGetSetInfoCacheMiss()
+    {
+        $cacheMock = $this->getMockBuilder('Magento\Framework\App\CacheInterface')
+            ->disableOriginalConstructor()
+            ->setMethods(['load', 'save', 'getFrontend', 'remove', 'clean'])
+            ->getMock();
+        $cacheKey = Set::ATTRIBUTES_CACHE_ID . 1;
+        $cacheMock
+            ->expects($this->once())
+            ->method('load')
+            ->with($cacheKey)
+            ->willReturn(false);
+        $cacheMock
+            ->expects($this->once())
+            ->method('save')
+            ->with(
+                serialize(
+                    [
+                        1 => [
+                            10000 => [
+                                'group_id' =>  10,
+                                'group_sort' =>  100,
+                                'sort' =>  1000
+                            ]
+                        ]
+                    ]
+                ),
+                $cacheKey,
+                [\Magento\Eav\Model\Cache\Type::CACHE_TAG, \Magento\Eav\Model\Entity\Attribute::CACHE_TAG]
+            );
+
+        $this->eavConfigMock->expects($this->any())->method('isCacheEnabled')->willReturn(true);
+        $this->eavConfigMock->expects($this->any())->method('getCache')->willReturn($cacheMock);
+
+        $fetchResult = [
+            [
+                'attribute_id' => 1,
+                'attribute_group_id' => 10,
+                'group_sort_order' => 100,
+                'sort_order' => 1000,
+                'attribute_set_id' => 10000
+            ]
+        ];
+
+        $selectMock = $this->getMockBuilder('Magento\Framework\DB\Select')
+            ->disableOriginalConstructor()
+            ->setMethods(['from', 'joinLeft', 'where'])
+            ->getMock();
+        $selectMock->expects($this->once())->method('from')->will($this->returnSelf());
+        $selectMock->expects($this->once())->method('joinLeft')->will($this->returnSelf());
+        $selectMock->expects($this->atLeastOnce())->method('where')->will($this->returnSelf());
+
+        $connectionMock = $this->getMockBuilder('Magento\Framework\DB\Adapter\Pdo\Mysql')
+            ->disableOriginalConstructor()
+            ->setMethods(['select', 'fetchAll'])
+            ->getMock();
+        $connectionMock->expects($this->atLeastOnce())->method('select')->willReturn($selectMock);
+        $connectionMock->expects($this->atLeastOnce())->method('fetchAll')->willReturn($fetchResult);
+
+        $this->resourceMock->expects($this->any())->method('getConnection')->willReturn($connectionMock);
+        $this->resourceMock->expects($this->any())->method('getTableName')->willReturn('_TABLE_');
+        $this->assertEquals(
+            [
+                1 => [
+                    10000 => [
+                        'group_id' =>  10,
+                        'group_sort' =>  100,
+                        'sort' =>  1000
+                    ]
+                ],
+                2 => [],
+                3 => []
+            ],
+            $this->model->getSetInfo([1, 2, 3], 1)
+        );
+    }
+
+    /**
+     * @return void
+     */
+    public function testGetSetInfoCacheHit()
+    {
+        $cached = [
+            1 => [
+                10000 => [
+                    'group_id' => 10,
+                    'group_sort' => 100,
+                    'sort' => 1000
+                ]
+            ]
+        ];
+
+        $this->resourceMock->expects($this->never())->method('getConnection');
+        $this->eavConfigMock->expects($this->any())->method('isCacheEnabled')->willReturn(true);
+        $cacheMock = $this->getMockBuilder('Magento\Framework\App\CacheInterface')
+            ->disableOriginalConstructor()
+            ->setMethods(['load', 'save', 'getFrontend', 'remove', 'clean'])
+            ->getMock();
+        $cacheMock
+            ->expects($this->once())
+            ->method('load')
+            ->with(Set::ATTRIBUTES_CACHE_ID . 1)
+            ->willReturn(serialize($cached));
+
+        $this->eavConfigMock->expects($this->any())->method('getCache')->willReturn($cacheMock);
+
+        $this->assertEquals(
+            [
+                1 => [
+                    10000 => [
+                        'group_id' =>  10,
+                        'group_sort' =>  100,
+                        'sort' =>  1000
+                    ]
+                ],
+                2 => [],
+                3 => []
+            ],
+            $this->model->getSetInfo([1, 2, 3], 1)
+        );
+    }
 }
diff --git a/app/code/Magento/Review/Test/Unit/Model/Resource/Review/Product/CollectionTest.php b/app/code/Magento/Review/Test/Unit/Model/Resource/Review/Product/CollectionTest.php
index cc3683bbe0150c82e36d039f0fa6eb7f4625173b..9e49be6d7aa6cfc9f28cd1a65c618bee8b59dd7a 100644
--- a/app/code/Magento/Review/Test/Unit/Model/Resource/Review/Product/CollectionTest.php
+++ b/app/code/Magento/Review/Test/Unit/Model/Resource/Review/Product/CollectionTest.php
@@ -25,8 +25,8 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
     public function setUp()
     {
         $attribute = $this->getMock('\Magento\Eav\Model\Entity\Attribute\AbstractAttribute', null, [], '', false);
-        $eavConfig = $this->getMock('\Magento\Eav\Model\Config', ['getCollectionAttribute'], [], '', false);
-        $eavConfig->expects($this->any())->method('getCollectionAttribute')->will($this->returnValue($attribute));
+        $eavConfig = $this->getMock('\Magento\Eav\Model\Config', ['getAttribute'], [], '', false);
+        $eavConfig->expects($this->any())->method('getAttribute')->will($this->returnValue($attribute));
         $this->dbSelect = $this->getMock('Magento\Framework\DB\Select', ['where', 'from', 'join'], [], '', false);
         $this->dbSelect->expects($this->any())->method('from')->will($this->returnSelf());
         $this->dbSelect->expects($this->any())->method('join')->will($this->returnSelf());
diff --git a/app/code/Magento/Sales/Controller/Download.php b/app/code/Magento/Sales/Controller/Download.php
deleted file mode 100644
index dc2d31878bc5373fc1741c7cde49ac563bf7bc9c..0000000000000000000000000000000000000000
--- a/app/code/Magento/Sales/Controller/Download.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Sales\Controller;
-
-use Magento\Framework\App\Action\Context;
-use Magento\Sales\Model\Download as ModelDownload;
-
-/**
- * Sales controller for download purposes
- */
-class Download extends \Magento\Framework\App\Action\Action
-{
-    /**
-     * @var \Magento\Sales\Model\Download
-     */
-    protected $_download;
-
-    /**
-     * @param Context $context
-     * @param ModelDownload $download
-     */
-    public function __construct(Context $context, ModelDownload $download)
-    {
-        $this->_download = $download;
-        parent::__construct($context);
-    }
-}
diff --git a/app/code/Magento/Sales/Controller/Download/DownloadCustomOption.php b/app/code/Magento/Sales/Controller/Download/DownloadCustomOption.php
index aa5e0541fc896b059a7e881506ddbab43f50b03e..de556cb7ebf21884aad8570bae246277e60e8014 100644
--- a/app/code/Magento/Sales/Controller/Download/DownloadCustomOption.php
+++ b/app/code/Magento/Sales/Controller/Download/DownloadCustomOption.php
@@ -7,9 +7,9 @@
 namespace Magento\Sales\Controller\Download;
 
 use Magento\Sales\Model\Download;
-use Magento\Backend\App\Action\Context;
+use Magento\Framework\App\Action\Context;
 use Magento\Catalog\Model\Product\Type\AbstractType;
-use Magento\Backend\Model\View\Result\ForwardFactory;
+use Magento\Framework\Controller\Result\ForwardFactory;
 
 class DownloadCustomOption extends \Magento\Framework\App\Action\Action
 {
@@ -49,8 +49,8 @@ class DownloadCustomOption extends \Magento\Framework\App\Action\Action
     public function execute()
     {
         $quoteItemOptionId = $this->getRequest()->getParam('id');
-        /** @var $option \Magento\Sales\Model\Quote\Item\Option */
-        $option = $this->_objectManager->create('Magento\Sales\Model\Quote\Item\Option')->load($quoteItemOptionId);
+        /** @var $option \Magento\Quote\Model\Quote\Item\Option */
+        $option = $this->_objectManager->create('Magento\Quote\Model\Quote\Item\Option')->load($quoteItemOptionId);
         /** @var \Magento\Framework\Controller\Result\Forward $resultForward */
         $resultForward = $this->resultForwardFactory->create();
 
diff --git a/dev/tests/integration/testsuite/Magento/Indexer/Controller/Adminhtml/IndexerTest.php b/dev/tests/integration/testsuite/Magento/Indexer/Controller/Adminhtml/IndexerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..26fe450bc09707af9b4288f1bac4c82b8a3ac593
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Indexer/Controller/Adminhtml/IndexerTest.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Indexer\Controller\Adminhtml;
+
+/**
+ * @magentoAppArea adminhtml
+ */
+class IndexerTest extends \Magento\Backend\Utility\Controller
+{
+    /**
+     * Assert that current page is index management page and that it has indexers mode selector
+     *
+     * @return void
+     */
+    public function testIndexersMode()
+    {
+        $this->dispatch('backend/indexer/indexer/list/');
+        $body = $this->getResponse()->getBody();
+        $this->assertContains('<h1 class="title">Index Management</h1>', $body);
+        $this->assertSelectCount('#gridIndexer_massaction-select', 1, $body, 'Mode selector is not found');
+        $this->assertContains('option value="change_mode_onthefly"', $body);
+        $this->assertContains('option value="change_mode_changelog"', $body);
+    }
+
+    /**
+     * Assert that index management contains a certain number of indexers
+     *
+     * @return void
+     */
+    public function testDefaultNumberOfIndexers()
+    {
+        $this->dispatch('backend/indexer/indexer/list/');
+        $body = $this->getResponse()->getBody();
+        $this->assertSelectCount(
+            '[name="indexer_ids"]',
+            true,
+            $body,
+            'Indexer list is empty'
+        );
+    }
+}
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 3c8d02398cafa1eaf5144df8a652223e28d8aece..1afa25055ddc04de479b612ea4e9666cd1a5f0c4 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
@@ -115,6 +115,7 @@ return [
     ['Magento\Sales\Block\Adminhtml\Order\Shipment\View', 'Magento\Shipping\Block\Adminhtml\View'],
     ['Magento\Sales\Block\Order\Shipment\Items', 'Magento\Shipping\Block\Items'],
     ['Magento\Sales\Controller\Adminhtml\Order\Shipment', 'Magento\Shipping\Controller\Adminhtml\Order\Shipment'],
+    ['Magento\Sales\Controller\Download'],
     ['Magento\Sales\Block\Order\Shipment', 'Magento\Shipping\Block\Order\Shipment'],
     ['Mage_Adminhtml_Block_Sales_Order_Create_Customer_Grid'],
     ['Mage_Adminhtml_Block_Sales_Order_Create_Search_Grid_Renderer_Giftmessage'],
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 50e8d13bcdb0bf2b36a009ea45bef00d894a28c2..6dbca32165dd5ef56301be9883101668b13f018d 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
@@ -2124,4 +2124,8 @@ return [
     ['utcDate', 'Magento\Framework\Stdlib\DateTime\Timezone'],
     ['getLocaleCode', 'Magento\Framework\View\Asset\File\FallbackContext', 'getLocale'],
     ['getLocaleCode', 'Magento\Paypal\Model\Api\AbstractApi', 'getLocale'],
+    ['getCollectionAttribute', 'Magento\Eav\Model\Config'],
+    ['loadCollectionAttributes', 'Magento\Eav\Model\Config'],
+    ['_isCacheEnabled', 'Magento\Eav\Model\Config'],
+    ['_createCustomerAttribute', '\Magento\Customer\Model\Customer'],
 ];
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_properties.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_properties.php
index f9b9c49a8b91ce39248c27cf08d31f416d28dacd..5014947fdb32a80c042a1e61ffcf53a0fbabf9e4 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_properties.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_properties.php
@@ -409,4 +409,6 @@ return [
     ['_cache', 'Magento\Framework\Locale\Resolver'],
     ['_localeFactory', 'Magento\Framework\Locale\Resolver'],
     ['_emulatedLocales', 'Magento\Framework\Locale\Resolver', 'emulatedLocales'],
+    ['_collectionAttributes', 'Magento\Eav\Model\Config'],
+    ['_attributeFactory', '\Magento\Customer\Model\Customer'],
 ];