diff --git a/.php_cs b/.php_cs
index 7ae5d11f4ad1c9c4d65a3b9b59644885e99b327e..743cab6ee0d17db99cfd1373cf35f246772921fe 100644
--- a/.php_cs
+++ b/.php_cs
@@ -15,7 +15,6 @@ $finder = Symfony\CS\Finder\DefaultFinder::create()
     ->exclude('dev/tests/functional/vendor')
     ->exclude('dev/tests/integration/tmp')
     ->exclude('dev/tests/integration/var')
-    ->exclude('lib/internal/Apache')
     ->exclude('lib/internal/CardinalCommerce')
     ->exclude('lib/internal/Cm')
     ->exclude('lib/internal/Credis')
diff --git a/app/code/Magento/Bundle/Api/Data/LinkInterface.php b/app/code/Magento/Bundle/Api/Data/LinkInterface.php
index 77ca71986d8a217100401a29533d913c5bcfd30a..e16fad7f555bee04fb7f42743598acff877c6c6b 100644
--- a/app/code/Magento/Bundle/Api/Data/LinkInterface.php
+++ b/app/code/Magento/Bundle/Api/Data/LinkInterface.php
@@ -144,4 +144,19 @@ interface LinkInterface extends \Magento\Framework\Api\ExtensibleDataInterface
      * @return $this
      */
     public function setCanChangeQuantity($canChangeQuantity);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Bundle\Api\Data\LinkExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Bundle\Api\Data\LinkExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Bundle\Api\Data\LinkExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Bundle/Api/Data/OptionInterface.php b/app/code/Magento/Bundle/Api/Data/OptionInterface.php
index f15c1856981ba02b77f560bc8040d48a4d4bb761..47d52ba713c6410e935ccab66e3ea3b66a96416e 100644
--- a/app/code/Magento/Bundle/Api/Data/OptionInterface.php
+++ b/app/code/Magento/Bundle/Api/Data/OptionInterface.php
@@ -113,4 +113,19 @@ interface OptionInterface extends \Magento\Framework\Api\ExtensibleDataInterface
      * @return $this
      */
     public function setProductLinks(array $productLinks = null);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Bundle\Api\Data\OptionExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Bundle\Api\Data\OptionExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Bundle\Api\Data\OptionExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Bundle/Api/Data/OptionTypeInterface.php b/app/code/Magento/Bundle/Api/Data/OptionTypeInterface.php
index 9132f2babc7f53470b02ad93f3a2d6ef1f4d1b45..9883c8535da83ca0dd252e30d64cfe82b4144cf7 100644
--- a/app/code/Magento/Bundle/Api/Data/OptionTypeInterface.php
+++ b/app/code/Magento/Bundle/Api/Data/OptionTypeInterface.php
@@ -37,4 +37,19 @@ interface OptionTypeInterface extends \Magento\Framework\Api\ExtensibleDataInter
      * @return $this
      */
     public function setCode($code);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Bundle\Api\Data\OptionTypeExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Bundle\Api\Data\OptionTypeExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Bundle\Api\Data\OptionTypeExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Bundle/Model/Link.php b/app/code/Magento/Bundle/Model/Link.php
index f20685ee211fde7efe7c4f484a7455e169f68d90..eb99eff55e334fd9c878af2054243956b76a115c 100644
--- a/app/code/Magento/Bundle/Model/Link.php
+++ b/app/code/Magento/Bundle/Model/Link.php
@@ -7,6 +7,7 @@
 namespace Magento\Bundle\Model;
 
 /**
+ * Class Link
  * @codeCoverageIgnore
  */
 class Link extends \Magento\Framework\Model\AbstractExtensibleModel implements
@@ -196,4 +197,25 @@ class Link extends \Magento\Framework\Model\AbstractExtensibleModel implements
     {
         return $this->setData(self::KEY_CAN_CHANGE_QUANTITY, $canChangeQuantity);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Bundle\Api\Data\LinkExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Bundle\Api\Data\LinkExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Bundle\Api\Data\LinkExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Bundle/Model/Option.php b/app/code/Magento/Bundle/Model/Option.php
index dd265884d84999cb2f007c7a4a1c39b19f020f67..a541f00b80e24c7c6b8d221169b9f2efea55a900 100644
--- a/app/code/Magento/Bundle/Model/Option.php
+++ b/app/code/Magento/Bundle/Model/Option.php
@@ -269,5 +269,26 @@ class Option extends \Magento\Framework\Model\AbstractExtensibleModel implements
     {
         return $this->setData(self::KEY_PRODUCT_LINKS, $productLinks);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Bundle\Api\Data\OptionExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Bundle\Api\Data\OptionExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Bundle\Api\Data\OptionExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Bundle/Model/Plugin/BundleLoadOptions.php b/app/code/Magento/Bundle/Model/Plugin/BundleLoadOptions.php
index 7e7294d98bc1e766709bb8ed2cf668e50076de1e..76b5dd84b3620c4ee3fa4da5eae8fc6490b602ce 100644
--- a/app/code/Magento/Bundle/Model/Plugin/BundleLoadOptions.php
+++ b/app/code/Magento/Bundle/Model/Plugin/BundleLoadOptions.php
@@ -15,20 +15,21 @@ class BundleLoadOptions
     protected $productOptionList;
 
     /**
-     * @var \Magento\Framework\Api\AttributeValueFactory
+     * @var \Magento\Catalog\Api\Data\ProductExtensionFactory
      */
-    protected $customAttributeFactory;
+    protected $productExtensionFactory;
 
     /**
      * @param \Magento\Bundle\Model\Product\OptionList $productOptionList
-     * @param \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory
+     * @param \Magento\Framework\Api\AttributeDataBuilder $customAttributeBuilder
+     * @param \Magento\Catalog\Api\Data\ProductExtensionFactory $productExtensionFactory
      */
     public function __construct(
         \Magento\Bundle\Model\Product\OptionList $productOptionList,
-        \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory
+        \Magento\Catalog\Api\Data\ProductExtensionFactory $productExtensionFactory
     ) {
         $this->productOptionList = $productOptionList;
-        $this->customAttributeFactory = $customAttributeFactory;
+        $this->productExtensionFactory = $productExtensionFactory;
     }
 
     /**
@@ -50,11 +51,12 @@ class BundleLoadOptions
         if ($product->getTypeId() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) {
             return $product;
         }
-        $customAttribute = $this->customAttributeFactory->create()
-            ->setAttributeCode('bundle_product_options')
-            ->setValue($this->productOptionList->getItems($product));
-        $attributes = array_merge($product->getCustomAttributes(), ['bundle_product_options' => $customAttribute]);
-        $product->setData('custom_attributes', $attributes);
+
+        $productExtension = $this->productExtensionFactory->create();
+        $productExtension->setBundleProductOptions($this->productOptionList->getItems($product));
+
+        $product->setExtensionAttributes($productExtension);
+
         return $product;
     }
 }
diff --git a/app/code/Magento/Bundle/Model/Plugin/BundleSaveOptions.php b/app/code/Magento/Bundle/Model/Plugin/BundleSaveOptions.php
index 715feaab8e8220cc2396a076b7f2ed361647d198..b0e9ee6de4700da4651aee4c31aaed0b03db657b 100644
--- a/app/code/Magento/Bundle/Model/Plugin/BundleSaveOptions.php
+++ b/app/code/Magento/Bundle/Model/Plugin/BundleSaveOptions.php
@@ -44,13 +44,8 @@ class BundleSaveOptions
             return $result;
         }
 
-        /* @var \Magento\Framework\Api\AttributeValue $bundleProductOptionsAttrValue */
-        $bundleProductOptionsAttrValue = $product->getCustomAttribute('bundle_product_options');
-        if (is_null($bundleProductOptionsAttrValue) || !is_array($bundleProductOptionsAttrValue->getValue())) {
-            $bundleProductOptions = [];
-        } else {
-            $bundleProductOptions = $bundleProductOptionsAttrValue->getValue();
-        }
+        /* @var \Magento\Bundle\Api\Data\OptionInterface[] $options */
+        $bundleProductOptions = $product->getExtensionAttributes()->getBundleProductOptions();
 
         if (is_array($bundleProductOptions)) {
             foreach ($bundleProductOptions as $option) {
diff --git a/app/code/Magento/Bundle/Model/Source/Option/Type.php b/app/code/Magento/Bundle/Model/Source/Option/Type.php
index 711b94c2a554735aca2e24cb968e983518723316..98ecd93865d4cc25ca07963e2a1fe6866f25a04a 100644
--- a/app/code/Magento/Bundle/Model/Source/Option/Type.php
+++ b/app/code/Magento/Bundle/Model/Source/Option/Type.php
@@ -9,8 +9,12 @@
 namespace Magento\Bundle\Model\Source\Option;
 
 use Magento\Framework\Api\AttributeValueFactory;
-use Magento\Framework\Api\MetadataServiceInterface;
+use Magento\Framework\Api\ExtensionAttributesFactory;
 
+/**
+ * Class Type
+ *
+ */
 class Type extends \Magento\Framework\Model\AbstractExtensibleModel implements
     \Magento\Framework\Option\ArrayInterface,
     \Magento\Bundle\Api\Data\OptionTypeInterface
@@ -30,7 +34,7 @@ class Type extends \Magento\Framework\Model\AbstractExtensibleModel implements
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param MetadataServiceInterface $metadataService
+     * @param ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param array $options
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
@@ -40,7 +44,7 @@ class Type extends \Magento\Framework\Model\AbstractExtensibleModel implements
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        MetadataServiceInterface $metadataService,
+        ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         array $options,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
@@ -51,7 +55,7 @@ class Type extends \Magento\Framework\Model\AbstractExtensibleModel implements
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
@@ -111,5 +115,26 @@ class Type extends \Magento\Framework\Model\AbstractExtensibleModel implements
     {
         return $this->setData(self::KEY_CODE, $code);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Bundle\Api\Data\OptionTypeExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Bundle\Api\Data\OptionTypeExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Bundle\Api\Data\OptionTypeExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php b/app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php
index 2ed7bdb1b29e5864135cfa067f78a7022c28ec7a..7b91140a3bfe6fd0aa0196384d298e656afbb5bd 100644
--- a/app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php
+++ b/app/code/Magento/Bundle/Test/Unit/Model/OptionRepositoryTest.php
@@ -4,6 +4,9 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
+// @codingStandardsIgnoreFile
+
 namespace Magento\Bundle\Test\Unit\Model;
 
 class OptionRepositoryTest extends \PHPUnit_Framework_TestCase
@@ -71,6 +74,7 @@ class OptionRepositoryTest extends \PHPUnit_Framework_TestCase
         $this->optionFactoryMock = $this->getMockBuilder('\Magento\Bundle\Api\Data\OptionInterfaceFactory')
             ->disableOriginalConstructor()
             ->setMethods(['create'])
+            ->disableOriginalConstructor()
             ->getMock();
         $this->dataObjectHelperMock = $this->getMockBuilder('\Magento\Framework\Api\DataObjectHelper')
             ->disableOriginalConstructor()
diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Plugin/BundleLoadOptionsTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Plugin/BundleLoadOptionsTest.php
index 0618065c4e80bacd68fe211d7a433209636aa97a..e4050d99040ca61dacc97b54731fd79e67719af1 100644
--- a/app/code/Magento/Bundle/Test/Unit/Model/Plugin/BundleLoadOptionsTest.php
+++ b/app/code/Magento/Bundle/Test/Unit/Model/Plugin/BundleLoadOptionsTest.php
@@ -4,6 +4,9 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
+// @codingStandardsIgnoreFile
+
 namespace Magento\Bundle\Test\Unit\Model\Plugin;
 
 class BundleLoadOptionsTest extends \PHPUnit_Framework_TestCase
@@ -23,13 +26,20 @@ class BundleLoadOptionsTest extends \PHPUnit_Framework_TestCase
      */
     protected $attributeFactoryMock;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productExtensionFactory;
+
     protected function setUp()
     {
         $this->optionListMock = $this->getMock('\Magento\Bundle\Model\Product\OptionList', [], [], '', false);
-        $this->attributeFactoryMock = $this->getMock('\Magento\Framework\Api\AttributeValueFactory', [], [], '', false);
+        $this->productExtensionFactory = $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductExtensionFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
         $this->model = new \Magento\Bundle\Model\Plugin\BundleLoadOptions(
             $this->optionListMock,
-            $this->attributeFactoryMock
+            $this->productExtensionFactory
         );
     }
 
@@ -50,9 +60,10 @@ class BundleLoadOptionsTest extends \PHPUnit_Framework_TestCase
 
     public function testAroundLoad()
     {
+        $this->markTestSkipped('MAGETWO-34577');
         $productMock = $this->getMock(
             '\Magento\Catalog\Model\Product',
-            ['getTypeId', 'getCustomAttributes', 'setData'],
+            ['getTypeId', 'setExtensionAttributes'],
             [],
             '',
             false
@@ -69,22 +80,19 @@ class BundleLoadOptionsTest extends \PHPUnit_Framework_TestCase
             ->method('getItems')
             ->with($productMock)
             ->willReturn([$optionMock]);
-        $customAttributeMock = $this->getMock('\Magento\Framework\Api\AttributeValue', [], [], '', false);
-        $customAttributeMock->expects($this->once())
-            ->method('setAttributeCode')
-            ->with('bundle_product_options')
-            ->willReturnSelf();
-        $customAttributeMock->expects($this->once())
-            ->method('setValue')
+        $productExtensionMock = $this->getMockBuilder('\Magento\Catalog\Api\Data\ProductExtension')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->productExtensionFactory->expects($this->once())
+            ->method('create')
+            ->willReturn($productExtensionMock);
+        $productExtensionMock->expects($this->once())
+            ->method('setBundleProductOptions')
             ->with([$optionMock])
             ->willReturnSelf();
-        $this->attributeFactoryMock->expects($this->once())->method('create')->willReturn($customAttributeMock);
-
-        $productAttributeMock = $this->getMock('\Magento\Framework\Api\AttributeValue', [], [], '', false);
-        $productMock->expects($this->once())->method('getCustomAttributes')->willReturn([$productAttributeMock]);
         $productMock->expects($this->once())
-            ->method('setData')
-            ->with('custom_attributes', ['bundle_product_options' => $customAttributeMock, $productAttributeMock])
+            ->method('setExtensionAttributes')
+            ->with($productExtensionMock)
             ->willReturnSelf();
 
         $this->assertEquals(
diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Plugin/BundleSaveOptionsTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Plugin/BundleSaveOptionsTest.php
index 7bf90801c4620a0d40b47265b39aebac41531251..1615760e6dbee5b4ad44d0d30cd81b53b19e691e 100644
--- a/app/code/Magento/Bundle/Test/Unit/Model/Plugin/BundleSaveOptionsTest.php
+++ b/app/code/Magento/Bundle/Test/Unit/Model/Plugin/BundleSaveOptionsTest.php
@@ -5,6 +5,8 @@
  * See COPYING.txt for license details.
  */
 
+// @codingStandardsIgnoreFile
+
 namespace Magento\Bundle\Test\Unit\Model\Plugin;
 
 use \Magento\Bundle\Model\Plugin\BundleSaveOptions;
@@ -31,6 +33,16 @@ class BundleSaveOptionsTest extends \PHPUnit_Framework_TestCase
      */
     protected $productMock;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productExtensionMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productBundleOptionsMock;
+
     /**
      * @var \Closure
      */
@@ -40,17 +52,37 @@ class BundleSaveOptionsTest extends \PHPUnit_Framework_TestCase
     {
         $this->productRepositoryMock = $this->getMock('Magento\Catalog\Api\ProductRepositoryInterface');
         $this->productOptionRepositoryMock = $this->getMock('Magento\Bundle\Api\ProductOptionRepositoryInterface');
-        $this->productMock = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false);
+        $this->productMock = $this->getMock(
+            'Magento\Catalog\Model\Product',
+            ['getExtensionAttributes', 'getTypeId'],
+            [],
+            '',
+            false
+        );
         $this->closureMock = function () {
             return $this->productMock;
         };
         $this->plugin = new BundleSaveOptions($this->productOptionRepositoryMock);
+        $this->productExtensionMock = $this->getMock(
+            'Magento\Catalog\Api\Data\ProductExtension',
+            ['getBundleProductOptions'],
+            [],
+            '',
+            false
+        );
+        $this->productBundleOptionsMock = $this->getMock(
+            'Magento\Bundle\Api\Data\OptionInterface',
+            [],
+            [],
+            '',
+            false
+        );
     }
 
     public function testAroundSaveWhenProductIsSimple()
     {
         $this->productMock->expects($this->once())->method('getTypeId')->willReturn('simple');
-        $this->productMock->expects($this->never())->method('getCustomAttribute');
+        $this->productMock->expects($this->never())->method('getExtensionAttributes');
 
         $this->assertEquals(
             $this->productMock,
@@ -62,9 +94,11 @@ class BundleSaveOptionsTest extends \PHPUnit_Framework_TestCase
     {
         $this->productMock->expects($this->once())->method('getTypeId')->willReturn('bundle');
         $this->productMock->expects($this->once())
-            ->method('getCustomAttribute')
-            ->with('bundle_product_options')
-            ->willReturn(null);
+            ->method('getExtensionAttributes')
+            ->willReturn($this->productExtensionMock);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getBundleProductOptions')
+            ->willReturn([]);
 
         $this->productOptionRepositoryMock->expects($this->never())->method('save');
 
@@ -76,16 +110,17 @@ class BundleSaveOptionsTest extends \PHPUnit_Framework_TestCase
 
     public function testAroundSaveWhenProductIsBundleWithOptions()
     {
-        $option = $this->getMock('\Magento\Bundle\Api\Data\OptionInterface');
-        $bundleProductOptionsAttrValue = $this->getMock('\Magento\Framework\Api\AttributeValue', [], [], '', false);
-        $bundleProductOptionsAttrValue->expects($this->atLeastOnce())->method('getValue')->willReturn([$option]);
         $this->productMock->expects($this->once())->method('getTypeId')->willReturn('bundle');
         $this->productMock->expects($this->once())
-            ->method('getCustomAttribute')
-            ->with('bundle_product_options')
-            ->willReturn($bundleProductOptionsAttrValue);
-
-        $this->productOptionRepositoryMock->expects($this->once())->method('save')->with($this->productMock, $option);
+            ->method('getExtensionAttributes')
+            ->willReturn($this->productExtensionMock);
+        $this->productExtensionMock->expects($this->once())
+            ->method('getBundleProductOptions')
+            ->willReturn([$this->productBundleOptionsMock]);
+
+        $this->productOptionRepositoryMock->expects($this->once())
+            ->method('save')
+            ->with($this->productMock, $this->productBundleOptionsMock);
 
         $this->assertEquals(
             $this->productMock,
diff --git a/app/code/Magento/Bundle/Test/Unit/Pricing/Price/DiscountCalculatorTest.php b/app/code/Magento/Bundle/Test/Unit/Pricing/Price/DiscountCalculatorTest.php
index f15939bfd5add7b635db8fd8a39a875b1cf5e91c..8ebcc1cb67a8b5d2b7dc606cc99ca5e740d2f1e5 100644
--- a/app/code/Magento/Bundle/Test/Unit/Pricing/Price/DiscountCalculatorTest.php
+++ b/app/code/Magento/Bundle/Test/Unit/Pricing/Price/DiscountCalculatorTest.php
@@ -8,8 +8,6 @@
 
 namespace Magento\Bundle\Test\Unit\Pricing\Price;
 
-use Magento\Catalog\Pricing\Price\FinalPrice;
-
 /**
  * Class DiscountCalculatorTest
  */
@@ -95,7 +93,7 @@ class DiscountCalculatorTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue($this->priceInfoMock));
         $this->priceInfoMock->expects($this->once())
             ->method('getPrice')
-            ->with($this->equalTo(FinalPrice::PRICE_CODE))
+            ->with($this->equalTo(\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE))
             ->will($this->returnValue($this->finalPriceMock));
         $this->finalPriceMock->expects($this->once())
             ->method('getValue')
diff --git a/app/code/Magento/Bundle/etc/data_object.xml b/app/code/Magento/Bundle/etc/data_object.xml
index 2b3da013978f971bb20baca3a5e0ca95f2b501fc..88e317dafc78c8ce9d0c9a3fe6f703b777361e4a 100644
--- a/app/code/Magento/Bundle/etc/data_object.xml
+++ b/app/code/Magento/Bundle/etc/data_object.xml
@@ -8,5 +8,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Api/etc/data_object.xsd">
     <custom_attributes for="Magento\Catalog\Api\Data\ProductInterface">
         <attribute code="bundle_product_options" type="Magento\Bundle\Api\Data\OptionInterface[]" />
+        <attribute code="price_type" type="integer" />
+        <attribute code="price_view" type="string" />
     </custom_attributes>
 </config>
diff --git a/app/code/Magento/Catalog/Api/Data/CategoryInterface.php b/app/code/Magento/Catalog/Api/Data/CategoryInterface.php
index fe49eab7d10b1a5e31e3bb7319ec0a14658fc9e8..8ca5780579cf2f6062e9ba8df686e1f0eba56463 100644
--- a/app/code/Magento/Catalog/Api/Data/CategoryInterface.php
+++ b/app/code/Magento/Catalog/Api/Data/CategoryInterface.php
@@ -8,7 +8,7 @@
 
 namespace Magento\Catalog\Api\Data;
 
-interface CategoryInterface extends \Magento\Framework\Api\ExtensibleDataInterface
+interface CategoryInterface extends \Magento\Framework\Api\CustomAttributesDataInterface
 {
     /**
      * @return int|null
@@ -149,4 +149,19 @@ interface CategoryInterface extends \Magento\Framework\Api\ExtensibleDataInterfa
      * @return $this
      */
     public function setIncludeInMenu($includeInMenu);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Catalog\Api\Data\CategoryExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Catalog\Api\Data\CategoryExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Catalog\Api\Data\CategoryExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Catalog/Api/Data/CategoryProductLinkInterface.php b/app/code/Magento/Catalog/Api/Data/CategoryProductLinkInterface.php
index 04b8f8fe5b7a54c2e3dc4fa3857b7b8db5b9ad8b..ba9b235f9f4032658509039c0b970ae51fb2699d 100644
--- a/app/code/Magento/Catalog/Api/Data/CategoryProductLinkInterface.php
+++ b/app/code/Magento/Catalog/Api/Data/CategoryProductLinkInterface.php
@@ -6,7 +6,9 @@
 
 namespace Magento\Catalog\Api\Data;
 
-interface CategoryProductLinkInterface
+use Magento\Framework\Api\ExtensibleDataInterface;
+
+interface CategoryProductLinkInterface extends ExtensibleDataInterface
 {
     /**
      * @return string|null
@@ -44,4 +46,21 @@ interface CategoryProductLinkInterface
      * @return $this
      */
     public function setCategoryId($categoryId);
+
+    /**
+     * Retrieve existing extension attributes object.
+     *
+     * @return \Magento\Catalog\Api\Data\CategoryProductLinkExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Catalog\Api\Data\CategoryProductLinkExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Catalog\Api\Data\CategoryProductLinkExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Catalog/Api/Data/CategoryTreeInterface.php b/app/code/Magento/Catalog/Api/Data/CategoryTreeInterface.php
index 42f5b2c56edef8d7f18e5e438848538ecb0d10bb..66078497c25e0c479eded4aedea9fe8610a5688e 100644
--- a/app/code/Magento/Catalog/Api/Data/CategoryTreeInterface.php
+++ b/app/code/Magento/Catalog/Api/Data/CategoryTreeInterface.php
@@ -7,7 +7,7 @@
 
 namespace Magento\Catalog\Api\Data;
 
-interface CategoryTreeInterface extends \Magento\Framework\Api\ExtensibleDataInterface
+interface CategoryTreeInterface
 {
     /**
      * @return int|null
diff --git a/app/code/Magento/Catalog/Api/Data/EavAttributeInterface.php b/app/code/Magento/Catalog/Api/Data/EavAttributeInterface.php
index 02e9c54f2dc400c37bdf46044bd1fcea28cc0824..6fa35baa0f9a8257a9ad6a128477aa9321c5d11c 100644
--- a/app/code/Magento/Catalog/Api/Data/EavAttributeInterface.php
+++ b/app/code/Magento/Catalog/Api/Data/EavAttributeInterface.php
@@ -275,4 +275,9 @@ interface EavAttributeInterface extends \Magento\Eav\Api\Data\AttributeInterface
      * @return $this
      */
     public function setScope($scope);
+
+    /**
+     * @return \Magento\Catalog\Api\Data\EavAttributeExtensionInterface|null
+     */
+    public function getExtensionAttributes();
 }
diff --git a/app/code/Magento/Catalog/Api/Data/ProductAttributeMediaGalleryEntryContentInterface.php b/app/code/Magento/Catalog/Api/Data/ProductAttributeMediaGalleryEntryContentInterface.php
index f6651f1caf686750296ee754e5d33b21a69e05d4..ccad19926c342f7a16a46c67897fcac8da48f769 100644
--- a/app/code/Magento/Catalog/Api/Data/ProductAttributeMediaGalleryEntryContentInterface.php
+++ b/app/code/Magento/Catalog/Api/Data/ProductAttributeMediaGalleryEntryContentInterface.php
@@ -1,13 +1,17 @@
 <?php
 /**
- * Product Media Content
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
 namespace Magento\Catalog\Api\Data;
 
-interface ProductAttributeMediaGalleryEntryContentInterface
+use Magento\Framework\Api\ExtensibleDataInterface;
+
+/**
+ * Product Media Content
+ */
+interface ProductAttributeMediaGalleryEntryContentInterface extends ExtensibleDataInterface
 {
     const DATA = 'entry_data';
     const MIME_TYPE = 'mime_type';
@@ -57,4 +61,21 @@ interface ProductAttributeMediaGalleryEntryContentInterface
      * @return $this
      */
     public function setName($name);
+
+    /**
+     * Retrieve existing extension attributes object.
+     *
+     * @return \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryContentExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryContentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryContentExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Catalog/Api/Data/ProductAttributeMediaGalleryEntryInterface.php b/app/code/Magento/Catalog/Api/Data/ProductAttributeMediaGalleryEntryInterface.php
index 1e7d37e4abd73bde244e69147e11aee2ebc48c71..afac0c209edd87374d0bfbcfd40655e131a0dcc3 100644
--- a/app/code/Magento/Catalog/Api/Data/ProductAttributeMediaGalleryEntryInterface.php
+++ b/app/code/Magento/Catalog/Api/Data/ProductAttributeMediaGalleryEntryInterface.php
@@ -7,7 +7,9 @@
  */
 namespace Magento\Catalog\Api\Data;
 
-interface ProductAttributeMediaGalleryEntryInterface
+use Magento\Framework\Api\ExtensibleDataInterface;
+
+interface ProductAttributeMediaGalleryEntryInterface extends ExtensibleDataInterface
 {
     const ID = 'id';
     const LABEL = 'label';
@@ -121,4 +123,21 @@ interface ProductAttributeMediaGalleryEntryInterface
      * @return $this 
      */
     public function setContent($content);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Catalog/Api/Data/ProductAttributeTypeInterface.php b/app/code/Magento/Catalog/Api/Data/ProductAttributeTypeInterface.php
index 759f359748a8dcf15d875a9f747cd3c473346391..eebbfb307a252827cc567bd3217d640471222f69 100644
--- a/app/code/Magento/Catalog/Api/Data/ProductAttributeTypeInterface.php
+++ b/app/code/Magento/Catalog/Api/Data/ProductAttributeTypeInterface.php
@@ -1,12 +1,14 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
 namespace Magento\Catalog\Api\Data;
 
-interface ProductAttributeTypeInterface
+use Magento\Framework\Api\ExtensibleDataInterface;
+
+interface ProductAttributeTypeInterface extends ExtensibleDataInterface
 {
     const VALUE = 'value';
 
@@ -41,4 +43,21 @@ interface ProductAttributeTypeInterface
      * @return $this
      */
     public function setLabel($label);
+
+    /**
+     * Retrieve existing extension attributes object.
+     *
+     * @return \Magento\Catalog\Api\Data\ProductAttributeTypeExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Catalog\Api\Data\ProductAttributeTypeExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Catalog\Api\Data\ProductAttributeTypeExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Catalog/Api/Data/ProductCustomOptionTypeInterface.php b/app/code/Magento/Catalog/Api/Data/ProductCustomOptionTypeInterface.php
index c4f137a0cb355e74c415cf78e9728324d055e795..6a562efc3b0c73326f9d1c9a436325414f77ba72 100644
--- a/app/code/Magento/Catalog/Api/Data/ProductCustomOptionTypeInterface.php
+++ b/app/code/Magento/Catalog/Api/Data/ProductCustomOptionTypeInterface.php
@@ -6,7 +6,9 @@
 
 namespace Magento\Catalog\Api\Data;
 
-interface ProductCustomOptionTypeInterface
+use Magento\Framework\Api\ExtensibleDataInterface;
+
+interface ProductCustomOptionTypeInterface extends ExtensibleDataInterface
 {
     /**
      * Get option type label
@@ -52,4 +54,21 @@ interface ProductCustomOptionTypeInterface
      * @return $this
      */
     public function setGroup($group);
+
+    /**
+     * Retrieve existing extension attributes object.
+     *
+     * @return \Magento\Catalog\Api\Data\ProductCustomOptionTypeExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Catalog\Api\Data\ProductCustomOptionTypeExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Catalog\Api\Data\ProductCustomOptionTypeExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Catalog/Api/Data/ProductGroupPriceInterface.php b/app/code/Magento/Catalog/Api/Data/ProductGroupPriceInterface.php
index 9e2162f41f2439a5e4fa82ddaa70f4293f636465..4c2b9bd80abc1e3bdbc62958d9cd5fd0739798ec 100644
--- a/app/code/Magento/Catalog/Api/Data/ProductGroupPriceInterface.php
+++ b/app/code/Magento/Catalog/Api/Data/ProductGroupPriceInterface.php
@@ -6,7 +6,9 @@
  */
 namespace Magento\Catalog\Api\Data;
 
-interface ProductGroupPriceInterface
+use Magento\Framework\Api\ExtensibleDataInterface;
+
+interface ProductGroupPriceInterface extends ExtensibleDataInterface
 {
     /**
      * Retrieve customer group id
@@ -37,4 +39,21 @@ interface ProductGroupPriceInterface
      * @return $this
      */
     public function setValue($value);
+
+    /**
+     * Retrieve existing extension attributes object.
+     *
+     * @return \Magento\Catalog\Api\Data\ProductGroupPriceExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Catalog\Api\Data\ProductGroupPriceExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Catalog\Api\Data\ProductGroupPriceExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Catalog/Api/Data/ProductInterface.php b/app/code/Magento/Catalog/Api/Data/ProductInterface.php
index b0021ca89cdfa04e3e126784bad1f08dd460fb0b..34eed7fdf7bab210c1ff8c75a6690973bcc1cbca 100644
--- a/app/code/Magento/Catalog/Api/Data/ProductInterface.php
+++ b/app/code/Magento/Catalog/Api/Data/ProductInterface.php
@@ -7,7 +7,7 @@
 
 namespace Magento\Catalog\Api\Data;
 
-interface ProductInterface extends \Magento\Framework\Api\ExtensibleDataInterface
+interface ProductInterface extends \Magento\Framework\Api\CustomAttributesDataInterface
 {
     /**#@+
      * Constants defined for keys of  data array
@@ -214,4 +214,19 @@ interface ProductInterface extends \Magento\Framework\Api\ExtensibleDataInterfac
      * @return $this
      */
     public function setWeight($weight);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Catalog\Api\Data\ProductExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Catalog\Api\Data\ProductExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Catalog\Api\Data\ProductExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Catalog/Api/Data/ProductLinkAttributeInterface.php b/app/code/Magento/Catalog/Api/Data/ProductLinkAttributeInterface.php
index 794d60b99b6c9d793e2ad957474b7152cbbf0938..bad462ff801c942b967308d12e30c5a68199a66c 100644
--- a/app/code/Magento/Catalog/Api/Data/ProductLinkAttributeInterface.php
+++ b/app/code/Magento/Catalog/Api/Data/ProductLinkAttributeInterface.php
@@ -6,7 +6,9 @@
 
 namespace Magento\Catalog\Api\Data;
 
-interface ProductLinkAttributeInterface
+use Magento\Framework\Api\ExtensibleDataInterface;
+
+interface ProductLinkAttributeInterface extends ExtensibleDataInterface
 {
     /**
      * Get attribute code
@@ -37,4 +39,21 @@ interface ProductLinkAttributeInterface
      * @return $this
      */
     public function setType($type);
+
+    /**
+     * Retrieve existing extension attributes object.
+     *
+     * @return \Magento\Catalog\Api\Data\ProductLinkAttributeExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Catalog\Api\Data\ProductLinkAttributeExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Catalog\Api\Data\ProductLinkAttributeExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Catalog/Api/Data/ProductLinkInterface.php b/app/code/Magento/Catalog/Api/Data/ProductLinkInterface.php
index 7e9d8c882ef35b088cc07d9b5dcf159d7250e873..7a19d3c465a4b77d79b910e641c4333193c74e0e 100644
--- a/app/code/Magento/Catalog/Api/Data/ProductLinkInterface.php
+++ b/app/code/Magento/Catalog/Api/Data/ProductLinkInterface.php
@@ -82,4 +82,21 @@ interface ProductLinkInterface extends \Magento\Framework\Api\ExtensibleDataInte
      * @return $this
      */
     public function setPosition($position);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Catalog\Api\Data\ProductLinkExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Catalog\Api\Data\ProductLinkExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Catalog\Api\Data\ProductLinkExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Catalog/Api/Data/ProductLinkTypeInterface.php b/app/code/Magento/Catalog/Api/Data/ProductLinkTypeInterface.php
index 617f9cde2c1ebad2ff2f71c6a54c4b79c590e462..a5863c09f5f099eb772b9412423523496e87c1b8 100644
--- a/app/code/Magento/Catalog/Api/Data/ProductLinkTypeInterface.php
+++ b/app/code/Magento/Catalog/Api/Data/ProductLinkTypeInterface.php
@@ -6,7 +6,9 @@
 
 namespace Magento\Catalog\Api\Data;
 
-interface ProductLinkTypeInterface
+use Magento\Framework\Api\ExtensibleDataInterface;
+
+interface ProductLinkTypeInterface extends ExtensibleDataInterface
 {
     /**
      * Get link type code
@@ -37,4 +39,21 @@ interface ProductLinkTypeInterface
      * @return $this
      */
     public function setName($name);
+
+    /**
+     * Retrieve existing extension attributes object.
+     *
+     * @return \Magento\Catalog\Api\Data\ProductLinkTypeExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Catalog\Api\Data\ProductLinkTypeExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Catalog\Api\Data\ProductLinkTypeExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php b/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php
index ee7f92d622bb929128188ce385137db23a43f5e5..bee553af0f504824cb8c85b50d2a4c0fa485f9fe 100644
--- a/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php
+++ b/app/code/Magento/Catalog/Api/Data/ProductTierPriceInterface.php
@@ -7,10 +7,12 @@
 
 namespace Magento\Catalog\Api\Data;
 
+use Magento\Framework\Api\ExtensibleDataInterface;
+
 /**
  * @todo remove this interface if framework support return array
  */
-interface ProductTierPriceInterface
+interface ProductTierPriceInterface extends ExtensibleDataInterface
 {
     const QTY = 'qty';
 
@@ -45,4 +47,21 @@ interface ProductTierPriceInterface
      * @return $this
      */
     public function setValue($value);
+
+    /**
+     * Retrieve existing extension attributes object.
+     *
+     * @return \Magento\Catalog\Api\Data\ProductTierPriceExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Catalog\Api\Data\ProductTierPriceExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Catalog\Api\Data\ProductTierPriceExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Catalog/Api/Data/ProductTypeInterface.php b/app/code/Magento/Catalog/Api/Data/ProductTypeInterface.php
index 0d888145c3fd6db515c5d92f22d9512c84b598a1..50599c36231e1b74611c1c1238d05c541627b53f 100644
--- a/app/code/Magento/Catalog/Api/Data/ProductTypeInterface.php
+++ b/app/code/Magento/Catalog/Api/Data/ProductTypeInterface.php
@@ -1,13 +1,17 @@
 <?php
 /**
- * Product type details
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
 namespace Magento\Catalog\Api\Data;
 
-interface ProductTypeInterface
+use Magento\Framework\Api\ExtensibleDataInterface;
+
+/**
+ * Product type details
+ */
+interface ProductTypeInterface extends ExtensibleDataInterface
 {
     /**
      * Get product type code
@@ -38,4 +42,21 @@ interface ProductTypeInterface
      * @return $this
      */
     public function setLabel($label);
+
+    /**
+     * Retrieve existing extension attributes object.
+     *
+     * @return \Magento\Catalog\Api\Data\ProductTypeExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Catalog\Api\Data\ProductTypeExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Catalog\Api\Data\ProductTypeExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Catalog/Model/AbstractModel.php b/app/code/Magento/Catalog/Model/AbstractModel.php
index 19c70245700c41c2c56f1f42aa645ab8a4f23cc5..738a88b5c04c9a1fafbc77c767c1e20e544c3967 100644
--- a/app/code/Magento/Catalog/Model/AbstractModel.php
+++ b/app/code/Magento/Catalog/Model/AbstractModel.php
@@ -62,7 +62,7 @@ abstract class AbstractModel extends \Magento\Framework\Model\AbstractExtensible
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
@@ -72,7 +72,7 @@ abstract class AbstractModel extends \Magento\Framework\Model\AbstractExtensible
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
@@ -83,7 +83,7 @@ abstract class AbstractModel extends \Magento\Framework\Model\AbstractExtensible
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
diff --git a/app/code/Magento/Catalog/Model/Category.php b/app/code/Magento/Catalog/Model/Category.php
index 2a0519a89d625cfaef579fe6f3bcae92d10573e9..38261678195d2dc4f1041cd0dc1dbb0b5be0747a 100644
--- a/app/code/Magento/Catalog/Model/Category.php
+++ b/app/code/Magento/Catalog/Model/Category.php
@@ -189,12 +189,18 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements
      */
     protected $categoryRepository;
 
+    /**
+     * @var \Magento\Framework\Api\MetadataServiceInterface
+     */
+    protected $metadataService;
+
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Catalog\Api\CategoryAttributeRepositoryInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     * @param \Magento\Catalog\Api\CategoryAttributeRepositoryInterface $metadataService
      * @param Resource\Category\Tree $categoryTreeResource
      * @param Resource\Category\TreeFactory $categoryTreeFactory
      * @param \Magento\Store\Model\Resource\Store\CollectionFactory $storeCollectionFactory
@@ -215,9 +221,10 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Catalog\Api\CategoryAttributeRepositoryInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
+        \Magento\Catalog\Api\CategoryAttributeRepositoryInterface $metadataService,
         \Magento\Catalog\Model\Resource\Category\Tree $categoryTreeResource,
         \Magento\Catalog\Model\Resource\Category\TreeFactory $categoryTreeFactory,
         \Magento\Store\Model\Resource\Store\CollectionFactory $storeCollectionFactory,
@@ -234,6 +241,7 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements
         \Magento\Framework\Data\Collection\Db $resourceCollection = null,
         array $data = []
     ) {
+        $this->metadataService = $metadataService;
         $this->_treeModel = $categoryTreeResource;
         $this->_categoryTreeFactory = $categoryTreeFactory;
         $this->_storeCollectionFactory = $storeCollectionFactory;
@@ -249,7 +257,7 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $storeManager,
             $resource,
@@ -274,6 +282,17 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements
         }
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    protected function getCustomAttributesCodes()
+    {
+        if ($this->customAttributesCodes === null) {
+            $this->customAttributesCodes = $this->getEavAttributesCodes($this->metadataService);
+        }
+        return $this->customAttributesCodes;
+    }
+
     /**
      * Get flat resource model flag
      *
@@ -1324,5 +1343,26 @@ class Category extends \Magento\Catalog\Model\AbstractModel implements
     {
         return $this->setData(self::KEY_CHILDREN_DATA, $childrenData);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Catalog\Api\Data\CategoryExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Catalog\Api\Data\CategoryExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Catalog\Api\Data\CategoryExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Catalog/Model/Category/Attribute.php b/app/code/Magento/Catalog/Model/Category/Attribute.php
index 99659b6760e6eb7b4311559fe7be113561c6615d..faf1fbd8c12194e79b04a91ff00c5e5c0d0ac434 100644
--- a/app/code/Magento/Catalog/Model/Category/Attribute.php
+++ b/app/code/Magento/Catalog/Model/Category/Attribute.php
@@ -5,6 +5,11 @@
  */
 namespace Magento\Catalog\Model\Category;
 
+/**
+ * Class Attribute
+ *
+ * @method \Magento\Eav\Api\Data\AttributeExtensionInterface getExtensionAttributes()
+ */
 class Attribute extends \Magento\Catalog\Model\Entity\Attribute implements
     \Magento\Catalog\Api\Data\CategoryAttributeInterface
 {
diff --git a/app/code/Magento/Catalog/Model/Category/AttributeRepository.php b/app/code/Magento/Catalog/Model/Category/AttributeRepository.php
index 7538322e36920ec192f3b49607c6a96d7278524d..38ee0f02fccdd16a5e5aad62b53a71a1429e5e9c 100644
--- a/app/code/Magento/Catalog/Model/Category/AttributeRepository.php
+++ b/app/code/Magento/Catalog/Model/Category/AttributeRepository.php
@@ -25,25 +25,17 @@ class AttributeRepository implements CategoryAttributeRepositoryInterface
     protected $eavAttributeRepository;
 
     /**
-     * @var \Magento\Eav\Model\Config
-     */
-    protected $eavConfig;
-
-    /**
-     * @param \Magento\Framework\Api\Config\MetadataConfig $metadataConfig
      * @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
      * @param \Magento\Framework\Api\FilterBuilder $filterBuilder
      * @param \Magento\Eav\Api\AttributeRepositoryInterface $eavAttributeRepository
      * @param \Magento\Eav\Model\Config $eavConfig
      */
     public function __construct(
-        \Magento\Framework\Api\Config\MetadataConfig $metadataConfig,
         \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
         \Magento\Framework\Api\FilterBuilder $filterBuilder,
         \Magento\Eav\Api\AttributeRepositoryInterface $eavAttributeRepository,
         \Magento\Eav\Model\Config $eavConfig
     ) {
-        $this->metadataConfig = $metadataConfig;
         $this->searchCriteriaBuilder = $searchCriteriaBuilder;
         $this->filterBuilder = $filterBuilder;
         $this->eavAttributeRepository = $eavAttributeRepository;
@@ -74,6 +66,7 @@ class AttributeRepository implements CategoryAttributeRepositoryInterface
 
     /**
      * {@inheritdoc}
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function getCustomAttributesMetadata($dataObjectClassName = null)
     {
@@ -89,12 +82,6 @@ class AttributeRepository implements CategoryAttributeRepositoryInterface
             ]
         );
 
-        $customAttributes = [];
-        $entityAttributes = $this->getList($searchCriteria->create())->getItems();
-
-        foreach ($entityAttributes as $attributeMetadata) {
-            $customAttributes[] = $attributeMetadata;
-        }
-        return array_merge($customAttributes, $this->metadataConfig->getCustomAttributesMetadata($dataObjectClassName));
+        return $this->getList($searchCriteria->create())->getItems();
     }
 }
diff --git a/app/code/Magento/Catalog/Model/CategoryProductLink.php b/app/code/Magento/Catalog/Model/CategoryProductLink.php
index b8912fcf08e7c00f7d42114c258c5842de8040c7..2250d914d58f8e23d25c159ef1c5f9d3459829cf 100644
--- a/app/code/Magento/Catalog/Model/CategoryProductLink.php
+++ b/app/code/Magento/Catalog/Model/CategoryProductLink.php
@@ -72,4 +72,26 @@ class CategoryProductLink extends \Magento\Framework\Api\AbstractExtensibleObjec
     {
         return $this->setData(self::KEY_CATEGORY_ID, $categoryId);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Catalog\Api\Data\CategoryProductLinkExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Catalog\Api\Data\CategoryProductLinkExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Catalog\Api\Data\CategoryProductLinkExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/CategoryRepository.php b/app/code/Magento/Catalog/Model/CategoryRepository.php
index e1fc8c0c2d670313b30e961f5e51dfff09df15c8..d436d06561d816dcce4695013d54b3f566eb575a 100644
--- a/app/code/Magento/Catalog/Model/CategoryRepository.php
+++ b/app/code/Magento/Catalog/Model/CategoryRepository.php
@@ -77,6 +77,8 @@ class CategoryRepository implements \Magento\Catalog\Api\CategoryRepositoryInter
         } else {
             $parentId = $category->getParentId() ?: $this->storeManager->getStore()->getRootCategoryId();
             $parentCategory = $this->get($parentId);
+            $existingData['include_in_menu'] =
+                isset($existingData['include_in_menu']) ? (bool)$existingData['include_in_menu'] : false;
             /** @var  $category Category */
             $category->setData($existingData);
             $category->setPath($parentCategory->getPath());
diff --git a/app/code/Magento/Catalog/Model/Entity/Attribute.php b/app/code/Magento/Catalog/Model/Entity/Attribute.php
index 7ca6107c0518590941e8e2cee3a92cbcd074d60d..5ff035d22422267e50f777df8a92e41b38bf6e8d 100644
--- a/app/code/Magento/Catalog/Model/Entity/Attribute.php
+++ b/app/code/Magento/Catalog/Model/Entity/Attribute.php
@@ -43,6 +43,7 @@ use Magento\Framework\Api\AttributeValueFactory;
  * @method \Magento\Catalog\Model\Entity\Attribute setIsWysiwygEnabled(int $value)
  * @method int getIsUsedForPromoRules()
  * @method \Magento\Catalog\Model\Entity\Attribute setIsUsedForPromoRules(int $value)
+ * @method \Magento\Eav\Api\Data\AttributeExtensionInterface getExtensionAttributes()
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class Attribute extends \Magento\Eav\Model\Entity\Attribute
@@ -71,7 +72,7 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Eav\Model\Config $eavConfig
      * @param \Magento\Eav\Model\Entity\TypeFactory $eavTypeFactory
@@ -93,7 +94,7 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Eav\Model\Config $eavConfig,
         \Magento\Eav\Model\Entity\TypeFactory $eavTypeFactory,
@@ -115,7 +116,7 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $eavConfig,
             $eavTypeFactory,
diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php
index 0b9af7cceaa0747fb642f549866b96a02e0468f1..1510c2aad137a65fe3de9b8e515c50dd001d5571 100644
--- a/app/code/Magento/Catalog/Model/Product.php
+++ b/app/code/Magento/Catalog/Model/Product.php
@@ -237,6 +237,11 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
      */
     protected $imageCacheFactory;
 
+    /**
+     * @var \Magento\Catalog\Api\ProductAttributeRepositoryInterface
+     */
+    protected $metadataService;
+
     /**
      * @var \Magento\Framework\Api\DataObjectHelper
      */
@@ -245,9 +250,10 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $metadataService
      * @param Product\Url $url
      * @param Product\Link $productLink
      * @param Product\Configuration\Item\OptionFactory $itemOptionFactory
@@ -277,9 +283,10 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Catalog\Api\ProductAttributeRepositoryInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
+        \Magento\Catalog\Api\ProductAttributeRepositoryInterface $metadataService,
         Product\Url $url,
         Product\Link $productLink,
         \Magento\Catalog\Model\Product\Configuration\Item\OptionFactory $itemOptionFactory,
@@ -304,6 +311,7 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
         \Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
         array $data = []
     ) {
+        $this->metadataService = $metadataService;
         $this->_itemOptionFactory = $itemOptionFactory;
         $this->_stockItemFactory = $stockItemFactory;
         $this->_optionInstance = $catalogProductOption;
@@ -327,7 +335,7 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $storeManager,
             $resource,
@@ -346,6 +354,17 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
         $this->_init('Magento\Catalog\Model\Resource\Product');
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    protected function getCustomAttributesCodes()
+    {
+        if ($this->customAttributesCodes === null) {
+            $this->customAttributesCodes = $this->getEavAttributesCodes($this->metadataService);
+        }
+        return $this->customAttributesCodes;
+    }
+
     /**
      * Retrieve Store Id
      *
@@ -2215,5 +2234,26 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
     {
         return $this->setData(self::TYPE_ID, $typeId);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Catalog\Api\Data\ProductExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Catalog\Api\Data\ProductExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Catalog\Api\Data\ProductExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Group.php b/app/code/Magento/Catalog/Model/Product/Attribute/Group.php
index 97a6572077121baa53401bac3b9b8d58c85ee848..7bbabfc9b3fc8c2b62cfbb7e95a76a0c8f54cc7c 100644
--- a/app/code/Magento/Catalog/Model/Product/Attribute/Group.php
+++ b/app/code/Magento/Catalog/Model/Product/Attribute/Group.php
@@ -20,7 +20,7 @@ class Group extends \Magento\Eav\Model\Entity\Attribute\Group
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Catalog\Model\Resource\Product\Attribute\CollectionFactory $attributeCollectionFactory
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
@@ -30,7 +30,7 @@ class Group extends \Magento\Eav\Model\Entity\Attribute\Group
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Catalog\Model\Resource\Product\Attribute\CollectionFactory $attributeCollectionFactory,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
@@ -41,7 +41,7 @@ class Group extends \Magento\Eav\Model\Entity\Attribute\Group
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php b/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php
index 03799df3732029c155c4c182a649d4b4df429575..49fdcf4a8a892783d3fde5fb652f67cfbf6eee2d 100644
--- a/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php
+++ b/app/code/Magento/Catalog/Model/Product/Attribute/Repository.php
@@ -44,11 +44,6 @@ class Repository implements \Magento\Catalog\Api\ProductAttributeRepositoryInter
      */
     protected $filterManager;
 
-    /**
-     * @var \Magento\Framework\Api\Config\MetadataConfig
-     */
-    protected $metadataConfig;
-
     /**
      * @var \Magento\Framework\Api\SearchCriteriaBuilder
      */
@@ -66,7 +61,6 @@ class Repository implements \Magento\Catalog\Api\ProductAttributeRepositoryInter
      * @param \Magento\Eav\Api\AttributeRepositoryInterface $eavAttributeRepository
      * @param \Magento\Eav\Model\Config $eavConfig
      * @param \Magento\Eav\Model\Adminhtml\System\Config\Source\Inputtype\ValidatorFactory $validatorFactory
-     * @param \Magento\Framework\Api\Config\MetadataConfig $metadataConfig
      * @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
      * @param \Magento\Framework\Api\FilterBuilder $filterBuilder
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
@@ -78,7 +72,6 @@ class Repository implements \Magento\Catalog\Api\ProductAttributeRepositoryInter
         \Magento\Eav\Api\AttributeRepositoryInterface $eavAttributeRepository,
         \Magento\Eav\Model\Config $eavConfig,
         \Magento\Eav\Model\Adminhtml\System\Config\Source\Inputtype\ValidatorFactory $validatorFactory,
-        \Magento\Framework\Api\Config\MetadataConfig $metadataConfig,
         \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
         \Magento\Framework\Api\FilterBuilder $filterBuilder
     ) {
@@ -88,7 +81,6 @@ class Repository implements \Magento\Catalog\Api\ProductAttributeRepositoryInter
         $this->eavAttributeRepository = $eavAttributeRepository;
         $this->eavConfig = $eavConfig;
         $this->inputtypeValidatorFactory = $validatorFactory;
-        $this->metadataConfig = $metadataConfig;
         $this->searchCriteriaBuilder = $searchCriteriaBuilder;
         $this->filterBuilder = $filterBuilder;
     }
@@ -213,6 +205,7 @@ class Repository implements \Magento\Catalog\Api\ProductAttributeRepositoryInter
 
     /**
      * {@inheritdoc}
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function getCustomAttributesMetadata($dataObjectClassName = null)
     {
@@ -228,13 +221,7 @@ class Repository implements \Magento\Catalog\Api\ProductAttributeRepositoryInter
             ]
         );
 
-        $customAttributes = [];
-        $entityAttributes = $this->getList($searchCriteria->create())->getItems();
-
-        foreach ($entityAttributes as $attributeMetadata) {
-            $customAttributes[] = $attributeMetadata;
-        }
-        return array_merge($customAttributes, $this->metadataConfig->getCustomAttributesMetadata($dataObjectClassName));
+        return $this->getList($searchCriteria->create())->getItems();
     }
 
     /**
diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Type.php b/app/code/Magento/Catalog/Model/Product/Attribute/Type.php
index f3935642a168c4cf16050825e508d9f3c0470be7..a809df6591d7c34a04951cd6d330636f07ff3c05 100644
--- a/app/code/Magento/Catalog/Model/Product/Attribute/Type.php
+++ b/app/code/Magento/Catalog/Model/Product/Attribute/Type.php
@@ -1,9 +1,9 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
 namespace Magento\Catalog\Model\Product\Attribute;
 
 /**
@@ -49,4 +49,26 @@ class Type extends \Magento\Framework\Model\AbstractExtensibleModel implements
     {
         return $this->setData(self::LABEL, $label);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Catalog\Api\Data\ProductAttributeTypeExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Catalog\Api\Data\ProductAttributeTypeExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Catalog\Api\Data\ProductAttributeTypeExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/Product/Gallery/Entry.php b/app/code/Magento/Catalog/Model/Product/Gallery/Entry.php
index 3331ee24d7ee6415ef67e0ed4fdbc3aa0e266ccc..54c8123415d9050806de6a0509cc1c51b4828696 100644
--- a/app/code/Magento/Catalog/Model/Product/Gallery/Entry.php
+++ b/app/code/Magento/Catalog/Model/Product/Gallery/Entry.php
@@ -6,11 +6,14 @@
  */
 namespace Magento\Catalog\Model\Product\Gallery;
 
+use Magento\Framework\Model\AbstractExtensibleModel;
+use Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface;
+use Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryExtensionInterface;
+
 /**
  * @codeCoverageIgnore
  */
-class Entry extends \Magento\Framework\Model\AbstractExtensibleModel implements
-    \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface
+class Entry extends AbstractExtensibleModel implements ProductAttributeMediaGalleryEntryInterface
 {
     /**
      * Retrieve gallery entry ID
@@ -145,4 +148,25 @@ class Entry extends \Magento\Framework\Model\AbstractExtensibleModel implements
     {
         return $this->setData(self::CONTENT, $content);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return ProductAttributeMediaGalleryEntryExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param ProductAttributeMediaGalleryEntryExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(ProductAttributeMediaGalleryEntryExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/Product/GroupPrice.php b/app/code/Magento/Catalog/Model/Product/GroupPrice.php
index 531546e1a4a086f55fc2d2170e23b1d882f91f01..740a2b1b976b47d16b07166bb7551220cf779dbf 100644
--- a/app/code/Magento/Catalog/Model/Product/GroupPrice.php
+++ b/app/code/Magento/Catalog/Model/Product/GroupPrice.php
@@ -61,4 +61,26 @@ class GroupPrice extends \Magento\Framework\Model\AbstractExtensibleModel implem
     {
         return $this->setData(self::KEY_VALUE, $value);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Catalog\Api\Data\ProductGroupPriceExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Catalog\Api\Data\ProductGroupPriceExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Catalog\Api\Data\ProductGroupPriceExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/Product/Media/GalleryEntryContent.php b/app/code/Magento/Catalog/Model/Product/Media/GalleryEntryContent.php
index 4844a001a86add8567c691a387fa875049f7709e..48c0b4dc10739a0c8902656999fc856e701ca841 100644
--- a/app/code/Magento/Catalog/Model/Product/Media/GalleryEntryContent.php
+++ b/app/code/Magento/Catalog/Model/Product/Media/GalleryEntryContent.php
@@ -1,9 +1,9 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
 namespace Magento\Catalog\Model\Product\Media;
 
 /**
@@ -68,4 +68,26 @@ class GalleryEntryContent extends \Magento\Framework\Model\AbstractExtensibleMod
     {
         return $this->setData(self::NAME, $name);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryContentExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryContentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryContentExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/Product/Option.php b/app/code/Magento/Catalog/Model/Product/Option.php
index a6ba38bc1703dbb1becb1ea4404385ccdd81a757..3afdf86af8f964579c65ced1115c779102f3a8c7 100644
--- a/app/code/Magento/Catalog/Model/Product/Option.php
+++ b/app/code/Magento/Catalog/Model/Product/Option.php
@@ -9,11 +9,9 @@
 namespace Magento\Catalog\Model\Product;
 
 use Magento\Catalog\Api\Data\ProductCustomOptionValuesInterface;
-use Magento\Framework\Model\AbstractExtensibleModel;
 use Magento\Catalog\Model\Product;
 use Magento\Catalog\Model\Resource\Product\Option\Value\Collection;
 use Magento\Catalog\Pricing\Price\BasePrice;
-use Magento\Framework\Api\AttributeValueFactory;
 use Magento\Framework\Model\AbstractModel;
 use Magento\Framework\Exception\LocalizedException;
 
@@ -28,7 +26,7 @@ use Magento\Framework\Exception\LocalizedException;
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  * @SuppressWarnings(PHPMD.ExcessivePublicCount)
  */
-class Option extends AbstractExtensibleModel implements \Magento\Catalog\Api\Data\ProductCustomOptionInterface
+class Option extends AbstractModel implements \Magento\Catalog\Api\Data\ProductCustomOptionInterface
 {
     const OPTION_GROUP_TEXT = 'text';
 
@@ -118,8 +116,6 @@ class Option extends AbstractExtensibleModel implements \Magento\Catalog\Api\Dat
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Catalog\Api\CategoryAttributeRepositoryInterface $metadataService
-     * @param AttributeValueFactory $customAttributeFactory
      * @param Option\Value $productOptionValue
      * @param Option\Type\Factory $optionFactory
      * @param \Magento\Framework\Stdlib\String $string
@@ -132,8 +128,6 @@ class Option extends AbstractExtensibleModel implements \Magento\Catalog\Api\Dat
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Catalog\Api\CategoryAttributeRepositoryInterface $metadataService,
-        AttributeValueFactory $customAttributeFactory,
         Option\Value $productOptionValue,
         \Magento\Catalog\Model\Product\Option\Type\Factory $optionFactory,
         \Magento\Framework\Stdlib\String $string,
@@ -149,8 +143,6 @@ class Option extends AbstractExtensibleModel implements \Magento\Catalog\Api\Dat
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
-            $customAttributeFactory,
             $resource,
             $resourceCollection,
             $data
diff --git a/app/code/Magento/Catalog/Model/Product/Option/Type.php b/app/code/Magento/Catalog/Model/Product/Option/Type.php
index cb69c24a1c8ee27f32df3ac87c4bbbbc44b3b7cc..045bb591e8b3ea86e53f2db46c79c1ab3b54550e 100644
--- a/app/code/Magento/Catalog/Model/Product/Option/Type.php
+++ b/app/code/Magento/Catalog/Model/Product/Option/Type.php
@@ -82,4 +82,26 @@ class Type extends \Magento\Framework\Model\AbstractExtensibleModel implements
     {
         return $this->setData(self::KEY_GROUP, $group);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Catalog\Api\Data\ProductCustomOptionTypeExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Catalog\Api\Data\ProductCustomOptionTypeExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Catalog\Api\Data\ProductCustomOptionTypeExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/Product/Option/Value.php b/app/code/Magento/Catalog/Model/Product/Option/Value.php
index 37f706b2a8163bc125810af9deae309bf33ff413..227f070a683e75e67bf464442b8c5c5c35b7381e 100644
--- a/app/code/Magento/Catalog/Model/Product/Option/Value.php
+++ b/app/code/Magento/Catalog/Model/Product/Option/Value.php
@@ -8,10 +8,9 @@
 
 namespace Magento\Catalog\Model\Product\Option;
 
-use Magento\Framework\Model\AbstractExtensibleModel;
+use Magento\Framework\Model\AbstractModel;
 use Magento\Catalog\Model\Product;
 use Magento\Catalog\Model\Product\Option;
-use Magento\Framework\Api\AttributeValueFactory;
 
 /**
  * Catalog product option select type model
@@ -23,7 +22,7 @@ use Magento\Framework\Api\AttributeValueFactory;
  *
  * @SuppressWarnings(PHPMD.LongVariable)
  */
-class Value extends AbstractExtensibleModel implements \Magento\Catalog\Api\Data\ProductCustomOptionValuesInterface
+class Value extends AbstractModel implements \Magento\Catalog\Api\Data\ProductCustomOptionValuesInterface
 {
     /**
      * Option type percent
@@ -66,8 +65,6 @@ class Value extends AbstractExtensibleModel implements \Magento\Catalog\Api\Data
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Catalog\Api\CategoryAttributeRepositoryInterface $metadataService
-     * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Catalog\Model\Resource\Product\Option\Value\CollectionFactory $valueCollectionFactory
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
      * @param \Magento\Framework\Data\Collection\Db $resourceCollection
@@ -76,8 +73,6 @@ class Value extends AbstractExtensibleModel implements \Magento\Catalog\Api\Data
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Catalog\Api\CategoryAttributeRepositoryInterface $metadataService,
-        AttributeValueFactory $customAttributeFactory,
         \Magento\Catalog\Model\Resource\Product\Option\Value\CollectionFactory $valueCollectionFactory,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
         \Magento\Framework\Data\Collection\Db $resourceCollection = null,
@@ -87,8 +82,6 @@ class Value extends AbstractExtensibleModel implements \Magento\Catalog\Api\Data
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
-            $customAttributeFactory,
             $resource,
             $resourceCollection,
             $data
diff --git a/app/code/Magento/Catalog/Model/Product/TierPrice.php b/app/code/Magento/Catalog/Model/Product/TierPrice.php
index 6bc86d069d488df581917d40dac7a344791b2f39..4f28981a036f82c1da0c118483cd3f1bc5a1fb8f 100644
--- a/app/code/Magento/Catalog/Model/Product/TierPrice.php
+++ b/app/code/Magento/Catalog/Model/Product/TierPrice.php
@@ -54,4 +54,26 @@ class TierPrice extends \Magento\Framework\Model\AbstractExtensibleModel impleme
     {
         return $this->setData(self::VALUE, $value);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Catalog\Api\Data\ProductTierPriceExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Catalog\Api\Data\ProductTierPriceExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Catalog\Api\Data\ProductTierPriceExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/ProductLink/Attribute.php b/app/code/Magento/Catalog/Model/ProductLink/Attribute.php
index 2a2f15daa3d3856fa5aa14cf447a99f35d791253..ede2f7e22ebc204a430ca75884ab9a726df43510 100644
--- a/app/code/Magento/Catalog/Model/ProductLink/Attribute.php
+++ b/app/code/Magento/Catalog/Model/ProductLink/Attribute.php
@@ -57,4 +57,26 @@ class Attribute extends \Magento\Framework\Api\AbstractExtensibleObject implemen
     {
         return $this->setData(self::KEY_TYPE, $type);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Catalog\Api\Data\ProductLinkAttributeExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Catalog\Api\Data\ProductLinkAttributeExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Catalog\Api\Data\ProductLinkAttributeExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/ProductLink/Link.php b/app/code/Magento/Catalog/Model/ProductLink/Link.php
index e105ca4317652fdbb2bfb2ba6384ff1adf58d442..84fdd67df676b354d497de50667e43d0b949ea26 100644
--- a/app/code/Magento/Catalog/Model/ProductLink/Link.php
+++ b/app/code/Magento/Catalog/Model/ProductLink/Link.php
@@ -167,4 +167,30 @@ class Link extends \Magento\Framework\Model\AbstractExtensibleModel implements
     {
         return $this->setData(self::KEY_POSITION, $position);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Catalog\Api\Data\ProductLinkExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        if (!$this->_getExtensionAttributes()) {
+            $this->setExtensionAttributes(
+                $this->extensionAttributesFactory->create('Magento\Catalog\Model\ProductLink\Link')
+            );
+        }
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Catalog\Api\Data\ProductLinkExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Catalog\Api\Data\ProductLinkExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/ProductLink/Management.php b/app/code/Magento/Catalog/Model/ProductLink/Management.php
index 4f065bbd5b359153c0d048d74e04993be0f7979b..2987ebc079a4bb954b2c3de90b670b99dc7198d5 100644
--- a/app/code/Magento/Catalog/Model/ProductLink/Management.php
+++ b/app/code/Magento/Catalog/Model/ProductLink/Management.php
@@ -89,10 +89,7 @@ class Management implements \Magento\Catalog\Api\ProductLinkManagementInterface
                 ->setPosition($item['position']);
             if (isset($item['custom_attributes'])) {
                 foreach ($item['custom_attributes'] as $option) {
-                    $productLink->setCustomAttribute(
-                        $option['attribute_code'],
-                        $option['value']
-                    );
+                    $productLink->getExtensionAttributes()->setQty($option['value']);
                 }
             }
             $output[] = $productLink;
diff --git a/app/code/Magento/Catalog/Model/ProductLink/Repository.php b/app/code/Magento/Catalog/Model/ProductLink/Repository.php
index 800e7888c161df72985de30059fd7d68b140a868..386e7e8bb4d880942eed3f14ed575bd7b1eb3a49 100644
--- a/app/code/Magento/Catalog/Model/ProductLink/Repository.php
+++ b/app/code/Magento/Catalog/Model/ProductLink/Repository.php
@@ -34,21 +34,31 @@ class Repository implements \Magento\Catalog\Api\ProductLinkRepositoryInterface
     protected $linkManagement;
 
     /**
+     * @var \Magento\Framework\Reflection\DataObjectProcessor
+     */
+    protected $dataObjectProcessor;
+
+    /**
+     * Initialize dependencies.
+     *
      * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
      * @param CollectionProvider $entityCollectionProvider
      * @param LinksInitializer $linkInitializer
      * @param Management $linkManagement
+     * @param \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor
      */
     public function __construct(
         \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
         \Magento\Catalog\Model\ProductLink\CollectionProvider $entityCollectionProvider,
         \Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks $linkInitializer,
-        \Magento\Catalog\Model\ProductLink\Management $linkManagement
+        \Magento\Catalog\Model\ProductLink\Management $linkManagement,
+        \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor
     ) {
         $this->productRepository = $productRepository;
         $this->entityCollectionProvider = $entityCollectionProvider;
         $this->linkInitializer = $linkInitializer;
         $this->linkManagement = $linkManagement;
+        $this->dataObjectProcessor = $dataObjectProcessor;
     }
 
     /**
@@ -59,11 +69,16 @@ class Repository implements \Magento\Catalog\Api\ProductLinkRepositoryInterface
         $linkedProduct = $this->productRepository->get($entity->getLinkedProductSku());
         $product = $this->productRepository->get($entity->getProductSku());
         $links = $this->entityCollectionProvider->getCollection($product, $entity->getLinkType());
-
+        $extensions = $this->dataObjectProcessor->buildOutputDataArray(
+            $entity->getExtensionAttributes(),
+            'Magento\Catalog\Api\Data\ProductLinkExtensionInterface'
+        );
+        $extensions = is_array($extensions) ? $extensions : [];
         $data = $entity->__toArray();
-        foreach ($entity->getCustomAttributes() as $attribute) {
-            $data[$attribute->getAttributeCode()] = $attribute->getValue();
+        foreach ($extensions as $attributeCode => $attribute) {
+            $data[$attributeCode] = $attribute;
         }
+        unset($data['extension_attributes']);
         $data['product_id'] = $linkedProduct->getId();
         $links[$linkedProduct->getId()] = $data;
         $this->linkInitializer->initializeLinks($product, [$entity->getLinkType() => $links]);
diff --git a/app/code/Magento/Catalog/Model/ProductLink/Type.php b/app/code/Magento/Catalog/Model/ProductLink/Type.php
index 493bece24b31469e1b6d35608335a710949ec1f7..278662033f544a84c4121449205c05473f7a76f4 100644
--- a/app/code/Magento/Catalog/Model/ProductLink/Type.php
+++ b/app/code/Magento/Catalog/Model/ProductLink/Type.php
@@ -57,4 +57,26 @@ class Type extends \Magento\Framework\Api\AbstractExtensibleObject implements Pr
     {
         return $this->setData(self::KEY_NAME, $name);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Catalog\Api\Data\ProductLinkTypeExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Catalog\Api\Data\ProductLinkTypeExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Catalog\Api\Data\ProductLinkTypeExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php
index ffb6efb3f304d4fb095a03700ebdf5a676735165..284f7343cc629880a54d4898fc569b02599a76ed 100644
--- a/app/code/Magento/Catalog/Model/ProductRepository.php
+++ b/app/code/Magento/Catalog/Model/ProductRepository.php
@@ -76,6 +76,11 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
      */
     protected $eavConfig;
 
+    /**
+     * @var \Magento\Framework\Api\ExtensibleDataObjectConverter
+     */
+    protected $extensibleDataObjectConverter;
+
     /**
      * @param ProductFactory $productFactory
      * @param \Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper $initializationHelper
@@ -86,6 +91,7 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
      * @param Resource\Product $resourceModel
      * @param \Magento\Framework\Api\FilterBuilder $filterBuilder
      * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $metadataServiceInterface
+     * @param \Magento\Framework\Api\ExtensibleDataObjectConverter $extensibleDataObjectConverter
      * @param \Magento\Eav\Model\Config $eavConfig
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
@@ -99,6 +105,7 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
         \Magento\Catalog\Model\Resource\Product $resourceModel,
         \Magento\Framework\Api\FilterBuilder $filterBuilder,
         \Magento\Catalog\Api\ProductAttributeRepositoryInterface $metadataServiceInterface,
+        \Magento\Framework\Api\ExtensibleDataObjectConverter $extensibleDataObjectConverter,
         \Magento\Eav\Model\Config $eavConfig
     ) {
         $this->productFactory = $productFactory;
@@ -110,6 +117,7 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
         $this->attributeRepository = $attributeRepository;
         $this->filterBuilder = $filterBuilder;
         $this->metadataService = $metadataServiceInterface;
+        $this->extensibleDataObjectConverter = $extensibleDataObjectConverter;
         $this->eavConfig = $eavConfig;
     }
 
@@ -210,8 +218,16 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
      */
     public function save(\Magento\Catalog\Api\Data\ProductInterface $product, $saveOptions = false)
     {
+        if ($saveOptions) {
+            $productOptions = $product->getProductOptions();
+        }
+        $groupPrices = $product->getData('group_price');
+        $tierPrices = $product->getData('tier_price');
+
         $productId = $this->resourceModel->getIdBySku($product->getSku());
-        $product = $this->initializeProductData($product->toFlatArray(), empty($productId));
+        $productDataArray = $this->extensibleDataObjectConverter
+            ->toNestedArray($product, [], 'Magento\Catalog\Api\Data\ProductInterface');
+        $product = $this->initializeProductData($productDataArray, empty($productId));
         $validationResult = $this->resourceModel->validate($product);
         if (true !== $validationResult) {
             throw new \Magento\Framework\Exception\CouldNotSaveException(
@@ -220,8 +236,11 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
         }
         try {
             if ($saveOptions) {
+                $product->setProductOptions($productOptions);
                 $product->setCanSaveCustomOptions(true);
             }
+            $product->setData('group_price', $groupPrices);
+            $product->setData('tier_price', $tierPrices);
             $this->resourceModel->save($product);
         } catch (\Magento\Eav\Model\Entity\Attribute\Exception $exception) {
             throw \Magento\Framework\Exception\InputException::invalidFieldValue(
diff --git a/app/code/Magento/Catalog/Model/ProductType.php b/app/code/Magento/Catalog/Model/ProductType.php
index 2f5f266b2a6a0cf44456353cdf94252cf87f3bc3..ba9a7e5c4150d092bf100967d2ebc9599404f983 100644
--- a/app/code/Magento/Catalog/Model/ProductType.php
+++ b/app/code/Magento/Catalog/Model/ProductType.php
@@ -58,4 +58,26 @@ class ProductType extends \Magento\Framework\Api\AbstractExtensibleObject implem
     {
         return $this->setData(self::KEY_LABEL, $label);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Catalog\Api\Data\ProductTypeExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Catalog\Api\Data\ProductTypeExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Catalog\Api\Data\ProductTypeExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/Resource/Eav/Attribute.php b/app/code/Magento/Catalog/Model/Resource/Eav/Attribute.php
index 0a0800ce27bcd3617a68ead274a74662adcbf419..34f07aff2415de9ede946f1a30bbce63918d2f52 100644
--- a/app/code/Magento/Catalog/Model/Resource/Eav/Attribute.php
+++ b/app/code/Magento/Catalog/Model/Resource/Eav/Attribute.php
@@ -23,6 +23,7 @@ use Magento\Framework\Api\AttributeValueFactory;
  * @method int setSearchWeight(int $value)
  * @method \Magento\Catalog\Model\Resource\Eav\Attribute getIsUsedForPriceRules()
  * @method int setIsUsedForPriceRules(int $value)
+ * @method \Magento\Eav\Api\Data\AttributeExtensionInterface getExtensionAttributes()
  *
  * @author      Magento Core Team <core@magentocommerce.com>
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -88,7 +89,7 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute implements
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Eav\Model\Config $eavConfig
      * @param \Magento\Eav\Model\Entity\TypeFactory $eavTypeFactory
@@ -113,7 +114,7 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute implements
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Eav\Model\Config $eavConfig,
         \Magento\Eav\Model\Entity\TypeFactory $eavTypeFactory,
@@ -141,7 +142,7 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute implements
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $eavConfig,
             $eavTypeFactory,
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Category/AttributeRepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Category/AttributeRepositoryTest.php
index ffba8e8113717a370bd4cd1823ce7dd16136f3c7..c2c63a0ed168c2dab56f20bf9044fd9310bed2fa 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Category/AttributeRepositoryTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Category/AttributeRepositoryTest.php
@@ -34,11 +34,6 @@ class AttributeRepositoryTest extends \PHPUnit_Framework_TestCase
      */
     protected $attributeRepositoryMock;
 
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $metadataConfigMock;
-
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
@@ -57,8 +52,6 @@ class AttributeRepositoryTest extends \PHPUnit_Framework_TestCase
             $this->getMock('Magento\Framework\Api\FilterBuilder', [], [], '', false);
         $this->attributeRepositoryMock =
             $this->getMock('Magento\Eav\Api\AttributeRepositoryInterface', [], [], '', false);
-        $this->metadataConfigMock =
-            $this->getMock('Magento\Framework\Api\Config\MetadataConfig', [], [], '', false);
         $this->searchResultMock =
             $this->getMock(
                 'Magento\Framework\Api\SearchResultsInterface',
@@ -80,7 +73,6 @@ class AttributeRepositoryTest extends \PHPUnit_Framework_TestCase
         $this->model = (new ObjectManager($this))->getObject(
             'Magento\Catalog\Model\Category\AttributeRepository',
             [
-                'metadataConfig' => $this->metadataConfigMock,
                 'searchCriteriaBuilder' => $this->searchBuilderMock,
                 'filterBuilder' => $this->filterBuilderMock,
                 'eavAttributeRepository' => $this->attributeRepositoryMock,
@@ -131,9 +123,7 @@ class AttributeRepositoryTest extends \PHPUnit_Framework_TestCase
             $searchCriteriaMock
         )->willReturn($this->searchResultMock);
         $this->searchResultMock->expects($this->once())->method('getItems')->willReturn([$itemMock]);
-        $this->metadataConfigMock->expects($this->once())
-            ->method('getCustomAttributesMetadata')->with(null)->willReturn(['attribute']);
-        $expected = array_merge([$itemMock], ['attribute']);
+        $expected = [$itemMock];
 
         $this->assertEquals($expected, $this->model->getCustomAttributesMetadata(null));
     }
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Entity/AttributeTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Entity/AttributeTest.php
index 0ecf9b024aa0704ace1dfca1bdca098d9e8a5402..ca53d6b6fec5f0d7b2276692bdb65bd86a88b0d8 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Entity/AttributeTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Entity/AttributeTest.php
@@ -4,6 +4,8 @@
  * See COPYING.txt for license details.
  */
 
+// @codingStandardsIgnoreFile
+
 namespace Magento\Catalog\Test\Unit\Model\Entity;
 
 use Magento\Catalog\Model\Entity\Attribute;
@@ -114,6 +116,11 @@ class AttributeTest extends \PHPUnit_Framework_TestCase
      */
     private $dataObjectHelperMock;
 
+    /**
+     * @var \Magento\Framework\Api\ExtensionAttributesFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $extensionAttributesFactory;
+
     protected function setUp()
     {
         $this->contextMock = $this->getMockBuilder('Magento\Framework\Model\Context')
@@ -124,6 +131,9 @@ class AttributeTest extends \PHPUnit_Framework_TestCase
             ->getMock();
         $this->metadataServiceMock = $this->getMockBuilder('Magento\Framework\Api\MetadataServiceInterface')
             ->getMock();
+        $this->extensionAttributesFactory = $this->getMockBuilder('Magento\Framework\Api\ExtensionAttributesFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
         $this->attributeValueFactoryMock = $this->getMockBuilder('Magento\Framework\Api\AttributeValueFactory')
             ->disableOriginalConstructor()
             ->getMock();
@@ -181,7 +191,7 @@ class AttributeTest extends \PHPUnit_Framework_TestCase
         $this->attribute = new Attribute(
             $this->contextMock,
             $this->registryMock,
-            $this->metadataServiceMock,
+            $this->extensionAttributesFactory,
             $this->attributeValueFactoryMock,
             $this->configMock,
             $this->typeFactoryMock,
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ObserverTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ObserverTest.php
index d9d783495bd1332cd1d432a201e86e8b0b8969ea..5da2e23ba4b8268b5ec9b21a8b910a6c75597a46 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/ObserverTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ObserverTest.php
@@ -4,6 +4,8 @@
  * See COPYING.txt for license details.
  */
 
+// @codingStandardsIgnoreFile
+
 namespace Magento\Catalog\Test\Unit\Model;
 
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
@@ -63,7 +65,6 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
             ->getMock();
 
         $this->_observer = (new ObjectManager($this))->getObject('Magento\Catalog\Model\Observer', [
-            'urlFactory' => $this->_getCleanMock('\Magento\Catalog\Model\UrlFactory'),
             'categoryResource' => $this->_getCleanMock('\Magento\Catalog\Model\Resource\Category'),
             'catalogProduct' => $this->_getCleanMock('\Magento\Catalog\Model\Resource\Product'),
             'storeManager' => $this->_storeManager,
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/RepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/RepositoryTest.php
index 96744e487a0ddc76ed0ae8121e46e2233a152606..0689f5062dcca1d5ab7f07efd57b35de33e81b6d 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/RepositoryTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/RepositoryTest.php
@@ -87,8 +87,6 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
             [],
             '',
             false);
-        $this->metadataConfigMock =
-            $this->getMock('Magento\Framework\Api\Config\MetadataConfig', [], [], '', false);
         $this->searchCriteriaBuilderMock =
             $this->getMock('Magento\Framework\Api\SearchCriteriaBuilder', [], [], '', false);
         $this->filterBuilderMock =
@@ -116,7 +114,6 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
             $this->eavAttributeRepositoryMock,
             $this->eavConfigMock,
             $this->validatorFactoryMock,
-            $this->metadataConfigMock,
             $this->searchCriteriaBuilderMock,
             $this->filterBuilderMock
         );
@@ -196,11 +193,7 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
                 $searchCriteriaMock
             )->willReturn($this->searchResultMock);
         $this->searchResultMock->expects($this->once())->method('getItems')->willReturn([$itemMock]);
-        $this->metadataConfigMock->expects($this->once())
-            ->method('getCustomAttributesMetadata')
-            ->with(null)
-            ->willReturn(['Attribute metadata']);
-        $expected = array_merge([$itemMock], ['Attribute metadata']);
+        $expected = [$itemMock];
 
         $this->assertEquals($expected, $this->model->getCustomAttributesMetadata());
     }
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductLink/ManagementTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductLink/ManagementTest.php
index cf436ae14b35b862f0d8297f2c704115d90bee03..4fcdb62579697612abcce7d2a2e6dc79ce800b16 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/ProductLink/ManagementTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductLink/ManagementTest.php
@@ -3,6 +3,9 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
+// @codingStandardsIgnoreFile
+
 namespace Magento\Catalog\Test\Unit\Model\ProductLink;
 
 use Magento\Framework\Exception\NoSuchEntityException;
@@ -228,7 +231,8 @@ class ManagementTest extends \PHPUnit_Framework_TestCase
                     'getLinkedProductSku', 'getProductSku', 'getLinkType',
                     '__toArray', 'getLinkedProductType', 'getPosition', 'getCustomAttribute', 'getCustomAttributes',
                     'setCustomAttribute', 'setCustomAttributes', 'getMetadataServiceInterface',
-                    'setLinkedProductSku', 'setProductSku', 'setLinkType', 'setLinkedProductType', 'setPosition',
+                    'getExtensionAttributes', 'setExtensionAttributes',
+                    'setLinkedProductSku', 'setProductSku', 'setLinkType', 'setLinkedProductType', 'setPosition'
                 ]
             );
             $productLinkMock->expects($this->any())
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductLink/RepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductLink/RepositoryTest.php
index 24213fbc4ca9485260dff7ca74527fa015af6a0d..affded52e9586413fb24378919bf538fdf4b74fb 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/ProductLink/RepositoryTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductLink/RepositoryTest.php
@@ -3,6 +3,9 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
+// @codingStandardsIgnoreFile
+
 namespace Magento\Catalog\Test\Unit\Model\ProductLink;
 
 class RepositoryTest extends \PHPUnit_Framework_TestCase
@@ -28,6 +31,9 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
      */
     protected $linkInitializerMock;
 
+    /**
+     * Test method
+     */
     protected function setUp()
     {
         $linkManagementMock = $this->getMock('\Magento\Catalog\Model\ProductLink\Management', [], [], '', false);
@@ -58,6 +64,9 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
         );
     }
 
+    /**
+     * Test method
+     */
     public function testSave()
     {
         $entityMock = $this->getMock('\Magento\Catalog\Model\ProductLink\Link', [], [], '', false);
@@ -70,18 +79,14 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
                 ['linkedProduct', false, null, $linkedProductMock],
             ]
         ));
-        $customAttributeMock = $this->getMock('\Magento\Framework\Api\AttributeInterface');
-        $customAttributeMock->expects($this->once())->method('getAttributeCode')->willReturn('attribute_code');
-        $customAttributeMock->expects($this->once())->method('getValue')->willReturn('value');
         $entityMock->expects($this->once())->method('getLinkedProductSku')->willReturn('linkedProduct');
         $entityMock->expects($this->once())->method('getProductSku')->willReturn('product');
         $entityMock->expects($this->exactly(2))->method('getLinkType')->willReturn('linkType');
         $entityMock->expects($this->once())->method('__toArray')->willReturn([]);
-        $entityMock->expects($this->once())->method('getCustomAttributes')->willReturn([$customAttributeMock]);
         $linkedProductMock->expects($this->exactly(2))->method('getId')->willReturn(42);
         $this->entityCollectionProviderMock->expects($this->once())->method('getCollection')->willReturn([]);
         $this->linkInitializerMock->expects($this->once())->method('initializeLinks')->with($productMock, [
-            'linkType' => [42 => ['attribute_code' => 'value', 'product_id' => 42]]
+            'linkType' => [42 => ['product_id' => 42]]
         ]);
         $this->assertTrue($this->model->save($entityMock));
     }
@@ -101,10 +106,6 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
                 ['linkedProduct', false, null, $linkedProductMock],
             ]
         ));
-        $customAttributeMock = $this->getMock('\Magento\Framework\Api\AttributeInterface');
-        $customAttributeMock->expects($this->once())->method('getAttributeCode')->willReturn('attribute_code');
-        $customAttributeMock->expects($this->once())->method('getValue')->willReturn('value');
-        $entityMock->expects($this->once())->method('getCustomAttributes')->willReturn([$customAttributeMock]);
         $entityMock->expects($this->once())->method('getLinkedProductSku')->willReturn('linkedProduct');
         $entityMock->expects($this->once())->method('getProductSku')->willReturn('product');
         $entityMock->expects($this->exactly(2))->method('getLinkType')->willReturn('linkType');
@@ -112,12 +113,15 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
         $linkedProductMock->expects($this->exactly(2))->method('getId')->willReturn(42);
         $this->entityCollectionProviderMock->expects($this->once())->method('getCollection')->willReturn([]);
         $this->linkInitializerMock->expects($this->once())->method('initializeLinks')->with($productMock, [
-            'linkType' => [42 => ['attribute_code' => 'value', 'product_id' => 42]]
+            'linkType' => [42 => ['product_id' => 42]]
         ]);
         $productMock->expects($this->once())->method('save')->willThrowException(new \Exception());
         $this->model->save($entityMock);
     }
 
+    /**
+     * Test method
+     */
     public function testDelete()
     {
         $entityMock = $this->getMock('\Magento\Catalog\Model\ProductLink\Link', [], [], '', false);
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php
index 4a9f671bcdb570bb3a26900d7b66aa7482bb84e9..8a7930bb0f6d7243e66fc68fcbc51751d517f6d5 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php
@@ -4,6 +4,9 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
+// @codingStandardsIgnoreFile
+
 namespace Magento\Catalog\Test\Unit\Model;
 
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
@@ -65,6 +68,11 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
      */
     protected $eavConfigMock;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $extensibleDataObjectConverterMock;
+
     /**
      * @var array data to create product
      */
@@ -124,6 +132,12 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
             ->willReturn(new \Magento\Framework\Object(['default_attribute_set_id' => 4]));
         $this->objectManager = new ObjectManager($this);
 
+        $this->extensibleDataObjectConverterMock = $this
+            ->getMockBuilder('\Magento\Framework\Api\ExtensibleDataObjectConverter')
+            ->setMethods(['toNestedArray'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
         $this->model = $this->objectManager->getObject(
             'Magento\Catalog\Model\ProductRepository',
             [
@@ -135,6 +149,7 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
                 'searchCriteriaBuilder' => $this->searchCriteriaBuilderMock,
                 'metadataServiceInterface' => $this->metadataServiceMock,
                 'searchResultsFactory' => $this->searchResultsFactoryMock,
+                'extensibleDataObjectConverter' => $this->extensibleDataObjectConverterMock,
                 'eavConfig' => $this->eavConfigMock,
             ]
         );
@@ -252,30 +267,34 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
     public function testSaveExisting()
     {
         $this->resourceModelMock->expects($this->exactly(2))->method('getIdBySku')->will($this->returnValue(100));
-        $this->productMock->expects($this->once())->method('toFlatArray')->will($this->returnValue($this->productData));
         $this->productFactoryMock->expects($this->once())
             ->method('create')
             ->will($this->returnValue($this->productMock));
         $this->initializationHelperMock->expects($this->once())->method('initialize')->with($this->productMock);
         $this->resourceModelMock->expects($this->once())->method('validate')->with($this->productMock)
             ->willReturn(true);
-        $this->productMock->expects($this->once())->method('toFlatArray')->will($this->returnValue($this->productData));
         $this->resourceModelMock->expects($this->once())->method('save')->with($this->productMock)->willReturn(true);
+        $this->extensibleDataObjectConverterMock
+            ->expects($this->once())
+            ->method('toNestedArray')
+            ->will($this->returnValue($this->productData));
         $this->assertEquals($this->productMock, $this->model->save($this->productMock));
     }
 
     public function testSaveNew()
     {
         $this->resourceModelMock->expects($this->exactly(1))->method('getIdBySku')->will($this->returnValue(null));
-        $this->productMock->expects($this->once())->method('toFlatArray')->will($this->returnValue($this->productData));
         $this->productFactoryMock->expects($this->once())
             ->method('create')
             ->will($this->returnValue($this->productMock));
         $this->initializationHelperMock->expects($this->never())->method('initialize')->with($this->productMock);
         $this->resourceModelMock->expects($this->once())->method('validate')->with($this->productMock)
             ->willReturn(true);
-        $this->productMock->expects($this->once())->method('toFlatArray')->will($this->returnValue($this->productData));
         $this->resourceModelMock->expects($this->once())->method('save')->with($this->productMock)->willReturn(true);
+        $this->extensibleDataObjectConverterMock
+            ->expects($this->once())
+            ->method('toNestedArray')
+            ->will($this->returnValue($this->productData));
         $this->assertEquals($this->productMock, $this->model->save($this->productMock));
     }
 
@@ -286,7 +305,6 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
     public function testSaveUnableToSaveException()
     {
         $this->resourceModelMock->expects($this->exactly(1))->method('getIdBySku')->will($this->returnValue(null));
-        $this->productMock->expects($this->once())->method('toFlatArray')->will($this->returnValue($this->productData));
         $this->productFactoryMock->expects($this->once())
             ->method('create')
             ->will($this->returnValue($this->productMock));
@@ -295,6 +313,10 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
             ->willReturn(true);
         $this->resourceModelMock->expects($this->once())->method('save')->with($this->productMock)
             ->willThrowException(new \Exception());
+        $this->extensibleDataObjectConverterMock
+            ->expects($this->once())
+            ->method('toNestedArray')
+            ->will($this->returnValue($this->productData));
         $this->model->save($this->productMock);
     }
 
@@ -305,7 +327,6 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
     public function testSaveException()
     {
         $this->resourceModelMock->expects($this->exactly(1))->method('getIdBySku')->will($this->returnValue(null));
-        $this->productMock->expects($this->once())->method('toFlatArray')->will($this->returnValue($this->productData));
         $this->productFactoryMock->expects($this->once())
             ->method('create')
             ->will($this->returnValue($this->productMock));
@@ -315,6 +336,10 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
         $this->resourceModelMock->expects($this->once())->method('save')->with($this->productMock)
             ->willThrowException(new \Magento\Eav\Model\Entity\Attribute\Exception('123'));
         $this->productMock->expects($this->never())->method('getId');
+        $this->extensibleDataObjectConverterMock
+            ->expects($this->once())
+            ->method('toNestedArray')
+            ->will($this->returnValue($this->productData));
         $this->model->save($this->productMock);
     }
 
@@ -325,7 +350,6 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
     public function testSaveInvalidProductException()
     {
         $this->resourceModelMock->expects($this->exactly(1))->method('getIdBySku')->will($this->returnValue(null));
-        $this->productMock->expects($this->once())->method('toFlatArray')->will($this->returnValue($this->productData));
         $this->productFactoryMock->expects($this->once())
             ->method('create')
             ->will($this->returnValue($this->productMock));
@@ -333,6 +357,10 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
         $this->resourceModelMock->expects($this->once())->method('validate')->with($this->productMock)
             ->willReturn(['error1', 'error2']);
         $this->productMock->expects($this->never())->method('getId');
+        $this->extensibleDataObjectConverterMock
+            ->expects($this->once())
+            ->method('toNestedArray')
+            ->will($this->returnValue($this->productData));
         $this->model->save($this->productMock);
     }
 
diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockInterface.php
index 31aa3678440faeb85e0788a651a0a56f67318197..47bd9b85cc321a7a945c15d38304b4a97bf33059 100644
--- a/app/code/Magento/CatalogInventory/Api/Data/StockInterface.php
+++ b/app/code/Magento/CatalogInventory/Api/Data/StockInterface.php
@@ -62,4 +62,21 @@ interface StockInterface extends ExtensibleDataInterface
      * @return $this
      */
     public function setStockName($stockName);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\CatalogInventory\Api\Data\StockExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\CatalogInventory\Api\Data\StockExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\CatalogInventory\Api\Data\StockExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php
index e32c4178e5767f73b989f983446eebe1d8802a54..46163c26be6d3df33831a35e9344333ffeaef7ef 100644
--- a/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php
+++ b/app/code/Magento/CatalogInventory/Api/Data/StockItemInterface.php
@@ -398,4 +398,21 @@ interface StockItemInterface extends ExtensibleDataInterface
      * @return $this
      */
     public function setStockStatusChangedAuto($stockStatusChangedAuto);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\CatalogInventory\Api\Data\StockItemExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\CatalogInventory\Api\Data\StockItemExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\CatalogInventory\Api\Data\StockItemExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php b/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php
index 7788b53df36bf73670eab34f72e0532ce5f7e400..3c90ea451776a752c578ffb0e741de06fac46f3c 100644
--- a/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php
+++ b/app/code/Magento/CatalogInventory/Api/Data/StockStatusInterface.php
@@ -83,4 +83,21 @@ interface StockStatusInterface extends ExtensibleDataInterface
      * @return \Magento\CatalogInventory\Api\Data\StockItemInterface
      */
     public function getStockItem();
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\CatalogInventory\Api\Data\StockStatusExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\CatalogInventory\Api\Data\StockStatusExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\CatalogInventory\Api\Data\StockStatusExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php b/app/code/Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php
index fe76faa8934a55a6a68915f800849af506442f84..56c05595a2c4c93020ab65fe15be63086dbba902 100644
--- a/app/code/Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php
+++ b/app/code/Magento/CatalogInventory/Model/Adminhtml/Stock/Item.php
@@ -10,10 +10,11 @@ use Magento\CatalogInventory\Api\StockItemRepositoryInterface as StockItemReposi
 use Magento\CatalogInventory\Api\StockRegistryInterface;
 use Magento\Customer\Api\GroupManagementInterface;
 use Magento\Framework\Api\AttributeValueFactory;
-use Magento\Framework\Api\MetadataServiceInterface;
+use Magento\Framework\Api\ExtensionAttributesFactory;
 
 /**
  * Catalog Inventory Stock Model for adminhtml area
+ * @method \Magento\CatalogInventory\Api\Data\StockItemExtensionInterface getExtensionAttributes()
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class Item extends \Magento\CatalogInventory\Model\Stock\Item
@@ -26,7 +27,7 @@ class Item extends \Magento\CatalogInventory\Model\Stock\Item
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param MetadataServiceInterface $metadataService
+     * @param ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
@@ -42,7 +43,7 @@ class Item extends \Magento\CatalogInventory\Model\Stock\Item
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        MetadataServiceInterface $metadataService,
+        ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
@@ -57,7 +58,7 @@ class Item extends \Magento\CatalogInventory\Model\Stock\Item
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $customerSession,
             $storeManager,
diff --git a/app/code/Magento/CatalogInventory/Model/Stock.php b/app/code/Magento/CatalogInventory/Model/Stock.php
index 8ba03fa36a0727b8b52d13384e62d09f89d9af6e..1eed06294edaf05139695e5048ba6725e91de515 100644
--- a/app/code/Magento/CatalogInventory/Model/Stock.php
+++ b/app/code/Magento/CatalogInventory/Model/Stock.php
@@ -10,6 +10,7 @@ use Magento\Framework\Model\AbstractExtensibleModel;
 
 /**
  * Class Stock
+ *
  */
 class Stock extends AbstractExtensibleModel implements StockInterface
 {
@@ -119,5 +120,27 @@ class Stock extends AbstractExtensibleModel implements StockInterface
     {
         return $this->setData(self::STOCK_NAME, $stockName);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\CatalogInventory\Api\Data\StockExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\CatalogInventory\Api\Data\StockExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\CatalogInventory\Api\Data\StockExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/CatalogInventory/Model/Stock/Item.php b/app/code/Magento/CatalogInventory/Model/Stock/Item.php
index 322eb0812d8f88cd4e348afecb48494fb78a9921..cb622e904c6bbab1838275d66a5f9129e6640a24 100644
--- a/app/code/Magento/CatalogInventory/Model/Stock/Item.php
+++ b/app/code/Magento/CatalogInventory/Model/Stock/Item.php
@@ -11,7 +11,7 @@ use Magento\CatalogInventory\Api\StockConfigurationInterface as StockConfigurati
 use Magento\CatalogInventory\Api\StockItemRepositoryInterface as StockItemRepositoryInterface;
 use Magento\CatalogInventory\Api\StockRegistryInterface;
 use Magento\Framework\Api\AttributeValueFactory;
-use Magento\Framework\Api\MetadataServiceInterface;
+use Magento\Framework\Api\ExtensionAttributesFactory;
 use Magento\Framework\Model\AbstractExtensibleModel;
 
 /**
@@ -92,7 +92,7 @@ class Item extends AbstractExtensibleModel implements StockItemInterface
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param MetadataServiceInterface $metadataService
+     * @param ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
@@ -107,7 +107,7 @@ class Item extends AbstractExtensibleModel implements StockItemInterface
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        MetadataServiceInterface $metadataService,
+        ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
@@ -121,7 +121,7 @@ class Item extends AbstractExtensibleModel implements StockItemInterface
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
@@ -807,5 +807,27 @@ class Item extends AbstractExtensibleModel implements StockItemInterface
     {
         return $this->setData(self::STOCK_STATUS_CHANGED_AUTO, $stockStatusChangedAuto);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\CatalogInventory\Api\Data\StockItemExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\CatalogInventory\Api\Data\StockItemExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\CatalogInventory\Api\Data\StockItemExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/CatalogInventory/Model/Stock/Status.php b/app/code/Magento/CatalogInventory/Model/Stock/Status.php
index a930ab4169d2f86f50f3e9429b6eabaa95da4eec..4b91ba19d267e8dea109408f44978215d7c3f29c 100644
--- a/app/code/Magento/CatalogInventory/Model/Stock/Status.php
+++ b/app/code/Magento/CatalogInventory/Model/Stock/Status.php
@@ -9,7 +9,7 @@ use Magento\CatalogInventory\Api\Data\StockItemInterface;
 use Magento\CatalogInventory\Api\Data\StockStatusInterface;
 use Magento\CatalogInventory\Api\StockRegistryInterface;
 use Magento\Framework\Api\AttributeValueFactory;
-use Magento\Framework\Api\MetadataServiceInterface;
+use Magento\Framework\Api\ExtensionAttributesFactory;
 use Magento\Framework\Model\AbstractExtensibleModel;
 
 /**
@@ -38,7 +38,7 @@ class Status extends AbstractExtensibleModel implements StockStatusInterface
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param MetadataServiceInterface $metadataService
+     * @param ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param StockRegistryInterface $stockRegistry
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
@@ -48,7 +48,7 @@ class Status extends AbstractExtensibleModel implements StockStatusInterface
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        MetadataServiceInterface $metadataService,
+        ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         StockRegistryInterface $stockRegistry,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
@@ -58,7 +58,7 @@ class Status extends AbstractExtensibleModel implements StockStatusInterface
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
@@ -172,5 +172,27 @@ class Status extends AbstractExtensibleModel implements StockStatusInterface
     {
         return $this->setData(self::KEY_STOCK_STATUS, $stockStatus);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\CatalogInventory\Api\Data\StockStatusExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\CatalogInventory\Api\Data\StockStatusExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\CatalogInventory\Api\Data\StockStatusExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/CanonicalUrlRewriteGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/CanonicalUrlRewriteGenerator.php
index 749b746ca8e8e2853b8c29f7732753adf257dde0..1e71af266597a15bc4d580dffff8afb86ccf4e26 100644
--- a/app/code/Magento/CatalogUrlRewrite/Model/Category/CanonicalUrlRewriteGenerator.php
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/CanonicalUrlRewriteGenerator.php
@@ -39,12 +39,14 @@ class CanonicalUrlRewriteGenerator
      */
     public function generate($storeId, Category $category)
     {
-        return [
-            $this->urlRewriteFactory->create()->setStoreId($storeId)
+        $urlPath = $this->categoryUrlPathGenerator->getUrlPathWithSuffix($category, $storeId);
+        $result = [
+            $urlPath . '_' . $storeId => $this->urlRewriteFactory->create()->setStoreId($storeId)
                 ->setEntityType(CategoryUrlRewriteGenerator::ENTITY_TYPE)
                 ->setEntityId($category->getId())
-                ->setRequestPath($this->categoryUrlPathGenerator->getUrlPathWithSuffix($category, $storeId))
+                ->setRequestPath($urlPath)
                 ->setTargetPath($this->categoryUrlPathGenerator->getCanonicalUrlPath($category))
         ];
+        return $result;
     }
 }
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/Category/CurrentUrlRewritesRegenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/Category/CurrentUrlRewritesRegenerator.php
index fc7107801aca1499d67eb3ec16e6dbd385f7a588..6f0cfdb2b5ccd65a3de26d869daab89465728498 100644
--- a/app/code/Magento/CatalogUrlRewrite/Model/Category/CurrentUrlRewritesRegenerator.php
+++ b/app/code/Magento/CatalogUrlRewrite/Model/Category/CurrentUrlRewritesRegenerator.php
@@ -83,7 +83,7 @@ class CurrentUrlRewritesRegenerator
         if ($this->category->getData('save_rewrites_history')) {
             $targetPath = $this->categoryUrlPathGenerator->getUrlPathWithSuffix($this->category, $storeId);
             if ($url->getRequestPath() !== $targetPath) {
-                $urls[] = $this->urlRewriteFactory->create()
+                $urls[$url->getRequestPath() . '_' . $storeId] = $this->urlRewriteFactory->create()
                     ->setEntityType(CategoryUrlRewriteGenerator::ENTITY_TYPE)
                     ->setEntityId($this->category->getId())
                     ->setRequestPath($url->getRequestPath())
@@ -108,7 +108,7 @@ class CurrentUrlRewritesRegenerator
             ? $url->getTargetPath()
             : $this->categoryUrlPathGenerator->getUrlPathWithSuffix($this->category, $storeId);
         if ($url->getRequestPath() !== $targetPath) {
-            $urls[] = $this->urlRewriteFactory->create()
+            $urls[$url->getRequestPath() . '_' . $storeId] = $this->urlRewriteFactory->create()
                 ->setEntityType(CategoryUrlRewriteGenerator::ENTITY_TYPE)
                 ->setEntityId($this->category->getId())
                 ->setRequestPath($url->getRequestPath())
diff --git a/app/code/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteGenerator.php b/app/code/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteGenerator.php
index a8661bfdc9eaa358ead6ad52b74989d4bf705794..74158ce4093d3be02799dba710e235bbbc305095 100644
--- a/app/code/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteGenerator.php
+++ b/app/code/Magento/CatalogUrlRewrite/Model/ProductUrlRewriteGenerator.php
@@ -137,13 +137,22 @@ class ProductUrlRewriteGenerator
             }
         }
         $this->productCategories = $this->objectRegistryFactory->create(['entities' => $categories]);
+        /**
+         * @var $urls \Magento\UrlRewrite\Service\V1\Data\UrlRewrite[]
+         */
         $urls = array_merge(
             $this->canonicalUrlRewriteGenerator->generate($storeId, $this->product),
             $this->categoriesUrlRewriteGenerator->generate($storeId, $this->product, $this->productCategories),
             $this->currentUrlRewritesRegenerator->generate($storeId, $this->product, $this->productCategories)
         );
+
+        /* Reduce duplicates. Last wins */
+        $result = [];
+        foreach ($urls as $url) {
+            $result[$url->getTargetPath() . '-' . $url->getStoreId()] = $url;
+        }
         $this->productCategories = null;
-        return $urls;
+        return $result;
     }
 
     /**
diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/CanonicalUrlRewriteGeneratorTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/CanonicalUrlRewriteGeneratorTest.php
index 93a09f24ea8ac466b08ac4d8c2ce0d0771476a81..80983cad9beeda486da557f9b373216fbb993c54 100644
--- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/CanonicalUrlRewriteGeneratorTest.php
+++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/CanonicalUrlRewriteGeneratorTest.php
@@ -3,6 +3,7 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+// @codingStandardsIgnoreFile
 namespace Magento\CatalogUrlRewrite\Test\Unit\Model\Category;
 
 use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
@@ -70,7 +71,7 @@ class CanonicalUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnSelf());
         $this->urlRewriteFactory->expects($this->any())->method('create')->will($this->returnValue($this->urlRewrite));
         $this->assertEquals(
-            [$this->urlRewrite],
+            ['category.html_store_id' => $this->urlRewrite],
             $this->canonicalUrlRewriteGenerator->generate($storeId, $this->category)
         );
     }
diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/CurrentUrlRewritesRegeneratorTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/CurrentUrlRewritesRegeneratorTest.php
index db8545333579635b506339ead620e789fd8551de..4e1b56ce6eeb5c9c474b27606bda50a7c3e37456 100644
--- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/CurrentUrlRewritesRegeneratorTest.php
+++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/Category/CurrentUrlRewritesRegeneratorTest.php
@@ -3,6 +3,7 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+// @codingStandardsIgnoreFile
 namespace Magento\CatalogUrlRewrite\Test\Unit\Model\Category;
 
 use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;
@@ -128,7 +129,7 @@ class CurrentUrlRewritesRegeneratorTest extends \PHPUnit_Framework_TestCase
         $this->prepareUrlRewriteMock($storeId, $categoryId, $requestPath, $targetPath, OptionProvider::PERMANENT);
 
         $this->assertEquals(
-            [$this->urlRewrite],
+            ['autogenerated.html_2' => $this->urlRewrite],
             $this->currentUrlRewritesRegenerator->generate($storeId, $this->category)
         );
     }
@@ -191,7 +192,7 @@ class CurrentUrlRewritesRegeneratorTest extends \PHPUnit_Framework_TestCase
         $this->prepareUrlRewriteMock($storeId, $categoryId, $requestPath, $targetPath, 0);
 
         $this->assertEquals(
-            [$this->urlRewrite],
+            ['generate-for-custom-without-redirect-type.html_12' => $this->urlRewrite],
             $this->currentUrlRewritesRegenerator->generate($storeId, $this->category)
         );
     }
@@ -230,7 +231,7 @@ class CurrentUrlRewritesRegeneratorTest extends \PHPUnit_Framework_TestCase
         $this->prepareUrlRewriteMock($storeId, $categoryId, $requestPath, $targetPath, 'code');
 
         $this->assertEquals(
-            [$this->urlRewrite],
+            ['generate-for-custom-without-redirect-type.html_12' => $this->urlRewrite],
             $this->currentUrlRewritesRegenerator->generate($storeId, $this->category)
         );
     }
diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/CategoryUrlRewriteGeneratorTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/CategoryUrlRewriteGeneratorTest.php
index 239dcffcbba3ee19b64ef4fe372e6eb1336a50a5..c435eda8c7bd345a5a0c9e700e097a8362ee28c6 100644
--- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/CategoryUrlRewriteGeneratorTest.php
+++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/CategoryUrlRewriteGeneratorTest.php
@@ -3,6 +3,9 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
+// @codingStandardsIgnoreFile
+
 namespace Magento\CatalogUrlRewrite\Test\Unit\Model;
 
 use Magento\Catalog\Model\Category;
@@ -28,6 +31,9 @@ class CategoryUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Catalog\Model\Category|\PHPUnit_Framework_MockObject_MockObject */
     protected $category;
 
+    /**
+     * Test method
+     */
     protected function setUp()
     {
         $this->currentUrlRewritesRegenerator = $this->getMockBuilder(
@@ -54,39 +60,60 @@ class CategoryUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
         );
     }
 
+    /**
+     * Test method
+     */
     public function testGenerationForGlobalScope()
     {
         $this->category->expects($this->any())->method('getStoreId')->will($this->returnValue(null));
         $this->category->expects($this->any())->method('getStoreIds')->will($this->returnValue([1]));
         $this->storeViewService->expects($this->once())->method('doesEntityHaveOverriddenUrlKeyForStore')
             ->will($this->returnValue(false));
+        $canonical = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
+        $canonical->setTargetPath('category-1')
+            ->setStoreId(1);
         $this->canonicalUrlRewriteGenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue(['canonical']));
+            ->will($this->returnValue([$canonical]));
+        $children = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
+        $children->setTargetPath('category-2')
+            ->setStoreId(2);
         $this->childrenUrlRewriteGenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue(['children']));
+            ->will($this->returnValue([$children]));
+        $current = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
+        $current->setTargetPath('category-3')
+            ->setStoreId(3);
         $this->currentUrlRewritesRegenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue(['current']));
+            ->will($this->returnValue([$current]));
 
         $this->assertEquals(
-            ['canonical', 'children', 'current'],
+            [$canonical, $children, $current],
             $this->categoryUrlRewriteGenerator->generate($this->category)
         );
     }
 
+    /**
+     * Test method
+     */
     public function testGenerationForSpecificStore()
     {
         $this->category->expects($this->any())->method('getStoreId')->will($this->returnValue(1));
         $this->category->expects($this->never())->method('getStoreIds');
+        $canonical = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
+        $canonical->setTargetPath('category-1')
+            ->setStoreId(1);
         $this->canonicalUrlRewriteGenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue(['canonical']));
+            ->will($this->returnValue([$canonical]));
         $this->childrenUrlRewriteGenerator->expects($this->any())->method('generate')
             ->will($this->returnValue([]));
         $this->currentUrlRewritesRegenerator->expects($this->any())->method('generate')
             ->will($this->returnValue([]));
 
-        $this->assertEquals(['canonical'], $this->categoryUrlRewriteGenerator->generate($this->category));
+        $this->assertEquals([$canonical], $this->categoryUrlRewriteGenerator->generate($this->category));
     }
 
+    /**
+     * Test method
+     */
     public function testSkipGenerationForGlobalScope()
     {
         $this->category->expects($this->any())->method('getStoreIds')->will($this->returnValue([1, 2]));
diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/ProductUrlRewriteGeneratorTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/ProductUrlRewriteGeneratorTest.php
index 0608f755137936d1c6b8c612f3bb97f0c55d546e..861516a338f1bc8c92f86d98815741f78ef899b5 100644
--- a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/ProductUrlRewriteGeneratorTest.php
+++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Model/ProductUrlRewriteGeneratorTest.php
@@ -3,6 +3,9 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
+// @codingStandardsIgnoreFile
+
 namespace Magento\CatalogUrlRewrite\Test\Unit\Model;
 
 use Magento\Catalog\Model\Category;
@@ -37,6 +40,9 @@ class ProductUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Catalog\Model\Resource\Category\Collection|\PHPUnit_Framework_MockObject_MockObject */
     protected $categoriesCollection;
 
+    /**
+     * Test method
+     */
     protected function setUp()
     {
         $this->product = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false);
@@ -75,6 +81,9 @@ class ProductUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
         );
     }
 
+    /**
+     * Test method
+     */
     public function testGenerationForGlobalScope()
     {
         $this->product->expects($this->any())->method('getStoreId')->will($this->returnValue(null));
@@ -84,19 +93,31 @@ class ProductUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
         $this->categoriesCollection->expects($this->any())->method('getIterator')
             ->willReturn(new \ArrayIterator([]));
         $this->initObjectRegistryFactory([]);
+        $canonical = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
+        $canonical->setTargetPath('category-1')
+            ->setStoreId(1);
         $this->canonicalUrlRewriteGenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue(['canonical']));
+            ->will($this->returnValue([$canonical]));
+        $categories = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
+        $categories->setTargetPath('category-2')
+            ->setStoreId(2);
         $this->categoriesUrlRewriteGenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue(['categories']));
+            ->will($this->returnValue([$categories]));
+        $current = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
+        $current->setTargetPath('category-3')
+            ->setStoreId(3);
         $this->currentUrlRewritesRegenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue(['current']));
+            ->will($this->returnValue([$current]));
 
         $this->assertEquals(
-            ['canonical', 'categories', 'current'],
+            ['category-1-1' => $canonical, 'category-2-2' => $categories, 'category-3-3' => $current],
             $this->productUrlRewriteGenerator->generate($this->product)
         );
     }
 
+    /**
+     * Test method
+     */
     public function testGenerationForSpecificStore()
     {
         $this->product->expects($this->any())->method('getStoreId')->will($this->returnValue(1));
@@ -113,16 +134,22 @@ class ProductUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
         $this->categoriesCollection->expects($this->any())->method('getIterator')
             ->willReturn(new \ArrayIterator([$category]));
         $this->initObjectRegistryFactory([$category]);
+        $canonical = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
+        $canonical->setTargetPath('category-1')
+            ->setStoreId(1);
         $this->canonicalUrlRewriteGenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue(['canonical']));
+            ->will($this->returnValue([$canonical]));
         $this->categoriesUrlRewriteGenerator->expects($this->any())->method('generate')
             ->will($this->returnValue([]));
         $this->currentUrlRewritesRegenerator->expects($this->any())->method('generate')
             ->will($this->returnValue([]));
 
-        $this->assertEquals(['canonical'], $this->productUrlRewriteGenerator->generate($this->product));
+        $this->assertEquals(['category-1-1' => $canonical], $this->productUrlRewriteGenerator->generate($this->product));
     }
 
+    /**
+     * Test method
+     */
     public function testSkipRootCategoryForCategoriesGenerator()
     {
         $this->product->expects($this->any())->method('getStoreId')->will($this->returnValue(1));
@@ -136,16 +163,22 @@ class ProductUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
         $this->categoriesCollection->expects($this->any())->method('getIterator')
             ->willReturn(new \ArrayIterator([$rootCategory]));
         $this->initObjectRegistryFactory([]);
+        $canonical = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
+        $canonical->setTargetPath('category-1')
+            ->setStoreId(1);
         $this->canonicalUrlRewriteGenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue(['canonical']));
+            ->will($this->returnValue([$canonical]));
         $this->categoriesUrlRewriteGenerator->expects($this->any())->method('generate')
             ->will($this->returnValue([]));
         $this->currentUrlRewritesRegenerator->expects($this->any())->method('generate')
             ->will($this->returnValue([]));
 
-        $this->assertEquals(['canonical'], $this->productUrlRewriteGenerator->generate($this->product));
+        $this->assertEquals(['category-1-1' => $canonical], $this->productUrlRewriteGenerator->generate($this->product));
     }
 
+    /**
+     * Test method
+     */
     public function testSkipGenerationForNotStoreRootCategory()
     {
         $this->product->expects($this->any())->method('getStoreId')->will($this->returnValue(1));
@@ -159,16 +192,22 @@ class ProductUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
         $this->categoriesCollection->expects($this->any())->method('getIterator')
             ->willReturn(new \ArrayIterator([$category]));
         $this->initObjectRegistryFactory([]);
+        $canonical = new \Magento\UrlRewrite\Service\V1\Data\UrlRewrite();
+        $canonical->setTargetPath('category-1')
+            ->setStoreId(1);
         $this->canonicalUrlRewriteGenerator->expects($this->any())->method('generate')
-            ->will($this->returnValue(['canonical']));
+            ->will($this->returnValue([$canonical]));
         $this->categoriesUrlRewriteGenerator->expects($this->any())->method('generate')
             ->will($this->returnValue([]));
         $this->currentUrlRewritesRegenerator->expects($this->any())->method('generate')
             ->will($this->returnValue([]));
 
-        $this->assertEquals(['canonical'], $this->productUrlRewriteGenerator->generate($this->product));
+        $this->assertEquals(['category-1-1' => $canonical], $this->productUrlRewriteGenerator->generate($this->product));
     }
 
+    /**
+     * Test method
+     */
     public function testSkipGenerationForGlobalScope()
     {
         $this->product->expects($this->any())->method('getStoreIds')->will($this->returnValue([1, 2]));
diff --git a/app/code/Magento/CheckoutAgreements/Model/Agreement.php b/app/code/Magento/CheckoutAgreements/Model/Agreement.php
index ceca39fa477ea584e4a8531fd08c7a6baab76dc2..6f951c12d5b629bc304cb0d80933030654598d1b 100644
--- a/app/code/Magento/CheckoutAgreements/Model/Agreement.php
+++ b/app/code/Magento/CheckoutAgreements/Model/Agreement.php
@@ -6,9 +6,9 @@
 namespace Magento\CheckoutAgreements\Model;
 
 use Magento\CheckoutAgreements\Api\Data\AgreementInterface;
-use Magento\Framework\Model\AbstractExtensibleModel;
+use Magento\Framework\Model\AbstractModel;
 
-class Agreement extends AbstractExtensibleModel implements AgreementInterface
+class Agreement extends AbstractModel implements AgreementInterface
 {
     /**
      * Allowed CSS units for height field
diff --git a/app/code/Magento/ConfigurableProduct/Api/Data/OptionInterface.php b/app/code/Magento/ConfigurableProduct/Api/Data/OptionInterface.php
index 8f4bbba818b2cbef6eddadca0c2a357e0a32139b..82e73fe8686e268e1b3701c216fe3bb8a2d4ee95 100644
--- a/app/code/Magento/ConfigurableProduct/Api/Data/OptionInterface.php
+++ b/app/code/Magento/ConfigurableProduct/Api/Data/OptionInterface.php
@@ -84,4 +84,21 @@ interface OptionInterface extends \Magento\Framework\Api\ExtensibleDataInterface
      * @return $this
      */
     public function setValues(array $values = null);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\ConfigurableProduct\Api\Data\OptionExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\ConfigurableProduct\Api\Data\OptionExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\ConfigurableProduct\Api\Data\OptionExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/ConfigurableProduct/Api/Data/OptionValueInterface.php b/app/code/Magento/ConfigurableProduct/Api/Data/OptionValueInterface.php
index b24f4702da96fd9a496c709cf2523e53b3f86840..a6838c3b72d8d31f43457ecb7c356cefc0ed82be 100644
--- a/app/code/Magento/ConfigurableProduct/Api/Data/OptionValueInterface.php
+++ b/app/code/Magento/ConfigurableProduct/Api/Data/OptionValueInterface.php
@@ -40,4 +40,21 @@ interface OptionValueInterface extends \Magento\Framework\Api\ExtensibleDataInte
      * @return $this
      */
     public function setValueIndex($valueIndex);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\ConfigurableProduct\Api\Data\OptionValueExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\ConfigurableProduct\Api\Data\OptionValueExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\ConfigurableProduct\Api\Data\OptionValueExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Attribute.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Attribute.php
index d2e9954bd1cfa4fab7cb11016829042ebf36eb94..73c029fe5db46074da69204e5a48c6e90ea7959d 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Attribute.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Attribute.php
@@ -209,5 +209,27 @@ class Attribute extends \Magento\Framework\Model\AbstractExtensibleModel impleme
     {
         return $this->setData(self::KEY_VALUES, $values);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\ConfigurableProduct\Api\Data\OptionExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\ConfigurableProduct\Api\Data\OptionExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\ConfigurableProduct\Api\Data\OptionExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/OptionValue.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/OptionValue.php
index 7acd37f43cab707da519717e3788d4cd4156f0ee..8a551ed9e5f362d998da7e1504c178be0a1cd88b 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/OptionValue.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/OptionValue.php
@@ -9,6 +9,10 @@ namespace Magento\ConfigurableProduct\Model\Product\Type\Configurable;
 
 use Magento\ConfigurableProduct\Api\Data\OptionValueInterface;
 
+/**
+ * Class OptionValue
+ *
+ */
 class OptionValue extends \Magento\Framework\Model\AbstractExtensibleModel implements
     \Magento\ConfigurableProduct\Api\Data\OptionValueInterface
 {
@@ -44,6 +48,7 @@ class OptionValue extends \Magento\Framework\Model\AbstractExtensibleModel imple
     {
         return $this->getData(self::KEY_VALUE_INDEX);
     }
+
     /**
      * @param float $pricingValue
      * @return $this
@@ -70,5 +75,27 @@ class OptionValue extends \Magento\Framework\Model\AbstractExtensibleModel imple
     {
         return $this->setData(self::KEY_VALUE_INDEX, $valueIndex);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\ConfigurableProduct\Api\Data\OptionValueExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\ConfigurableProduct\Api\Data\OptionValueExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\ConfigurableProduct\Api\Data\OptionValueExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Customer/Api/Data/AddressInterface.php b/app/code/Magento/Customer/Api/Data/AddressInterface.php
index f1180ce71bb59440c7e10b08c0d848d903449ab4..d4828f5abc8e67580ca9abcfb338bffb8b172cdf 100644
--- a/app/code/Magento/Customer/Api/Data/AddressInterface.php
+++ b/app/code/Magento/Customer/Api/Data/AddressInterface.php
@@ -7,12 +7,10 @@
 
 namespace Magento\Customer\Api\Data;
 
-use Magento\Framework\Api\ExtensibleDataInterface;
-
 /**
  * Customer address interface.
  */
-interface AddressInterface extends ExtensibleDataInterface
+interface AddressInterface extends \Magento\Framework\Api\CustomAttributesDataInterface
 {
     /**#@+
      * Constants for keys of data array. Identical to the name of the getter in snake case
@@ -306,4 +304,19 @@ interface AddressInterface extends ExtensibleDataInterface
      * @return $this
      */
     public function setIsDefaultBilling($isDefaultBilling);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Customer\Api\Data\AddressExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Customer\Api\Data\AddressExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Customer\Api\Data\AddressExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Customer/Api/Data/AttributeMetadataInterface.php b/app/code/Magento/Customer/Api/Data/AttributeMetadataInterface.php
index 5db373c70a3ca8c662c0243ebe154209a553ad2b..d5af12db20d6176e3621b0b155eb083f704b0bba 100644
--- a/app/code/Magento/Customer/Api/Data/AttributeMetadataInterface.php
+++ b/app/code/Magento/Customer/Api/Data/AttributeMetadataInterface.php
@@ -9,7 +9,7 @@ namespace Magento\Customer\Api\Data;
 /**
  * Customer attribute metadata interface.
  */
-interface AttributeMetadataInterface
+interface AttributeMetadataInterface extends \Magento\Framework\Api\MetadataObjectInterface
 {
     /**#@+
      * Constants used as keys of data array
@@ -33,21 +33,6 @@ interface AttributeMetadataInterface
     const BACKEND_TYPE = 'backend_type';
     /**#@-*/
 
-    /**
-     * Retrieve code of the attribute.
-     *
-     * @return string
-     */
-    public function getAttributeCode();
-
-    /**
-     * Set attribute code
-     *
-     * @param string $attributeCode
-     * @return $this
-     */
-    public function setAttributeCode($attributeCode);
-
     /**
      * Frontend HTML for input element.
      *
diff --git a/app/code/Magento/Customer/Api/Data/CustomerInterface.php b/app/code/Magento/Customer/Api/Data/CustomerInterface.php
index a5b781439ae1b600a7e0495f35667be9d38a3031..78be9d556014ac871eff29a9053153033690a736 100644
--- a/app/code/Magento/Customer/Api/Data/CustomerInterface.php
+++ b/app/code/Magento/Customer/Api/Data/CustomerInterface.php
@@ -5,12 +5,10 @@
  */
 namespace Magento\Customer\Api\Data;
 
-use Magento\Framework\Api\ExtensibleDataInterface;
-
 /**
  * Customer interface.
  */
-interface CustomerInterface extends ExtensibleDataInterface
+interface CustomerInterface extends \Magento\Framework\Api\CustomAttributesDataInterface
 {
     /**#@+
      * Constants defined for keys of the data array. Identical to the name of the getter in snake case
@@ -320,4 +318,19 @@ interface CustomerInterface extends ExtensibleDataInterface
      * @return $this
      */
     public function setAddresses(array $addresses = null);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Customer\Api\Data\CustomerExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Customer\Api\Data\CustomerExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Customer\Api\Data\CustomerExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Customer/Api/Data/GroupInterface.php b/app/code/Magento/Customer/Api/Data/GroupInterface.php
index 9062e8f4732de593e20ccb813c333772e76b65a5..7bb583d433a33e3ad16129038c9c03d7abf95cb9 100644
--- a/app/code/Magento/Customer/Api/Data/GroupInterface.php
+++ b/app/code/Magento/Customer/Api/Data/GroupInterface.php
@@ -85,4 +85,19 @@ interface GroupInterface extends ExtensibleDataInterface
      * @return string|null
      */
     public function setTaxClassName($taxClassName);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Customer\Api\Data\GroupExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Customer\Api\Data\GroupExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Customer\Api\Data\GroupExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Customer/Api/Data/RegionInterface.php b/app/code/Magento/Customer/Api/Data/RegionInterface.php
index 2d698fefc473039ce85c4990262d074bee0a1c28..808274c02f051b2decca7e39a2f7d0b614ca22a6 100644
--- a/app/code/Magento/Customer/Api/Data/RegionInterface.php
+++ b/app/code/Magento/Customer/Api/Data/RegionInterface.php
@@ -65,4 +65,19 @@ interface RegionInterface extends ExtensibleDataInterface
      * @return $this
      */
     public function setRegionId($regionId);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Customer\Api\Data\RegionExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Customer\Api\Data\RegionExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Customer\Api\Data\RegionExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Customer/Block/Address/Renderer/DefaultRenderer.php b/app/code/Magento/Customer/Block/Address/Renderer/DefaultRenderer.php
index eff04d6e3d725842551df57e3d37b86db0a0bff1..1db7f1964955a8e524eba4c4125aefb9beae7e33 100644
--- a/app/code/Magento/Customer/Block/Address/Renderer/DefaultRenderer.php
+++ b/app/code/Magento/Customer/Block/Address/Renderer/DefaultRenderer.php
@@ -47,7 +47,7 @@ class DefaultRenderer extends AbstractBlock implements RendererInterface
      *
      * @param \Magento\Framework\View\Element\Context $context
      * @param ElementFactory $elementFactory
-     * @param \Magento\Directory\Model\CountryFactory $countryFactory ,
+     * @param \Magento\Directory\Model\CountryFactory $countryFactory
      * @param \Magento\Customer\Api\AddressMetadataInterface $metadataService
      * @param Mapper $addressMapper
      * @param array $data
diff --git a/app/code/Magento/Customer/Model/Address.php b/app/code/Magento/Customer/Model/Address.php
index 3aa89244fbefdb7886e674cd7e021a5d4575b984..9a66ec376f5641136eb146ddd9aae9ba66249013 100644
--- a/app/code/Magento/Customer/Model/Address.php
+++ b/app/code/Magento/Customer/Model/Address.php
@@ -9,7 +9,6 @@ use Magento\Customer\Api\AddressMetadataInterface;
 use Magento\Customer\Api\Data\AddressInterfaceFactory;
 use Magento\Customer\Api\Data\AddressInterface;
 use Magento\Customer\Api\Data\RegionInterfaceFactory;
-use Magento\Framework\Api\AttributeValueFactory;
 
 /**
  * Customer address model
@@ -45,14 +44,14 @@ class Address extends \Magento\Customer\Model\Address\AbstractAddress
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
-     * @param AttributeValueFactory $customAttributeFactory
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
+     * @param \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory
      * @param \Magento\Directory\Helper\Data $directoryData
      * @param \Magento\Eav\Model\Config $eavConfig
      * @param Address\Config $addressConfig
      * @param \Magento\Directory\Model\RegionFactory $regionFactory
      * @param \Magento\Directory\Model\CountryFactory $countryFactory
-     * @param AddressMetadataInterface $addressMetadataService
+     * @param AddressMetadataInterface $metadataService
      * @param AddressInterfaceFactory $addressDataFactory
      * @param RegionInterfaceFactory $regionDataFactory
      * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper
@@ -66,14 +65,14 @@ class Address extends \Magento\Customer\Model\Address\AbstractAddress
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
-        AttributeValueFactory $customAttributeFactory,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
+        \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory,
         \Magento\Directory\Helper\Data $directoryData,
         \Magento\Eav\Model\Config $eavConfig,
         \Magento\Customer\Model\Address\Config $addressConfig,
         \Magento\Directory\Model\RegionFactory $regionFactory,
         \Magento\Directory\Model\CountryFactory $countryFactory,
-        AddressMetadataInterface $addressMetadataService,
+        AddressMetadataInterface $metadataService,
         AddressInterfaceFactory $addressDataFactory,
         RegionInterfaceFactory $regionDataFactory,
         \Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
@@ -88,14 +87,14 @@ class Address extends \Magento\Customer\Model\Address\AbstractAddress
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $directoryData,
             $eavConfig,
             $addressConfig,
             $regionFactory,
             $countryFactory,
-            $addressMetadataService,
+            $metadataService,
             $addressDataFactory,
             $regionDataFactory,
             $dataObjectHelper,
diff --git a/app/code/Magento/Customer/Model/Address/AbstractAddress.php b/app/code/Magento/Customer/Model/Address/AbstractAddress.php
index 65c9db82bf0ee887255c4c05c774f8071fe7a61a..d6be608bea7a70cb267c91f215523f9e5d2a691a 100644
--- a/app/code/Magento/Customer/Model/Address/AbstractAddress.php
+++ b/app/code/Magento/Customer/Model/Address/AbstractAddress.php
@@ -12,7 +12,7 @@ use Magento\Customer\Api\Data\AddressInterface;
 use Magento\Customer\Api\Data\RegionInterfaceFactory;
 use Magento\Customer\Api\Data\RegionInterface;
 use Magento\Customer\Model\Data\Address as AddressData;
-use Magento\Framework\Api\AttributeValueFactory;
+use Magento\Framework\Model\AbstractExtensibleModel;
 
 /**
  * Address abstract model
@@ -29,7 +29,7 @@ use Magento\Framework\Api\AttributeValueFactory;
  * @method bool getShouldIgnoreValidation()
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
-class AbstractAddress extends \Magento\Framework\Model\AbstractExtensibleModel
+class AbstractAddress extends AbstractExtensibleModel
 {
     /**
      * Possible customer address types
@@ -96,7 +96,7 @@ class AbstractAddress extends \Magento\Framework\Model\AbstractExtensibleModel
     /**
      * @var AddressMetadataInterface
      */
-    protected $_addressMetadataService;
+    protected $metadataService;
 
     /**
      * @var AddressInterfaceFactory
@@ -116,14 +116,14 @@ class AbstractAddress extends \Magento\Framework\Model\AbstractExtensibleModel
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
-     * @param AttributeValueFactory $customAttributeFactory
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
+     * @param \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory
      * @param \Magento\Directory\Helper\Data $directoryData
      * @param \Magento\Eav\Model\Config $eavConfig
      * @param Config $addressConfig
      * @param \Magento\Directory\Model\RegionFactory $regionFactory
      * @param \Magento\Directory\Model\CountryFactory $countryFactory
-     * @param AddressMetadataInterface $addressMetadataService
+     * @param AddressMetadataInterface $metadataService
      * @param AddressInterfaceFactory $addressDataFactory
      * @param RegionInterfaceFactory $regionDataFactory
      * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper
@@ -135,14 +135,14 @@ class AbstractAddress extends \Magento\Framework\Model\AbstractExtensibleModel
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
-        AttributeValueFactory $customAttributeFactory,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
+        \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory,
         \Magento\Directory\Helper\Data $directoryData,
         \Magento\Eav\Model\Config $eavConfig,
         Config $addressConfig,
         \Magento\Directory\Model\RegionFactory $regionFactory,
         \Magento\Directory\Model\CountryFactory $countryFactory,
-        AddressMetadataInterface $addressMetadataService,
+        AddressMetadataInterface $metadataService,
         AddressInterfaceFactory $addressDataFactory,
         RegionInterfaceFactory $regionDataFactory,
         \Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
@@ -156,14 +156,14 @@ class AbstractAddress extends \Magento\Framework\Model\AbstractExtensibleModel
         $this->_addressConfig = $addressConfig;
         $this->_regionFactory = $regionFactory;
         $this->_countryFactory = $countryFactory;
-        $this->_addressMetadataService = $addressMetadataService;
+        $this->metadataService = $metadataService;
         $this->addressDataFactory = $addressDataFactory;
         $this->regionDataFactory = $regionDataFactory;
         $this->dataObjectHelper = $dataObjectHelper;
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
@@ -488,7 +488,7 @@ class AbstractAddress extends \Magento\Framework\Model\AbstractExtensibleModel
     {
         $addressId = $this->getId();
 
-        $attributes = $this->_addressMetadataService->getAllAttributesMetadata();
+        $attributes = $this->metadataService->getAllAttributesMetadata();
         $addressData = [];
         foreach ($attributes as $attribute) {
             $code = $attribute->getAttributeCode();
diff --git a/app/code/Magento/Customer/Model/Customer.php b/app/code/Magento/Customer/Model/Customer.php
index c4d6a3e6c360e3f38740f0710839ab483de8dca5..cefc5f867f66f30274cbf6007f18d13856189979 100644
--- a/app/code/Magento/Customer/Model/Customer.php
+++ b/app/code/Magento/Customer/Model/Customer.php
@@ -13,7 +13,6 @@ use Magento\Customer\Model\Resource\Customer as ResourceCustomer;
 use Magento\Customer\Api\Data\CustomerInterfaceFactory;
 use Magento\Customer\Model\Data\Customer as CustomerData;
 use Magento\Framework\Reflection\DataObjectProcessor;
-use Magento\Framework\Api\AttributeValueFactory;
 use Magento\Framework\Exception\EmailNotConfirmedException;
 use Magento\Framework\Exception\InvalidEmailOrPasswordException;
 use Magento\Framework\Exception\AuthenticationException;
@@ -39,7 +38,7 @@ use Magento\Framework\Exception\AuthenticationException;
  * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
-class Customer extends \Magento\Framework\Model\AbstractExtensibleModel
+class Customer extends \Magento\Framework\Model\AbstractModel
 {
     /**
      * Configuration paths for email templates and identities
@@ -194,18 +193,21 @@ class Customer extends \Magento\Framework\Model\AbstractExtensibleModel
      */
     protected $dataObjectHelper;
 
+    /**
+     * @var \Magento\Customer\Api\CustomerMetadataInterface
+     */
+    protected $metadataService;
+
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
-     * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Eav\Model\Config $config
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param Resource\Customer $resource
-     * @param Config\Share $configShare
+     * @param ResourceCustomer $resource
+     * @param Share $configShare
      * @param AddressFactory $addressFactory
-     * @param Resource\Address\CollectionFactory $addressesFactory
+     * @param CollectionFactory $addressesFactory
      * @param \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder
      * @param GroupRepositoryInterface $groupRepository
      * @param AttributeFactory $attributeFactory
@@ -214,6 +216,7 @@ class Customer extends \Magento\Framework\Model\AbstractExtensibleModel
      * @param CustomerInterfaceFactory $customerDataFactory
      * @param DataObjectProcessor $dataObjectProcessor
      * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper
+     * @param CustomerMetadataInterface $metadataService
      * @param \Magento\Framework\Data\Collection\Db $resourceCollection
      * @param array $data
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
@@ -221,8 +224,6 @@ class Customer extends \Magento\Framework\Model\AbstractExtensibleModel
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
-        AttributeValueFactory $customAttributeFactory,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Eav\Model\Config $config,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
@@ -237,9 +238,11 @@ class Customer extends \Magento\Framework\Model\AbstractExtensibleModel
         CustomerInterfaceFactory $customerDataFactory,
         DataObjectProcessor $dataObjectProcessor,
         \Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
+        \Magento\Customer\Api\CustomerMetadataInterface $metadataService,
         \Magento\Framework\Data\Collection\Db $resourceCollection = null,
         array $data = []
     ) {
+        $this->metadataService = $metadataService;
         $this->_scopeConfig = $scopeConfig;
         $this->_storeManager = $storeManager;
         $this->_config = $config;
@@ -256,8 +259,6 @@ class Customer extends \Magento\Framework\Model\AbstractExtensibleModel
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
-            $customAttributeFactory,
             $resource,
             $resourceCollection,
             $data
diff --git a/app/code/Magento/Customer/Model/Data/Address.php b/app/code/Magento/Customer/Model/Data/Address.php
index a4785786c8c21bbc0fa720e86646b933acd60ab8..d44fbda0bbba599c71f28e661dd3b65695b8e2ed 100644
--- a/app/code/Magento/Customer/Model/Data/Address.php
+++ b/app/code/Magento/Customer/Model/Data/Address.php
@@ -10,20 +10,43 @@ namespace Magento\Customer\Model\Data;
 use Magento\Customer\Api\Data\RegionInterface;
 use \Magento\Framework\Api\AttributeValueFactory;
 
+/**
+ * Class Address
+ *
+ */
 class Address extends \Magento\Framework\Api\AbstractExtensibleObject implements
     \Magento\Customer\Api\Data\AddressInterface
 {
     /**
-     * @param \Magento\Customer\Api\AddressMetadataInterface $metadataService
+     * @var \Magento\Customer\Api\AddressMetadataInterface
+     */
+    protected $metadataService;
+
+    /**
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $attributeValueFactory
+     * @param \Magento\Customer\Api\AddressMetadataInterface $metadataService
      * @param array $data
      */
     public function __construct(
-        \Magento\Customer\Api\AddressMetadataInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $attributeValueFactory,
+        \Magento\Customer\Api\AddressMetadataInterface $metadataService,
         $data = []
     ) {
-        parent::__construct($metadataService, $attributeValueFactory, $data);
+        $this->metadataService = $metadataService;
+        parent::__construct($extensionFactory, $attributeValueFactory, $data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getCustomAttributesCodes()
+    {
+        if ($this->customAttributesCodes === null) {
+            $this->customAttributesCodes = $this->getEavAttributesCodes($this->metadataService);
+        }
+        return $this->customAttributesCodes;
     }
 
     /**
@@ -403,4 +426,25 @@ class Address extends \Magento\Framework\Api\AbstractExtensibleObject implements
     {
         return $this->setData(self::DEFAULT_BILLING, $isDefaultBilling);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Customer\Api\Data\AddressExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Customer\Api\Data\AddressExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Customer\Api\Data\AddressExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Customer/Model/Data/AttributeMetadata.php b/app/code/Magento/Customer/Model/Data/AttributeMetadata.php
index 5b4010e4ebc408495d91efcd94e870e5c71be4f9..dbf7feb726e23ba71d7bbf9dcef3b79a4433c1d7 100644
--- a/app/code/Magento/Customer/Model/Data/AttributeMetadata.php
+++ b/app/code/Magento/Customer/Model/Data/AttributeMetadata.php
@@ -9,7 +9,7 @@ namespace Magento\Customer\Model\Data;
 /**
  * Customer attribute metadata class.
  */
-class AttributeMetadata extends \Magento\Framework\Api\AbstractExtensibleObject implements
+class AttributeMetadata extends \Magento\Framework\Api\AbstractSimpleObject implements
     \Magento\Customer\Api\Data\AttributeMetadataInterface
 {
     /**
diff --git a/app/code/Magento/Customer/Model/Data/Customer.php b/app/code/Magento/Customer/Model/Data/Customer.php
index 995bdd421c93383298a0106a70da28b3530b8d8a..4daf096e5ccd15268988e368107e41db8c48dcc2 100644
--- a/app/code/Magento/Customer/Model/Data/Customer.php
+++ b/app/code/Magento/Customer/Model/Data/Customer.php
@@ -6,23 +6,47 @@
 
 namespace Magento\Customer\Model\Data;
 
-use Magento\Customer\Api\Data\CustomerInterface;
 use \Magento\Framework\Api\AttributeValueFactory;
 
+/**
+ * Class Customer
+ *
+ */
 class Customer extends \Magento\Framework\Api\AbstractExtensibleObject implements
     \Magento\Customer\Api\Data\CustomerInterface
 {
     /**
-     * @param \Magento\Customer\Api\CustomerMetadataInterface $metadataService
+     * @var \Magento\Customer\Api\CustomerMetadataInterface
+     */
+    protected $metadataService;
+
+    /**
+     * Initialize dependencies.
+     *
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $attributeValueFactory
+     * @param \Magento\Customer\Api\CustomerMetadataInterface $metadataService
      * @param array $data
      */
     public function __construct(
-        \Magento\Customer\Api\CustomerMetadataInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $attributeValueFactory,
+        \Magento\Customer\Api\CustomerMetadataInterface $metadataService,
         $data = []
     ) {
-        parent::__construct($metadataService, $attributeValueFactory, $data);
+        $this->metadataService = $metadataService;
+        parent::__construct($extensionFactory, $attributeValueFactory, $data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getCustomAttributesCodes()
+    {
+        if ($this->customAttributesCodes === null) {
+            $this->customAttributesCodes = $this->getEavAttributesCodes($this->metadataService);
+        }
+        return $this->customAttributesCodes;
     }
 
     /**
@@ -421,4 +445,25 @@ class Customer extends \Magento\Framework\Api\AbstractExtensibleObject implement
     {
         return $this->setData(self::KEY_ADDRESSES, $addresses);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Customer\Api\Data\CustomerExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Customer\Api\Data\CustomerExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Customer\Api\Data\CustomerExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Customer/Model/Data/Group.php b/app/code/Magento/Customer/Model/Data/Group.php
index 7f2883670308e7d37231282922a5d306ba661b00..9edc461f982c0a963f6c8aa29c8e391ffd81ef08 100644
--- a/app/code/Magento/Customer/Model/Data/Group.php
+++ b/app/code/Magento/Customer/Model/Data/Group.php
@@ -95,4 +95,25 @@ class Group extends \Magento\Framework\Api\AbstractExtensibleObject implements
     {
         return $this->setData(self::TAX_CLASS_NAME, $taxClassName);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Customer\Api\Data\GroupExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Customer\Api\Data\GroupExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Customer\Api\Data\GroupExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Customer/Model/Data/Option.php b/app/code/Magento/Customer/Model/Data/Option.php
index 7ebf6893d15136b692a1eb05e5d4049d1f4d97c3..080f9449ca1443555645d06ca7ad4f6d5af0d2a1 100644
--- a/app/code/Magento/Customer/Model/Data/Option.php
+++ b/app/code/Magento/Customer/Model/Data/Option.php
@@ -11,7 +11,7 @@ namespace Magento\Customer\Model\Data;
 /**
  * Class Option
  */
-class Option extends \Magento\Framework\Api\AbstractExtensibleObject implements
+class Option extends \Magento\Framework\Api\AbstractSimpleObject implements
     \Magento\Customer\Api\Data\OptionInterface
 {
     /**
diff --git a/app/code/Magento/Customer/Model/Data/Region.php b/app/code/Magento/Customer/Model/Data/Region.php
index 42b5a1c944afbca4b58284ebcb1617c40c6af27c..ddea4c3a90ceb1597c497b516cd53a656548c2dd 100644
--- a/app/code/Magento/Customer/Model/Data/Region.php
+++ b/app/code/Magento/Customer/Model/Data/Region.php
@@ -7,6 +7,7 @@ namespace Magento\Customer\Model\Data;
 
 /**
  * Data Model implementing Address Region interface
+ *
  */
 class Region extends \Magento\Framework\Api\AbstractExtensibleObject implements
     \Magento\Customer\Api\Data\RegionInterface
@@ -73,4 +74,25 @@ class Region extends \Magento\Framework\Api\AbstractExtensibleObject implements
     {
         return $this->setData(self::REGION_ID, $regionId);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Customer\Api\Data\RegionExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Customer\Api\Data\RegionExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Customer\Api\Data\RegionExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Customer/Model/Data/ValidationResults.php b/app/code/Magento/Customer/Model/Data/ValidationResults.php
index 684b451360d4c8be6180ad0e86cf8ef0464a21bc..6c473ed0f167da0aa95aee4f42e8b1044549d595 100644
--- a/app/code/Magento/Customer/Model/Data/ValidationResults.php
+++ b/app/code/Magento/Customer/Model/Data/ValidationResults.php
@@ -10,7 +10,7 @@ namespace Magento\Customer\Model\Data;
 /**
  * Validation results data model.
  */
-class ValidationResults extends \Magento\Framework\Api\AbstractExtensibleObject implements
+class ValidationResults extends \Magento\Framework\Api\AbstractSimpleObject implements
     \Magento\Customer\Api\Data\ValidationResultsInterface
 {
     /**
diff --git a/app/code/Magento/Customer/Model/Data/ValidationRule.php b/app/code/Magento/Customer/Model/Data/ValidationRule.php
index 5d8234cce281a0439e083e5e1b5d997f2bff6a0f..ce5a4a419a8e2fc962dbb2e7d5df4e4cb52a10cc 100644
--- a/app/code/Magento/Customer/Model/Data/ValidationRule.php
+++ b/app/code/Magento/Customer/Model/Data/ValidationRule.php
@@ -7,7 +7,7 @@ namespace Magento\Customer\Model\Data;
 
 use Magento\Customer\Api\Data\ValidationRuleInterface;
 
-class ValidationRule extends \Magento\Framework\Api\AbstractExtensibleObject implements
+class ValidationRule extends \Magento\Framework\Api\AbstractSimpleObject implements
     \Magento\Customer\Api\Data\ValidationRuleInterface
 {
     /**
diff --git a/app/code/Magento/Customer/Model/Group.php b/app/code/Magento/Customer/Model/Group.php
index 252b62393b6d9c24136fba6bb59990ac982837cf..b11d73f55bfac12c7f9b6f7a28cc271441543e8e 100644
--- a/app/code/Magento/Customer/Model/Group.php
+++ b/app/code/Magento/Customer/Model/Group.php
@@ -5,8 +5,6 @@
  */
 namespace Magento\Customer\Model;
 
-use Magento\Framework\Api\AttributeValueFactory;
-
 /**
  * Customer group model
  *
@@ -17,7 +15,7 @@ use Magento\Framework\Api\AttributeValueFactory;
  * @method \Magento\Customer\Model\Group setTaxClassId(int $value)
  * @method Group setTaxClassName(string $value)
  */
-class Group extends \Magento\Framework\Model\AbstractExtensibleModel
+class Group extends \Magento\Framework\Model\AbstractModel
 {
     const NOT_LOGGED_IN_ID = 0;
 
@@ -63,8 +61,6 @@ class Group extends \Magento\Framework\Model\AbstractExtensibleModel
      *
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
-     * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Store\Model\StoresConfig $storesConfig
      * @param \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor
      * @param \Magento\Tax\Model\ClassModelFactory $classModelFactory
@@ -76,8 +72,6 @@ class Group extends \Magento\Framework\Model\AbstractExtensibleModel
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
-        AttributeValueFactory $customAttributeFactory,
         \Magento\Store\Model\StoresConfig $storesConfig,
         \Magento\Framework\Reflection\DataObjectProcessor $dataObjectProcessor,
         \Magento\Tax\Model\ClassModelFactory $classModelFactory,
@@ -91,8 +85,6 @@ class Group extends \Magento\Framework\Model\AbstractExtensibleModel
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
-            $customAttributeFactory,
             $resource,
             $resourceCollection,
             $data
diff --git a/app/code/Magento/Customer/Model/Metadata/AddressMetadata.php b/app/code/Magento/Customer/Model/Metadata/AddressMetadata.php
index 08a1ea6a1d263ee28d42fe18c79c01b5ea5c4bb3..0095cb509e2ee4c0ae8419327f4d1507961a841f 100644
--- a/app/code/Magento/Customer/Model/Metadata/AddressMetadata.php
+++ b/app/code/Magento/Customer/Model/Metadata/AddressMetadata.php
@@ -10,7 +10,6 @@ use Magento\Customer\Api\AddressMetadataInterface;
 use Magento\Customer\Model\AttributeMetadataConverter;
 use Magento\Customer\Model\AttributeMetadataDataProvider;
 use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
-use Magento\Framework\Api\Config\MetadataConfig;
 use Magento\Framework\Api\SimpleDataObjectConverter;
 use Magento\Framework\Exception\NoSuchEntityException;
 
@@ -24,11 +23,6 @@ class AddressMetadata implements AddressMetadataInterface
      */
     private $addressDataObjectMethods;
 
-    /**
-     * @var MetadataConfig
-     */
-    private $metadataConfig;
-
     /**
      * @var AttributeMetadataConverter
      */
@@ -40,16 +34,13 @@ class AddressMetadata implements AddressMetadataInterface
     private $attributeMetadataDataProvider;
 
     /**
-     * @param MetadataConfig $metadataConfig
      * @param AttributeMetadataConverter $attributeMetadataConverter
      * @param AttributeMetadataDataProvider $attributeMetadataDataProvider
      */
     public function __construct(
-        MetadataConfig $metadataConfig,
         AttributeMetadataConverter $attributeMetadataConverter,
         AttributeMetadataDataProvider $attributeMetadataDataProvider
     ) {
-        $this->metadataConfig = $metadataConfig;
         $this->attributeMetadataConverter = $attributeMetadataConverter;
         $this->attributeMetadataDataProvider = $attributeMetadataDataProvider;
     }
@@ -127,7 +118,6 @@ class AddressMetadata implements AddressMetadataInterface
      */
     public function getCustomAttributesMetadata($dataObjectClassName = AddressMetadataInterface::DATA_INTERFACE_NAME)
     {
-        $customAttributes = [];
         if (!$this->addressDataObjectMethods) {
             $dataObjectMethods = array_flip(get_class_methods($dataObjectClassName));
             $baseClassDataObjectMethods = array_flip(
@@ -135,6 +125,7 @@ class AddressMetadata implements AddressMetadataInterface
             );
             $this->addressDataObjectMethods = array_diff_key($dataObjectMethods, $baseClassDataObjectMethods);
         }
+        $customAttributes = [];
         foreach ($this->getAllAttributesMetadata() as $attributeMetadata) {
             $attributeCode = $attributeMetadata->getAttributeCode();
             $camelCaseKey = SimpleDataObjectConverter::snakeCaseToUpperCamelCase($attributeCode);
@@ -145,6 +136,6 @@ class AddressMetadata implements AddressMetadataInterface
                 $customAttributes[] = $attributeMetadata;
             }
         }
-        return array_merge($customAttributes, $this->metadataConfig->getCustomAttributesMetadata($dataObjectClassName));
+        return $customAttributes;
     }
 }
diff --git a/app/code/Magento/Customer/Model/Metadata/CustomerMetadata.php b/app/code/Magento/Customer/Model/Metadata/CustomerMetadata.php
index 46e696cb17f86639ab00ba9bebcf3b62ad9a3ca7..91c017f2c3726fbca7e1c088d2ae12c4318b8f20 100644
--- a/app/code/Magento/Customer/Model/Metadata/CustomerMetadata.php
+++ b/app/code/Magento/Customer/Model/Metadata/CustomerMetadata.php
@@ -10,7 +10,6 @@ use Magento\Customer\Api\CustomerMetadataInterface;
 use Magento\Customer\Model\AttributeMetadataConverter;
 use Magento\Customer\Model\AttributeMetadataDataProvider;
 use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
-use Magento\Framework\Api\Config\MetadataConfig;
 use Magento\Framework\Api\SimpleDataObjectConverter;
 use Magento\Framework\Exception\NoSuchEntityException;
 
@@ -24,11 +23,6 @@ class CustomerMetadata implements CustomerMetadataInterface
      */
     private $customerDataObjectMethods;
 
-    /**
-     * @var MetadataConfig
-     */
-    private $metadataConfig;
-
     /**
      * @var AttributeMetadataConverter
      */
@@ -40,16 +34,13 @@ class CustomerMetadata implements CustomerMetadataInterface
     private $attributeMetadataDataProvider;
 
     /**
-     * @param MetadataConfig $metadataConfig
      * @param AttributeMetadataConverter $attributeMetadataConverter
      * @param AttributeMetadataDataProvider $attributeMetadataDataProvider
      */
     public function __construct(
-        MetadataConfig $metadataConfig,
         AttributeMetadataConverter $attributeMetadataConverter,
         AttributeMetadataDataProvider $attributeMetadataDataProvider
     ) {
-        $this->metadataConfig = $metadataConfig;
         $this->attributeMetadataConverter = $attributeMetadataConverter;
         $this->attributeMetadataDataProvider = $attributeMetadataDataProvider;
     }
@@ -148,6 +139,6 @@ class CustomerMetadata implements CustomerMetadataInterface
                 $customAttributes[] = $attributeMetadata;
             }
         }
-        return array_merge($customAttributes, $this->metadataConfig->getCustomAttributesMetadata($dataObjectClassName));
+        return $customAttributes;
     }
 }
diff --git a/app/code/Magento/Customer/Test/Unit/Model/AttributeTest.php b/app/code/Magento/Customer/Test/Unit/Model/AttributeTest.php
index aed47c9e45898f0b9e4ea6dc6877c06c87f92d1f..81fdf472c365eb9e7ff2348ac3922b320a28b1bf 100644
--- a/app/code/Magento/Customer/Test/Unit/Model/AttributeTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Model/AttributeTest.php
@@ -4,6 +4,8 @@
  * See COPYING.txt for license details.
  */
 
+// @codingStandardsIgnoreFile
+
 namespace Magento\Customer\Test\Unit\Model;
 
 use Magento\Customer\Model\Attribute;
@@ -29,11 +31,6 @@ class AttributeTest extends \PHPUnit_Framework_TestCase
      */
     protected $registryMock;
 
-    /**
-     * @var \Magento\Framework\Api\MetadataServiceInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $metadataServiceMock;
-
     /**
      * @var \Magento\Framework\Api\AttributeValueFactory|\PHPUnit_Framework_MockObject_MockObject
      */
@@ -109,6 +106,14 @@ class AttributeTest extends \PHPUnit_Framework_TestCase
      */
     private $dataObjectHelperMock;
 
+    /**
+     * @var \Magento\Framework\Api\ExtensionAttributesFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $extensionAttributesFactory;
+
+    /**
+     * Test method
+     */
     protected function setUp()
     {
         $this->contextMock = $this->getMockBuilder('Magento\Framework\Model\Context')
@@ -116,7 +121,8 @@ class AttributeTest extends \PHPUnit_Framework_TestCase
             ->getMock();
         $this->registryMock = $this->getMockBuilder('Magento\Framework\Registry')
             ->getMock();
-        $this->metadataServiceMock = $this->getMockBuilder('Magento\Framework\Api\MetadataServiceInterface')
+        $this->extensionAttributesFactory = $this->getMockBuilder('Magento\Framework\Api\ExtensionAttributesFactory')
+            ->disableOriginalConstructor()
             ->getMock();
         $this->attributeValueFactoryMock = $this->getMockBuilder('Magento\Framework\Api\AttributeValueFactory')
             ->disableOriginalConstructor()
@@ -173,7 +179,7 @@ class AttributeTest extends \PHPUnit_Framework_TestCase
         $this->attribute = new Attribute(
             $this->contextMock,
             $this->registryMock,
-            $this->metadataServiceMock,
+            $this->extensionAttributesFactory,
             $this->attributeValueFactoryMock,
             $this->configMock,
             $this->typeFactoryMock,
@@ -190,6 +196,9 @@ class AttributeTest extends \PHPUnit_Framework_TestCase
         );
     }
 
+    /**
+     * Test method
+     */
     public function testAfterSaveEavCache()
     {
         $this->configMock
@@ -199,6 +208,9 @@ class AttributeTest extends \PHPUnit_Framework_TestCase
         $this->attribute->afterSave();
     }
 
+    /**
+     * Test method
+     */
     public function testAfterDeleteEavCache()
     {
         $this->configMock
diff --git a/app/code/Magento/Customer/etc/di.xml b/app/code/Magento/Customer/etc/di.xml
index fb07378f191ad35ad2f3ff3e6c0105e381570bd8..acf37638c3915db937145e8245c1a59b14cac1c9 100644
--- a/app/code/Magento/Customer/etc/di.xml
+++ b/app/code/Magento/Customer/etc/di.xml
@@ -63,20 +63,6 @@
             </argument>
         </arguments>
     </type>
-    <virtualType name="Magento\Customer\Api\Config\CustomerMetadataConfig" type="Magento\Framework\Api\Config\MetadataConfig">
-    </virtualType>
-    <type name="Magento\Customer\Model\Metadata\CustomerMetadata">
-        <arguments>
-            <argument name="metadataConfig" xsi:type="object">Magento\Customer\Api\Config\CustomerMetadataConfig</argument>
-        </arguments>
-    </type>
-    <virtualType name="Magento\Customer\Api\Config\AddressMetadataConfig" type="Magento\Framework\Api\Config\MetadataConfig">
-    </virtualType>
-    <type name="Magento\Customer\Model\Metadata\AddressMetadata">
-        <arguments>
-            <argument name="metadataConfig" xsi:type="object">Magento\Customer\Api\Config\AddressMetadataConfig</argument>
-        </arguments>
-    </type>
     <type name="Magento\Framework\Model\ActionValidator\RemoveAction">
         <arguments>
             <argument name="protectedModels" xsi:type="array">
diff --git a/app/code/Magento/Downloadable/Api/Data/File/ContentInterface.php b/app/code/Magento/Downloadable/Api/Data/File/ContentInterface.php
index ce1e4b8afa1e879f97a18a87ad68bbc2d35f2a68..01194703cbb86cb65e151634f862f7fa794f46df 100644
--- a/app/code/Magento/Downloadable/Api/Data/File/ContentInterface.php
+++ b/app/code/Magento/Downloadable/Api/Data/File/ContentInterface.php
@@ -39,4 +39,21 @@ interface ContentInterface extends \Magento\Framework\Api\ExtensibleDataInterfac
      * @return $this
      */
     public function setName($name);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Downloadable\Api\Data\File\ContentExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Downloadable\Api\Data\File\ContentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Downloadable\Api\Data\File\ContentExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Downloadable/Api/Data/LinkContentInterface.php b/app/code/Magento/Downloadable/Api/Data/LinkContentInterface.php
index ec82d46a008cbfd001d906913eefbd35a81497c7..1972068f435512611b3d564f875ec666f6d20b56 100644
--- a/app/code/Magento/Downloadable/Api/Data/LinkContentInterface.php
+++ b/app/code/Magento/Downloadable/Api/Data/LinkContentInterface.php
@@ -174,4 +174,21 @@ interface LinkContentInterface extends \Magento\Framework\Api\ExtensibleDataInte
      * @return $this
      */
     public function setSampleType($sampleType);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Downloadable\Api\Data\LinkContentExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Downloadable\Api\Data\LinkContentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Downloadable\Api\Data\LinkContentExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Downloadable/Api/Data/LinkInterface.php b/app/code/Magento/Downloadable/Api/Data/LinkInterface.php
index df4f97a055ee838142ac05c0e5ee91f9bd0663b9..0152a1a256540db9b0cab423e2804bd906475245 100644
--- a/app/code/Magento/Downloadable/Api/Data/LinkInterface.php
+++ b/app/code/Magento/Downloadable/Api/Data/LinkInterface.php
@@ -173,4 +173,19 @@ interface LinkInterface extends \Magento\Framework\Api\ExtensibleDataInterface
      * @return $this
      */
     public function setSampleUrl($sampleUrl);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Downloadable\Api\Data\LinkExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Downloadable\Api\Data\LinkExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Downloadable\Api\Data\LinkExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Downloadable/Api/Data/SampleContentInterface.php b/app/code/Magento/Downloadable/Api/Data/SampleContentInterface.php
index 03864afad3dd6a7b98683ed4a7ae53bf2e1f0734..b4b0580bda1879b6aa75ab70371f6c522b7d1100 100644
--- a/app/code/Magento/Downloadable/Api/Data/SampleContentInterface.php
+++ b/app/code/Magento/Downloadable/Api/Data/SampleContentInterface.php
@@ -84,4 +84,21 @@ interface SampleContentInterface extends \Magento\Framework\Api\ExtensibleDataIn
      * @return $this
      */
     public function setSampleUrl($sampleUrl);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Downloadable\Api\Data\SampleContentExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Downloadable\Api\Data\SampleContentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Downloadable\Api\Data\SampleContentExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Downloadable/Api/Data/SampleInterface.php b/app/code/Magento/Downloadable/Api/Data/SampleInterface.php
index aff31bf3f413f1b8ae20691678faaa0261d6b023..3d6dfc937f3871a4a489e43c1f1912c5a7498082 100644
--- a/app/code/Magento/Downloadable/Api/Data/SampleInterface.php
+++ b/app/code/Magento/Downloadable/Api/Data/SampleInterface.php
@@ -96,4 +96,21 @@ interface SampleInterface extends \Magento\Framework\Api\ExtensibleDataInterface
      * @return $this
      */
     public function setSampleUrl($sampleUrl);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Downloadable\Api\Data\SampleExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Downloadable\Api\Data\SampleExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Downloadable\Api\Data\SampleExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Downloadable/Model/File/Content.php b/app/code/Magento/Downloadable/Model/File/Content.php
index e59ffc9dd605df594e47245d6fb41c15396615c1..5fdd65fa9440b49cde9988cf97516e42a335fbed 100644
--- a/app/code/Magento/Downloadable/Model/File/Content.php
+++ b/app/code/Magento/Downloadable/Model/File/Content.php
@@ -56,4 +56,26 @@ class Content extends \Magento\Framework\Model\AbstractExtensibleModel implement
     {
         return $this->setData(self::NAME, $name);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Downloadable\Api\Data\File\ContentExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Downloadable\Api\Data\File\ContentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Downloadable\Api\Data\File\ContentExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Downloadable/Model/Link.php b/app/code/Magento/Downloadable/Model/Link.php
index 776e2983fdac58a8d627c637cac8237363b81f03..84de54915ab0edec47b492ac19a2fde4f5d131b4 100644
--- a/app/code/Magento/Downloadable/Model/Link.php
+++ b/app/code/Magento/Downloadable/Model/Link.php
@@ -6,7 +6,6 @@
 namespace Magento\Downloadable\Model;
 
 use Magento\Downloadable\Api\Data\LinkInterface;
-use Magento\Framework\Api\MetadataServiceInterface;
 use Magento\Downloadable\Model\Resource\Link as Resource;
 
 /**
@@ -50,15 +49,10 @@ class Link extends \Magento\Framework\Model\AbstractExtensibleModel implements C
     const KEY_SAMPLE_URL = 'sample_url';
     /**#@-*/
 
-    /**
-     * @var MetadataServiceInterface
-     */
-    protected $metadataService;
-
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
      * @param \Magento\Framework\Data\Collection\Db $resourceCollection
@@ -67,7 +61,7 @@ class Link extends \Magento\Framework\Model\AbstractExtensibleModel implements C
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
         \Magento\Framework\Data\Collection\Db $resourceCollection = null,
@@ -76,7 +70,7 @@ class Link extends \Magento\Framework\Model\AbstractExtensibleModel implements C
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
@@ -367,5 +361,26 @@ class Link extends \Magento\Framework\Model\AbstractExtensibleModel implements C
     {
         return $this->setData(self::KEY_SAMPLE_URL, $sampleUrl);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Downloadable\Api\Data\LinkExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Downloadable\Api\Data\LinkExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Downloadable\Api\Data\LinkExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Downloadable/Model/Link/Content.php b/app/code/Magento/Downloadable/Model/Link/Content.php
index 071e130a25de07bdc7af2306dacd793eec172f52..a40f76faf1cff5c353a8406943c9b51b4f95e428 100644
--- a/app/code/Magento/Downloadable/Model/Link/Content.php
+++ b/app/code/Magento/Downloadable/Model/Link/Content.php
@@ -243,4 +243,26 @@ class Content extends \Magento\Framework\Model\AbstractExtensibleModel implement
     {
         return $this->setData(self::SAMPLE_TYPE, $sampleType);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Downloadable\Api\Data\LinkContentExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Downloadable\Api\Data\LinkContentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Downloadable\Api\Data\LinkContentExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Downloadable/Model/Sample.php b/app/code/Magento/Downloadable/Model/Sample.php
index 23cd6bd9408e61195d3f1eb6955363cc77fa514c..07dd821050aad1d60ae18abc38211afdd1fb4a55 100644
--- a/app/code/Magento/Downloadable/Model/Sample.php
+++ b/app/code/Magento/Downloadable/Model/Sample.php
@@ -33,7 +33,7 @@ class Sample extends \Magento\Framework\Model\AbstractExtensibleModel implements
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
      * @param \Magento\Framework\Data\Collection\Db $resourceCollection
@@ -42,7 +42,7 @@ class Sample extends \Magento\Framework\Model\AbstractExtensibleModel implements
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
         \Magento\Framework\Data\Collection\Db $resourceCollection = null,
@@ -51,7 +51,7 @@ class Sample extends \Magento\Framework\Model\AbstractExtensibleModel implements
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
@@ -224,4 +224,25 @@ class Sample extends \Magento\Framework\Model\AbstractExtensibleModel implements
     {
         return $this->setData(self::KEY_SAMPLE_URL, $sampleUrl);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Downloadable\Api\Data\SampleExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Downloadable\Api\Data\SampleExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Downloadable\Api\Data\SampleExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Downloadable/Model/Sample/Content.php b/app/code/Magento/Downloadable/Model/Sample/Content.php
index f60f92f9d11f91e86de522f3d346030e694f5178..0fcf613353966548cfbf6ec83e2ca47837ff9f54 100644
--- a/app/code/Magento/Downloadable/Model/Sample/Content.php
+++ b/app/code/Magento/Downloadable/Model/Sample/Content.php
@@ -117,4 +117,26 @@ class Content extends \Magento\Framework\Model\AbstractExtensibleModel implement
     {
         return $this->setData(self::SAMPLE_URL, $sampleUrl);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Downloadable\Api\Data\SampleContentExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Downloadable\Api\Data\SampleContentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Downloadable\Api\Data\SampleContentExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Eav/Api/Data/AttributeGroupInterface.php b/app/code/Magento/Eav/Api/Data/AttributeGroupInterface.php
index 074bc9c6721d0cbf944c5d5b5a07542b69143c1b..9c02bda805670c87d5870d4e8828769666d474ae 100644
--- a/app/code/Magento/Eav/Api/Data/AttributeGroupInterface.php
+++ b/app/code/Magento/Eav/Api/Data/AttributeGroupInterface.php
@@ -1,12 +1,13 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
 namespace Magento\Eav\Api\Data;
 
-interface AttributeGroupInterface
+use Magento\Framework\Api\ExtensibleDataInterface;
+
+interface AttributeGroupInterface extends ExtensibleDataInterface
 {
     const GROUP_ID = 'attribute_group_id';
 
@@ -58,4 +59,21 @@ interface AttributeGroupInterface
      * @return $this
      */
     public function setAttributeSetId($attributeSetId);
+
+    /**
+     * Retrieve existing extension attributes object.
+     *
+     * @return \Magento\Eav\Api\Data\AttributeGroupExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Eav\Api\Data\AttributeGroupExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Eav\Api\Data\AttributeGroupExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Eav/Api/Data/AttributeInterface.php b/app/code/Magento/Eav/Api/Data/AttributeInterface.php
index 45f61ee56dd2aa920b225bbb66a2404fdd81ba3c..614d75a1279454b3aed41b98788e85cd15c193d8 100644
--- a/app/code/Magento/Eav/Api/Data/AttributeInterface.php
+++ b/app/code/Magento/Eav/Api/Data/AttributeInterface.php
@@ -6,7 +6,7 @@
  */
 namespace Magento\Eav\Api\Data;
 
-interface AttributeInterface extends \Magento\Framework\Api\ExtensibleDataInterface
+interface AttributeInterface extends \Magento\Framework\Api\CustomAttributesDataInterface
 {
     const ATTRIBUTE_ID = 'attribute_id';
 
@@ -297,4 +297,9 @@ interface AttributeInterface extends \Magento\Framework\Api\ExtensibleDataInterf
      * @return $this
      */
     public function setValidationRules(array $validationRules = null);
+
+    /**
+     * @return \Magento\Eav\Api\Data\AttributeExtensionInterface|null
+     */
+    public function getExtensionAttributes();
 }
diff --git a/app/code/Magento/Eav/Api/Data/AttributeSetInterface.php b/app/code/Magento/Eav/Api/Data/AttributeSetInterface.php
index 0c8e66dae0f0e09bf519e21875ca6acc90bcc24e..a44a0bd4dae93040d2903c97b4355362ce872b2d 100644
--- a/app/code/Magento/Eav/Api/Data/AttributeSetInterface.php
+++ b/app/code/Magento/Eav/Api/Data/AttributeSetInterface.php
@@ -5,7 +5,7 @@
  */
 namespace Magento\Eav\Api\Data;
 
-interface AttributeSetInterface
+interface AttributeSetInterface extends \Magento\Framework\Api\ExtensibleDataInterface
 {
     /**
      * Get attribute set ID
@@ -66,4 +66,19 @@ interface AttributeSetInterface
      * @return $this
      */
     public function setEntityTypeId($entityTypeId);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Eav\Api\Data\AttributeSetExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Eav\Api\Data\AttributeSetExtensionInterface|null $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Eav\Api\Data\AttributeSetExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php
index 5a2b8365a25204491b4c079f86ef3aca4768b3b6..6c2dcc71ed12a164f6a8675b18aef512523a97d0 100644
--- a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php
+++ b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php
@@ -1024,6 +1024,9 @@ abstract class AbstractEntity extends \Magento\Framework\Model\Resource\Abstract
         if (empty($attributes)) {
             $this->loadAllAttributes($object);
         } else {
+            if (!is_array($attributes)) {
+                $attributes = [$attributes];
+            }
             foreach ($attributes as $attrCode) {
                 $this->getAttribute($attrCode);
             }
diff --git a/app/code/Magento/Eav/Model/Entity/Attribute.php b/app/code/Magento/Eav/Model/Entity/Attribute.php
index ef74bb1e59e968598de052ba3c08707c67f402cd..df877f97a92afdec4ea0cdb857e10d3a90f84ba9 100644
--- a/app/code/Magento/Eav/Model/Entity/Attribute.php
+++ b/app/code/Magento/Eav/Model/Entity/Attribute.php
@@ -12,6 +12,7 @@ use Magento\Framework\Api\AttributeValueFactory;
  * EAV Entity attribute model
  *
  * @method \Magento\Eav\Model\Entity\Attribute setOption($value)
+ * @method \Magento\Eav\Api\Data\AttributeExtensionInterface getExtensionAttributes()
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class Attribute extends \Magento\Eav\Model\Entity\Attribute\AbstractAttribute implements
@@ -66,7 +67,7 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute\AbstractAttribute im
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Eav\Model\Config $eavConfig
      * @param TypeFactory $eavTypeFactory
@@ -87,7 +88,7 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute\AbstractAttribute im
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Eav\Model\Config $eavConfig,
         \Magento\Eav\Model\Entity\TypeFactory $eavTypeFactory,
@@ -107,7 +108,7 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute\AbstractAttribute im
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $eavConfig,
             $eavTypeFactory,
diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php b/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php
index 155f3a0f0e1fb2ed46c73c472a57ee8b9b92ee9c..d241a3234fa697bfdb4c833f511a8159d1998d06 100644
--- a/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php
+++ b/app/code/Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php
@@ -114,7 +114,7 @@ abstract class AbstractAttribute extends \Magento\Framework\Model\AbstractExtens
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Eav\Model\Config $eavConfig
      * @param \Magento\Eav\Model\Entity\TypeFactory $eavTypeFactory
@@ -132,7 +132,7 @@ abstract class AbstractAttribute extends \Magento\Framework\Model\AbstractExtens
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Eav\Model\Config $eavConfig,
         \Magento\Eav\Model\Entity\TypeFactory $eavTypeFactory,
@@ -149,7 +149,7 @@ abstract class AbstractAttribute extends \Magento\Framework\Model\AbstractExtens
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
@@ -1184,4 +1184,25 @@ abstract class AbstractAttribute extends \Magento\Framework\Model\AbstractExtens
     {
         return $this->setData(self::VALIDATE_RULES, $validationRules);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Eav\Api\Data\AttributeExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Eav\Api\Data\AttributeExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Eav\Api\Data\AttributeExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/Group.php b/app/code/Magento/Eav/Model/Entity/Attribute/Group.php
index 1e68ac3ccbf19c3e0961a381b7c334b99f082114..4248f1523d4d517c4061b453cb6353832206d4b0 100644
--- a/app/code/Magento/Eav/Model/Entity/Attribute/Group.php
+++ b/app/code/Magento/Eav/Model/Entity/Attribute/Group.php
@@ -3,6 +3,7 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
 namespace Magento\Eav\Model\Entity\Attribute;
 
 /**
@@ -124,5 +125,27 @@ class Group extends \Magento\Framework\Model\AbstractExtensibleModel implements
     {
         return $this->setData(self::ATTRIBUTE_SET_ID, $attributeSetId);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Eav\Api\Data\AttributeGroupExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Eav\Api\Data\AttributeGroupExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Eav\Api\Data\AttributeGroupExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/Option.php b/app/code/Magento/Eav/Model/Entity/Attribute/Option.php
index f884585623b3be172c84067a7293f53c3ac95237..57cbb324ef7c81b39cdb76d140ed697b90ce999f 100644
--- a/app/code/Magento/Eav/Model/Entity/Attribute/Option.php
+++ b/app/code/Magento/Eav/Model/Entity/Attribute/Option.php
@@ -6,7 +6,7 @@
 namespace Magento\Eav\Model\Entity\Attribute;
 
 use Magento\Eav\Api\Data\AttributeOptionInterface;
-use Magento\Framework\Model\AbstractExtensibleModel;
+use Magento\Framework\Model\AbstractModel;
 
 /**
  * Emtity attribute option model
@@ -18,7 +18,7 @@ use Magento\Framework\Model\AbstractExtensibleModel;
  *
  * @author      Magento Core Team <core@magentocommerce.com>
  */
-class Option extends AbstractExtensibleModel implements AttributeOptionInterface
+class Option extends AbstractModel implements AttributeOptionInterface
 {
     /**
      * Resource initialization
diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/OptionLabel.php b/app/code/Magento/Eav/Model/Entity/Attribute/OptionLabel.php
index 5319477495b36e0e87e8a3e294db2a6d5c3a8ece..dfb45c211041d8dd89fb05974df32a7af9930901 100644
--- a/app/code/Magento/Eav/Model/Entity/Attribute/OptionLabel.php
+++ b/app/code/Magento/Eav/Model/Entity/Attribute/OptionLabel.php
@@ -6,13 +6,13 @@
 namespace Magento\Eav\Model\Entity\Attribute;
 
 use Magento\Eav\Api\Data\AttributeOptionLabelInterface;
-use Magento\Framework\Model\AbstractExtensibleModel;
+use Magento\Framework\Model\AbstractModel;
 
 /**
  * Entity attribute option label model
  *
  */
-class OptionLabel extends AbstractExtensibleModel implements AttributeOptionLabelInterface
+class OptionLabel extends AbstractModel implements AttributeOptionLabelInterface
 {
     /**
      * {@inheritdoc}
diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/Set.php b/app/code/Magento/Eav/Model/Entity/Attribute/Set.php
index 75122ca097d4d06a0b459d2d688632dcf925dd8d..c8eb151622d4d235b8460fc548ac202d504b0e4a 100644
--- a/app/code/Magento/Eav/Model/Entity/Attribute/Set.php
+++ b/app/code/Magento/Eav/Model/Entity/Attribute/Set.php
@@ -19,8 +19,8 @@
  */
 namespace Magento\Eav\Model\Entity\Attribute;
 
-use Magento\Eav\Model\Entity\Type;
 use Magento\Eav\Exception as EavException;
+use Magento\Eav\Model\Entity\Type;
 use Magento\Framework\Api\AttributeValueFactory;
 
 /**
@@ -47,6 +47,7 @@ class Set extends \Magento\Framework\Model\AbstractExtensibleModel implements
 
     /**
      * Prefix of model events names
+     *
      * @var string
      */
     protected $_eventPrefix = 'eav_entity_attribute_set';
@@ -74,7 +75,7 @@ class Set extends \Magento\Framework\Model\AbstractExtensibleModel implements
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Eav\Model\Config $eavConfig
      * @param GroupFactory $attrGroupFactory
@@ -88,7 +89,7 @@ class Set extends \Magento\Framework\Model\AbstractExtensibleModel implements
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Eav\Model\Config $eavConfig,
         \Magento\Eav\Model\Entity\Attribute\GroupFactory $attrGroupFactory,
@@ -101,7 +102,7 @@ class Set extends \Magento\Framework\Model\AbstractExtensibleModel implements
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
@@ -439,5 +440,26 @@ class Set extends \Magento\Framework\Model\AbstractExtensibleModel implements
     {
         return $this->setData(self::KEY_ENTITY_TYPE_ID, $entityTypeId);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Eav\Api\Data\AttributeSetExtensionInterface|null|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Eav\Api\Data\AttributeSetExtensionInterface|null $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Eav\Api\Data\AttributeSetExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Eav/Model/Entity/Attribute/ValidationRule.php b/app/code/Magento/Eav/Model/Entity/Attribute/ValidationRule.php
index c3d4743674af8fa0a459ef9dd42ee344973d31f7..ee9367705335ae4fe6f4212bb23beabee05760e4 100644
--- a/app/code/Magento/Eav/Model/Entity/Attribute/ValidationRule.php
+++ b/app/code/Magento/Eav/Model/Entity/Attribute/ValidationRule.php
@@ -9,7 +9,7 @@ namespace Magento\Eav\Model\Entity\Attribute;
 /**
  * @codeCoverageIgnore
  */
-class ValidationRule extends \Magento\Framework\Model\AbstractExtensibleModel implements
+class ValidationRule extends \Magento\Framework\Model\AbstractModel implements
     \Magento\Eav\Api\Data\AttributeValidationRuleInterface
 {
     /**
diff --git a/app/code/Magento/GiftMessage/Api/Data/MessageInterface.php b/app/code/Magento/GiftMessage/Api/Data/MessageInterface.php
index c360ca4e8f1f2539e7be29789da17de5108ceb1c..a044e7c0ab0c72253dc3b375c1ed2677fb47c389 100644
--- a/app/code/Magento/GiftMessage/Api/Data/MessageInterface.php
+++ b/app/code/Magento/GiftMessage/Api/Data/MessageInterface.php
@@ -91,4 +91,21 @@ interface MessageInterface extends \Magento\Framework\Api\ExtensibleDataInterfac
      * @return $this
      */
     public function setMessage($message);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\GiftMessage\Api\Data\MessageExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\GiftMessage\Api\Data\MessageExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\GiftMessage\Api\Data\MessageExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/GiftMessage/Model/Message.php b/app/code/Magento/GiftMessage/Model/Message.php
index 4dda8d5546d9fd788a4f295555297e8936f4d1e9..be07b6cfb242c50d11fc7a9cf691d91b717150ef 100644
--- a/app/code/Magento/GiftMessage/Model/Message.php
+++ b/app/code/Magento/GiftMessage/Model/Message.php
@@ -26,7 +26,7 @@ class Message extends \Magento\Framework\Model\AbstractExtensibleModel implement
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param Resource\Message $resource
      * @param \Magento\Framework\Data\Collection\Db $resourceCollection
@@ -36,7 +36,7 @@ class Message extends \Magento\Framework\Model\AbstractExtensibleModel implement
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\GiftMessage\Model\Resource\Message $resource,
         \Magento\Framework\Data\Collection\Db $resourceCollection,
@@ -47,7 +47,7 @@ class Message extends \Magento\Framework\Model\AbstractExtensibleModel implement
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
@@ -164,5 +164,26 @@ class Message extends \Magento\Framework\Model\AbstractExtensibleModel implement
     {
         return $this->setData(self::MESSAGE, $message);
     }
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\GiftMessage\Api\Data\MessageExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\GiftMessage\Api\Data\MessageExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\GiftMessage\Api\Data\MessageExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/OfflinePayments/Model/Banktransfer.php b/app/code/Magento/OfflinePayments/Model/Banktransfer.php
index 4cc48a575272039644fe0c1211c4172249647f60..9eee92e1e2478a960e71e599bc4d78bea4d97334 100644
--- a/app/code/Magento/OfflinePayments/Model/Banktransfer.php
+++ b/app/code/Magento/OfflinePayments/Model/Banktransfer.php
@@ -7,6 +7,8 @@ namespace Magento\OfflinePayments\Model;
 
 /**
  * Bank Transfer payment method model
+ *
+ * @method \Magento\Quote\Api\Data\PaymentMethodExtensionInterface getExtensionAttributes()
  */
 class Banktransfer extends \Magento\Payment\Model\Method\AbstractMethod
 {
diff --git a/app/code/Magento/OfflinePayments/Model/Cashondelivery.php b/app/code/Magento/OfflinePayments/Model/Cashondelivery.php
index c1a125463d926cf328e42fb4b9c43b9102112430..06f2862acd07e6e7ed30da8a1dd3351e639014d8 100644
--- a/app/code/Magento/OfflinePayments/Model/Cashondelivery.php
+++ b/app/code/Magento/OfflinePayments/Model/Cashondelivery.php
@@ -7,6 +7,8 @@ namespace Magento\OfflinePayments\Model;
 
 /**
  * Cash on delivery payment method model
+ *
+ * @method \Magento\Quote\Api\Data\PaymentMethodExtensionInterface getExtensionAttributes()
  */
 class Cashondelivery extends \Magento\Payment\Model\Method\AbstractMethod
 {
diff --git a/app/code/Magento/OfflinePayments/Model/Checkmo.php b/app/code/Magento/OfflinePayments/Model/Checkmo.php
index 2de8ab28e97bc2e099d3579e75965cb49726fbd3..e282b502979df74feecf1ffc6a6509e7de651a71 100644
--- a/app/code/Magento/OfflinePayments/Model/Checkmo.php
+++ b/app/code/Magento/OfflinePayments/Model/Checkmo.php
@@ -5,6 +5,11 @@
  */
 namespace Magento\OfflinePayments\Model;
 
+/**
+ * Class Checkmo
+ *
+ * @method \Magento\Quote\Api\Data\PaymentMethodExtensionInterface getExtensionAttributes()
+ */
 class Checkmo extends \Magento\Payment\Model\Method\AbstractMethod
 {
     /**
diff --git a/app/code/Magento/OfflinePayments/Model/Purchaseorder.php b/app/code/Magento/OfflinePayments/Model/Purchaseorder.php
index 180ec57133db7e6eadf0964a33cea8797fd60eca..3a4aa15d089031bbb5aafd87523d4bba1999516f 100644
--- a/app/code/Magento/OfflinePayments/Model/Purchaseorder.php
+++ b/app/code/Magento/OfflinePayments/Model/Purchaseorder.php
@@ -5,6 +5,11 @@
  */
 namespace Magento\OfflinePayments\Model;
 
+/**
+ * Class Purchaseorder
+ *
+ * @method \Magento\Quote\Api\Data\PaymentMethodExtensionInterface getExtensionAttributes()
+ */
 class Purchaseorder extends \Magento\Payment\Model\Method\AbstractMethod
 {
     /**
diff --git a/app/code/Magento/Payment/Model/Info.php b/app/code/Magento/Payment/Model/Info.php
index f00d9117f4f5792fbc69b4236c278889e47f9cb6..0fd732033538183850c40b55d5bf32f233362def 100644
--- a/app/code/Magento/Payment/Model/Info.php
+++ b/app/code/Magento/Payment/Model/Info.php
@@ -5,7 +5,6 @@
  */
 namespace Magento\Payment\Model;
 
-use Magento\Framework\Api\AttributeValueFactory;
 use Magento\Framework\Model\AbstractExtensibleModel;
 
 /**
@@ -35,8 +34,8 @@ class Info extends AbstractExtensibleModel
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
-     * @param AttributeValueFactory $customAttributeFactory
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
+     * @param \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory,
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\Encryption\EncryptorInterface $encryptor
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
@@ -46,8 +45,8 @@ class Info extends AbstractExtensibleModel
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
-        AttributeValueFactory $customAttributeFactory,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
+        \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\Encryption\EncryptorInterface $encryptor,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
@@ -59,7 +58,7 @@ class Info extends AbstractExtensibleModel
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
diff --git a/app/code/Magento/Payment/Model/Method/AbstractMethod.php b/app/code/Magento/Payment/Model/Method/AbstractMethod.php
index fa331dd477414a2113dceee2ed2a447f2c7c8a07..926017b8bcce80f53a492ad3cb6849d4cbc2d2eb 100644
--- a/app/code/Magento/Payment/Model/Method/AbstractMethod.php
+++ b/app/code/Magento/Payment/Model/Method/AbstractMethod.php
@@ -222,7 +222,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
@@ -233,7 +233,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
@@ -244,7 +244,7 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
@@ -848,4 +848,25 @@ abstract class AbstractMethod extends \Magento\Framework\Model\AbstractExtensibl
     {
         $this->_debug($debugData);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Quote\Api\Data\PaymentMethodExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Quote\Api\Data\PaymentMethodExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Quote\Api\Data\PaymentMethodExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Payment/Model/Method/Cc.php b/app/code/Magento/Payment/Model/Method/Cc.php
index 23e7dfda59a9b40a4da2e115d01deb1ff1017307..8fdec55da4492bdcbe1c38fd2c3587bcf4a830eb 100644
--- a/app/code/Magento/Payment/Model/Method/Cc.php
+++ b/app/code/Magento/Payment/Model/Method/Cc.php
@@ -6,6 +6,7 @@
 namespace Magento\Payment\Model\Method;
 
 /**
+ * @method \Magento\Quote\Api\Data\PaymentMethodExtensionInterface getExtensionAttributes()
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class Cc extends \Magento\Payment\Model\Method\AbstractMethod
@@ -45,7 +46,7 @@ class Cc extends \Magento\Payment\Model\Method\AbstractMethod
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
@@ -60,7 +61,7 @@ class Cc extends \Magento\Payment\Model\Method\AbstractMethod
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
@@ -74,7 +75,7 @@ class Cc extends \Magento\Payment\Model\Method\AbstractMethod
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $paymentData,
             $scopeConfig,
diff --git a/app/code/Magento/Payment/Model/Method/Free.php b/app/code/Magento/Payment/Model/Method/Free.php
index 00c4145d7ba58687e1361b1d109a2645c79775c4..3793669383195a50c582674ed89ce19c634f6e82 100644
--- a/app/code/Magento/Payment/Model/Method/Free.php
+++ b/app/code/Magento/Payment/Model/Method/Free.php
@@ -9,6 +9,7 @@ use Magento\Framework\Pricing\PriceCurrencyInterface;
 
 /**
  * Free payment method
+ * @method \Magento\Quote\Api\Data\PaymentMethodExtensionInterface getExtensionAttributes()
  */
 class Free extends \Magento\Payment\Model\Method\AbstractMethod
 {
@@ -43,7 +44,7 @@ class Free extends \Magento\Payment\Model\Method\AbstractMethod
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
@@ -56,7 +57,7 @@ class Free extends \Magento\Payment\Model\Method\AbstractMethod
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
@@ -68,7 +69,7 @@ class Free extends \Magento\Payment\Model\Method\AbstractMethod
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $paymentData,
             $scopeConfig,
diff --git a/app/code/Magento/Payment/Model/Method/Substitution.php b/app/code/Magento/Payment/Model/Method/Substitution.php
index 98563e5092d778de27d06e54b523c7e5753bf216..819ecc267d130dee4be334565a961cb5a8184d9d 100644
--- a/app/code/Magento/Payment/Model/Method/Substitution.php
+++ b/app/code/Magento/Payment/Model/Method/Substitution.php
@@ -8,6 +8,8 @@ namespace Magento\Payment\Model\Method;
 
 /**
  * Substitution payment method for non-existing payments
+ *
+ * @method \Magento\Quote\Api\Data\PaymentMethodExtensionInterface getExtensionAttributes()
  */
 class Substitution extends AbstractMethod
 {
diff --git a/app/code/Magento/Payment/Test/Unit/Model/Method/FreeTest.php b/app/code/Magento/Payment/Test/Unit/Model/Method/FreeTest.php
index 064beb8b5428e3468b0c12a64e5652412d8d49ef..9976a46c96dee56bd06824421b160a98ef2e91e2 100644
--- a/app/code/Magento/Payment/Test/Unit/Model/Method/FreeTest.php
+++ b/app/code/Magento/Payment/Test/Unit/Model/Method/FreeTest.php
@@ -3,6 +3,9 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
+// @codingStandardsIgnoreFile
+
 namespace Magento\Payment\Test\Unit\Model\Method;
 
 class FreeTest extends \PHPUnit_Framework_TestCase
@@ -27,13 +30,19 @@ class FreeTest extends \PHPUnit_Framework_TestCase
         $context->expects($this->any())->method('getEventDispatcher')->willReturn($eventManagerMock);
 
         $registry = $this->getMock('\Magento\Framework\Registry', [], [], '', false);
-        $metadataService = $this->getMock('\Magento\Framework\Api\MetadataServiceInterface');
+        $extensionAttributesFactory = $this->getMock(
+            'Magento\Framework\Api\ExtensionAttributesFactory',
+            [],
+            [],
+            '',
+            false
+        );
         $customAttributeFactory = $this->getMock('\Magento\Framework\Api\AttributeValueFactory', [], [], '', false);
 
         $this->methodFree = new \Magento\Payment\Model\Method\Free(
             $context,
             $registry,
-            $metadataService,
+            $extensionAttributesFactory,
             $customAttributeFactory,
             $paymentData,
             $this->scopeConfig,
diff --git a/app/code/Magento/Quote/Api/Data/AddressInterface.php b/app/code/Magento/Quote/Api/Data/AddressInterface.php
index 689ec768e2b5a8082057fed91962eceffa03b780..4b0487a3431dcb3859814f8bcdaefe14a2c8719a 100644
--- a/app/code/Magento/Quote/Api/Data/AddressInterface.php
+++ b/app/code/Magento/Quote/Api/Data/AddressInterface.php
@@ -334,4 +334,19 @@ interface AddressInterface extends \Magento\Framework\Api\ExtensibleDataInterfac
      * @return $this
      */
     public function setEmail($email);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Quote\Api\Data\AddressExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Quote\Api\Data\AddressExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Quote\Api\Data\AddressExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Quote/Api/Data/CartInterface.php b/app/code/Magento/Quote/Api/Data/CartInterface.php
index 1fe5372c518bb2fabc106f13a11ef7d289181e65..2a56c448336bf4f8ad5bd9da2b588b6ac7582598 100644
--- a/app/code/Magento/Quote/Api/Data/CartInterface.php
+++ b/app/code/Magento/Quote/Api/Data/CartInterface.php
@@ -345,4 +345,19 @@ interface CartInterface extends \Magento\Framework\Api\ExtensibleDataInterface
      * @return $this
      */
     public function setCustomerTaxClassId($customerTaxClassId);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Quote\Api\Data\CartExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Quote\Api\Data\CartExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Quote\Api\Data\CartExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Quote/Api/Data/CartItemInterface.php b/app/code/Magento/Quote/Api/Data/CartItemInterface.php
index 511184992ab89c18d0177a9eca99ce3312bfb20f..4951fe1698006419285934bc95c4645537394e1c 100644
--- a/app/code/Magento/Quote/Api/Data/CartItemInterface.php
+++ b/app/code/Magento/Quote/Api/Data/CartItemInterface.php
@@ -130,4 +130,19 @@ interface CartItemInterface extends \Magento\Framework\Api\ExtensibleDataInterfa
      * @return $this
      */
     public function setQuoteId($quoteId);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Quote\Api\Data\CartItemExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Quote\Api\Data\CartItemExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Quote\Api\Data\CartItemExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Quote/Api/Data/CurrencyInterface.php b/app/code/Magento/Quote/Api/Data/CurrencyInterface.php
index b00350c5f600c2fc3917dbaa33c4315f56bf8c03..81a0ff8d3fad21400625f7c51c0634ede6dc2901 100644
--- a/app/code/Magento/Quote/Api/Data/CurrencyInterface.php
+++ b/app/code/Magento/Quote/Api/Data/CurrencyInterface.php
@@ -147,4 +147,19 @@ interface CurrencyInterface extends \Magento\Framework\Api\ExtensibleDataInterfa
      * @return $this
      */
     public function setBaseToQuoteRate($baseToQuoteRate);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Quote\Api\Data\CurrencyExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Quote\Api\Data\CurrencyExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Quote\Api\Data\CurrencyExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Quote/Api/Data/PaymentInterface.php b/app/code/Magento/Quote/Api/Data/PaymentInterface.php
index 7d437b97e2326a9044b57a481e06ce8393346f77..7f0704edbfe32782368afd6ff87d0d633037dbd5 100644
--- a/app/code/Magento/Quote/Api/Data/PaymentInterface.php
+++ b/app/code/Magento/Quote/Api/Data/PaymentInterface.php
@@ -147,4 +147,19 @@ interface PaymentInterface extends \Magento\Framework\Api\ExtensibleDataInterfac
      * @return $this
      */
     public function setAdditionalData($additionalData);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Quote\Api\Data\PaymentExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Quote\Api\Data\PaymentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Quote\Api\Data\PaymentExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Quote/Api/Data/PaymentMethodInterface.php b/app/code/Magento/Quote/Api/Data/PaymentMethodInterface.php
index 3be900400f305ed076761bfab80a498dd7637d24..4ae7a9100508b4dadbaad4713f342061c7c93e93 100644
--- a/app/code/Magento/Quote/Api/Data/PaymentMethodInterface.php
+++ b/app/code/Magento/Quote/Api/Data/PaymentMethodInterface.php
@@ -20,4 +20,21 @@ interface PaymentMethodInterface extends \Magento\Framework\Api\ExtensibleDataIn
      * @return string
      */
     public function getTitle();
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Quote\Api\Data\PaymentMethodExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Quote\Api\Data\PaymentMethodExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Quote\Api\Data\PaymentMethodExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Quote/Api/Data/ShippingMethodInterface.php b/app/code/Magento/Quote/Api/Data/ShippingMethodInterface.php
index 92a60cbb3ad1f70d1d80391f89d4b156e0df33f7..ccebbdaa679e0a002971379aa4d5b6206bbd88b0 100644
--- a/app/code/Magento/Quote/Api/Data/ShippingMethodInterface.php
+++ b/app/code/Magento/Quote/Api/Data/ShippingMethodInterface.php
@@ -147,4 +147,21 @@ interface ShippingMethodInterface extends \Magento\Framework\Api\ExtensibleDataI
      * @return $this
      */
     public function setAvailable($available);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Quote\Api\Data\ShippingMethodExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Quote\Api\Data\ShippingMethodExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Quote\Api\Data\ShippingMethodExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Quote/Api/Data/TotalsInterface.php b/app/code/Magento/Quote/Api/Data/TotalsInterface.php
index b3594a9209f6bb063537a6cda701ce4ad5cf09c4..76684c5a75e196a29cec604f56cd5d5ca5a5402e 100644
--- a/app/code/Magento/Quote/Api/Data/TotalsInterface.php
+++ b/app/code/Magento/Quote/Api/Data/TotalsInterface.php
@@ -402,4 +402,19 @@ interface TotalsInterface extends \Magento\Framework\Api\ExtensibleDataInterface
      * @return $this
      */
     public function setItems(array $items = null);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Quote\Api\Data\TotalsExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Quote\Api\Data\TotalsExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Quote\Api\Data\TotalsExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Quote/Api/Data/TotalsItemInterface.php b/app/code/Magento/Quote/Api/Data/TotalsItemInterface.php
index a37c78802f8ae767b08cc4fb0c3e4ae00faffa94..21b895553a4daeb6438b6000cd117f7a112bdf88 100644
--- a/app/code/Magento/Quote/Api/Data/TotalsItemInterface.php
+++ b/app/code/Magento/Quote/Api/Data/TotalsItemInterface.php
@@ -332,4 +332,19 @@ interface TotalsItemInterface extends \Magento\Framework\Api\ExtensibleDataInter
      * @return $this
      */
     public function setBaseRowTotalInclTax($baseRowTotalInclTax);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Quote\Api\Data\TotalsItemExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Quote\Api\Data\TotalsItemExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Quote\Api\Data\TotalsItemExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Quote/Model/Cart/Currency.php b/app/code/Magento/Quote/Model/Cart/Currency.php
index 67e6e95b32a572717dfd6b8ff4f1ead6a06ba184..5f7b57a9508168e2b6f4ab136aa0c716fd30806c 100644
--- a/app/code/Magento/Quote/Model/Cart/Currency.php
+++ b/app/code/Magento/Quote/Model/Cart/Currency.php
@@ -162,4 +162,25 @@ class Currency extends \Magento\Framework\Model\AbstractExtensibleModel implemen
     {
         return $this->setData(self::KEY_BASE_TO_QUOTE_RATE, $baseToQuoteRate);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Quote\Api\Data\CurrencyExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Quote\Api\Data\CurrencyExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Quote\Api\Data\CurrencyExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Quote/Model/Cart/ShippingMethod.php b/app/code/Magento/Quote/Model/Cart/ShippingMethod.php
index da61bf9820df6263a6d079a7b30ec6a3644818ec..75cba2f03cad98c8b53e727e1f4c0e699dde4bdd 100644
--- a/app/code/Magento/Quote/Model/Cart/ShippingMethod.php
+++ b/app/code/Magento/Quote/Model/Cart/ShippingMethod.php
@@ -162,4 +162,26 @@ class ShippingMethod extends \Magento\Framework\Api\AbstractExtensibleObject imp
     {
         return $this->setData(self::KEY_AVAILABLE, $available);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Quote\Api\Data\ShippingMethodExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Quote\Api\Data\ShippingMethodExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Quote\Api\Data\ShippingMethodExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Quote/Model/Cart/Totals.php b/app/code/Magento/Quote/Model/Cart/Totals.php
index a1c8969dc954b50b4efd34192860fa855ee839c7..4612824f9cebb05dc6c4dedbb00bd8827e4019a3 100644
--- a/app/code/Magento/Quote/Model/Cart/Totals.php
+++ b/app/code/Magento/Quote/Model/Cart/Totals.php
@@ -498,4 +498,25 @@ class Totals extends AbstractExtensibleModel implements TotalsInterface
     {
         return $this->setData(self::KEY_ITEMS, $items);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Quote\Api\Data\TotalsExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Quote\Api\Data\TotalsExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Quote\Api\Data\TotalsExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Quote/Model/Cart/Totals/Item.php b/app/code/Magento/Quote/Model/Cart/Totals/Item.php
index 1cd39994d7c644a1277d83906765625c5fbfc79c..0cd716b5082d7ae9f7ef82f82806a2b894959dd3 100644
--- a/app/code/Magento/Quote/Model/Cart/Totals/Item.php
+++ b/app/code/Magento/Quote/Model/Cart/Totals/Item.php
@@ -350,4 +350,25 @@ class Item extends AbstractExtensibleObject implements TotalsItemInterface
     {
         return $this->setData(self::KEY_BASE_ROW_TOTAL_INCL_TAX, $baseRowTotalInclTax);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Quote\Api\Data\TotalsItemExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Quote\Api\Data\TotalsItemExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Quote\Api\Data\TotalsItemExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Quote/Model/Quote.php b/app/code/Magento/Quote/Model/Quote.php
index 22971a88af7530ee0c4c254d1a6d97b4d744b846..91cc54e548ff163128c24a00337041b43671e6ce 100644
--- a/app/code/Magento/Quote/Model/Quote.php
+++ b/app/code/Magento/Quote/Model/Quote.php
@@ -325,7 +325,7 @@ class Quote extends AbstractExtensibleModel implements \Magento\Quote\Api\Data\C
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param QuoteValidator $quoteValidator
      * @param \Magento\Catalog\Helper\Product $catalogProduct
@@ -363,7 +363,7 @@ class Quote extends AbstractExtensibleModel implements \Magento\Quote\Api\Data\C
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Quote\Model\QuoteValidator $quoteValidator,
         \Magento\Catalog\Helper\Product $catalogProduct,
@@ -428,7 +428,7 @@ class Quote extends AbstractExtensibleModel implements \Magento\Quote\Api\Data\C
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
@@ -2525,4 +2525,25 @@ class Quote extends AbstractExtensibleModel implements \Magento\Quote\Api\Data\C
     {
         return \count($this->getAllShippingAddresses()) > 1;
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Quote\Api\Data\CartExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Quote\Api\Data\CartExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Quote\Api\Data\CartExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Quote/Model/Quote/Address.php b/app/code/Magento/Quote/Model/Quote/Address.php
index 01b4582cea36f116cddf6fba40e123c25c1c91d4..c57a8d0d5e8163661cdb1e240d60924801c3e5bb 100644
--- a/app/code/Magento/Quote/Model/Quote/Address.php
+++ b/app/code/Magento/Quote/Model/Quote/Address.php
@@ -8,7 +8,6 @@ namespace Magento\Quote\Model\Quote;
 use Magento\Customer\Api\AddressMetadataInterface;
 use Magento\Customer\Api\Data\AddressInterfaceFactory;
 use Magento\Customer\Api\Data\RegionInterfaceFactory;
-use Magento\Framework\Api\AttributeValueFactory;
 
 /**
  * Sales Quote address model
@@ -228,14 +227,14 @@ class Address extends \Magento\Customer\Model\Address\AbstractAddress implements
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
-     * @param AttributeValueFactory $customAttributeFactory
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
+     * @param \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory
      * @param \Magento\Directory\Helper\Data $directoryData
      * @param \Magento\Eav\Model\Config $eavConfig
      * @param \Magento\Customer\Model\Address\Config $addressConfig
      * @param \Magento\Directory\Model\RegionFactory $regionFactory
      * @param \Magento\Directory\Model\CountryFactory $countryFactory
-     * @param AddressMetadataInterface $addressMetadataService
+     * @param AddressMetadataInterface $metadataService
      * @param AddressInterfaceFactory $addressDataFactory
      * @param RegionInterfaceFactory $regionDataFactory
      * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper
@@ -260,14 +259,14 @@ class Address extends \Magento\Customer\Model\Address\AbstractAddress implements
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
-        AttributeValueFactory $customAttributeFactory,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
+        \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory,
         \Magento\Directory\Helper\Data $directoryData,
         \Magento\Eav\Model\Config $eavConfig,
         \Magento\Customer\Model\Address\Config $addressConfig,
         \Magento\Directory\Model\RegionFactory $regionFactory,
         \Magento\Directory\Model\CountryFactory $countryFactory,
-        AddressMetadataInterface $addressMetadataService,
+        AddressMetadataInterface $metadataService,
         AddressInterfaceFactory $addressDataFactory,
         RegionInterfaceFactory $regionDataFactory,
         \Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
@@ -305,14 +304,14 @@ class Address extends \Magento\Customer\Model\Address\AbstractAddress implements
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $directoryData,
             $eavConfig,
             $addressConfig,
             $regionFactory,
             $countryFactory,
-            $addressMetadataService,
+            $metadataService,
             $addressDataFactory,
             $regionDataFactory,
             $dataObjectHelper,
@@ -1611,4 +1610,25 @@ class Address extends \Magento\Customer\Model\Address\AbstractAddress implements
         return $this->setData(self::KEY_REGION_CODE, $regionCode);
     }
     //@codeCoverageIgnoreEnd
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Quote\Api\Data\AddressExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Quote\Api\Data\AddressExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Quote\Api\Data\AddressExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Quote/Model/Quote/Item.php b/app/code/Magento/Quote/Model/Quote/Item.php
index 8f48eadab4877255c12fe54372edda53fed1947e..8dab6a6d2bf42f326b6397b3e239e943003954a0 100644
--- a/app/code/Magento/Quote/Model/Quote/Item.php
+++ b/app/code/Magento/Quote/Model/Quote/Item.php
@@ -9,7 +9,7 @@
 namespace Magento\Quote\Model\Quote;
 
 use Magento\Framework\Api\AttributeValueFactory;
-use Magento\Framework\Api\MetadataServiceInterface;
+use Magento\Framework\Api\ExtensionAttributesFactory;
 
 /**
  * Sales Quote Item Model
@@ -181,7 +181,7 @@ class Item extends \Magento\Quote\Model\Quote\Item\AbstractItem implements \Mage
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param MetadataServiceInterface $metadataService
+     * @param ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
      * @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
@@ -199,7 +199,7 @@ class Item extends \Magento\Quote\Model\Quote\Item\AbstractItem implements \Mage
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        MetadataServiceInterface $metadataService,
+        ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
         \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
@@ -220,7 +220,7 @@ class Item extends \Magento\Quote\Model\Quote\Item\AbstractItem implements \Mage
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $productRepository,
             $priceCurrency,
@@ -1002,4 +1002,25 @@ class Item extends \Magento\Quote\Model\Quote\Item\AbstractItem implements \Mage
         return $this->setData(self::KEY_QUOTE_ID, $quoteId);
     }
     //@codeCoverageIgnoreEnd
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Quote\Api\Data\CartItemExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Quote\Api\Data\CartItemExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Quote\Api\Data\CartItemExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Quote/Model/Quote/Item/AbstractItem.php b/app/code/Magento/Quote/Model/Quote/Item/AbstractItem.php
index 5a689e03d994a9afb8185c9fe8b6ea5a5c5034bf..8542ee1e6abb22406a447ba1386c372fc564a7db 100644
--- a/app/code/Magento/Quote/Model/Quote/Item/AbstractItem.php
+++ b/app/code/Magento/Quote/Model/Quote/Item/AbstractItem.php
@@ -83,7 +83,7 @@ abstract class AbstractItem extends \Magento\Framework\Model\AbstractExtensibleM
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
      * @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
@@ -94,7 +94,7 @@ abstract class AbstractItem extends \Magento\Framework\Model\AbstractExtensibleM
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
         \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
@@ -105,7 +105,7 @@ abstract class AbstractItem extends \Magento\Framework\Model\AbstractExtensibleM
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
diff --git a/app/code/Magento/Quote/Model/Quote/Payment.php b/app/code/Magento/Quote/Model/Quote/Payment.php
index f420bad2202e58d972379a4202203b1a3f210ac7..f071b845cbb1fe3509696882da93882829db3f2a 100644
--- a/app/code/Magento/Quote/Model/Quote/Payment.php
+++ b/app/code/Magento/Quote/Model/Quote/Payment.php
@@ -5,8 +5,6 @@
  */
 namespace Magento\Quote\Model\Quote;
 
-use Magento\Framework\Api\AttributeValueFactory;
-
 /**
  * Quote payment information
  *
@@ -63,8 +61,8 @@ class Payment extends \Magento\Payment\Model\Info implements \Magento\Quote\Api\
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
-     * @param AttributeValueFactory $customAttributeFactory
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
+     * @param \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\Encryption\EncryptorInterface $encryptor
      * @param \Magento\Payment\Model\Checks\SpecificationFactory $methodSpecificationFactory
@@ -76,8 +74,8 @@ class Payment extends \Magento\Payment\Model\Info implements \Magento\Quote\Api\
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
-        AttributeValueFactory $customAttributeFactory,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
+        \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\Encryption\EncryptorInterface $encryptor,
         \Magento\Payment\Model\Checks\SpecificationFactory $methodSpecificationFactory,
@@ -89,7 +87,7 @@ class Payment extends \Magento\Payment\Model\Info implements \Magento\Quote\Api\
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $paymentData,
             $encryptor,
@@ -414,4 +412,25 @@ class Payment extends \Magento\Payment\Model\Info implements \Magento\Quote\Api\
         return $this->setData(self::KEY_ADDITIONAL_DATA, $additionalData);
     }
     //@codeCoverageIgnoreEnd
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Quote\Api\Data\PaymentExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Quote\Api\Data\PaymentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Quote\Api\Data\PaymentExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Quote/Test/Unit/Model/Quote/Payment/ToOrderPaymentTest.php b/app/code/Magento/Quote/Test/Unit/Model/Quote/Payment/ToOrderPaymentTest.php
index 8349a6e8f19e669d1b664c1f627616934d3e9da2..b68aeb602acb6cfd7d7d8af9cf45b60595dcd6c6 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/Quote/Payment/ToOrderPaymentTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/Quote/Payment/ToOrderPaymentTest.php
@@ -4,6 +4,8 @@
  * See COPYING.txt for license details.
  */
 
+// @codingStandardsIgnoreFile
+
 namespace Magento\Quote\Test\Unit\Model\Quote\Payment;
 
 use Magento\Payment\Model\Method\Substitution;
@@ -79,7 +81,7 @@ class ToOrderPaymentTest extends \PHPUnit_Framework_TestCase
         $data = ['some_id' => 1];
         $paymentMethodTitle = 'TestTitle';
         $additionalInfo = ['token' => 'TOKEN-123'];
-        
+
         $this->paymentMock->expects($this->once())->method('getMethodInstance')->willReturn($methodInterface);
         $methodInterface->expects($this->once())->method('getTitle')->willReturn($paymentMethodTitle);
         $this->objectCopyMock->expects($this->once())->method('getDataFromFieldset')->with(
diff --git a/app/code/Magento/Sales/Api/Data/CreditmemoCommentInterface.php b/app/code/Magento/Sales/Api/Data/CreditmemoCommentInterface.php
index 4d8ce351eddeb4cfa5f96c0ea73a963465e9e938..28afae3c0f9528343770c22dfe283b82324a7c5a 100644
--- a/app/code/Magento/Sales/Api/Data/CreditmemoCommentInterface.php
+++ b/app/code/Magento/Sales/Api/Data/CreditmemoCommentInterface.php
@@ -124,4 +124,21 @@ interface CreditmemoCommentInterface extends \Magento\Framework\Api\ExtensibleDa
      * @return $this
      */
     public function setComment($comment);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Sales\Api\Data\CreditmemoCommentExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Sales\Api\Data\CreditmemoCommentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Sales\Api\Data\CreditmemoCommentExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Sales/Api/Data/CreditmemoInterface.php b/app/code/Magento/Sales/Api/Data/CreditmemoInterface.php
index 8063c5d64e3aa6c766f21955d9731c30c61f6be1..205d5c37b3f1033132c9679a240e036223a2e5e8 100644
--- a/app/code/Magento/Sales/Api/Data/CreditmemoInterface.php
+++ b/app/code/Magento/Sales/Api/Data/CreditmemoInterface.php
@@ -960,4 +960,19 @@ interface CreditmemoInterface extends \Magento\Framework\Api\ExtensibleDataInter
      * @return $this
      */
     public function setDiscountDescription($description);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Sales\Api\Data\CreditmemoExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Sales\Api\Data\CreditmemoExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\CreditmemoExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Sales/Api/Data/CreditmemoItemInterface.php b/app/code/Magento/Sales/Api/Data/CreditmemoItemInterface.php
index c01bb4c6ee75d2ebb127aa20d6211cc3f0a95892..f93eedf1cff1f281cdc2ca9cbff68719cc67f6bb 100644
--- a/app/code/Magento/Sales/Api/Data/CreditmemoItemInterface.php
+++ b/app/code/Magento/Sales/Api/Data/CreditmemoItemInterface.php
@@ -645,4 +645,21 @@ interface CreditmemoItemInterface extends \Magento\Framework\Api\ExtensibleDataI
      * @return $this
      */
     public function setWeeeTaxAppliedRowAmount($amount);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Sales\Api\Data\CreditmemoItemExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Sales\Api\Data\CreditmemoItemExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Sales\Api\Data\CreditmemoItemExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php b/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php
index 05e605a530f94a822ed1496cf73abc5729b119c1..10c86a870231cd4cd0c24a165c1cc5cf022bcdaf 100644
--- a/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php
+++ b/app/code/Magento/Sales/Api/Data/InvoiceCommentInterface.php
@@ -122,4 +122,21 @@ interface InvoiceCommentInterface extends \Magento\Framework\Api\ExtensibleDataI
      * @return $this
      */
     public function setComment($comment);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Sales\Api\Data\InvoiceCommentExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Sales\Api\Data\InvoiceCommentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Sales\Api\Data\InvoiceCommentExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Sales/Api/Data/InvoiceInterface.php b/app/code/Magento/Sales/Api/Data/InvoiceInterface.php
index 6cd291831bf5892bb8180223d8b007a48eb082d3..e17decc98e0bbd364313f43a2d7373cbfd7990cc 100644
--- a/app/code/Magento/Sales/Api/Data/InvoiceInterface.php
+++ b/app/code/Magento/Sales/Api/Data/InvoiceInterface.php
@@ -881,4 +881,19 @@ interface InvoiceInterface extends \Magento\Framework\Api\ExtensibleDataInterfac
      * @return $this
      */
     public function setDiscountDescription($description);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Sales\Api\Data\InvoiceExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Sales\Api\Data\InvoiceExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\InvoiceExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php b/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php
index 127318da2ef1ca63d43a73c1958fff462ee03cf8..6dc2d85022e727245aaa71475e4355f2ef05060c 100644
--- a/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php
+++ b/app/code/Magento/Sales/Api/Data/InvoiceItemInterface.php
@@ -471,4 +471,19 @@ interface InvoiceItemInterface extends \Magento\Framework\Api\ExtensibleDataInte
      * @return $this
      */
     public function setBaseHiddenTaxAmount($amount);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Sales\Api\Data\InvoiceItemExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Sales\Api\Data\InvoiceItemExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\InvoiceItemExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Sales/Api/Data/OrderAddressInterface.php b/app/code/Magento/Sales/Api/Data/OrderAddressInterface.php
index 10c62d33ee5ce320785a1cee71af02e9c7208f89..9e9e53f1727a00ba597fae6a2e4402c943b717c0 100644
--- a/app/code/Magento/Sales/Api/Data/OrderAddressInterface.php
+++ b/app/code/Magento/Sales/Api/Data/OrderAddressInterface.php
@@ -508,4 +508,19 @@ interface OrderAddressInterface extends \Magento\Framework\Api\ExtensibleDataInt
      * @return $this
      */
     public function setVatRequestSuccess($vatRequestSuccess);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Sales\Api\Data\OrderAddressExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Sales\Api\Data\OrderAddressExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\OrderAddressExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Sales/Api/Data/OrderInterface.php b/app/code/Magento/Sales/Api/Data/OrderInterface.php
index b01e0d81d76047e60d7aad7bd8ac56269c5b1a88..7bd62fbe1c3228b2241690b981a7f0ab8c2f84eb 100644
--- a/app/code/Magento/Sales/Api/Data/OrderInterface.php
+++ b/app/code/Magento/Sales/Api/Data/OrderInterface.php
@@ -2672,4 +2672,19 @@ interface OrderInterface extends \Magento\Framework\Api\ExtensibleDataInterface
      * @return $this
      */
     public function setBaseShippingInclTax($amount);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Sales\Api\Data\OrderExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Sales\Api\Data\OrderExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\OrderExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Sales/Api/Data/OrderItemInterface.php b/app/code/Magento/Sales/Api/Data/OrderItemInterface.php
index 286f79aefd34631c48fb7d1e07e77881e3cdd8cf..6e59b03a98370feb88a6d6522c9fb84560e12bf3 100644
--- a/app/code/Magento/Sales/Api/Data/OrderItemInterface.php
+++ b/app/code/Magento/Sales/Api/Data/OrderItemInterface.php
@@ -1797,4 +1797,19 @@ interface OrderItemInterface extends \Magento\Framework\Api\ExtensibleDataInterf
      * @return $this
      */
     public function setBaseWeeeTaxRowDisposition($baseWeeeTaxRowDisposition);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Sales\Api\Data\OrderItemExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Sales\Api\Data\OrderItemExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\OrderItemExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Sales/Api/Data/OrderPaymentInterface.php b/app/code/Magento/Sales/Api/Data/OrderPaymentInterface.php
index d080a1cd765a3446e8ddb3eb285bbed44079b09a..44fda2cdbcc1c5424b4d8518ae9917cefb3c1932 100644
--- a/app/code/Magento/Sales/Api/Data/OrderPaymentInterface.php
+++ b/app/code/Magento/Sales/Api/Data/OrderPaymentInterface.php
@@ -1035,4 +1035,19 @@ interface OrderPaymentInterface extends \Magento\Framework\Api\ExtensibleDataInt
      * @return $this
      */
     public function setAddressStatus($addressStatus);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Sales\Api\Data\OrderPaymentExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Sales\Api\Data\OrderPaymentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\OrderPaymentExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Sales/Api/Data/OrderStatusHistoryInterface.php b/app/code/Magento/Sales/Api/Data/OrderStatusHistoryInterface.php
index dafc6547d77052f68cb63ed0d5a531a0b68f2fce..4ef7daf322d37f0ca1b26f0ab7501e7ad5a79fcf 100644
--- a/app/code/Magento/Sales/Api/Data/OrderStatusHistoryInterface.php
+++ b/app/code/Magento/Sales/Api/Data/OrderStatusHistoryInterface.php
@@ -161,4 +161,21 @@ interface OrderStatusHistoryInterface extends \Magento\Framework\Api\ExtensibleD
      * @return $this
      */
     public function setEntityName($entityName);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Sales\Api\Data\OrderStatusHistoryExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Sales\Api\Data\OrderStatusHistoryExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Sales\Api\Data\OrderStatusHistoryExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Sales/Api/Data/ShipmentCommentInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentCommentInterface.php
index 56346939103c84913e7bd883235b69e97fce9463..213b7c2e5e4931bd9f9295aee3b537f817891a68 100644
--- a/app/code/Magento/Sales/Api/Data/ShipmentCommentInterface.php
+++ b/app/code/Magento/Sales/Api/Data/ShipmentCommentInterface.php
@@ -122,4 +122,21 @@ interface ShipmentCommentInterface extends \Magento\Framework\Api\ExtensibleData
      * @return $this
      */
     public function setComment($comment);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Sales\Api\Data\ShipmentCommentExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Sales\Api\Data\ShipmentCommentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Sales\Api\Data\ShipmentCommentExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Sales/Api/Data/ShipmentInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentInterface.php
index dbd2854e9ce220d14bf785de3ee60339336d619a..3af3b16ebf66154df3527aa22d298881cab5466e 100644
--- a/app/code/Magento/Sales/Api/Data/ShipmentInterface.php
+++ b/app/code/Magento/Sales/Api/Data/ShipmentInterface.php
@@ -350,4 +350,19 @@ interface ShipmentInterface extends \Magento\Framework\Api\ExtensibleDataInterfa
      * @return $this
      */
     public function setUpdatedAt($timestamp);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Sales\Api\Data\ShipmentExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Sales\Api\Data\ShipmentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\ShipmentExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Sales/Api/Data/ShipmentItemInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentItemInterface.php
index 5b78e92571050f0a0cb7f40f83c3969f9916c54b..ad75b14cde2a155b5e684da289997b1d488b324c 100644
--- a/app/code/Magento/Sales/Api/Data/ShipmentItemInterface.php
+++ b/app/code/Magento/Sales/Api/Data/ShipmentItemInterface.php
@@ -244,4 +244,19 @@ interface ShipmentItemInterface extends \Magento\Framework\Api\ExtensibleDataInt
      * @return $this
      */
     public function setSku($sku);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Sales\Api\Data\ShipmentItemExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Sales\Api\Data\ShipmentItemExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\ShipmentItemExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Sales/Api/Data/ShipmentPackageInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentPackageInterface.php
index 9172405a3f7d531a9da67966c552e6a8a00b3ba9..00b79d6f50e6d725fadb4a92e2ced0a456179cd0 100644
--- a/app/code/Magento/Sales/Api/Data/ShipmentPackageInterface.php
+++ b/app/code/Magento/Sales/Api/Data/ShipmentPackageInterface.php
@@ -13,4 +13,20 @@ namespace Magento\Sales\Api\Data;
  */
 interface ShipmentPackageInterface extends \Magento\Framework\Api\ExtensibleDataInterface
 {
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Sales\Api\Data\ShipmentPackageExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Sales\Api\Data\ShipmentPackageExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Sales\Api\Data\ShipmentPackageExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php b/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php
index 7160fc3fff2d8a7c415d5a143f5192ed08dbc9cb..7ace1ead4114db6c8c81c9a3921d56f1e9195727 100644
--- a/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php
+++ b/app/code/Magento/Sales/Api/Data/ShipmentTrackInterface.php
@@ -218,4 +218,21 @@ interface ShipmentTrackInterface extends \Magento\Framework\Api\ExtensibleDataIn
      * @return $this
      */
     public function setCarrierCode($code);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Sales\Api\Data\ShipmentTrackExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Sales\Api\Data\ShipmentTrackExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Sales\Api\Data\ShipmentTrackExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Sales/Api/Data/TransactionInterface.php b/app/code/Magento/Sales/Api/Data/TransactionInterface.php
index 1e350f1388372111181a71a1b276912925274d42..224d9765582f0e3381846f159814103e72111351 100644
--- a/app/code/Magento/Sales/Api/Data/TransactionInterface.php
+++ b/app/code/Magento/Sales/Api/Data/TransactionInterface.php
@@ -212,4 +212,19 @@ interface TransactionInterface extends \Magento\Framework\Api\ExtensibleDataInte
      * @throws \Magento\Framework\Exception\LocalizedException
      */
     public function setAdditionalInformation($key, $value);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Sales\Api\Data\TransactionExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Sales\Api\Data\TransactionExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\TransactionExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Sales/Model/AbstractModel.php b/app/code/Magento/Sales/Model/AbstractModel.php
index b87d43e79f47cb97ceedab4e14bdd9babb13e002..a506b7efd3b3b02c5683a5ea2bc87611422c7de0 100644
--- a/app/code/Magento/Sales/Model/AbstractModel.php
+++ b/app/code/Magento/Sales/Model/AbstractModel.php
@@ -27,7 +27,7 @@ abstract class AbstractModel extends AbstractExtensibleModel
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
@@ -38,7 +38,7 @@ abstract class AbstractModel extends AbstractExtensibleModel
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Framework\Stdlib\DateTime $dateTime,
@@ -49,7 +49,7 @@ abstract class AbstractModel extends AbstractExtensibleModel
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php
index fa437025ad8487896f2a011d7d4248e45f8025ab..6a27ad12b323da64252cbdaf0ac2005f9cbd62f9 100644
--- a/app/code/Magento/Sales/Model/Order.php
+++ b/app/code/Magento/Sales/Model/Order.php
@@ -9,7 +9,7 @@ use Magento\Directory\Model\Currency;
 use Magento\Framework\Api\AttributeValueFactory;
 use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Framework\Pricing\PriceCurrencyInterface;
-use Magento\Sales\Api\Data\OrderInterface as ApiOrderInterface;
+use Magento\Sales\Api\Data\OrderInterface;
 use Magento\Sales\Api\Data\OrderStatusHistoryInterface;
 use Magento\Sales\Model\Order\Payment;
 use Magento\Sales\Model\Resource\Order\Address\Collection;
@@ -50,7 +50,7 @@ use Magento\Sales\Model\Resource\Order\Status\History\Collection as HistoryColle
  * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
-class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
+class Order extends AbstractModel implements EntityInterface, OrderInterface
 {
     const ENTITY = 'order';
 
@@ -260,7 +260,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
@@ -290,7 +290,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Framework\Stdlib\DateTime $dateTime,
@@ -338,7 +338,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $localeDate,
             $dateTime,
@@ -1944,13 +1944,13 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getItems()
     {
-        if ($this->getData(ApiOrderInterface::ITEMS) == null) {
+        if ($this->getData(OrderInterface::ITEMS) == null) {
             $this->setData(
-                ApiOrderInterface::ITEMS,
+                OrderInterface::ITEMS,
                 $this->getItemsCollection()->getItems()
             );
         }
-        return $this->getData(ApiOrderInterface::ITEMS);
+        return $this->getData(OrderInterface::ITEMS);
     }
 
     /**
@@ -1958,7 +1958,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setItems($items)
     {
-        return $this->setData(ApiOrderInterface::ITEMS, $items);
+        return $this->setData(OrderInterface::ITEMS, $items);
     }
 
     /**
@@ -1966,13 +1966,13 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getPayments()
     {
-        if ($this->getData(ApiOrderInterface::PAYMENTS) == null) {
+        if ($this->getData(OrderInterface::PAYMENTS) == null) {
             $this->setData(
-                ApiOrderInterface::PAYMENTS,
+                OrderInterface::PAYMENTS,
                 $this->getPaymentsCollection()->getItems()
             );
         }
-        return $this->getData(ApiOrderInterface::PAYMENTS);
+        return $this->getData(OrderInterface::PAYMENTS);
     }
 
     /**
@@ -1980,7 +1980,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setPayments(array $payments = null)
     {
-        return $this->setData(ApiOrderInterface::PAYMENTS, $payments);
+        return $this->setData(OrderInterface::PAYMENTS, $payments);
     }
 
     /**
@@ -1988,13 +1988,13 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getAddresses()
     {
-        if ($this->getData(ApiOrderInterface::ADDRESSES) == null) {
+        if ($this->getData(OrderInterface::ADDRESSES) == null) {
             $this->setData(
-                ApiOrderInterface::ADDRESSES,
+                OrderInterface::ADDRESSES,
                 $this->getAddressesCollection()->getItems()
             );
         }
-        return $this->getData(ApiOrderInterface::ADDRESSES);
+        return $this->getData(OrderInterface::ADDRESSES);
     }
 
     /**
@@ -2002,7 +2002,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setAddresses(array $addresses = null)
     {
-        return $this->setData(ApiOrderInterface::ADDRESSES, $addresses);
+        return $this->setData(OrderInterface::ADDRESSES, $addresses);
     }
 
     /**
@@ -2012,7 +2012,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getAdjustmentNegative()
     {
-        return $this->getData(ApiOrderInterface::ADJUSTMENT_NEGATIVE);
+        return $this->getData(OrderInterface::ADJUSTMENT_NEGATIVE);
     }
 
     /**
@@ -2022,7 +2022,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getAdjustmentPositive()
     {
-        return $this->getData(ApiOrderInterface::ADJUSTMENT_POSITIVE);
+        return $this->getData(OrderInterface::ADJUSTMENT_POSITIVE);
     }
 
     /**
@@ -2032,7 +2032,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getAppliedRuleIds()
     {
-        return $this->getData(ApiOrderInterface::APPLIED_RULE_IDS);
+        return $this->getData(OrderInterface::APPLIED_RULE_IDS);
     }
 
     /**
@@ -2042,7 +2042,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseAdjustmentNegative()
     {
-        return $this->getData(ApiOrderInterface::BASE_ADJUSTMENT_NEGATIVE);
+        return $this->getData(OrderInterface::BASE_ADJUSTMENT_NEGATIVE);
     }
 
     /**
@@ -2052,7 +2052,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseAdjustmentPositive()
     {
-        return $this->getData(ApiOrderInterface::BASE_ADJUSTMENT_POSITIVE);
+        return $this->getData(OrderInterface::BASE_ADJUSTMENT_POSITIVE);
     }
 
     /**
@@ -2062,7 +2062,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseCurrencyCode()
     {
-        return $this->getData(ApiOrderInterface::BASE_CURRENCY_CODE);
+        return $this->getData(OrderInterface::BASE_CURRENCY_CODE);
     }
 
     /**
@@ -2072,7 +2072,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseDiscountAmount()
     {
-        return $this->getData(ApiOrderInterface::BASE_DISCOUNT_AMOUNT);
+        return $this->getData(OrderInterface::BASE_DISCOUNT_AMOUNT);
     }
 
     /**
@@ -2082,7 +2082,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseDiscountCanceled()
     {
-        return $this->getData(ApiOrderInterface::BASE_DISCOUNT_CANCELED);
+        return $this->getData(OrderInterface::BASE_DISCOUNT_CANCELED);
     }
 
     /**
@@ -2092,7 +2092,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseDiscountInvoiced()
     {
-        return $this->getData(ApiOrderInterface::BASE_DISCOUNT_INVOICED);
+        return $this->getData(OrderInterface::BASE_DISCOUNT_INVOICED);
     }
 
     /**
@@ -2102,7 +2102,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseDiscountRefunded()
     {
-        return $this->getData(ApiOrderInterface::BASE_DISCOUNT_REFUNDED);
+        return $this->getData(OrderInterface::BASE_DISCOUNT_REFUNDED);
     }
 
     /**
@@ -2112,7 +2112,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseGrandTotal()
     {
-        return $this->getData(ApiOrderInterface::BASE_GRAND_TOTAL);
+        return $this->getData(OrderInterface::BASE_GRAND_TOTAL);
     }
 
     /**
@@ -2122,7 +2122,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseHiddenTaxAmount()
     {
-        return $this->getData(ApiOrderInterface::BASE_HIDDEN_TAX_AMOUNT);
+        return $this->getData(OrderInterface::BASE_HIDDEN_TAX_AMOUNT);
     }
 
     /**
@@ -2132,7 +2132,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseHiddenTaxInvoiced()
     {
-        return $this->getData(ApiOrderInterface::BASE_HIDDEN_TAX_INVOICED);
+        return $this->getData(OrderInterface::BASE_HIDDEN_TAX_INVOICED);
     }
 
     /**
@@ -2142,7 +2142,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseHiddenTaxRefunded()
     {
-        return $this->getData(ApiOrderInterface::BASE_HIDDEN_TAX_REFUNDED);
+        return $this->getData(OrderInterface::BASE_HIDDEN_TAX_REFUNDED);
     }
 
     /**
@@ -2152,7 +2152,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseShippingAmount()
     {
-        return $this->getData(ApiOrderInterface::BASE_SHIPPING_AMOUNT);
+        return $this->getData(OrderInterface::BASE_SHIPPING_AMOUNT);
     }
 
     /**
@@ -2162,7 +2162,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseShippingCanceled()
     {
-        return $this->getData(ApiOrderInterface::BASE_SHIPPING_CANCELED);
+        return $this->getData(OrderInterface::BASE_SHIPPING_CANCELED);
     }
 
     /**
@@ -2172,7 +2172,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseShippingDiscountAmount()
     {
-        return $this->getData(ApiOrderInterface::BASE_SHIPPING_DISCOUNT_AMOUNT);
+        return $this->getData(OrderInterface::BASE_SHIPPING_DISCOUNT_AMOUNT);
     }
 
     /**
@@ -2182,7 +2182,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseShippingHiddenTaxAmnt()
     {
-        return $this->getData(ApiOrderInterface::BASE_SHIPPING_HIDDEN_TAX_AMNT);
+        return $this->getData(OrderInterface::BASE_SHIPPING_HIDDEN_TAX_AMNT);
     }
 
     /**
@@ -2192,7 +2192,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseShippingInclTax()
     {
-        return $this->getData(ApiOrderInterface::BASE_SHIPPING_INCL_TAX);
+        return $this->getData(OrderInterface::BASE_SHIPPING_INCL_TAX);
     }
 
     /**
@@ -2202,7 +2202,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseShippingInvoiced()
     {
-        return $this->getData(ApiOrderInterface::BASE_SHIPPING_INVOICED);
+        return $this->getData(OrderInterface::BASE_SHIPPING_INVOICED);
     }
 
     /**
@@ -2212,7 +2212,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseShippingRefunded()
     {
-        return $this->getData(ApiOrderInterface::BASE_SHIPPING_REFUNDED);
+        return $this->getData(OrderInterface::BASE_SHIPPING_REFUNDED);
     }
 
     /**
@@ -2222,7 +2222,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseShippingTaxAmount()
     {
-        return $this->getData(ApiOrderInterface::BASE_SHIPPING_TAX_AMOUNT);
+        return $this->getData(OrderInterface::BASE_SHIPPING_TAX_AMOUNT);
     }
 
     /**
@@ -2232,7 +2232,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseShippingTaxRefunded()
     {
-        return $this->getData(ApiOrderInterface::BASE_SHIPPING_TAX_REFUNDED);
+        return $this->getData(OrderInterface::BASE_SHIPPING_TAX_REFUNDED);
     }
 
     /**
@@ -2242,7 +2242,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseSubtotal()
     {
-        return $this->getData(ApiOrderInterface::BASE_SUBTOTAL);
+        return $this->getData(OrderInterface::BASE_SUBTOTAL);
     }
 
     /**
@@ -2252,7 +2252,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseSubtotalCanceled()
     {
-        return $this->getData(ApiOrderInterface::BASE_SUBTOTAL_CANCELED);
+        return $this->getData(OrderInterface::BASE_SUBTOTAL_CANCELED);
     }
 
     /**
@@ -2262,7 +2262,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseSubtotalInclTax()
     {
-        return $this->getData(ApiOrderInterface::BASE_SUBTOTAL_INCL_TAX);
+        return $this->getData(OrderInterface::BASE_SUBTOTAL_INCL_TAX);
     }
 
     /**
@@ -2272,7 +2272,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseSubtotalInvoiced()
     {
-        return $this->getData(ApiOrderInterface::BASE_SUBTOTAL_INVOICED);
+        return $this->getData(OrderInterface::BASE_SUBTOTAL_INVOICED);
     }
 
     /**
@@ -2282,7 +2282,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseSubtotalRefunded()
     {
-        return $this->getData(ApiOrderInterface::BASE_SUBTOTAL_REFUNDED);
+        return $this->getData(OrderInterface::BASE_SUBTOTAL_REFUNDED);
     }
 
     /**
@@ -2292,7 +2292,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseTaxAmount()
     {
-        return $this->getData(ApiOrderInterface::BASE_TAX_AMOUNT);
+        return $this->getData(OrderInterface::BASE_TAX_AMOUNT);
     }
 
     /**
@@ -2302,7 +2302,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseTaxCanceled()
     {
-        return $this->getData(ApiOrderInterface::BASE_TAX_CANCELED);
+        return $this->getData(OrderInterface::BASE_TAX_CANCELED);
     }
 
     /**
@@ -2312,7 +2312,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseTaxInvoiced()
     {
-        return $this->getData(ApiOrderInterface::BASE_TAX_INVOICED);
+        return $this->getData(OrderInterface::BASE_TAX_INVOICED);
     }
 
     /**
@@ -2322,7 +2322,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseTaxRefunded()
     {
-        return $this->getData(ApiOrderInterface::BASE_TAX_REFUNDED);
+        return $this->getData(OrderInterface::BASE_TAX_REFUNDED);
     }
 
     /**
@@ -2332,7 +2332,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseTotalCanceled()
     {
-        return $this->getData(ApiOrderInterface::BASE_TOTAL_CANCELED);
+        return $this->getData(OrderInterface::BASE_TOTAL_CANCELED);
     }
 
     /**
@@ -2342,7 +2342,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseTotalInvoiced()
     {
-        return $this->getData(ApiOrderInterface::BASE_TOTAL_INVOICED);
+        return $this->getData(OrderInterface::BASE_TOTAL_INVOICED);
     }
 
     /**
@@ -2352,7 +2352,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseTotalInvoicedCost()
     {
-        return $this->getData(ApiOrderInterface::BASE_TOTAL_INVOICED_COST);
+        return $this->getData(OrderInterface::BASE_TOTAL_INVOICED_COST);
     }
 
     /**
@@ -2362,7 +2362,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseTotalOfflineRefunded()
     {
-        return $this->getData(ApiOrderInterface::BASE_TOTAL_OFFLINE_REFUNDED);
+        return $this->getData(OrderInterface::BASE_TOTAL_OFFLINE_REFUNDED);
     }
 
     /**
@@ -2372,7 +2372,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseTotalOnlineRefunded()
     {
-        return $this->getData(ApiOrderInterface::BASE_TOTAL_ONLINE_REFUNDED);
+        return $this->getData(OrderInterface::BASE_TOTAL_ONLINE_REFUNDED);
     }
 
     /**
@@ -2382,7 +2382,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseTotalPaid()
     {
-        return $this->getData(ApiOrderInterface::BASE_TOTAL_PAID);
+        return $this->getData(OrderInterface::BASE_TOTAL_PAID);
     }
 
     /**
@@ -2392,7 +2392,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseTotalQtyOrdered()
     {
-        return $this->getData(ApiOrderInterface::BASE_TOTAL_QTY_ORDERED);
+        return $this->getData(OrderInterface::BASE_TOTAL_QTY_ORDERED);
     }
 
     /**
@@ -2402,7 +2402,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseTotalRefunded()
     {
-        return $this->getData(ApiOrderInterface::BASE_TOTAL_REFUNDED);
+        return $this->getData(OrderInterface::BASE_TOTAL_REFUNDED);
     }
 
     /**
@@ -2412,7 +2412,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseToGlobalRate()
     {
-        return $this->getData(ApiOrderInterface::BASE_TO_GLOBAL_RATE);
+        return $this->getData(OrderInterface::BASE_TO_GLOBAL_RATE);
     }
 
     /**
@@ -2422,7 +2422,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBaseToOrderRate()
     {
-        return $this->getData(ApiOrderInterface::BASE_TO_ORDER_RATE);
+        return $this->getData(OrderInterface::BASE_TO_ORDER_RATE);
     }
 
     /**
@@ -2432,7 +2432,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getBillingAddressId()
     {
-        return $this->getData(ApiOrderInterface::BILLING_ADDRESS_ID);
+        return $this->getData(OrderInterface::BILLING_ADDRESS_ID);
     }
 
     /**
@@ -2442,7 +2442,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getCanShipPartially()
     {
-        return $this->getData(ApiOrderInterface::CAN_SHIP_PARTIALLY);
+        return $this->getData(OrderInterface::CAN_SHIP_PARTIALLY);
     }
 
     /**
@@ -2452,7 +2452,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getCanShipPartiallyItem()
     {
-        return $this->getData(ApiOrderInterface::CAN_SHIP_PARTIALLY_ITEM);
+        return $this->getData(OrderInterface::CAN_SHIP_PARTIALLY_ITEM);
     }
 
     /**
@@ -2462,7 +2462,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getCouponCode()
     {
-        return $this->getData(ApiOrderInterface::COUPON_CODE);
+        return $this->getData(OrderInterface::COUPON_CODE);
     }
 
     /**
@@ -2472,7 +2472,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getCreatedAt()
     {
-        return $this->getData(ApiOrderInterface::CREATED_AT);
+        return $this->getData(OrderInterface::CREATED_AT);
     }
 
     /**
@@ -2482,7 +2482,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getCustomerDob()
     {
-        return $this->getData(ApiOrderInterface::CUSTOMER_DOB);
+        return $this->getData(OrderInterface::CUSTOMER_DOB);
     }
 
     /**
@@ -2492,7 +2492,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getCustomerEmail()
     {
-        return $this->getData(ApiOrderInterface::CUSTOMER_EMAIL);
+        return $this->getData(OrderInterface::CUSTOMER_EMAIL);
     }
 
     /**
@@ -2502,7 +2502,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getCustomerFirstname()
     {
-        return $this->getData(ApiOrderInterface::CUSTOMER_FIRSTNAME);
+        return $this->getData(OrderInterface::CUSTOMER_FIRSTNAME);
     }
 
     /**
@@ -2512,7 +2512,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getCustomerGender()
     {
-        return $this->getData(ApiOrderInterface::CUSTOMER_GENDER);
+        return $this->getData(OrderInterface::CUSTOMER_GENDER);
     }
 
     /**
@@ -2522,7 +2522,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getCustomerGroupId()
     {
-        return $this->getData(ApiOrderInterface::CUSTOMER_GROUP_ID);
+        return $this->getData(OrderInterface::CUSTOMER_GROUP_ID);
     }
 
     /**
@@ -2532,7 +2532,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getCustomerId()
     {
-        return $this->getData(ApiOrderInterface::CUSTOMER_ID);
+        return $this->getData(OrderInterface::CUSTOMER_ID);
     }
 
     /**
@@ -2542,7 +2542,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getCustomerIsGuest()
     {
-        return $this->getData(ApiOrderInterface::CUSTOMER_IS_GUEST);
+        return $this->getData(OrderInterface::CUSTOMER_IS_GUEST);
     }
 
     /**
@@ -2552,7 +2552,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getCustomerLastname()
     {
-        return $this->getData(ApiOrderInterface::CUSTOMER_LASTNAME);
+        return $this->getData(OrderInterface::CUSTOMER_LASTNAME);
     }
 
     /**
@@ -2562,7 +2562,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getCustomerMiddlename()
     {
-        return $this->getData(ApiOrderInterface::CUSTOMER_MIDDLENAME);
+        return $this->getData(OrderInterface::CUSTOMER_MIDDLENAME);
     }
 
     /**
@@ -2572,7 +2572,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getCustomerNote()
     {
-        return $this->getData(ApiOrderInterface::CUSTOMER_NOTE);
+        return $this->getData(OrderInterface::CUSTOMER_NOTE);
     }
 
     /**
@@ -2582,7 +2582,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getCustomerNoteNotify()
     {
-        return $this->getData(ApiOrderInterface::CUSTOMER_NOTE_NOTIFY);
+        return $this->getData(OrderInterface::CUSTOMER_NOTE_NOTIFY);
     }
 
     /**
@@ -2592,7 +2592,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getCustomerPrefix()
     {
-        return $this->getData(ApiOrderInterface::CUSTOMER_PREFIX);
+        return $this->getData(OrderInterface::CUSTOMER_PREFIX);
     }
 
     /**
@@ -2602,7 +2602,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getCustomerSuffix()
     {
-        return $this->getData(ApiOrderInterface::CUSTOMER_SUFFIX);
+        return $this->getData(OrderInterface::CUSTOMER_SUFFIX);
     }
 
     /**
@@ -2612,7 +2612,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getCustomerTaxvat()
     {
-        return $this->getData(ApiOrderInterface::CUSTOMER_TAXVAT);
+        return $this->getData(OrderInterface::CUSTOMER_TAXVAT);
     }
 
     /**
@@ -2622,7 +2622,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getDiscountAmount()
     {
-        return $this->getData(ApiOrderInterface::DISCOUNT_AMOUNT);
+        return $this->getData(OrderInterface::DISCOUNT_AMOUNT);
     }
 
     /**
@@ -2632,7 +2632,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getDiscountCanceled()
     {
-        return $this->getData(ApiOrderInterface::DISCOUNT_CANCELED);
+        return $this->getData(OrderInterface::DISCOUNT_CANCELED);
     }
 
     /**
@@ -2642,7 +2642,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getDiscountDescription()
     {
-        return $this->getData(ApiOrderInterface::DISCOUNT_DESCRIPTION);
+        return $this->getData(OrderInterface::DISCOUNT_DESCRIPTION);
     }
 
     /**
@@ -2652,7 +2652,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getDiscountInvoiced()
     {
-        return $this->getData(ApiOrderInterface::DISCOUNT_INVOICED);
+        return $this->getData(OrderInterface::DISCOUNT_INVOICED);
     }
 
     /**
@@ -2662,7 +2662,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getDiscountRefunded()
     {
-        return $this->getData(ApiOrderInterface::DISCOUNT_REFUNDED);
+        return $this->getData(OrderInterface::DISCOUNT_REFUNDED);
     }
 
     /**
@@ -2672,7 +2672,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getEditIncrement()
     {
-        return $this->getData(ApiOrderInterface::EDIT_INCREMENT);
+        return $this->getData(OrderInterface::EDIT_INCREMENT);
     }
 
     /**
@@ -2682,7 +2682,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getEmailSent()
     {
-        return $this->getData(ApiOrderInterface::EMAIL_SENT);
+        return $this->getData(OrderInterface::EMAIL_SENT);
     }
 
     /**
@@ -2692,7 +2692,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getExtCustomerId()
     {
-        return $this->getData(ApiOrderInterface::EXT_CUSTOMER_ID);
+        return $this->getData(OrderInterface::EXT_CUSTOMER_ID);
     }
 
     /**
@@ -2702,7 +2702,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getExtOrderId()
     {
-        return $this->getData(ApiOrderInterface::EXT_ORDER_ID);
+        return $this->getData(OrderInterface::EXT_ORDER_ID);
     }
 
     /**
@@ -2712,7 +2712,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getForcedShipmentWithInvoice()
     {
-        return $this->getData(ApiOrderInterface::FORCED_SHIPMENT_WITH_INVOICE);
+        return $this->getData(OrderInterface::FORCED_SHIPMENT_WITH_INVOICE);
     }
 
     /**
@@ -2722,7 +2722,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getGlobalCurrencyCode()
     {
-        return $this->getData(ApiOrderInterface::GLOBAL_CURRENCY_CODE);
+        return $this->getData(OrderInterface::GLOBAL_CURRENCY_CODE);
     }
 
     /**
@@ -2732,7 +2732,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getGrandTotal()
     {
-        return $this->getData(ApiOrderInterface::GRAND_TOTAL);
+        return $this->getData(OrderInterface::GRAND_TOTAL);
     }
 
     /**
@@ -2742,7 +2742,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getHiddenTaxAmount()
     {
-        return $this->getData(ApiOrderInterface::HIDDEN_TAX_AMOUNT);
+        return $this->getData(OrderInterface::HIDDEN_TAX_AMOUNT);
     }
 
     /**
@@ -2752,7 +2752,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getHiddenTaxInvoiced()
     {
-        return $this->getData(ApiOrderInterface::HIDDEN_TAX_INVOICED);
+        return $this->getData(OrderInterface::HIDDEN_TAX_INVOICED);
     }
 
     /**
@@ -2762,7 +2762,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getHiddenTaxRefunded()
     {
-        return $this->getData(ApiOrderInterface::HIDDEN_TAX_REFUNDED);
+        return $this->getData(OrderInterface::HIDDEN_TAX_REFUNDED);
     }
 
     /**
@@ -2772,7 +2772,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getHoldBeforeState()
     {
-        return $this->getData(ApiOrderInterface::HOLD_BEFORE_STATE);
+        return $this->getData(OrderInterface::HOLD_BEFORE_STATE);
     }
 
     /**
@@ -2782,7 +2782,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getHoldBeforeStatus()
     {
-        return $this->getData(ApiOrderInterface::HOLD_BEFORE_STATUS);
+        return $this->getData(OrderInterface::HOLD_BEFORE_STATUS);
     }
 
     /**
@@ -2792,7 +2792,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getIsVirtual()
     {
-        return $this->getData(ApiOrderInterface::IS_VIRTUAL);
+        return $this->getData(OrderInterface::IS_VIRTUAL);
     }
 
     /**
@@ -2802,7 +2802,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getOrderCurrencyCode()
     {
-        return $this->getData(ApiOrderInterface::ORDER_CURRENCY_CODE);
+        return $this->getData(OrderInterface::ORDER_CURRENCY_CODE);
     }
 
     /**
@@ -2812,7 +2812,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getOriginalIncrementId()
     {
-        return $this->getData(ApiOrderInterface::ORIGINAL_INCREMENT_ID);
+        return $this->getData(OrderInterface::ORIGINAL_INCREMENT_ID);
     }
 
     /**
@@ -2822,7 +2822,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getPaymentAuthorizationAmount()
     {
-        return $this->getData(ApiOrderInterface::PAYMENT_AUTHORIZATION_AMOUNT);
+        return $this->getData(OrderInterface::PAYMENT_AUTHORIZATION_AMOUNT);
     }
 
     /**
@@ -2832,7 +2832,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getPaymentAuthExpiration()
     {
-        return $this->getData(ApiOrderInterface::PAYMENT_AUTH_EXPIRATION);
+        return $this->getData(OrderInterface::PAYMENT_AUTH_EXPIRATION);
     }
 
     /**
@@ -2842,7 +2842,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getProtectCode()
     {
-        return $this->getData(ApiOrderInterface::PROTECT_CODE);
+        return $this->getData(OrderInterface::PROTECT_CODE);
     }
 
     /**
@@ -2852,7 +2852,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getQuoteAddressId()
     {
-        return $this->getData(ApiOrderInterface::QUOTE_ADDRESS_ID);
+        return $this->getData(OrderInterface::QUOTE_ADDRESS_ID);
     }
 
     /**
@@ -2862,7 +2862,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getQuoteId()
     {
-        return $this->getData(ApiOrderInterface::QUOTE_ID);
+        return $this->getData(OrderInterface::QUOTE_ID);
     }
 
     /**
@@ -2872,7 +2872,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getRelationChildId()
     {
-        return $this->getData(ApiOrderInterface::RELATION_CHILD_ID);
+        return $this->getData(OrderInterface::RELATION_CHILD_ID);
     }
 
     /**
@@ -2882,7 +2882,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getRelationChildRealId()
     {
-        return $this->getData(ApiOrderInterface::RELATION_CHILD_REAL_ID);
+        return $this->getData(OrderInterface::RELATION_CHILD_REAL_ID);
     }
 
     /**
@@ -2892,7 +2892,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getRelationParentId()
     {
-        return $this->getData(ApiOrderInterface::RELATION_PARENT_ID);
+        return $this->getData(OrderInterface::RELATION_PARENT_ID);
     }
 
     /**
@@ -2902,7 +2902,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getRelationParentRealId()
     {
-        return $this->getData(ApiOrderInterface::RELATION_PARENT_REAL_ID);
+        return $this->getData(OrderInterface::RELATION_PARENT_REAL_ID);
     }
 
     /**
@@ -2912,7 +2912,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getRemoteIp()
     {
-        return $this->getData(ApiOrderInterface::REMOTE_IP);
+        return $this->getData(OrderInterface::REMOTE_IP);
     }
 
     /**
@@ -2922,7 +2922,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getShippingAddressId()
     {
-        return $this->getData(ApiOrderInterface::SHIPPING_ADDRESS_ID);
+        return $this->getData(OrderInterface::SHIPPING_ADDRESS_ID);
     }
 
     /**
@@ -2932,7 +2932,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getShippingAmount()
     {
-        return $this->getData(ApiOrderInterface::SHIPPING_AMOUNT);
+        return $this->getData(OrderInterface::SHIPPING_AMOUNT);
     }
 
     /**
@@ -2942,7 +2942,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getShippingCanceled()
     {
-        return $this->getData(ApiOrderInterface::SHIPPING_CANCELED);
+        return $this->getData(OrderInterface::SHIPPING_CANCELED);
     }
 
     /**
@@ -2952,7 +2952,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getShippingDescription()
     {
-        return $this->getData(ApiOrderInterface::SHIPPING_DESCRIPTION);
+        return $this->getData(OrderInterface::SHIPPING_DESCRIPTION);
     }
 
     /**
@@ -2962,7 +2962,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getShippingDiscountAmount()
     {
-        return $this->getData(ApiOrderInterface::SHIPPING_DISCOUNT_AMOUNT);
+        return $this->getData(OrderInterface::SHIPPING_DISCOUNT_AMOUNT);
     }
 
     /**
@@ -2972,7 +2972,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getShippingHiddenTaxAmount()
     {
-        return $this->getData(ApiOrderInterface::SHIPPING_HIDDEN_TAX_AMOUNT);
+        return $this->getData(OrderInterface::SHIPPING_HIDDEN_TAX_AMOUNT);
     }
 
     /**
@@ -2982,7 +2982,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getShippingInclTax()
     {
-        return $this->getData(ApiOrderInterface::SHIPPING_INCL_TAX);
+        return $this->getData(OrderInterface::SHIPPING_INCL_TAX);
     }
 
     /**
@@ -2992,7 +2992,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getShippingInvoiced()
     {
-        return $this->getData(ApiOrderInterface::SHIPPING_INVOICED);
+        return $this->getData(OrderInterface::SHIPPING_INVOICED);
     }
 
     /**
@@ -3002,7 +3002,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getShippingRefunded()
     {
-        return $this->getData(ApiOrderInterface::SHIPPING_REFUNDED);
+        return $this->getData(OrderInterface::SHIPPING_REFUNDED);
     }
 
     /**
@@ -3012,7 +3012,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getShippingTaxAmount()
     {
-        return $this->getData(ApiOrderInterface::SHIPPING_TAX_AMOUNT);
+        return $this->getData(OrderInterface::SHIPPING_TAX_AMOUNT);
     }
 
     /**
@@ -3022,7 +3022,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getShippingTaxRefunded()
     {
-        return $this->getData(ApiOrderInterface::SHIPPING_TAX_REFUNDED);
+        return $this->getData(OrderInterface::SHIPPING_TAX_REFUNDED);
     }
 
     /**
@@ -3032,7 +3032,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getState()
     {
-        return $this->getData(ApiOrderInterface::STATE);
+        return $this->getData(OrderInterface::STATE);
     }
 
     /**
@@ -3042,7 +3042,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getStatus()
     {
-        return $this->getData(ApiOrderInterface::STATUS);
+        return $this->getData(OrderInterface::STATUS);
     }
 
     /**
@@ -3052,7 +3052,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getStoreCurrencyCode()
     {
-        return $this->getData(ApiOrderInterface::STORE_CURRENCY_CODE);
+        return $this->getData(OrderInterface::STORE_CURRENCY_CODE);
     }
 
     /**
@@ -3062,7 +3062,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getStoreId()
     {
-        return $this->getData(ApiOrderInterface::STORE_ID);
+        return $this->getData(OrderInterface::STORE_ID);
     }
 
     /**
@@ -3072,7 +3072,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getStoreName()
     {
-        return $this->getData(ApiOrderInterface::STORE_NAME);
+        return $this->getData(OrderInterface::STORE_NAME);
     }
 
     /**
@@ -3082,7 +3082,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getStoreToBaseRate()
     {
-        return $this->getData(ApiOrderInterface::STORE_TO_BASE_RATE);
+        return $this->getData(OrderInterface::STORE_TO_BASE_RATE);
     }
 
     /**
@@ -3092,7 +3092,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getStoreToOrderRate()
     {
-        return $this->getData(ApiOrderInterface::STORE_TO_ORDER_RATE);
+        return $this->getData(OrderInterface::STORE_TO_ORDER_RATE);
     }
 
     /**
@@ -3102,7 +3102,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getSubtotal()
     {
-        return $this->getData(ApiOrderInterface::SUBTOTAL);
+        return $this->getData(OrderInterface::SUBTOTAL);
     }
 
     /**
@@ -3112,7 +3112,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getSubtotalCanceled()
     {
-        return $this->getData(ApiOrderInterface::SUBTOTAL_CANCELED);
+        return $this->getData(OrderInterface::SUBTOTAL_CANCELED);
     }
 
     /**
@@ -3122,7 +3122,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getSubtotalInclTax()
     {
-        return $this->getData(ApiOrderInterface::SUBTOTAL_INCL_TAX);
+        return $this->getData(OrderInterface::SUBTOTAL_INCL_TAX);
     }
 
     /**
@@ -3132,7 +3132,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getSubtotalInvoiced()
     {
-        return $this->getData(ApiOrderInterface::SUBTOTAL_INVOICED);
+        return $this->getData(OrderInterface::SUBTOTAL_INVOICED);
     }
 
     /**
@@ -3142,7 +3142,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getSubtotalRefunded()
     {
-        return $this->getData(ApiOrderInterface::SUBTOTAL_REFUNDED);
+        return $this->getData(OrderInterface::SUBTOTAL_REFUNDED);
     }
 
     /**
@@ -3152,7 +3152,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getTaxAmount()
     {
-        return $this->getData(ApiOrderInterface::TAX_AMOUNT);
+        return $this->getData(OrderInterface::TAX_AMOUNT);
     }
 
     /**
@@ -3162,7 +3162,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getTaxCanceled()
     {
-        return $this->getData(ApiOrderInterface::TAX_CANCELED);
+        return $this->getData(OrderInterface::TAX_CANCELED);
     }
 
     /**
@@ -3172,7 +3172,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getTaxInvoiced()
     {
-        return $this->getData(ApiOrderInterface::TAX_INVOICED);
+        return $this->getData(OrderInterface::TAX_INVOICED);
     }
 
     /**
@@ -3182,7 +3182,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getTaxRefunded()
     {
-        return $this->getData(ApiOrderInterface::TAX_REFUNDED);
+        return $this->getData(OrderInterface::TAX_REFUNDED);
     }
 
     /**
@@ -3192,7 +3192,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getTotalCanceled()
     {
-        return $this->getData(ApiOrderInterface::TOTAL_CANCELED);
+        return $this->getData(OrderInterface::TOTAL_CANCELED);
     }
 
     /**
@@ -3202,7 +3202,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getTotalInvoiced()
     {
-        return $this->getData(ApiOrderInterface::TOTAL_INVOICED);
+        return $this->getData(OrderInterface::TOTAL_INVOICED);
     }
 
     /**
@@ -3212,7 +3212,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getTotalItemCount()
     {
-        return $this->getData(ApiOrderInterface::TOTAL_ITEM_COUNT);
+        return $this->getData(OrderInterface::TOTAL_ITEM_COUNT);
     }
 
     /**
@@ -3222,7 +3222,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getTotalOfflineRefunded()
     {
-        return $this->getData(ApiOrderInterface::TOTAL_OFFLINE_REFUNDED);
+        return $this->getData(OrderInterface::TOTAL_OFFLINE_REFUNDED);
     }
 
     /**
@@ -3232,7 +3232,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getTotalOnlineRefunded()
     {
-        return $this->getData(ApiOrderInterface::TOTAL_ONLINE_REFUNDED);
+        return $this->getData(OrderInterface::TOTAL_ONLINE_REFUNDED);
     }
 
     /**
@@ -3242,7 +3242,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getTotalPaid()
     {
-        return $this->getData(ApiOrderInterface::TOTAL_PAID);
+        return $this->getData(OrderInterface::TOTAL_PAID);
     }
 
     /**
@@ -3252,7 +3252,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getTotalQtyOrdered()
     {
-        return $this->getData(ApiOrderInterface::TOTAL_QTY_ORDERED);
+        return $this->getData(OrderInterface::TOTAL_QTY_ORDERED);
     }
 
     /**
@@ -3262,7 +3262,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getTotalRefunded()
     {
-        return $this->getData(ApiOrderInterface::TOTAL_REFUNDED);
+        return $this->getData(OrderInterface::TOTAL_REFUNDED);
     }
 
     /**
@@ -3272,7 +3272,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getUpdatedAt()
     {
-        return $this->getData(ApiOrderInterface::UPDATED_AT);
+        return $this->getData(OrderInterface::UPDATED_AT);
     }
 
     /**
@@ -3282,7 +3282,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getWeight()
     {
-        return $this->getData(ApiOrderInterface::WEIGHT);
+        return $this->getData(OrderInterface::WEIGHT);
     }
 
     /**
@@ -3292,7 +3292,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getXForwardedFor()
     {
-        return $this->getData(ApiOrderInterface::X_FORWARDED_FOR);
+        return $this->getData(OrderInterface::X_FORWARDED_FOR);
     }
 
     /**
@@ -3300,13 +3300,34 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function getStatusHistories()
     {
-        if ($this->getData(ApiOrderInterface::STATUS_HISTORIES) == null) {
+        if ($this->getData(OrderInterface::STATUS_HISTORIES) == null) {
             $this->setData(
-                ApiOrderInterface::STATUS_HISTORIES,
+                OrderInterface::STATUS_HISTORIES,
                 $this->getStatusHistoryCollection()->getItems()
             );
         }
-        return $this->getData(ApiOrderInterface::STATUS_HISTORIES);
+        return $this->getData(OrderInterface::STATUS_HISTORIES);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Sales\Api\Data\OrderExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Sales\Api\Data\OrderExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\OrderExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
     }
 
     /**
@@ -3314,7 +3335,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setStatusHistories(array $statusHistories = null)
     {
-        return $this->setData(ApiOrderInterface::STATUS_HISTORIES, $statusHistories);
+        return $this->setData(OrderInterface::STATUS_HISTORIES, $statusHistories);
     }
 
     //@codeCoverageIgnoreStart
@@ -3323,7 +3344,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setStatus($status)
     {
-        return $this->setData(ApiOrderInterface::STATUS, $status);
+        return $this->setData(OrderInterface::STATUS, $status);
     }
 
     /**
@@ -3331,7 +3352,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setCouponCode($code)
     {
-        return $this->setData(ApiOrderInterface::COUPON_CODE, $code);
+        return $this->setData(OrderInterface::COUPON_CODE, $code);
     }
 
     /**
@@ -3339,7 +3360,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setProtectCode($code)
     {
-        return $this->setData(ApiOrderInterface::PROTECT_CODE, $code);
+        return $this->setData(OrderInterface::PROTECT_CODE, $code);
     }
 
     /**
@@ -3347,7 +3368,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setShippingDescription($description)
     {
-        return $this->setData(ApiOrderInterface::SHIPPING_DESCRIPTION, $description);
+        return $this->setData(OrderInterface::SHIPPING_DESCRIPTION, $description);
     }
 
     /**
@@ -3355,7 +3376,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setIsVirtual($isVirtual)
     {
-        return $this->setData(ApiOrderInterface::IS_VIRTUAL, $isVirtual);
+        return $this->setData(OrderInterface::IS_VIRTUAL, $isVirtual);
     }
 
     /**
@@ -3363,7 +3384,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setStoreId($id)
     {
-        return $this->setData(ApiOrderInterface::STORE_ID, $id);
+        return $this->setData(OrderInterface::STORE_ID, $id);
     }
 
     /**
@@ -3371,7 +3392,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setCustomerId($id)
     {
-        return $this->setData(ApiOrderInterface::CUSTOMER_ID, $id);
+        return $this->setData(OrderInterface::CUSTOMER_ID, $id);
     }
 
     /**
@@ -3379,7 +3400,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseDiscountAmount($amount)
     {
-        return $this->setData(ApiOrderInterface::BASE_DISCOUNT_AMOUNT, $amount);
+        return $this->setData(OrderInterface::BASE_DISCOUNT_AMOUNT, $amount);
     }
 
     /**
@@ -3387,7 +3408,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseDiscountCanceled($baseDiscountCanceled)
     {
-        return $this->setData(ApiOrderInterface::BASE_DISCOUNT_CANCELED, $baseDiscountCanceled);
+        return $this->setData(OrderInterface::BASE_DISCOUNT_CANCELED, $baseDiscountCanceled);
     }
 
     /**
@@ -3395,7 +3416,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseDiscountInvoiced($baseDiscountInvoiced)
     {
-        return $this->setData(ApiOrderInterface::BASE_DISCOUNT_INVOICED, $baseDiscountInvoiced);
+        return $this->setData(OrderInterface::BASE_DISCOUNT_INVOICED, $baseDiscountInvoiced);
     }
 
     /**
@@ -3403,7 +3424,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseDiscountRefunded($baseDiscountRefunded)
     {
-        return $this->setData(ApiOrderInterface::BASE_DISCOUNT_REFUNDED, $baseDiscountRefunded);
+        return $this->setData(OrderInterface::BASE_DISCOUNT_REFUNDED, $baseDiscountRefunded);
     }
 
     /**
@@ -3411,7 +3432,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseGrandTotal($amount)
     {
-        return $this->setData(ApiOrderInterface::BASE_GRAND_TOTAL, $amount);
+        return $this->setData(OrderInterface::BASE_GRAND_TOTAL, $amount);
     }
 
     /**
@@ -3419,7 +3440,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseShippingAmount($amount)
     {
-        return $this->setData(ApiOrderInterface::BASE_SHIPPING_AMOUNT, $amount);
+        return $this->setData(OrderInterface::BASE_SHIPPING_AMOUNT, $amount);
     }
 
     /**
@@ -3427,7 +3448,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseShippingCanceled($baseShippingCanceled)
     {
-        return $this->setData(ApiOrderInterface::BASE_SHIPPING_CANCELED, $baseShippingCanceled);
+        return $this->setData(OrderInterface::BASE_SHIPPING_CANCELED, $baseShippingCanceled);
     }
 
     /**
@@ -3435,7 +3456,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseShippingInvoiced($baseShippingInvoiced)
     {
-        return $this->setData(ApiOrderInterface::BASE_SHIPPING_INVOICED, $baseShippingInvoiced);
+        return $this->setData(OrderInterface::BASE_SHIPPING_INVOICED, $baseShippingInvoiced);
     }
 
     /**
@@ -3443,7 +3464,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseShippingRefunded($baseShippingRefunded)
     {
-        return $this->setData(ApiOrderInterface::BASE_SHIPPING_REFUNDED, $baseShippingRefunded);
+        return $this->setData(OrderInterface::BASE_SHIPPING_REFUNDED, $baseShippingRefunded);
     }
 
     /**
@@ -3451,7 +3472,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseShippingTaxAmount($amount)
     {
-        return $this->setData(ApiOrderInterface::BASE_SHIPPING_TAX_AMOUNT, $amount);
+        return $this->setData(OrderInterface::BASE_SHIPPING_TAX_AMOUNT, $amount);
     }
 
     /**
@@ -3459,7 +3480,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseShippingTaxRefunded($baseShippingTaxRefunded)
     {
-        return $this->setData(ApiOrderInterface::BASE_SHIPPING_TAX_REFUNDED, $baseShippingTaxRefunded);
+        return $this->setData(OrderInterface::BASE_SHIPPING_TAX_REFUNDED, $baseShippingTaxRefunded);
     }
 
     /**
@@ -3467,7 +3488,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseSubtotal($amount)
     {
-        return $this->setData(ApiOrderInterface::BASE_SUBTOTAL, $amount);
+        return $this->setData(OrderInterface::BASE_SUBTOTAL, $amount);
     }
 
     /**
@@ -3475,7 +3496,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseSubtotalCanceled($baseSubtotalCanceled)
     {
-        return $this->setData(ApiOrderInterface::BASE_SUBTOTAL_CANCELED, $baseSubtotalCanceled);
+        return $this->setData(OrderInterface::BASE_SUBTOTAL_CANCELED, $baseSubtotalCanceled);
     }
 
     /**
@@ -3483,7 +3504,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseSubtotalInvoiced($baseSubtotalInvoiced)
     {
-        return $this->setData(ApiOrderInterface::BASE_SUBTOTAL_INVOICED, $baseSubtotalInvoiced);
+        return $this->setData(OrderInterface::BASE_SUBTOTAL_INVOICED, $baseSubtotalInvoiced);
     }
 
     /**
@@ -3491,7 +3512,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseSubtotalRefunded($baseSubtotalRefunded)
     {
-        return $this->setData(ApiOrderInterface::BASE_SUBTOTAL_REFUNDED, $baseSubtotalRefunded);
+        return $this->setData(OrderInterface::BASE_SUBTOTAL_REFUNDED, $baseSubtotalRefunded);
     }
 
     /**
@@ -3499,7 +3520,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseTaxAmount($amount)
     {
-        return $this->setData(ApiOrderInterface::BASE_TAX_AMOUNT, $amount);
+        return $this->setData(OrderInterface::BASE_TAX_AMOUNT, $amount);
     }
 
     /**
@@ -3507,7 +3528,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseTaxCanceled($baseTaxCanceled)
     {
-        return $this->setData(ApiOrderInterface::BASE_TAX_CANCELED, $baseTaxCanceled);
+        return $this->setData(OrderInterface::BASE_TAX_CANCELED, $baseTaxCanceled);
     }
 
     /**
@@ -3515,7 +3536,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseTaxInvoiced($baseTaxInvoiced)
     {
-        return $this->setData(ApiOrderInterface::BASE_TAX_INVOICED, $baseTaxInvoiced);
+        return $this->setData(OrderInterface::BASE_TAX_INVOICED, $baseTaxInvoiced);
     }
 
     /**
@@ -3523,7 +3544,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseTaxRefunded($baseTaxRefunded)
     {
-        return $this->setData(ApiOrderInterface::BASE_TAX_REFUNDED, $baseTaxRefunded);
+        return $this->setData(OrderInterface::BASE_TAX_REFUNDED, $baseTaxRefunded);
     }
 
     /**
@@ -3531,7 +3552,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseToGlobalRate($rate)
     {
-        return $this->setData(ApiOrderInterface::BASE_TO_GLOBAL_RATE, $rate);
+        return $this->setData(OrderInterface::BASE_TO_GLOBAL_RATE, $rate);
     }
 
     /**
@@ -3539,7 +3560,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseToOrderRate($rate)
     {
-        return $this->setData(ApiOrderInterface::BASE_TO_ORDER_RATE, $rate);
+        return $this->setData(OrderInterface::BASE_TO_ORDER_RATE, $rate);
     }
 
     /**
@@ -3547,7 +3568,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseTotalCanceled($baseTotalCanceled)
     {
-        return $this->setData(ApiOrderInterface::BASE_TOTAL_CANCELED, $baseTotalCanceled);
+        return $this->setData(OrderInterface::BASE_TOTAL_CANCELED, $baseTotalCanceled);
     }
 
     /**
@@ -3555,7 +3576,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseTotalInvoiced($baseTotalInvoiced)
     {
-        return $this->setData(ApiOrderInterface::BASE_TOTAL_INVOICED, $baseTotalInvoiced);
+        return $this->setData(OrderInterface::BASE_TOTAL_INVOICED, $baseTotalInvoiced);
     }
 
     /**
@@ -3563,7 +3584,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseTotalInvoicedCost($baseTotalInvoicedCost)
     {
-        return $this->setData(ApiOrderInterface::BASE_TOTAL_INVOICED_COST, $baseTotalInvoicedCost);
+        return $this->setData(OrderInterface::BASE_TOTAL_INVOICED_COST, $baseTotalInvoicedCost);
     }
 
     /**
@@ -3571,7 +3592,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseTotalOfflineRefunded($baseTotalOfflineRefunded)
     {
-        return $this->setData(ApiOrderInterface::BASE_TOTAL_OFFLINE_REFUNDED, $baseTotalOfflineRefunded);
+        return $this->setData(OrderInterface::BASE_TOTAL_OFFLINE_REFUNDED, $baseTotalOfflineRefunded);
     }
 
     /**
@@ -3579,7 +3600,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseTotalOnlineRefunded($baseTotalOnlineRefunded)
     {
-        return $this->setData(ApiOrderInterface::BASE_TOTAL_ONLINE_REFUNDED, $baseTotalOnlineRefunded);
+        return $this->setData(OrderInterface::BASE_TOTAL_ONLINE_REFUNDED, $baseTotalOnlineRefunded);
     }
 
     /**
@@ -3587,7 +3608,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseTotalPaid($baseTotalPaid)
     {
-        return $this->setData(ApiOrderInterface::BASE_TOTAL_PAID, $baseTotalPaid);
+        return $this->setData(OrderInterface::BASE_TOTAL_PAID, $baseTotalPaid);
     }
 
     /**
@@ -3595,7 +3616,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseTotalQtyOrdered($baseTotalQtyOrdered)
     {
-        return $this->setData(ApiOrderInterface::BASE_TOTAL_QTY_ORDERED, $baseTotalQtyOrdered);
+        return $this->setData(OrderInterface::BASE_TOTAL_QTY_ORDERED, $baseTotalQtyOrdered);
     }
 
     /**
@@ -3603,7 +3624,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseTotalRefunded($baseTotalRefunded)
     {
-        return $this->setData(ApiOrderInterface::BASE_TOTAL_REFUNDED, $baseTotalRefunded);
+        return $this->setData(OrderInterface::BASE_TOTAL_REFUNDED, $baseTotalRefunded);
     }
 
     /**
@@ -3611,7 +3632,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setDiscountAmount($amount)
     {
-        return $this->setData(ApiOrderInterface::DISCOUNT_AMOUNT, $amount);
+        return $this->setData(OrderInterface::DISCOUNT_AMOUNT, $amount);
     }
 
     /**
@@ -3619,7 +3640,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setDiscountCanceled($discountCanceled)
     {
-        return $this->setData(ApiOrderInterface::DISCOUNT_CANCELED, $discountCanceled);
+        return $this->setData(OrderInterface::DISCOUNT_CANCELED, $discountCanceled);
     }
 
     /**
@@ -3627,7 +3648,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setDiscountInvoiced($discountInvoiced)
     {
-        return $this->setData(ApiOrderInterface::DISCOUNT_INVOICED, $discountInvoiced);
+        return $this->setData(OrderInterface::DISCOUNT_INVOICED, $discountInvoiced);
     }
 
     /**
@@ -3635,7 +3656,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setDiscountRefunded($discountRefunded)
     {
-        return $this->setData(ApiOrderInterface::DISCOUNT_REFUNDED, $discountRefunded);
+        return $this->setData(OrderInterface::DISCOUNT_REFUNDED, $discountRefunded);
     }
 
     /**
@@ -3643,7 +3664,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setGrandTotal($amount)
     {
-        return $this->setData(ApiOrderInterface::GRAND_TOTAL, $amount);
+        return $this->setData(OrderInterface::GRAND_TOTAL, $amount);
     }
 
     /**
@@ -3651,7 +3672,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setShippingAmount($amount)
     {
-        return $this->setData(ApiOrderInterface::SHIPPING_AMOUNT, $amount);
+        return $this->setData(OrderInterface::SHIPPING_AMOUNT, $amount);
     }
 
     /**
@@ -3659,7 +3680,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setShippingCanceled($shippingCanceled)
     {
-        return $this->setData(ApiOrderInterface::SHIPPING_CANCELED, $shippingCanceled);
+        return $this->setData(OrderInterface::SHIPPING_CANCELED, $shippingCanceled);
     }
 
     /**
@@ -3667,7 +3688,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setShippingInvoiced($shippingInvoiced)
     {
-        return $this->setData(ApiOrderInterface::SHIPPING_INVOICED, $shippingInvoiced);
+        return $this->setData(OrderInterface::SHIPPING_INVOICED, $shippingInvoiced);
     }
 
     /**
@@ -3675,7 +3696,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setShippingRefunded($shippingRefunded)
     {
-        return $this->setData(ApiOrderInterface::SHIPPING_REFUNDED, $shippingRefunded);
+        return $this->setData(OrderInterface::SHIPPING_REFUNDED, $shippingRefunded);
     }
 
     /**
@@ -3683,7 +3704,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setShippingTaxAmount($amount)
     {
-        return $this->setData(ApiOrderInterface::SHIPPING_TAX_AMOUNT, $amount);
+        return $this->setData(OrderInterface::SHIPPING_TAX_AMOUNT, $amount);
     }
 
     /**
@@ -3691,7 +3712,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setShippingTaxRefunded($shippingTaxRefunded)
     {
-        return $this->setData(ApiOrderInterface::SHIPPING_TAX_REFUNDED, $shippingTaxRefunded);
+        return $this->setData(OrderInterface::SHIPPING_TAX_REFUNDED, $shippingTaxRefunded);
     }
 
     /**
@@ -3699,7 +3720,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setStoreToBaseRate($rate)
     {
-        return $this->setData(ApiOrderInterface::STORE_TO_BASE_RATE, $rate);
+        return $this->setData(OrderInterface::STORE_TO_BASE_RATE, $rate);
     }
 
     /**
@@ -3707,7 +3728,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setStoreToOrderRate($rate)
     {
-        return $this->setData(ApiOrderInterface::STORE_TO_ORDER_RATE, $rate);
+        return $this->setData(OrderInterface::STORE_TO_ORDER_RATE, $rate);
     }
 
     /**
@@ -3715,7 +3736,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setSubtotal($amount)
     {
-        return $this->setData(ApiOrderInterface::SUBTOTAL, $amount);
+        return $this->setData(OrderInterface::SUBTOTAL, $amount);
     }
 
     /**
@@ -3723,7 +3744,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setSubtotalCanceled($subtotalCanceled)
     {
-        return $this->setData(ApiOrderInterface::SUBTOTAL_CANCELED, $subtotalCanceled);
+        return $this->setData(OrderInterface::SUBTOTAL_CANCELED, $subtotalCanceled);
     }
 
     /**
@@ -3731,7 +3752,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setSubtotalInvoiced($subtotalInvoiced)
     {
-        return $this->setData(ApiOrderInterface::SUBTOTAL_INVOICED, $subtotalInvoiced);
+        return $this->setData(OrderInterface::SUBTOTAL_INVOICED, $subtotalInvoiced);
     }
 
     /**
@@ -3739,7 +3760,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setSubtotalRefunded($subtotalRefunded)
     {
-        return $this->setData(ApiOrderInterface::SUBTOTAL_REFUNDED, $subtotalRefunded);
+        return $this->setData(OrderInterface::SUBTOTAL_REFUNDED, $subtotalRefunded);
     }
 
     /**
@@ -3747,7 +3768,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setTaxAmount($amount)
     {
-        return $this->setData(ApiOrderInterface::TAX_AMOUNT, $amount);
+        return $this->setData(OrderInterface::TAX_AMOUNT, $amount);
     }
 
     /**
@@ -3755,7 +3776,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setTaxCanceled($taxCanceled)
     {
-        return $this->setData(ApiOrderInterface::TAX_CANCELED, $taxCanceled);
+        return $this->setData(OrderInterface::TAX_CANCELED, $taxCanceled);
     }
 
     /**
@@ -3763,7 +3784,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setTaxInvoiced($taxInvoiced)
     {
-        return $this->setData(ApiOrderInterface::TAX_INVOICED, $taxInvoiced);
+        return $this->setData(OrderInterface::TAX_INVOICED, $taxInvoiced);
     }
 
     /**
@@ -3771,7 +3792,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setTaxRefunded($taxRefunded)
     {
-        return $this->setData(ApiOrderInterface::TAX_REFUNDED, $taxRefunded);
+        return $this->setData(OrderInterface::TAX_REFUNDED, $taxRefunded);
     }
 
     /**
@@ -3779,7 +3800,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setTotalCanceled($totalCanceled)
     {
-        return $this->setData(ApiOrderInterface::TOTAL_CANCELED, $totalCanceled);
+        return $this->setData(OrderInterface::TOTAL_CANCELED, $totalCanceled);
     }
 
     /**
@@ -3787,7 +3808,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setTotalInvoiced($totalInvoiced)
     {
-        return $this->setData(ApiOrderInterface::TOTAL_INVOICED, $totalInvoiced);
+        return $this->setData(OrderInterface::TOTAL_INVOICED, $totalInvoiced);
     }
 
     /**
@@ -3795,7 +3816,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setTotalOfflineRefunded($totalOfflineRefunded)
     {
-        return $this->setData(ApiOrderInterface::TOTAL_OFFLINE_REFUNDED, $totalOfflineRefunded);
+        return $this->setData(OrderInterface::TOTAL_OFFLINE_REFUNDED, $totalOfflineRefunded);
     }
 
     /**
@@ -3803,7 +3824,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setTotalOnlineRefunded($totalOnlineRefunded)
     {
-        return $this->setData(ApiOrderInterface::TOTAL_ONLINE_REFUNDED, $totalOnlineRefunded);
+        return $this->setData(OrderInterface::TOTAL_ONLINE_REFUNDED, $totalOnlineRefunded);
     }
 
     /**
@@ -3811,7 +3832,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setTotalPaid($totalPaid)
     {
-        return $this->setData(ApiOrderInterface::TOTAL_PAID, $totalPaid);
+        return $this->setData(OrderInterface::TOTAL_PAID, $totalPaid);
     }
 
     /**
@@ -3819,7 +3840,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setTotalQtyOrdered($totalQtyOrdered)
     {
-        return $this->setData(ApiOrderInterface::TOTAL_QTY_ORDERED, $totalQtyOrdered);
+        return $this->setData(OrderInterface::TOTAL_QTY_ORDERED, $totalQtyOrdered);
     }
 
     /**
@@ -3827,7 +3848,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setTotalRefunded($totalRefunded)
     {
-        return $this->setData(ApiOrderInterface::TOTAL_REFUNDED, $totalRefunded);
+        return $this->setData(OrderInterface::TOTAL_REFUNDED, $totalRefunded);
     }
 
     /**
@@ -3835,7 +3856,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setCanShipPartially($flag)
     {
-        return $this->setData(ApiOrderInterface::CAN_SHIP_PARTIALLY, $flag);
+        return $this->setData(OrderInterface::CAN_SHIP_PARTIALLY, $flag);
     }
 
     /**
@@ -3843,7 +3864,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setCanShipPartiallyItem($flag)
     {
-        return $this->setData(ApiOrderInterface::CAN_SHIP_PARTIALLY_ITEM, $flag);
+        return $this->setData(OrderInterface::CAN_SHIP_PARTIALLY_ITEM, $flag);
     }
 
     /**
@@ -3851,7 +3872,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setCustomerIsGuest($customerIsGuest)
     {
-        return $this->setData(ApiOrderInterface::CUSTOMER_IS_GUEST, $customerIsGuest);
+        return $this->setData(OrderInterface::CUSTOMER_IS_GUEST, $customerIsGuest);
     }
 
     /**
@@ -3859,7 +3880,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setCustomerNoteNotify($customerNoteNotify)
     {
-        return $this->setData(ApiOrderInterface::CUSTOMER_NOTE_NOTIFY, $customerNoteNotify);
+        return $this->setData(OrderInterface::CUSTOMER_NOTE_NOTIFY, $customerNoteNotify);
     }
 
     /**
@@ -3867,7 +3888,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBillingAddressId($id)
     {
-        return $this->setData(ApiOrderInterface::BILLING_ADDRESS_ID, $id);
+        return $this->setData(OrderInterface::BILLING_ADDRESS_ID, $id);
     }
 
     /**
@@ -3875,7 +3896,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setCustomerGroupId($id)
     {
-        return $this->setData(ApiOrderInterface::CUSTOMER_GROUP_ID, $id);
+        return $this->setData(OrderInterface::CUSTOMER_GROUP_ID, $id);
     }
 
     /**
@@ -3883,7 +3904,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setEditIncrement($editIncrement)
     {
-        return $this->setData(ApiOrderInterface::EDIT_INCREMENT, $editIncrement);
+        return $this->setData(OrderInterface::EDIT_INCREMENT, $editIncrement);
     }
 
     /**
@@ -3891,7 +3912,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setEmailSent($emailSent)
     {
-        return $this->setData(ApiOrderInterface::EMAIL_SENT, $emailSent);
+        return $this->setData(OrderInterface::EMAIL_SENT, $emailSent);
     }
 
     /**
@@ -3899,7 +3920,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setForcedShipmentWithInvoice($forcedShipmentWithInvoice)
     {
-        return $this->setData(ApiOrderInterface::FORCED_SHIPMENT_WITH_INVOICE, $forcedShipmentWithInvoice);
+        return $this->setData(OrderInterface::FORCED_SHIPMENT_WITH_INVOICE, $forcedShipmentWithInvoice);
     }
 
     /**
@@ -3907,7 +3928,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setPaymentAuthExpiration($paymentAuthExpiration)
     {
-        return $this->setData(ApiOrderInterface::PAYMENT_AUTH_EXPIRATION, $paymentAuthExpiration);
+        return $this->setData(OrderInterface::PAYMENT_AUTH_EXPIRATION, $paymentAuthExpiration);
     }
 
     /**
@@ -3915,7 +3936,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setQuoteAddressId($id)
     {
-        return $this->setData(ApiOrderInterface::QUOTE_ADDRESS_ID, $id);
+        return $this->setData(OrderInterface::QUOTE_ADDRESS_ID, $id);
     }
 
     /**
@@ -3923,7 +3944,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setQuoteId($id)
     {
-        return $this->setData(ApiOrderInterface::QUOTE_ID, $id);
+        return $this->setData(OrderInterface::QUOTE_ID, $id);
     }
 
     /**
@@ -3931,7 +3952,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setShippingAddressId($id)
     {
-        return $this->setData(ApiOrderInterface::SHIPPING_ADDRESS_ID, $id);
+        return $this->setData(OrderInterface::SHIPPING_ADDRESS_ID, $id);
     }
 
     /**
@@ -3939,7 +3960,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setAdjustmentNegative($adjustmentNegative)
     {
-        return $this->setData(ApiOrderInterface::ADJUSTMENT_NEGATIVE, $adjustmentNegative);
+        return $this->setData(OrderInterface::ADJUSTMENT_NEGATIVE, $adjustmentNegative);
     }
 
     /**
@@ -3947,7 +3968,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setAdjustmentPositive($adjustmentPositive)
     {
-        return $this->setData(ApiOrderInterface::ADJUSTMENT_POSITIVE, $adjustmentPositive);
+        return $this->setData(OrderInterface::ADJUSTMENT_POSITIVE, $adjustmentPositive);
     }
 
     /**
@@ -3955,7 +3976,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseAdjustmentNegative($baseAdjustmentNegative)
     {
-        return $this->setData(ApiOrderInterface::BASE_ADJUSTMENT_NEGATIVE, $baseAdjustmentNegative);
+        return $this->setData(OrderInterface::BASE_ADJUSTMENT_NEGATIVE, $baseAdjustmentNegative);
     }
 
     /**
@@ -3963,7 +3984,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseAdjustmentPositive($baseAdjustmentPositive)
     {
-        return $this->setData(ApiOrderInterface::BASE_ADJUSTMENT_POSITIVE, $baseAdjustmentPositive);
+        return $this->setData(OrderInterface::BASE_ADJUSTMENT_POSITIVE, $baseAdjustmentPositive);
     }
 
     /**
@@ -3971,7 +3992,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseShippingDiscountAmount($amount)
     {
-        return $this->setData(ApiOrderInterface::BASE_SHIPPING_DISCOUNT_AMOUNT, $amount);
+        return $this->setData(OrderInterface::BASE_SHIPPING_DISCOUNT_AMOUNT, $amount);
     }
 
     /**
@@ -3979,7 +4000,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseSubtotalInclTax($amount)
     {
-        return $this->setData(ApiOrderInterface::BASE_SUBTOTAL_INCL_TAX, $amount);
+        return $this->setData(OrderInterface::BASE_SUBTOTAL_INCL_TAX, $amount);
     }
 
     /**
@@ -3987,7 +4008,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseTotalDue($baseTotalDue)
     {
-        return $this->setData(ApiOrderInterface::BASE_TOTAL_DUE, $baseTotalDue);
+        return $this->setData(OrderInterface::BASE_TOTAL_DUE, $baseTotalDue);
     }
 
     /**
@@ -3995,7 +4016,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setPaymentAuthorizationAmount($amount)
     {
-        return $this->setData(ApiOrderInterface::PAYMENT_AUTHORIZATION_AMOUNT, $amount);
+        return $this->setData(OrderInterface::PAYMENT_AUTHORIZATION_AMOUNT, $amount);
     }
 
     /**
@@ -4003,7 +4024,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setShippingDiscountAmount($amount)
     {
-        return $this->setData(ApiOrderInterface::SHIPPING_DISCOUNT_AMOUNT, $amount);
+        return $this->setData(OrderInterface::SHIPPING_DISCOUNT_AMOUNT, $amount);
     }
 
     /**
@@ -4011,7 +4032,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setSubtotalInclTax($amount)
     {
-        return $this->setData(ApiOrderInterface::SUBTOTAL_INCL_TAX, $amount);
+        return $this->setData(OrderInterface::SUBTOTAL_INCL_TAX, $amount);
     }
 
     /**
@@ -4019,7 +4040,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setTotalDue($totalDue)
     {
-        return $this->setData(ApiOrderInterface::TOTAL_DUE, $totalDue);
+        return $this->setData(OrderInterface::TOTAL_DUE, $totalDue);
     }
 
     /**
@@ -4027,7 +4048,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setWeight($weight)
     {
-        return $this->setData(ApiOrderInterface::WEIGHT, $weight);
+        return $this->setData(OrderInterface::WEIGHT, $weight);
     }
 
     /**
@@ -4035,7 +4056,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setCustomerDob($customerDob)
     {
-        return $this->setData(ApiOrderInterface::CUSTOMER_DOB, $customerDob);
+        return $this->setData(OrderInterface::CUSTOMER_DOB, $customerDob);
     }
 
     /**
@@ -4043,7 +4064,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setIncrementId($id)
     {
-        return $this->setData(ApiOrderInterface::INCREMENT_ID, $id);
+        return $this->setData(OrderInterface::INCREMENT_ID, $id);
     }
 
     /**
@@ -4051,7 +4072,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setAppliedRuleIds($appliedRuleIds)
     {
-        return $this->setData(ApiOrderInterface::APPLIED_RULE_IDS, $appliedRuleIds);
+        return $this->setData(OrderInterface::APPLIED_RULE_IDS, $appliedRuleIds);
     }
 
     /**
@@ -4059,7 +4080,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseCurrencyCode($code)
     {
-        return $this->setData(ApiOrderInterface::BASE_CURRENCY_CODE, $code);
+        return $this->setData(OrderInterface::BASE_CURRENCY_CODE, $code);
     }
 
     /**
@@ -4067,7 +4088,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setCustomerEmail($customerEmail)
     {
-        return $this->setData(ApiOrderInterface::CUSTOMER_EMAIL, $customerEmail);
+        return $this->setData(OrderInterface::CUSTOMER_EMAIL, $customerEmail);
     }
 
     /**
@@ -4075,7 +4096,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setCustomerFirstname($customerFirstname)
     {
-        return $this->setData(ApiOrderInterface::CUSTOMER_FIRSTNAME, $customerFirstname);
+        return $this->setData(OrderInterface::CUSTOMER_FIRSTNAME, $customerFirstname);
     }
 
     /**
@@ -4083,7 +4104,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setCustomerLastname($customerLastname)
     {
-        return $this->setData(ApiOrderInterface::CUSTOMER_LASTNAME, $customerLastname);
+        return $this->setData(OrderInterface::CUSTOMER_LASTNAME, $customerLastname);
     }
 
     /**
@@ -4091,7 +4112,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setCustomerMiddlename($customerMiddlename)
     {
-        return $this->setData(ApiOrderInterface::CUSTOMER_MIDDLENAME, $customerMiddlename);
+        return $this->setData(OrderInterface::CUSTOMER_MIDDLENAME, $customerMiddlename);
     }
 
     /**
@@ -4099,7 +4120,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setCustomerPrefix($customerPrefix)
     {
-        return $this->setData(ApiOrderInterface::CUSTOMER_PREFIX, $customerPrefix);
+        return $this->setData(OrderInterface::CUSTOMER_PREFIX, $customerPrefix);
     }
 
     /**
@@ -4107,7 +4128,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setCustomerSuffix($customerSuffix)
     {
-        return $this->setData(ApiOrderInterface::CUSTOMER_SUFFIX, $customerSuffix);
+        return $this->setData(OrderInterface::CUSTOMER_SUFFIX, $customerSuffix);
     }
 
     /**
@@ -4115,7 +4136,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setCustomerTaxvat($customerTaxvat)
     {
-        return $this->setData(ApiOrderInterface::CUSTOMER_TAXVAT, $customerTaxvat);
+        return $this->setData(OrderInterface::CUSTOMER_TAXVAT, $customerTaxvat);
     }
 
     /**
@@ -4123,7 +4144,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setDiscountDescription($description)
     {
-        return $this->setData(ApiOrderInterface::DISCOUNT_DESCRIPTION, $description);
+        return $this->setData(OrderInterface::DISCOUNT_DESCRIPTION, $description);
     }
 
     /**
@@ -4131,7 +4152,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setExtCustomerId($id)
     {
-        return $this->setData(ApiOrderInterface::EXT_CUSTOMER_ID, $id);
+        return $this->setData(OrderInterface::EXT_CUSTOMER_ID, $id);
     }
 
     /**
@@ -4139,7 +4160,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setExtOrderId($id)
     {
-        return $this->setData(ApiOrderInterface::EXT_ORDER_ID, $id);
+        return $this->setData(OrderInterface::EXT_ORDER_ID, $id);
     }
 
     /**
@@ -4147,7 +4168,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setGlobalCurrencyCode($code)
     {
-        return $this->setData(ApiOrderInterface::GLOBAL_CURRENCY_CODE, $code);
+        return $this->setData(OrderInterface::GLOBAL_CURRENCY_CODE, $code);
     }
 
     /**
@@ -4155,7 +4176,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setHoldBeforeState($holdBeforeState)
     {
-        return $this->setData(ApiOrderInterface::HOLD_BEFORE_STATE, $holdBeforeState);
+        return $this->setData(OrderInterface::HOLD_BEFORE_STATE, $holdBeforeState);
     }
 
     /**
@@ -4163,7 +4184,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setHoldBeforeStatus($holdBeforeStatus)
     {
-        return $this->setData(ApiOrderInterface::HOLD_BEFORE_STATUS, $holdBeforeStatus);
+        return $this->setData(OrderInterface::HOLD_BEFORE_STATUS, $holdBeforeStatus);
     }
 
     /**
@@ -4171,7 +4192,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setOrderCurrencyCode($code)
     {
-        return $this->setData(ApiOrderInterface::ORDER_CURRENCY_CODE, $code);
+        return $this->setData(OrderInterface::ORDER_CURRENCY_CODE, $code);
     }
 
     /**
@@ -4179,7 +4200,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setOriginalIncrementId($id)
     {
-        return $this->setData(ApiOrderInterface::ORIGINAL_INCREMENT_ID, $id);
+        return $this->setData(OrderInterface::ORIGINAL_INCREMENT_ID, $id);
     }
 
     /**
@@ -4187,7 +4208,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setRelationChildId($id)
     {
-        return $this->setData(ApiOrderInterface::RELATION_CHILD_ID, $id);
+        return $this->setData(OrderInterface::RELATION_CHILD_ID, $id);
     }
 
     /**
@@ -4195,7 +4216,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setRelationChildRealId($realId)
     {
-        return $this->setData(ApiOrderInterface::RELATION_CHILD_REAL_ID, $realId);
+        return $this->setData(OrderInterface::RELATION_CHILD_REAL_ID, $realId);
     }
 
     /**
@@ -4203,7 +4224,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setRelationParentId($id)
     {
-        return $this->setData(ApiOrderInterface::RELATION_PARENT_ID, $id);
+        return $this->setData(OrderInterface::RELATION_PARENT_ID, $id);
     }
 
     /**
@@ -4211,7 +4232,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setRelationParentRealId($realId)
     {
-        return $this->setData(ApiOrderInterface::RELATION_PARENT_REAL_ID, $realId);
+        return $this->setData(OrderInterface::RELATION_PARENT_REAL_ID, $realId);
     }
 
     /**
@@ -4219,7 +4240,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setRemoteIp($remoteIp)
     {
-        return $this->setData(ApiOrderInterface::REMOTE_IP, $remoteIp);
+        return $this->setData(OrderInterface::REMOTE_IP, $remoteIp);
     }
 
     /**
@@ -4227,7 +4248,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setShippingMethod($shippingMethod)
     {
-        return $this->setData(ApiOrderInterface::SHIPPING_METHOD, $shippingMethod);
+        return $this->setData(OrderInterface::SHIPPING_METHOD, $shippingMethod);
     }
 
     /**
@@ -4235,7 +4256,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setStoreCurrencyCode($code)
     {
-        return $this->setData(ApiOrderInterface::STORE_CURRENCY_CODE, $code);
+        return $this->setData(OrderInterface::STORE_CURRENCY_CODE, $code);
     }
 
     /**
@@ -4243,7 +4264,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setStoreName($storeName)
     {
-        return $this->setData(ApiOrderInterface::STORE_NAME, $storeName);
+        return $this->setData(OrderInterface::STORE_NAME, $storeName);
     }
 
     /**
@@ -4251,7 +4272,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setXForwardedFor($xForwardedFor)
     {
-        return $this->setData(ApiOrderInterface::X_FORWARDED_FOR, $xForwardedFor);
+        return $this->setData(OrderInterface::X_FORWARDED_FOR, $xForwardedFor);
     }
 
     /**
@@ -4259,7 +4280,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setCustomerNote($customerNote)
     {
-        return $this->setData(ApiOrderInterface::CUSTOMER_NOTE, $customerNote);
+        return $this->setData(OrderInterface::CUSTOMER_NOTE, $customerNote);
     }
 
     /**
@@ -4267,7 +4288,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setUpdatedAt($timestamp)
     {
-        return $this->setData(ApiOrderInterface::UPDATED_AT, $timestamp);
+        return $this->setData(OrderInterface::UPDATED_AT, $timestamp);
     }
 
     /**
@@ -4275,7 +4296,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setTotalItemCount($totalItemCount)
     {
-        return $this->setData(ApiOrderInterface::TOTAL_ITEM_COUNT, $totalItemCount);
+        return $this->setData(OrderInterface::TOTAL_ITEM_COUNT, $totalItemCount);
     }
 
     /**
@@ -4283,7 +4304,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setCustomerGender($customerGender)
     {
-        return $this->setData(ApiOrderInterface::CUSTOMER_GENDER, $customerGender);
+        return $this->setData(OrderInterface::CUSTOMER_GENDER, $customerGender);
     }
 
     /**
@@ -4291,7 +4312,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setHiddenTaxAmount($amount)
     {
-        return $this->setData(ApiOrderInterface::HIDDEN_TAX_AMOUNT, $amount);
+        return $this->setData(OrderInterface::HIDDEN_TAX_AMOUNT, $amount);
     }
 
     /**
@@ -4299,7 +4320,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseHiddenTaxAmount($amount)
     {
-        return $this->setData(ApiOrderInterface::BASE_HIDDEN_TAX_AMOUNT, $amount);
+        return $this->setData(OrderInterface::BASE_HIDDEN_TAX_AMOUNT, $amount);
     }
 
     /**
@@ -4307,7 +4328,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setShippingHiddenTaxAmount($amount)
     {
-        return $this->setData(ApiOrderInterface::SHIPPING_HIDDEN_TAX_AMOUNT, $amount);
+        return $this->setData(OrderInterface::SHIPPING_HIDDEN_TAX_AMOUNT, $amount);
     }
 
     /**
@@ -4315,7 +4336,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseShippingHiddenTaxAmnt($amnt)
     {
-        return $this->setData(ApiOrderInterface::BASE_SHIPPING_HIDDEN_TAX_AMNT, $amnt);
+        return $this->setData(OrderInterface::BASE_SHIPPING_HIDDEN_TAX_AMNT, $amnt);
     }
 
     /**
@@ -4323,7 +4344,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setHiddenTaxInvoiced($hiddenTaxInvoiced)
     {
-        return $this->setData(ApiOrderInterface::HIDDEN_TAX_INVOICED, $hiddenTaxInvoiced);
+        return $this->setData(OrderInterface::HIDDEN_TAX_INVOICED, $hiddenTaxInvoiced);
     }
 
     /**
@@ -4331,7 +4352,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseHiddenTaxInvoiced($baseHiddenTaxInvoiced)
     {
-        return $this->setData(ApiOrderInterface::BASE_HIDDEN_TAX_INVOICED, $baseHiddenTaxInvoiced);
+        return $this->setData(OrderInterface::BASE_HIDDEN_TAX_INVOICED, $baseHiddenTaxInvoiced);
     }
 
     /**
@@ -4339,7 +4360,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setHiddenTaxRefunded($hiddenTaxRefunded)
     {
-        return $this->setData(ApiOrderInterface::HIDDEN_TAX_REFUNDED, $hiddenTaxRefunded);
+        return $this->setData(OrderInterface::HIDDEN_TAX_REFUNDED, $hiddenTaxRefunded);
     }
 
     /**
@@ -4347,7 +4368,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseHiddenTaxRefunded($baseHiddenTaxRefunded)
     {
-        return $this->setData(ApiOrderInterface::BASE_HIDDEN_TAX_REFUNDED, $baseHiddenTaxRefunded);
+        return $this->setData(OrderInterface::BASE_HIDDEN_TAX_REFUNDED, $baseHiddenTaxRefunded);
     }
 
     /**
@@ -4355,7 +4376,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setShippingInclTax($amount)
     {
-        return $this->setData(ApiOrderInterface::SHIPPING_INCL_TAX, $amount);
+        return $this->setData(OrderInterface::SHIPPING_INCL_TAX, $amount);
     }
 
     /**
@@ -4363,7 +4384,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
      */
     public function setBaseShippingInclTax($amount)
     {
-        return $this->setData(ApiOrderInterface::BASE_SHIPPING_INCL_TAX, $amount);
+        return $this->setData(OrderInterface::BASE_SHIPPING_INCL_TAX, $amount);
     }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Sales/Model/Order/Address.php b/app/code/Magento/Sales/Model/Order/Address.php
index a5e853f9f3ba7c0b7f0a5a59272ca90c7876eb5f..e0bc6ef9445d7e9cf32fd01860013a3b49fc1d90 100644
--- a/app/code/Magento/Sales/Model/Order/Address.php
+++ b/app/code/Magento/Sales/Model/Order/Address.php
@@ -9,7 +9,6 @@ use Magento\Customer\Api\AddressMetadataInterface;
 use Magento\Customer\Api\Data\AddressInterfaceFactory;
 use Magento\Customer\Api\Data\RegionInterfaceFactory;
 use Magento\Customer\Model\Address\AbstractAddress;
-use Magento\Framework\Api\AttributeValueFactory;
 use Magento\Sales\Api\Data\OrderAddressInterface;
 
 /**
@@ -47,14 +46,14 @@ class Address extends AbstractAddress implements OrderAddressInterface
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
-     * @param AttributeValueFactory $customAttributeFactory
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
+     * @param \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory
      * @param \Magento\Directory\Helper\Data $directoryData
      * @param \Magento\Eav\Model\Config $eavConfig
      * @param \Magento\Customer\Model\Address\Config $addressConfig
      * @param \Magento\Directory\Model\RegionFactory $regionFactory
      * @param \Magento\Directory\Model\CountryFactory $countryFactory
-     * @param AddressMetadataInterface $addressMetadataService
+     * @param AddressMetadataInterface $metadataService
      * @param AddressInterfaceFactory $addressDataFactory
      * @param RegionInterfaceFactory $regionDataFactory
      * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper
@@ -67,14 +66,14 @@ class Address extends AbstractAddress implements OrderAddressInterface
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
-        AttributeValueFactory $customAttributeFactory,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
+        \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory,
         \Magento\Directory\Helper\Data $directoryData,
         \Magento\Eav\Model\Config $eavConfig,
         \Magento\Customer\Model\Address\Config $addressConfig,
         \Magento\Directory\Model\RegionFactory $regionFactory,
         \Magento\Directory\Model\CountryFactory $countryFactory,
-        AddressMetadataInterface $addressMetadataService,
+        AddressMetadataInterface $metadataService,
         AddressInterfaceFactory $addressDataFactory,
         RegionInterfaceFactory $regionDataFactory,
         \Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
@@ -86,14 +85,14 @@ class Address extends AbstractAddress implements OrderAddressInterface
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $directoryData,
             $eavConfig,
             $addressConfig,
             $regionFactory,
             $countryFactory,
-            $addressMetadataService,
+            $metadataService,
             $addressDataFactory,
             $regionDataFactory,
             $dataObjectHelper,
@@ -602,5 +601,26 @@ class Address extends AbstractAddress implements OrderAddressInterface
     {
         return $this->setData(OrderAddressInterface::VAT_REQUEST_SUCCESS, $vatRequestSuccess);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Sales\Api\Data\OrderAddressExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Sales\Api\Data\OrderAddressExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\OrderAddressExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo.php b/app/code/Magento/Sales/Model/Order/Creditmemo.php
index 0b75b3c314eebc86694846fef6d0362ab273e911..852d09607d019b58e30e627ca8e497e4c7390cd0 100644
--- a/app/code/Magento/Sales/Model/Order/Creditmemo.php
+++ b/app/code/Magento/Sales/Model/Order/Creditmemo.php
@@ -114,7 +114,7 @@ class Creditmemo extends AbstractModel implements EntityInterface, CreditmemoInt
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
@@ -134,7 +134,7 @@ class Creditmemo extends AbstractModel implements EntityInterface, CreditmemoInt
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Framework\Stdlib\DateTime $dateTime,
@@ -161,7 +161,7 @@ class Creditmemo extends AbstractModel implements EntityInterface, CreditmemoInt
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $localeDate,
             $dateTime,
@@ -1630,5 +1630,26 @@ class Creditmemo extends AbstractModel implements EntityInterface, CreditmemoInt
     {
         return $this->setData(CreditmemoInterface::DISCOUNT_DESCRIPTION, $description);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Sales\Api\Data\CreditmemoExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Sales\Api\Data\CreditmemoExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\CreditmemoExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Comment.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Comment.php
index 065c772b311e9da882c70a308f176ccce83c54c5..02317f4af9c974829dc5b97f77630ad19bb62322 100644
--- a/app/code/Magento/Sales/Model/Order/Creditmemo/Comment.php
+++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Comment.php
@@ -31,7 +31,7 @@ class Comment extends AbstractModel implements CreditmemoCommentInterface
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
@@ -44,7 +44,7 @@ class Comment extends AbstractModel implements CreditmemoCommentInterface
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Framework\Stdlib\DateTime $dateTime,
@@ -56,7 +56,7 @@ class Comment extends AbstractModel implements CreditmemoCommentInterface
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $localeDate,
             $dateTime,
@@ -194,5 +194,27 @@ class Comment extends AbstractModel implements CreditmemoCommentInterface
     {
         return $this->setData(CreditmemoCommentInterface::COMMENT, $comment);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Sales\Api\Data\CreditmemoCommentExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Sales\Api\Data\CreditmemoCommentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Sales\Api\Data\CreditmemoCommentExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo/Item.php b/app/code/Magento/Sales/Model/Order/Creditmemo/Item.php
index ccf9b3ccba989fed845300a50c71709f395868a5..d432435aee29d49dc3ee4c36119ce5c9f30ece4a 100644
--- a/app/code/Magento/Sales/Model/Order/Creditmemo/Item.php
+++ b/app/code/Magento/Sales/Model/Order/Creditmemo/Item.php
@@ -45,7 +45,7 @@ class Item extends AbstractExtensibleModel implements CreditmemoItemInterface
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Sales\Model\Order\ItemFactory $orderItemFactory
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
@@ -55,7 +55,7 @@ class Item extends AbstractExtensibleModel implements CreditmemoItemInterface
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Sales\Model\Order\ItemFactory $orderItemFactory,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
@@ -65,7 +65,7 @@ class Item extends AbstractExtensibleModel implements CreditmemoItemInterface
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
@@ -821,5 +821,27 @@ class Item extends AbstractExtensibleModel implements CreditmemoItemInterface
     {
         return $this->setData(CreditmemoItemInterface::WEEE_TAX_APPLIED_ROW_AMOUNT, $amount);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Sales\Api\Data\CreditmemoItemExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Sales\Api\Data\CreditmemoItemExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Sales\Api\Data\CreditmemoItemExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Sales/Model/Order/Invoice.php b/app/code/Magento/Sales/Model/Order/Invoice.php
index ab6e124d48c21d0e3d89fe96b6430d365f4afc48..106aaf473b446e5718c6e28e4c2983424bb7fd04 100644
--- a/app/code/Magento/Sales/Model/Order/Invoice.php
+++ b/app/code/Magento/Sales/Model/Order/Invoice.php
@@ -116,7 +116,7 @@ class Invoice extends AbstractModel implements EntityInterface, InvoiceInterface
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
@@ -134,7 +134,7 @@ class Invoice extends AbstractModel implements EntityInterface, InvoiceInterface
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Framework\Stdlib\DateTime $dateTime,
@@ -157,7 +157,7 @@ class Invoice extends AbstractModel implements EntityInterface, InvoiceInterface
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $localeDate,
             $dateTime,
@@ -1574,5 +1574,26 @@ class Invoice extends AbstractModel implements EntityInterface, InvoiceInterface
     {
         return $this->setData(InvoiceInterface::DISCOUNT_DESCRIPTION, $description);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Sales\Api\Data\InvoiceExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Sales\Api\Data\InvoiceExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\InvoiceExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Sales/Model/Order/Invoice/Comment.php b/app/code/Magento/Sales/Model/Order/Invoice/Comment.php
index 73b1007e543759b14c97f36fca337ffe3ceed9af..e1f31fa4c025719b4a95caac311b1f42fedfbe1b 100644
--- a/app/code/Magento/Sales/Model/Order/Invoice/Comment.php
+++ b/app/code/Magento/Sales/Model/Order/Invoice/Comment.php
@@ -31,7 +31,7 @@ class Comment extends AbstractModel implements InvoiceCommentInterface
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
@@ -44,7 +44,7 @@ class Comment extends AbstractModel implements InvoiceCommentInterface
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Framework\Stdlib\DateTime $dateTime,
@@ -56,7 +56,7 @@ class Comment extends AbstractModel implements InvoiceCommentInterface
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $localeDate,
             $dateTime,
@@ -194,5 +194,27 @@ class Comment extends AbstractModel implements InvoiceCommentInterface
     {
         return $this->setData(InvoiceCommentInterface::COMMENT, $comment);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Sales\Api\Data\InvoiceCommentExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Sales\Api\Data\InvoiceCommentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Sales\Api\Data\InvoiceCommentExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Sales/Model/Order/Invoice/Item.php b/app/code/Magento/Sales/Model/Order/Invoice/Item.php
index ddd89354cd33790e53b037bc50a0411c6d840f7b..60c92a7f68b0f68d61697171246020ed2d103688 100644
--- a/app/code/Magento/Sales/Model/Order/Invoice/Item.php
+++ b/app/code/Magento/Sales/Model/Order/Invoice/Item.php
@@ -62,7 +62,7 @@ class Item extends AbstractExtensibleModel implements InvoiceItemInterface
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Sales\Model\Order\ItemFactory $orderItemFactory
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
@@ -72,7 +72,7 @@ class Item extends AbstractExtensibleModel implements InvoiceItemInterface
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Sales\Model\Order\ItemFactory $orderItemFactory,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
@@ -82,7 +82,7 @@ class Item extends AbstractExtensibleModel implements InvoiceItemInterface
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
@@ -684,5 +684,26 @@ class Item extends AbstractExtensibleModel implements InvoiceItemInterface
     {
         return $this->setData(InvoiceItemInterface::BASE_HIDDEN_TAX_AMOUNT, $amount);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Sales\Api\Data\InvoiceItemExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Sales\Api\Data\InvoiceItemExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\InvoiceItemExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Sales/Model/Order/Item.php b/app/code/Magento/Sales/Model/Order/Item.php
index e91edff1ccc35b863ca87918d18715001648ee21..7fd4dc4ec38fa1681b592e496ef303e38acb8e4e 100644
--- a/app/code/Magento/Sales/Model/Order/Item.php
+++ b/app/code/Magento/Sales/Model/Order/Item.php
@@ -101,20 +101,20 @@ class Item extends AbstractExtensibleModel implements OrderItemInterface
      *
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Sales\Model\OrderFactory $orderFactory
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
      * @param \Magento\Framework\Data\Collection\Db $resourceCollection
-     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param array $data
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Sales\Model\OrderFactory $orderFactory,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
@@ -126,7 +126,7 @@ class Item extends AbstractExtensibleModel implements OrderItemInterface
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
@@ -2327,5 +2327,26 @@ class Item extends AbstractExtensibleModel implements OrderItemInterface
     {
         return $this->setData(OrderItemInterface::BASE_WEEE_TAX_ROW_DISPOSITION, $baseWeeeTaxRowDisposition);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Sales\Api\Data\OrderItemExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Sales\Api\Data\OrderItemExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\OrderItemExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Sales/Model/Order/Payment.php b/app/code/Magento/Sales/Model/Order/Payment.php
index d20449aea2849382028664428b386ffa34290de8..fe65a74f1e94e07eadbae950d6364d04b43a9e54 100644
--- a/app/code/Magento/Sales/Model/Order/Payment.php
+++ b/app/code/Magento/Sales/Model/Order/Payment.php
@@ -8,7 +8,6 @@
 
 namespace Magento\Sales\Model\Order;
 
-use Magento\Framework\Api\AttributeValueFactory;
 use Magento\Framework\Pricing\PriceCurrencyInterface;
 use Magento\Payment\Model\Info;
 use Magento\Sales\Api\Data\OrderPaymentInterface;
@@ -101,8 +100,8 @@ class Payment extends Info implements OrderPaymentInterface
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
-     * @param AttributeValueFactory $customAttributeFactory
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
+     * @param \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\Encryption\EncryptorInterface $encryptor
      * @param \Magento\Sales\Model\Service\OrderFactory $serviceOrderFactory
@@ -118,8 +117,8 @@ class Payment extends Info implements OrderPaymentInterface
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
-        AttributeValueFactory $customAttributeFactory,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
+        \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\Encryption\EncryptorInterface $encryptor,
         \Magento\Sales\Model\Service\OrderFactory $serviceOrderFactory,
@@ -139,7 +138,7 @@ class Payment extends Info implements OrderPaymentInterface
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $paymentData,
             $encryptor,
@@ -2572,5 +2571,26 @@ class Payment extends Info implements OrderPaymentInterface
     {
         return $this->setData(OrderPaymentInterface::ADDRESS_STATUS, $addressStatus);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Sales\Api\Data\OrderPaymentExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Sales\Api\Data\OrderPaymentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\OrderPaymentExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Sales/Model/Order/Payment/Transaction.php b/app/code/Magento/Sales/Model/Order/Payment/Transaction.php
index 9b4d6f39fdcaac1fbc20177cab1c7e19fb0019ba..942cf9475983eb24457bfd676c6cf216dc8f2294 100644
--- a/app/code/Magento/Sales/Model/Order/Payment/Transaction.php
+++ b/app/code/Magento/Sales/Model/Order/Payment/Transaction.php
@@ -20,7 +20,7 @@ use Magento\Sales\Api\Data\TransactionInterface;
  * @method \Magento\Sales\Model\Resource\Order\Payment\Transaction _getResource()
  * @method \Magento\Sales\Model\Resource\Order\Payment\Transaction getResource()
  * @method \Magento\Sales\Model\Order\Payment\Transaction setCreatedAt(string $value)
- *
+
  * @author      Magento Core Team <core@magentocommerce.com>
  * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -153,7 +153,7 @@ class Transaction extends AbstractExtensibleModel implements TransactionInterfac
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Sales\Model\Order\PaymentFactory $paymentFactory
      * @param \Magento\Sales\Model\OrderFactory $orderFactory
@@ -167,7 +167,7 @@ class Transaction extends AbstractExtensibleModel implements TransactionInterfac
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Sales\Model\Order\PaymentFactory $paymentFactory,
         \Magento\Sales\Model\OrderFactory $orderFactory,
@@ -184,7 +184,7 @@ class Transaction extends AbstractExtensibleModel implements TransactionInterfac
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
@@ -1044,5 +1044,26 @@ class Transaction extends AbstractExtensibleModel implements TransactionInterfac
     {
         return $this->setData(TransactionInterface::IS_CLOSED, $isClosed);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Sales\Api\Data\TransactionExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Sales\Api\Data\TransactionExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\TransactionExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Sales/Model/Order/Shipment.php b/app/code/Magento/Sales/Model/Order/Shipment.php
index 0e5a3c5cf9249f742dd1fbb51bed1d05d951c589..51b24d4fb8946a28f8d21585e789ee561f611bb2 100644
--- a/app/code/Magento/Sales/Model/Order/Shipment.php
+++ b/app/code/Magento/Sales/Model/Order/Shipment.php
@@ -92,7 +92,7 @@ class Shipment extends AbstractModel implements EntityInterface, ShipmentInterfa
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
@@ -109,7 +109,7 @@ class Shipment extends AbstractModel implements EntityInterface, ShipmentInterfa
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Framework\Stdlib\DateTime $dateTime,
@@ -130,7 +130,7 @@ class Shipment extends AbstractModel implements EntityInterface, ShipmentInterfa
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $localeDate,
             $dateTime,
@@ -826,5 +826,26 @@ class Shipment extends AbstractModel implements EntityInterface, ShipmentInterfa
     {
         return $this->setData(ShipmentInterface::UPDATED_AT, $timestamp);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Sales\Api\Data\ShipmentExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Sales\Api\Data\ShipmentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\ShipmentExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Comment.php b/app/code/Magento/Sales/Model/Order/Shipment/Comment.php
index cd39cbf1818f3889f8df0ae6f6198e980e2a5dc8..871d04fa49f472f06913b2ceb950557d7912f9db 100644
--- a/app/code/Magento/Sales/Model/Order/Shipment/Comment.php
+++ b/app/code/Magento/Sales/Model/Order/Shipment/Comment.php
@@ -31,7 +31,7 @@ class Comment extends AbstractModel implements ShipmentCommentInterface
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
@@ -44,7 +44,7 @@ class Comment extends AbstractModel implements ShipmentCommentInterface
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Framework\Stdlib\DateTime $dateTime,
@@ -56,7 +56,7 @@ class Comment extends AbstractModel implements ShipmentCommentInterface
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $localeDate,
             $dateTime,
@@ -194,5 +194,27 @@ class Comment extends AbstractModel implements ShipmentCommentInterface
     {
         return $this->setData(ShipmentCommentInterface::COMMENT, $comment);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Sales\Api\Data\ShipmentCommentExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Sales\Api\Data\ShipmentCommentExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Sales\Api\Data\ShipmentCommentExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Item.php b/app/code/Magento/Sales/Model/Order/Shipment/Item.php
index 4e0099fee1fe842f785fd3e96b3e194b2d55ea2d..099a6af8875ff0f1044198b77e118b5788448700 100644
--- a/app/code/Magento/Sales/Model/Order/Shipment/Item.php
+++ b/app/code/Magento/Sales/Model/Order/Shipment/Item.php
@@ -46,7 +46,7 @@ class Item extends AbstractExtensibleModel implements ShipmentItemInterface
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Sales\Model\Order\ItemFactory $orderItemFactory
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
@@ -56,7 +56,7 @@ class Item extends AbstractExtensibleModel implements ShipmentItemInterface
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Sales\Model\Order\ItemFactory $orderItemFactory,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
@@ -66,7 +66,7 @@ class Item extends AbstractExtensibleModel implements ShipmentItemInterface
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
@@ -364,5 +364,26 @@ class Item extends AbstractExtensibleModel implements ShipmentItemInterface
     {
         return $this->setData(ShipmentItemInterface::SKU, $sku);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Sales\Api\Data\ShipmentItemExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Sales\Api\Data\ShipmentItemExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\ShipmentItemExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Sales/Model/Order/Shipment/Track.php b/app/code/Magento/Sales/Model/Order/Shipment/Track.php
index f8e47cd53ee210a6d297c6ac13df86edfb06dfd1..85b0e3419eca06e7e7564a9a9b57d72317fbf37a 100644
--- a/app/code/Magento/Sales/Model/Order/Shipment/Track.php
+++ b/app/code/Magento/Sales/Model/Order/Shipment/Track.php
@@ -52,7 +52,7 @@ class Track extends AbstractModel implements ShipmentTrackInterface
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
@@ -66,7 +66,7 @@ class Track extends AbstractModel implements ShipmentTrackInterface
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Framework\Stdlib\DateTime $dateTime,
@@ -79,7 +79,7 @@ class Track extends AbstractModel implements ShipmentTrackInterface
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $localeDate,
             $dateTime,
@@ -380,5 +380,26 @@ class Track extends AbstractModel implements ShipmentTrackInterface
     {
         return $this->setData(ShipmentTrackInterface::CARRIER_CODE, $code);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Sales\Api\Data\ShipmentTrackExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Sales\Api\Data\ShipmentTrackExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Sales\Api\Data\ShipmentTrackExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Sales/Model/Order/Status/History.php b/app/code/Magento/Sales/Model/Order/Status/History.php
index 59d6c02054eb1b3b1d829969ae0dc48ff070e559..5ce6a1aa42ba7fa0a405d3174b9e06a469d276db 100644
--- a/app/code/Magento/Sales/Model/Order/Status/History.php
+++ b/app/code/Magento/Sales/Model/Order/Status/History.php
@@ -45,7 +45,7 @@ class History extends AbstractModel implements OrderStatusHistoryInterface
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
@@ -58,7 +58,7 @@ class History extends AbstractModel implements OrderStatusHistoryInterface
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Framework\Stdlib\DateTime $dateTime,
@@ -70,7 +70,7 @@ class History extends AbstractModel implements OrderStatusHistoryInterface
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $localeDate,
             $dateTime,
@@ -301,5 +301,27 @@ class History extends AbstractModel implements OrderStatusHistoryInterface
     {
         return $this->setData(OrderStatusHistoryInterface::ENTITY_NAME, $entityName);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Sales\Api\Data\OrderStatusHistoryExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Sales\Api\Data\OrderStatusHistoryExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Sales\Api\Data\OrderStatusHistoryExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
     //@codeCoverageIgnoreEnd
 }
diff --git a/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/View/Tab/Stub/OnlineMethod.php b/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/View/Tab/Stub/OnlineMethod.php
index f6145240f582a67e371f5debc9dcafa745e13135..3052b410765c572f7d308017bd8a26c46d6ad8af 100644
--- a/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/View/Tab/Stub/OnlineMethod.php
+++ b/app/code/Magento/Sales/Test/Unit/Block/Adminhtml/Order/View/Tab/Stub/OnlineMethod.php
@@ -7,6 +7,7 @@ namespace Magento\Sales\Test\Unit\Block\Adminhtml\Order\View\Tab\Stub;
 
 /**
  * Stub for an online payment method
+ * @method \Magento\Quote\Api\Data\PaymentMethodExtensionInterface getExtensionAttributes()
  */
 class OnlineMethod extends \Magento\Payment\Model\Method\AbstractMethod
 {
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Email/TemplateTest.php b/app/code/Magento/Sales/Test/Unit/Model/Email/TemplateTest.php
index f9a38143e5023767f7936761260e61d6301e31e7..c8c3632bb160226bbf95918724fe1423fdad2755 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Email/TemplateTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Email/TemplateTest.php
@@ -4,6 +4,8 @@
  * See COPYING.txt for license details.
  */
 
+// @codingStandardsIgnoreFile
+
 /**
  * Test class for \Magento\Sales\Model\Email\Template
  */
@@ -46,6 +48,14 @@ class TemplateTest extends \PHPUnit_Framework_TestCase
         );
     }
 
+    protected function tearDown()
+    {
+        parent::tearDown();
+        $magentoObjectManagerFactory = \Magento\Framework\App\Bootstrap::createObjectManagerFactory(BP, $_SERVER);
+        $objectManager = $magentoObjectManagerFactory->create($_SERVER);
+        \Magento\Framework\App\ObjectManager::setInstance($objectManager);
+    }
+
     public function testIncludeTemplate()
     {
         $this->mockViewFilesystem->expects($this->once())
diff --git a/app/code/Magento/Shipping/Model/Order/Track.php b/app/code/Magento/Shipping/Model/Order/Track.php
index ff7167e94ab78f5bdfffbaa8ee302621cff0bf7a..3eadf958b8902664592bab8b7e67be6664e3adea 100644
--- a/app/code/Magento/Shipping/Model/Order/Track.php
+++ b/app/code/Magento/Shipping/Model/Order/Track.php
@@ -21,7 +21,7 @@ use Magento\Framework\Api\AttributeValueFactory;
  * @method string getCreatedAt()
  * @method \Magento\Sales\Model\Order\Shipment\Track setCreatedAt(string $value)
  * @method string getUpdatedAt()
- *
+ * @method \Magento\Sales\Api\Data\ShipmentTrackExtensionInterface getExtensionAttributes()
  */
 class Track extends \Magento\Sales\Model\Order\Shipment\Track
 {
@@ -33,7 +33,7 @@ class Track extends \Magento\Sales\Model\Order\Shipment\Track
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
@@ -49,7 +49,7 @@ class Track extends \Magento\Sales\Model\Order\Shipment\Track
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Framework\Stdlib\DateTime $dateTime,
@@ -63,7 +63,7 @@ class Track extends \Magento\Sales\Model\Order\Shipment\Track
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $localeDate,
             $dateTime,
diff --git a/app/code/Magento/Tax/Api/Data/AppliedTaxInterface.php b/app/code/Magento/Tax/Api/Data/AppliedTaxInterface.php
index a447c3944a03eea781b35d21d93afa35c29665ad..356d39d0bc106519315c3fa76da8321931c116fd 100644
--- a/app/code/Magento/Tax/Api/Data/AppliedTaxInterface.php
+++ b/app/code/Magento/Tax/Api/Data/AppliedTaxInterface.php
@@ -78,4 +78,19 @@ interface AppliedTaxInterface extends \Magento\Framework\Api\ExtensibleDataInter
      * @return $this
      */
     public function setRates(array $rates = null);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Tax\Api\Data\AppliedTaxExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Tax\Api\Data\AppliedTaxExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\AppliedTaxExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Tax/Api/Data/AppliedTaxRateInterface.php b/app/code/Magento/Tax/Api/Data/AppliedTaxRateInterface.php
index f0c83cbe8d469c20b964d19e17ea6b9bbec5a929..cee4ab16fd1f0acdde90bd353b3d264e4ba52b11 100644
--- a/app/code/Magento/Tax/Api/Data/AppliedTaxRateInterface.php
+++ b/app/code/Magento/Tax/Api/Data/AppliedTaxRateInterface.php
@@ -62,4 +62,19 @@ interface AppliedTaxRateInterface extends \Magento\Framework\Api\ExtensibleDataI
      * @return $this
      */
     public function setPercent($percent);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Tax\Api\Data\AppliedTaxRateExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Tax\Api\Data\AppliedTaxRateExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\AppliedTaxRateExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Tax/Api/Data/OrderTaxDetailsAppliedTaxInterface.php b/app/code/Magento/Tax/Api/Data/OrderTaxDetailsAppliedTaxInterface.php
index bf8fed9966b07dce82fd5a751a98982423cb1fca..7123087eacf565f0341178e6f9643c9a98bf7036 100644
--- a/app/code/Magento/Tax/Api/Data/OrderTaxDetailsAppliedTaxInterface.php
+++ b/app/code/Magento/Tax/Api/Data/OrderTaxDetailsAppliedTaxInterface.php
@@ -97,4 +97,21 @@ interface OrderTaxDetailsAppliedTaxInterface extends \Magento\Framework\Api\Exte
      * @return $this
      */
     public function setBaseAmount($baseAmount);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Tax\Api\Data\OrderTaxDetailsAppliedTaxExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Tax\Api\Data\OrderTaxDetailsAppliedTaxExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Tax\Api\Data\OrderTaxDetailsAppliedTaxExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Tax/Api/Data/OrderTaxDetailsInterface.php b/app/code/Magento/Tax/Api/Data/OrderTaxDetailsInterface.php
index cee19ce16af5d69f9ef3ae96a057f8f9f96a5c11..d68de6f5858aab5c3362c60d62a1d006bc22c42d 100644
--- a/app/code/Magento/Tax/Api/Data/OrderTaxDetailsInterface.php
+++ b/app/code/Magento/Tax/Api/Data/OrderTaxDetailsInterface.php
@@ -42,4 +42,21 @@ interface OrderTaxDetailsInterface extends \Magento\Framework\Api\ExtensibleData
      * @return $this
      */
     public function setItems(array $items = null);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Tax\Api\Data\OrderTaxDetailsExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Tax\Api\Data\OrderTaxDetailsExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Tax\Api\Data\OrderTaxDetailsExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Tax/Api/Data/OrderTaxDetailsItemInterface.php b/app/code/Magento/Tax/Api/Data/OrderTaxDetailsItemInterface.php
index 601371a4259c11b12e8bd7b383d87c6fec9aec1e..905a0aa203594097e5377130679dfb4e5bb18a92 100644
--- a/app/code/Magento/Tax/Api/Data/OrderTaxDetailsItemInterface.php
+++ b/app/code/Magento/Tax/Api/Data/OrderTaxDetailsItemInterface.php
@@ -80,4 +80,21 @@ interface OrderTaxDetailsItemInterface extends \Magento\Framework\Api\Extensible
      * @return $this
      */
     public function setAppliedTaxes(array $appliedTaxes = null);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Tax\Api\Data\OrderTaxDetailsItemExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Tax\Api\Data\OrderTaxDetailsItemExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Tax\Api\Data\OrderTaxDetailsItemExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Tax/Api/Data/QuoteDetailsInterface.php b/app/code/Magento/Tax/Api/Data/QuoteDetailsInterface.php
index f8e60a4cfd08e2bf84115321daa7d6ce22575e5b..f7d69e1572f86eaecfad263eeeb026ebe8f280bc 100644
--- a/app/code/Magento/Tax/Api/Data/QuoteDetailsInterface.php
+++ b/app/code/Magento/Tax/Api/Data/QuoteDetailsInterface.php
@@ -114,4 +114,19 @@ interface QuoteDetailsInterface extends \Magento\Framework\Api\ExtensibleDataInt
      * @return $this
      */
     public function setCustomerTaxClassId($customerTaxClassId);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Tax\Api\Data\QuoteDetailsExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Tax\Api\Data\QuoteDetailsExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\QuoteDetailsExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Tax/Api/Data/QuoteDetailsItemInterface.php b/app/code/Magento/Tax/Api/Data/QuoteDetailsItemInterface.php
index 212236f8d599a62de5a00475091fd3ac94a63c84..ea3e57327f3115581853572e3159628b600c31cd 100644
--- a/app/code/Magento/Tax/Api/Data/QuoteDetailsItemInterface.php
+++ b/app/code/Magento/Tax/Api/Data/QuoteDetailsItemInterface.php
@@ -198,4 +198,21 @@ interface QuoteDetailsItemInterface extends \Magento\Framework\Api\ExtensibleDat
      * @return $this
      */
     public function setTaxClassId($taxClassId);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Tax\Api\Data\QuoteDetailsItemExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Tax\Api\Data\QuoteDetailsItemExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Tax\Api\Data\QuoteDetailsItemExtensionInterface $extensionAttributes
+    );
 }
diff --git a/app/code/Magento/Tax/Api/Data/TaxClassInterface.php b/app/code/Magento/Tax/Api/Data/TaxClassInterface.php
index 1539ea9e5c5acd739675390bc73cba9912600ab7..80774ef47c646bed3cb54e3813b7968c37536adc 100644
--- a/app/code/Magento/Tax/Api/Data/TaxClassInterface.php
+++ b/app/code/Magento/Tax/Api/Data/TaxClassInterface.php
@@ -62,4 +62,19 @@ interface TaxClassInterface extends \Magento\Framework\Api\ExtensibleDataInterfa
      * @return $this
      */
     public function setClassType($classType);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Tax\Api\Data\TaxClassExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Tax\Api\Data\TaxClassExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\TaxClassExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Tax/Api/Data/TaxClassKeyInterface.php b/app/code/Magento/Tax/Api/Data/TaxClassKeyInterface.php
index 709291ff35ce434f58e55ff83ae3cd8247074617..9f0a25a170cbadbd71ad8e1c1e7d7cd6de7d0c27 100644
--- a/app/code/Magento/Tax/Api/Data/TaxClassKeyInterface.php
+++ b/app/code/Magento/Tax/Api/Data/TaxClassKeyInterface.php
@@ -55,4 +55,19 @@ interface TaxClassKeyInterface extends ExtensibleDataInterface
      * @return $this
      */
     public function setValue($value);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Tax\Api\Data\TaxClassKeyExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Tax\Api\Data\TaxClassKeyExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\TaxClassKeyExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Tax/Api/Data/TaxDetailsInterface.php b/app/code/Magento/Tax/Api/Data/TaxDetailsInterface.php
index 0c6f80296474a2211b8048fef57d5c561f6d64b3..f06ba96bc54ca28a6ed4e167d48bbc4e553dcd15 100644
--- a/app/code/Magento/Tax/Api/Data/TaxDetailsInterface.php
+++ b/app/code/Magento/Tax/Api/Data/TaxDetailsInterface.php
@@ -97,4 +97,19 @@ interface TaxDetailsInterface extends \Magento\Framework\Api\ExtensibleDataInter
      * @return $this
      */
     public function setItems(array $items = null);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Tax\Api\Data\TaxDetailsExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Tax\Api\Data\TaxDetailsExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\TaxDetailsExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Tax/Api/Data/TaxDetailsItemInterface.php b/app/code/Magento/Tax/Api/Data/TaxDetailsItemInterface.php
index 8c2f50111b313df4b0c00c66c4b48f68c199bc92..fad3229d7076a589363cbabf9f5bcb064984e04f 100644
--- a/app/code/Magento/Tax/Api/Data/TaxDetailsItemInterface.php
+++ b/app/code/Magento/Tax/Api/Data/TaxDetailsItemInterface.php
@@ -232,4 +232,19 @@ interface TaxDetailsItemInterface extends \Magento\Framework\Api\ExtensibleDataI
      * @return $this
      */
     public function setAssociatedItemCode($associatedItemCode);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Tax\Api\Data\TaxDetailsItemExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Tax\Api\Data\TaxDetailsItemExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\TaxDetailsItemExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Tax/Api/Data/TaxRateInterface.php b/app/code/Magento/Tax/Api/Data/TaxRateInterface.php
index 7e878cb77564be1ae4c687df027e8be3b77a9567..881bb7fa7e013838c558f5514af373dcbe6fceaa 100644
--- a/app/code/Magento/Tax/Api/Data/TaxRateInterface.php
+++ b/app/code/Magento/Tax/Api/Data/TaxRateInterface.php
@@ -189,4 +189,19 @@ interface TaxRateInterface extends \Magento\Framework\Api\ExtensibleDataInterfac
      * @return $this
      */
     public function setTitles(array $titles = null);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Tax\Api\Data\TaxRateExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Tax\Api\Data\TaxRateExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\TaxRateExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Tax/Api/Data/TaxRateTitleInterface.php b/app/code/Magento/Tax/Api/Data/TaxRateTitleInterface.php
index 2d9ff88958b105ef78e95630fb31eed4d88d5893..8d3991070b9565d9527c7c036aca9e45864d15f4 100644
--- a/app/code/Magento/Tax/Api/Data/TaxRateTitleInterface.php
+++ b/app/code/Magento/Tax/Api/Data/TaxRateTitleInterface.php
@@ -47,4 +47,19 @@ interface TaxRateTitleInterface extends \Magento\Framework\Api\ExtensibleDataInt
      * @return string
      */
     public function setValue($value);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Tax\Api\Data\TaxRateTitleExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Tax\Api\Data\TaxRateTitleExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\TaxRateTitleExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Tax/Api/Data/TaxRuleInterface.php b/app/code/Magento/Tax/Api/Data/TaxRuleInterface.php
index e746fd0c9f2630d266dad79383c2790fb9154b4d..67c9b6a80c65e9ad7388e9c43be71144e5ba8690 100644
--- a/app/code/Magento/Tax/Api/Data/TaxRuleInterface.php
+++ b/app/code/Magento/Tax/Api/Data/TaxRuleInterface.php
@@ -129,4 +129,19 @@ interface TaxRuleInterface extends ExtensibleDataInterface
      * @return $this
      */
     public function setCalculateSubtotal($calculateSubtotal);
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Tax\Api\Data\TaxRuleExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Tax\Api\Data\TaxRuleExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\TaxRuleExtensionInterface $extensionAttributes);
 }
diff --git a/app/code/Magento/Tax/Model/Calculation/Rate.php b/app/code/Magento/Tax/Model/Calculation/Rate.php
index bb05f8694e82f1c881fc172980ae6472c0fa093e..06e40c545eb868797a682864365c96483b28d4a1 100644
--- a/app/code/Magento/Tax/Model/Calculation/Rate.php
+++ b/app/code/Magento/Tax/Model/Calculation/Rate.php
@@ -51,7 +51,7 @@ class Rate extends \Magento\Framework\Model\AbstractExtensibleModel implements \
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Directory\Model\RegionFactory $regionFactory
      * @param Rate\TitleFactory $taxTitleFactory
@@ -64,7 +64,7 @@ class Rate extends \Magento\Framework\Model\AbstractExtensibleModel implements \
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Directory\Model\RegionFactory $regionFactory,
         \Magento\Tax\Model\Calculation\Rate\TitleFactory $taxTitleFactory,
@@ -79,7 +79,7 @@ class Rate extends \Magento\Framework\Model\AbstractExtensibleModel implements \
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
@@ -484,4 +484,25 @@ class Rate extends \Magento\Framework\Model\AbstractExtensibleModel implements \
         return $this->setData(self::KEY_TITLES, $titles);
     }
     // @codeCoverageIgnoreEnd
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Tax\Api\Data\TaxRateExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Tax\Api\Data\TaxRateExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\TaxRateExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Tax/Model/Calculation/Rate/Title.php b/app/code/Magento/Tax/Model/Calculation/Rate/Title.php
index 674c59e0eff8151627db9a8a1155557692702caa..a98b220548940e240774250f868c8b1abb8c4f1d 100644
--- a/app/code/Magento/Tax/Model/Calculation/Rate/Title.php
+++ b/app/code/Magento/Tax/Model/Calculation/Rate/Title.php
@@ -76,4 +76,25 @@ class Title extends \Magento\Framework\Model\AbstractExtensibleModel implements
         return $this->setData(self::KEY_VALUE_ID, $value);
     }
     // @codeCoverageIgnoreEnd
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Tax\Api\Data\TaxRateTitleExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Tax\Api\Data\TaxRateTitleExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\TaxRateTitleExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Tax/Model/Calculation/Rule.php b/app/code/Magento/Tax/Model/Calculation/Rule.php
index ddf7acb1e7afeb119dfbf3821679d99520f18966..13d287ce5da36b67ece5d16a634a1ba3a743ca44 100644
--- a/app/code/Magento/Tax/Model/Calculation/Rule.php
+++ b/app/code/Magento/Tax/Model/Calculation/Rule.php
@@ -6,7 +6,7 @@
 namespace Magento\Tax\Model\Calculation;
 
 use Magento\Framework\Api\AttributeValueFactory;
-use Magento\Framework\Api\MetadataServiceInterface;
+use Magento\Framework\Api\ExtensionAttributesFactory;
 use Magento\Tax\Api\Data\TaxRuleInterface;
 
 /**
@@ -72,7 +72,7 @@ class Rule extends \Magento\Framework\Model\AbstractExtensibleModel implements T
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param MetadataServiceInterface $metadataService
+     * @param ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Tax\Model\ClassModel $taxClass
      * @param \Magento\Tax\Model\Calculation $calculation
@@ -85,7 +85,7 @@ class Rule extends \Magento\Framework\Model\AbstractExtensibleModel implements T
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        MetadataServiceInterface $metadataService,
+        ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Tax\Model\ClassModel $taxClass,
         \Magento\Tax\Model\Calculation $calculation,
@@ -99,7 +99,7 @@ class Rule extends \Magento\Framework\Model\AbstractExtensibleModel implements T
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
@@ -377,4 +377,25 @@ class Rule extends \Magento\Framework\Model\AbstractExtensibleModel implements T
     {
         return $this->setData(self::KEY_CALCULATE_SUBTOTAL, $calculateSubtotal);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Tax\Api\Data\TaxRuleExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Tax\Api\Data\TaxRuleExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\TaxRuleExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Tax/Model/ClassModel.php b/app/code/Magento/Tax/Model/ClassModel.php
index 143cb9504cecd6d4c41900b1322fe0a1b4592ba3..9835203636346d9a2d6a66a7bd2b75bf5eae09e7 100644
--- a/app/code/Magento/Tax/Model/ClassModel.php
+++ b/app/code/Magento/Tax/Model/ClassModel.php
@@ -37,7 +37,7 @@ class ClassModel extends \Magento\Framework\Model\AbstractExtensibleModel implem
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param TaxClass\Factory $classFactory
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
@@ -47,7 +47,7 @@ class ClassModel extends \Magento\Framework\Model\AbstractExtensibleModel implem
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Api\MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Tax\Model\TaxClass\Factory $classFactory,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
@@ -57,7 +57,7 @@ class ClassModel extends \Magento\Framework\Model\AbstractExtensibleModel implem
         parent::__construct(
             $context,
             $registry,
-            $metadataService,
+            $extensionFactory,
             $customAttributeFactory,
             $resource,
             $resourceCollection,
@@ -174,4 +174,25 @@ class ClassModel extends \Magento\Framework\Model\AbstractExtensibleModel implem
         return $this->setData(self::KEY_TYPE, $classType);
     }
     //@codeCoverageIgnoreEnd
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Tax\Api\Data\TaxClassExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Tax\Api\Data\TaxClassExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\TaxClassExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Tax/Model/Sales/Order/Details.php b/app/code/Magento/Tax/Model/Sales/Order/Details.php
index 14fce1cbbb59f4880e143b3bb22c7d435cf4666c..5161ab9fe6f7397f08cb88972033a8a6be6f6ef4 100644
--- a/app/code/Magento/Tax/Model/Sales/Order/Details.php
+++ b/app/code/Magento/Tax/Model/Sales/Order/Details.php
@@ -50,4 +50,25 @@ class Details extends \Magento\Framework\Model\AbstractExtensibleModel implement
     {
         return $this->setData(self::KEY_ITEMS, $items);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Tax\Api\Data\OrderTaxDetailsExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Tax\Api\Data\OrderTaxDetailsExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\OrderTaxDetailsExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Tax/Model/Sales/Order/Tax.php b/app/code/Magento/Tax/Model/Sales/Order/Tax.php
index d361064b51b734abd849e9fa85666789a595b120..29ce7e404f5696bcff549d3b276f6b14f6aea1d2 100644
--- a/app/code/Magento/Tax/Model/Sales/Order/Tax.php
+++ b/app/code/Magento/Tax/Model/Sales/Order/Tax.php
@@ -127,4 +127,26 @@ class Tax extends \Magento\Framework\Model\AbstractExtensibleModel implements
     {
         return $this->setData(self::KEY_BASE_AMOUNT, $baseAmount);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Tax\Api\Data\OrderTaxDetailsAppliedTaxExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Tax\Api\Data\OrderTaxDetailsAppliedTaxExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Tax\Api\Data\OrderTaxDetailsAppliedTaxExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Tax/Model/Sales/Order/Tax/Item.php b/app/code/Magento/Tax/Model/Sales/Order/Tax/Item.php
index a57234e0ece611f01f39a313705f9d67613d18b5..a6b6148ed0c9eaca83d07b74c4d32f53ce3a1e74 100644
--- a/app/code/Magento/Tax/Model/Sales/Order/Tax/Item.php
+++ b/app/code/Magento/Tax/Model/Sales/Order/Tax/Item.php
@@ -94,4 +94,26 @@ class Item extends \Magento\Framework\Model\AbstractExtensibleModel implements
     {
         return $this->setData(self::KEY_APPLIED_TAXES, $appliedTaxes);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Tax\Api\Data\OrderTaxDetailsItemExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Tax\Api\Data\OrderTaxDetailsItemExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Tax\Api\Data\OrderTaxDetailsItemExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Tax/Model/Sales/Quote/ItemDetails.php b/app/code/Magento/Tax/Model/Sales/Quote/ItemDetails.php
index ca74f9f940315bd0d61dca0dda68714e530b4d2b..71d18024ea5f1a199b99ff3811fa4d82d7009ed7 100644
--- a/app/code/Magento/Tax/Model/Sales/Quote/ItemDetails.php
+++ b/app/code/Magento/Tax/Model/Sales/Quote/ItemDetails.php
@@ -221,4 +221,26 @@ class ItemDetails extends AbstractExtensibleModel implements QuoteDetailsItemInt
     {
         return $this->setData(QuoteDetailsItemInterface::KEY_TAX_CLASS_ID, $taxClassId);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Tax\Api\Data\QuoteDetailsItemExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Tax\Api\Data\QuoteDetailsItemExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Tax\Api\Data\QuoteDetailsItemExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Tax/Model/Sales/Quote/QuoteDetails.php b/app/code/Magento/Tax/Model/Sales/Quote/QuoteDetails.php
index 0ebdffd3ba107668c3a02a0b1da232a27bd161df..1ef369ba40d82dfb3655926be7970e003892a152 100644
--- a/app/code/Magento/Tax/Model/Sales/Quote/QuoteDetails.php
+++ b/app/code/Magento/Tax/Model/Sales/Quote/QuoteDetails.php
@@ -126,4 +126,25 @@ class QuoteDetails extends AbstractExtensibleModel implements QuoteDetailsInterf
     {
         return $this->setData(QuoteDetailsInterface::CUSTOMER_TAX_CLASS_ID, $customerTaxClassId);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Tax\Api\Data\QuoteDetailsExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Tax\Api\Data\QuoteDetailsExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\QuoteDetailsExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Tax/Model/TaxClass/Key.php b/app/code/Magento/Tax/Model/TaxClass/Key.php
index 11ccf63e872d3fc5b0fd3264cae7610d7a24a438..085b018aa88f7ad8ba4ef5a36fea99c31f6ded54 100644
--- a/app/code/Magento/Tax/Model/TaxClass/Key.php
+++ b/app/code/Magento/Tax/Model/TaxClass/Key.php
@@ -50,4 +50,25 @@ class Key extends AbstractExtensibleModel implements TaxClassKeyInterface
     {
         return $this->setData(TaxClassKeyInterface::KEY_VALUE, $value);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Tax\Api\Data\TaxClassKeyExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Tax\Api\Data\TaxClassKeyExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\TaxClassKeyExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Tax/Model/TaxDetails/AppliedTax.php b/app/code/Magento/Tax/Model/TaxDetails/AppliedTax.php
index 135fada6e8e39ff474e4ddb7267d98572824f0f4..79265cacbc0c8615b0989d9deae57cb4ab6ee405 100644
--- a/app/code/Magento/Tax/Model/TaxDetails/AppliedTax.php
+++ b/app/code/Magento/Tax/Model/TaxDetails/AppliedTax.php
@@ -88,4 +88,25 @@ class AppliedTax extends AbstractExtensibleModel implements AppliedTaxInterface
     {
         return $this->setData(AppliedTaxInterface::KEY_RATES, $rates);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Tax\Api\Data\AppliedTaxExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Tax\Api\Data\AppliedTaxExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\AppliedTaxExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Tax/Model/TaxDetails/AppliedTaxRate.php b/app/code/Magento/Tax/Model/TaxDetails/AppliedTaxRate.php
index c1dddb0a87dcc834e68ff02745f6ee360dffbbbd..8cd44cb70e0e36de4ebe281b05e439e18be8312d 100644
--- a/app/code/Magento/Tax/Model/TaxDetails/AppliedTaxRate.php
+++ b/app/code/Magento/Tax/Model/TaxDetails/AppliedTaxRate.php
@@ -69,4 +69,25 @@ class AppliedTaxRate extends AbstractExtensibleModel implements AppliedTaxRateIn
     {
         return $this->setData(AppliedTaxRateInterface::KEY_PERCENT, $percent);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Tax\Api\Data\AppliedTaxRateExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Tax\Api\Data\AppliedTaxRateExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\AppliedTaxRateExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Tax/Model/TaxDetails/ItemDetails.php b/app/code/Magento/Tax/Model/TaxDetails/ItemDetails.php
index 711a228705ddd70c274f507d438f059f3283f6ee..9ba71b43dedf1c2bf676436e6a3754e4f168d69f 100644
--- a/app/code/Magento/Tax/Model/TaxDetails/ItemDetails.php
+++ b/app/code/Magento/Tax/Model/TaxDetails/ItemDetails.php
@@ -262,4 +262,25 @@ class ItemDetails extends AbstractExtensibleModel implements TaxDetailsItemInter
     {
         return $this->setData(TaxDetailsItemInterface::KEY_ASSOCIATED_ITEM_CODE, $associatedItemCode);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Tax\Api\Data\TaxDetailsItemExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Tax\Api\Data\TaxDetailsItemExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\TaxDetailsItemExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/Tax/Model/TaxDetails/TaxDetails.php b/app/code/Magento/Tax/Model/TaxDetails/TaxDetails.php
index bc7c87b48209900aec99200760f3c82d37c73f7b..91f1587c8b575ce08e5f52a0196c724f40917a36 100644
--- a/app/code/Magento/Tax/Model/TaxDetails/TaxDetails.php
+++ b/app/code/Magento/Tax/Model/TaxDetails/TaxDetails.php
@@ -110,4 +110,25 @@ class TaxDetails extends AbstractExtensibleModel implements TaxDetailsInterface
     {
         return $this->setData(TaxDetailsInterface::KEY_ITEMS, $items);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Tax\Api\Data\TaxDetailsExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Tax\Api\Data\TaxDetailsExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(\Magento\Tax\Api\Data\TaxDetailsExtensionInterface $extensionAttributes)
+    {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/app/code/Magento/UrlRewrite/Service/V1/Data/UrlRewrite.php b/app/code/Magento/UrlRewrite/Service/V1/Data/UrlRewrite.php
index 517babf6cde83e102b292977fef0d25339a1e59d..6bd75f0bcdff14bf119a145beb1443d42260fb29 100644
--- a/app/code/Magento/UrlRewrite/Service/V1/Data/UrlRewrite.php
+++ b/app/code/Magento/UrlRewrite/Service/V1/Data/UrlRewrite.php
@@ -5,14 +5,12 @@
  */
 namespace Magento\UrlRewrite\Service\V1\Data;
 
-use Magento\Framework\Api\AbstractExtensibleObject;
-use \Magento\Framework\Api\AttributeValueFactory;
-use \Magento\Framework\Api\MetadataServiceInterface;
+use Magento\Framework\Api\AbstractSimpleObject;
 
 /**
  * Data abstract class for url storage
  */
-class UrlRewrite extends AbstractExtensibleObject
+class UrlRewrite extends AbstractSimpleObject
 {
     /**#@+
      * Value object attribute names
@@ -39,22 +37,6 @@ class UrlRewrite extends AbstractExtensibleObject
         self::DESCRIPTION => null,
     ];
 
-    /**
-     * Initialize internal storage
-     *
-     * @param MetadataServiceInterface $metadataService
-     * @param AttributeValueFactory $attributeValueFactory
-     * @param array $data
-     */
-    public function __construct(
-        MetadataServiceInterface $metadataService,
-        AttributeValueFactory $attributeValueFactory,
-        $data = []
-    ) {
-        $data = array_merge($this->defaultValues, $data);
-        parent::__construct($metadataService, $attributeValueFactory, $data);
-    }
-
     /**
      * Get data by key
      *
@@ -124,7 +106,8 @@ class UrlRewrite extends AbstractExtensibleObject
      */
     public function getIsAutogenerated()
     {
-        return $this->_get(self::IS_AUTOGENERATED);
+        return $this->_get(self::IS_AUTOGENERATED) === null ?
+            $this->defaultValues[self::IS_AUTOGENERATED] : $this->_get(self::IS_AUTOGENERATED);
     }
 
     /**
@@ -256,6 +239,6 @@ class UrlRewrite extends AbstractExtensibleObject
      */
     public function toArray()
     {
-        return $this->_data;
+        return array_merge($this->defaultValues, $this->_data);
     }
 }
diff --git a/app/code/Magento/Webapi/Controller/Soap/Request/Handler.php b/app/code/Magento/Webapi/Controller/Soap/Request/Handler.php
index e45d378592f0413d4b10059b84606e16ff5a7cc9..cafdaa8927b9322b72a04cb8055d36cb676b9fa8 100644
--- a/app/code/Magento/Webapi/Controller/Soap/Request/Handler.php
+++ b/app/code/Magento/Webapi/Controller/Soap/Request/Handler.php
@@ -6,6 +6,7 @@
 namespace Magento\Webapi\Controller\Soap\Request;
 
 use Magento\Framework\Api\ExtensibleDataInterface;
+use Magento\Framework\Api\MetadataObjectInterface;
 use Magento\Framework\Api\SimpleDataObjectConverter;
 use Magento\Framework\AuthorizationInterface;
 use Magento\Framework\Exception\AuthorizationException;
@@ -154,7 +155,7 @@ class Handler
         } elseif (is_array($data)) {
             $dataType = substr($dataType, 0, -2);
             foreach ($data as $key => $value) {
-                if ($value instanceof ExtensibleDataInterface) {
+                if ($value instanceof ExtensibleDataInterface || $value instanceof MetadataObjectInterface) {
                     $result[] = $this->_dataObjectConverter
                         ->convertKeysToCamelCase($this->_dataObjectProcessor->buildOutputDataArray($value, $dataType));
                 } else {
diff --git a/app/code/Magento/Webapi/Test/Unit/Controller/RestTest.php b/app/code/Magento/Webapi/Test/Unit/Controller/RestTest.php
index 734a50ea3e2a3b5e0de99fed4c66aea7a41ac936..30a175b6024bfaacf78b4079203ceffb36e2256b 100644
--- a/app/code/Magento/Webapi/Test/Unit/Controller/RestTest.php
+++ b/app/code/Magento/Webapi/Test/Unit/Controller/RestTest.php
@@ -82,7 +82,7 @@ class RestTest extends \PHPUnit_Framework_TestCase
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
     protected $areaMock;
-
+    
     /**
      * @var \Magento\Webapi\Controller\Rest\ParamsOverrider|\PHPUnit_Framework_MockObject_MockObject
      */
diff --git a/app/etc/di.xml b/app/etc/di.xml
index de5633a6639e278c01403d21d01a133394e846b9..fe752e71c22539f98bb5247288575f86ee683aad 100755
--- a/app/etc/di.xml
+++ b/app/etc/di.xml
@@ -82,7 +82,7 @@
     <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\Config\MetadataConfig"/>
+    <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"/>
     <preference for="Magento\Framework\App\Rss\UrlBuilderInterface" type="Magento\Framework\App\Rss\UrlBuilder"/>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/AllSoapAndRest.php b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/AllSoapAndRest.php
index f5f821b4fb2a578ec20c93c4694f417dc0180e55..0c7df325f28d5d13ade1d440364c0f48e4b9e32d 100644
--- a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/AllSoapAndRest.php
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/AllSoapAndRest.php
@@ -5,7 +5,7 @@
  */
 namespace Magento\TestModule1\Service\V1;
 
-use Magento\TestModule1\Service\V1\Entity\CustomAttributeDataObjectFactory;
+use Magento\TestModuleMSC\Model\Data\CustomAttributeDataObjectFactory;
 use Magento\TestModule1\Service\V1\Entity\Item;
 use Magento\TestModule1\Service\V1\Entity\ItemFactory;
 
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeDataObject.php b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeDataObject.php
deleted file mode 100644
index 05c5581b7d1afb01ad5b3a8e61424c1f39656dc9..0000000000000000000000000000000000000000
--- a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeDataObject.php
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-// @codingStandardsIgnoreFile
-
-namespace Magento\TestModule1\Service\V1\Entity;
-
-class CustomAttributeDataObject extends \Magento\Framework\Api\AbstractExtensibleObject
-{
-    /**
-     * @return string
-     */
-    public function getName()
-    {
-        return $this->_data['name'];
-    }
-    /**
-     * @param string $name
-     * @return $this
-     */
-    public function setName($name)
-    {
-        return $this->setData('name', $name);
-    }
-}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeNestedDataObject.php b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeNestedDataObject.php
deleted file mode 100644
index d1ead31be911b0f0895150e7e433cde576ddb8a8..0000000000000000000000000000000000000000
--- a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeNestedDataObject.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-// @codingStandardsIgnoreFile
-
-namespace Magento\TestModule1\Service\V1\Entity;
-
-class CustomAttributeNestedDataObject extends \Magento\Framework\Api\AbstractExtensibleObject
-{
-    /**
-     * @return string
-     */
-    public function getName()
-    {
-        return $this->_data['name'];
-    }
-
-    /**
-     * @param string $name
-     * @return $this
-     */
-    public function setName($name)
-    {
-        return $this->setData('name', $name);
-    }
-}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/Eav/AttributeMetadata.php b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/Eav/AttributeMetadata.php
deleted file mode 100644
index b8a87f3d74056569a1fe6a502c8985cd4148d86b..0000000000000000000000000000000000000000
--- a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/Eav/AttributeMetadata.php
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-// @codingStandardsIgnoreFile
-
-namespace Magento\TestModule1\Service\V1\Entity\Eav;
-
-use Magento\Framework\Api\AbstractExtensibleObject;
-use Magento\Framework\Api\MetadataObjectInterface;
-
-/**
- * Class AttributeMetadata
- */
-class AttributeMetadata extends AbstractExtensibleObject implements MetadataObjectInterface
-{
-    /**#@+
-     * Constants used as keys into $_data
-     */
-    const ATTRIBUTE_ID = 'attribute_id';
-
-    const ATTRIBUTE_CODE = 'attribute_code';
-    /**#@-*/
-
-    /**
-     * Retrieve id of the attribute.
-     *
-     * @return string|null
-     */
-    public function getAttributeId()
-    {
-        return $this->_get(self::ATTRIBUTE_ID);
-    }
-
-    /**
-     * Set id of the attribute.
-     *
-     * @param string $attributeId
-     * @return $this
-     */
-    public function setAttributeId($attributeId)
-    {
-        return $this->setData(self::ATTRIBUTE_ID, $attributeId);
-    }
-
-    /**
-     * Retrieve code of the attribute.
-     *
-     * @return string|null
-     */
-    public function getAttributeCode()
-    {
-        return $this->_get(self::ATTRIBUTE_CODE);
-    }
-
-    /**
-     * Set code of the attribute.
-     *
-     * @param string $attributeCode
-     * @return $this
-     */
-    public function setAttributeCode($attributeCode)
-    {
-        return $this->setData(self::ATTRIBUTE_CODE, $attributeCode);
-    }
-}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/etc/data_object.xml b/dev/tests/api-functional/_files/Magento/TestModule1/etc/data_object.xml
index 19cdbc3710a713062ae5a42677ebf9d551c75e55..de2236e2195f380aedd5614447065bc9e480f7aa 100644
--- a/dev/tests/api-functional/_files/Magento/TestModule1/etc/data_object.xml
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/etc/data_object.xml
@@ -7,11 +7,11 @@
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/Api/etc/data_object.xsd">
     <custom_attributes for="Magento\TestModule1\Service\V1\Entity\Item">
-        <attribute code="custom_attribute_data_object" type="Magento\TestModule1\Service\V1\Entity\CustomAttributeDataObject" />
+        <attribute code="custom_attribute_data_object" type="Magento\TestModuleMSC\Model\Data\CustomAttributeDataObject" />
         <attribute code="custom_attribute_string" type="string" />
     </custom_attributes>
-    <custom_attributes for="Magento\TestModule1\Service\V1\Entity\CustomAttributeDataObject">
-        <attribute code="custom_attribute_nested" type="Magento\TestModule1\Service\V1\Entity\CustomAttributeNestedDataObject" />
+    <custom_attributes for="Magento\TestModuleMSC\Model\Data\CustomAttributeDataObject">
+        <attribute code="custom_attribute_nested" type="Magento\TestModuleMSC\Model\Data\CustomAttributeNestedDataObject" />
         <attribute code="custom_attribute_int" type="int" />
     </custom_attributes>
 </config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/etc/di.xml b/dev/tests/api-functional/_files/Magento/TestModule1/etc/di.xml
index 7ae28455d3a64a1abe6aa319881f0459e486c76e..61cdfb19a09e0b1b59a27663d261969600e6340e 100644
--- a/dev/tests/api-functional/_files/Magento/TestModule1/etc/di.xml
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/etc/di.xml
@@ -11,7 +11,13 @@
 
     <virtualType name="Magento\TestModule1\Service\Config\TestModule1MetadataConfig" type="Magento\Framework\Api\Config\MetadataConfig">
         <arguments>
+            <argument name="attributeMetadataBuilder" xsi:type="object">Magento\TestModuleMSC\Model\Data\Eav\AttributeMetadataBuilder</argument>
             <argument name="dataObjectClassName" xsi:type="string">Magento\TestModule1\Service\V1\Entity\Item</argument>
         </arguments>
     </virtualType>
+    <type name="Magento\TestModule1\Service\V1\Entity\ItemBuilder">
+        <arguments>
+            <argument name="metadataService" xsi:type="object">Magento\TestModule1\Service\Config\TestModule1MetadataConfig</argument>
+        </arguments>
+    </type>
 </config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Entity/WrappedErrorParameter.php b/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Entity/WrappedErrorParameter.php
index c073b4276be0a3e066287c95761ae2aaa8c5c633..a08ea627cfaa7a4eca4ecd4666f372d030ff65da 100644
--- a/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Entity/WrappedErrorParameter.php
+++ b/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Entity/WrappedErrorParameter.php
@@ -21,24 +21,24 @@ class WrappedErrorParameter extends \Magento\Framework\Api\AbstractExtensibleObj
     }
 
     /**
-     * Set field name.
+     * Get value.
      *
-     * @param string $fieldName
-     * @return $this
+     * @return string $value
      */
-    public function setFieldName($fieldName)
+    public function getValue()
     {
-        return $this->setData('field_name', $fieldName);
+        return $this->_data['value'];
     }
 
     /**
-     * Get value.
+     * Set field name.
      *
-     * @return string $value
+     * @param string $fieldName
+     * @return $this
      */
-    public function getValue()
+    public function setFieldName($fieldName)
     {
-        return $this->_data['value'];
+        return $this->setData('field_name', $fieldName);
     }
 
     /**
diff --git a/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/ExtensibleRequest.php b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/ExtensibleRequest.php
index 515e73f3b4aec9a34d7f79cf4c1dc5cbfb49df0f..114f9a9dc9a07533f3db9e334c965eb65621d7ce 100644
--- a/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/ExtensibleRequest.php
+++ b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/ExtensibleRequest.php
@@ -8,6 +8,11 @@
 
 namespace Magento\TestModule4\Service\V1\Entity;
 
+/**
+ * Class ExtensibleRequest
+ *
+ * @method \Magento\TestModule4\Service\V1\Entity\ExtensibleRequestExtensionInterface getExtensionAttributes()
+ */
 class ExtensibleRequest extends \Magento\Framework\Model\AbstractExtensibleModel implements ExtensibleRequestInterface
 {
     public function getName()
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/CustomAttributeDataObject.php b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/CustomAttributeDataObject.php
index 57b9202beba4aa4c5602ecd65e0a4607bab042ff..02e45da759543fdb8b9d94ae95c6020cf0f64abe 100644
--- a/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/CustomAttributeDataObject.php
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/CustomAttributeDataObject.php
@@ -11,6 +11,11 @@ namespace Magento\TestModuleMSC\Model\Data;
 use Magento\TestModuleMSC\Api\Data\CustomAttributeDataObjectInterface;
 use Magento\Framework\Api\AbstractExtensibleObject;
 
+/**
+ * Class CustomAttributeDataObject
+ *
+ * @method \Magento\TestModuleMSC\Api\Data\CustomAttributeDataObjectExtensionInterface getExtensionAttributes()
+ */
 class CustomAttributeDataObject extends AbstractExtensibleObject implements CustomAttributeDataObjectInterface
 {
     /**
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/CustomAttributeNestedDataObject.php b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/CustomAttributeNestedDataObject.php
index e1e7a49a09e2b40b3f05a23173cd320b5b0ddab0..ee683aa1610b713010c1812adaff87ebc3d9e61f 100644
--- a/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/CustomAttributeNestedDataObject.php
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/CustomAttributeNestedDataObject.php
@@ -10,6 +10,11 @@ namespace Magento\TestModuleMSC\Model\Data;
 
 use Magento\TestModuleMSC\Api\Data\CustomAttributeNestedDataObjectInterface;
 
+/**
+ * Class CustomAttributeNestedDataObject
+ *
+ * @method \Magento\TestModuleMSC\Api\Data\CustomAttributeNestedDataObjectExtensionInterface getExtensionAttributes()
+ */
 class CustomAttributeNestedDataObject extends \Magento\Framework\Model\AbstractExtensibleModel implements
     CustomAttributeNestedDataObjectInterface
 {
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/Item.php b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/Item.php
index ff18bed75ef1fd16fe6139cd4aeb4dd60ed92ef0..1d57017fabd42b6b01749771e25db25ef63aff48 100644
--- a/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/Item.php
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/Item.php
@@ -10,6 +10,11 @@ namespace Magento\TestModuleMSC\Model\Data;
 
 use Magento\TestModuleMSC\Api\Data\ItemInterface;
 
+/**
+ * Class Item
+ *
+ * @method \Magento\TestModuleMSC\Api\Data\ItemExtensionInterface getExtensionAttributes()
+ */
 class Item extends \Magento\Framework\Model\AbstractExtensibleModel implements ItemInterface
 {
     /**
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/di.xml b/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/di.xml
index ea1e9ab9bc871215ffbd87448084ba274de9d236..2be26f6ab283284c7b4ffde3c2402473c550201e 100644
--- a/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/di.xml
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/di.xml
@@ -15,6 +15,7 @@
 
     <virtualType name="Magento\TestModuleMSC\Service\Config\TestModuleMSCMetadataConfig" type="Magento\Framework\Api\Config\MetadataConfig">
         <arguments>
+            <argument name="attributeMetadataBuilder" xsi:type="object">Magento\TestModuleMSC\Model\Data\Eav\AttributeMetadataBuilder</argument>
             <argument name="dataObjectClassName" xsi:type="string">Magento\TestModuleMSC\Model\Data\Item</argument>
         </arguments>
     </virtualType>
diff --git a/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductServiceTest.php
index d995829a1ec31fdc1531af60a738ba8051e4fbd2..1a817b18d3b593df2cbbef8280a42e40f0d5b84c 100644
--- a/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductServiceTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductServiceTest.php
@@ -7,7 +7,7 @@
 namespace Magento\Bundle\Api;
 
 use Magento\Catalog\Api\Data\ProductInterface;
-use Magento\Framework\Api\AbstractExtensibleObject;
+use Magento\Framework\Api\ExtensibleDataInterface;
 use Magento\TestFramework\Helper\Bootstrap;
 use Magento\TestFramework\TestCase\WebapiAbstract;
 
@@ -63,17 +63,17 @@ class ProductServiceTest extends WebapiAbstract
     {
         $this->markTestSkipped('Processing of custom attributes has been changed in MAGETWO-34448.');
         $bundleProductOptions = [
-            "attribute_code" => "bundle_product_options",
-            "value" => [
-                [
-                    "title" => "test option",
-                    "type" => "checkbox",
-                    "required" => 1,
-                    "product_links" => [
-                        [
-                            "sku" => 'simple',
-                            "qty" => 1,
-                        ],
+            [
+                "title" => "test option",
+                "type" => "checkbox",
+                "required" => true,
+                "product_links" => [
+                    [
+                        "sku" => 'simple',
+                        "qty" => 1,
+                        'is_default' => false,
+                        'price' => 1.0,
+                        'price_type' => 1
                     ],
                 ],
             ],
@@ -86,36 +86,25 @@ class ProductServiceTest extends WebapiAbstract
             "type_id" => "bundle",
             "price" => 50,
             'attribute_set_id' => 4,
-            "custom_attributes" => [
-                "price_type" => [
-                    'attribute_code' => 'price_type',
-                    'value' => \Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC
-                ],
+            "extension_attributes" => [
+                "price_type" => \Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC,
                 "bundle_product_options" => $bundleProductOptions,
-                "price_view" => [
-                    "attribute_code" => "price_view",
-                    "value" => "test",
-                ],
+                "price_view" => "test"
             ],
         ];
 
         $response = $this->createProduct($product);
 
         $this->assertEquals($uniqueId, $response[ProductInterface::SKU]);
-        $this->assertEquals(
-            $bundleProductOptions,
-            $response[AbstractExtensibleObject::CUSTOM_ATTRIBUTES_KEY]["bundle_product_options"]
-        );
+        $resultBundleProductOptions
+            = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["bundle_product_options"];
+        $this->assertEquals($bundleProductOptions, $resultBundleProductOptions);
+        $this->assertEquals('simple', $resultBundleProductOptions[0]["product_links"][0]["sku"]);
 
         $response = $this->getProduct($uniqueId);
-        $foundBundleProductOptions = false;
-        foreach ($response[AbstractExtensibleObject::CUSTOM_ATTRIBUTES_KEY] as $customAttribute) {
-            if ($customAttribute["attribute_code"] === 'bundle_product_options') {
-                $this->assertEquals('simple', $customAttribute["value"][0]["product_links"][0]["sku"]);
-                $foundBundleProductOptions = true;
-            }
-        }
-        $this->assertTrue($foundBundleProductOptions);
+        $resultBundleProductOptions
+            = $response[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]["bundle_product_options"];
+        $this->assertEquals('simple', $resultBundleProductOptions[0]["product_links"][0]["sku"]);
     }
 
     /**
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryAttributeOptionManagementInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryAttributeOptionManagementInterfaceTest.php
index 61a54a548800a4e33b8c5710d63de95a4af30b87..345f76e3d923aade74604d952acc321c1e79c446 100644
--- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryAttributeOptionManagementInterfaceTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryAttributeOptionManagementInterfaceTest.php
@@ -15,6 +15,7 @@ class CategoryAttributeOptionManagementInterfaceTest extends WebapiAbstract
 
     public function testGetItems()
     {
+        $this->_markTestAsRestOnly('Fix inconsistencies in WSDL and Data interfaces');
         $testAttributeCode = 'include_in_menu';
         $expectedOptions = [
             [
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionManagementInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionManagementInterfaceTest.php
index adc93f12c15337ab3a992586e3bae06bcb0b8a3a..2e31bec6182ee8d142cab94e7bc18eb3e49d9354 100644
--- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionManagementInterfaceTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionManagementInterfaceTest.php
@@ -17,6 +17,7 @@ class ProductAttributeOptionManagementInterfaceTest extends WebapiAbstract
 
     public function testGetItems()
     {
+        $this->_markTestAsRestOnly('Fix inconsistencies in WSDL and Data interfaces');
         $testAttributeCode = 'quantity_and_stock_status';
         $expectedOptions = [
             [
@@ -52,6 +53,7 @@ class ProductAttributeOptionManagementInterfaceTest extends WebapiAbstract
      */
     public function testAdd()
     {
+        $this->_markTestAsRestOnly('Fix inconsistencies in WSDL and Data interfaces');
         $testAttributeCode = 'select_attribute';
         $serviceInfo = [
             'rest' => [
@@ -100,6 +102,7 @@ class ProductAttributeOptionManagementInterfaceTest extends WebapiAbstract
      */
     public function testDelete()
     {
+        $this->_markTestAsRestOnly('Fix inconsistencies in WSDL and Data interfaces');
         $attributeCode = 'select_attribute';
         //get option Id
         $optionList = $this->getAttributeOptions($attributeCode);
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php
index be4f82898a333e6dfda170dae9b46c1efbfb43d4..1ddf12ceb1bb39315bb2155415d39eaee067aaa4 100644
--- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php
@@ -101,6 +101,7 @@ class ProductCustomOptionRepositoryTest extends WebapiAbstract
      */
     public function testGetList()
     {
+        $this->_markTestAsRestOnly('Fix inconsistencies in WSDL and Data interfaces');
         $productSku = 'simple';
         $serviceInfo = [
             'rest' => [
diff --git a/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkManagementTest.php b/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkManagementTest.php
index 6215e0c519275efa260a5d8ca3824063f75af34d..10e6d6f41ed029f84d9aab099da6cf27c462a736 100644
--- a/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkManagementTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkManagementTest.php
@@ -55,14 +55,14 @@ class ProductLinkManagementTest extends \Magento\TestFramework\TestCase\WebapiAb
             array_walk(
                 $expected,
                 function (&$item) {
-                    $item['custom_attributes'] = [['attribute_code' => 'qty', 'value' => 1.0000]];
+                    $item['extension_attributes'] = ['qty' => 1.0000];
                 }
             );
         } else {
             array_walk(
                 $expected,
                 function (&$item) {
-                    $item['custom_attributes'] = [['attribute_code' => 'qty', 'value' => 1.0000]];
+                    $item['extension_attributes'] = ['qty' => 1.0000];
                 }
             );
         }
diff --git a/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkRepositoryTest.php
index 4d375e84e39e9fadfea209c33cd29a5a9ef54d5b..69b1ef5073b6169102748462104bade23fc22017 100644
--- a/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkRepositoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkRepositoryTest.php
@@ -37,8 +37,8 @@ class ProductLinkRepositoryTest extends \Magento\TestFramework\TestCase\WebapiAb
             'linked_product_type' => 'simple',
             'linked_product_sku' => 'simple',
             'position' => 3,
-            'custom_attributes' => [
-                'qty' => ['attribute_code' => 'qty', 'value' => (float) 300.0000],
+            'extension_attributes' => [
+                'qty' =>  (float) 300.0000,
             ],
         ];
 
@@ -55,7 +55,7 @@ class ProductLinkRepositoryTest extends \Magento\TestFramework\TestCase\WebapiAb
         ];
         $this->_webApiCall($serviceInfo, ['entity' => $productData]);
 
-        /** @var \Magento\Catalog\Model\ProductLink\Management $linkManagement */
+        /** @var \Magento\Catalog\Api\ProductLinkManagementInterface $linkManagement */
         $linkManagement = $this->objectManager->get('Magento\Catalog\Api\ProductLinkManagementInterface');
         $actual = $linkManagement->getLinkedItemsByType($productSku, $linkType);
         array_walk($actual, function (&$item) {
diff --git a/dev/tests/integration/etc/install-config-mysql.php.dist b/dev/tests/integration/etc/install-config-mysql.php.dist
index 391e1a7679b00c152b165b379be8bd5d9ea508bb..0f5adb4727c5fecff8c195f6c70d25fb7b0cee0a 100644
--- a/dev/tests/integration/etc/install-config-mysql.php.dist
+++ b/dev/tests/integration/etc/install-config-mysql.php.dist
@@ -7,7 +7,7 @@
 return [
     'db_host' => 'localhost',
     'db_user' => 'root',
-    'db_pass' => '',
+    'db_pass' => 'root',
     'db_name' => 'magento_integration_tests',
     'db_prefix' => '',
     'backend_frontname' => 'backend',
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/AbstractModel/Stub.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/AbstractModel/Stub.php
new file mode 100644
index 0000000000000000000000000000000000000000..ced9dd4c1ea77bb044f74242c28323cec1643212
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/AbstractModel/Stub.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Catalog\Model\AbstractModel;
+
+abstract class Stub extends \Magento\Catalog\Model\AbstractModel implements \Magento\Catalog\Api\Data\ProductInterface
+{
+    /**
+     * Retrieve Store Id
+     *
+     * @return int
+     */
+    public function getStoreId()
+    {
+        return $this->getData(self::STORE_ID);
+    }
+
+    /**
+     * Set product store id
+     *
+     * @param int $storeId
+     * @return $this
+     */
+    public function setStoreId($storeId)
+    {
+        return $this->setData(self::STORE_ID, $storeId);
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/AbstractTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/AbstractTest.php
index b45e05df43559ce9e92d08809fc1995cda7397cf..026e4f09722cc31c062dca66bef7e01c1a063a23 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/AbstractTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/AbstractTest.php
@@ -27,7 +27,7 @@ class AbstractTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         if (!self::$_isStubClass) {
-            $this->getMockForAbstractClass('Magento\Catalog\Model\AbstractModel', [], self::STUB_CLASS, false);
+            $this->getMockForAbstractClass('Magento\Catalog\Model\AbstractModel\Stub', [], self::STUB_CLASS, false);
             self::$_isStubClass = true;
         }
 
diff --git a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Model/CategoryUrlRewriteGeneratorTest.php b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Model/CategoryUrlRewriteGeneratorTest.php
index 9b3387532ab4dc6a1d31a59c03aa62fe4b1413b0..c3f988bad63fce6660fa13c90fbfc605e73911df 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Model/CategoryUrlRewriteGeneratorTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Model/CategoryUrlRewriteGeneratorTest.php
@@ -25,9 +25,17 @@ class CategoryUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
         $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
     }
 
+    public function tearDown()
+    {
+        $category = $this->objectManager->create('Magento\Catalog\Model\Category');
+        $category->load(3);
+        $category->delete();
+    }
+
     /**
      * @magentoDataFixture Magento/CatalogUrlRewrite/_files/categories.php
      * @magentoDbIsolation enabled
+     * @magentoAppIsolation enabled
      */
     public function testGenerateUrlRewritesWithoutSaveHistory()
     {
@@ -53,9 +61,9 @@ class CategoryUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * @magentoDataFixture Magento/CatalogUrlRewrite/_files/categories.php
      * @magentoDbIsolation enabled
-     *
+     * @magentoDataFixture Magento/CatalogUrlRewrite/_files/categories.php
+     * @magentoAppIsolation enabled
      */
     public function testGenerateUrlRewritesWithSaveHistory()
     {
@@ -101,7 +109,7 @@ class CategoryUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
             $actualResults[] = [
                 $url->getRequestPath(),
                 $url->getTargetPath(),
-                $url->getIsAutogenerated(),
+                (int)$url->getIsAutogenerated(),
                 $url->getRedirectType()
             ];
         }
@@ -114,8 +122,12 @@ class CategoryUrlRewriteGeneratorTest extends \PHPUnit_Framework_TestCase
      */
     protected function assertResults($expected, $actual)
     {
-        foreach ($actual as $row) {
-            $this->assertContains($row, $expected, implode(', ', $row));
+        foreach ($expected as $row) {
+            $this->assertContains(
+                $row,
+                $actual,
+                'Expected: ' . var_export($row, true) . "\nIn Actual: " . var_export($actual, true)
+            );
         }
 
     }
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/AddressMetadataTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/AddressMetadataTest.php
index 9f77693988cab1d85a44186e2c696778e759951c..1b9ad064466529226a1751f4a7c359931f6a1abd 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Model/AddressMetadataTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Model/AddressMetadataTest.php
@@ -31,18 +31,7 @@ class AddressMetadataTest extends \PHPUnit_Framework_TestCase
     public function testGetCustomAttributesMetadata()
     {
         $customAttributesMetadata = $this->_service->getCustomAttributesMetadata();
-        $this->assertCount(2, $customAttributesMetadata, "Invalid number of attributes returned.");
-        $configAttributeCode = 'address_attribute_1';
-        $configAttributeFound = false;
-        foreach ($customAttributesMetadata as $attribute) {
-            if ($attribute->getAttributeCode() == $configAttributeCode) {
-                $configAttributeFound = true;
-                break;
-            }
-        }
-        if (!$configAttributeFound) {
-            $this->fail("Custom attribute declared in the config not found.");
-        }
+        $this->assertCount(0, $customAttributesMetadata, "Invalid number of attributes returned.");
     }
 
     /**
@@ -69,7 +58,7 @@ class AddressMetadataTest extends \PHPUnit_Framework_TestCase
         if (!$customAttributesFound) {
             $this->fail("Custom attributes declared in the config not found.");
         }
-        $this->assertCount(4, $customAttributesMetadata, "Invalid number of attributes returned.");
+        $this->assertCount(2, $customAttributesMetadata, "Invalid number of attributes returned.");
     }
 
     public function testGetAddressAttributeMetadata()
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/CustomerMetadataTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/CustomerMetadataTest.php
index b18d1c2b598e8dce4af38fdbbe87ece1a0a9517b..672e0e17c6cc424819ec36046829e9e193e58fa7 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Model/CustomerMetadataTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Model/CustomerMetadataTest.php
@@ -47,18 +47,7 @@ class CustomerMetadataTest extends \PHPUnit_Framework_TestCase
     public function testGetCustomAttributesMetadata()
     {
         $customAttributesMetadata = $this->_service->getCustomAttributesMetadata();
-        $this->assertCount(3, $customAttributesMetadata, "Invalid number of attributes returned.");
-        $configAttributeCode = 'customer_attribute_1';
-        $configAttributeFound = false;
-        foreach ($customAttributesMetadata as $attribute) {
-            if ($attribute->getAttributeCode() == $configAttributeCode) {
-                $configAttributeFound = true;
-                break;
-            }
-        }
-        if (!$configAttributeFound) {
-            $this->fail("Custom attribute declared in the config not found.");
-        }
+        $this->assertCount(1, $customAttributesMetadata, "Invalid number of attributes returned.");
     }
 
     public function testGetNestedOptionsCustomAttributesMetadata()
@@ -104,7 +93,7 @@ class CustomerMetadataTest extends \PHPUnit_Framework_TestCase
         if (!$customAttributesFound) {
             $this->fail("Custom attributes declared in the config not found.");
         }
-        $this->assertCount(5, $customAttributesMetadata, "Invalid number of attributes returned.");
+        $this->assertCount(3, $customAttributesMetadata, "Invalid number of attributes returned.");
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Api/AbstractExtensibleObjectTest.php b/dev/tests/integration/testsuite/Magento/Framework/Api/AbstractExtensibleObjectTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..dd5fba5c4d60d9740bd931dffe0d5e208a883fa2
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Framework/Api/AbstractExtensibleObjectTest.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Api;
+
+/**
+ * Test for \Magento\Framework\Api\AbstractExtensibleObject
+ */
+class AbstractExtensibleObjectTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Framework\ObjectManagerInterface */
+    private $_objectManager;
+
+    protected function setUp()
+    {
+        $autoloadWrapper = \Magento\Framework\Autoload\AutoloaderRegistry::getAutoloader();
+        $autoloadWrapper->addPsr4('Magento\\Wonderland\\', realpath(__DIR__ . '/_files/Magento/Wonderland'));
+        $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->_objectManager->configure(
+            [
+                'preferences' => [
+                    'Magento\Wonderland\Api\Data\FakeAddressInterface' => 'Magento\Wonderland\Model\FakeAddress',
+                    'Magento\Wonderland\Api\Data\FakeRegionInterface' => 'Magento\Wonderland\Model\FakeRegion',
+                ],
+            ]
+        );
+    }
+
+    /**
+     * Test setExtensionAttributes and getExtensionAttributes for \Magento\Framework\Api\AbstractExtensibleObject
+     *
+     * @param array $expectedDataBefore
+     * @param array $expectedDataAfter
+     * @dataProvider extensionAttributesDataProvider
+     */
+    public function testExtensionAttributes($expectedDataBefore, $expectedDataAfter)
+    {
+        /** @var \Magento\Framework\Api\ExtensionAttributesFactory $regionExtensionFactory */
+        $regionExtensionFactory = $this->_objectManager->get('Magento\Framework\Api\ExtensionAttributesFactory');
+        /** @var \Magento\Wonderland\Model\Data\FakeRegionFactory $regionFactory */
+        $regionFactory = $this->_objectManager->get('Magento\Wonderland\Model\Data\FakeRegionFactory');
+
+        /** @var \Magento\Wonderland\Model\Data\FakeRegion $region */
+        $region = $regionFactory->create();
+
+        $regionCode = 'test_code';
+        /** @var \Magento\Wonderland\Model\Data\FakeRegionExtensionInterface $regionExtension */
+        $regionExtension = $regionExtensionFactory->create(
+            'Magento\Wonderland\Model\Data\FakeRegion',
+            ['data' => $expectedDataBefore]
+        );
+        $region->setRegionCode($regionCode)->setExtensionAttributes($regionExtension);
+        $this->assertInstanceOf('Magento\Wonderland\Model\Data\FakeRegion', $region);
+
+        $extensionAttributes = $region->getExtensionAttributes();
+        $this->assertInstanceOf('Magento\Wonderland\Api\Data\FakeRegionExtension', $extensionAttributes);
+        $this->assertEquals($expectedDataBefore, $extensionAttributes->__toArray());
+        $this->assertEquals($regionCode, $region->getRegionCode());
+
+        $regionCode = 'changed_test_code';
+        $region->setExtensionAttributes(
+            $regionExtensionFactory->create('Magento\Wonderland\Model\Data\FakeRegion', ['data' => $expectedDataAfter])
+        )->setRegionCode($regionCode); // change $regionCode to test AbstractExtensibleObject::setData
+        $extensionAttributes = $region->getExtensionAttributes();
+        $this->assertEquals($expectedDataAfter, $extensionAttributes->__toArray());
+        $this->assertEquals($regionCode, $region->getRegionCode());
+    }
+
+    public function extensionAttributesDataProvider()
+    {
+        return [
+            'boolean' => [
+                [true],
+                [false]
+            ],
+            'integer' => [
+                [1],
+                [2]
+            ],
+            'string' => [
+                ['test'],
+                ['test test']
+            ],
+            'array' => [
+                [[1]],
+                [[1, 2]]
+            ]
+        ];
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Api/ExtensionAttributesFactoryTest.php b/dev/tests/integration/testsuite/Magento/Framework/Api/ExtensionAttributesFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2c6ddf42f67cbbfc9edb55330c4ae09f387807ae
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Framework/Api/ExtensionAttributesFactoryTest.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Api;
+
+class ExtensionAttributesFactoryTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Framework\Api\ExtensionAttributesFactory */
+    private $factory;
+
+    protected function setUp()
+    {
+        $autoloadWrapper = \Magento\Framework\Autoload\AutoloaderRegistry::getAutoloader();
+        $autoloadWrapper->addPsr4('Magento\\Wonderland\\', realpath(__DIR__ . '/_files/Magento/Wonderland'));
+        /** @var \Magento\Framework\ObjectManagerInterface */
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->factory = new ExtensionAttributesFactory($objectManager);
+    }
+
+    /**
+     * @expectedException \LogicException
+     */
+    public function testCreateThrowExceptionIfInterfaceNotImplemented()
+    {
+        $this->factory->create('Magento\Framework\Api\ExtensionAttributesFactoryTest');
+    }
+
+    /**
+     * @expectedException \LogicException
+     */
+    public function testCreateThrowExceptionIfInterfaceNotOverridden()
+    {
+        $this->factory->create('\Magento\Wonderland\Model\Data\FakeExtensibleOne');
+    }
+
+    /**
+     * @expectedException \LogicException
+     */
+    public function testCreateThrowExceptionIfReturnIsIncorrect()
+    {
+        $this->factory->create('\Magento\Wonderland\Model\Data\FakeExtensibleTwo');
+    }
+
+    public function testCreate()
+    {
+        $this->assertInstanceOf(
+            'Magento\Wonderland\Api\Data\FakeRegionExtension',
+            $this->factory->create('Magento\Wonderland\Model\Data\FakeRegion')
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Api/Data/FakeAddressInterface.php b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Api/Data/FakeAddressInterface.php
index 597a30cc1de907d7eeb1f193ef97716b0568bdfd..8377ec40155785df4aeb482bc867d43cf2763224 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Api/Data/FakeAddressInterface.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Api/Data/FakeAddressInterface.php
@@ -170,4 +170,21 @@ interface FakeAddressInterface extends ExtensibleDataInterface
      * @return bool|null
      */
     public function isDefaultBilling();
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Wonderland\Api\Data\FakeAddressExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Wonderland\Api\Data\FakeAddressExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Wonderland\Api\Data\FakeAddressExtensionInterface $extensionAttributes
+    );
 }
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Api/Data/FakeExtensibleOneInterface.php b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Api/Data/FakeExtensibleOneInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..fdf9d49a67c3fe67503ec23dda9fa8742c0d291f
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Api/Data/FakeExtensibleOneInterface.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Wonderland\Api\Data;
+
+use Magento\Framework\Api\ExtensibleDataInterface;
+
+/**
+ * Fake interface
+ * to test exception if the method 'getExtensionAttributes' is not overridden
+ */
+interface FakeExtensibleOneInterface extends ExtensibleDataInterface
+{
+}
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Api/Data/FakeExtensibleTwoInterface.php b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Api/Data/FakeExtensibleTwoInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..42f212c861474c3e66595458473d7227470fad7e
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Api/Data/FakeExtensibleTwoInterface.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Wonderland\Api\Data;
+
+use Magento\Framework\Api\ExtensibleDataInterface;
+
+/**
+ * Fake interface
+ * to test exception if the method 'getExtensionAttributes' does not return concrete type
+ */
+interface FakeExtensibleTwoInterface extends ExtensibleDataInterface
+{
+    /**
+     * test incorrect return type
+     *
+     * @return int
+     */
+    public function getExtensionAttributes();
+}
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Api/Data/FakeRegionInterface.php b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Api/Data/FakeRegionInterface.php
index ce54b0484b530f1fdbd47753002b556fe2d841a0..76cb08b2395f8a5d5d8848ccce74302de8822dee 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Api/Data/FakeRegionInterface.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Api/Data/FakeRegionInterface.php
@@ -41,4 +41,21 @@ interface FakeRegionInterface extends ExtensibleDataInterface
      * @return int
      */
     public function getRegionId();
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Wonderland\Api\Data\FakeRegionExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Wonderland\Api\Data\FakeRegionExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Wonderland\Api\Data\FakeRegionExtensionInterface $extensionAttributes
+    );
 }
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/Data/FakeAddress.php b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/Data/FakeAddress.php
index 0070597fa58bd402876514caf99ffbe6d933d91d..98407fcebb8f2a30cfb3c3f5a1de9c1f6710dc98 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/Data/FakeAddress.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/Data/FakeAddress.php
@@ -7,31 +7,10 @@
 namespace Magento\Wonderland\Model\Data;
 
 use Magento\Framework\Api\AbstractExtensibleObject;
+use Magento\Wonderland\Api\Data\FakeAddressInterface;
 
-class FakeAddress extends AbstractExtensibleObject
+class FakeAddress extends AbstractExtensibleObject implements FakeAddressInterface
 {
-    /**#@+
-     * Constants for keys of data array
-     */
-    const ID = 'id';
-    const CUSTOMER_ID = 'customer_id';
-    const REGION = 'region';
-    const REGIONS = 'regions';
-    const COUNTRY_ID = 'country_id';
-    const STREET = 'street';
-    const COMPANY = 'company';
-    const TELEPHONE = 'telephone';
-    const FAX = 'fax';
-    const POSTCODE = 'postcode';
-    const CITY = 'city';
-    const FIRSTNAME = 'firstname';
-    const LASTNAME = 'lastname';
-    const MIDDLENAME = 'middlename';
-    const PREFIX = 'prefix';
-    const SUFFIX = 'suffix';
-    const VAT_ID = 'vat_id';
-    /**#@-*/
-
     /**
      * Get ID
      *
@@ -201,4 +180,46 @@ class FakeAddress extends AbstractExtensibleObject
     {
         return $this->_get(self::VAT_ID);
     }
+
+    /**
+     * Get if this address is default shipping address.
+     *
+     * @return bool|null
+     */
+    public function isDefaultShipping()
+    {
+        return $this->_get(self::DEFAULT_SHIPPING);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Wonderland\Api\Data\FakeAddressExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * Get if this address is default billing address
+     *
+     * @return bool|null
+     */
+    public function isDefaultBilling()
+    {
+        return $this->_get(self::DEFAULT_BILLING);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Wonderland\Api\Data\FakeAddressExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Wonderland\Api\Data\FakeAddressExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/Data/FakeExtensibleOne.php b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/Data/FakeExtensibleOne.php
new file mode 100644
index 0000000000000000000000000000000000000000..536aeb9343dce89989d2662b2bbe4ca85a2292a7
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/Data/FakeExtensibleOne.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Wonderland\Model\Data;
+
+use Magento\Wonderland\Api\Data\FakeExtensibleOneInterface;
+
+class FakeExtensibleOne implements FakeExtensibleOneInterface
+{
+}
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/Data/FakeExtensibleTwo.php b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/Data/FakeExtensibleTwo.php
new file mode 100644
index 0000000000000000000000000000000000000000..47c95a12b83c510ed50c72e99ef0738b0700a1e6
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/Data/FakeExtensibleTwo.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Wonderland\Model\Data;
+
+use Magento\Framework\Api\AbstractExtensibleObject;
+use Magento\Wonderland\Api\Data\FakeExtensibleTwoInterface;
+
+class FakeExtensibleTwo extends AbstractExtensibleObject implements FakeExtensibleTwoInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/Data/FakeRegion.php b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/Data/FakeRegion.php
index e6dad7fd79fc310c8298feb90420d8967e6aef88..cef747dcbdd1ceed0f357b680352921136420074 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/Data/FakeRegion.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/Data/FakeRegion.php
@@ -8,16 +8,8 @@ namespace Magento\Wonderland\Model\Data;
 
 use Magento\Framework\Api\AbstractExtensibleObject;
 
-class FakeRegion extends AbstractExtensibleObject
+class FakeRegion extends AbstractExtensibleObject implements \Magento\Wonderland\Api\Data\FakeRegionInterface
 {
-    /**#@+
-     * Constants for keys of data array
-     */
-    const REGION_CODE = 'region_code';
-    const REGION = 'region';
-    const REGION_ID = 'region_id';
-    /**#@-*/
-
     /**
      * Get region
      *
@@ -47,4 +39,37 @@ class FakeRegion extends AbstractExtensibleObject
     {
         return $this->_get(self::REGION_ID);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Wonderland\Api\Data\FakeRegionExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Wonderland\Api\Data\FakeRegionExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Wonderland\Api\Data\FakeRegionExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
+
+    /**
+     * Set region code
+     *
+     * @param string $regionCode
+     * @return $this
+     */
+    public function setRegionCode($regionCode)
+    {
+        return $this->setData(self::REGION_CODE, $regionCode);
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/FakeAddress.php b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/FakeAddress.php
index 67db23b4f055b8fe778b480aa281aba05b789281..f98e3f5051c31b4c47b1dcdf07fcc4718a0022f4 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/FakeAddress.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/FakeAddress.php
@@ -200,4 +200,26 @@ class FakeAddress extends AbstractExtensibleModel implements FakeAddressInterfac
     {
         return $this->getData(self::DEFAULT_BILLING);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Wonderland\Api\Data\FakeAddressExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Wonderland\Api\Data\FakeAddressExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Wonderland\Api\Data\FakeAddressExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/FakeRegion.php b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/FakeRegion.php
index 9074d3fcf36feeeacb19e65302378424cc6e342a..7527cde11534a301cfb6ae6e0e7ccd306c96ceb1 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/FakeRegion.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/FakeRegion.php
@@ -40,4 +40,26 @@ class FakeRegion extends AbstractExtensibleModel implements FakeRegionInterface
     {
         return $this->getData(self::REGION_ID);
     }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return \Magento\Wonderland\Api\Data\FakeRegionExtensionInterface|null
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @param \Magento\Wonderland\Api\Data\FakeRegionExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\Wonderland\Api\Data\FakeRegionExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Code/GeneratorTest.php b/dev/tests/integration/testsuite/Magento/Framework/Code/GeneratorTest.php
index 943cc88e8f697eb55bec4754f01742945853dfd2..e31201caf943440ce75a00725b65c79cde471c29 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Code/GeneratorTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Code/GeneratorTest.php
@@ -39,7 +39,8 @@ class GeneratorTest extends \PHPUnit_Framework_TestCase
 
     protected function setUp()
     {
-        $this->varDirectory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->varDirectory = $objectManager->get(
             'Magento\Framework\Filesystem'
         )->getDirectoryWrite(
             DirectoryList::VAR_DIR
@@ -49,7 +50,7 @@ class GeneratorTest extends \PHPUnit_Framework_TestCase
             new \Magento\Framework\Filesystem\Driver\File(),
             $generationDirectory
         );
-        $this->_generator = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+        $this->_generator = $objectManager->create(
             'Magento\Framework\Code\Generator',
             [
                 'ioObject' => $this->_ioObject,
@@ -61,6 +62,7 @@ class GeneratorTest extends \PHPUnit_Framework_TestCase
                 ]
             ]
         );
+        $this->_generator->setObjectManager($objectManager);
     }
 
     protected function tearDown()
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxCalculationTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxCalculationTest.php
index 76d788a77dd462d2f5b735671de16eedc46a3b0a..0c3af306bdeaa8f70d4a0b9e3e0d4bda252693e1 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxCalculationTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxCalculationTest.php
@@ -1951,12 +1951,18 @@ class TaxCalculationTest extends \PHPUnit_Framework_TestCase
      *
      * This utility function is used to simplify expected result verification.
      *
-     * @param AbstractExtensibleModel $object
+     * @param \Magento\Framework\Object $object
      * @return array
      */
-    private function convertObjectToArray(AbstractExtensibleModel $object)
+    private function convertObjectToArray($object)
     {
-        $data = $object->getData();
+        if ($object instanceof \Magento\Framework\Object) {
+            $data = $object->getData();
+        } else if (is_object($object)) {
+            $data = (array)$object;
+        } else {
+            throw new \InvalidArgumentException("Provided argument is not an object.");
+        }
         foreach ($data as $key => $value) {
             if (is_object($value)) {
                 $data[$key] = $this->convertObjectToArray($value);
diff --git a/dev/tests/static/framework/autoload.php b/dev/tests/static/framework/autoload.php
index cb9a10bb9d057575ecf1a2af821030e4136899fa..17e643a9f9a3b821ae529713ab5bbec84f250fb0 100644
--- a/dev/tests/static/framework/autoload.php
+++ b/dev/tests/static/framework/autoload.php
@@ -4,9 +4,10 @@
  * See COPYING.txt for license details.
  */
 
-require __DIR__ . '/../../../../app/autoload.php';
-$testsBaseDir = realpath(__DIR__ . '/../');
-
+$baseDir = realpath(__DIR__ . '/../../../../');
+require $baseDir . '/app/autoload.php';
+$testsBaseDir = $baseDir . '/dev/tests/static';
 $autoloadWrapper = \Magento\Framework\Autoload\AutoloaderRegistry::getAutoloader();
 $autoloadWrapper->addPsr4('Magento\\', $testsBaseDir . '/testsuite/Magento/');
 $autoloadWrapper->addPsr4('Magento\\TestFramework\\', $testsBaseDir . '/framework/Magento/TestFramework/');
+$autoloadWrapper->addPsr4('Magento\\', $baseDir . '/var/generation/Magento/');
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Di/CompilerTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Di/CompilerTest.php
index 2a90df9b592c34aec24ec7cc96ae639fb53b0738..493f1310e380c6e586ca25d5afc032c727cbd891 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/Di/CompilerTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Di/CompilerTest.php
@@ -12,7 +12,8 @@ use Magento\Framework\Api\Code\Generator\SearchResults;
 use Magento\Framework\ObjectManager\Code\Generator\Converter;
 use Magento\Framework\ObjectManager\Code\Generator\Factory;
 use Magento\Framework\ObjectManager\Code\Generator\Repository;
-use Magento\Framework\Api\Code\Generator\ObjectExtensionInterface;
+use Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator;
+use Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -319,8 +320,10 @@ class CompilerTest extends \PHPUnit_Framework_TestCase
                 Converter::ENTITY_TYPE => 'Magento\Framework\ObjectManager\Code\Generator\Converter',
                 Mapper::ENTITY_TYPE => 'Magento\Framework\Api\Code\Generator\Mapper',
                 SearchResults::ENTITY_TYPE => 'Magento\Framework\Api\Code\Generator\SearchResults',
-                ObjectExtensionInterface::ENTITY_TYPE =>
-                    'Magento\Framework\Api\Code\Generator\ObjectExtensionInterface'
+                ExtensionAttributesInterfaceGenerator::ENTITY_TYPE =>
+                    'Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator',
+                ExtensionAttributesGenerator::ENTITY_TYPE =>
+                    'Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator'
             ]
         );
         $generationAutoloader = new \Magento\Framework\Code\Generator\Autoloader($generator);
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Api/ExtensibleInterfacesTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Api/ExtensibleInterfacesTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e25f22a20e9d192e6c44c34b1d31402204c439a8
--- /dev/null
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Api/ExtensibleInterfacesTest.php
@@ -0,0 +1,265 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Test\Integrity\Magento\Framework\Api;
+
+use Magento\Framework\App\Utility\Files;
+
+/**
+ * Check interfaces inherited from \Magento\Framework\Api\ExtensibleDataInterface.
+ *
+ * Ensure that all interfaces inherited from \Magento\Framework\Api\ExtensibleDataInterface
+ * override getExtensionAttributes() method and have correct return type specified.
+ */
+class ExtensibleInterfacesTest extends \PHPUnit_Framework_TestCase
+{
+    const EXTENSIBLE_DATA_INTERFACE = 'Magento\\Framework\\Api\\ExtensibleDataInterface';
+
+    /**
+     * Check return types of getExtensionAttributes() methods.
+     */
+    public function testGetSetExtensionAttributes()
+    {
+        $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this);
+        $invoker(
+        /**
+         * @param string $filename
+         */
+            function ($filename) {
+                $errors = [];
+                $fileContent = file_get_contents($filename);
+                $extendsFromExtensibleDataInterface = preg_match(
+                    '/' . str_replace('\\', '\\\\', self::EXTENSIBLE_DATA_INTERFACE) . '/',
+                    $fileContent
+                );
+                if ($extendsFromExtensibleDataInterface
+                    && preg_match('/namespace ([\w\\\\]+).*interface ([\w\\\\]+)/s', $fileContent, $matches)
+                ) {
+                    $namespace = $matches[1];
+                    $interfaceName = $matches[2];
+                    $fullInterfaceName = '\\' . $namespace . '\\' . $interfaceName;
+                    $interfaceReflection = new \ReflectionClass($fullInterfaceName);
+                    if ($interfaceReflection->isSubclassOf(self::EXTENSIBLE_DATA_INTERFACE)) {
+                        $interfaceName = '\\' . $interfaceReflection->getName();
+                        $extensionClassName = substr($interfaceName, 0, -strlen('Interface')) . 'Extension';
+                        $extensionInterfaceName = $extensionClassName . 'Interface';
+
+                        /** Check getExtensionAttributes method */
+                        $errors = $this->checkGetExtensionAttributes(
+                            $interfaceReflection,
+                            $extensionInterfaceName,
+                            $fullInterfaceName
+                        );
+
+                        /** Check setExtensionAttributes method */
+                        $errors = array_merge(
+                            $errors,
+                            $this->checkSetExtensionAttributes(
+                                $interfaceReflection,
+                                $extensionInterfaceName,
+                                $fullInterfaceName
+                            )
+                        );
+                    }
+                }
+
+                $this->assertEmpty(
+                    $errors,
+                    "Error validating $filename\n" . print_r($errors, true)
+                );
+            },
+            $this->getInterfacesFiles()
+        );
+    }
+
+    /**
+     * Check getExtensionAttributes methods
+     *
+     * @param \ReflectionClass $interfaceReflection
+     * @param string $extensionInterfaceName
+     * @param string $fullInterfaceName
+     * @return array
+     */
+    private function checkGetExtensionAttributes(
+        \ReflectionClass $interfaceReflection,
+        $extensionInterfaceName,
+        $fullInterfaceName
+    ) {
+        $errors = [];
+        try {
+            $methodReflection = $interfaceReflection->getMethod('getExtensionAttributes');
+            /** Ensure that proper return type of getExtensionAttributes() method is specified */
+            $methodDocBlock = $methodReflection->getDocComment();
+            $pattern = "/@return\s+" . str_replace('\\', '\\\\', $extensionInterfaceName) . "/";
+            if (!preg_match($pattern, $methodDocBlock)) {
+                $errors[] =
+                    "'{$fullInterfaceName}::getExtensionAttributes()' must be declared "
+                    . "with a return type of '{$extensionInterfaceName}'.";
+            }
+        } catch (\ReflectionException $e) {
+            $errors[] = "The following method should be declared in "
+                . "'{$extensionInterfaceName}'. '{$extensionInterfaceName}' must be specified as"
+                . " a return type for '{$fullInterfaceName}::getExtensionAttributes()'";
+        }
+
+        return $errors;
+    }
+
+    /**
+     * Check setExtensionAttributes methods
+     *
+     * @param \ReflectionClass $interfaceReflection
+     * @param string $extensionInterfaceName
+     * @param string $fullInterfaceName
+     * @return array
+     */
+    private function checkSetExtensionAttributes(
+        \ReflectionClass $interfaceReflection,
+        $extensionInterfaceName,
+        $fullInterfaceName
+    ) {
+        $errors = [];
+        try {
+            $methodReflection = $interfaceReflection->getMethod('setExtensionAttributes');
+            /** Ensure that proper argument type for setExtensionAttributes() method is specified */
+            $methodParameters = $methodReflection->getParameters();
+
+            if (empty($methodParameters)) {
+                $errors[] = "'{$extensionInterfaceName}' must be specified as the parameter type "
+                    . "in '{$fullInterfaceName}::setExtensionAttributes()'.";
+            } else {
+                // Get the parameter name via a regular expression capture because the class may
+                // not exist which causes a fatal error
+                preg_match('/\[\s\<\w+?>\s([\w]+)/s', $methodParameters[0]->__toString(), $matches);
+                $isCorrectParameter = false;
+                if (isset($matches[1]) && '\\' . $matches[1] != $extensionInterfaceName) {
+                    $isCorrectParameter = true;
+                }
+
+                if (!$isCorrectParameter) {
+                    $errors[] = "'{$extensionInterfaceName}' must be specified as the parameter type "
+                        . "in '{$fullInterfaceName}::setExtensionAttributes()'.";
+                }
+            }
+        } catch (\ReflectionException $e) {
+            $errors[] = "'{$fullInterfaceName}::setExtensionAttributes()' must be declared "
+                . "with a '{$extensionInterfaceName}' parameter type.";
+        }
+
+        return $errors;
+    }
+
+    /**
+     * Ensure that all classes extended from extensible classes implement getter and setter for extension attributes.
+     */
+    public function testExtensibleClassesWithMissingInterface()
+    {
+        $invoker = new \Magento\Framework\App\Utility\AggregateInvoker($this);
+        $invoker(
+        /**
+         * @param string $filename
+         */
+            function ($filename) {
+                $errors = [];
+                $fileContent = file_get_contents($filename);
+                $extensibleClassPattern = 'class [^\{]+extends[^\{]+AbstractExtensible';
+                $abstractExtensibleClassPattern = 'abstract ' . $extensibleClassPattern;
+                if (preg_match('/' . $extensibleClassPattern . '/', $fileContent) &&
+                    !preg_match('/' . $abstractExtensibleClassPattern . '/', $fileContent)
+                ) {
+                    $fileReflection = new \Zend\Code\Reflection\FileReflection($filename, true);
+                    foreach ($fileReflection->getClasses() as $classReflection) {
+                        if ($classReflection->isSubclassOf(self::EXTENSIBLE_DATA_INTERFACE)) {
+                            $methodsToCheck = ['setExtensionAttributes', 'getExtensionAttributes'];
+                            foreach ($methodsToCheck as $methodName) {
+                                try {
+                                    $classReflection->getMethod($methodName);
+                                } catch (\ReflectionException $e) {
+                                    $className = $classReflection->getName();
+                                    $errors[] = "'{$className}::{$methodName}()' must be declared or "
+                                        . "'{$className}' should not be inherited from extensible class.";
+                                }
+                            }
+                        }
+                    }
+                }
+
+                $this->assertEmpty(
+                    $errors,
+                    "Error validating $filename\n" . print_r($errors, true)
+                );
+            },
+            $this->getPhpFiles()
+        );
+    }
+
+    /**
+     * Retrieve a list of all interfaces declared in the Magento application and Magento library.
+     *
+     * @return array
+     */
+    public function getInterfacesFiles()
+    {
+        $codeInterfaceFiles = $this->getFiles(BP . '/app', '*Interface.php');
+        $libInterfaceFiles = $this->getFiles(BP . '/lib/Magento', '*Interface.php');
+        $interfaces = [];
+        $filesToCheck = $this->blacklistFilter(array_merge($codeInterfaceFiles, $libInterfaceFiles));
+        foreach ($filesToCheck as $file) {
+            $interfaces[substr($file, strlen(BP))] = [$file];
+        }
+        return $interfaces;
+    }
+
+    /**
+     * Retrieve a list of all php files declared in the Magento application and Magento library.
+     *
+     * @return array
+     */
+    public function getPhpFiles()
+    {
+        $codeFiles = $this->getFiles(BP . '/app', '*.php');
+        $libFiles = $this->getFiles(BP . '/lib/Magento', '*.php');
+        $phpFiles = [];
+        $filesToCheck = $this->blacklistFilter(array_merge($codeFiles, $libFiles));
+        foreach ($filesToCheck as $file) {
+            $phpFiles[substr($file, strlen(BP))] = [$file];
+        }
+        return $phpFiles;
+    }
+
+    /**
+     * Retrieve all files in a directory that correspond to the given pattern
+     *
+     * @param string $dir
+     * @param string $pattern
+     * @return array
+     */
+    protected function getFiles($dir, $pattern)
+    {
+        $files = glob($dir . '/' . $pattern, GLOB_NOSORT);
+        foreach (glob($dir . '/*', GLOB_ONLYDIR | GLOB_NOSORT) as $newDir) {
+            $files = array_merge($files, $this->getFiles($newDir, $pattern));
+        }
+        return $files;
+    }
+
+    /**
+     * Filter blacklisted files out of an array
+     *
+     * @param array $preFilter
+     * @return array
+     */
+    protected function blacklistFilter($preFilter)
+    {
+        $postFilter = [];
+        $blacklist = Files::readLists(__DIR__ . '/_files/ExtensibleInterfacesTest/blacklist*');
+        foreach ($preFilter as $file) {
+            if (!in_array($file, $blacklist)) {
+                $postFilter[] = $file;
+            }
+        }
+        return $postFilter;
+    }
+}
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Api/_files/ExtensibleInterfacesTest/blacklist_ce.txt b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Api/_files/ExtensibleInterfacesTest/blacklist_ce.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b43e1551c9e9d4b216df0fc88e525e0c8a1609dc
--- /dev/null
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/Magento/Framework/Api/_files/ExtensibleInterfacesTest/blacklist_ce.txt
@@ -0,0 +1,2 @@
+app/code/Magento/Payment/Model/Info.php
+app/code/Magento/Customer/Model/Address/AbstractAddress.php
\ No newline at end of file
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/namespace.txt b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/namespace.txt
index 3040b28edc5274f7d8fa138c0a7d4ba8be521d85..1c00c272708bd0ec91a8cdd3b6f4ff1df4637715 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/namespace.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/namespace.txt
@@ -29,11 +29,19 @@ dev/tests/integration/testsuite/Magento/Test/Tools/I18n/Dictionary/_files/source
 dev/tests/integration/testsuite/Magento/Test/Tools/I18n/Dictionary/_files/source/not_magento_dir/Model.php
 dev/tests/integration/testsuite/Magento/Test/Tools/I18n/Dictionary/_files/source/app/code/Magento/FirstModule/Helper/Helper.php
 dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Api/Data/FakeAddressInterface.php
+dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Api/Data/FakeExtensibleOneInterface.php
+dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Api/Data/FakeExtensibleTwoInterface.php
 dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Api/Data/FakeRegionInterface.php
+dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Api/Data/FakeExtensibleOneInterface.php
+dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Api/Data/FakeExtensibleTwoInterface.php
 dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/FakeAddress.php
+dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/FakeExtensibleOne.php
+dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/FakeExtensibleTwo.php
 dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/FakeRegion.php
 dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/Data/FakeAddress.php
 dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/Data/FakeRegion.php
+dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/Data/FakeExtensibleOne.php
+dev/tests/integration/testsuite/Magento/Framework/Api/_files/Magento/Wonderland/Model/Data/FakeExtensibleTwo.php
 dev/tests/static/testsuite/Magento/Test/Php/Exemplar/CodeMessTest/phpmd/input/coupling.php
 dev/tests/static/testsuite/Magento/Test/Php/Exemplar/CodeMessTest/phpmd/input/cyclomatic_complexity.php
 dev/tests/static/testsuite/Magento/Test/Php/Exemplar/CodeMessTest/phpmd/input/descendant_count.php
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/reference.txt b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/reference.txt
index 29a6687221a578eec95394ebb2161c46ceba331f..1310a906961d107a4aa3b399324bcb35bca08b33 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/reference.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/reference.txt
@@ -34,8 +34,12 @@ Model1
 Model3
 \Magento\Wonderland\Api\Data\FakeRegionInterface
 \Magento\Wonderland\Api\Data\FakeAddressInterface
+\Magento\Wonderland\Api\Data\FakeExtensibleOneInterface
+\Magento\Wonderland\Api\Data\FakeExtensibleTwoInterface
 \Magento\Wonderland\Model\Data\FakeRegion
 \Magento\Wonderland\Model\Data\FakeAddress
+\Magento\Wonderland\Model\Data\FakeExtensibleOne
+\Magento\Wonderland\Model\Data\FakeExtensibleTwo
 \Magento\Framework\Error\Processor
 \Magento\TestModule3\Service\V1\Entity\Parameter
 \Magento\TestModule3\Service\V1\Entity\ParameterBuilder
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 92b49b9ef7cd70ccc802117e6b8cb936c7da22a0..2f915d7ffb489af665131b0bea82328ecccc1a8f 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
@@ -2168,6 +2168,7 @@ return [
     ['Magento\Usa\Model\Shipping\Carrier\Usps\Source\Machinable', 'Magento\Usps\Model\Source\Machinable'],
     ['Magento\Usa\Model\Shipping\Carrier\Usps\Source\Method', 'Magento\Usps\Model\Source\Method'],
     ['Magento\Usa\Model\Shipping\Carrier\Usps\Source\Size', 'Magento\Usps\Model\Source\Size'],
+    ['Magento\Framework\Api\Config\MetadataConfig'],
     ['Magento\Usa\Model\Shipping\Carrier\Usps', 'Magento\Usps\Model\Carrier'],
     ['Magento\Usa\Model\Shipping\Carrier\Ups', 'Magento\Ups\Model\Carrier'],
     ['Magento\Usa\Model\Simplexml\Element', 'Magento\Shipping\Model\Simplexml\Element'],
diff --git a/dev/tests/unit/framework/autoload.php b/dev/tests/unit/framework/autoload.php
new file mode 100644
index 0000000000000000000000000000000000000000..56021a2bb4acf835cf73ebb210789a84d77c2818
--- /dev/null
+++ b/dev/tests/unit/framework/autoload.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+use Magento\Framework\Api\Code\Generator\DataBuilder;
+use Magento\Framework\Api\Code\Generator\Mapper;
+use Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator;
+use Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator;
+use Magento\Framework\Api\Code\Generator\SearchResults;
+use Magento\Framework\Api\Code\Generator\SearchResultsBuilder;
+use Magento\Framework\Interception\Code\Generator\Interceptor;
+use Magento\Framework\ObjectManager\Code\Generator\Converter;
+use Magento\Framework\ObjectManager\Code\Generator\Factory;
+use Magento\Framework\ObjectManager\Code\Generator\Persistor;
+use Magento\Framework\ObjectManager\Code\Generator\Proxy;
+use Magento\Framework\ObjectManager\Code\Generator\Repository;
+use Magento\Tools\Di\Code\Scanner;
+use Magento\Tools\Di\Compiler\Log\Writer;
+use Magento\Tools\Di\Definition\Compressor;
+
+/**
+ * Enable code generation for the undeclared classes.
+ */
+$generationDir = TESTS_TEMP_DIR . '/var/generation';
+$generatorIo = new \Magento\Framework\Code\Generator\Io(
+    new \Magento\Framework\Filesystem\Driver\File(),
+    $generationDir
+);
+$generator = new \Magento\Framework\Code\Generator(
+    $generatorIo,
+    [
+        Interceptor::ENTITY_TYPE => 'Magento\Framework\Interception\Code\Generator\Interceptor',
+        Proxy::ENTITY_TYPE => 'Magento\Framework\ObjectManager\Code\Generator\Proxy',
+        Factory::ENTITY_TYPE => 'Magento\Framework\ObjectManager\Code\Generator\Factory',
+        Mapper::ENTITY_TYPE => 'Magento\Framework\Api\Code\Generator\Mapper',
+        Persistor::ENTITY_TYPE => 'Magento\Framework\ObjectManager\Code\Generator\Persistor',
+        Repository::ENTITY_TYPE => 'Magento\Framework\ObjectManager\Code\Generator\Repository',
+        Converter::ENTITY_TYPE => 'Magento\Framework\ObjectManager\Code\Generator\Converter',
+        SearchResults::ENTITY_TYPE => 'Magento\Framework\Api\Code\Generator\SearchResults',
+        ExtensionAttributesInterfaceGenerator::ENTITY_TYPE =>
+            'Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator',
+        ExtensionAttributesGenerator::ENTITY_TYPE => 'Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator'
+    ]
+);
+/** Initialize object manager for code generation based on configs */
+$magentoObjectManagerFactory = \Magento\Framework\App\Bootstrap::createObjectManagerFactory(BP, $_SERVER);
+$objectManager = $magentoObjectManagerFactory->create($_SERVER);
+$generator->setObjectManager($objectManager);
+
+$autoloader = new \Magento\Framework\Code\Generator\Autoloader($generator);
+spl_autoload_register([$autoloader, 'load']);
+$autoloadWrapper = \Magento\Framework\Autoload\AutoloaderRegistry::getAutoloader();
+$autoloadWrapper->addPsr4('Magento\\', $generationDir . '/Magento/');
diff --git a/dev/tests/unit/framework/bootstrap.php b/dev/tests/unit/framework/bootstrap.php
index 96ff9c21b8765cddb3f750ce6aeb61e2dbece0a5..b30486b50a17dc3a6e0b67adaa072868b1747736 100755
--- a/dev/tests/unit/framework/bootstrap.php
+++ b/dev/tests/unit/framework/bootstrap.php
@@ -10,6 +10,7 @@ if (!defined('TESTS_TEMP_DIR')) {
     define('TESTS_TEMP_DIR', dirname(__DIR__) . '/tmp');
 }
 
+require_once __DIR__ . '/autoload.php';
 require BP . '/app/functions.php';
 
 
diff --git a/dev/tools/Magento/Tools/Di/Code/Scanner/PhpScanner.php b/dev/tools/Magento/Tools/Di/Code/Scanner/PhpScanner.php
index 6346d51bd2f8c03a820f6a56ecb9642956784ef3..bf5fc24e4749a2252511471bf3581476b9153d5e 100644
--- a/dev/tools/Magento/Tools/Di/Code/Scanner/PhpScanner.php
+++ b/dev/tools/Magento/Tools/Di/Code/Scanner/PhpScanner.php
@@ -6,6 +6,9 @@
 namespace Magento\Tools\Di\Code\Scanner;
 
 use Magento\Tools\Di\Compiler\Log\Log;
+use Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator;
+use Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator;
+use Magento\Framework\ObjectManager\Code\Generator\Factory as FactoryGenerator;
 
 class PhpScanner implements ScannerInterface
 {
@@ -23,51 +26,138 @@ class PhpScanner implements ScannerInterface
     }
 
     /**
-     * Fetch factories from class constructor
+     * Find classes which are used as parameters types of the specified method and are not declared.
      *
-     * @param $file string
-     * @param $reflectionClass mixed
-     * @return array
+     * @param string $file
+     * @param \ReflectionClass $classReflection
+     * @param string $methodName
+     * @param string $entityType
+     * @return string[]
      */
-    protected function _fetchFactories($file, $reflectionClass)
+    protected function _findMissingClasses($file, $classReflection, $methodName, $entityType)
     {
-        $absentFactories = [];
-        if ($reflectionClass->hasMethod('__construct')) {
-            $constructor = $reflectionClass->getMethod('__construct');
+        $missingClasses = [];
+        if ($classReflection->hasMethod($methodName)) {
+            $constructor = $classReflection->getMethod($methodName);
             $parameters = $constructor->getParameters();
             /** @var $parameter \ReflectionParameter */
             foreach ($parameters as $parameter) {
                 preg_match('/\[\s\<\w+?>\s([\w\\\\]+)/s', $parameter->__toString(), $matches);
-                if (isset($matches[1]) && substr($matches[1], -7) == 'Factory') {
-                    $factoryClassName = $matches[1];
-                    if (class_exists($factoryClassName)) {
-                        continue;
-                    }
-                    $entityName = rtrim(substr($factoryClassName, 0, -7), '\\');
-                    if (!class_exists($entityName) && !interface_exists($entityName)) {
-                        $this->_log->add(
-                            Log::CONFIGURATION_ERROR,
-                            $factoryClassName,
-                            'Invalid Factory for nonexistent class ' . $entityName . ' in file ' . $file
-                        );
-                        continue;
+                if (isset($matches[1]) && substr($matches[1], -strlen($entityType)) == $entityType) {
+                    $missingClassName = $matches[1];
+                    try {
+                        if (class_exists($missingClassName)) {
+                            continue;
+                        }
+                    } catch (\Magento\Framework\Exception $e) {
                     }
-
-                    if (substr($factoryClassName, -8) == '\\Factory') {
+                    $sourceClassName = $this->getSourceClassName($missingClassName, $entityType);
+                    if (!class_exists($sourceClassName) && !interface_exists($sourceClassName)) {
                         $this->_log->add(
                             Log::CONFIGURATION_ERROR,
-                            $factoryClassName,
-                            'Invalid Factory declaration for class ' . $entityName . ' in file ' . $file
+                            $missingClassName,
+                            "Invalid {$entityType} for nonexistent class {$sourceClassName} in file {$file}"
                         );
                         continue;
                     }
-                    $absentFactories[] = $factoryClassName;
+                    $missingClasses[] = $missingClassName;
                 }
             }
         }
+        return $missingClasses;
+    }
+
+    /**
+     * Identify source class name for the provided class.
+     *
+     * @param string $missingClassName
+     * @param string $entityType
+     * @return string
+     */
+    protected function getSourceClassName($missingClassName, $entityType)
+    {
+        $sourceClassName = rtrim(substr($missingClassName, 0, -strlen($entityType)), '\\');
+        $entityType = lcfirst($entityType);
+        if ($entityType == ExtensionAttributesInterfaceGenerator::ENTITY_TYPE
+            || $entityType == ExtensionAttributesGenerator::ENTITY_TYPE
+        ) {
+            /** Process special cases for extension class and extension interface */
+            return $sourceClassName . 'Interface';
+        } else if ($entityType == FactoryGenerator::ENTITY_TYPE) {
+            $extensionAttributesSuffix = ucfirst(ExtensionAttributesGenerator::ENTITY_TYPE);
+            if (substr($sourceClassName, -strlen($extensionAttributesSuffix)) == $extensionAttributesSuffix) {
+                /** Process special case for extension factories */
+                $extensionAttributesClass = substr(
+                    $sourceClassName,
+                    0,
+                    -strlen(ExtensionAttributesGenerator::ENTITY_TYPE)
+                );
+                $sourceClassName = $extensionAttributesClass . 'Interface';
+            }
+        }
+        return $sourceClassName;
+    }
+
+    /**
+     * Fetch factories from class constructor
+     *
+     * @param \ReflectionClass $reflectionClass
+     * @param string $file
+     * @return string[]
+     */
+    protected function _fetchFactories($reflectionClass, $file)
+    {
+        $factorySuffix = '\\'.ucfirst(FactoryGenerator::ENTITY_TYPE);
+        $absentFactories = $this->_findMissingClasses(
+            $file,
+            $reflectionClass,
+            '__construct',
+            ucfirst(FactoryGenerator::ENTITY_TYPE)
+        );
+        foreach ($absentFactories as $key => $absentFactory) {
+            if (substr($absentFactory, -strlen($factorySuffix)) == $factorySuffix) {
+                $entityName = rtrim(substr($absentFactory, 0, -strlen($factorySuffix)), '\\');
+                $this->_log->add(
+                    Log::CONFIGURATION_ERROR,
+                    $absentFactory,
+                    'Invalid Factory declaration for class ' . $entityName . ' in file ' . $file
+                );
+                unset($absentFactories[$key]);
+            }
+        }
         return $absentFactories;
     }
 
+    /**
+     * Find missing extension attributes related classes, interfaces and factories.
+     *
+     * @param \ReflectionClass $reflectionClass
+     * @param string $file
+     * @return string[]
+     */
+    protected function _fetchMissingExtensionAttributesClasses($reflectionClass, $file)
+    {
+        $missingExtensionInterfaces = $this->_findMissingClasses(
+            $file,
+            $reflectionClass,
+            'setExtensionAttributes',
+            ucfirst(\Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator::ENTITY_TYPE)
+        );
+        $missingExtensionClasses = [];
+        $missingExtensionFactories = [];
+        foreach ($missingExtensionInterfaces as $missingExtensionInterface) {
+            $extension = rtrim(substr($missingExtensionInterface, 0, -strlen('Interface')), '\\');
+            if (!class_exists($extension)) {
+                $missingExtensionClasses[] = $extension;
+            }
+            $extensionFactory = $extension . 'Factory';
+            if (!class_exists($extensionFactory)) {
+                $missingExtensionFactories[] = $extensionFactory;
+            }
+        }
+        return array_merge($missingExtensionInterfaces, $missingExtensionClasses, $missingExtensionFactories);
+    }
+
     /**
      * Get array of class names
      *
@@ -81,10 +171,11 @@ class PhpScanner implements ScannerInterface
             $classes = $this->_getDeclaredClasses($file);
             foreach ($classes as $className) {
                 $reflectionClass = new \ReflectionClass($className);
-                $absentFactories = $this->_fetchFactories($file, $reflectionClass);
-                if (!empty($absentFactories)) {
-                    $output = array_merge($output, $absentFactories);
-                }
+                $output = array_merge(
+                    $output,
+                    $this->_fetchFactories($reflectionClass, $file),
+                    $this->_fetchMissingExtensionAttributesClasses($reflectionClass, $file)
+                );
             }
         }
         return array_unique($output);
@@ -128,7 +219,7 @@ class PhpScanner implements ScannerInterface
     }
 
     /**
-     * Get classes declared in the file
+     * Get classes and interfaces declared in the file
      *
      * @param string $file
      * @return array
@@ -145,7 +236,9 @@ class PhpScanner implements ScannerInterface
                 $namespace .= $this->_fetchNamespace($tokenIterator, $count, $tokens);
             }
 
-            if ($tokens[$tokenIterator][0] === T_CLASS) {
+            if ($tokens[$tokenIterator][0] === T_CLASS
+                || $tokens[$tokenIterator][0] === T_INTERFACE
+            ) {
                 $classes = array_merge($classes, $this->_fetchClasses($namespace, $tokenIterator, $count, $tokens));
             }
         }
diff --git a/dev/tools/Magento/Tools/Di/Code/Scanner/XmlScanner.php b/dev/tools/Magento/Tools/Di/Code/Scanner/XmlScanner.php
index 23ad5d57a25ef85c8a13b6234f4d83d91f3cc406..9f0b2ec3304b621728a6e94efb15f738b96170a9 100644
--- a/dev/tools/Magento/Tools/Di/Code/Scanner/XmlScanner.php
+++ b/dev/tools/Magento/Tools/Di/Code/Scanner/XmlScanner.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Tools\Di\Code\Scanner;
 
+use Magento\Framework\ObjectManager\Code\Generator\Proxy as ProxyGenerator;
+
 class XmlScanner implements ScannerInterface
 {
     /**
@@ -57,10 +59,18 @@ class XmlScanner implements ScannerInterface
      */
     protected function _filterEntities(array $output)
     {
+        $entitySuffix = '\\' . ucfirst(ProxyGenerator::ENTITY_TYPE);
         $filteredEntities = [];
         foreach ($output as $className) {
-            $entityName = substr($className, -6) === '\Proxy' ? substr($className, 0, -6) : $className;
-            if (false === class_exists($className)) {
+            $entityName = substr($className, -strlen($entitySuffix)) === $entitySuffix
+                ? substr($className, 0, -strlen($entitySuffix))
+                : $className;
+            $isClassExists = false;
+            try {
+                $isClassExists = class_exists($className);
+            } catch (\Magento\Framework\Exception $e) {
+            }
+            if (false === $isClassExists) {
                 if (class_exists($entityName) || interface_exists($entityName)) {
                     array_push($filteredEntities, $className);
                 } else {
diff --git a/dev/tools/Magento/Tools/Di/Test/Unit/Code/Scanner/XmlScannerTest.php b/dev/tools/Magento/Tools/Di/Test/Unit/Code/Scanner/XmlScannerTest.php
index 76a1e87268f3b32b048326ffc2db3bf9ce26bf53..b1cd9b3dac280b565d3d152a5c49c2d9b9da1688 100644
--- a/dev/tools/Magento/Tools/Di/Test/Unit/Code/Scanner/XmlScannerTest.php
+++ b/dev/tools/Magento/Tools/Di/Test/Unit/Code/Scanner/XmlScannerTest.php
@@ -69,7 +69,7 @@ class XmlScannerTest extends \PHPUnit_Framework_TestCase
             'Invalid proxy class for ' . substr('\Magento\SomeModule\Model\Nested\Element\Proxy', 0, -5)
         );
         $actual = $this->_model->collectEntities($this->_testFiles);
-        $expected = ['Magento\Framework\App\Request\Http\Proxy'];
+        $expected = [];
         $this->assertEquals($expected, $actual);
     }
 }
diff --git a/dev/tools/Magento/Tools/Di/compiler.php b/dev/tools/Magento/Tools/Di/compiler.php
index 8fb0cd5d24c18a29736cc083757ebaceb1c6b0cb..fee6aa1320565f3f45bb6247e184ff5a756ae24c 100644
--- a/dev/tools/Magento/Tools/Di/compiler.php
+++ b/dev/tools/Magento/Tools/Di/compiler.php
@@ -15,7 +15,8 @@ use Magento\Framework\ObjectManager\Code\Generator\Factory;
 use Magento\Framework\ObjectManager\Code\Generator\Proxy;
 use Magento\Framework\ObjectManager\Code\Generator\Repository;
 use Magento\Framework\ObjectManager\Code\Generator\Persistor;
-use Magento\Framework\Api\Code\Generator\ObjectExtensionInterface;
+use Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator;
+use Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator;
 use Magento\Tools\Di\Code\Scanner;
 use Magento\Tools\Di\Compiler\Log\Log;
 use Magento\Tools\Di\Compiler\Log\Writer;
@@ -103,10 +104,16 @@ try {
             Repository::ENTITY_TYPE => 'Magento\Framework\ObjectManager\Code\Generator\Repository',
             Converter::ENTITY_TYPE => 'Magento\Framework\ObjectManager\Code\Generator\Converter',
             SearchResults::ENTITY_TYPE => 'Magento\Framework\Api\Code\Generator\SearchResults',
-            ObjectExtensionInterface::ENTITY_TYPE =>
-                'Magento\Framework\Api\Code\Generator\ObjectExtensionInterface'
+            ExtensionAttributesInterfaceGenerator::ENTITY_TYPE =>
+                'Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator',
+            ExtensionAttributesGenerator::ENTITY_TYPE =>
+                'Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator'
         ]
     );
+    /** Initialize object manager for code generation based on configs */
+    $magentoObjectManagerFactory = \Magento\Framework\App\Bootstrap::createObjectManagerFactory(BP, $_SERVER);
+    $objectManager = $magentoObjectManagerFactory->create($_SERVER);
+    $generator->setObjectManager($objectManager);
 
     $generatorAutoloader = new \Magento\Framework\Code\Generator\Autoloader($generator);
     spl_autoload_register([$generatorAutoloader, 'load']);
@@ -235,6 +242,17 @@ try {
     if ($log->hasError()) {
         exit(1);
     }
+
+    echo 'On *nix systems, verify the Magento application has permissions to modify files created by the compiler'
+        . ' in the "var" directory. For instance, if you run the Magento application using Apache,'
+        . ' the owner of the files in the "var" directory should be the Apache user (example command:'
+        . ' "chown -R www-data:www-data <MAGENTO_ROOT>/var" where MAGENTO_ROOT is the Magento root directory).' . "\n";
+    /** TODO: Temporary solution before having necessary changes on bamboo to overcome issue described above */
+    $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($rootDir . '/var'));
+    foreach ($iterator as $item) {
+        chmod($item, 0777);
+    }
+
 } catch (Zend_Console_Getopt_Exception $e) {
     echo $e->getUsageMessage();
     echo 'Please, use quotes(") for wrapping strings.' . "\n";
diff --git a/dev/tools/Magento/Tools/Di/entity_generator.php b/dev/tools/Magento/Tools/Di/entity_generator.php
index 9a94fe29156e77c22335b424739a20c2862744f9..4ab81346a4e3b3b555936a9ed1136ea163e28fb8 100644
--- a/dev/tools/Magento/Tools/Di/entity_generator.php
+++ b/dev/tools/Magento/Tools/Di/entity_generator.php
@@ -16,7 +16,8 @@ use Magento\Framework\ObjectManager\Code\Generator\Converter;
 use Magento\Framework\ObjectManager\Code\Generator\Factory;
 use Magento\Framework\ObjectManager\Code\Generator\Proxy;
 use Magento\Framework\ObjectManager\Code\Generator\Repository;
-use Magento\Framework\Api\Code\Generator\ObjectExtensionInterface;
+use Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator;
+use Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator;
 
 require __DIR__ . '/../../../../../app/bootstrap.php';
 
@@ -70,7 +71,6 @@ try {
 //reinit generator with correct generation path
 $io = new Io(new File(), $generationDir);
 $generator = new Generator(
-    $validator,
     $io,
     [
         Proxy::ENTITY_TYPE => 'Magento\Framework\ObjectManager\Code\Generator\Proxy',
@@ -80,10 +80,15 @@ $generator = new Generator(
         Repository::ENTITY_TYPE => 'Magento\Framework\ObjectManager\Code\Generator\Repository',
         Converter::ENTITY_TYPE => 'Magento\Framework\ObjectManager\Code\Generator\Converter',
         SearchResults::ENTITY_TYPE => 'Magento\Framework\Api\Code\Generator\SearchResults',
-        ObjectExtensionInterface::ENTITY_TYPE =>
-            'Magento\Framework\Api\Code\Generator\ObjectExtensionInterface'
+        ExtensionAttributesInterfaceGenerator::ENTITY_TYPE =>
+            'Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator',
+        ExtensionAttributesGenerator::ENTITY_TYPE => 'Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator'
     ]
 );
+/** Initialize object manager for code generation based on configs */
+$magentoObjectManagerFactory = \Magento\Framework\App\Bootstrap::createObjectManagerFactory(BP, $_SERVER);
+$objectManager = $magentoObjectManagerFactory->create($_SERVER);
+$generator->setObjectManager($objectManager);
 
 try {
     if (Generator::GENERATION_SUCCESS == $generator->generateClass($className)) {
diff --git a/lib/internal/Magento/Framework/Api/AbstractExtensibleObject.php b/lib/internal/Magento/Framework/Api/AbstractExtensibleObject.php
index 0eb68d88fb4d0417bd91b40b5a41b01cd9c2cd8a..6455c7ca7f2cb2c9f3056910c1a594e5b95519aa 100644
--- a/lib/internal/Magento/Framework/Api/AbstractExtensibleObject.php
+++ b/lib/internal/Magento/Framework/Api/AbstractExtensibleObject.php
@@ -10,8 +10,9 @@ use \Magento\Framework\Api\AttributeValueFactory;
 /**
  * Base Class for extensible data Objects
  * @SuppressWarnings(PHPMD.NumberOfChildren)
+ * TODO: This class can be split into Custom attribute and Extension attribute implementation classes
  */
-abstract class AbstractExtensibleObject extends AbstractSimpleObject implements ExtensibleDataInterface
+abstract class AbstractExtensibleObject extends AbstractSimpleObject implements CustomAttributesDataInterface
 {
     /**
      * Array key for custom attributes
@@ -19,14 +20,14 @@ abstract class AbstractExtensibleObject extends AbstractSimpleObject implements
     const CUSTOM_ATTRIBUTES_KEY = 'custom_attributes';
 
     /**
-     * @var AttributeValueFactory
+     * @var \Magento\Framework\Api\ExtensionAttributesFactory
      */
-    protected $attributeValueFactory;
+    protected $extensionFactory;
 
     /**
-     * @var MetadataServiceInterface
+     * @var AttributeValueFactory
      */
-    protected $metadataService;
+    protected $attributeValueFactory;
 
     /**
      * @var string[]
@@ -36,16 +37,16 @@ abstract class AbstractExtensibleObject extends AbstractSimpleObject implements
     /**
      * Initialize internal storage
      *
-     * @param MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $attributeValueFactory
      * @param array $data
      */
     public function __construct(
-        MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $attributeValueFactory,
         $data = []
     ) {
-        $this->metadataService = $metadataService;
+        $this->extensionFactory = $extensionFactory;
         $this->attributeValueFactory = $attributeValueFactory;
         parent::__construct($data);
     }
@@ -118,23 +119,57 @@ abstract class AbstractExtensibleObject extends AbstractSimpleObject implements
     }
 
     /**
+     * Get a list of custom attribute codes.
+     *
+     * By default, entity can be extended only using extension attributes functionality.
      *
      * @return string[]
      */
     protected function getCustomAttributesCodes()
     {
-        if (!is_null($this->customAttributesCodes)) {
-            return $this->customAttributesCodes;
-        }
+        return isset($this->customAttributesCodes) ? $this->customAttributesCodes : [];
+    }
+
+    /**
+     * Receive a list of EAV attributes using provided metadata service.
+     *
+     * Can be used in child classes, which represent EAV entities.
+     *
+     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @return string[]
+     */
+    protected function getEavAttributesCodes(\Magento\Framework\Api\MetadataServiceInterface $metadataService)
+    {
         $attributeCodes = [];
-        $customAttributesMetadata = $this->metadataService->getCustomAttributesMetadata(get_class($this));
+        $customAttributesMetadata = $metadataService->getCustomAttributesMetadata(get_class($this));
         if (is_array($customAttributesMetadata)) {
             /** @var $attribute \Magento\Framework\Api\MetadataObjectInterface */
             foreach ($customAttributesMetadata as $attribute) {
                 $attributeCodes[] = $attribute->getAttributeCode();
             }
         }
-        $this->customAttributesCodes = $attributeCodes;
         return $attributeCodes;
     }
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Framework\Api\ExtensionAttributesInterface
+     */
+    protected function _getExtensionAttributes()
+    {
+        return $this->_get(self::EXTENSION_ATTRIBUTES_KEY);
+    }
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Framework\Api\ExtensionAttributesInterface $extensionAttributes
+     * @return $this
+     */
+    protected function _setExtensionAttributes(\Magento\Framework\Api\ExtensionAttributesInterface $extensionAttributes)
+    {
+        $this->_data[self::EXTENSION_ATTRIBUTES_KEY] = $extensionAttributes;
+        return $this;
+    }
 }
diff --git a/lib/internal/Magento/Framework/Api/Code/Generator/ObjectExtension.php b/lib/internal/Magento/Framework/Api/Code/Generator/ExtensionAttributesGenerator.php
similarity index 72%
rename from lib/internal/Magento/Framework/Api/Code/Generator/ObjectExtension.php
rename to lib/internal/Magento/Framework/Api/Code/Generator/ExtensionAttributesGenerator.php
index 28569195579c975131e800fe687ac45dfa88cb12..98f5dc5d5e07250fe7b427ca68286cb99c22ee35 100644
--- a/lib/internal/Magento/Framework/Api/Code/Generator/ObjectExtension.php
+++ b/lib/internal/Magento/Framework/Api/Code/Generator/ExtensionAttributesGenerator.php
@@ -12,7 +12,7 @@ use Magento\Framework\Api\SimpleDataObjectConverter;
 /**
  * Code generator for data object extensions.
  */
-class ObjectExtension extends \Magento\Framework\Code\Generator\EntityAbstract
+class ExtensionAttributesGenerator extends \Magento\Framework\Code\Generator\EntityAbstract
 {
     const ENTITY_TYPE = 'extension';
 
@@ -70,16 +70,7 @@ class ObjectExtension extends \Magento\Framework\Code\Generator\EntityAbstract
      */
     protected function _getClassProperties()
     {
-        $properties = [];
-        foreach ($this->getCustomAttributes() as $attributeName => $attributeType) {
-            $propertyName = SimpleDataObjectConverter::snakeCaseToCamelCase($attributeName);
-            $properties[] = [
-                'name' => $propertyName,
-                'visibility' => 'protected',
-                'docblock' => ['tags' => [['name' => 'var', 'description' => $attributeType]]],
-            ];
-        }
-        return $properties;
+        return [];
     }
 
     /**
@@ -94,13 +85,13 @@ class ObjectExtension extends \Magento\Framework\Code\Generator\EntityAbstract
             $setterName = 'set' . ucfirst($propertyName);
             $methods[] = [
                 'name' => $getterName,
-                'body' => "return \$this->{$propertyName};",
+                'body' => "return \$this->_get('{$attributeName}');",
                 'docblock' => ['tags' => [['name' => 'return', 'description' => $attributeType]]],
             ];
             $methods[] = [
                 'name' => $setterName,
                 'parameters' => [['name' => $propertyName]],
-                'body' => "\$this->{$propertyName} = \${$propertyName};" . PHP_EOL . "return \$this;",
+                'body' => "\$this->setData('{$attributeName}', \${$propertyName});" . PHP_EOL . "return \$this;",
                 'docblock' => [
                     'tags' => [
                         [
@@ -123,18 +114,8 @@ class ObjectExtension extends \Magento\Framework\Code\Generator\EntityAbstract
      */
     protected function _validateData()
     {
-        $result = true;
-        $sourceClassName = $this->_getSourceClassName();
-        $resultClassName = $this->_getResultClassName();
-        $interfaceSuffix = 'Interface';
-        $expectedResultClassName = substr($sourceClassName, 0, -strlen($interfaceSuffix)) . self::EXTENSION_SUFFIX;
-        if ($resultClassName !== $expectedResultClassName) {
-            $this->_addError(
-                'Invalid extension name [' . $resultClassName . ']. Use ' . $expectedResultClassName
-            );
-            $result = false;
-        }
-        return parent::_validateData() && $result;
+        $classNameValidationResults = $this->validateResultClassName();
+        return parent::_validateData() && $classNameValidationResults;
     }
 
     /**
@@ -143,9 +124,20 @@ class ObjectExtension extends \Magento\Framework\Code\Generator\EntityAbstract
     protected function _generateCode()
     {
         $this->_classGenerator->setImplementedInterfaces([$this->_getResultClassName() . 'Interface']);
+        $this->_classGenerator->setExtendedClass($this->getExtendedClass());
         return parent::_generateCode();
     }
 
+    /**
+     * Get class, which should be used as a parent for generated class.
+     *
+     * @return string
+     */
+    protected function getExtendedClass()
+    {
+        return '\Magento\Framework\Api\AbstractSimpleObject';
+    }
+
     /**
      * Retrieve a list of attributes associated with current source class.
      *
@@ -156,11 +148,40 @@ class ObjectExtension extends \Magento\Framework\Code\Generator\EntityAbstract
         if (!isset($this->allCustomAttributes)) {
             $this->allCustomAttributes = $this->configReader->read();
         }
-        $dataInterface = ltrim($this->_getSourceClassName(), '\\');
+        $dataInterface = ltrim($this->getSourceClassName(), '\\');
         if (isset($this->allCustomAttributes[$dataInterface])) {
+            foreach ($this->allCustomAttributes[$dataInterface] as $attributeName => $attributeType) {
+                if (strpos($attributeType, '\\') !== false) {
+                    /** Add preceding slash to class names, while leaving primitive types as is */
+                    $attributeType = $this->_getFullyQualifiedClassName($attributeType);
+                    $this->allCustomAttributes[$dataInterface][$attributeName] =
+                        $this->_getFullyQualifiedClassName($attributeType);
+                }
+            }
             return $this->allCustomAttributes[$dataInterface];
         } else {
             return [];
         }
     }
+
+    /**
+     * Ensure that result class name corresponds to the source class name.
+     *
+     * @return bool
+     */
+    protected function validateResultClassName()
+    {
+        $result = true;
+        $sourceClassName = $this->getSourceClassName();
+        $resultClassName = $this->_getResultClassName();
+        $interfaceSuffix = 'Interface';
+        $expectedResultClassName = substr($sourceClassName, 0, -strlen($interfaceSuffix)) . self::EXTENSION_SUFFIX;
+        if ($resultClassName !== $expectedResultClassName) {
+            $this->_addError(
+                'Invalid extension name [' . $resultClassName . ']. Use ' . $expectedResultClassName
+            );
+            $result = false;
+        }
+        return $result;
+    }
 }
diff --git a/lib/internal/Magento/Framework/Api/Code/Generator/ObjectExtensionInterface.php b/lib/internal/Magento/Framework/Api/Code/Generator/ExtensionAttributesInterfaceGenerator.php
similarity index 83%
rename from lib/internal/Magento/Framework/Api/Code/Generator/ObjectExtensionInterface.php
rename to lib/internal/Magento/Framework/Api/Code/Generator/ExtensionAttributesInterfaceGenerator.php
index 73fb6556c2c0191a28b4c94e6f99f4754a631e55..59b6f225bb6c1d84acdfb20d96880980712b1bd2 100644
--- a/lib/internal/Magento/Framework/Api/Code/Generator/ObjectExtensionInterface.php
+++ b/lib/internal/Magento/Framework/Api/Code/Generator/ExtensionAttributesInterfaceGenerator.php
@@ -11,7 +11,7 @@ use Magento\Framework\Code\Generator\Io;
 /**
  * Code generator for data object extension interfaces.
  */
-class ObjectExtensionInterface extends \Magento\Framework\Api\Code\Generator\ObjectExtension
+class ExtensionAttributesInterfaceGenerator extends \Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator
 {
     const ENTITY_TYPE = 'extensionInterface';
 
@@ -51,10 +51,18 @@ class ObjectExtensionInterface extends \Magento\Framework\Api\Code\Generator\Obj
     /**
      * {@inheritdoc}
      */
-    protected function _validateData()
+    protected function getExtendedClass()
+    {
+        return '\Magento\Framework\Api\ExtensionAttributesInterface';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function validateResultClassName()
     {
         $result = true;
-        $sourceClassName = $this->_getSourceClassName();
+        $sourceClassName = $this->getSourceClassName();
         $resultClassName = $this->_getResultClassName();
         $interfaceSuffix = 'Interface';
         $expectedResultClassName = substr($sourceClassName, 0, -strlen($interfaceSuffix))
@@ -65,6 +73,6 @@ class ObjectExtensionInterface extends \Magento\Framework\Api\Code\Generator\Obj
             );
             $result = false;
         }
-        return parent::_validateData() && $result;
+        return $result;
     }
 }
diff --git a/lib/internal/Magento/Framework/Api/Code/Generator/Mapper.php b/lib/internal/Magento/Framework/Api/Code/Generator/Mapper.php
index 64d511448c03ff46aa1404b0d598721075c35f85..edd460f42bfd9deb68128a99da7f76353f290d68 100644
--- a/lib/internal/Magento/Framework/Api/Code/Generator/Mapper.php
+++ b/lib/internal/Magento/Framework/Api/Code/Generator/Mapper.php
@@ -31,7 +31,7 @@ class Mapper extends \Magento\Framework\Code\Generator\EntityAbstract
                     'tags' => [
                         [
                             'name' => 'var',
-                            'description' => $this->_getSourceClassName() . 'Builder',
+                            'description' => $this->getSourceClassName() . 'Builder',
                         ],
                     ],
                 ],
@@ -41,7 +41,7 @@ class Mapper extends \Magento\Framework\Code\Generator\EntityAbstract
                 'visibility' => 'protected',
                 'defaultValue' => [],
                 'docblock' => [
-                    'shortDescription' => $this->_getSourceClassName() . '[]',
+                    'shortDescription' => $this->getSourceClassName() . '[]',
                     'tags' => [['name' => 'var', 'description' => 'array']],
                 ]
             ],
@@ -56,8 +56,7 @@ class Mapper extends \Magento\Framework\Code\Generator\EntityAbstract
      */
     protected function _getSourceBuilderPropertyName()
     {
-        $parts = explode('\\', ltrim($this->_getSourceClassName(), '\\'));
-        return lcfirst(end($parts)) . 'Builder';
+        return lcfirst($this->getSourceClassNameWithoutNamespace()) . 'Builder';
     }
 
     /**
@@ -72,7 +71,7 @@ class Mapper extends \Magento\Framework\Code\Generator\EntityAbstract
             'parameters' => [
                 [
                     'name' => $this->_getSourceBuilderPropertyName(),
-                    'type' => $this->_getSourceClassName() . 'Builder',
+                    'type' => $this->getSourceClassName() . 'Builder',
                 ],
             ],
             'body' => "\$this->"
@@ -83,7 +82,7 @@ class Mapper extends \Magento\Framework\Code\Generator\EntityAbstract
                 'tags' => [
                     [
                         'name' => 'param',
-                        'description' => $this->_getSourceClassName() . " \$" . $this->_getSourceBuilderPropertyName(),
+                        'description' => $this->getSourceClassName() . " \$" . $this->_getSourceBuilderPropertyName(),
                     ],
                 ],
             ]
@@ -118,7 +117,7 @@ class Mapper extends \Magento\Framework\Code\Generator\EntityAbstract
                     ],
                     [
                         'name' => 'return',
-                        'description' => $this->_getSourceClassName(),
+                        'description' => $this->getSourceClassName(),
                     ],
                 ],
             ],
@@ -134,7 +133,7 @@ class Mapper extends \Magento\Framework\Code\Generator\EntityAbstract
         $result = parent::_validateData();
 
         if ($result) {
-            $sourceClassName = $this->_getSourceClassName();
+            $sourceClassName = $this->getSourceClassName();
             $resultClassName = $this->_getResultClassName();
 
             if ($resultClassName !== $sourceClassName . 'Mapper') {
diff --git a/lib/internal/Magento/Framework/Api/Code/Generator/SearchResults.php b/lib/internal/Magento/Framework/Api/Code/Generator/SearchResults.php
index c1613b0628dc93bcc9334438f45f47952521996c..32a4071ebf0c7aaa15f45c2a6cf966c91313472c 100644
--- a/lib/internal/Magento/Framework/Api/Code/Generator/SearchResults.php
+++ b/lib/internal/Magento/Framework/Api/Code/Generator/SearchResults.php
@@ -51,7 +51,7 @@ class SearchResults extends EntityAbstract
                 'tags' => [
                     [
                         'name' => 'return',
-                        'description' => $this->_getSourceClassName() . '[]',
+                        'description' => $this->getSourceClassName() . '[]',
                     ],
                 ],
             ],
diff --git a/lib/internal/Magento/Framework/Api/Config/MetadataConfig.php b/lib/internal/Magento/Framework/Api/Config/MetadataConfig.php
deleted file mode 100644
index 9bfb2eb651cdd0a0ec8c4ed6b806c9a1c7a1940e..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/Api/Config/MetadataConfig.php
+++ /dev/null
@@ -1,92 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\Framework\Api\Config;
-
-use Magento\Framework\Api\ObjectFactory;
-use Magento\Framework\Api\Config\Reader as ServiceConfigReader;
-use Magento\Framework\Api\MetadataServiceInterface;
-
-/**
- * Class which allows to get a metadata of the attributes declared in a config.
- */
-class MetadataConfig implements MetadataServiceInterface
-{
-    /**
-     * @var ServiceConfigReader
-     */
-    private $serviceConfigReader;
-
-    /**
-     * @var ObjectFactory
-     */
-    private $objectFactory;
-
-    /**
-     * @var array
-     */
-    private $allAttributes = [];
-
-    /**
-     * Initialize dependencies.
-     *
-     * @param ServiceConfigReader $serviceConfigReader
-     * @param ObjectFactory $objectFactory
-     */
-    public function __construct(
-        ServiceConfigReader $serviceConfigReader,
-        ObjectFactory $objectFactory
-    ) {
-        $this->serviceConfigReader = $serviceConfigReader;
-        $this->objectFactory = $objectFactory;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getCustomAttributesMetadata($dataObjectClassName = null)
-    {
-        $attributes = [];
-        if (!is_null($this->objectFactory) && !is_null($dataObjectClassName)) {
-            /**
-             * Attribute metadata builder and data object class name are expected to be configured
-             * via DI using virtual types. If configuration is missing, empty array should be returned.
-             */
-            $attributes = $this->getAttributesMetadata($dataObjectClassName);
-            $implementedInterfaces = (new \ReflectionClass($dataObjectClassName))->getInterfaceNames();
-            foreach ($implementedInterfaces as $interfaceName) {
-                $attributes = array_merge($attributes, $this->getAttributesMetadata($interfaceName));
-            }
-        }
-        return $attributes;
-    }
-
-    /**
-     * Get custom attribute metadata for the given class/interface.
-     *
-     * @param string $dataObjectClassName
-     * @return \Magento\Framework\Api\MetadataObjectInterface[]
-     */
-    protected function getAttributesMetadata($dataObjectClassName)
-    {
-        $attributes = [];
-        if (empty($this->allAttributes)) {
-            $this->allAttributes = $this->serviceConfigReader->read();
-        }
-        $dataObjectClassName = ltrim($dataObjectClassName, '\\');
-        if (isset($this->allAttributes[$dataObjectClassName])
-            && is_array($this->allAttributes[$dataObjectClassName])
-        ) {
-            $attributeCodes = array_keys($this->allAttributes[$dataObjectClassName]);
-            foreach ($attributeCodes as $attributeCode) {
-                $attributes[$attributeCode] = $this->objectFactory
-                    ->create('\Magento\Framework\Api\MetadataObjectInterface', [])
-                    ->setAttributeCode($attributeCode);
-            }
-        }
-        return $attributes;
-    }
-}
diff --git a/lib/internal/Magento/Framework/Api/CustomAttributesDataInterface.php b/lib/internal/Magento/Framework/Api/CustomAttributesDataInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..239066d34c0f9515b83a771f2d4711620e0309c6
--- /dev/null
+++ b/lib/internal/Magento/Framework/Api/CustomAttributesDataInterface.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\Api;
+
+/**
+ * Interface for entities which can be extended with custom attributes.
+ */
+interface CustomAttributesDataInterface extends ExtensibleDataInterface
+{
+    /**
+     * Array key for custom attributes
+     */
+    const CUSTOM_ATTRIBUTES = 'custom_attributes';
+
+    /**
+     * Get an attribute value.
+     *
+     * @param string $attributeCode
+     * @return \Magento\Framework\Api\AttributeInterface|null
+     */
+    public function getCustomAttribute($attributeCode);
+
+    /**
+     * Set an attribute value for a given attribute code
+     *
+     * @param string $attributeCode
+     * @param mixed $attributeValue
+     * @return $this
+     */
+    public function setCustomAttribute($attributeCode, $attributeValue);
+
+    /**
+     * Retrieve custom attributes values.
+     *
+     * @return \Magento\Framework\Api\AttributeInterface[]|null
+     */
+    public function getCustomAttributes();
+
+    /**
+     * Set array of custom attributes
+     *
+     * @param \Magento\Framework\Api\AttributeInterface[] $attributes
+     * @return $this
+     * @throws \LogicException
+     */
+    public function setCustomAttributes(array $attributes);
+}
diff --git a/lib/internal/Magento/Framework/Api/DataObjectHelper.php b/lib/internal/Magento/Framework/Api/DataObjectHelper.php
index 61d813a261d55ed5ef9e15211fcceb6e8d17de93..f7d16e57321607846234dcda516586e873ad75c2 100644
--- a/lib/internal/Magento/Framework/Api/DataObjectHelper.php
+++ b/lib/internal/Magento/Framework/Api/DataObjectHelper.php
@@ -23,19 +23,27 @@ class DataObjectHelper
      */
     protected $typeProcessor;
 
+    /**
+     * @var \Magento\Framework\Api\ExtensionAttributesFactory
+     */
+    protected $extensionFactory;
+
     /**
      * @param ObjectFactory $objectFactory
      * @param \Magento\Framework\Reflection\DataObjectProcessor $objectProcessor
      * @param \Magento\Framework\Reflection\TypeProcessor $typeProcessor
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      */
     public function __construct(
         ObjectFactory $objectFactory,
         \Magento\Framework\Reflection\DataObjectProcessor $objectProcessor,
-        \Magento\Framework\Reflection\TypeProcessor $typeProcessor
+        \Magento\Framework\Reflection\TypeProcessor $typeProcessor,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
     ) {
         $this->objectFactory = $objectFactory;
         $this->objectProcessor = $objectProcessor;
         $this->typeProcessor = $typeProcessor;
+        $this->extensionFactory = $extensionFactory;
     }
 
     /**
@@ -69,7 +77,7 @@ class DataObjectHelper
                 'set' . $camelCaseKey,
                 'setIs' . $camelCaseKey,
             ];
-            if ($key === ExtensibleDataInterface::CUSTOM_ATTRIBUTES
+            if ($key === CustomAttributesDataInterface::CUSTOM_ATTRIBUTES
                 && ($dataObject instanceof ExtensibleDataInterface)
                 && is_array($data[$key])
                 && !empty($data[$key])
@@ -83,7 +91,11 @@ class DataObjectHelper
             } elseif ($methodNames = array_intersect($possibleMethods, $dataObjectMethods)) {
                 $methodName = array_values($methodNames)[0];
                 if (!is_array($value)) {
-                    $dataObject->$methodName($value);
+                    if ($methodName === 'setExtensionAttributes' && is_null($value)) {
+                        // Cannot pass a null value to a method with a typed parameter
+                    } else {
+                        $dataObject->$methodName($value);
+                    }
                 } else {
                     $getterMethodName = 'get' . $camelCaseKey;
                     $this->setComplexValue($dataObject, $getterMethodName, $methodName, $value, $interfaceName);
@@ -137,6 +149,8 @@ class DataObjectHelper
         if (is_subclass_of($returnType, '\Magento\Framework\Api\ExtensibleDataInterface')) {
             $object = $this->objectFactory->create($returnType, []);
             $this->populateWithArray($object, $value, $returnType);
+        } else if (is_subclass_of($returnType, '\Magento\Framework\Api\ExtensionAttributesInterface')) {
+            $object = $this->extensionFactory->create(get_class($dataObject), $value);
         } else {
             $object = $this->objectFactory->create($returnType, $value);
         }
diff --git a/lib/internal/Magento/Framework/Api/DefaultMetadataService.php b/lib/internal/Magento/Framework/Api/DefaultMetadataService.php
new file mode 100644
index 0000000000000000000000000000000000000000..5a5d2e6a9e23365ad3f59c3ee9995e7269dbf2f9
--- /dev/null
+++ b/lib/internal/Magento/Framework/Api/DefaultMetadataService.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\Api;
+
+/**
+ * Default implementation of metadata service, which does not return any real attributes.
+ */
+class DefaultMetadataService implements MetadataServiceInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getCustomAttributesMetadata($dataObjectClassName = null)
+    {
+        return [];
+    }
+}
diff --git a/lib/internal/Magento/Framework/Api/ExtensibleDataInterface.php b/lib/internal/Magento/Framework/Api/ExtensibleDataInterface.php
index ba6efb39290912c10079cf2d9a3cb0bc83339f4c..6dd8f258b4db78768cf90ca0b9fd182d33f47587 100644
--- a/lib/internal/Magento/Framework/Api/ExtensibleDataInterface.php
+++ b/lib/internal/Magento/Framework/Api/ExtensibleDataInterface.php
@@ -7,45 +7,12 @@
 namespace Magento\Framework\Api;
 
 /**
- * Interface for entities which can be extended with custom attributes.
+ * Interface for entities which can be extended with extension attributes.
  */
 interface ExtensibleDataInterface
 {
     /**
-     * Array key for custom attributes
+     * Key for extension attributes object
      */
-    const CUSTOM_ATTRIBUTES = 'custom_attributes';
-
-    /**
-     * Get an attribute value.
-     *
-     * @param string $attributeCode
-     * @return \Magento\Framework\Api\AttributeInterface|null
-     */
-    public function getCustomAttribute($attributeCode);
-
-    /**
-     * Set an attribute value for a given attribute code
-     *
-     * @param string $attributeCode
-     * @param mixed $attributeValue
-     * @return $this
-     */
-    public function setCustomAttribute($attributeCode, $attributeValue);
-
-    /**
-     * Retrieve custom attributes values.
-     *
-     * @return \Magento\Framework\Api\AttributeInterface[]|null
-     */
-    public function getCustomAttributes();
-
-    /**
-     * Set array of custom attributes
-     *
-     * @param \Magento\Framework\Api\AttributeInterface[] $attributes
-     * @return $this
-     * @throws \LogicException
-     */
-    public function setCustomAttributes(array $attributes);
+    const EXTENSION_ATTRIBUTES_KEY = 'extension_attributes';
 }
diff --git a/lib/internal/Magento/Framework/Api/ExtensibleDataObjectConverter.php b/lib/internal/Magento/Framework/Api/ExtensibleDataObjectConverter.php
index 22cad52d286c54b40ee7c5546e49990d0772a0c6..2ad42cac8b20c4a49347928a84811aa788797c90 100644
--- a/lib/internal/Magento/Framework/Api/ExtensibleDataObjectConverter.php
+++ b/lib/internal/Magento/Framework/Api/ExtensibleDataObjectConverter.php
@@ -31,13 +31,13 @@ class ExtensibleDataObjectConverter
      * Convert AbstractExtensibleObject into a nested array.
      *
      * @param ExtensibleDataInterface $dataObject
-     * @param string[] $skipCustomAttributes
+     * @param string[] $skipAttributes
      * @param string $dataObjectType
      * @return array
      */
     public function toNestedArray(
         ExtensibleDataInterface $dataObject,
-        $skipCustomAttributes = [],
+        $skipAttributes = [],
         $dataObjectType = null
     ) {
         if ($dataObjectType == null) {
@@ -50,12 +50,22 @@ class ExtensibleDataObjectConverter
             $customAttributes = $dataObjectArray[AbstractExtensibleObject::CUSTOM_ATTRIBUTES_KEY];
             unset ($dataObjectArray[AbstractExtensibleObject::CUSTOM_ATTRIBUTES_KEY]);
             foreach ($customAttributes as $attributeValue) {
-                if (!in_array($attributeValue[AttributeValue::ATTRIBUTE_CODE], $skipCustomAttributes)) {
+                if (!in_array($attributeValue[AttributeValue::ATTRIBUTE_CODE], $skipAttributes)) {
                     $dataObjectArray[$attributeValue[AttributeValue::ATTRIBUTE_CODE]]
                         = $attributeValue[AttributeValue::VALUE];
                 }
             }
         }
+        if (!empty($dataObjectArray[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY])) {
+            /** @var array $extensionAttributes */
+            $extensionAttributes = $dataObjectArray[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY];
+            unset ($dataObjectArray[ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY]);
+            foreach ($extensionAttributes as $attributeKey => $attributeValue) {
+                if (!in_array($attributeKey, $skipAttributes)) {
+                    $dataObjectArray[$attributeKey] = $attributeValue;
+                }
+            }
+        }
         return $dataObjectArray;
     }
 
diff --git a/lib/internal/Magento/Framework/Api/ExtensionAttributesFactory.php b/lib/internal/Magento/Framework/Api/ExtensionAttributesFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..e50b83d11c7a95758ed9d8f07a4231419018e43a
--- /dev/null
+++ b/lib/internal/Magento/Framework/Api/ExtensionAttributesFactory.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\Api;
+
+/**
+ * Factory class for instantiation of extension attributes objects.
+ */
+class ExtensionAttributesFactory
+{
+    /**
+     * Object Manager instance
+     *
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $_objectManager = null;
+
+    /**
+     * Factory constructor
+     *
+     * @param \Magento\Framework\ObjectManagerInterface $objectManager
+     */
+    public function __construct(\Magento\Framework\ObjectManagerInterface $objectManager)
+    {
+        $this->_objectManager = $objectManager;
+    }
+
+    /**
+     * Create extension attributes object, custom for each extensible class.
+     *
+     * @param string $extensibleClassName
+     * @param array $data
+     * @return object
+     */
+    public function create($extensibleClassName, $data = [])
+    {
+        $modelReflection = new \ReflectionClass($extensibleClassName);
+
+        $implementsExtensibleInterface = false;
+        $extensibleInterfaceName = 'Magento\Framework\Api\ExtensibleDataInterface';
+        foreach ($modelReflection->getInterfaces() as $interfaceReflection) {
+            if ($interfaceReflection->isSubclassOf($extensibleInterfaceName)
+                && $interfaceReflection->hasMethod('getExtensionAttributes')
+            ) {
+                $implementsExtensibleInterface = true;
+                break;
+            }
+        }
+        if (!$implementsExtensibleInterface) {
+            throw new \LogicException(
+                "Class '{$extensibleClassName}' must implement an interface, "
+                . "which extends from 'Magento\\Framework\\Api\\ExtensibleDataInterface'"
+            );
+        }
+
+        $methodReflection = $interfaceReflection->getMethod('getExtensionAttributes');
+        if ($methodReflection->getDeclaringClass() == $extensibleInterfaceName) {
+            throw new \LogicException(
+                "Method 'getExtensionAttributes' must be overridden in the interfaces "
+                . "which extend 'Magento\\Framework\\Api\\ExtensibleDataInterface'. "
+                . "Concrete return type should be specified."
+            );
+        }
+
+        $interfaceName = '\\' . $interfaceReflection->getName();
+        $extensionClassName = substr($interfaceName, 0, -strlen('Interface')) . 'Extension';
+        $extensionInterfaceName = $extensionClassName . 'Interface';
+
+        /** Ensure that proper return type of getExtensionAttributes() method is specified */
+        $methodDocBlock = $methodReflection->getDocComment();
+        $pattern = "/@return\s+" . str_replace('\\', '\\\\', $extensionInterfaceName) . "/";
+        if (!preg_match($pattern, $methodDocBlock)) {
+            throw new \LogicException(
+                "Method 'getExtensionAttributes' must be overridden in the interfaces "
+                . "which extend 'Magento\\Framework\\Api\\ExtensibleDataInterface'. "
+                . "Concrete return type must be specified. Please fix :" . $interfaceName
+            );
+        }
+
+        $extensionFactoryName = $extensionClassName . 'Factory';
+        $extensionFactory = $this->_objectManager->create($extensionFactoryName);
+        return $extensionFactory->create($data);
+    }
+}
diff --git a/lib/internal/Magento/Framework/Api/ExtensionAttributesInterface.php b/lib/internal/Magento/Framework/Api/ExtensionAttributesInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..aef1607c31dae9747711da2459a0fffabf4028c8
--- /dev/null
+++ b/lib/internal/Magento/Framework/Api/ExtensionAttributesInterface.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\Api;
+
+/**
+ * Marker interface for all extension attributes interfaces.
+ */
+interface ExtensionAttributesInterface
+{
+}
diff --git a/lib/internal/Magento/Framework/Api/Filter.php b/lib/internal/Magento/Framework/Api/Filter.php
index e86ea49047d0ea34e29903f125edc4cf2474e3ed..b803e5fe926241667b8e1ae04969b6bc36e8fb23 100644
--- a/lib/internal/Magento/Framework/Api/Filter.php
+++ b/lib/internal/Magento/Framework/Api/Filter.php
@@ -6,11 +6,13 @@
 
 namespace Magento\Framework\Api;
 
+use Magento\Framework\Api\AbstractSimpleObject;
+
 /**
  * Filter which can be used by any methods from service layer.
  * @codeCoverageIgnore
  */
-class Filter extends AbstractExtensibleObject
+class Filter extends AbstractSimpleObject
 {
     /**#@+
      * Constants for Data Object keys
diff --git a/lib/internal/Magento/Framework/Api/Search/FilterGroup.php b/lib/internal/Magento/Framework/Api/Search/FilterGroup.php
index 860c36710ad0d9051f9ea6b02244abcbce785663..ae1dd308b647b51505a176987ec1ba8d2b6363c2 100644
--- a/lib/internal/Magento/Framework/Api/Search/FilterGroup.php
+++ b/lib/internal/Magento/Framework/Api/Search/FilterGroup.php
@@ -6,12 +6,12 @@
 
 namespace Magento\Framework\Api\Search;
 
-use Magento\Framework\Api\AbstractExtensibleObject;
+use Magento\Framework\Api\AbstractSimpleObject;
 
 /**
  * Groups two or more filters together using a logical OR
  */
-class FilterGroup extends AbstractExtensibleObject
+class FilterGroup extends AbstractSimpleObject
 {
     const FILTERS = 'filters';
 
diff --git a/lib/internal/Magento/Framework/Api/SearchCriteria.php b/lib/internal/Magento/Framework/Api/SearchCriteria.php
index a02d3e27dac79e7d75b9d3311cea7fe1f6b488f0..727be2cac88b47b98e73fc919a2cb47057997433 100644
--- a/lib/internal/Magento/Framework/Api/SearchCriteria.php
+++ b/lib/internal/Magento/Framework/Api/SearchCriteria.php
@@ -6,12 +6,11 @@
 
 namespace Magento\Framework\Api;
 
-
 /**
  * Data Object for SearchCriteria
  * @codeCoverageIgnore
  */
-class SearchCriteria extends AbstractExtensibleObject implements SearchCriteriaInterface
+class SearchCriteria extends AbstractSimpleObject implements SearchCriteriaInterface
 {
     /**#@+
      * Constants for Data Object keys
diff --git a/lib/internal/Magento/Framework/Api/SearchResults.php b/lib/internal/Magento/Framework/Api/SearchResults.php
index ad1481e9dde6afbc0b84349a111498e52913615a..8d5b998e99a6de80cdc0377230e58b6c36efe8a1 100644
--- a/lib/internal/Magento/Framework/Api/SearchResults.php
+++ b/lib/internal/Magento/Framework/Api/SearchResults.php
@@ -9,7 +9,7 @@ namespace Magento\Framework\Api;
 /**
  * SearchResults Service Data Object used for the search service requests
  */
-class SearchResults extends \Magento\Framework\Api\AbstractExtensibleObject
+class SearchResults extends AbstractSimpleObject
 {
     const KEY_ITEMS = 'items';
     const KEY_SEARCH_CRITERIA = 'search_criteria';
diff --git a/lib/internal/Magento/Framework/Api/SortOrder.php b/lib/internal/Magento/Framework/Api/SortOrder.php
index a29bac335b972f993ebcf9086450aa3d6b258e36..f328b93aa176399e1673206e4e58a0935d10d324 100644
--- a/lib/internal/Magento/Framework/Api/SortOrder.php
+++ b/lib/internal/Magento/Framework/Api/SortOrder.php
@@ -6,12 +6,11 @@
 
 namespace Magento\Framework\Api;
 
-
 /**
  * Data object for sort order.
  * @codeCoverageIgnore
  */
-class SortOrder extends AbstractExtensibleObject
+class SortOrder extends AbstractSimpleObject
 {
     const FIELD = 'field';
     const DIRECTION = 'direction';
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/ExtensionGeneratorTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/ExtensionAttributesGeneratorTest.php
similarity index 88%
rename from lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/ExtensionGeneratorTest.php
rename to lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/ExtensionAttributesGeneratorTest.php
index a7ae7e8a0b37dc4be67f76e8462211cb0eedaf89..5207a20588c73dcbf83aa767b907f585db8bb114 100644
--- a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/ExtensionGeneratorTest.php
+++ b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/ExtensionAttributesGeneratorTest.php
@@ -3,10 +3,10 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
+// @codingStandardsIgnoreFile
 namespace Magento\Framework\Api\Test\Unit\Code\Generator;
 
-class ExtensionGeneratorTest extends \PHPUnit_Framework_TestCase
+class ExtensionAttributesGeneratorTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * @var \Magento\Framework\Api\Config\Reader|\PHPUnit_Framework_MockObject_MockObject
@@ -14,7 +14,7 @@ class ExtensionGeneratorTest extends \PHPUnit_Framework_TestCase
     protected $configReaderMock;
 
     /**
-     * @var \Magento\Framework\Api\Code\Generator\ObjectExtension|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $model;
 
@@ -26,7 +26,7 @@ class ExtensionGeneratorTest extends \PHPUnit_Framework_TestCase
 
         $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
         $this->model = $objectManager->getObject(
-            'Magento\Framework\Api\Code\Generator\ObjectExtension',
+            'Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator',
             [
                 'configReader' => $this->configReaderMock,
                 'sourceClassName' => '\Magento\Catalog\Api\Data\Product',
@@ -68,9 +68,9 @@ class ExtensionGeneratorTest extends \PHPUnit_Framework_TestCase
     public function testValidateException()
     {
         $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
-        /** @var \Magento\Framework\Api\Code\Generator\ObjectExtension $model */
+        /** @var \Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator $model */
         $model = $objectManager->getObject(
-            'Magento\Framework\Api\Code\Generator\ObjectExtension',
+            'Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator',
             [
                 'sourceClassName' => '\Magento\Catalog\Api\Data\Product',
                 'resultClassName' => '\Magento\Catalog\Api\Data\ProductInterface'
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/ExtensionInterfaceGeneratorTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/ExtensionAttributesInterfaceGeneratorTest.php
similarity index 84%
rename from lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/ExtensionInterfaceGeneratorTest.php
rename to lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/ExtensionAttributesInterfaceGeneratorTest.php
index 80ee07f036b1d67cf546c9740cd23361e798ceaf..8f80baf39beeeec1955800e7ea4a51ac12d02382 100644
--- a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/ExtensionInterfaceGeneratorTest.php
+++ b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/ExtensionAttributesInterfaceGeneratorTest.php
@@ -3,10 +3,10 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
+// @codingStandardsIgnoreFile
 namespace Magento\Framework\Api\Test\Unit\Code\Generator;
 
-class ExtensionInterfaceGeneratorTest extends \PHPUnit_Framework_TestCase
+class ExtensionAttributesInterfaceGeneratorTest extends \PHPUnit_Framework_TestCase
 {
     public function testGenerate()
     {
@@ -28,9 +28,9 @@ class ExtensionInterfaceGeneratorTest extends \PHPUnit_Framework_TestCase
                 ]
             );
 
-        /** @var \Magento\Framework\Api\Code\Generator\ObjectExtensionInterface $model */
+        /** @var \Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator $model */
         $model = $objectManager->getObject(
-            'Magento\Framework\Api\Code\Generator\ObjectExtensionInterface',
+            'Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator',
             [
                 'configReader' => $configReaderMock,
                 'sourceClassName' => '\Magento\Catalog\Api\Data\Product',
@@ -49,9 +49,9 @@ class ExtensionInterfaceGeneratorTest extends \PHPUnit_Framework_TestCase
     public function testValidateException()
     {
         $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
-        /** @var \Magento\Framework\Api\Code\Generator\ObjectExtensionInterface $model */
+        /** @var \Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator $model */
         $model = $objectManager->getObject(
-            'Magento\Framework\Api\Code\Generator\ObjectExtensionInterface',
+            'Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator',
             [
                 'sourceClassName' => '\Magento\Catalog\Api\Data\Product',
                 'resultClassName' => '\Magento\Catalog\Api\Data\ProductInterface'
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleEmptyExtension.txt b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleEmptyExtension.txt
index 9cd99093c935725a6c8a9ba357b2ca7c508ddfe3..1605dad849f045361e5a4858b70d216bc8879c56 100644
--- a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleEmptyExtension.txt
+++ b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleEmptyExtension.txt
@@ -3,6 +3,6 @@ namespace Magento\Catalog\Api\Data;
 /**
  * Extension class for @see \Magento\Catalog\Api\Data\ProductInterface
  */
-class ProductExtension implements \Magento\Catalog\Api\Data\ProductExtensionInterface
+class ProductExtension extends \Magento\Framework\Api\AbstractSimpleObject implements \Magento\Catalog\Api\Data\ProductExtensionInterface
 {
 }
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleExtension.txt b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleExtension.txt
index 3ea82ea52c4c8d54079ef305f9a8c32d7c641711..8b5caad1ecc4456ae51380e25c735be8f2660d37 100644
--- a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleExtension.txt
+++ b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleExtension.txt
@@ -3,24 +3,14 @@ namespace Magento\Catalog\Api\Data;
 /**
  * Extension class for @see \Magento\Catalog\Api\Data\ProductInterface
  */
-class ProductExtension implements \Magento\Catalog\Api\Data\ProductExtensionInterface
+class ProductExtension extends \Magento\Framework\Api\AbstractSimpleObject implements \Magento\Catalog\Api\Data\ProductExtensionInterface
 {
-    /**
-     * @var string
-     */
-    protected $stringAttribute = null;
-
-    /**
-     * @var \Magento\Bundle\Api\Data\OptionInterface[]
-     */
-    protected $complexObjectAttribute = null;
-
     /**
      * @return string
      */
     public function getStringAttribute()
     {
-        return $this->stringAttribute;
+        return $this->_get('string_attribute');
     }
 
     /**
@@ -29,7 +19,7 @@ class ProductExtension implements \Magento\Catalog\Api\Data\ProductExtensionInte
      */
     public function setStringAttribute($stringAttribute)
     {
-        $this->stringAttribute = $stringAttribute;
+        $this->setData('string_attribute', $stringAttribute);
         return $this;
     }
 
@@ -38,7 +28,7 @@ class ProductExtension implements \Magento\Catalog\Api\Data\ProductExtensionInte
      */
     public function getComplexObjectAttribute()
     {
-        return $this->complexObjectAttribute;
+        return $this->_get('complex_object_attribute');
     }
 
     /**
@@ -47,7 +37,7 @@ class ProductExtension implements \Magento\Catalog\Api\Data\ProductExtensionInte
      */
     public function setComplexObjectAttribute($complexObjectAttribute)
     {
-        $this->complexObjectAttribute = $complexObjectAttribute;
+        $this->setData('complex_object_attribute', $complexObjectAttribute);
         return $this;
     }
 }
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleExtensionInterface.txt b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleExtensionInterface.txt
index a16dd05799e00b7be507c5abcce788400c292a1d..ec9edd7affc2d68e5444d914b833bff81ccc1d4d 100644
--- a/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleExtensionInterface.txt
+++ b/lib/internal/Magento/Framework/Api/Test/Unit/Code/Generator/_files/SampleExtensionInterface.txt
@@ -3,7 +3,7 @@ namespace Magento\Catalog\Api\Data;
 /**
  * ExtensionInterface class for @see \Magento\Catalog\Api\Data\ProductInterface
  */
-interface ProductExtensionInterface
+interface ProductExtensionInterface extends \Magento\Framework\Api\ExtensionAttributesInterface
 {
     /**
      * @return string
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/Config/MetadataConfigTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/Config/MetadataConfigTest.php
deleted file mode 100644
index bc310d2ee3acbc4044f64f71e4425dfda2af2aa7..0000000000000000000000000000000000000000
--- a/lib/internal/Magento/Framework/Api/Test/Unit/Config/MetadataConfigTest.php
+++ /dev/null
@@ -1,73 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Framework\Api\Test\Unit\Config;
-
-class MetadataConfigTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Framework\Api\Config\MetadataConfig
-     */
-    protected $metadataConfig;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Api\Config\Reader
-     */
-    protected $serviceConfigReaderMock;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Api\ObjectFactory
-     */
-    protected $objectFactoryMock;
-
-    /**
-     * Prepare parameters
-     */
-    public function setUp()
-    {
-        $this->serviceConfigReaderMock = $this->getMockBuilder('\Magento\Framework\Api\Config\Reader')
-            ->disableOriginalConstructor()
-            ->getMock();
-        $this->objectFactoryMock = $this->getMockBuilder(
-            '\Magento\Framework\Api\ObjectFactory'
-        )->setMethods(['create'])->disableOriginalConstructor()->getMock();
-
-        $this->metadataConfig = new \Magento\Framework\Api\Config\MetadataConfig(
-            $this->serviceConfigReaderMock,
-            $this->objectFactoryMock
-        );
-    }
-
-    /**
-     * Test caching
-     */
-    public function testCaching()
-    {
-        $dataObjectClassName = 'Magento\Customer\Model\Data\Address';
-        $attributeCode = 'street';
-        $allAttributes = [
-            $dataObjectClassName => [
-                $attributeCode => 'value',
-            ]
-        ];
-        $this->serviceConfigReaderMock->expects($this->once())
-            ->method('read')
-            ->willReturn($allAttributes);
-
-        $attributeMock = $this->getMock('\Magento\Framework\Api\MetadataObjectInterface');
-        $attributeMock->expects($this->exactly(2))
-            ->method('setAttributeCode')
-            ->with($attributeCode)
-            ->will($this->returnSelf());
-        $this->objectFactoryMock->expects($this->exactly(2))
-            ->method('create')
-            ->willReturn($attributeMock);
-
-        $attributes = $this->metadataConfig->getCustomAttributesMetadata($dataObjectClassName);
-        $this->assertEquals($attributeMock, $attributes[$attributeCode]);
-        $attributes = $this->metadataConfig->getCustomAttributesMetadata($dataObjectClassName);
-        $this->assertEquals($attributeMock, $attributes[$attributeCode]);
-    }
-}
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/DataObjectHelperTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/DataObjectHelperTest.php
index 1478deb7c41daf420af12deda53c97bed9368639..ff229abd7d22e9be0f810da4034336e5e9631f63 100644
--- a/lib/internal/Magento/Framework/Api/Test/Unit/DataObjectHelperTest.php
+++ b/lib/internal/Magento/Framework/Api/Test/Unit/DataObjectHelperTest.php
@@ -3,10 +3,13 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
+// @codingStandardsIgnoreFile
+
 namespace Magento\Framework\Api\Test\Unit;
 
-use \Magento\Framework\Api\ExtensibleDataInterface;
-use \Magento\Framework\Api\AttributeInterface;
+use Magento\Framework\Api\CustomAttributesDataInterface;
+use Magento\Framework\Api\AttributeInterface;
 
 class DataObjectHelperTest extends \PHPUnit_Framework_TestCase
 {
@@ -219,7 +222,7 @@ class DataObjectHelperTest extends \PHPUnit_Framework_TestCase
 
         $data = [
             'id' => $id,
-            ExtensibleDataInterface::CUSTOM_ATTRIBUTES => [
+            CustomAttributesDataInterface::CUSTOM_ATTRIBUTES => [
                 [
                     AttributeInterface::ATTRIBUTE_CODE => $customAttributeCode,
                     AttributeInterface::VALUE => $customAttributeValue,
diff --git a/lib/internal/Magento/Framework/App/ObjectManagerFactory.php b/lib/internal/Magento/Framework/App/ObjectManagerFactory.php
index 8c777c869e82417a90e684ed24db56a204feac2e..ddb68b8583ac41420e46d57f04302efd43797d4c 100644
--- a/lib/internal/Magento/Framework/App/ObjectManagerFactory.php
+++ b/lib/internal/Magento/Framework/App/ObjectManagerFactory.php
@@ -163,6 +163,7 @@ class ObjectManagerFactory
 
         $this->factory->setObjectManager($objectManager);
         ObjectManager::setInstance($objectManager);
+        $definitionFactory->getCodeGenerator()->setObjectManager($objectManager);
 
         $diConfig->setCache(
             $objectManager->get('Magento\Framework\App\ObjectManager\ConfigCache')
diff --git a/lib/internal/Magento/Framework/App/Test/Unit/Response/HttpTest.php b/lib/internal/Magento/Framework/App/Test/Unit/Response/HttpTest.php
index c1502736e273ec2e56af9c4faba802208d4172f3..26d126e7b5692febfe28dcad162c56fabd99d20b 100644
--- a/lib/internal/Magento/Framework/App/Test/Unit/Response/HttpTest.php
+++ b/lib/internal/Magento/Framework/App/Test/Unit/Response/HttpTest.php
@@ -3,6 +3,9 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
+// @codingStandardsIgnoreFile
+
 namespace Magento\Framework\App\Test\Unit\Response;
 
 use \Magento\Framework\App\Response\Http;
@@ -53,6 +56,9 @@ class HttpTest extends \PHPUnit_Framework_TestCase
     protected function tearDown()
     {
         unset($this->model);
+        $magentoObjectManagerFactory = \Magento\Framework\App\Bootstrap::createObjectManagerFactory(BP, $_SERVER);
+        $objectManager = $magentoObjectManagerFactory->create($_SERVER);
+        \Magento\Framework\App\ObjectManager::setInstance($objectManager);
     }
 
     public function testSendVary()
diff --git a/lib/internal/Magento/Framework/App/Utility/Classes.php b/lib/internal/Magento/Framework/App/Utility/Classes.php
index 197efbc95fb0a88104b727c3c3fbc53ce9184ba3..6671bd6a0464da30ef79dd001742cd2ff6ad43ef 100644
--- a/lib/internal/Magento/Framework/App/Utility/Classes.php
+++ b/lib/internal/Magento/Framework/App/Utility/Classes.php
@@ -272,7 +272,11 @@ class Classes
      */
     public static function isAutogenerated($className)
     {
-        if (preg_match('/.*\\\\[a-zA-Z0-9]{1,}(Factory|Proxy|SearchResults|DataBuilder)$/', $className)
+        if (
+            preg_match(
+                '/.*\\\\[a-zA-Z0-9]{1,}(Factory|Proxy|SearchResults|DataBuilder|Extension|ExtensionInterface)$/',
+                $className
+            )
             || preg_match('/Magento\\\\[\w]+\\\\(Test\\\\(Page|Fixture))\\\\/', $className)
         ) {
             return true;
diff --git a/lib/internal/Magento/Framework/Code/Generator.php b/lib/internal/Magento/Framework/Code/Generator.php
index 1339a790efc9b6fa0bdf67a1c9a65a234ef8d759..35026a88b69d1d66c4e10d913ea5b5fa35e2d155 100644
--- a/lib/internal/Magento/Framework/Code/Generator.php
+++ b/lib/internal/Magento/Framework/Code/Generator.php
@@ -31,6 +31,11 @@ class Generator
      */
     protected $definedClasses;
 
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
     /**
      * @param Generator\Io   $ioObject
      * @param array          $generatedEntities
@@ -86,18 +91,15 @@ class Generator
         }
         if (!$entity || !$entityName) {
             return self::GENERATION_ERROR;
-        }
-
-        if ($this->definedClasses->classLoadable($className)) {
+        } else if ($this->definedClasses->classLoadable($className)) {
             return self::GENERATION_SKIP;
-        }
-
-        if (!isset($this->_generatedEntities[$entity])) {
+        } else if (!isset($this->_generatedEntities[$entity])) {
             throw new \InvalidArgumentException('Unknown generation entity.');
         }
         $generatorClass = $this->_generatedEntities[$entity];
         /** @var EntityAbstract $generator */
         $generator = $this->createGeneratorInstance($generatorClass, $entityName, $className);
+        $this->tryToLoadSourceClass($className, $generator);
         if (!($file = $generator->generate())) {
             $errors = $generator->getErrors();
             throw new \Magento\Framework\Exception(implode(' ', $errors));
@@ -125,6 +127,57 @@ class Generator
      */
     protected function createGeneratorInstance($generatorClass, $entityName, $className)
     {
-        return new $generatorClass($entityName, $className, $this->_ioObject);
+        return $this->getObjectManager()->create(
+            $generatorClass,
+            ['sourceClassName' => $entityName, 'resultClassName' => $className, 'ioObject' => $this->_ioObject]
+        );
+    }
+
+    /**
+     * Set object manager instance.
+     *
+     * @param \Magento\Framework\ObjectManagerInterface $objectManager
+     * @return $this
+     */
+    public function setObjectManager(\Magento\Framework\ObjectManagerInterface $objectManager)
+    {
+        $this->objectManager = $objectManager;
+        return $this;
+    }
+
+    /**
+     * Get object manager instance.
+     *
+     * @return \Magento\Framework\ObjectManagerInterface
+     */
+    public function getObjectManager()
+    {
+        if (!($this->objectManager instanceof \Magento\Framework\ObjectManagerInterface)) {
+            throw new \LogicException(
+                "Object manager was expected to be set using setObjectManger() "
+                . "before getObjectManager() invocation."
+            );
+        }
+        return $this->objectManager;
+    }
+
+    /**
+     * Try to load/generate source class to check if it is valid or not.
+     *
+     * @param string $className
+     * @param \Magento\Framework\Code\Generator\EntityAbstract $generator
+     * @return void
+     * @throws \Magento\Framework\Exception
+     */
+    protected function tryToLoadSourceClass($className, $generator)
+    {
+        $sourceClassName = $generator->getSourceClassName();
+        if (!$this->definedClasses->classLoadable($sourceClassName)) {
+            if ($this->generateClass($sourceClassName) !== self::GENERATION_SUCCESS) {
+                throw new \Magento\Framework\Exception(
+                    sprintf('Source class "%s" for "%s" generation does not exist.', $sourceClassName, $className)
+                );
+            }
+        }
     }
 }
diff --git a/lib/internal/Magento/Framework/Code/Generator/EntityAbstract.php b/lib/internal/Magento/Framework/Code/Generator/EntityAbstract.php
index f98c4d689653fb007b7eec15e8ceec8228de39f1..20da9af1a5aaff1fa2904dac17a5f65f00069aea 100644
--- a/lib/internal/Magento/Framework/Code/Generator/EntityAbstract.php
+++ b/lib/internal/Magento/Framework/Code/Generator/EntityAbstract.php
@@ -121,15 +121,26 @@ abstract class EntityAbstract
     }
 
     /**
-     * Get source class name
+     * Get full source class name, with namespace
      *
      * @return string
      */
-    protected function _getSourceClassName()
+    public function getSourceClassName()
     {
         return $this->_sourceClassName;
     }
 
+    /**
+     * Get source class without namespace.
+     *
+     * @return string
+     */
+    public function getSourceClassNameWithoutNamespace()
+    {
+        $parts = explode('\\', ltrim($this->getSourceClassName(), '\\'));
+        return end($parts);
+    }
+
     /**
      * Get fully qualified class name
      *
@@ -234,7 +245,7 @@ abstract class EntityAbstract
      */
     protected function _validateData()
     {
-        $sourceClassName = $this->_getSourceClassName();
+        $sourceClassName = $this->getSourceClassName();
         $resultClassName = $this->_getResultClassName();
         $resultFileName = $this->_ioObject->getResultFileName($resultClassName);
 
@@ -292,7 +303,7 @@ abstract class EntityAbstract
      */
     protected function _getClassDocBlock()
     {
-        $description = ucfirst(static::ENTITY_TYPE) . ' class for @see ' . $this->_getSourceClassName();
+        $description = ucfirst(static::ENTITY_TYPE) . ' class for @see ' . $this->getSourceClassName();
         return ['shortDescription' => $description];
     }
 
diff --git a/lib/internal/Magento/Framework/Code/Test/Unit/GeneratorTest.php b/lib/internal/Magento/Framework/Code/Test/Unit/GeneratorTest.php
index 3e7d273a24d5c152dd778f824e538331c54e79de..efa21cde844f603a7e347bf46002d9b77312e529 100644
--- a/lib/internal/Magento/Framework/Code/Test/Unit/GeneratorTest.php
+++ b/lib/internal/Magento/Framework/Code/Test/Unit/GeneratorTest.php
@@ -3,6 +3,9 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
+// @codingStandardsIgnoreFile
+
 namespace Magento\Framework\Code\Test\Unit;
 
 class GeneratorTest extends \PHPUnit_Framework_TestCase
@@ -70,8 +73,12 @@ class GeneratorTest extends \PHPUnit_Framework_TestCase
                 'interceptor' => '\Magento\Framework\Interception\Code\Generator\Interceptor'
             ]
         );
-
-        $this->model->generateClass($className . $entityType);
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManagerInterface');
+        $fullClassName = $className . $entityType;
+        $entityGeneratorMock = $this->getMockBuilder($fullClassName)->disableOriginalConstructor()->getMock();
+        $objectManagerMock->expects($this->once())->method('create')->willReturn($entityGeneratorMock);
+        $this->model->setObjectManager($objectManagerMock);
+        $this->model->generateClass($fullClassName);
     }
 
     /**
@@ -125,7 +132,10 @@ class GeneratorTest extends \PHPUnit_Framework_TestCase
 
         $expectedEntities = array_values($this->expectedEntities);
         $resultClassName = self::SOURCE_CLASS . ucfirst(array_shift($expectedEntities));
-
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManagerInterface');
+        $entityGeneratorMock = $this->getMockBuilder($resultClassName)->disableOriginalConstructor()->getMock();
+        $objectManagerMock->expects($this->once())->method('create')->willReturn($entityGeneratorMock);
+        $this->model->setObjectManager($objectManagerMock);
         $this->model->generateClass($resultClassName);
     }
 
diff --git a/lib/internal/Magento/Framework/Interception/Code/Generator/Interceptor.php b/lib/internal/Magento/Framework/Interception/Code/Generator/Interceptor.php
index f0cb7cd637c48d9331fad0f8d0f4e6a890eb3389..2458a3cbd7518252b1d5671a5ec379445b87f0c1 100644
--- a/lib/internal/Magento/Framework/Interception/Code/Generator/Interceptor.php
+++ b/lib/internal/Magento/Framework/Interception/Code/Generator/Interceptor.php
@@ -83,7 +83,7 @@ class Interceptor extends \Magento\Framework\Code\Generator\EntityAbstract
      */
     protected function _getDefaultConstructorDefinition()
     {
-        $reflectionClass = new \ReflectionClass($this->_getSourceClassName());
+        $reflectionClass = new \ReflectionClass($this->getSourceClassName());
         $constructor = $reflectionClass->getConstructor();
         $parameters = [];
         if ($constructor) {
@@ -201,7 +201,7 @@ class Interceptor extends \Magento\Framework\Code\Generator\EntityAbstract
             "return \$result;\n",
         ];
 
-        $reflectionClass = new \ReflectionClass($this->_getSourceClassName());
+        $reflectionClass = new \ReflectionClass($this->getSourceClassName());
         $publicMethods = $reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC);
         foreach ($publicMethods as $method) {
             if ($this->isInterceptedMethod($method)) {
@@ -283,7 +283,7 @@ class Interceptor extends \Magento\Framework\Code\Generator\EntityAbstract
      */
     protected function _generateCode()
     {
-        $typeName = $this->_getSourceClassName();
+        $typeName = $this->getSourceClassName();
         $reflection = new \ReflectionClass($typeName);
 
         if ($reflection->isInterface()) {
@@ -302,7 +302,7 @@ class Interceptor extends \Magento\Framework\Code\Generator\EntityAbstract
         $result = parent::_validateData();
 
         if ($result) {
-            $sourceClassName = $this->_getSourceClassName();
+            $sourceClassName = $this->getSourceClassName();
             $resultClassName = $this->_getResultClassName();
 
             if ($resultClassName !== $sourceClassName . '\\Interceptor') {
diff --git a/lib/internal/Magento/Framework/Interception/Test/Unit/Config/ConfigTest.php b/lib/internal/Magento/Framework/Interception/Test/Unit/Config/ConfigTest.php
index f35ef42d6dc435af0b689f597276d22e4cdf9962..6c12758905634c325153a2b588ee72d08c5ad108 100644
--- a/lib/internal/Magento/Framework/Interception/Test/Unit/Config/ConfigTest.php
+++ b/lib/internal/Magento/Framework/Interception/Test/Unit/Config/ConfigTest.php
@@ -3,6 +3,7 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+// @codingStandardsIgnoreFile
 namespace Magento\Framework\Interception\Test\Unit\Config;
 
 require_once __DIR__ . '/../Custom/Module/Model/Item.php';
@@ -40,6 +41,11 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
      */
     protected $definitionMock;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $relationsMock;
+
     protected function setUp()
     {
         $this->readerMock = $this->getMock(
@@ -55,6 +61,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
             'Magento\Framework\Interception\ObjectManager\ConfigInterface'
         );
         $this->definitionMock = $this->getMock('Magento\Framework\ObjectManager\DefinitionInterface');
+        $this->relationsMock = $this->getMockForAbstractClass('Magento\Framework\ObjectManager\RelationsInterface');
     }
 
     /**
@@ -62,7 +69,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
      * @param string $type
      * @dataProvider hasPluginsDataProvider
      */
-    public function testHasPluginsWhenDataIsNotCached($expectedResult, $type)
+    public function testHasPluginsWhenDataIsNotCached($expectedResult, $type, $entityParents)
     {
         $readerMap = include __DIR__ . '/../_files/reader_mock_map.php';
         $this->readerMock->expects($this->any())
@@ -112,14 +119,17 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
         $this->definitionMock->expects($this->any())->method('getClasses')->will($this->returnValue(
             [
                 'Magento\Framework\Interception\Test\Unit\Custom\Module\Model\ItemProxy',
-                '\Magento\Framework\Interception\Custom\Module\Model\Backslash\ItemProxy',
+                'Magento\Framework\Interception\Custom\Module\Model\Backslash\ItemProxy',
             ]
         ));
+        $this->relationsMock->expects($this->any())->method('has')->will($this->returnValue($expectedResult));
+        $this->relationsMock->expects($this->any())->method('getParents')->will($this->returnValue($entityParents));
+
         $model = new \Magento\Framework\Interception\Config\Config(
             $this->readerMock,
             $this->configScopeMock,
             $this->cacheMock,
-            new \Magento\Framework\ObjectManager\Relations\Runtime(),
+            $this->relationsMock,
             $this->omConfigMock,
             $this->definitionMock,
             'interception'
@@ -170,27 +180,33 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
             [
                 true,
                 'Magento\Framework\Interception\Test\Unit\Custom\Module\Model\ItemContainer',
+                [],
             ],
             [
                 true,
                 'Magento\Framework\Interception\Test\Unit\Custom\Module\Model\Item',
+                [],
             ],
             [
                 true,
                 'Magento\Framework\Interception\Test\Unit\Custom\Module\Model\Item\Enhanced',
+                [],
             ],
             [
                 // the following model has only inherited plugins
                 true,
                 'Magento\Framework\Interception\Test\Unit\Custom\Module\Model\ItemContainer\Enhanced',
+                ['Magento\Framework\Interception\Test\Unit\Custom\Module\Model\ItemContainer'],
             ],
             [
                 false,
                 'Magento\Framework\Interception\Test\Unit\Custom\Module\Model\ItemProxy',
+                [],
             ],
             [
                 true,
                 'virtual_custom_item',
+                [],
             ]
         ];
     }
diff --git a/lib/internal/Magento/Framework/Model/AbstractExtensibleModel.php b/lib/internal/Magento/Framework/Model/AbstractExtensibleModel.php
index d69723ea8c5cef32357ea7e8766c24a69cf3bbb3..e5a84c89fa4ef60da3c42df09584990a53a1cced 100644
--- a/lib/internal/Magento/Framework/Model/AbstractExtensibleModel.php
+++ b/lib/internal/Magento/Framework/Model/AbstractExtensibleModel.php
@@ -6,11 +6,7 @@
 
 namespace Magento\Framework\Model;
 
-use Magento\Framework\Api\ExtensibleDataInterface;
-use Magento\Framework\Api\MetadataServiceInterface;
-use Magento\Framework\Api\AttributeValue;
 use Magento\Framework\Api\AttributeValueFactory;
-use Symfony\Component\DependencyInjection\Exception\LogicException;
 
 /**
  * Abstract model with custom attributes support.
@@ -19,12 +15,18 @@ use Symfony\Component\DependencyInjection\Exception\LogicException;
  * Implementations may choose to process custom attributes as their persistence requires them to.
  * @SuppressWarnings(PHPMD.NumberOfChildren)
  */
-abstract class AbstractExtensibleModel extends AbstractModel implements ExtensibleDataInterface
+abstract class AbstractExtensibleModel extends AbstractModel implements
+    \Magento\Framework\Api\CustomAttributesDataInterface
 {
     /**
-     * @var MetadataServiceInterface
+     * @var \Magento\Framework\Api\ExtensionAttributesFactory
      */
-    protected $metadataService;
+    protected $extensionAttributesFactory;
+
+    /**
+     * @var \Magento\Framework\Api\ExtensionAttributesInterface
+     */
+    protected $extensionAttributes;
 
     /**
      * @var AttributeValueFactory
@@ -39,7 +41,7 @@ abstract class AbstractExtensibleModel extends AbstractModel implements Extensib
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param MetadataServiceInterface $metadataService
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
      * @param AttributeValueFactory $customAttributeFactory
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
      * @param \Magento\Framework\Data\Collection\Db $resourceCollection
@@ -48,13 +50,13 @@ abstract class AbstractExtensibleModel extends AbstractModel implements Extensib
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        MetadataServiceInterface $metadataService,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
         AttributeValueFactory $customAttributeFactory,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
         \Magento\Framework\Data\Collection\Db $resourceCollection = null,
         array $data = []
     ) {
-        $this->metadataService = $metadataService;
+        $this->extensionAttributesFactory = $extensionFactory;
         $this->customAttributeFactory = $customAttributeFactory;
         $data = $this->filterCustomAttributes($data);
         parent::__construct($context, $registry, $resource, $resourceCollection, $data);
@@ -77,7 +79,7 @@ abstract class AbstractExtensibleModel extends AbstractModel implements Extensib
         $customAttributesCodes = $this->getCustomAttributesCodes();
         $data[self::CUSTOM_ATTRIBUTES] = array_intersect_key(
             (array)$data[self::CUSTOM_ATTRIBUTES],
-            $customAttributesCodes
+            array_flip($customAttributesCodes)
         );
         foreach ($data[self::CUSTOM_ATTRIBUTES] as $code => $value) {
             if (!($value instanceof \Magento\Framework\Api\AttributeInterface)) {
@@ -148,11 +150,12 @@ abstract class AbstractExtensibleModel extends AbstractModel implements Extensib
     {
         if (is_array($key)) {
             $key = $this->filterCustomAttributes($key);
-        } elseif ($key == self::CUSTOM_ATTRIBUTES) {
+        } else if ($key == self::CUSTOM_ATTRIBUTES) {
             $filteredData = $this->filterCustomAttributes([self::CUSTOM_ATTRIBUTES => $value]);
             $value = $filteredData[self::CUSTOM_ATTRIBUTES];
         }
-        return parent::setData($key, $value);
+        parent::setData($key, $value);
+        return $this;
     }
 
     /**
@@ -168,7 +171,7 @@ abstract class AbstractExtensibleModel extends AbstractModel implements Extensib
      *
      * In addition to parent implementation custom attributes support is added.
      *
-     * @param string     $key
+     * @param string $key
      * @param string|int $index
      * @return mixed
      */
@@ -194,26 +197,35 @@ abstract class AbstractExtensibleModel extends AbstractModel implements Extensib
     }
 
     /**
-     * Fetch all custom attributes for the given extensible model
-     * //TODO : check if the custom attribute is already defined as a getter on the data interface
+     * Get a list of custom attribute codes.
+     *
+     * By default, entity can be extended only using extension attributes functionality.
      *
      * @return string[]
      */
     protected function getCustomAttributesCodes()
     {
-        if (!is_null($this->customAttributesCodes)) {
-            return $this->customAttributesCodes;
-        }
+        return [];
+    }
+
+    /**
+     * Receive a list of EAV attributes using provided metadata service.
+     *
+     * Can be used in child classes, which represent EAV entities.
+     *
+     * @param \Magento\Framework\Api\MetadataServiceInterface $metadataService
+     * @return string[]
+     */
+    protected function getEavAttributesCodes(\Magento\Framework\Api\MetadataServiceInterface $metadataService)
+    {
         $attributeCodes = [];
-        $customAttributesMetadata = $this->metadataService->getCustomAttributesMetadata(get_class($this));
+        $customAttributesMetadata = $metadataService->getCustomAttributesMetadata(get_class($this));
         if (is_array($customAttributesMetadata)) {
             /** @var $attribute \Magento\Framework\Api\MetadataObjectInterface */
             foreach ($customAttributesMetadata as $attribute) {
-                // Create a map for easier processing
-                $attributeCodes[$attribute->getAttributeCode()] = $attribute->getAttributeCode();
+                $attributeCodes[] = $attribute->getAttributeCode();
             }
         }
-        $this->customAttributesCodes = $attributeCodes;
         return $attributeCodes;
     }
 
@@ -228,4 +240,26 @@ abstract class AbstractExtensibleModel extends AbstractModel implements Extensib
         parent::setId($value);
         return $this->setData('id', $value);
     }
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\Framework\Api\ExtensionAttributesInterface $extensionAttributes
+     * @return $this
+     */
+    protected function _setExtensionAttributes(\Magento\Framework\Api\ExtensionAttributesInterface $extensionAttributes)
+    {
+        $this->_data[self::EXTENSION_ATTRIBUTES_KEY] = $extensionAttributes;
+        return $this;
+    }
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\Framework\Api\ExtensionAttributesInterface
+     */
+    protected function _getExtensionAttributes()
+    {
+        return $this->getData(self::EXTENSION_ATTRIBUTES_KEY);
+    }
 }
diff --git a/lib/internal/Magento/Framework/Model/Test/Unit/AbstractExtensibleModelTest.php b/lib/internal/Magento/Framework/Model/Test/Unit/AbstractExtensibleModelTest.php
index 2d224e2d6cada6ba260a9d3d857e03b52b8832d4..df82d6f679446790dd0df79b6cf2633e6070053d 100644
--- a/lib/internal/Magento/Framework/Model/Test/Unit/AbstractExtensibleModelTest.php
+++ b/lib/internal/Magento/Framework/Model/Test/Unit/AbstractExtensibleModelTest.php
@@ -4,6 +4,8 @@
  * See COPYING.txt for license details.
  */
 
+// @codingStandardsIgnoreFile
+
 namespace Magento\Framework\Model\Test\Unit;
 
 use Magento\Framework\Api\AttributeValue;
@@ -98,6 +100,9 @@ class AbstractExtensibleModelTest extends \PHPUnit_Framework_TestCase
                     new \Magento\Framework\Object(['attribute_code' => 'attribute3']),
                 ]
             );
+        $extensionAttributesFactory = $this->getMockBuilder('Magento\Framework\Api\ExtensionAttributesFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
         $this->attributeValueFactoryMock = $this->getMockBuilder('Magento\Framework\Api\AttributeValueFactory')
             ->disableOriginalConstructor()
             ->getMock();
@@ -106,7 +111,7 @@ class AbstractExtensibleModelTest extends \PHPUnit_Framework_TestCase
             [
                 $this->contextMock,
                 $this->registryMock,
-                $this->metadataServiceMock,
+                $extensionAttributesFactory,
                 $this->attributeValueFactoryMock,
                 $this->resourceMock,
                 $this->resourceCollectionMock
@@ -130,10 +135,9 @@ class AbstractExtensibleModelTest extends \PHPUnit_Framework_TestCase
             "Null is expected as a result of getCustomAttribute(\$code) when custom attribute is not set."
         );
         $attributesAsArray = ['attribute1' => true, 'attribute2' => 'Attribute Value', 'attribute3' => 333];
-        $addedAttributes = $this->addCustomAttributesToModel($attributesAsArray, $this->model);
-        $addedAttributes = array_values($addedAttributes);
+        $this->addCustomAttributesToModel($attributesAsArray, $this->model);
         $this->assertEquals(
-            $addedAttributes,
+            [],
             $this->model->getCustomAttributes(),
             'Custom attributes retrieved from the model using getCustomAttributes() are invalid.'
         );
@@ -152,15 +156,13 @@ class AbstractExtensibleModelTest extends \PHPUnit_Framework_TestCase
         ];
         $modelData = ['key1' => 'value1', 'key2' => 222];
         $this->model->setData($modelData);
-        $addedAttributes = $this->addCustomAttributesToModel($attributesAsArray, $this->model);
-        $modelDataAsFlatArray = array_merge($modelData, $addedAttributes);
-        unset($modelDataAsFlatArray['invalid']);
+        $this->addCustomAttributesToModel($attributesAsArray, $this->model);
         $this->assertEquals(
-            $modelDataAsFlatArray,
+            $modelData,
             $this->model->getData(),
             'All model data should be represented as a flat array, including custom attributes.'
         );
-        foreach ($modelDataAsFlatArray as $field => $value) {
+        foreach ($modelData as $field => $value) {
             $this->assertEquals(
                 $value,
                 $this->model->getData($field),
@@ -174,7 +176,7 @@ class AbstractExtensibleModelTest extends \PHPUnit_Framework_TestCase
      */
     public function testRestrictedCustomAttributesGet()
     {
-        $this->model->getData(\Magento\Framework\Api\ExtensibleDataInterface::CUSTOM_ATTRIBUTES);
+        $this->model->getData(\Magento\Framework\Api\CustomAttributesDataInterface::CUSTOM_ATTRIBUTES);
     }
 
     public function testSetCustomAttributesAsLiterals()
@@ -184,18 +186,18 @@ class AbstractExtensibleModelTest extends \PHPUnit_Framework_TestCase
         $attributeMock = $this->getMockBuilder('\Magento\Framework\Api\AttributeValue')
             ->disableOriginalConstructor()
             ->getMock();
-        $attributeMock->expects($this->once())
+        $attributeMock->expects($this->never())
             ->method('setAttributeCode')
             ->with($attributeCode)
             ->will($this->returnSelf());
-        $attributeMock->expects($this->once())
+        $attributeMock->expects($this->never())
             ->method('setValue')
             ->with($attributeValue)
             ->will($this->returnSelf());
-        $this->attributeValueFactoryMock->expects($this->once())->method('create')
+        $this->attributeValueFactoryMock->expects($this->never())->method('create')
             ->willReturn($attributeMock);
         $this->model->setData(
-            \Magento\Framework\Api\ExtensibleDataInterface::CUSTOM_ATTRIBUTES,
+            \Magento\Framework\Api\CustomAttributesDataInterface::CUSTOM_ATTRIBUTES,
             [$attributeCode => $attributeValue]
         );
     }
@@ -219,7 +221,7 @@ class AbstractExtensibleModelTest extends \PHPUnit_Framework_TestCase
         $model->setData(
             array_merge(
                 $model->getData(),
-                [\Magento\Framework\Api\ExtensibleDataInterface::CUSTOM_ATTRIBUTES => $addedAttributes]
+                [\Magento\Framework\Api\CustomAttributesDataInterface::CUSTOM_ATTRIBUTES => $addedAttributes]
             )
         );
         return $addedAttributes;
diff --git a/lib/internal/Magento/Framework/Model/Test/Unit/Resource/Db/Collection/AbstractCollectionTest.php b/lib/internal/Magento/Framework/Model/Test/Unit/Resource/Db/Collection/AbstractCollectionTest.php
index e0dcd8a6d4da249be3d1d5ddfbbc90f56cb799c1..9d4540a26e896351957dd9bf08dd49454dfd842e 100644
--- a/lib/internal/Magento/Framework/Model/Test/Unit/Resource/Db/Collection/AbstractCollectionTest.php
+++ b/lib/internal/Magento/Framework/Model/Test/Unit/Resource/Db/Collection/AbstractCollectionTest.php
@@ -12,6 +12,9 @@ use Magento\Framework\Model\Resource\Db\Collection\AbstractCollection;
 use Magento\Framework\Object as MagentoObject;
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
 
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class AbstractCollectionTest extends \PHPUnit_Framework_TestCase
 {
     const TABLE_NAME = 'some_table';
@@ -78,6 +81,14 @@ class AbstractCollectionTest extends \PHPUnit_Framework_TestCase
         $this->uut = $this->getUut();
     }
 
+    protected function tearDown()
+    {
+        parent::tearDown();
+        $magentoObjectManagerFactory = \Magento\Framework\App\Bootstrap::createObjectManagerFactory(BP, $_SERVER);
+        $objectManager = $magentoObjectManagerFactory->create($_SERVER);
+        \Magento\Framework\App\ObjectManager::setInstance($objectManager);
+    }
+
     protected function getUut()
     {
         return $this->objectManagerHelper->getObject(
diff --git a/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Converter.php b/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Converter.php
index e2bca1d2086337a2a55a84c807024497fbc51107..65b02d8afce7189b5e4a912e2c3664c247f75276 100644
--- a/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Converter.php
+++ b/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Converter.php
@@ -47,8 +47,7 @@ class Converter extends \Magento\Framework\Code\Generator\EntityAbstract
      */
     protected function _getFactoryPropertyName()
     {
-        $parts = explode('\\', ltrim($this->_getSourceClassName(), '\\'));
-        return lcfirst(end($parts)) . 'Factory';
+        return lcfirst($this->getSourceClassNameWithoutNamespace()) . 'Factory';
     }
 
     /**
@@ -58,7 +57,7 @@ class Converter extends \Magento\Framework\Code\Generator\EntityAbstract
      */
     protected function _getFactoryClass()
     {
-        return $this->_getSourceClassName() . 'Factory';
+        return $this->getSourceClassName() . 'Factory';
     }
 
     /**
@@ -84,7 +83,7 @@ class Converter extends \Magento\Framework\Code\Generator\EntityAbstract
                 'tags' => [
                     [
                         'name' => 'param',
-                        'description' => $this->_getSourceClassName()
+                        'description' => $this->getSourceClassName()
                             . " \$" . $this->_getFactoryPropertyName(),
                     ],
                 ],
@@ -121,7 +120,7 @@ class Converter extends \Magento\Framework\Code\Generator\EntityAbstract
                     ],
                     [
                         'name' => 'return',
-                        'description' => $this->_getSourceClassName()
+                        'description' => $this->getSourceClassName()
                     ],
                 ],
             ],
@@ -138,7 +137,7 @@ class Converter extends \Magento\Framework\Code\Generator\EntityAbstract
             return false;
         }
 
-        $sourceClassName = $this->_getSourceClassName();
+        $sourceClassName = $this->getSourceClassName();
         $resultClassName = $this->_getResultClassName();
 
         if ($resultClassName !== $sourceClassName . 'Converter') {
diff --git a/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Factory.php b/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Factory.php
index 33a4e7ee10f7add76fb93baca44b46daa3c871fa..ee28a12c169a83a19fda2db50adf4a5993aae6ee 100644
--- a/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Factory.php
+++ b/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Factory.php
@@ -44,7 +44,7 @@ class Factory extends \Magento\Framework\Code\Generator\EntityAbstract
             'name' => '__construct',
             'parameters' => [
                 ['name' => 'objectManager', 'type' => '\Magento\Framework\ObjectManagerInterface'],
-                ['name' => 'instanceName', 'defaultValue' => $this->_getSourceClassName()],
+                ['name' => 'instanceName', 'defaultValue' => $this->getSourceClassName()],
             ],
             'body' => "\$this->_objectManager = \$objectManager;\n\$this->_instanceName = \$instanceName;",
             'docblock' => [
@@ -80,7 +80,7 @@ class Factory extends \Magento\Framework\Code\Generator\EntityAbstract
                     ['name' => 'param', 'description' => 'array $data'],
                     [
                         'name' => 'return',
-                        'description' => $this->_getSourceClassName()
+                        'description' => $this->getSourceClassName()
                     ],
                 ],
             ],
@@ -97,7 +97,7 @@ class Factory extends \Magento\Framework\Code\Generator\EntityAbstract
         $result = parent::_validateData();
 
         if ($result) {
-            $sourceClassName = $this->_getSourceClassName();
+            $sourceClassName = $this->getSourceClassName();
             $resultClassName = $this->_getResultClassName();
 
             if ($resultClassName !== $sourceClassName . 'Factory') {
diff --git a/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Persistor.php b/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Persistor.php
index 9b83cb681d80177ceed23136ae93038d4915c078..8c54a7c689a0ee6e3eb11eb1ef1922463a0a0860 100644
--- a/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Persistor.php
+++ b/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Persistor.php
@@ -34,7 +34,7 @@ class Persistor extends \Magento\Framework\Code\Generator\EntityAbstract
                     'tags' => [
                         [
                             'name' => 'var',
-                            'description' => $this->_getSourceClassName() . 'Factory',
+                            'description' => $this->getSourceClassName() . 'Factory',
                         ],
                     ],
                 ],
@@ -117,8 +117,7 @@ class Persistor extends \Magento\Framework\Code\Generator\EntityAbstract
      */
     protected function _getSourceFactoryPropertyName()
     {
-        $parts = explode('\\', ltrim($this->_getSourceClassName(), '\\'));
-        return lcfirst(end($parts)) . 'Factory';
+        return lcfirst($this->getSourceClassNameWithoutNamespace()) . 'Factory';
     }
 
     /**
@@ -127,8 +126,7 @@ class Persistor extends \Magento\Framework\Code\Generator\EntityAbstract
      */
     protected function _getSourceResourcePropertyName() // InvoiceResource
     {
-        $parts = explode('\\', ltrim($this->_getSourceClassName(), '\\'));
-        return lcfirst(end($parts)) . "Resource";
+        return lcfirst($this->getSourceClassNameWithoutNamespace()) . "Resource";
     }
 
     /**
@@ -138,7 +136,7 @@ class Persistor extends \Magento\Framework\Code\Generator\EntityAbstract
      */
     protected function _getSourceResourceClassName() // Invoice\Resource
     {
-        $temporary = str_replace('\\Api\\Data\\', '\\Model\\Spi\\', $this->_getSourceClassName());
+        $temporary = str_replace('\\Api\\Data\\', '\\Model\\Spi\\', $this->getSourceClassName());
         $parts = explode('\\', ltrim($temporary, '\\'));
         $className = array_pop($parts);
         $className = str_replace('Interface', '', $className);
@@ -180,7 +178,7 @@ class Persistor extends \Magento\Framework\Code\Generator\EntityAbstract
                 ],
                 [
                     'name' => $this->_getSourceFactoryPropertyName(),
-                    'type' => $this->_getSourceClassName() . 'Factory'
+                    'type' => $this->getSourceClassName() . 'Factory'
                 ],
                 [
                     'name' => 'resource',
@@ -205,7 +203,7 @@ class Persistor extends \Magento\Framework\Code\Generator\EntityAbstract
                     ],
                     [
                         'name' => 'param',
-                        'description' => $this->_getSourceClassName() . 'Factory'
+                        'description' => $this->getSourceClassName() . 'Factory'
                             . " \$" . $this->_getSourceFactoryPropertyName()
                     ],
                     [
@@ -295,7 +293,7 @@ class Persistor extends \Magento\Framework\Code\Generator\EntityAbstract
             'parameters' => [
                 [
                     'name' => 'entity',
-                    'type' => $this->_getSourceClassName(),
+                    'type' => $this->getSourceClassName(),
                 ],
             ],
             'body' => $body,
@@ -304,7 +302,7 @@ class Persistor extends \Magento\Framework\Code\Generator\EntityAbstract
                 'tags' => [
                     [
                         'name' => 'param',
-                        'description' => $this->_getSourceClassName() . " \$entity",
+                        'description' => $this->getSourceClassName() . " \$entity",
                     ],
                 ],
             ]
@@ -388,7 +386,7 @@ class Persistor extends \Magento\Framework\Code\Generator\EntityAbstract
             'parameters' => [
                 [
                     'name' => 'entity',
-                    'type' => $this->_getSourceClassName(),
+                    'type' => $this->getSourceClassName(),
                 ],
             ],
             'body' => $body,
@@ -397,7 +395,7 @@ class Persistor extends \Magento\Framework\Code\Generator\EntityAbstract
                 'tags' => [
                     [
                         'name' => 'param',
-                        'description' => $this->_getSourceClassName() . " \$entity",
+                        'description' => $this->getSourceClassName() . " \$entity",
                     ],
                 ],
             ]
@@ -431,7 +429,7 @@ class Persistor extends \Magento\Framework\Code\Generator\EntityAbstract
                     ],
                     [
                         'name' => 'param',
-                        'description' => $this->_getSourceClassName() . " \$entity",
+                        'description' => $this->getSourceClassName() . " \$entity",
                     ],
                 ],
             ]
@@ -457,7 +455,7 @@ class Persistor extends \Magento\Framework\Code\Generator\EntityAbstract
             'parameters' => [
                 [
                     'name' => 'entity',
-                    'type' => $this->_getSourceClassName(),
+                    'type' => $this->getSourceClassName(),
                 ],
             ],
             'body' => $body,
@@ -467,7 +465,7 @@ class Persistor extends \Magento\Framework\Code\Generator\EntityAbstract
 
                     [
                         'name' => 'param',
-                        'description' => $this->_getSourceClassName() . " \$entity",
+                        'description' => $this->getSourceClassName() . " \$entity",
                     ],
                 ],
             ]
@@ -482,7 +480,7 @@ class Persistor extends \Magento\Framework\Code\Generator\EntityAbstract
         $result = parent::_validateData();
 
         if ($result) {
-            $sourceClassName = $this->_getSourceClassName();
+            $sourceClassName = $this->getSourceClassName();
             $resultClassName = $this->_getResultClassName();
 
             if ($resultClassName !== $sourceClassName . 'Persistor') {
diff --git a/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Proxy.php b/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Proxy.php
index e09dcef74ac47445da2b4672d771539986110128..82686165132f8367f7999972af0e51c238e2cc8b 100644
--- a/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Proxy.php
+++ b/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Proxy.php
@@ -47,7 +47,7 @@ class Proxy extends \Magento\Framework\Code\Generator\EntityAbstract
             'visibility' => 'protected',
             'docblock' => [
                 'shortDescription' => 'Proxied instance',
-                'tags' => [['name' => 'var', 'description' => $this->_getSourceClassName()]],
+                'tags' => [['name' => 'var', 'description' => $this->getSourceClassName()]],
             ],
         ];
 
@@ -101,10 +101,10 @@ class Proxy extends \Magento\Framework\Code\Generator\EntityAbstract
             "return \$this->_subject;",
             'docblock' => [
                 'shortDescription' => 'Get proxied instance',
-                'tags' => [['name' => 'return', 'description' => $this->_getSourceClassName()]],
+                'tags' => [['name' => 'return', 'description' => $this->getSourceClassName()]],
             ],
         ];
-        $reflectionClass = new \ReflectionClass($this->_getSourceClassName());
+        $reflectionClass = new \ReflectionClass($this->getSourceClassName());
         $publicMethods = $reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC);
         foreach ($publicMethods as $method) {
             if (!($method->isConstructor() ||
@@ -127,7 +127,7 @@ class Proxy extends \Magento\Framework\Code\Generator\EntityAbstract
      */
     protected function _generateCode()
     {
-        $typeName = $this->_getSourceClassName();
+        $typeName = $this->getSourceClassName();
         $reflection = new \ReflectionClass($typeName);
 
         if ($reflection->isInterface()) {
@@ -181,7 +181,7 @@ class Proxy extends \Magento\Framework\Code\Generator\EntityAbstract
             'name' => '__construct',
             'parameters' => [
                 ['name' => 'objectManager', 'type' => '\Magento\Framework\ObjectManagerInterface'],
-                ['name' => 'instanceName', 'defaultValue' => $this->_getSourceClassName()],
+                ['name' => 'instanceName', 'defaultValue' => $this->getSourceClassName()],
                 ['name' => 'shared', 'defaultValue' => true],
             ],
             'body' => "\$this->_objectManager = \$objectManager;" .
@@ -225,7 +225,7 @@ class Proxy extends \Magento\Framework\Code\Generator\EntityAbstract
     {
         $result = parent::_validateData();
         if ($result) {
-            $sourceClassName = $this->_getSourceClassName();
+            $sourceClassName = $this->getSourceClassName();
             $resultClassName = $this->_getResultClassName();
 
             if ($resultClassName !== $sourceClassName . '\\Proxy') {
diff --git a/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Repository.php b/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Repository.php
index ce047eb4a6f693d23df1459070ba981e9c82fd34..22857fcf9bcfae8bfe3f0de7f675263cfdae33ee 100644
--- a/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Repository.php
+++ b/lib/internal/Magento/Framework/ObjectManager/Code/Generator/Repository.php
@@ -64,7 +64,7 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract
                 'visibility' => 'protected',
                 'defaultValue' => [],
                 'docblock' => [
-                    'shortDescription' => $this->_getSourceClassName() . '[]',
+                    'shortDescription' => $this->getSourceClassName() . '[]',
                     'tags' => [
                         [
                             'name' => 'var',
@@ -84,8 +84,7 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract
      */
     protected function _getSourcePersistorPropertyName()
     {
-        $parts = explode('\\', ltrim($this->_getSourceClassName(), '\\'));
-        return lcfirst(end($parts)) . 'Persistor';
+        return lcfirst($this->getSourceClassNameWithoutNamespace()) . 'Persistor';
     }
 
     /**
@@ -94,8 +93,7 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract
      */
     protected function _getSourceCollectionFactoryPropertyName()
     {
-        $parts = explode('\\', ltrim($this->_getSourceClassName(), '\\'));
-        return lcfirst(end($parts)) . 'SearchResultFactory';
+        return lcfirst($this->getSourceClassNameWithoutNamespace()) . 'SearchResultFactory';
     }
 
     /**
@@ -106,7 +104,7 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract
     protected function _getCollectionFactoryClassName()
     {
         return
-            str_replace('Interface', '', $this->_getSourceClassName()) . 'SearchResultInterfaceFactory';
+            str_replace('Interface', '', $this->getSourceClassName()) . 'SearchResultInterfaceFactory';
     }
     /**
      * Returns source persistor class name
@@ -115,7 +113,7 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract
      */
     protected function _getPersistorClassName()
     {
-        $target = $this->_getSourceClassName();
+        $target = $this->getSourceClassName();
 //        if (substr($target, -9) == 'Interface') {
 //            $target = substr($target, 1, strlen($target) -9);
 //        }
@@ -153,7 +151,7 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract
                 'tags' => [
                     [
                         'name' => 'param',
-                        'description' => $this->_getSourceClassName() . " \$" . $this->_getSourcePersistorPropertyName(),
+                        'description' => $this->getSourceClassName() . " \$" . $this->_getSourcePersistorPropertyName(),
                     ],
                     [
                         'name' => 'param',
@@ -202,7 +200,7 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract
                     ],
                     [
                         'name' => 'return',
-                        'description' => $this->_getSourceClassName(),
+                        'description' => $this->getSourceClassName(),
                     ],
                     [
                         'name' => 'throws',
@@ -263,7 +261,7 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract
             'parameters' => [
                 [
                     'name' => 'entity',
-                    'type' => $this->_getSourceClassName(),
+                    'type' => $this->getSourceClassName(),
                 ],
             ],
             'body' => $body,
@@ -276,7 +274,7 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract
                     ],
                     [
                         'name' => 'return',
-                        'description' => $this->_getSourceClassName(),
+                        'description' => $this->getSourceClassName(),
                     ],
                 ],
             ]
@@ -319,7 +317,7 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract
             'parameters' => [
                 [
                     'name' => 'entity',
-                    'type' => $this->_getSourceClassName(),
+                    'type' => $this->getSourceClassName(),
                 ],
             ],
             'body' => $body,
@@ -328,11 +326,11 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract
                 'tags' => [
                     [
                         'name' => 'param',
-                        'description' => $this->_getSourceClassName() . " \$entity",
+                        'description' => $this->getSourceClassName() . " \$entity",
                     ],
                     [
                         'name' => 'return',
-                        'description' => $this->_getSourceClassName(),
+                        'description' => $this->getSourceClassName(),
                     ],
                 ],
             ]
@@ -353,7 +351,7 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract
             'parameters' => [
                 [
                     'name' => 'entity',
-                    'type' => $this->_getSourceClassName(),
+                    'type' => $this->getSourceClassName(),
                 ],
             ],
             'body' => $body,
@@ -362,7 +360,7 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract
                 'tags' => [
                     [
                         'name' => 'param',
-                        'description' => $this->_getSourceClassName() . ' $entity',
+                        'description' => $this->getSourceClassName() . ' $entity',
                     ],
                 ],
             ]
@@ -413,7 +411,7 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract
             'parameters' => [
                 [
                     'name' => 'entity',
-                    'type' => $this->_getSourceClassName(),
+                    'type' => $this->getSourceClassName(),
                 ],
             ],
             'body' => $body,
@@ -422,7 +420,7 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract
                 'tags' => [
                     [
                         'name' => 'param',
-                        'description' => $this->_getSourceClassName() . ' $entity',
+                        'description' => $this->getSourceClassName() . ' $entity',
                     ],
                 ],
             ]
@@ -464,7 +462,7 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract
                     ],
                     [
                         'name' => 'return',
-                        'description' => $this->_getSourceClassName() . '[]',
+                        'description' => $this->getSourceClassName() . '[]',
                     ],
                 ],
             ]
@@ -500,7 +498,7 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract
         $result = parent::_validateData();
 
         if ($result) {
-            $sourceClassName = $this->_getSourceClassName();
+            $sourceClassName = $this->getSourceClassName();
             $resultClassName = $this->_getResultClassName();
 
             if ($resultClassName !== str_replace('Interface', '', $sourceClassName) . '\\Repository') {
@@ -520,7 +518,7 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract
      */
     protected function _generateCode()
     {
-        $className = str_replace('Interface', '', str_replace('Data\\', '', $this->_getSourceClassName()));
+        $className = str_replace('Interface', '', str_replace('Data\\', '', $this->getSourceClassName()));
         $this->_classGenerator->setName(
             $this->_getResultClassName()
         )->addProperties(
@@ -542,8 +540,8 @@ class Repository extends \Magento\Framework\Code\Generator\EntityAbstract
      *
      * @return string
      */
-    protected function _getSourceClassName()
+    public function getSourceClassName()
     {
-        return parent::_getSourceClassName() . 'Interface';
+        return parent::getSourceClassName() . 'Interface';
     }
 }
diff --git a/lib/internal/Magento/Framework/ObjectManager/DefinitionFactory.php b/lib/internal/Magento/Framework/ObjectManager/DefinitionFactory.php
index 626dbd548aab0f5a369f8dffd3cebe683598a27b..00aac17d300ed3522a3c1f0726186622a594875f 100644
--- a/lib/internal/Magento/Framework/ObjectManager/DefinitionFactory.php
+++ b/lib/internal/Magento/Framework/ObjectManager/DefinitionFactory.php
@@ -21,7 +21,8 @@ use Magento\Framework\ObjectManager\Definition\Compiled\Binary;
 use Magento\Framework\ObjectManager\Definition\Compiled\Serialized;
 use Magento\Framework\ObjectManager\Definition\Runtime;
 use Magento\Framework\ObjectManager\Profiler\Code\Generator as ProfilerGenerator;
-use Magento\Framework\Api\Code\Generator\ObjectExtensionInterface;
+use Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator;
+use Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -66,6 +67,11 @@ class DefinitionFactory
         Serialized::MODE_NAME => '\Magento\Framework\ObjectManager\Definition\Compiled\Serialized',
     ];
 
+    /**
+     * @var \Magento\Framework\Code\Generator
+     */
+    protected $codeGenerator;
+
     /**
      * @param DriverInterface $filesystemDriver
      * @param string $definitionDir
@@ -95,26 +101,7 @@ class DefinitionFactory
             $definitionModel = $this->_definitionClasses[$this->_definitionFormat];
             $result = new $definitionModel($definitions);
         } else {
-            $generatorIo = new \Magento\Framework\Code\Generator\Io(
-                $this->_filesystemDriver,
-                $this->_generationDir
-            );
-            $generator = new \Magento\Framework\Code\Generator(
-                $generatorIo,
-                [
-                    Generator\Factory::ENTITY_TYPE => '\Magento\Framework\ObjectManager\Code\Generator\Factory',
-                    Generator\Proxy::ENTITY_TYPE => '\Magento\Framework\ObjectManager\Code\Generator\Proxy',
-                    Generator\Repository::ENTITY_TYPE => '\Magento\Framework\ObjectManager\Code\Generator\Repository',
-                    Generator\Persistor::ENTITY_TYPE => '\Magento\Framework\ObjectManager\Code\Generator\Persistor',
-                    InterceptionGenerator\Interceptor::ENTITY_TYPE => '\Magento\Framework\Interception\Code\Generator\Interceptor',
-                    MapperGenerator::ENTITY_TYPE => '\Magento\Framework\Api\Code\Generator\Mapper',
-                    SearchResults::ENTITY_TYPE => '\Magento\Framework\Api\Code\Generator\SearchResults',
-                    ConverterGenerator::ENTITY_TYPE => '\Magento\Framework\ObjectManager\Code\Generator\Converter',
-                    ProfilerGenerator\Logger::ENTITY_TYPE => '\Magento\Framework\ObjectManager\Profiler\Code\Generator\Logger',
-                    ObjectExtensionInterface::ENTITY_TYPE =>
-                        'Magento\Framework\Api\Code\Generator\ObjectExtensionInterface'                ]
-            );
-            $autoloader = new \Magento\Framework\Code\Generator\Autoloader($generator);
+            $autoloader = new \Magento\Framework\Code\Generator\Autoloader($this->getCodeGenerator());
             spl_autoload_register([$autoloader, 'load']);
 
             $result = new Runtime();
@@ -167,4 +154,36 @@ class DefinitionFactory
         $extractor = $this->_definitionFormat == Binary::MODE_NAME ? 'igbinary_unserialize' : 'unserialize';
         return $extractor($definitions);
     }
+
+    /**
+     * Get existing code generator. Instantiate a new one if it does not exist yet.
+     *
+     * @return \Magento\Framework\Code\Generator
+     */
+    public function getCodeGenerator()
+    {
+        if (!$this->codeGenerator) {
+            $generatorIo = new \Magento\Framework\Code\Generator\Io(
+                $this->_filesystemDriver,
+                $this->_generationDir
+            );
+            $this->codeGenerator = new \Magento\Framework\Code\Generator(
+                $generatorIo,
+                [
+                    Generator\Factory::ENTITY_TYPE => '\Magento\Framework\ObjectManager\Code\Generator\Factory',
+                    Generator\Proxy::ENTITY_TYPE => '\Magento\Framework\ObjectManager\Code\Generator\Proxy',
+                    Generator\Repository::ENTITY_TYPE => '\Magento\Framework\ObjectManager\Code\Generator\Repository',
+                    Generator\Persistor::ENTITY_TYPE => '\Magento\Framework\ObjectManager\Code\Generator\Persistor',
+                    InterceptionGenerator\Interceptor::ENTITY_TYPE => '\Magento\Framework\Interception\Code\Generator\Interceptor',
+                    MapperGenerator::ENTITY_TYPE => '\Magento\Framework\Api\Code\Generator\Mapper',
+                    SearchResults::ENTITY_TYPE => '\Magento\Framework\Api\Code\Generator\SearchResults',
+                    ConverterGenerator::ENTITY_TYPE => '\Magento\Framework\ObjectManager\Code\Generator\Converter',
+                    ProfilerGenerator\Logger::ENTITY_TYPE => '\Magento\Framework\ObjectManager\Profiler\Code\Generator\Logger',
+                    ExtensionAttributesGenerator::ENTITY_TYPE => 'Magento\Framework\Api\Code\Generator\ExtensionAttributesGenerator',
+                    ExtensionAttributesInterfaceGenerator::ENTITY_TYPE => 'Magento\Framework\Api\Code\Generator\ExtensionAttributesInterfaceGenerator'
+                ]
+            );
+        }
+        return $this->codeGenerator;
+    }
 }
diff --git a/lib/internal/Magento/Framework/ObjectManager/Profiler/Code/Generator/Logger.php b/lib/internal/Magento/Framework/ObjectManager/Profiler/Code/Generator/Logger.php
index c30507a345a4225b46c4c272dcee7a4e243c390a..c8336a6ad15eb52152b7ab41e77c6cbef5d78182 100644
--- a/lib/internal/Magento/Framework/ObjectManager/Profiler/Code/Generator/Logger.php
+++ b/lib/internal/Magento/Framework/ObjectManager/Profiler/Code/Generator/Logger.php
@@ -116,7 +116,7 @@ class Logger extends \Magento\Framework\Code\Generator\EntityAbstract
                 . "\n\$this->log->add(\$this->subject);",
         ];
 
-        $reflectionClass = new \ReflectionClass($this->_getSourceClassName());
+        $reflectionClass = new \ReflectionClass($this->getSourceClassName());
         $publicMethods   = $reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC);
         foreach ($publicMethods as $method) {
             if (!($method->isConstructor() || $method->isFinal() || $method->isStatic() || $method->isDestructor())
@@ -183,7 +183,7 @@ class Logger extends \Magento\Framework\Code\Generator\EntityAbstract
      */
     protected function _generateCode()
     {
-        $typeName = $this->_getSourceClassName();
+        $typeName = $this->getSourceClassName();
         $reflection = new \ReflectionClass($typeName);
 
         if ($reflection->isInterface()) {
@@ -202,7 +202,7 @@ class Logger extends \Magento\Framework\Code\Generator\EntityAbstract
         $result = parent::_validateData();
 
         if ($result) {
-            $sourceClassName = $this->_getSourceClassName();
+            $sourceClassName = $this->getSourceClassName();
             $resultClassName = $this->_getResultClassName();
 
             if ($resultClassName !== $sourceClassName . '\\Logger') {
diff --git a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Relations/RuntimeTest.php b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Relations/RuntimeTest.php
index 7309a4b1a67ba16f2c83524882f9427c6aedaf54..3fde1b24d33603ef8159914db3ec962de5c9299b 100644
--- a/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Relations/RuntimeTest.php
+++ b/lib/internal/Magento/Framework/ObjectManager/Test/Unit/Relations/RuntimeTest.php
@@ -3,6 +3,9 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+
+// @codingStandardsIgnoreFile
+
 namespace Magento\Framework\ObjectManager\Test\Unit\Relations;
 
 require_once __DIR__ . '/../_files/Child.php';
@@ -36,4 +39,25 @@ class RuntimeTest extends \PHPUnit_Framework_TestCase
             ['Magento\Test\Di\Child', ['Magento\Test\Di\DiParent', 'Magento\Test\Di\ChildInterface']]
         ];
     }
+
+    /**
+     * @param $entity
+     * @expectedException  \Magento\Framework\Exception
+     * @dataProvider nonExistentGeneratorsDataProvider
+     */
+    public function testHasIfNonExists($entity)
+    {
+        $this->_model->has($entity);
+    }
+
+    public function nonExistentGeneratorsDataProvider()
+    {
+        return [
+            ['Magento\Test\Module\Model\Item\Factory'],
+            ['Magento\Test\Module\Model\Item\Proxy'],
+            ['Magento\Test\Module\Model\Item\Interceptor'],
+            ['Magento\Test\Module\Model\Item\Mapper'],
+            ['Magento\Test\Module\Model\Item\SearchResults']
+        ];
+    }
 }
diff --git a/lib/internal/Magento/Framework/Reflection/DataObjectProcessor.php b/lib/internal/Magento/Framework/Reflection/DataObjectProcessor.php
index c1d58952de1c9d4006c947a6fa34de1aeb427f48..2b9977d7355f565e808b15cc539c7c892f38afa6 100644
--- a/lib/internal/Magento/Framework/Reflection/DataObjectProcessor.php
+++ b/lib/internal/Magento/Framework/Reflection/DataObjectProcessor.php
@@ -8,7 +8,7 @@ namespace Magento\Framework\Reflection;
 
 use Magento\Framework\Phrase;
 use Magento\Framework\Api\AttributeValue;
-use Magento\Framework\Api\ExtensibleDataInterface;
+use Magento\Framework\Api\CustomAttributesDataInterface;
 use Magento\Framework\Api\SimpleDataObjectConverter;
 use Zend\Code\Reflection\ClassReflection;
 use Zend\Code\Reflection\MethodReflection;
@@ -108,7 +108,7 @@ class DataObjectProcessor
                     continue;
                 }
                 $key = SimpleDataObjectConverter::camelCaseToSnakeCase(substr($methodName, 3));
-                if ($key === ExtensibleDataInterface::CUSTOM_ATTRIBUTES) {
+                if ($key === CustomAttributesDataInterface::CUSTOM_ATTRIBUTES) {
                     $value = $this->convertCustomAttributes($value, $dataObjectType);
                 } elseif (is_object($value) && !($value instanceof Phrase)) {
                     $value = $this->buildOutputDataArray($value, $returnType);
@@ -304,10 +304,7 @@ class DataObjectProcessor
         $isSuitableMethodType = !($method->isConstructor() || $method->isFinal()
             || $method->isStatic() || $method->isDestructor());
 
-        $isExcludedMagicMethod = in_array(
-            $method->getName(),
-            ['__sleep', '__wakeup', '__clone']
-        );
+        $isExcludedMagicMethod = strpos($method->getName(), '__') === 0;
         return $isSuitableMethodType && !$isExcludedMagicMethod;
     }
 }
diff --git a/lib/internal/Magento/Framework/Reflection/Test/Unit/TypeProcessorTest.php b/lib/internal/Magento/Framework/Reflection/Test/Unit/TypeProcessorTest.php
index 56cd942eac6de82fab4b43f450ead4b7901e23a9..496416ff379e4f24a877ddb27fabe17a5535e104 100644
--- a/lib/internal/Magento/Framework/Reflection/Test/Unit/TypeProcessorTest.php
+++ b/lib/internal/Magento/Framework/Reflection/Test/Unit/TypeProcessorTest.php
@@ -3,6 +3,7 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+// @codingStandardsIgnoreStart
 namespace Magento\Framework\Reflection\Test\Unit;
 
 use Zend\Code\Reflection\ClassReflection;
@@ -174,7 +175,7 @@ class TypeProcessorTest extends \PHPUnit_Framework_TestCase
 
     /**
      * @expectedException \Magento\Framework\Exception\SerializationException
-     * @expectedExceptionMessage Invalid type for value :"1". Expected Type: "int[]".
+     * @expectedExceptionMessage Invalid type for value :"integer". Expected Type: "int[]".
      */
     public function testProcessSimpleTypeInvalidType()
     {
diff --git a/lib/internal/Magento/Framework/Reflection/TypeProcessor.php b/lib/internal/Magento/Framework/Reflection/TypeProcessor.php
index 0a29b8210793f5aecb46857e518da251a4278b82..38d65da521c7b9aee6e3d92a6948e55ebc1adc32 100644
--- a/lib/internal/Magento/Framework/Reflection/TypeProcessor.php
+++ b/lib/internal/Magento/Framework/Reflection/TypeProcessor.php
@@ -241,11 +241,17 @@ class TypeProcessor
     {
         $methodDocBlock = $methodReflection->getDocBlock();
         if (!$methodDocBlock) {
-            throw new \InvalidArgumentException('Each getter must have description with @return annotation.');
+            throw new \InvalidArgumentException(
+                "Each getter must have description with @return annotation. "
+                . "See {$methodReflection->getDeclaringClass()->getName()}::{$methodReflection->getName()}()"
+            );
         }
         $returnAnnotations = $methodDocBlock->getTags('return');
         if (empty($returnAnnotations)) {
-            throw new \InvalidArgumentException('Getter return type must be specified using @return annotation.');
+            throw new \InvalidArgumentException(
+                "Getter return type must be specified using @return annotation. "
+                . "See {$methodReflection->getDeclaringClass()->getName()}::{$methodReflection->getName()}()"
+            );
         }
         /** @var \Zend\Code\Reflection\DocBlock\Tag\ReturnTag $returnAnnotation */
         $returnAnnotation = current($returnAnnotations);
@@ -441,7 +447,7 @@ class TypeProcessor
         } else {
             throw new SerializationException(
                 SerializationException::TYPE_MISMATCH,
-                ['value' => (string)$value, 'type' => $type]
+                ['value' => gettype($value), 'type' => $type]
             );
         }
         return $value;
diff --git a/lib/internal/Magento/Framework/Webapi/ServiceInputProcessor.php b/lib/internal/Magento/Framework/Webapi/ServiceInputProcessor.php
index df8c25b15d4b2459d999d9214d626a79ac65e8f3..2298ea27fdfc6c08ef9d69e37981b2fc3d9d7cc1 100644
--- a/lib/internal/Magento/Framework/Webapi/ServiceInputProcessor.php
+++ b/lib/internal/Magento/Framework/Webapi/ServiceInputProcessor.php
@@ -30,6 +30,8 @@ class ServiceInputProcessor
 {
     const CACHE_ID_PREFIX = 'service_method_params_';
 
+    const EXTENSION_ATTRIBUTES_TYPE = '\Magento\Framework\Api\ExtensionAttributesInterface';
+
     /** @var \Magento\Framework\Reflection\TypeProcessor */
     protected $typeProcessor;
 
@@ -126,12 +128,15 @@ class ServiceInputProcessor
      * @param string $className
      * @param array $data
      * @return object the newly created and populated object
+     * @throws \Exception
      */
     protected function _createFromArray($className, $data)
     {
         $data = is_array($data) ? $data : [];
         $class = new ClassReflection($className);
-
+        if (is_subclass_of($className, self::EXTENSION_ATTRIBUTES_TYPE)) {
+            $className = substr($className, 0, -strlen('Interface'));
+        }
         $factory = $this->objectManager->get($className . 'Factory');
         $object = $factory->create();
 
diff --git a/lib/internal/Magento/Framework/Webapi/Test/Unit/ServiceInputProcessorTest.php b/lib/internal/Magento/Framework/Webapi/Test/Unit/ServiceInputProcessorTest.php
index cccc983e642301d3eef8083d04c836735d118ec3..41cdf8184ba372143f8ed2fdde2ff790f8633fa0 100644
--- a/lib/internal/Magento/Framework/Webapi/Test/Unit/ServiceInputProcessorTest.php
+++ b/lib/internal/Magento/Framework/Webapi/Test/Unit/ServiceInputProcessorTest.php
@@ -8,11 +8,11 @@
 
 namespace Magento\Framework\Webapi\Test\Unit;
 
-use \Magento\Framework\Webapi\ServiceInputProcessor;
-use \Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\WebapiBuilderFactory;
+use Magento\Framework\Webapi\ServiceInputProcessor;
+use Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\WebapiBuilderFactory;
 use Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\AssociativeArray;
 use Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\DataArray;
-use \Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\ObjectWithCustomAttributes;
+use Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\ObjectWithCustomAttributes;
 use Magento\Webapi\Test\Unit\Service\Entity\DataArrayData;
 use Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\Nested;
 use Magento\Webapi\Test\Unit\Service\Entity\NestedData;
@@ -167,7 +167,7 @@ class ServiceInputProcessorTest extends \PHPUnit_Framework_TestCase
 
     public function testAssociativeArrayProperties()
     {
-        $this->setupFactory(['\Magento\Webapi\Service\Entity\Simple']);
+        $this->setupFactory(['Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\Simple']);
         $data = ['associativeArray' => ['key' => 'value', 'key_two' => 'value_two']];
         $result = $this->serviceInputProcessor->process(
             'Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\TestService',
@@ -186,7 +186,7 @@ class ServiceInputProcessorTest extends \PHPUnit_Framework_TestCase
 
     public function testAssociativeArrayPropertiesWithItem()
     {
-        $this->setupFactory(['Magento\Webapi\Service\Entity\AssociativeArray']);
+        $this->setupFactory(['Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\AssociativeArray']);
         $data = ['associativeArray' => ['item' => 'value']];
         $result = $this->serviceInputProcessor->process(
             'Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\TestService',
@@ -204,7 +204,7 @@ class ServiceInputProcessorTest extends \PHPUnit_Framework_TestCase
 
     public function testAssociativeArrayPropertiesWithItemArray()
     {
-        $this->setupFactory(['Magento\Webapi\Service\Entity\AssociativeArray']);
+        $this->setupFactory(['Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\AssociativeArray']);
         $data = ['associativeArray' => ['item' => ['value1','value2']]];
         $result = $this->serviceInputProcessor->process(
             'Magento\Framework\Webapi\Test\Unit\ServiceInputProcessor\TestService',
@@ -529,6 +529,7 @@ class ServiceInputProcessorTest extends \PHPUnit_Framework_TestCase
         foreach ($classNames as $className) {
             $factoryMock = $this->getMockBuilder($className . 'Factory')
                 ->setMethods(['create'])
+                ->disableOriginalConstructor()
                 ->getMock();
             $factoryMock->expects($this->any())
                 ->method('create')