diff --git a/app/code/Magento/Integration/Model/Config.php b/app/code/Magento/Integration/Model/Config.php
index 70795cae0035034a7801c6a21cc3bb90ab566e1f..3cea4d33743198988c44d8c8aae9bf6e9f247efa 100644
--- a/app/code/Magento/Integration/Model/Config.php
+++ b/app/code/Magento/Integration/Model/Config.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Integration\Model;
 
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Serialize\SerializerInterface;
 use Magento\Integration\Model\Cache\Type;
 
 /**
@@ -34,14 +36,24 @@ class Config
      */
     protected $_integrations;
 
+    /**
+     * @var SerializerInterface
+     */
+    private $serializer;
+
     /**
      * @param Cache\Type $configCacheType
      * @param Config\Reader $configReader
+     * @param SerializerInterface $serializer
      */
-    public function __construct(Cache\Type $configCacheType, Config\Reader $configReader)
-    {
+    public function __construct(
+        Cache\Type $configCacheType,
+        Config\Reader $configReader,
+        SerializerInterface $serializer = null
+    ) {
         $this->_configCacheType = $configCacheType;
         $this->_configReader = $configReader;
+        $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
     }
 
     /**
@@ -55,10 +67,14 @@ class Config
         if (null === $this->_integrations) {
             $integrations = $this->_configCacheType->load(self::CACHE_ID);
             if ($integrations && is_string($integrations)) {
-                $this->_integrations = unserialize($integrations);
+                $this->_integrations = $this->serializer->unserialize($integrations);
             } else {
                 $this->_integrations = $this->_configReader->read();
-                $this->_configCacheType->save(serialize($this->_integrations), self::CACHE_ID, [Type::CACHE_TAG]);
+                $this->_configCacheType->save(
+                    $this->serializer->serialize($this->_integrations),
+                    self::CACHE_ID,
+                    [Type::CACHE_TAG]
+                );
             }
         }
         return $this->_integrations;
diff --git a/app/code/Magento/Integration/Model/ConsolidatedConfig.php b/app/code/Magento/Integration/Model/ConsolidatedConfig.php
index 9027bf774bc30a9a5b7cb6a427057efc45971742..9208d19e7028f8f753d6e20c2d43765163cb9bec 100644
--- a/app/code/Magento/Integration/Model/ConsolidatedConfig.php
+++ b/app/code/Magento/Integration/Model/ConsolidatedConfig.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Integration\Model;
 
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Serialize\SerializerInterface;
 use Magento\Integration\Model\Cache\TypeConsolidated;
 
 /**
@@ -31,14 +33,24 @@ class ConsolidatedConfig
      */
     protected $integrations;
 
+    /**
+     * @var SerializerInterface
+     */
+    private $serializer;
+
     /**
      * @param Cache\TypeConsolidated $configCacheType
      * @param Config\Consolidated\Reader $configReader
+     * @param SerializerInterface $serializer
      */
-    public function __construct(Cache\TypeConsolidated $configCacheType, Config\Consolidated\Reader $configReader)
-    {
+    public function __construct(
+        Cache\TypeConsolidated $configCacheType,
+        Config\Consolidated\Reader $configReader,
+        SerializerInterface $serializer = null
+    ) {
         $this->configCacheType = $configCacheType;
         $this->configReader = $configReader;
+        $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
     }
 
     /**
@@ -51,11 +63,11 @@ class ConsolidatedConfig
         if (null === $this->integrations) {
             $integrations = $this->configCacheType->load(self::CACHE_ID);
             if ($integrations && is_string($integrations)) {
-                $this->integrations = unserialize($integrations);
+                $this->integrations = $this->serializer->unserialize($integrations);
             } else {
                 $this->integrations = $this->configReader->read();
                 $this->configCacheType->save(
-                    serialize($this->integrations),
+                    $this->serializer->serialize($this->integrations),
                     self::CACHE_ID,
                     [TypeConsolidated::CACHE_TAG]
                 );
diff --git a/app/code/Magento/Integration/Model/IntegrationConfig.php b/app/code/Magento/Integration/Model/IntegrationConfig.php
index 647bff70efe4afdffd35e5294251e0fe9e98aa98..cde4fc20d22351ff4b9dedd9d93254f8d838438a 100644
--- a/app/code/Magento/Integration/Model/IntegrationConfig.php
+++ b/app/code/Magento/Integration/Model/IntegrationConfig.php
@@ -6,6 +6,8 @@
 
 namespace Magento\Integration\Model;
 
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Serialize\SerializerInterface;
 use Magento\Integration\Model\Cache\TypeIntegration;
 use Magento\Integration\Model\Config\Integration\Reader;
 
@@ -36,14 +38,24 @@ class IntegrationConfig
      */
     protected $_integrations;
 
+    /**
+     * @var SerializerInterface
+     */
+    private $serializer;
+
     /**
      * @param TypeIntegration $configCacheType
      * @param Reader $configReader
+     * @param SerializerInterface $serializer
      */
-    public function __construct(TypeIntegration $configCacheType, Reader $configReader)
-    {
+    public function __construct(
+        TypeIntegration $configCacheType,
+        Reader $configReader,
+        SerializerInterface $serializer = null
+    ) {
         $this->_configCacheType = $configCacheType;
         $this->_configReader = $configReader;
+        $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
     }
 
     /**
@@ -57,11 +69,11 @@ class IntegrationConfig
         if (null === $this->_integrations) {
             $integrations = $this->_configCacheType->load(self::CACHE_ID);
             if ($integrations && is_string($integrations)) {
-                $this->_integrations = unserialize($integrations);
+                $this->_integrations = $this->serializer->unserialize($integrations);
             } else {
                 $this->_integrations = $this->_configReader->read();
                 $this->_configCacheType->save(
-                    serialize($this->_integrations),
+                    $this->serializer->serialize($this->_integrations),
                     self::CACHE_ID,
                     [TypeIntegration::CACHE_TAG]
                 );
diff --git a/app/code/Magento/Integration/Test/Unit/Model/ConsolidatedConfigTest.php b/app/code/Magento/Integration/Test/Unit/Model/ConsolidatedConfigTest.php
index 0b75592782773d504061e4e6f9a56c67ebe5982e..22b50a8aef8d070c479ca2a28b499308a6a95c80 100644
--- a/app/code/Magento/Integration/Test/Unit/Model/ConsolidatedConfigTest.php
+++ b/app/code/Magento/Integration/Test/Unit/Model/ConsolidatedConfigTest.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\Integration\Test\Unit\Model;
 
+use Magento\Framework\Serialize\SerializerInterface;
 use Magento\Integration\Model\ConsolidatedConfig as Config;
 use Magento\Integration\Model\Cache\TypeConsolidated as Type;
 
@@ -18,17 +19,22 @@ class ConsolidatedConfigTest extends \PHPUnit_Framework_TestCase
      *
      * @var Config
      */
-    protected $configModel;
+    private $configModel;
 
     /**
      * @var Type|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $configCacheTypeMock;
+    private $configCacheTypeMock;
 
     /**
      * @var  \Magento\Integration\Model\Config\Consolidated\Reader|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $configReaderMock;
+    private $configReaderMock;
+
+    /**
+     * @var  SerializerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $serializer;
 
     protected function setUp()
     {
@@ -38,12 +44,16 @@ class ConsolidatedConfigTest extends \PHPUnit_Framework_TestCase
         $this->configReaderMock = $this->getMockBuilder(\Magento\Integration\Model\Config\Consolidated\Reader::class)
             ->disableOriginalConstructor()
             ->getMock();
+        $this->serializer = $this->getMockBuilder(SerializerInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
         $this->configModel = $objectManagerHelper->getObject(
             \Magento\Integration\Model\ConsolidatedConfig::class,
             [
                 'configCacheType' => $this->configCacheTypeMock,
-                'configReader' => $this->configReaderMock
+                'configReader' => $this->configReaderMock,
+                'serializer' => $this->serializer,
             ]
         );
     }
@@ -51,10 +61,15 @@ class ConsolidatedConfigTest extends \PHPUnit_Framework_TestCase
     public function testGetIntegrationsFromConfigCacheType()
     {
         $integrations = ['foo', 'bar', 'baz'];
+        $serializedIntegrations = '["foo","bar","baz"]';
         $this->configCacheTypeMock->expects($this->once())
             ->method('load')
             ->with(Config::CACHE_ID)
-            ->will($this->returnValue(serialize($integrations)));
+            ->will($this->returnValue($serializedIntegrations));
+        $this->serializer->expects($this->once())
+            ->method('unserialize')
+            ->with($serializedIntegrations)
+            ->willReturn($integrations);
 
         $this->assertEquals($integrations, $this->configModel->getIntegrations());
     }
@@ -62,17 +77,21 @@ class ConsolidatedConfigTest extends \PHPUnit_Framework_TestCase
     public function testGetIntegrationsFromConfigReader()
     {
         $integrations = ['foo', 'bar', 'baz'];
+        $serializedIntegrations = '["foo","bar","baz"]';
         $this->configCacheTypeMock->expects($this->once())
             ->method('load')
             ->with(Config::CACHE_ID)
             ->will($this->returnValue(null));
-        $this->configCacheTypeMock->expects($this->once())
-            ->method('save')
-            ->with(serialize($integrations), Config::CACHE_ID, [Type::CACHE_TAG])
-            ->will($this->returnValue(null));
         $this->configReaderMock->expects($this->once())
             ->method('read')
             ->will($this->returnValue($integrations));
+        $this->serializer->expects($this->once())
+            ->method('serialize')
+            ->with($integrations)
+            ->willReturn($serializedIntegrations);
+        $this->configCacheTypeMock->expects($this->once())
+            ->method('save')
+            ->with($serializedIntegrations, Config::CACHE_ID, [Type::CACHE_TAG]);
 
         $this->assertEquals($integrations, $this->configModel->getIntegrations());
     }
diff --git a/app/code/Magento/Integration/Test/Unit/Model/IntegrationConfigTest.php b/app/code/Magento/Integration/Test/Unit/Model/IntegrationConfigTest.php
index aed4e02453dc435fa5ff87f30931560bace8721e..14871420a621aceec2d5dcb79f209c60fac1f9f6 100644
--- a/app/code/Magento/Integration/Test/Unit/Model/IntegrationConfigTest.php
+++ b/app/code/Magento/Integration/Test/Unit/Model/IntegrationConfigTest.php
@@ -5,6 +5,7 @@
  */
 namespace Magento\Integration\Test\Unit\Model;
 
+use Magento\Framework\Serialize\SerializerInterface;
 use Magento\Integration\Model\IntegrationConfig;
 use Magento\Integration\Model\Cache\TypeIntegration;
 
@@ -16,17 +17,22 @@ class IntegrationConfigTest extends \PHPUnit_Framework_TestCase
     /**
      * @var IntegrationConfig
      */
-    protected $integrationConfigModel;
+    private $integrationConfigModel;
 
     /**
      * @var TypeIntegration|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $configCacheTypeMock;
+    private $configCacheTypeMock;
 
     /**
      * @var  \Magento\Integration\Model\Config\Integration\Reader|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $configReaderMock;
+    private $configReaderMock;
+
+    /**
+     * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $serializer;
 
     protected function setUp()
     {
@@ -36,19 +42,28 @@ class IntegrationConfigTest extends \PHPUnit_Framework_TestCase
         $this->configReaderMock = $this->getMockBuilder(\Magento\Integration\Model\Config\Integration\Reader::class)
             ->disableOriginalConstructor()
             ->getMock();
+        $this->serializer = $this->getMockBuilder(SerializerInterface::class)
+            ->disableOriginalConstructor()
+            ->getMock();
         $this->integrationConfigModel = new IntegrationConfig(
             $this->configCacheTypeMock,
-            $this->configReaderMock
+            $this->configReaderMock,
+            $this->serializer
         );
     }
 
     public function testGetIntegrationsFromConfigCacheType()
     {
         $integrations = ['foo', 'bar', 'baz'];
+        $serializedIntegrations = '["foo","bar","baz"]';
         $this->configCacheTypeMock->expects($this->once())
             ->method('load')
             ->with(IntegrationConfig::CACHE_ID)
-            ->will($this->returnValue(serialize($integrations)));
+            ->will($this->returnValue($serializedIntegrations));
+        $this->serializer->expects($this->once())
+            ->method('unserialize')
+            ->with($serializedIntegrations)
+            ->willReturn($integrations);
 
         $this->assertEquals($integrations, $this->integrationConfigModel->getIntegrations());
     }
@@ -56,17 +71,22 @@ class IntegrationConfigTest extends \PHPUnit_Framework_TestCase
     public function testGetIntegrationsFromConfigReader()
     {
         $integrations = ['foo', 'bar', 'baz'];
+        $serializedIntegrations = '["foo","bar","baz"]';
         $this->configCacheTypeMock->expects($this->once())
             ->method('load')
             ->with(IntegrationConfig::CACHE_ID)
             ->will($this->returnValue(null));
-        $this->configCacheTypeMock->expects($this->once())
-            ->method('save')
-            ->with(serialize($integrations), IntegrationConfig::CACHE_ID, [TypeIntegration::CACHE_TAG])
-            ->will($this->returnValue(null));
         $this->configReaderMock->expects($this->once())
             ->method('read')
             ->will($this->returnValue($integrations));
+        $this->serializer->expects($this->once())
+            ->method('serialize')
+            ->with($integrations)
+            ->willReturn($serializedIntegrations);
+        $this->configCacheTypeMock->expects($this->once())
+            ->method('save')
+            ->with($serializedIntegrations, IntegrationConfig::CACHE_ID, [TypeIntegration::CACHE_TAG])
+            ->will($this->returnValue(null));
 
         $this->assertEquals($integrations, $this->integrationConfigModel->getIntegrations());
     }
diff --git a/app/code/Magento/Marketplace/Helper/Cache.php b/app/code/Magento/Marketplace/Helper/Cache.php
index 1cb5fb9c710e67885f0e7266d57873ca29cb3e21..a0a4ce73e0373ac7d057777160c7ac5028321e8c 100644
--- a/app/code/Magento/Marketplace/Helper/Cache.php
+++ b/app/code/Magento/Marketplace/Helper/Cache.php
@@ -6,7 +6,8 @@
 
 namespace Magento\Marketplace\Helper;
 
-use Magento\Framework\Filesystem;
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Serialize\SerializerInterface;
 
 /**
  * Cache helper
@@ -25,15 +26,23 @@ class Cache extends \Magento\Framework\App\Helper\AbstractHelper
      */
     protected $cache;
 
+    /**
+     * @var SerializerInterface
+     */
+    private $serializer;
+
     /**
      * @param \Magento\Framework\App\Helper\Context $context
      * @param \Magento\Framework\Config\CacheInterface $cache
+     * @param SerializerInterface $serializer
      */
     public function __construct(
         \Magento\Framework\App\Helper\Context $context,
-        \Magento\Framework\Config\CacheInterface $cache
+        \Magento\Framework\Config\CacheInterface $cache,
+        SerializerInterface $serializer = null
     ) {
         $this->cache = $cache;
+        $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
         parent::__construct($context);
     }
 
@@ -46,7 +55,7 @@ class Cache extends \Magento\Framework\App\Helper\AbstractHelper
     {
         $data = $this->getCache()->load($this->pathToCacheFile);
         if (false !== $data) {
-            $data = unserialize($data);
+            $data = $this->serializer->unserialize($data);
         }
         return $data;
     }
@@ -59,7 +68,7 @@ class Cache extends \Magento\Framework\App\Helper\AbstractHelper
      */
     public function savePartnersToCache($partners)
     {
-        return $this->getCache()->save(serialize($partners), $this->pathToCacheFile);
+        return $this->getCache()->save($this->serializer->serialize($partners), $this->pathToCacheFile);
     }
 
     /**
diff --git a/app/code/Magento/Marketplace/Test/Unit/Helper/CacheTest.php b/app/code/Magento/Marketplace/Test/Unit/Helper/CacheTest.php
index 75c6e6110389c5a920c3053aa451a6d0deab3775..00b78a47eb4b0be4c5b89cf3383dac80028dc899 100644
--- a/app/code/Magento/Marketplace/Test/Unit/Helper/CacheTest.php
+++ b/app/code/Magento/Marketplace/Test/Unit/Helper/CacheTest.php
@@ -6,70 +6,79 @@
 
 namespace Magento\Marketplace\Test\Unit\Helper;
 
+use Magento\Framework\Serialize\SerializerInterface;
+
 class CacheTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Marketplace\Helper\Cache
+     * @var \Magento\Framework\Config\CacheInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $cache;
+
+    /**
+     * @var  SerializerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
-    private $cacheHelperMock;
+    private $serializer;
+
+    /**
+     * @var \Magento\Marketplace\Helper\Cache
+     */
+    private $cacheHelper;
 
     protected function setUp()
     {
-        $this->cacheHelperMock = $this->getCacheHelperMock(['getCache']);
+        $this->cache = $this->getMockForAbstractClass(\Magento\Framework\Config\CacheInterface::class);
+        $this->serializer = $this->getMockForAbstractClass(SerializerInterface::class);
+        $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->cacheHelper = $objectManagerHelper->getObject(
+            \Magento\Marketplace\Helper\Cache::class,
+            [
+                'cache' => $this->cache,
+                'serializer' => $this->serializer,
+            ]
+        );
     }
 
-    /**
-     * @covers \Magento\Marketplace\Helper\Cache::loadPartnersFromCache
-     */
     public function testLoadPartnersFromCache()
     {
-        $cache = $this->getCacheMock();
-        $this->cacheHelperMock
-            ->expects($this->once())
-            ->method('getCache')
-            ->will($this->returnValue($cache));
-        $cache->expects($this->once())
+        $partners = ['partner1', 'partner2'];
+        $serializedPartners = '["partner1", "partner2"]';
+        $this->cache->expects($this->once())
             ->method('load')
-            ->will($this->returnValue(''));
+            ->with('partners')
+            ->willReturn($serializedPartners);
+        $this->serializer->expects($this->once())
+            ->method('unserialize')
+            ->with($serializedPartners)
+            ->willReturn($partners);
 
-        $this->cacheHelperMock->loadPartnersFromCache();
+        $this->assertSame($partners, $this->cacheHelper->loadPartnersFromCache());
     }
 
-    /**
-     * @covers \Magento\Marketplace\Helper\Cache::savePartnersToCache
-     */
-    public function testSavePartnersToCache()
+    public function testLoadPartnersFromCacheNoCachedData()
     {
-        $cache = $this->getCacheMock();
-        $this->cacheHelperMock
-            ->expects($this->once())
-            ->method('getCache')
-            ->will($this->returnValue($cache));
-        $cache->expects($this->once())
-            ->method('save')
-            ->will($this->returnValue(true));
+        $this->cache->expects($this->once())
+            ->method('load')
+            ->with('partners')
+            ->willReturn(false);
+        $this->serializer->expects($this->never())
+            ->method('unserialize');
 
-        $this->cacheHelperMock->savePartnersToCache([]);
+        $this->assertSame(false, $this->cacheHelper->loadPartnersFromCache());
     }
 
-    /**
-     * Gets cache helper mock
-     *
-     * @param null $methods
-     * @return \PHPUnit_Framework_MockObject_MockObject|\Magento\Marketplace\Helper\Cache
-     */
-    public function getCacheHelperMock($methods = null)
+    public function testSavePartnersToCache()
     {
-        return $this->getMock(\Magento\Marketplace\Helper\Cache::class, $methods, [], '', false);
-    }
+        $partners = ['partner1', 'partner2'];
+        $serializedPartners = '["partner1", "partner2"]';
+        $this->serializer->expects($this->once())
+            ->method('serialize')
+            ->with($partners)
+            ->willReturn($serializedPartners);
+        $this->cache->expects($this->once())
+            ->method('save')
+            ->with($serializedPartners);
 
-    /**
-     * Gets Filesystem mock
-     *
-     * @return \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Config\CacheInterface
-     */
-    public function getCacheMock()
-    {
-        return $this->getMockForAbstractClass(\Magento\Framework\Config\CacheInterface::class);
+        $this->cacheHelper->savePartnersToCache($partners);
     }
 }
diff --git a/app/code/Magento/Quote/Model/QueryResolver.php b/app/code/Magento/Quote/Model/QueryResolver.php
index cfc1480feb66386a122b21a6484107a205cad566..04d83bab85b2bf4b31c5d57e8c2b742614a4694b 100644
--- a/app/code/Magento/Quote/Model/QueryResolver.php
+++ b/app/code/Magento/Quote/Model/QueryResolver.php
@@ -5,8 +5,10 @@
  */
 namespace Magento\Quote\Model;
 
+use Magento\Framework\App\ObjectManager;
 use Magento\Framework\Config\CacheInterface;
 use Magento\Framework\App\ResourceConnection\ConfigInterface;
+use Magento\Framework\Serialize\SerializerInterface;
 
 class QueryResolver
 {
@@ -37,19 +39,27 @@ class QueryResolver
      */
     private $cacheTags = [];
 
+    /**
+     * @var SerializerInterface
+     */
+    private $serializer;
+
     /**
      * @param ConfigInterface $config
      * @param CacheInterface $cache
      * @param string $cacheId
+     * @param SerializerInterface $serializer
      */
     public function __construct(
         ConfigInterface $config,
         CacheInterface $cache,
-        $cacheId = 'connection_config_cache'
+        $cacheId = 'connection_config_cache',
+        SerializerInterface $serializer = null
     ) {
         $this->config = $config;
         $this->cache = $cache;
         $this->cacheId = $cacheId;
+        $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
     }
 
     /**
@@ -75,9 +85,9 @@ class QueryResolver
         if (false === $data) {
             $singleQuery = $this->config->getConnectionName('checkout_setup') == 'default' ? true : false;
             $data['checkout'] = $singleQuery;
-            $this->cache->save(serialize($data), $this->cacheId, $this->cacheTags);
+            $this->cache->save($this->serializer->serialize($data), $this->cacheId, $this->cacheTags);
         } else {
-            $data = unserialize($data);
+            $data = $this->serializer->unserialize($data);
         }
         $this->merge($data);
     }
diff --git a/app/code/Magento/Quote/Model/Quote/Address/Total/Collector.php b/app/code/Magento/Quote/Model/Quote/Address/Total/Collector.php
index 8e62d1b942f1e2a5808e76ac293c94abd9830cad..d430bf3acc6cd08d22b0f352efde6b9dc7774fed 100644
--- a/app/code/Magento/Quote/Model/Quote/Address/Total/Collector.php
+++ b/app/code/Magento/Quote/Model/Quote/Address/Total/Collector.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Quote\Model\Quote\Address\Total;
 
+use Magento\Framework\Serialize\SerializerInterface;
+
 /**
  * Address Total Collector model
  */
@@ -69,6 +71,7 @@ class Collector extends \Magento\Sales\Model\Config\Ordered
      * @param \Magento\Quote\Model\Quote\Address\TotalFactory $totalFactory
      * @param mixed $sourceData
      * @param mixed $store
+     * @param SerializerInterface $serializer
      */
     public function __construct(
         \Magento\Framework\App\Cache\Type\Config $configCacheType,
@@ -78,11 +81,12 @@ class Collector extends \Magento\Sales\Model\Config\Ordered
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Quote\Model\Quote\Address\TotalFactory $totalFactory,
         $sourceData = null,
-        $store = null
+        $store = null,
+        SerializerInterface $serializer = null
     ) {
         $this->_scopeConfig = $scopeConfig;
         $this->_totalFactory = $totalFactory;
-        parent::__construct($configCacheType, $logger, $salesConfig, $sourceData);
+        parent::__construct($configCacheType, $logger, $salesConfig, $sourceData, $serializer);
         $this->_store = $store ?: $storeManager->getStore();
         $this->_initModels()->_initCollectors()->_initRetrievers();
     }
diff --git a/app/code/Magento/Quote/Test/Unit/Model/QueryResolverTest.php b/app/code/Magento/Quote/Test/Unit/Model/QueryResolverTest.php
index a2075b1161fc2a9cde83ba9af7bd2729244aa9a3..eb6828afff4edc79f0fb32bea383515ebacdcf86 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/QueryResolverTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/QueryResolverTest.php
@@ -6,83 +6,100 @@
 
 namespace Magento\Quote\Test\Unit\Model;
 
+use Magento\Framework\Serialize\SerializerInterface;
+
 class QueryResolverTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * @var \Magento\Quote\Model\QueryResolver
      */
-    protected $quoteResolver;
+    private $quoteResolver;
 
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
-    protected $configMock;
+    private $configMock;
 
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
-    protected $cacheMock;
+    private $cacheMock;
+
+    /**
+     * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $serializer;
 
     protected function setUp()
     {
         $this->configMock = $this->getMock(\Magento\Framework\App\ResourceConnection\ConfigInterface::class);
         $this->cacheMock = $this->getMock(\Magento\Framework\Config\CacheInterface::class);
+        $this->serializer = $this->getMockForAbstractClass(SerializerInterface::class);
         $this->quoteResolver = new \Magento\Quote\Model\QueryResolver(
             $this->configMock,
             $this->cacheMock,
-            'connection_config_cache'
+            'connection_config_cache',
+            $this->serializer
         );
-
     }
 
     public function testIsSingleQueryWhenDataWereCached()
     {
-        $queryData['checkout'] = true;
+        $serializedData = '{"checkout":true}';
+        $data = ['checkout' => true];
         $this->cacheMock
             ->expects($this->once())
             ->method('load')
             ->with('connection_config_cache')
-            ->willReturn(serialize($queryData));
+            ->willReturn($serializedData);
+        $this->serializer->expects($this->once())
+            ->method('unserialize')
+            ->with($serializedData)
+            ->willReturn($data);
         $this->assertTrue($this->quoteResolver->isSingleQuery());
     }
 
-    public function testIsSingleQueryWhenDataNotCached()
+    /**
+     * @param string $connectionName
+     * @param bool $isSingleQuery
+     *
+     * @dataProvider isSingleQueryWhenDataNotCachedDataProvider
+     */
+    public function testIsSingleQueryWhenDataNotCached($connectionName, $isSingleQuery)
     {
-        $queryData['checkout'] = true;
+        $data = ['checkout' => $isSingleQuery];
+        $serializedData = '{"checkout":true}';
         $this->cacheMock
             ->expects($this->once())
             ->method('load')
             ->with('connection_config_cache')
             ->willReturn(false);
+        $this->serializer->expects($this->never())
+            ->method('unserialize');
         $this->configMock
             ->expects($this->once())
             ->method('getConnectionName')
             ->with('checkout_setup')
-            ->willReturn('default');
+            ->willReturn($connectionName);
+        $this->serializer->expects($this->once())
+            ->method('serialize')
+            ->with($data)
+            ->willReturn($serializedData);
         $this->cacheMock
             ->expects($this->once())
             ->method('save')
-            ->with(serialize($queryData), 'connection_config_cache', []);
-        $this->assertTrue($this->quoteResolver->isSingleQuery());
+            ->with($serializedData, 'connection_config_cache', []);
+        $this->assertEquals($isSingleQuery, $this->quoteResolver->isSingleQuery());
     }
 
-    public function testIsSingleQueryWhenSeveralConnectionsExist()
+    /**
+     * @return array
+     */
+    public function isSingleQueryWhenDataNotCachedDataProvider()
     {
-        $queryData['checkout'] = false;
-        $this->cacheMock
-            ->expects($this->once())
-            ->method('load')
-            ->with('connection_config_cache')
-            ->willReturn(false);
-        $this->configMock
-            ->expects($this->once())
-            ->method('getConnectionName')
-            ->with('checkout_setup')
-            ->willReturn('checkout');
-        $this->cacheMock
-            ->expects($this->once())
-            ->method('save')
-            ->with(serialize($queryData), 'connection_config_cache', []);
-        $this->assertFalse($this->quoteResolver->isSingleQuery());
+        return [
+            ['default', true],
+            ['checkout', false],
+        ];
     }
 }
diff --git a/app/code/Magento/Sales/Model/Config/Ordered.php b/app/code/Magento/Sales/Model/Config/Ordered.php
index 7ea7d1f8cc5fae05277754e033c9a4cb9fac37f6..806a7b522c189f495e080307981bf8fd95f3d420 100644
--- a/app/code/Magento/Sales/Model/Config/Ordered.php
+++ b/app/code/Magento/Sales/Model/Config/Ordered.php
@@ -5,6 +5,9 @@
  */
 namespace Magento\Sales\Model\Config;
 
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Serialize\SerializerInterface;
+
 /**
  * Configuration class for ordered items
  *
@@ -69,22 +72,30 @@ abstract class Ordered extends \Magento\Framework\App\Config\Base
      */
     protected $_salesConfig;
 
+    /**
+     * @var SerializerInterface
+     */
+    private $serializer;
+
     /**
      * @param \Magento\Framework\App\Cache\Type\Config $configCacheType
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Sales\Model\Config $salesConfig
      * @param \Magento\Framework\Simplexml\Element $sourceData
+     * @param SerializerInterface $serializer
      */
     public function __construct(
         \Magento\Framework\App\Cache\Type\Config $configCacheType,
         \Psr\Log\LoggerInterface $logger,
         \Magento\Sales\Model\Config $salesConfig,
-        $sourceData = null
+        $sourceData = null,
+        SerializerInterface $serializer = null
     ) {
         parent::__construct($sourceData);
         $this->_configCacheType = $configCacheType;
         $this->_logger = $logger;
         $this->_salesConfig = $salesConfig;
+        $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
     }
 
     /**
@@ -179,11 +190,11 @@ abstract class Ordered extends \Magento\Framework\App\Config\Base
         $sortedCodes = [];
         $cachedData = $this->_configCacheType->load($this->_collectorsCacheKey);
         if ($cachedData) {
-            $sortedCodes = unserialize($cachedData);
+            $sortedCodes = $this->serializer->unserialize($cachedData);
         }
         if (!$sortedCodes) {
             $sortedCodes = $this->_getSortedCollectorCodes($this->_modelsConfig);
-            $this->_configCacheType->save(serialize($sortedCodes), $this->_collectorsCacheKey);
+            $this->_configCacheType->save($this->serializer->serialize($sortedCodes), $this->_collectorsCacheKey);
         }
         foreach ($sortedCodes as $code) {
             $this->_collectors[$code] = $this->_models[$code];
diff --git a/app/code/Magento/Sales/Model/Order/Total/Config/Base.php b/app/code/Magento/Sales/Model/Order/Total/Config/Base.php
index 22c71f48b6f35189bf532362a8647e53069a39a5..d96591118b82296a937445256e01e75ee942a569 100644
--- a/app/code/Magento/Sales/Model/Order/Total/Config/Base.php
+++ b/app/code/Magento/Sales/Model/Order/Total/Config/Base.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Sales\Model\Order\Total\Config;
 
+use Magento\Framework\Serialize\SerializerInterface;
+
 /**
  * Configuration class for totals
  */
@@ -42,15 +44,17 @@ class Base extends \Magento\Sales\Model\Config\Ordered
      * @param \Magento\Sales\Model\Config $salesConfig
      * @param \Magento\Sales\Model\Order\TotalFactory $orderTotalFactory
      * @param mixed $sourceData
+     * @param SerializerInterface $serializer
      */
     public function __construct(
         \Magento\Framework\App\Cache\Type\Config $configCacheType,
         \Psr\Log\LoggerInterface $logger,
         \Magento\Sales\Model\Config $salesConfig,
         \Magento\Sales\Model\Order\TotalFactory $orderTotalFactory,
-        $sourceData = null
+        $sourceData = null,
+        SerializerInterface $serializer = null
     ) {
-        parent::__construct($configCacheType, $logger, $salesConfig, $sourceData);
+        parent::__construct($configCacheType, $logger, $salesConfig, $sourceData, $serializer);
         $this->_orderTotalFactory = $orderTotalFactory;
     }
 
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/Total/Config/BaseTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/Total/Config/BaseTest.php
index ed44331f577d06ebdbe4df00401f85f34c59284d..bd519e76585ba452bb066ccac2cfbd27c5d58d7f 100644
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/Total/Config/BaseTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/Total/Config/BaseTest.php
@@ -5,24 +5,28 @@
  */
 namespace Magento\Sales\Test\Unit\Model\Order\Total\Config;
 
+use Magento\Framework\Serialize\SerializerInterface;
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
 
 class BaseTest extends \PHPUnit_Framework_TestCase
 {
     /** @var \Magento\Sales\Model\Order\Total\Config\Base */
-    protected $object;
+    private $object;
+
+    /** @var  SerializerInterface|\PHPUnit_Framework_MockObject_MockObject */
+    private $serializer;
 
     /** @var \Magento\Framework\App\Cache\Type\Config|\PHPUnit_Framework_MockObject_MockObject */
-    protected $configCacheType;
+    private $configCacheType;
 
     /** @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject */
-    protected $logger;
+    private $logger;
 
     /** @var \Magento\Sales\Model\Config|\PHPUnit_Framework_MockObject_MockObject */
-    protected $salesConfig;
+    private $salesConfig;
 
     /** @var \Magento\Sales\Model\Order\TotalFactory|\PHPUnit_Framework_MockObject_MockObject */
-    protected $orderTotalFactory;
+    private $orderTotalFactory;
 
     protected function setUp()
     {
@@ -30,6 +34,7 @@ class BaseTest extends \PHPUnit_Framework_TestCase
         $this->logger = $this->getMock(\Psr\Log\LoggerInterface::class);
         $this->salesConfig = $this->getMock(\Magento\Sales\Model\Config::class, [], [], '', false);
         $this->orderTotalFactory = $this->getMock(\Magento\Sales\Model\Order\TotalFactory::class, [], [], '', false);
+        $this->serializer = $this->getMockForAbstractClass(SerializerInterface::class);
 
         $objectManager = new ObjectManager($this);
         $this->object = $objectManager->getObject(
@@ -39,6 +44,7 @@ class BaseTest extends \PHPUnit_Framework_TestCase
                 'logger' => $this->logger,
                 'salesConfig' => $this->salesConfig,
                 'orderTotalFactory' => $this->orderTotalFactory,
+                'serializer' => $this->serializer,
             ]
         );
     }
@@ -59,8 +65,14 @@ class BaseTest extends \PHPUnit_Framework_TestCase
             ->with(\Magento\Sales\Model\Order\Total\AbstractTotal::class)
             ->will($this->returnValue($total));
 
+        $sortedCodes = ['other_code', 'some_code'];
+        $serializedCodes = '["other_code", "some_code"]';
+        $this->serializer->expects($this->once())
+            ->method('serialize')
+            ->with($sortedCodes)
+            ->willReturn($serializedCodes);
         $this->configCacheType->expects($this->once())->method('save')
-            ->with('a:2:{i:0;s:10:"other_code";i:1;s:9:"some_code";}', 'sorted_collectors');
+            ->with($serializedCodes, 'sorted_collectors');
 
         $this->assertSame(
             ['other_code' => $total, 'some_code' => $total],
@@ -106,8 +118,14 @@ class BaseTest extends \PHPUnit_Framework_TestCase
             ->with(\Magento\Sales\Model\Order\Total\AbstractTotal::class)
             ->will($this->returnValue($total));
 
+        $sortedCodes = ['other_code', 'some_code'];
+        $serializedCodes = '["other_code", "some_code"]';
         $this->configCacheType->expects($this->once())->method('load')->with('sorted_collectors')
-            ->will($this->returnValue('a:2:{i:0;s:10:"other_code";i:1;s:9:"some_code";}'));
+            ->will($this->returnValue($serializedCodes));
+        $this->serializer->expects($this->once())
+            ->method('unserialize')
+            ->with($serializedCodes)
+            ->willReturn($sortedCodes);
         $this->configCacheType->expects($this->never())->method('save');
 
         $this->assertSame(
diff --git a/app/code/Magento/Webapi/Model/Config.php b/app/code/Magento/Webapi/Model/Config.php
index 45d29bc59cf0d6a1c9c1be78ff84343f50b1029d..fb6dc894e3c0ae87915f12bdf38311a5be541874 100644
--- a/app/code/Magento/Webapi/Model/Config.php
+++ b/app/code/Magento/Webapi/Model/Config.php
@@ -8,6 +8,8 @@ namespace Magento\Webapi\Model;
 
 use Magento\Webapi\Model\Cache\Type\Webapi as WebapiCache;
 use Magento\Webapi\Model\Config\Reader;
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Serialize\SerializerInterface;
 
 /**
  * Web API Config Model.
@@ -40,16 +42,26 @@ class Config
      */
     protected $services;
 
+    /**
+     * @var SerializerInterface
+     */
+    private $serializer;
+
     /**
      * Initialize dependencies.
      *
      * @param WebapiCache $cache
      * @param Reader $configReader
+     * @param SerializerInterface|null $serializer
      */
-    public function __construct(WebapiCache $cache, Reader $configReader)
-    {
+    public function __construct(
+        WebapiCache $cache,
+        Reader $configReader,
+        SerializerInterface $serializer = null
+    ) {
         $this->cache = $cache;
         $this->configReader = $configReader;
+        $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
     }
 
     /**
@@ -62,10 +74,10 @@ class Config
         if (null === $this->services) {
             $services = $this->cache->load(self::CACHE_ID);
             if ($services && is_string($services)) {
-                $this->services = unserialize($services);
+                $this->services = $this->serializer->unserialize($services);
             } else {
                 $this->services = $this->configReader->read();
-                $this->cache->save(serialize($this->services), self::CACHE_ID);
+                $this->cache->save($this->serializer->serialize($this->services), self::CACHE_ID);
             }
         }
         return $this->services;
diff --git a/app/code/Magento/Webapi/Model/ServiceMetadata.php b/app/code/Magento/Webapi/Model/ServiceMetadata.php
index b75d10f9a271f7a3f39fff2ac9494f020b5cf660..14e45ccb409db24df2dd2f1c4f8d5693a55d3126 100644
--- a/app/code/Magento/Webapi/Model/ServiceMetadata.php
+++ b/app/code/Magento/Webapi/Model/ServiceMetadata.php
@@ -7,6 +7,8 @@ namespace Magento\Webapi\Model;
 
 use Magento\Webapi\Model\Config\Converter;
 use Magento\Webapi\Model\Cache\Type\Webapi as WebApiCache;
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Serialize\SerializerInterface;
 
 /**
  * Service Metadata Model
@@ -74,6 +76,11 @@ class ServiceMetadata
      */
     protected $typeProcessor;
 
+    /**
+     * @var SerializerInterface
+     */
+    private $serializer;
+
     /**
      * Initialize dependencies.
      *
@@ -81,17 +88,20 @@ class ServiceMetadata
      * @param WebApiCache $cache
      * @param \Magento\Webapi\Model\Config\ClassReflector $classReflector
      * @param \Magento\Framework\Reflection\TypeProcessor $typeProcessor
+     * @param SerializerInterface|null $serializer
      */
     public function __construct(
         \Magento\Webapi\Model\Config $config,
         WebApiCache $cache,
         \Magento\Webapi\Model\Config\ClassReflector $classReflector,
-        \Magento\Framework\Reflection\TypeProcessor $typeProcessor
+        \Magento\Framework\Reflection\TypeProcessor $typeProcessor,
+        SerializerInterface $serializer = null
     ) {
         $this->config = $config;
         $this->cache = $cache;
         $this->classReflector = $classReflector;
         $this->typeProcessor = $typeProcessor;
+        $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
     }
 
     /**
@@ -142,12 +152,18 @@ class ServiceMetadata
             $servicesConfig = $this->cache->load(self::SERVICES_CONFIG_CACHE_ID);
             $typesData = $this->cache->load(self::REFLECTED_TYPES_CACHE_ID);
             if ($servicesConfig && is_string($servicesConfig) && $typesData && is_string($typesData)) {
-                $this->services = unserialize($servicesConfig);
-                $this->typeProcessor->setTypesData(unserialize($typesData));
+                $this->services = $this->serializer->unserialize($servicesConfig);
+                $this->typeProcessor->setTypesData($this->serializer->unserialize($typesData));
             } else {
                 $this->services = $this->initServicesMetadata();
-                $this->cache->save(serialize($this->services), self::SERVICES_CONFIG_CACHE_ID);
-                $this->cache->save(serialize($this->typeProcessor->getTypesData()), self::REFLECTED_TYPES_CACHE_ID);
+                $this->cache->save(
+                    $this->serializer->serialize($this->services),
+                    self::SERVICES_CONFIG_CACHE_ID
+                );
+                $this->cache->save(
+                    $this->serializer->serialize($this->typeProcessor->getTypesData()),
+                    self::REFLECTED_TYPES_CACHE_ID
+                );
             }
         }
         return $this->services;
@@ -256,12 +272,18 @@ class ServiceMetadata
             $routesConfig = $this->cache->load(self::ROUTES_CONFIG_CACHE_ID);
             $typesData = $this->cache->load(self::REFLECTED_TYPES_CACHE_ID);
             if ($routesConfig && is_string($routesConfig) && $typesData && is_string($typesData)) {
-                $this->routes = unserialize($routesConfig);
-                $this->typeProcessor->setTypesData(unserialize($typesData));
+                $this->routes = $this->serializer->unserialize($routesConfig);
+                $this->typeProcessor->setTypesData($this->serializer->unserialize($typesData));
             } else {
                 $this->routes = $this->initRoutesMetadata();
-                $this->cache->save(serialize($this->routes), self::ROUTES_CONFIG_CACHE_ID);
-                $this->cache->save(serialize($this->typeProcessor->getTypesData()), self::REFLECTED_TYPES_CACHE_ID);
+                $this->cache->save(
+                    $this->serializer->serialize($this->routes),
+                    self::ROUTES_CONFIG_CACHE_ID
+                );
+                $this->cache->save(
+                    $this->serializer->serialize($this->typeProcessor->getTypesData()),
+                    self::REFLECTED_TYPES_CACHE_ID
+                );
             }
         }
         return $this->routes;
diff --git a/app/code/Magento/Webapi/Test/Unit/Model/ConfigTest.php b/app/code/Magento/Webapi/Test/Unit/Model/ConfigTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..74280f61916d7182e90bdf1e9b6125da55a6c31b
--- /dev/null
+++ b/app/code/Magento/Webapi/Test/Unit/Model/ConfigTest.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Webapi\Test\Unit\Model;
+
+use Magento\Framework\Serialize\SerializerInterface;
+use Magento\Webapi\Model\Config;
+use Magento\Webapi\Model\Config\Reader;
+use Magento\Webapi\Model\Cache\Type\Webapi;
+
+class ConfigTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Config
+     */
+    private $config;
+
+    /**
+     * @var Webapi|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $webapiCacheMock;
+
+    /**
+     * @var Reader|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $configReaderMock;
+
+    /**
+     * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $serializerMock;
+
+    protected function setUp()
+    {
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+
+        $this->webapiCacheMock = $this->getMock(\Magento\Webapi\Model\Cache\Type\Webapi::class, [], [], '', false);
+        $this->configReaderMock = $this->getMock(\Magento\Webapi\Model\Config\Reader::class, [], [], '', false);
+        $this->serializerMock = $this->getMock(SerializerInterface::class);
+
+        $this->config = $objectManager->getObject(
+            Config::class,
+            [
+                'cache' => $this->webapiCacheMock,
+                'configReader' => $this->configReaderMock,
+                'serializer' => $this->serializerMock
+            ]
+        );
+    }
+
+    public function testGetServices()
+    {
+        $data = ['foo' => 'bar'];
+        $serializedData = 'serialized data';
+        $this->webapiCacheMock->expects($this->once())
+            ->method('load')
+            ->with(Config::CACHE_ID)
+            ->willReturn($serializedData);
+        $this->serializerMock->expects($this->once())
+            ->method('unserialize')
+            ->with($serializedData)
+            ->willReturn($data);
+        $this->config->getServices();
+        $this->assertEquals($data, $this->config->getServices());
+    }
+
+    public function testGetServicesNoCache()
+    {
+        $data = ['foo' => 'bar'];
+        $serializedData = 'serialized data';
+        $this->webapiCacheMock->expects($this->once())
+            ->method('load')
+            ->with(Config::CACHE_ID)
+            ->willReturn(false);
+        $this->serializerMock->expects($this->never())
+            ->method('unserialize');
+        $this->configReaderMock->expects($this->once())
+            ->method('read')
+            ->willReturn($data);
+        $this->serializerMock->expects($this->once())
+            ->method('serialize')
+            ->with($data)
+            ->willReturn($serializedData);
+        $this->webapiCacheMock->expects($this->once())
+            ->method('save')
+            ->with(
+                $serializedData,
+                Config::CACHE_ID
+            );
+
+        $this->config->getServices();
+        $this->assertEquals($data, $this->config->getServices());
+    }
+}
diff --git a/app/code/Magento/Webapi/Test/Unit/Model/ServiceMetadataTest.php b/app/code/Magento/Webapi/Test/Unit/Model/ServiceMetadataTest.php
index 29c1bf90402ebe36d6ca91c5585cacb03f739cc3..4125f82b7923ffb30a3bfc0d86f3414255498231 100644
--- a/app/code/Magento/Webapi/Test/Unit/Model/ServiceMetadataTest.php
+++ b/app/code/Magento/Webapi/Test/Unit/Model/ServiceMetadataTest.php
@@ -1,187 +1,450 @@
 <?php
 /**
- * ServiceMetadata Unit tests.
- *
  * Copyright © 2016 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
-/**
- * Class implements tests for \Magento\Webapi\Model\ServiceMetadata class.
- */
 namespace Magento\Webapi\Test\Unit\Model;
 
+use Magento\Framework\Serialize\SerializerInterface;
+use Magento\Webapi\Model\Config;
+use Magento\Webapi\Model\Cache\Type\Webapi;
+use Magento\Webapi\Model\Config\ClassReflector;
+use Magento\Framework\Reflection\TypeProcessor;
+use Magento\Webapi\Model\ServiceMetadata;
+use Magento\Customer\Api\CustomerRepositoryInterface;
+
 class ServiceMetadataTest extends \PHPUnit_Framework_TestCase
 {
-    /** @var \Magento\Webapi\Model\ServiceMetadata */
-    protected $serviceMetadata;
+    /**
+     * @var ServiceMetadata
+     */
+    private $serviceMetadata;
 
     /**
-     * Set up helper.
-     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     * @var Webapi|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $cacheMock;
+
+    /**
+     * @var Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $configMock;
+
+    /**
+     * @var ClassReflector|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $classReflectorMock;
+
+    /**
+     * @var TypeProcessor|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $typeProcessorMock;
+
+    /**
+     * @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
+    private $serializerMock;
+
     protected function setUp()
     {
-        $interfaceParameters = [
-            'activateById' => [
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+
+        $this->configMock = $this->getMock(Config::class, [], [], '', false);
+        $this->cacheMock = $this->getMock(Webapi::class, [], [], '', false);
+        $this->classReflectorMock = $this->getMock(ClassReflector::class, [], [], '', false);
+        $this->typeProcessorMock = $this->getMock(TypeProcessor::class, [], [], '', false);
+        $this->serializerMock = $this->getMock(SerializerInterface::class);
+
+        $this->serviceMetadata = $objectManager->getObject(
+            ServiceMetadata::class,
+            [
+                'config' => $this->configMock,
+                'cache' => $this->cacheMock,
+                'classReflector' => $this->classReflectorMock,
+                'typeProcessor' => $this->typeProcessorMock,
+                'serializer' => $this->serializerMock
+            ]
+        );
+    }
+
+    public function testGetServicesConfig()
+    {
+        $servicesConfig = ['foo' => 'bar'];
+        $typeData = ['bar' => 'foo'];
+        $serializedServicesConfig = 'serialized services config';
+        $serializedTypeData = 'serialized type data';
+        $this->cacheMock->expects($this->at(0))
+            ->method('load')
+            ->with(ServiceMetadata::SERVICES_CONFIG_CACHE_ID)
+            ->willReturn($serializedServicesConfig);
+        $this->cacheMock->expects($this->at(1))
+            ->method('load')
+            ->with(ServiceMetadata::REFLECTED_TYPES_CACHE_ID)
+            ->willReturn($serializedTypeData);
+        $this->serializerMock->expects($this->at(0))
+            ->method('unserialize')
+            ->with($serializedServicesConfig)
+            ->willReturn($servicesConfig);
+        $this->serializerMock->expects($this->at(1))
+            ->method('unserialize')
+            ->with($serializedTypeData)
+            ->willReturn($typeData);
+        $this->typeProcessorMock->expects($this->once())
+            ->method('setTypesData')
+            ->with($typeData);
+        $this->serviceMetadata->getServicesConfig();
+        $this->assertEquals($servicesConfig, $this->serviceMetadata->getServicesConfig());
+    }
+
+    /**
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function testGetServicesConfigNoCache()
+    {
+        $servicesConfig = [
+            'services' => [
+                CustomerRepositoryInterface::class => [
+                    'V1' => [
+                        'methods' => [
+                            'getById' => [
+                                'resources' => [
+                                    [
+                                        'Magento_Customer::customer',
+                                    ]
+                                ],
+                                'secure' => false
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ];
+        $methodsReflectionData = [
+            'getById' => [
+                'documentation' => 'Get customer by customer ID.',
                 'interface' => [
                     'in' => [
                         'parameters' => [
                             'customerId' => [
-                                'force' => true,
-                                'value' => '%customer_id%',
-                            ],
-                            'requiredInputParameter' => [
+                                'type' => 'int',
                                 'required' => true,
-                            ],
-                        ],
+                                'documentation' => null
+                            ]
+                        ]
                     ],
                     'out' => [
                         'parameters' => [
-                            'outputParameter' => [
-                                'type' => 'string',
+                            'result' => [
+                                'type' => 'CustomerDataCustomerInterface',
+                                'required' => true,
+                                'documentation' => null
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ];
+        $servicesMetadata = [
+            'customerCustomerRepositoryV1' => [
+                'methods' => array_merge_recursive(
+                    [
+                        'getById' => [
+                            'resources' => [
+                                [
+                                    'Magento_Customer::customer',
+                                ],
                             ],
-                        ],
+                            'method' => 'getById',
+                            'inputRequired' => false,
+                            'isSecure' => false,
+                        ]
                     ],
-                ],
-            ],
+                    $methodsReflectionData
+                ),
+                'class' => CustomerRepositoryInterface::class,
+                'description' => 'Customer CRUD interface.'
+            ]
         ];
-        $classReflection = $this->getMock(
-            \Magento\Webapi\Model\Config\ClassReflector::class,
-            ['reflectClassMethods', 'extractClassDescription'],
-            [],
-            '',
-            false
-        );
-        $classReflection->expects($this->any())
+        $typeData = [
+            'CustomerDataCustomerInterface' => [
+                'documentation' => 'Customer interface.',
+                'parameters' => [
+                    'id' => [
+                        'type' => 'int',
+                        'required' => false,
+                        'documentation' => 'Customer id'
+                    ]
+                ]
+            ]
+        ];
+        $serializedServicesConfig = 'serialized services config';
+        $serializedTypeData = 'serialized type data';
+        $this->cacheMock->expects($this->at(0))
+            ->method('load')
+            ->with(ServiceMetadata::SERVICES_CONFIG_CACHE_ID)
+            ->willReturn(false);
+        $this->cacheMock->expects($this->at(1))
+            ->method('load')
+            ->with(ServiceMetadata::REFLECTED_TYPES_CACHE_ID)
+            ->willReturn(false);
+        $this->serializerMock->expects($this->never())
+            ->method('unserialize');
+        $this->configMock->expects($this->once())
+            ->method('getServices')
+            ->willReturn($servicesConfig);
+        $this->classReflectorMock->expects($this->once())
             ->method('reflectClassMethods')
-            ->will($this->returnValue($interfaceParameters));
-        $classReflection->expects($this->any())
+            ->willReturn($methodsReflectionData);
+        $this->classReflectorMock->expects($this->once())
             ->method('extractClassDescription')
-            ->will($this->returnValue('classDescription'));
+            ->with(CustomerRepositoryInterface::class)
+            ->willReturn('Customer CRUD interface.');
+        $this->typeProcessorMock->expects($this->once())
+            ->method('getTypesData')
+            ->willReturn($typeData);
+        $this->serializerMock->expects($this->at(0))
+            ->method('serialize')
+            ->with($servicesMetadata)
+            ->willReturn($serializedServicesConfig);
+        $this->serializerMock->expects($this->at(1))
+            ->method('serialize')
+            ->with($typeData)
+            ->willReturn($serializedTypeData);
+        $this->cacheMock->expects($this->at(2))
+            ->method('save')
+            ->with(
+                $serializedServicesConfig,
+                ServiceMetadata::SERVICES_CONFIG_CACHE_ID
+            );
+        $this->cacheMock->expects($this->at(3))
+            ->method('save')
+            ->with(
+                $serializedTypeData,
+                ServiceMetadata::REFLECTED_TYPES_CACHE_ID
+            );
+        $this->serviceMetadata->getServicesConfig();
+        $this->assertEquals($servicesMetadata, $this->serviceMetadata->getServicesConfig());
+    }
+
+    public function testGetRoutesConfig()
+    {
+        $routesConfig = ['foo' => 'bar'];
+        $typeData = ['bar' => 'foo'];
+        $serializedRoutesConfig = 'serialized routes config';
+        $serializedTypeData = 'serialized type data';
+        $this->cacheMock->expects($this->at(0))
+            ->method('load')
+            ->with(ServiceMetadata::ROUTES_CONFIG_CACHE_ID)
+            ->willReturn($serializedRoutesConfig);
+        $this->cacheMock->expects($this->at(1))
+            ->method('load')
+            ->with(ServiceMetadata::REFLECTED_TYPES_CACHE_ID)
+            ->willReturn($serializedTypeData);
+        $this->serializerMock->expects($this->at(0))
+            ->method('unserialize')
+            ->with($serializedRoutesConfig)
+            ->willReturn($routesConfig);
+        $this->serializerMock->expects($this->at(1))
+            ->method('unserialize')
+            ->with($serializedTypeData)
+            ->willReturn($typeData);
+        $this->typeProcessorMock->expects($this->once())
+            ->method('setTypesData')
+            ->with($typeData);
+        $this->serviceMetadata->getRoutesConfig();
+        $this->assertEquals($routesConfig, $this->serviceMetadata->getRoutesConfig());
+    }
 
+    /**
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function testGetRoutesConfigNoCache()
+    {
         $servicesConfig = [
-            'services' => [\Magento\Customer\Api\AccountManagementInterface::class => [
-                    'V1' => [
-                        'methods' => [
-                            'activateById' => [
-                                'resources' => [
-                                    [
-                                        'Magento_Customer::manage',
-                                    ],
-                                ],
-                                'secure' => false,
-                            ],
-                        ],
-                    ],
-                ], \Magento\Customer\Api\CustomerRepositoryInterface::class => [
+            'services' => [
+                CustomerRepositoryInterface::class => [
                     'V1' => [
                         'methods' => [
                             'getById' => [
                                 'resources' => [
                                     [
                                         'Magento_Customer::customer',
-                                    ],
+                                    ]
                                 ],
-                                'secure' => false,
-                            ],
-                        ],
-                    ],
-                ],
+                                'secure' => false
+                            ]
+                        ]
+                    ]
+                ]
             ],
             'routes' => [
-                '/V1/customers/me/activate' => [
-                    'PUT' => [
+                '/V1/customers/:customerId' => [
+                    'GET' => [
                         'secure' => false,
                         'service' => [
-                            'class' => \Magento\Customer\Api\AccountManagementInterface::class,
-                            'method' => 'activateById',
+                            'class' => CustomerRepositoryInterface::class,
+                            'method' => 'getById'
                         ],
                         'resources' => [
-                            'self' => true,
+                            'Magento_Customer::customer' => true
                         ],
+                        'parameters' => []
+                    ]
+                ]
+            ],
+            'class' => CustomerRepositoryInterface::class,
+            'description' => 'Customer CRUD interface.',
+        ];
+        $methodsReflectionData = [
+            'getById' => [
+                'documentation' => 'Get customer by customer ID.',
+                'interface' => [
+                    'in' => [
                         'parameters' => [
                             'customerId' => [
-                                'force' => true,
-                                'value' => '%customer_id%',
-                            ],
-                        ],
+                                'type' => 'int',
+                                'required' => true,
+                                'documentation' => null
+                            ]
+                        ]
                     ],
-                ],
-                '/V1/customers/:customerId' => [
-                    'GET' => [
-                        'secure' => false,
-                        'service' => [
-                            'class' => \Magento\Customer\Api\CustomerRepositoryInterface::class,
-                            'method' => 'getById',
-                        ],
-                        'resources' => [
-                            'Magento_Customer::customer' => true,
-                        ],
+                    'out' => [
                         'parameters' => [
-                        ],
+                            'result' => [
+                                'type' => 'CustomerDataCustomerInterface',
+                                'required' => true,
+                                'documentation' => null
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ];
+        $routesMetadata = [
+            'customerCustomerRepositoryV1' => [
+                'methods' => array_merge_recursive(
+                    [
+                        'getById' => [
+                            'resources' => [
+                                [
+                                    'Magento_Customer::customer',
+                                ]
+                            ],
+                            'method' => 'getById',
+                            'inputRequired' => false,
+                            'isSecure' => false,
+                        ]
                     ],
+                    $methodsReflectionData
+                ),
+                'routes' => [
+                    '/V1/customers/:customerId' => [
+                        'GET' => [
+                            'method' => 'getById',
+                            'parameters' => []
+                        ]
+                    ]
                 ],
+                'class' => CustomerRepositoryInterface::class,
+                'description' => 'Customer CRUD interface.'
             ]
         ];
-
-        /**
-         * @var $cacheMock \Magento\Webapi\Model\Cache\Type\Webapi
-         */
-        $cacheMock = $this->getMockBuilder(\Magento\Webapi\Model\Cache\Type\Webapi::class)
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        /** @var $readerMock \Magento\Webapi\Model\Config\Reader */
-        $readerMock = $this->getMockBuilder(\Magento\Webapi\Model\Config\Reader::class)
-            ->disableOriginalConstructor()
-            ->getMock();
-        $readerMock->expects($this->any())->method('read')->will($this->returnValue($servicesConfig));
-
-        /** @var $config \Magento\Webapi\Model\Config */
-        $config = new \Magento\Webapi\Model\Config($cacheMock, $readerMock);
-
-        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
-        $typeProcessor = $objectManager->getObject(\Magento\Framework\Reflection\TypeProcessor::class);
-
-        /** @var $config \Magento\Webapi\Model\ServiceMetadata */
-        $this->serviceMetadata = new \Magento\Webapi\Model\ServiceMetadata(
-            $config,
-            $cacheMock,
-            $classReflection,
-            $typeProcessor
-        );
-
-        parent::setUp();
+        $typeData = [
+            'CustomerDataCustomerInterface' => [
+                'documentation' => 'Customer interface.',
+                'parameters' => [
+                    'id' => [
+                        'type' => 'int',
+                        'required' => false,
+                        'documentation' => 'Customer id'
+                    ]
+                ]
+            ]
+        ];
+        $serializedRoutesConfig = 'serialized routes config';
+        $serializedTypeData = 'serialized type data';
+        $this->cacheMock->expects($this->at(0))
+            ->method('load')
+            ->with(ServiceMetadata::ROUTES_CONFIG_CACHE_ID)
+            ->willReturn(false);
+        $this->cacheMock->expects($this->at(1))
+            ->method('load')
+            ->with(ServiceMetadata::REFLECTED_TYPES_CACHE_ID)
+            ->willReturn(false);
+        $this->serializerMock->expects($this->never())
+            ->method('unserialize');
+        $this->configMock->expects($this->exactly(2))
+            ->method('getServices')
+            ->willReturn($servicesConfig);
+        $this->classReflectorMock->expects($this->once())
+            ->method('reflectClassMethods')
+            ->willReturn($methodsReflectionData);
+        $this->classReflectorMock->expects($this->once())
+            ->method('extractClassDescription')
+            ->with(CustomerRepositoryInterface::class)
+            ->willReturn('Customer CRUD interface.');
+        $this->typeProcessorMock->expects($this->exactly(2))
+            ->method('getTypesData')
+            ->willReturn($typeData);
+        $this->serializerMock->expects($this->at(2))
+            ->method('serialize')
+            ->with($routesMetadata)
+            ->willReturn($serializedRoutesConfig);
+        $this->serializerMock->expects($this->at(3))
+            ->method('serialize')
+            ->with($typeData)
+            ->willReturn($serializedTypeData);
+        $this->cacheMock->expects($this->at(6))
+            ->method('save')
+            ->with(
+                $serializedRoutesConfig,
+                ServiceMetadata::ROUTES_CONFIG_CACHE_ID
+            );
+        $this->cacheMock->expects($this->at(7))
+            ->method('save')
+            ->with(
+                $serializedTypeData,
+                ServiceMetadata::REFLECTED_TYPES_CACHE_ID
+            );
+        $this->serviceMetadata->getRoutesConfig();
+        $this->assertEquals($routesMetadata, $this->serviceMetadata->getRoutesConfig());
     }
 
     /**
-     * Test identifying service name including subservices using class name.
-     *
-     * @dataProvider serviceNameDataProvider
+     * @dataProvider getServiceNameDataProvider
      */
     public function testGetServiceName($className, $version, $preserveVersion, $expected)
     {
-        $actual = $this->serviceMetadata->getServiceName($className, $version, $preserveVersion);
-        $this->assertEquals($expected, $actual);
+        $this->assertEquals(
+            $expected,
+            $this->serviceMetadata->getServiceName($className, $version, $preserveVersion)
+        );
     }
 
     /**
-     * Dataprovider for testGetServiceName
-     *
      * @return string
      */
-    public function serviceNameDataProvider()
+    public function getServiceNameDataProvider()
     {
         return [
-            [\Magento\Customer\Api\AccountManagementInterface::class, 'V1', false, 'customerAccountManagement'],
-            [\Magento\Customer\Api\AddressRepositoryInterface::class, 'V1', true, 'customerAddressRepositoryV1'],
+            [
+                \Magento\Customer\Api\AccountManagementInterface::class,
+                'V1',
+                false,
+                'customerAccountManagement'
+            ],
+            [
+                \Magento\Customer\Api\AddressRepositoryInterface::class,
+                'V1',
+                true,
+                'customerAddressRepositoryV1'
+            ],
         ];
     }
 
     /**
      * @expectedException \InvalidArgumentException
-     * @dataProvider dataProviderForTestGetServiceNameInvalidName
+     * @dataProvider getServiceNameInvalidNameDataProvider
      */
     public function testGetServiceNameInvalidName($interfaceClassName, $version)
     {
@@ -189,111 +452,18 @@ class ServiceMetadataTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * Dataprovider for testGetServiceNameInvalidName
-     *
      * @return string
      */
-    public function dataProviderForTestGetServiceNameInvalidName()
+    public function getServiceNameInvalidNameDataProvider()
     {
         return [
-            ['BarV1Interface', 'V1'], // Missed vendor, module, 'Service'
+            ['BarV1Interface', 'V1'], // Missed vendor, module and Service
             ['Service\\V1Interface', 'V1'], // Missed vendor and module
             ['Magento\\Foo\\Service\\BarVxInterface', 'V1'], // Version number should be a number
-            ['Magento\\Foo\\Service\\BarInterface', 'V1'], // Version missed
-            ['Magento\\Foo\\Service\\BarV1', 'V1'], // 'Interface' missed
-            ['Foo\\Service\\BarV1Interface', 'V1'], // Module missed
-            ['Foo\\BarV1Interface', 'V1'] // Module and 'Service' missed
-        ];
-    }
-
-    public function testGetServiceMetadata()
-    {
-        $expectedResult = [
-            'methods' => [
-                'activateById' => [
-                    'method' => 'activateById',
-                    'inputRequired' => '',
-                    'isSecure' => '',
-                    'resources' => [['Magento_Customer::manage']],
-                    'interface' => [
-                        'in' => [
-                            'parameters' => [
-                                'customerId' => [
-                                    'force' => true,
-                                    'value' => '%customer_id%',
-                                ],
-                                'requiredInputParameter' => [
-                                    'required' => true,
-                                ],
-                            ],
-                        ],
-                        'out' => [
-                            'parameters' => [
-                                'outputParameter' => [
-                                    'type' => 'string',
-                                ],
-                            ],
-                        ],
-                    ],
-                ],
-            ],
-            'class' => \Magento\Customer\Api\AccountManagementInterface::class,
-            'description' => 'classDescription',
+            ['Magento\\Foo\\Service\\BarInterface', 'V1'], // Missed version
+            ['Magento\\Foo\\Service\\BarV1', 'V1'], // Missed Interface
+            ['Foo\\Service\\BarV1Interface', 'V1'], // Missed module
+            ['Foo\\BarV1Interface', 'V1'] // Missed module and Service
         ];
-        $result = $this->serviceMetadata->getServiceMetadata('customerAccountManagementV1');
-        $this->assertEquals($expectedResult, $result);
-    }
-
-    public function testGetRouteMetadata()
-    {
-        $expectedResult = [
-            'methods' => [
-                'activateById' => [
-                    'method' => 'activateById',
-                    'inputRequired' => '',
-                    'isSecure' => '',
-                    'resources' => [['Magento_Customer::manage']],
-                    'interface' => [
-                        'in' => [
-                            'parameters' => [
-                                'customerId' => [
-                                    'force' => true,
-                                    'value' => '%customer_id%',
-                                ],
-                                'requiredInputParameter' => [
-                                    'required' => true,
-                                ],
-                            ],
-                        ],
-                        'out' => [
-                            'parameters' => [
-                                'outputParameter' => [
-                                    'type' => 'string',
-                                ],
-                            ],
-                        ],
-                    ],
-                ],
-            ],
-            'class' => \Magento\Customer\Api\AccountManagementInterface::class,
-            'description' => 'classDescription',
-            'routes' => [
-                '/V1/customers/me/activate' => [
-                    'PUT' => [
-                        'method' => 'activateById',
-                        'parameters' => [
-                            'customerId' => [
-                                'force' => true,
-                                'value' => '%customer_id%'
-                            ]
-                        ]
-                    ]
-                ]
-            ]
-        ];
-        $result = $this->serviceMetadata->getRouteMetadata('customerAccountManagementV1');
-        $this->assertEquals($expectedResult, $result);
     }
 }
-
-require_once realpath(__DIR__ . '/../_files/test_interfaces.php');
diff --git a/app/code/Magento/Webapi/Test/Unit/Model/Soap/ConfigTest.php b/app/code/Magento/Webapi/Test/Unit/Model/Soap/ConfigTest.php
deleted file mode 100644
index aa5d1a7bfab7e5a1858ae9b321d41a1accba3955..0000000000000000000000000000000000000000
--- a/app/code/Magento/Webapi/Test/Unit/Model/Soap/ConfigTest.php
+++ /dev/null
@@ -1,166 +0,0 @@
-<?php
-/**
- * Config helper Unit tests.
- *
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-// @codingStandardsIgnoreFile
-
-/**
- * Class implements tests for \Magento\Webapi\Model\Soap\Config class.
- */
-namespace Magento\Webapi\Test\Unit\Model\Soap;
-
-class ConfigTest extends \PHPUnit_Framework_TestCase
-{
-    /** @var \Magento\Webapi\Model\Soap\Config */
-    protected $_soapConfig;
-
-    /** @var  \Magento\Framework\TestFramework\Unit\Helper\ObjectManager */
-    protected $objectManager;
-
-    /**
-     * Set up helper.
-     */
-    protected function setUp()
-    {
-        $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
-
-        $typeProcessor = $this->objectManager->getObject(\Magento\Framework\Reflection\TypeProcessor::class);
-
-        $objectManagerMock = $this->getMockBuilder(
-            \Magento\Framework\App\ObjectManager::class
-        )->disableOriginalConstructor()->getMock();
-
-        $classReflection = $this->getMock(
-            \Magento\Webapi\Model\Config\ClassReflector::class,
-            ['reflectClassMethods'],
-            ['_typeProcessor' => $typeProcessor],
-            ''
-        );
-        $classReflection->expects($this->any())->method('reflectClassMethods')->will($this->returnValue([]));
-
-        $servicesConfig = [
-            'services' => [\Magento\Customer\Api\AccountManagementInterface::class => [
-                    'V1' => [
-                        'methods' => [
-                            'activate' => [
-                                'resources' => [
-                                    [
-                                        'Magento_Customer::manage',
-                                    ],
-                                ],
-                                'secure' => false,
-                            ],
-                        ],
-                    ],
-                ], \Magento\Customer\Api\CustomerRepositoryInterface::class => [
-                    'V1' => [
-                        'methods' => [
-                            'getById' => [
-                                'resources' => [
-                                    [
-                                        'Magento_Customer::customer',
-                                    ],
-                                ],
-                                'secure' => false,
-                            ],
-                        ],
-                    ],
-                ],
-            ],
-        ];
-
-        /**
-         * @var $registryMock \Magento\Framework\Registry
-         */
-        $registryMock = $this->getMockBuilder(\Magento\Framework\Registry::class)
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        /**
-         * @var $cacheMock \Magento\Webapi\Model\Cache\Type\Webapi
-         */
-        $cacheMock = $this->getMockBuilder(\Magento\Webapi\Model\Cache\Type\Webapi::class)
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        /** @var $readerMock \Magento\Webapi\Model\Config\Reader */
-        $readerMock = $this->getMockBuilder(\Magento\Webapi\Model\Config\Reader::class)
-            ->disableOriginalConstructor()
-            ->getMock();
-        $readerMock->expects($this->any())->method('read')->will($this->returnValue($servicesConfig));
-
-        /** @var $config \Magento\Webapi\Model\Config */
-        $config = new \Magento\Webapi\Model\Config($cacheMock, $readerMock);
-
-        /** @var $config \Magento\Webapi\Model\ServiceMetadata */
-        $serviceMetadata = new \Magento\Webapi\Model\ServiceMetadata(
-            $config,
-            $cacheMock,
-            $classReflection,
-            $typeProcessor);
-
-        $this->_soapConfig = $this->objectManager->getObject(
-            \Magento\Webapi\Model\Soap\Config::class,
-            [
-                'objectManager' => $objectManagerMock,
-                'registry' => $registryMock,
-                'serviceMetadata' => $serviceMetadata,
-            ]
-        );
-        parent::setUp();
-    }
-
-    public function testGetRequestedSoapServices()
-    {
-        $expectedResult = [
-            'customerAccountManagementV1' =>
-                [
-                    'methods' => [
-                        'activate' => [
-                            'method' => 'activate',
-                            'inputRequired' => '',
-                            'isSecure' => '',
-                            'resources' => [['Magento_Customer::manage']],
-                        ],
-                    ],
-                    'class' => \Magento\Customer\Api\AccountManagementInterface::class,
-                    'description' => 'Interface for managing customers accounts.',
-                ],
-        ];
-
-        $result = $this->_soapConfig->getRequestedSoapServices(
-            ['customerAccountManagementV1', 'moduleBarV2', 'moduleBazV1']
-        );
-
-        $this->assertEquals($expectedResult, $result);
-    }
-
-    public function testGetServiceMethodInfo()
-    {
-        $expectedResult = [
-            'class' => \Magento\Customer\Api\CustomerRepositoryInterface::class,
-            'method' => 'getById',
-            'isSecure' => false,
-            'resources' => [['Magento_Customer::customer']],
-        ];
-        $methodInfo = $this->_soapConfig->getServiceMethodInfo(
-            'customerCustomerRepositoryV1GetById',
-            ['customerCustomerRepositoryV1', 'moduleBazV1']
-        );
-        $this->assertEquals($expectedResult, $methodInfo);
-    }
-
-    public function testGetSoapOperation()
-    {
-        $expectedResult = 'customerAccountManagementV1Activate';
-        $soapOperation = $this->_soapConfig
-            ->getSoapOperation(\Magento\Customer\Api\AccountManagementInterface::class, 'activate', 'V1');
-        $this->assertEquals($expectedResult, $soapOperation);
-    }
-}
-
-require_once realpath(__DIR__ . '/../../_files/test_interfaces.php');
diff --git a/app/code/Magento/Webapi/Test/Unit/_files/test_interfaces.php b/app/code/Magento/Webapi/Test/Unit/_files/test_interfaces.php
deleted file mode 100644
index 288a747cefd89cec4182de66890127eebd552806..0000000000000000000000000000000000000000
--- a/app/code/Magento/Webapi/Test/Unit/_files/test_interfaces.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-/**
- * Copyright © 2016 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-// @codingStandardsIgnoreFile
-
-namespace Magento\Framework\Module\Service;
-
-/**
- * The list of test interfaces.
- */
-interface FooV1Interface
-{
-    public function someMethod();
-}
-interface BarV1Interface
-{
-    public function someMethod();
-}
-interface FooBarV1Interface
-{
-    public function someMethod();
-}
-namespace Magento\Framework\Module\Service\Foo;
-
-interface BarV1Interface
-{
-    public function someMethod();
-}
diff --git a/app/etc/di.xml b/app/etc/di.xml
index 643390068a5e3e857ccb0e0d2d07fb5e26b8ea81..e430c15729d3d0cced20bf2b326d40f152b174e6 100755
--- a/app/etc/di.xml
+++ b/app/etc/di.xml
@@ -154,6 +154,7 @@
     <preference for="Magento\Framework\EntityManager\MapperInterface" type="Magento\Framework\EntityManager\CompositeMapper"/>
     <preference for="Magento\Framework\Console\CommandListInterface" type="Magento\Framework\Console\CommandList"/>
     <preference for="Magento\Framework\DataObject\IdentityGeneratorInterface" type="Magento\Framework\DataObject\IdentityService" />
+    <preference for="Magento\Framework\Serialize\SerializerInterface" type="Magento\Framework\Serialize\Serializer\Json" />
     <type name="Magento\Framework\Model\ResourceModel\Db\TransactionManager" shared="false" />
     <type name="Magento\Framework\Logger\Handler\Base">
         <arguments>
diff --git a/dev/tests/integration/testsuite/Magento/Webapi/Model/ServiceMetadataTest.php b/dev/tests/integration/testsuite/Magento/Webapi/Model/ServiceMetadataTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8fac1c9b0e7031277e59c67d31c8bbff555910c0
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Webapi/Model/ServiceMetadataTest.php
@@ -0,0 +1,135 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Webapi\Model;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Customer\Api\AccountManagementInterface;
+use Magento\Framework\Exception\LocalizedException;
+
+class ServiceMetadataTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var ServiceMetadata
+     */
+    private $serviceMetadata;
+
+    protected function setUp()
+    {
+        $objectManager = Bootstrap::getObjectManager();
+        $this->serviceMetadata = $objectManager->create(ServiceMetadata::class);
+    }
+
+    public function testGetServiceMetadata()
+    {
+        $expected = [
+            'methods' => [
+                'activate' => [
+                    'method' => 'activate',
+                    'inputRequired' => false,
+                    'isSecure' => false,
+                    'resources' => [
+                        'Magento_Customer::manage'
+                    ],
+                    'documentation' => 'Activate a customer account using a key that was sent in a confirmation email.',
+                    'interface' => [
+                        'in' => [
+                            'parameters' => [
+                                'email' => [
+                                    'type' => 'string',
+                                    'required' => true,
+                                    'documentation' => null
+                                ],
+                                'confirmationKey' => [
+                                    'type' => 'string',
+                                    'required' => true,
+                                    'documentation' => null
+                                ]
+                            ]
+                        ],
+                        'out' => [
+                            'parameters' => [
+                                'result' => [
+                                    'type' => 'CustomerDataCustomerInterface',
+                                    'required' => true,
+                                    'documentation' => ''
+                                ]
+                            ],
+                            'throws' => [
+                                '\\' . LocalizedException::class
+                            ]
+                        ]
+                    ]
+                ]
+            ],
+            'class' => AccountManagementInterface::class,
+            'description' => 'Interface for managing customers accounts.',
+        ];
+        $actual = $this->serviceMetadata->getServiceMetadata('customerAccountManagementV1');
+        $this->assertEquals(array_replace_recursive($actual, $expected), $actual);
+    }
+
+    public function testGetRouteMetadata()
+    {
+        $expected = [
+            'methods' => [
+                'activate' => [
+                    'method' => 'activate',
+                    'inputRequired' => false,
+                    'isSecure' => false,
+                    'resources' => [
+                        'Magento_Customer::manage'
+                    ],
+                    'documentation' => 'Activate a customer account using a key that was sent in a confirmation email.',
+                    'interface' => [
+                        'in' => [
+                            'parameters' => [
+                                'email' => [
+                                    'type' => 'string',
+                                    'required' => true,
+                                    'documentation' => null
+                                ],
+                                'confirmationKey' => [
+                                    'type' => 'string',
+                                    'required' => true,
+                                    'documentation' => null
+                                ]
+                            ]
+                        ],
+                        'out' => [
+                            'parameters' => [
+                                'result' => [
+                                    'type' => 'CustomerDataCustomerInterface',
+                                    'required' => true,
+                                    'documentation' => ''
+                                ]
+                            ],
+                            'throws' => [
+                                '\\' . LocalizedException::class
+                            ]
+                        ]
+                    ]
+                ]
+            ],
+            'class' => AccountManagementInterface::class,
+            'description' => 'Interface for managing customers accounts.',
+            'routes' => [
+                '/V1/customers/me/activate' => [
+                    'PUT' => [
+                        'method' => 'activateById',
+                        'parameters' => [
+                            'customerId' => [
+                                'force' => true,
+                                'value' => '%customer_id%'
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ];
+        $actual = $this->serviceMetadata->getRouteMetadata('customerAccountManagementV1');
+        $this->assertEquals(array_replace_recursive($actual, $expected), $actual);
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Webapi/Model/Soap/ConfigTest.php b/dev/tests/integration/testsuite/Magento/Webapi/Model/Soap/ConfigTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ff1634c60782aee3de08203078f9592716de7803
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Webapi/Model/Soap/ConfigTest.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Webapi\Model\Soap;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Customer\Api\AccountManagementInterface;
+use Magento\Customer\Api\CustomerRepositoryInterface;
+use Magento\Framework\Exception\LocalizedException;
+
+class ConfigTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Config
+     */
+    private $soapConfig;
+
+    protected function setUp()
+    {
+        $objectManager = Bootstrap::getObjectManager();
+        $this->soapConfig = $objectManager->create(Config::class);
+    }
+
+    public function testGetRequestedSoapServices()
+    {
+        $expected = [
+            'customerAccountManagementV1' => [
+                'methods' => [
+                    'activate' => [
+                        'method' => 'activate',
+                        'inputRequired' => false,
+                        'isSecure' => false,
+                        'resources' => [
+                            'Magento_Customer::manage'
+                        ],
+                        'documentation'
+                            => 'Activate a customer account using a key that was sent in a confirmation email.',
+                        'interface' => [
+                            'in' => [
+                                'parameters' => [
+                                    'email' => [
+                                        'type' => 'string',
+                                        'required' => true,
+                                        'documentation' => null
+                                    ],
+                                    'confirmationKey' => [
+                                        'type' => 'string',
+                                        'required' => true,
+                                        'documentation' => null
+                                    ]
+                                ]
+                            ],
+                            'out' => [
+                                'parameters' => [
+                                    'result' => [
+                                        'type' => 'CustomerDataCustomerInterface',
+                                        'required' => true,
+                                        'documentation' => null
+                                    ]
+                                ],
+                                'throws' => [
+                                    '\\' . LocalizedException::class
+                                ]
+                            ]
+                        ]
+                    ]
+                ],
+                'class' => AccountManagementInterface::class,
+                'description' => 'Interface for managing customers accounts.',
+            ]
+        ];
+        $actual = $this->soapConfig->getRequestedSoapServices(
+            [
+                'customerAccountManagementV1',
+                'NonExistentService'
+            ]
+        );
+        $this->assertEquals(array_replace_recursive($actual, $expected), $actual);
+    }
+
+    public function testGetServiceMethodInfo()
+    {
+        $expected = [
+            'class' => CustomerRepositoryInterface::class,
+            'method' => 'getById',
+            'isSecure' => false,
+            'resources' => [
+                'Magento_Customer::customer',
+                'self'
+            ],
+        ];
+        $actual = $this->soapConfig->getServiceMethodInfo(
+            'customerCustomerRepositoryV1GetById',
+            [
+                'customerCustomerRepositoryV1',
+                'NonExistentService'
+            ]
+        );
+        $this->assertEquals($expected, $actual);
+    }
+
+    public function testGetSoapOperation()
+    {
+        $expected = 'customerAccountManagementV1Activate';
+        $actual = $this->soapConfig
+            ->getSoapOperation(
+                AccountManagementInterface::class,
+                'activate',
+                'V1'
+            );
+        $this->assertEquals($expected, $actual);
+    }
+}
diff --git a/dev/tests/static/framework/Magento/TestFramework/CodingStandard/Tool/CopyPasteDetector.php b/dev/tests/static/framework/Magento/TestFramework/CodingStandard/Tool/CopyPasteDetector.php
index b2d9c164fbd1bc57cf9f2497ff02d6fe6f6895e9..b2766ebd90d92e85072bd84c7c7939813d863bc8 100644
--- a/dev/tests/static/framework/Magento/TestFramework/CodingStandard/Tool/CopyPasteDetector.php
+++ b/dev/tests/static/framework/Magento/TestFramework/CodingStandard/Tool/CopyPasteDetector.php
@@ -56,8 +56,7 @@ class CopyPasteDetector implements ToolInterface, BlacklistInterface
      */
     public function canRun()
     {
-        $vendorDir = require BP . '/app/etc/vendor_path.php';
-        exec('php ' . BP . '/' . $vendorDir . '/bin/phpcpd --version', $output, $exitCode);
+        exec($this->getCommand() . ' --version', $output, $exitCode);
         return $exitCode === 0;
     }
 
@@ -71,22 +70,37 @@ class CopyPasteDetector implements ToolInterface, BlacklistInterface
      */
     public function run(array $whiteList)
     {
-        $blackListStr = ' ';
+        $blacklistedDirs = [];
+        $blacklistedFileNames = [];
         foreach ($this->blacklist as $file) {
             $file = escapeshellarg(trim($file));
             if (!$file) {
                 continue;
             }
-            $blackListStr .= '--exclude ' . $file . ' ';
+            $ext = pathinfo($file, PATHINFO_EXTENSION);
+            if ($ext != '') {
+                $blacklistedFileNames[] = $file;
+            } else {
+                $blacklistedDirs[] = '--exclude ' . $file . ' ';
+            }
         }
 
-        $vendorDir = require BP . '/app/etc/vendor_path.php';
-        $command = 'php ' . BP . '/' . $vendorDir . '/bin/phpcpd' . ' --log-pmd ' . escapeshellarg(
-                $this->reportFile
-            ) . ' --names-exclude "*Test.php" --min-lines 13' . $blackListStr . ' ' . implode(' ', $whiteList);
-
+        $command = $this->getCommand() . ' --log-pmd ' . escapeshellarg($this->reportFile)
+            . ' --names-exclude ' . join(',', $blacklistedFileNames) . ' --min-lines 13 ' . join(' ', $blacklistedDirs)
+            . ' ' . implode(' ', $whiteList);
         exec($command, $output, $exitCode);
 
         return !(bool)$exitCode;
     }
+
+    /**
+     * Get PHPCPD command
+     *
+     * @return string
+     */
+    private function getCommand()
+    {
+        $vendorDir = require BP . '/app/etc/vendor_path.php';
+        return 'php ' . BP . '/' . $vendorDir . '/bin/phpcpd';
+    }
 }
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/UnsecureFunctionsUsageTest.php b/dev/tests/static/testsuite/Magento/Test/Legacy/UnsecureFunctionsUsageTest.php
index 6b18eb2b71478463e39e815dec078478c4034a07..e5263713d71d7af374ea1f32c2d765d3639e56ce 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/UnsecureFunctionsUsageTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/UnsecureFunctionsUsageTest.php
@@ -64,7 +64,7 @@ class UnsecureFunctionsUsageTest extends \PHPUnit_Framework_TestCase
                 if ($regexp) {
                     $matches = preg_grep(
                         $regexp,
-                        file($fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)
+                        file($fileName)
                     );
                     if (!empty($matches)) {
                         foreach (array_keys($matches) as $line) {
@@ -114,7 +114,8 @@ class UnsecureFunctionsUsageTest extends \PHPUnit_Framework_TestCase
                     if (strpos($path, $directory) === 0) {
                         if (preg_match($fileExtensions, $path)) {
                             foreach ($blackListFiles as $blackListFile) {
-                                if (preg_match($blackListFile, $path)) {
+                                $blackListFile = preg_quote($blackListFile, '#');
+                                if (preg_match('#' . $blackListFile . '#', $path)) {
                                     return false;
                                 }
                             }
@@ -158,10 +159,6 @@ class UnsecureFunctionsUsageTest extends \PHPUnit_Framework_TestCase
         if (empty($functions)) {
             return '';
         }
-        $regexArray = [];
-        foreach ($functions as $function) {
-            $regexArray[] = '\b' . $function . '\b\(';
-        }
-        return '/' . implode('|', $regexArray) . '/i';
+        return '/(?<!function |[^\s])\b(' . join('|', $functions) . ')\s*\(/i';
     }
 }
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/blacklist.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/blacklist.php
index d120a4543b9ddced597d330ab489de15c80cdb86..42b8e68e784111b96d43049ae27dc5ebc963ad40 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/blacklist.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/blacklist.php
@@ -4,6 +4,7 @@
  * See COPYING.txt for license details.
  */
 return [
-    '/Test\/Unit/',
-    '/lib\/internal\/Magento\/Framework\/DB\/Adapter\/Pdo\/Mysql\.php/',
+    'Test/Unit',
+    'lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php',
+    'lib/internal/Magento/Framework/Serialize/Serializer/Serialize.php',
 ];
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/whitelist.txt b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/whitelist.txt
index 2567475de6a035b2a369ac342c076ce1e5cad07d..e464d9713657f6341ccbf1f6d77986ebac08d979 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/whitelist.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/security/whitelist.txt
@@ -1,4 +1,5 @@
+# "Component Type" "Component Name" "Path Pattern"
 module * /
 library * /
 setup
-pub
\ No newline at end of file
+pub
diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt
index 56e0d51516c2632a28acd50ca2c3999e984720df..3afe3af79b14ff3177a0dc1c5ea9fe42e93b6331 100644
--- a/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/phpcpd/blacklist/common.txt
@@ -196,4 +196,6 @@ Magento/Framework/Mview/Config/Data
 Magento/Framework/View/File/Collector/Override
 Magento/Framework/MessageQueue/Consumer/Config/ConsumerConfigItem
 Magento/Framework/MessageQueue/Publisher/Config/PublisherConfigItem
-Magento/Framework/MessageQueue/Topology/Config/ExchangeConfigItem
\ No newline at end of file
+Magento/Framework/MessageQueue/Topology/Config/ExchangeConfigItem
+IntegrationConfig.php
+*Test.php
diff --git a/lib/internal/Magento/Framework/Serialize/README.md b/lib/internal/Magento/Framework/Serialize/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..5af8fb7f71b6b174855cb39d004ea29cb6d518a3
--- /dev/null
+++ b/lib/internal/Magento/Framework/Serialize/README.md
@@ -0,0 +1,8 @@
+# Serialize
+
+**Serialize** library provides interface *SerializerInterface* and multiple implementations:
+
+ * *Json* - default implementation. Uses PHP native json_encode/json_decode functions;
+ * *Serialize* - less secure than *Json*, but gives higher performance on big arrays. Uses PHP native serialize/unserialize functions, does not unserialize objects on PHP 7.
+ 
+Using *Serialize* implementation directly is discouraged, always use *SerializerInterface*, using *Serialize* implementation may lead to security vulnerabilities.
\ No newline at end of file
diff --git a/lib/internal/Magento/Framework/Serialize/Serializer/Json.php b/lib/internal/Magento/Framework/Serialize/Serializer/Json.php
new file mode 100644
index 0000000000000000000000000000000000000000..9c5e55b194165849cddaeebc9d6f772375d7a66e
--- /dev/null
+++ b/lib/internal/Magento/Framework/Serialize/Serializer/Json.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Serialize\Serializer;
+
+use Magento\Framework\Serialize\SerializerInterface;
+
+/**
+ * Class for serializing data to json string and unserializing json string to data
+ */
+class Json implements SerializerInterface
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function serialize($data)
+    {
+        return json_encode($data);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function unserialize($string)
+    {
+        return json_decode($string, true);
+    }
+}
diff --git a/lib/internal/Magento/Framework/Serialize/Serializer/Serialize.php b/lib/internal/Magento/Framework/Serialize/Serializer/Serialize.php
new file mode 100644
index 0000000000000000000000000000000000000000..3d2dc66e502ef478a868d04eac3bdc2e01bf8519
--- /dev/null
+++ b/lib/internal/Magento/Framework/Serialize/Serializer/Serialize.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Serialize\Serializer;
+
+use Magento\Framework\Serialize\SerializerInterface;
+
+/**
+ * Less secure than Json implementation, but gives higher performance on big arrays. Does not unserialize objects on
+ * PHP 7. Using this implementation directly is discouraged as it may lead to security vulnerabilities, especially on
+ * older versions of PHP
+ */
+class Serialize implements SerializerInterface
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function serialize($data)
+    {
+        return serialize($data);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function unserialize($string)
+    {
+        if ($this->getPhpVersion() >= 7) {
+            return unserialize($string, ['allowed_classes' => false]);
+        }
+        return unserialize($string);
+    }
+
+    /**
+     * Return major PHP version
+     *
+     * @return int
+     */
+    private function getPhpVersion()
+    {
+        return PHP_MAJOR_VERSION;
+    }
+}
diff --git a/lib/internal/Magento/Framework/Serialize/SerializerInterface.php b/lib/internal/Magento/Framework/Serialize/SerializerInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..f7a15b31a826e004541434a6ec6b4b30863ba9c3
--- /dev/null
+++ b/lib/internal/Magento/Framework/Serialize/SerializerInterface.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Serialize;
+
+/**
+ * Interface for serializing
+ */
+interface SerializerInterface
+{
+    /**
+     * Serialize data into string
+     *
+     * @param string|int|float|bool|array|null $data
+     * @return string|bool
+     */
+    public function serialize($data);
+
+    /**
+     * Unserialize the given string
+     *
+     * @param string $string
+     * @return string|int|float|bool|array|null
+     */
+    public function unserialize($string);
+}
diff --git a/lib/internal/Magento/Framework/Serialize/Test/Unit/Serializer/JsonTest.php b/lib/internal/Magento/Framework/Serialize/Test/Unit/Serializer/JsonTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..88e06d89e3763d36a1301b595942a513359ce076
--- /dev/null
+++ b/lib/internal/Magento/Framework/Serialize/Test/Unit/Serializer/JsonTest.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Serialize\Test\Unit\Serializer;
+
+use Magento\Framework\DataObject;
+use Magento\Framework\Serialize\Serializer\Json;
+
+class JsonTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\Serialize\Serializer\Json
+     */
+    private $json;
+
+    protected function setUp()
+    {
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->json = $objectManager->getObject(Json::class);
+    }
+
+    /**
+     * @param string|int|float|bool|array|null $value
+     * @param string $expected
+     * @dataProvider serializeDataProvider
+     */
+    public function testSerialize($value, $expected)
+    {
+        $this->assertEquals(
+            $expected,
+            $this->json->serialize($value)
+        );
+    }
+
+    public function serializeDataProvider()
+    {
+        $dataObject = new DataObject(['something']);
+        return [
+            ['', '""'],
+            ['string', '"string"'],
+            [null, 'null'],
+            [false, 'false'],
+            [['a' => 'b', 'd' => 123], '{"a":"b","d":123}'],
+            [123, '123'],
+            [10.56, '10.56'],
+            [$dataObject, '{}'],
+        ];
+    }
+
+    /**
+     * @param string $value
+     * @param string|int|float|bool|array|null $expected
+     * @dataProvider unserializeDataProvider
+     */
+    public function testUnserialize($value, $expected)
+    {
+        $this->assertEquals(
+            $expected,
+            $this->json->unserialize($value)
+        );
+    }
+
+    public function unserializeDataProvider()
+    {
+        return [
+            ['""', ''],
+            ['"string"', 'string'],
+            ['null', null],
+            ['false', false],
+            ['{"a":"b","d":123}', ['a' => 'b', 'd' => 123]],
+            ['123', 123],
+            ['10.56', 10.56],
+            ['{}', []],
+        ];
+    }
+}
diff --git a/lib/internal/Magento/Framework/Serialize/Test/Unit/Serializer/SerializeTest.php b/lib/internal/Magento/Framework/Serialize/Test/Unit/Serializer/SerializeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..874647b5d705fc55e6b9328bab8450e1908a8921
--- /dev/null
+++ b/lib/internal/Magento/Framework/Serialize/Test/Unit/Serializer/SerializeTest.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Serialize\Test\Unit\Serializer;
+
+use Magento\Framework\Serialize\Serializer\Serialize;
+use Magento\Framework\Serialize\Signer;
+use Psr\Log\LoggerInterface;
+use Magento\Framework\Serialize\InvalidSignatureException;
+
+class SerializeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Serialize
+     */
+    private $serialize;
+
+    protected function setUp()
+    {
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->serialize = $objectManager->getObject(Serialize::class);
+    }
+
+    /**
+     * @param string|int|float|bool|array|null $value
+     * @param string $serializedValue
+     * @dataProvider serializeDataProvider
+     */
+    public function testSerialize($value, $serializedValue)
+    {
+        $this->assertEquals($serializedValue, $this->serialize->serialize($value));
+    }
+
+    public function serializeDataProvider()
+    {
+        return [
+            ['string', 's:6:"string";'],
+            ['', 's:0:"";'],
+            [10, 'i:10;'],
+            [10.5, 'd:10.5;'],
+            [null, 'N;'],
+            [false, 'b:0;'],
+            [['foo' => 'bar'], 'a:1:{s:3:"foo";s:3:"bar";}'],
+        ];
+    }
+
+    /**
+     * @param string $serializedValue
+     * @param string|int|float|bool|array|null $value
+     * @dataProvider unserializeDataProvider
+     */
+    public function testUnserialize($serializedValue, $value)
+    {
+        $this->assertEquals($value, $this->serialize->unserialize($serializedValue));
+    }
+
+    public function unserializeDataProvider()
+    {
+        return [
+            ['s:6:"string";', 'string'],
+            ['s:0:"";', ''],
+            ['i:10;', 10],
+            ['d:10.5;', 10.5],
+            ['N;', null],
+            ['b:0;', false],
+            ['a:1:{s:3:"foo";s:3:"bar";}', ['foo' => 'bar']],
+        ];
+    }
+}