From 1922484990f50060fd4376bfb2c6cc3f286a31ff Mon Sep 17 00:00:00 2001
From: Dmytro Voskoboinikov <dvoskoboinikov@ebay.com>
Date: Thu, 18 Dec 2014 12:51:27 +0200
Subject: [PATCH 01/71] MAGETWO-3387: 'Append Comments' is cleared on
 validation error during Order Submit

---
 .../Block/Adminhtml/Order/Create/Comment.php  | 14 ----
 .../Block/Adminhtml/Order/Create/Totals.php   | 14 ++++
 .../templates/order/create/totals.phtml       |  2 +-
 .../Adminhtml/Order/Create/TotalsTest.php     | 84 +++++++++++++++++++
 4 files changed, 99 insertions(+), 15 deletions(-)
 create mode 100644 dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/TotalsTest.php

diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Comment.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Comment.php
index 7ca3943d4ec..6391503155d 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Comment.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Comment.php
@@ -47,18 +47,4 @@ class Comment extends \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate
     {
         return $this->escapeHtml($this->getQuote()->getCustomerNote());
     }
-
-    /**
-     * Get note notification
-     *
-     * @return bool
-     */
-    public function getNoteNotify()
-    {
-        $notify = $this->getQuote()->getCustomerNoteNotify();
-        if (is_null($notify) || $notify) {
-            return true;
-        }
-        return false;
-    }
 }
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Totals.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Totals.php
index 833932ae64b..dedf8478a6d 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Totals.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Totals.php
@@ -181,4 +181,18 @@ class Totals extends \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate
     {
         return $this->_salesData->canSendNewOrderConfirmationEmail($this->getQuote()->getStoreId());
     }
+
+    /**
+     * Get note notification
+     *
+     * @return bool
+     */
+    public function getNoteNotify()
+    {
+        $notify = $this->getQuote()->getCustomerNoteNotify();
+        if (is_null($notify) || $notify) {
+            return true;
+        }
+        return false;
+    }
 }
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/create/totals.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/create/totals.phtml
index 31c3a500313..2e104cccf9e 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/create/totals.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/create/totals.phtml
@@ -13,7 +13,7 @@
 <div class="divider"></div>
 <div class="order-totals-bottom">
     <div class="field choice field-append-comments">
-        <input type="checkbox" id="notify_customer" name="order[comment][customer_note_notify]" value="1" <?php if ($this->getNoteNotify()): ?>checked="true"<?php endif; ?>/>
+        <input type="checkbox" id="notify_customer" name="order[comment][customer_note_notify]" value="1"<?php if ($this->getNoteNotify()): ?> checked="checked"<?php endif; ?>/>
         <label for="notify_customer" class="normal"><?php echo __('Append Comments') ?></label>
     </div>
     <?php if ($this->canSendNewOrderConfirmationEmail()): ?>
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/TotalsTest.php b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/TotalsTest.php
new file mode 100644
index 00000000000..79deefa5c8c
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/TotalsTest.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Block\Adminhtml\Order\Create;
+
+use Magento\TestFramework\Helper\ObjectManager;
+
+/**
+ * Totals block test
+ */
+class TotalsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\TestFramework\Helper\ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * @var \Magento\Sales\Block\Adminhtml\Order\Create\Totals
+     */
+    protected $totals;
+
+    /**
+     * @var \Magento\Sales\Model\Quote|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $quoteMock;
+
+    /**
+     * @var \Magento\Backend\Model\Session\Quote|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $sessionQuoteMock;
+
+    protected function setUp()
+    {
+        $this->objectManager = new ObjectManager($this);
+
+        $this->quoteMock = $this->getMock(
+            '\Magento\Sales\Model\Quote', ['getCustomerNoteNotify'], [], '', false
+        );
+        $this->sessionQuoteMock = $this->getMock(
+            '\Magento\Backend\Model\Session\Quote', [], [], '', false
+        );
+
+        $this->sessionQuoteMock->expects($this->any())
+            ->method('getQuote')
+            ->willReturn($this->quoteMock);
+
+        $this->totals = $this->objectManager->getObject(
+            '\Magento\Sales\Block\Adminhtml\Order\Create\Totals',
+            [
+                'sessionQuote' => $this->sessionQuoteMock
+            ]
+        );
+    }
+
+    /**
+     * @param mixed $customerNoteNotify
+     * @param bool $expectedResult
+     * @dataProvider getNoteNotifyDataProvider
+     */
+    public function testGetNoteNotify($customerNoteNotify, $expectedResult)
+    {
+        $this->quoteMock->expects($this->any())
+            ->method('getCustomerNoteNotify')
+            ->willReturn($customerNoteNotify);
+
+        $this->assertEquals($expectedResult, $this->totals->getNoteNotify());
+    }
+
+    /**
+     * @return array
+     */
+    public function getNoteNotifyDataProvider()
+    {
+        return [
+            [0, false],
+            [1, true],
+            ['0', false],
+            ['1', true],
+            [null, true]
+        ];
+    }
+}
-- 
GitLab


From f99d59c1730268afea9982e36047b7a8f33102cc Mon Sep 17 00:00:00 2001
From: Dmytro Voskoboinikov <dvoskoboinikov@ebay.com>
Date: Thu, 18 Dec 2014 14:27:45 +0200
Subject: [PATCH 02/71] MAGETWO-3387: 'Append Comments' is cleared on
 validation error during Order Submit

---
 .../Magento/Test/Legacy/_files/obsolete_methods.php          | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
index 4ffcca56075..4ee4d932893 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
@@ -2001,4 +2001,9 @@ return [
     ['getScriptTranslation', 'Magento\Framework\LocaleInterface'],
     ['getCountryTranslation', 'Magento\Framework\LocaleInterface'],
     ['getTerritoryTranslation', 'Magento\Framework\LocaleInterface'],
+    [
+        'getNoteNotify',
+        'Magento\Sales\Block\Adminhtml\Order\Create\Comment',
+        'Magento\Sales\Block\Adminhtml\Order\Create\Totals'
+    ],
 ];
-- 
GitLab


From c2ad65c29ad19bc091bc607e5fab8ba643ebf4b7 Mon Sep 17 00:00:00 2001
From: Andriy Nasinnyk <anasinnyk@ebay.com>
Date: Thu, 18 Dec 2014 14:52:05 +0200
Subject: [PATCH 03/71] MAGETWO-13915: PSR-3: common interface for logging
 libraries.

---
 .../Magento/Backend/Model/Menu/Config.php     |   4 -
 app/code/Magento/Core/Model/Layout/Merge.php  |   1 -
 .../Magento/Store/Model/StorageFactory.php    |  33 ---
 composer.json                                 |   3 +-
 .../Magento/TestFramework/ErrorLog/Logger.php |   6 +-
 .../Magento/Core/Model/Layout/MergeTest.php   |   3 +-
 .../Magento/Framework/LoggerTest.php          | 211 ------------------
 .../Magento/Framework/Message/ManagerTest.php |   3 +-
 .../Store/Model/StorageFactoryTest.php        |  18 +-
 .../Image/Adapter/AbstractAdapter.php         |   1 -
 lib/internal/Magento/Framework/Logger.php     |  97 +-------
 .../Magento/Framework/Message/Manager.php     |   2 +-
 12 files changed, 13 insertions(+), 369 deletions(-)
 delete mode 100644 dev/tests/unit/testsuite/Magento/Framework/LoggerTest.php

diff --git a/app/code/Magento/Backend/Model/Menu/Config.php b/app/code/Magento/Backend/Model/Menu/Config.php
index 0a023244a00..089f0e1315e 100644
--- a/app/code/Magento/Backend/Model/Menu/Config.php
+++ b/app/code/Magento/Backend/Model/Menu/Config.php
@@ -101,10 +101,6 @@ class Config
      */
     public function getMenu()
     {
-        if ($this->_scopeConfig->getValue('dev/log/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)) {
-            $this->_logger->addStreamLog(\Magento\Backend\Model\Menu::LOGGER_KEY);
-        }
-
         try {
             $this->_initMenu();
             return $this->_menu;
diff --git a/app/code/Magento/Core/Model/Layout/Merge.php b/app/code/Magento/Core/Model/Layout/Merge.php
index d12c1a07b96..b703560efd4 100644
--- a/app/code/Magento/Core/Model/Layout/Merge.php
+++ b/app/code/Magento/Core/Model/Layout/Merge.php
@@ -436,7 +436,6 @@ class Merge implements \Magento\Framework\View\Layout\ProcessorInterface
                 $messages = $this->_layoutValidator->getMessages();
                 //Add first message to exception
                 $message = reset($messages);
-                $this->_logger->addStreamLog(\Magento\Framework\Logger::LOGGER_SYSTEM);
                 $this->_logger->log('Cache file with merged layout: ' . $cacheId . ': ' . $message, \Zend_Log::ERR);
             }
         }
diff --git a/app/code/Magento/Store/Model/StorageFactory.php b/app/code/Magento/Store/Model/StorageFactory.php
index 053a7180110..e7473e2ba7c 100644
--- a/app/code/Magento/Store/Model/StorageFactory.php
+++ b/app/code/Magento/Store/Model/StorageFactory.php
@@ -63,7 +63,6 @@ class StorageFactory
     /**
      * @param \Magento\Framework\ObjectManagerInterface $objectManager
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
-     * @param \Magento\Framework\Logger $logger
      * @param \Magento\Framework\Session\SidResolverInterface $sidResolver
      * @param \Magento\Framework\App\State $appState
      * @param \Magento\Framework\App\Http\Context $httpContext
@@ -75,7 +74,6 @@ class StorageFactory
     public function __construct(
         \Magento\Framework\ObjectManagerInterface $objectManager,
         \Magento\Framework\Event\ManagerInterface $eventManager,
-        \Magento\Framework\Logger $logger,
         \Magento\Framework\Session\SidResolverInterface $sidResolver,
         \Magento\Framework\App\State $appState,
         \Magento\Framework\App\Http\Context $httpContext,
@@ -87,7 +85,6 @@ class StorageFactory
         $this->_objectManager = $objectManager;
         $this->_storageClassName = $storageClassName;
         $this->_eventManager = $eventManager;
-        $this->_log = $logger;
         $this->_appState = $appState;
         $this->_sidResolver = $sidResolver;
         $this->_writerModel = $writerModel;
@@ -127,36 +124,6 @@ class StorageFactory
                 $this->_sidResolver->setUseSessionInUrl($useSid);
 
                 $this->_eventManager->dispatch('core_app_init_current_store_after');
-
-                $store = $storage->getStore(true);
-                $logActive = $this->_scopeConfig->isSetFlag(
-                    'dev/log/active',
-                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
-                    $store
-                );
-                if ($logActive || $this->_appState->getMode() === \Magento\Framework\App\State::MODE_DEVELOPER) {
-                    $logFile = $this->_scopeConfig->getValue(
-                        'dev/log/file',
-                        \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
-                        $store
-                    );
-                    $logExceptionFile = $this->_scopeConfig->getValue(
-                        'dev/log/exception_file',
-                        \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
-                        $store
-                    );
-                    $this->_log->unsetLoggers();
-                    $this->_log->addStreamLog(
-                        \Magento\Framework\Logger::LOGGER_SYSTEM,
-                        $logFile,
-                        $this->_writerModel
-                    );
-                    $this->_log->addStreamLog(
-                        \Magento\Framework\Logger::LOGGER_EXCEPTION,
-                        $logExceptionFile,
-                        $this->_writerModel
-                    );
-                }
             }
         }
         return $this->_cache[$className];
diff --git a/composer.json b/composer.json
index 7d2f6520184..27195619178 100644
--- a/composer.json
+++ b/composer.json
@@ -30,7 +30,8 @@
         "zendframework/zend-log": "2.3.1",
         "zendframework/zend-http": "2.3.1",
         "magento/zendframework1": "1.12.9",
-        "composer/composer": "1.0.0-alpha8"
+        "composer/composer": "1.0.0-alpha8",
+        "monolog/monolog": "1.11.0"
     },
     "require-dev": {
         "phpunit/phpunit": "4.1.0",
diff --git a/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Logger.php b/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Logger.php
index c97c2565cba..31f4202d628 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Logger.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Logger.php
@@ -47,17 +47,15 @@ class Logger extends \Magento\Framework\Logger
     /**
      * @param string $message
      * @param int $level
-     * @param string $loggerKey
      */
-    public function log($message, $level = \Zend_Log::DEBUG, $loggerKey = \Magento\Framework\Logger::LOGGER_SYSTEM)
+    public function log($message, $level = \Zend_Log::DEBUG)
     {
         if ($level <= $this->minimumErrorLevel) {
             $this->messages[] = [
-                'logger' => $loggerKey,
                 'level' => $level,
                 'message' => $message,
             ];
         }
-        parent::log($message, $level, $loggerKey);
+        parent::log($message, $level);
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Core/Model/Layout/MergeTest.php b/dev/tests/unit/testsuite/Magento/Core/Model/Layout/MergeTest.php
index 1b0e8eaa4de..df6071a6b64 100644
--- a/dev/tests/unit/testsuite/Magento/Core/Model/Layout/MergeTest.php
+++ b/dev/tests/unit/testsuite/Magento/Core/Model/Layout/MergeTest.php
@@ -297,8 +297,7 @@ class MergeTest extends \PHPUnit_Framework_TestCase
         $this->_logger->expects($this->atLeastOnce())->method('log')
             ->with(
                 $this->stringStartsWith($errorString),
-                \Zend_Log::ERR,
-                \Magento\Framework\Logger::LOGGER_SYSTEM
+                \Zend_Log::ERR
             );
 
         $actualXml = $this->_model->getFileLayoutUpdatesXml();
diff --git a/dev/tests/unit/testsuite/Magento/Framework/LoggerTest.php b/dev/tests/unit/testsuite/Magento/Framework/LoggerTest.php
deleted file mode 100644
index a1b3f8cdce7..00000000000
--- a/dev/tests/unit/testsuite/Magento/Framework/LoggerTest.php
+++ /dev/null
@@ -1,211 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- */
-namespace Magento\Framework;
-
-use Magento\Framework\App\Filesystem\DirectoryList;
-use Magento\Framework\Filesystem\Directory\Write;
-
-class LoggerTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $model = null;
-
-    /**
-     * @var \ReflectionProperty
-     */
-    protected $loggersProperty = null;
-
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $filesystemMock;
-
-    /**
-     * @var Write | \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $directory;
-
-    /**
-     * @var string
-     */
-    private static $logDir;
-
-    public static function setUpBeforeClass()
-    {
-        self::$logDir = TESTS_TEMP_DIR . '/var/log';
-        if (!is_dir(self::$logDir)) {
-            mkdir(self::$logDir, 0777, true);
-        }
-    }
-
-    public static function tearDownAfterClass()
-    {
-        $filesystemAdapter = new \Magento\Framework\Filesystem\Driver\File();
-        $filesystemAdapter->deleteDirectory(self::$logDir);
-    }
-
-    protected function setUp()
-    {
-        $logDir = self::$logDir;
-        $this->filesystemMock = $this->getMock('Magento\Framework\Filesystem', [], [], '', false);
-        $this->directory = $this->getMock('Magento\Framework\Filesystem\Directory\Write', [], [], '', false);
-        $this->filesystemMock->expects($this->any())
-            ->method('getDirectoryWrite')
-            ->with(DirectoryList::LOG)
-            ->will($this->returnValue($this->directory));
-        $this->directory->expects($this->any())->method('create')->will($this->returnValue(true));
-        $this->directory->expects($this->any())->method('getAbsolutePath')->will(
-            $this->returnCallback(
-                function ($path) use ($logDir) {
-                    $path = ltrim($path, '\/');
-                    return $logDir . '/' . $path;
-                }
-            )
-        );
-
-        $this->model = new \Magento\Framework\Logger($this->filesystemMock);
-        $this->loggersProperty = new \ReflectionProperty($this->model, '_loggers');
-        $this->loggersProperty->setAccessible(true);
-    }
-
-    protected function tearDown()
-    {
-        $this->model = null; // will cause __descruct() in the underlying log class, which will close the open log files
-    }
-
-    /**
-     * @param string $key
-     * @param string $fileOrWrapper
-     * @dataProvider addStreamLogDataProvider
-     */
-    public function testAddStreamLog($key, $fileOrWrapper)
-    {
-        $this->assertFalse($this->model->hasLog($key));
-        $this->model->addStreamLog($key, $fileOrWrapper);
-        $this->assertTrue($this->model->hasLog($key));
-
-        $loggers = $this->loggersProperty->getValue($this->model);
-        $this->assertArrayHasKey($key, $loggers);
-        $zendLog = $loggers[$key];
-        $this->assertInstanceOf('Zend_Log', $zendLog);
-
-        $writersProperty = new \ReflectionProperty($zendLog, '_writers');
-        $writersProperty->setAccessible(true);
-        $writers = $writersProperty->getValue($zendLog);
-        $this->assertArrayHasKey(0, $writers);
-        $stream = $writers[0];
-        $this->assertInstanceOf('Zend_Log_Writer_Stream', $writers[0]);
-
-        $streamProperty = new \ReflectionProperty($stream, '_stream');
-        $streamProperty->setAccessible(true);
-        $fileOrWrapper = $streamProperty->getValue($stream);
-        $this->assertInternalType('resource', $fileOrWrapper);
-        $this->assertEquals('stream', get_resource_type($fileOrWrapper));
-    }
-
-    /**
-     * @return array
-     */
-    public function addStreamLogDataProvider()
-    {
-        return [['test', 'php://output'], ['test', 'custom_file.log'], ['test', '']];
-    }
-
-    /**
-     * @covers \Magento\Framework\Logger::hasLog
-     */
-    public function testAddLogWithSpecificKey()
-    {
-        $key = uniqid();
-        $this->model->addStreamLog($key);
-        $this->assertTrue($this->model->hasLog($key));
-    }
-
-    public function testLog()
-    {
-        $messageOne = uniqid();
-        $messageTwo = uniqid();
-        $messageThree = uniqid();
-        $this->expectOutputRegex(
-            '/' . 'DEBUG \(7\).+?' . $messageTwo . '.+?' . 'CRIT \(2\).+?' . $messageThree . '/s'
-        );
-        $this->model->addStreamLog('test', 'php://output');
-        $this->model->log($messageOne);
-        $this->model->log($messageTwo, \Zend_Log::DEBUG, 'test');
-        $this->model->log($messageThree, \Zend_Log::CRIT, 'test');
-    }
-
-    public function testLogComplex()
-    {
-        $this->expectOutputRegex('/Array\s\(\s+\[0\] => 1\s\).+stdClass Object/s');
-        $this->model->addStreamLog(\Magento\Framework\Logger::LOGGER_SYSTEM, 'php://output');
-        $this->model->log([1]);
-        $this->model->log(new \StdClass());
-        $this->model->log('key');
-    }
-
-    public function testLogNoKey()
-    {
-        $key = 'key';
-        $this->model->log($key);
-        $this->assertFalse($this->model->hasLog($key));
-    }
-
-    public function testLogDebug()
-    {
-        $message = uniqid();
-        /** @var $model \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject */
-        $model = $this->getMock('Magento\Framework\Logger', ['log'], [], '', false);
-        $model->expects($this->at(0))
-            ->method('log')
-            ->with($message, \Zend_Log::DEBUG, \Magento\Framework\Logger::LOGGER_SYSTEM);
-        $model->expects($this->at(1))
-            ->method('log')
-            ->with(
-                $message,
-                \Zend_Log::DEBUG,
-                \Magento\Framework\Logger::LOGGER_EXCEPTION
-            );
-        $model->logDebug($message);
-        $model->logDebug($message, \Magento\Framework\Logger::LOGGER_EXCEPTION);
-    }
-
-    public function testLogException()
-    {
-        $exception = new \Exception();
-        $expected = "\n{$exception}";
-        /** @var $model \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject */
-        $model = $this->getMock('Magento\Framework\Logger', ['log'], [], '', false);
-        $model->expects($this->at(0))
-            ->method('log')
-            ->with(
-                $expected,
-                \Zend_Log::ERR,
-                \Magento\Framework\Logger::LOGGER_EXCEPTION
-            );
-        $model->logException($exception);
-    }
-
-    public function testUnsetLoggers()
-    {
-        $key = 'test';
-        $fileOrWrapper = 'custom_file.log';
-        $this->model->addStreamLog($key, $fileOrWrapper);
-        $this->assertTrue($this->model->hasLog($key));
-        $this->model->unsetLoggers();
-        $this->assertFalse($this->model->hasLog($key));
-    }
-
-    public function testLogFile()
-    {
-        $message = ['Wrong file name', 'Avoid using special chars'];
-        $filename = 'custom_file.log';
-        $this->model->logFile($message, \Zend_Log::DEBUG);
-        $this->model->logFile($message, \Zend_Log::DEBUG, $filename);
-        $this->assertTrue($this->model->hasLog($filename));
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Message/ManagerTest.php b/dev/tests/unit/testsuite/Magento/Framework/Message/ManagerTest.php
index 96db910fd4e..265e3a3197a 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Message/ManagerTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Message/ManagerTest.php
@@ -207,8 +207,7 @@ class ManagerTest extends \PHPUnit_Framework_TestCase
             'logFile'
         )->with(
             $this->stringStartsWith($logText),
-            \Zend_Log::DEBUG,
-            \Magento\Framework\Logger::LOGGER_EXCEPTION
+            \Zend_Log::DEBUG
         );
 
         $messageCollection = $this->getMockBuilder(
diff --git a/dev/tests/unit/testsuite/Magento/Store/Model/StorageFactoryTest.php b/dev/tests/unit/testsuite/Magento/Store/Model/StorageFactoryTest.php
index 40baf58ed1c..ea82acf99e2 100644
--- a/dev/tests/unit/testsuite/Magento/Store/Model/StorageFactoryTest.php
+++ b/dev/tests/unit/testsuite/Magento/Store/Model/StorageFactoryTest.php
@@ -119,7 +119,6 @@ class StorageFactoryTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $this->_logMock = $this->getMock('Magento\Framework\Logger', [], [], '', false);
         $this->_sidResolverMock = $this->getMock(
             '\Magento\Framework\Session\SidResolverInterface',
             [],
@@ -138,7 +137,6 @@ class StorageFactoryTest extends \PHPUnit_Framework_TestCase
         $this->_model = $this->helper->getObject('\Magento\Store\Model\StorageFactory', [
             'objectManager' => $this->_objectManagerMock,
             'eventManager' => $this->_eventManagerMock,
-            'logger' => $this->_logMock,
             'sidResolver' => $this->_sidResolverMock,
             'appState' => $this->_appStateMock,
             'httpContext' => $this->_httpContext,
@@ -183,7 +181,7 @@ class StorageFactoryTest extends \PHPUnit_Framework_TestCase
     {
         $store = $this->getMock('Magento\Store\Model\Store', [], [], '', false);
 
-        $this->_storeManager->expects($this->exactly(3))->method('getStore')->will($this->returnValue($store));
+        $this->_storeManager->expects($this->exactly(2))->method('getStore')->will($this->returnValue($store));
 
         $this->_scopeConfig->expects(
             $this->at(0)
@@ -196,17 +194,6 @@ class StorageFactoryTest extends \PHPUnit_Framework_TestCase
             $this->returnValue(true)
         );
 
-        $this->_scopeConfig->expects(
-            $this->at(1)
-        )->method(
-            'isSetFlag'
-        )->with(
-            'dev/log/active',
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-        )->will(
-            $this->returnValue(true)
-        );
-
         $this->_objectManagerMock->expects(
             $this->once()
         )->method(
@@ -225,8 +212,6 @@ class StorageFactoryTest extends \PHPUnit_Framework_TestCase
             'core_app_init_current_store_after'
         );
 
-        $this->_logMock->expects($this->once())->method('unsetLoggers');
-        $this->_logMock->expects($this->exactly(2))->method('addStreamLog');
 
         $this->_sidResolverMock->expects($this->once())->method('setUseSessionInUrl')->with(true);
 
@@ -255,7 +240,6 @@ class StorageFactoryTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->_eventManagerMock->expects($this->never())->method('dispatch');
-        $this->_logMock->expects($this->never())->method('initForStore');
         $this->_sidResolverMock->expects($this->never())->method('setUseSessionInUrl');
 
         /** test create instance */
diff --git a/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php b/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php
index 8a2222a2695..e79cdf57d8a 100644
--- a/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php
+++ b/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php
@@ -675,7 +675,6 @@ abstract class AbstractAdapter implements AdapterInterface
             try {
                 $this->directoryWrite->create($this->directoryWrite->getRelativePath($destination));
             } catch (\Magento\Framework\Filesystem\FilesystemException $e) {
-                $this->logger->addStreamLog(\Magento\Framework\Logger::LOGGER_SYSTEM);
                 $this->logger->log($e->getMessage());
                 throw new \Exception('Unable to write file into directory ' . $destination . '. Access forbidden.');
             }
diff --git a/lib/internal/Magento/Framework/Logger.php b/lib/internal/Magento/Framework/Logger.php
index 378f2099dc4..b2e848502ea 100644
--- a/lib/internal/Magento/Framework/Logger.php
+++ b/lib/internal/Magento/Framework/Logger.php
@@ -4,20 +4,11 @@
  */
 namespace Magento\Framework;
 
-use Magento\Framework\App\Filesystem\DirectoryList;
-
 /**
  * Logger model
  */
 class Logger
 {
-    /**#@+
-     * Keys that stand for particular log streams
-     */
-    const LOGGER_SYSTEM = 'system';
-
-    const LOGGER_EXCEPTION = 'exception';
-
     /**#@-*/
 
     /**
@@ -25,93 +16,19 @@ class Logger
      */
     protected $_loggers = [];
 
-    /**
-     * @var \Magento\Framework\Filesystem
-     */
-    protected $_filesystem;
-
-    /**
-     * @param \Magento\Framework\Filesystem $filesystem
-     * @param string $defaultFile
-     */
-    public function __construct(\Magento\Framework\Filesystem $filesystem, $defaultFile = '')
-    {
-        $this->_filesystem = $filesystem;
-        $this->addStreamLog(self::LOGGER_SYSTEM, $defaultFile)->addStreamLog(self::LOGGER_EXCEPTION, $defaultFile);
-    }
-
-    /**
-     * Add a logger by specified key
-     *
-     * Second argument is a file name (relative to log directory) or a PHP "wrapper"
-     *
-     * @param string $loggerKey
-     * @param string $fileOrWrapper
-     * @param string $writerClass
-     * @return \Magento\Framework\Logger
-     * @link http://php.net/wrappers
-     */
-    public function addStreamLog($loggerKey, $fileOrWrapper = '', $writerClass = '')
-    {
-        $file = $fileOrWrapper ?: "{$loggerKey}.log";
-        if (!preg_match('#^[a-z][a-z0-9+.-]*\://#i', $file)) {
-            $logDir = $this->_filesystem->getDirectoryWrite(DirectoryList::LOG);
-            $logDir->create();
-            $file = $logDir->getAbsolutePath($file);
-        }
-        if (!$writerClass || !is_subclass_of($writerClass, 'Zend_Log_Writer_Stream')) {
-            $writerClass = 'Zend_Log_Writer_Stream';
-        }
-        /** @var $writer \Zend_Log_Writer_Stream */
-        $writer = $writerClass::factory(['stream' => $file]);
-        $writer->setFormatter(
-            new \Zend_Log_Formatter_Simple('%timestamp% %priorityName% (%priority%): %message%' . PHP_EOL)
-        );
-        $this->_loggers[$loggerKey] = new \Zend_Log($writer);
-        return $this;
-    }
-
-    /**
-     * Unset all declared loggers
-     *
-     * @return $this
-     */
-    public function unsetLoggers()
-    {
-        $this->_loggers = [];
-        return $this;
-    }
-
-    /**
-     * Check whether a logger exists by specified key
-     *
-     * @param string $key
-     * @return bool
-     */
-    public function hasLog($key)
-    {
-        return isset($this->_loggers[$key]);
-    }
-
     /**
      * Log a message
      *
      * @param string $message
      * @param int $level
-     * @param string $loggerKey
      * @return void
      */
-    public function log($message, $level = \Zend_Log::DEBUG, $loggerKey = self::LOGGER_SYSTEM)
+    public function log($message, $level = \Zend_Log::DEBUG)
     {
-        if (!isset($this->_loggers[$loggerKey])) {
-            return;
-        }
         if (is_array($message) || is_object($message)) {
             $message = print_r($message, true);
         }
-        /** @var $logger \Zend_Log */
-        $logger = $this->_loggers[$loggerKey];
-        $logger->log($message, $level);
+        $this->log($message, $level);
     }
 
     /**
@@ -131,10 +48,6 @@ class Logger
             $message = print_r($message, true);
         }
         /** @var $logger \Zend_Log */
-        if (!$this->hasLog($file)) {
-            $this->addStreamLog($file, $file);
-        }
-        /** @var $logger \Zend_Log */
         $this->log($message, $level, $file);
     }
 
@@ -145,9 +58,9 @@ class Logger
      * @param string $loggerKey
      * @return void
      */
-    public function logDebug($message, $loggerKey = self::LOGGER_SYSTEM)
+    public function logDebug($message)
     {
-        $this->log($message, \Zend_Log::DEBUG, $loggerKey);
+        $this->log($message, \Zend_Log::DEBUG);
     }
 
     /**
@@ -158,6 +71,6 @@ class Logger
      */
     public function logException(\Exception $e)
     {
-        $this->log("\n" . $e->__toString(), \Zend_Log::ERR, self::LOGGER_EXCEPTION);
+        $this->log("\n" . $e->__toString(), \Zend_Log::ERR);
     }
 }
diff --git a/lib/internal/Magento/Framework/Message/Manager.php b/lib/internal/Magento/Framework/Message/Manager.php
index 01c7eee8f42..9b94a8ec22e 100644
--- a/lib/internal/Magento/Framework/Message/Manager.php
+++ b/lib/internal/Magento/Framework/Message/Manager.php
@@ -258,7 +258,7 @@ class Manager implements ManagerInterface
             $exception->getTraceAsString()
         );
 
-        $this->logger->logFile($message, \Zend_Log::DEBUG, Logger::LOGGER_EXCEPTION);
+        $this->logger->logFile($message, \Zend_Log::DEBUG);
         $this->addMessage($this->messageFactory->create(MessageInterface::TYPE_ERROR, $alternativeText), $group);
         return $this;
     }
-- 
GitLab


From 42236bcc7ec0ec401c1f577f0666f6608af14868 Mon Sep 17 00:00:00 2001
From: Andriy Nasinnyk <anasinnyk@ebay.com>
Date: Thu, 18 Dec 2014 15:07:51 +0200
Subject: [PATCH 04/71] MAGETWO-13915: PSR-3: common interface for logging
 libraries.

 - rename logException to critical
---
 .../Magento/Authorization/Model/Acl/AclRetriever.php   |  2 +-
 .../Magento/Authorization/Model/Resource/Rules.php     |  2 +-
 .../Adminhtml/Authorizenet/Payment/Cancel.php          |  4 ++--
 .../Controller/Authorizenet/Payment/Cancel.php         |  4 ++--
 .../Authorizenet/Controller/Directpost/Payment.php     |  4 ++--
 app/code/Magento/Authorizenet/Model/Directpost.php     |  4 ++--
 .../Backend/Block/Widget/Grid/Column/Renderer/Date.php |  2 +-
 .../Block/Widget/Grid/Column/Renderer/Datetime.php     |  2 +-
 .../Backend/Controller/Adminhtml/Dashboard/Tunnel.php  |  2 +-
 .../Adminhtml/System/Config/System/Storage/Status.php  |  2 +-
 .../System/Config/System/Storage/Synchronize.php       |  2 +-
 app/code/Magento/Backend/Model/Menu/Config.php         |  6 +++---
 app/code/Magento/Backup/Model/Observer.php             |  2 +-
 .../Catalog/Controller/Adminhtml/Category/Move.php     |  2 +-
 .../Catalog/Controller/Adminhtml/Product/Builder.php   |  2 +-
 .../Catalog/Controller/Adminhtml/Product/Duplicate.php |  2 +-
 .../Catalog/Controller/Adminhtml/Product/Save.php      |  2 +-
 app/code/Magento/Catalog/Controller/Category/View.php  |  2 +-
 app/code/Magento/Catalog/Controller/Product/View.php   |  2 +-
 app/code/Magento/Catalog/Helper/Image.php              |  2 +-
 app/code/Magento/Catalog/Helper/Product.php            |  2 +-
 .../Magento/Catalog/Helper/Product/Flat/Indexer.php    |  2 +-
 .../Catalog/Model/Category/Attribute/Backend/Image.php |  2 +-
 .../Catalog/Model/Product/Type/AbstractType.php        |  2 +-
 .../Magento/Catalog/Pricing/Render/FinalPriceBox.php   |  2 +-
 .../CatalogImportExport/Model/Export/Product.php       |  2 +-
 .../CatalogImportExport/Model/Import/Product.php       |  2 +-
 .../Controller/Adminhtml/Promo/Catalog/ApplyRules.php  |  2 +-
 .../Controller/Adminhtml/Promo/Catalog/Delete.php      |  2 +-
 .../Controller/Adminhtml/Promo/Catalog/Save.php        |  2 +-
 .../Magento/CatalogRule/Model/Indexer/IndexBuilder.php | 10 +++++-----
 .../Adminhtml/Centinel/Index/ValidatePaymentData.php   |  2 +-
 app/code/Magento/Checkout/Controller/Cart/Add.php      |  2 +-
 app/code/Magento/Checkout/Controller/Cart/Addgroup.php |  2 +-
 .../Magento/Checkout/Controller/Cart/Configure.php     |  2 +-
 .../Magento/Checkout/Controller/Cart/CouponPost.php    |  2 +-
 app/code/Magento/Checkout/Controller/Cart/Delete.php   |  2 +-
 .../Checkout/Controller/Cart/UpdateItemOptions.php     |  2 +-
 .../Magento/Checkout/Controller/Cart/UpdatePost.php    |  2 +-
 .../Magento/Checkout/Controller/Onepage/SaveOrder.php  |  4 ++--
 .../Checkout/Controller/Onepage/SavePayment.php        |  2 +-
 app/code/Magento/Checkout/Model/Type/Onepage.php       |  4 ++--
 .../Service/V1/Address/Billing/WriteService.php        |  2 +-
 .../Service/V1/Address/Shipping/WriteService.php       |  2 +-
 .../Cms/Controller/Adminhtml/Wysiwyg/Directive.php     |  2 +-
 app/code/Magento/Core/Model/File/Storage/Database.php  |  2 +-
 .../Core/Model/File/Storage/Directory/Database.php     |  2 +-
 app/code/Magento/Core/Model/File/Storage/File.php      |  6 +++---
 app/code/Magento/Core/Model/Observer.php               |  4 ++--
 .../Block/Adminhtml/Edit/Tab/View/PersonalInfo.php     |  2 +-
 .../Magento/Customer/Controller/Account/LoginPost.php  |  2 +-
 .../Customer/Controller/Adminhtml/Index/Wishlist.php   |  2 +-
 app/code/Magento/Customer/Model/AccountManagement.php  |  8 ++++----
 app/code/Magento/Customer/Model/Metadata/Form/File.php |  2 +-
 app/code/Magento/Customer/Model/Vat.php                |  2 +-
 app/code/Magento/Customer/Model/Visitor.php            |  2 +-
 .../Controller/Adminhtml/System/Design/Editor.php      |  2 +-
 .../System/Design/Editor/AssignThemeToStore.php        |  2 +-
 .../Adminhtml/System/Design/Editor/Duplicate.php       |  4 ++--
 .../Adminhtml/System/Design/Editor/Files/TreeJson.php  |  2 +-
 .../Adminhtml/System/Design/Editor/Launch.php          |  4 ++--
 .../Adminhtml/System/Design/Editor/LoadThemeList.php   |  2 +-
 .../Adminhtml/System/Design/Editor/QuickEdit.php       |  4 ++--
 .../Adminhtml/System/Design/Editor/Revert.php          |  2 +-
 .../Controller/Adminhtml/System/Design/Editor/Save.php |  2 +-
 .../System/Design/Editor/Tools/DeleteCustomFiles.php   |  2 +-
 .../Adminhtml/System/Design/Editor/Tools/JsList.php    |  2 +-
 .../Design/Editor/Tools/RemoveQuickStyleImage.php      |  4 ++--
 .../System/Design/Editor/Tools/RemoveStoreLogo.php     |  4 ++--
 .../Adminhtml/System/Design/Editor/Tools/ReorderJs.php |  4 ++--
 .../System/Design/Editor/Tools/SaveCssContent.php      |  4 ++--
 .../System/Design/Editor/Tools/SaveImageSizing.php     |  4 ++--
 .../System/Design/Editor/Tools/SaveQuickStyles.php     |  4 ++--
 .../Adminhtml/System/Design/Editor/Tools/Upload.php    |  4 ++--
 .../Adminhtml/System/Design/Editor/Tools/UploadJs.php  |  4 ++--
 .../Design/Editor/Tools/UploadQuickStyleImage.php      |  4 ++--
 .../System/Design/Editor/Tools/UploadStoreLogo.php     |  4 ++--
 app/code/Magento/Directory/Model/PriceCurrency.php     |  2 +-
 app/code/Magento/Eav/Model/Attribute/Data/File.php     |  2 +-
 .../Adminhtml/Email/Template/DefaultTemplate.php       |  2 +-
 .../Controller/Adminhtml/Email/Template/Delete.php     |  2 +-
 app/code/Magento/Email/Model/Template/Filter.php       |  2 +-
 app/code/Magento/Fedex/Model/Carrier.php               |  6 +++---
 .../Adminhtml/Googleshopping/Items/ConfirmCaptcha.php  |  2 +-
 .../Adminhtml/Googleshopping/Items/MassAdd.php         |  2 +-
 .../Adminhtml/Googleshopping/Items/Refresh.php         |  2 +-
 .../Adminhtml/Googleshopping/Types/Delete.php          |  2 +-
 .../Controller/Adminhtml/Googleshopping/Types/Edit.php |  2 +-
 .../Googleshopping/Types/LoadAttributeSets.php         |  2 +-
 .../Adminhtml/Googleshopping/Types/LoadAttributes.php  |  2 +-
 .../Adminhtml/Googleshopping/Types/NewAction.php       |  2 +-
 .../Controller/Adminhtml/Googleshopping/Types/Save.php |  2 +-
 .../Magento/GoogleShopping/Model/MassOperations.php    |  6 +++---
 .../GroupedProduct/Controller/Adminhtml/Edit/Popup.php |  2 +-
 .../Controller/Adminhtml/Export/Export.php             |  2 +-
 app/code/Magento/ImportExport/Model/Export.php         |  4 ++--
 app/code/Magento/ImportExport/Model/Import.php         |  2 +-
 .../Controller/Adminhtml/Integration/Delete.php        |  2 +-
 .../Controller/Adminhtml/Integration/Edit.php          |  2 +-
 .../Adminhtml/Integration/PermissionsDialog.php        |  2 +-
 .../Controller/Adminhtml/Integration/Save.php          |  4 ++--
 .../Controller/Adminhtml/Integration/TokensDialog.php  |  2 +-
 .../Adminhtml/Integration/TokensExchange.php           |  2 +-
 .../Integration/Service/V1/AuthorizationService.php    |  4 ++--
 app/code/Magento/Integration/Service/V1/Oauth.php      |  2 +-
 app/code/Magento/Log/Model/Visitor.php                 |  2 +-
 .../Multishipping/Controller/Checkout/Overview.php     |  2 +-
 .../Multishipping/Controller/Checkout/OverviewPost.php |  2 +-
 app/code/Magento/Newsletter/Model/Subscriber.php       |  2 +-
 .../Model/Resource/Carrier/Tablerate.php               |  2 +-
 .../Controller/Adminhtml/Billing/Agreement/Cancel.php  |  2 +-
 .../Controller/Adminhtml/Billing/Agreement/Delete.php  |  2 +-
 .../Controller/Adminhtml/Paypal/Reports/Fetch.php      |  4 ++--
 .../Paypal/Controller/Billing/Agreement/Cancel.php     |  2 +-
 .../Controller/Billing/Agreement/ReturnWizard.php      |  2 +-
 .../Controller/Billing/Agreement/StartWizard.php       |  2 +-
 .../Controller/Express/AbstractExpress/Cancel.php      |  2 +-
 .../Controller/Express/AbstractExpress/PlaceOrder.php  |  2 +-
 .../Express/AbstractExpress/ReturnAction.php           |  2 +-
 .../Controller/Express/AbstractExpress/Review.php      |  2 +-
 .../Express/AbstractExpress/SaveShippingMethod.php     |  2 +-
 .../AbstractExpress/ShippingOptionsCallback.php        |  2 +-
 .../Controller/Express/AbstractExpress/Start.php       |  2 +-
 .../Express/AbstractExpress/UpdateShippingMethods.php  |  2 +-
 app/code/Magento/Paypal/Controller/Ipn/Index.php       |  4 ++--
 .../Magento/Paypal/Controller/Payflow/SilentPost.php   |  2 +-
 app/code/Magento/Paypal/Model/Api/Nvp.php              |  6 +++---
 app/code/Magento/Paypal/Model/Api/PayflowNvp.php       |  2 +-
 app/code/Magento/Paypal/Model/Express/Checkout.php     |  4 ++--
 app/code/Magento/Paypal/Model/Observer.php             |  4 ++--
 .../Controller/Adminhtml/Report/Product/Viewed.php     |  2 +-
 .../Adminhtml/Report/Statistics/RefreshLifetime.php    |  2 +-
 .../Adminhtml/Report/Statistics/RefreshRecent.php      |  2 +-
 .../Reports/Model/Resource/Report/AbstractReport.php   |  2 +-
 app/code/Magento/Review/Controller/Product.php         |  2 +-
 app/code/Magento/Review/Model/Resource/Rating.php      |  4 ++--
 .../Rss/App/Action/Plugin/BackendAuthentication.php    |  2 +-
 app/code/Magento/Rss/Controller/Feed.php               |  2 +-
 app/code/Magento/Rule/Model/Condition/Combine.php      |  2 +-
 .../Sales/Controller/Adminhtml/Order/Cancel.php        |  2 +-
 .../Controller/Adminhtml/Order/Creditmemo/Save.php     |  2 +-
 .../Magento/Sales/Controller/Adminhtml/Order/Email.php |  2 +-
 .../Sales/Controller/Adminhtml/Order/Invoice/Save.php  |  6 +++---
 .../Sales/Controller/Adminhtml/Order/ReviewPayment.php |  2 +-
 .../Magento/Sales/Controller/Adminhtml/Order/View.php  |  2 +-
 .../Sales/Controller/Adminhtml/Order/VoidPayment.php   |  2 +-
 .../Sales/Controller/Adminhtml/Transactions/Fetch.php  |  2 +-
 app/code/Magento/Sales/Model/AbstractNotifier.php      |  2 +-
 app/code/Magento/Sales/Model/AdminOrder/Create.php     |  2 +-
 .../Magento/Sales/Model/AdminOrder/EmailSender.php     |  2 +-
 .../Controller/Adminhtml/Promo/Quote/Delete.php        |  2 +-
 .../Controller/Adminhtml/Promo/Quote/Generate.php      |  2 +-
 .../Controller/Adminhtml/Promo/Quote/Save.php          |  2 +-
 .../Adminhtml/Order/Shipment/CreateLabel.php           |  2 +-
 .../Controller/Adminhtml/Order/Shipment/PrintLabel.php |  2 +-
 .../Controller/Adminhtml/Order/Shipment/Save.php       |  2 +-
 .../Adminhtml/System/Design/Theme/Delete.php           |  2 +-
 .../Adminhtml/System/Design/Theme/DownloadCss.php      |  2 +-
 .../System/Design/Theme/DownloadCustomCss.php          |  2 +-
 .../Controller/Adminhtml/System/Design/Theme/Edit.php  |  2 +-
 .../Controller/Adminhtml/System/Design/Theme/Save.php  |  2 +-
 .../Adminhtml/System/Design/Theme/UploadCss.php        |  2 +-
 .../Adminhtml/System/Design/Theme/UploadJs.php         |  2 +-
 .../System/Design/Wysiwyg/Files/NewFolder.php          |  2 +-
 .../System/Design/Wysiwyg/Files/PreviewImage.php       |  2 +-
 .../Adminhtml/System/Design/Wysiwyg/Files/TreeJson.php |  2 +-
 app/code/Magento/Theme/Model/Wysiwyg/Storage.php       |  2 +-
 app/code/Magento/Webapi/Controller/ErrorProcessor.php  | 10 +++++-----
 .../Controller/Adminhtml/Widget/Instance/Save.php      |  2 +-
 app/code/Magento/Wishlist/Controller/Index/Add.php     |  2 +-
 .../Magento/Wishlist/Controller/Index/Configure.php    |  2 +-
 app/code/Magento/Wishlist/Controller/Index/Update.php  |  2 +-
 .../Wishlist/Controller/Index/UpdateItemOptions.php    |  2 +-
 app/code/Magento/Wishlist/Model/ItemCarrier.php        |  2 +-
 .../Service/V1/AuthorizationServiceTest.php            |  2 +-
 .../Magento/Translation/Model/InlineParserTest.php     |  2 +-
 .../Magento/Test/Legacy/_files/obsolete_methods.php    |  2 +-
 .../Controller/Adminhtml/Dashboard/TunnelTest.php      |  4 ++--
 .../Magento/Backend/Model/Menu/ConfigTest.php          |  4 ++--
 .../Backend/Model/Menu/Director/DirectorTest.php       |  2 +-
 .../Controller/Adminhtml/Product/BuilderTest.php       |  2 +-
 .../Catalog/Pricing/Render/FinalPriceBoxTest.php       |  2 +-
 .../Core/Model/File/Storage/Directory/DatabaseTest.php |  2 +-
 .../testsuite/Magento/Framework/DB/Logger/FileTest.php |  4 ++--
 .../Magento/Framework/View/Asset/MergedTest.php        |  6 +++---
 .../Magento/Framework/View/Asset/MinifiedTest.php      |  2 +-
 .../Framework/View/Page/Config/RendererTest.php        |  2 +-
 .../Adminhtml/Googleshopping/Items/MassAddTest.php     |  2 +-
 .../Adminhtml/Googleshopping/Items/RefreshTest.php     |  2 +-
 .../Controller/Adminhtml/IntegrationTest.php           |  4 ++--
 .../Magento/Integration/Helper/Oauth/ConsumerTest.php  |  2 +-
 .../Magento/Paypal/Controller/Ipn/IndexTest.php        |  2 +-
 .../Magento/Rule/Model/Condition/CombineTest.php       |  4 ++--
 .../Magento/Sales/Model/AdminOrder/EmailSenderTest.php |  2 +-
 .../Sales/Model/Order/CreditmemoNotifierTest.php       |  4 ++--
 .../Magento/Sales/Model/Order/InvoiceNotifierTest.php  |  4 ++--
 .../Magento/Sales/Model/OrderNotifierTest.php          |  4 ++--
 .../Adminhtml/Order/Shipment/CreateLabelTest.php       |  4 ++--
 .../Adminhtml/Order/Shipment/PrintLabelTest.php        |  4 ++--
 .../Magento/Shipping/Model/ShipmentNotifierTest.php    |  4 ++--
 .../Magento/Webapi/Controller/ErrorProcessorTest.php   |  2 +-
 lib/internal/Magento/Framework/App/Area.php            |  2 +-
 lib/internal/Magento/Framework/App/Bootstrap.php       |  2 +-
 .../Magento/Framework/DB/Adapter/Pdo/Mysql.php         |  2 +-
 lib/internal/Magento/Framework/DB/Logger/File.php      |  2 +-
 lib/internal/Magento/Framework/DB/Logger/Null.php      |  2 +-
 lib/internal/Magento/Framework/DB/LoggerInterface.php  |  2 +-
 .../Framework/Less/PreProcessor/ErrorHandler.php       |  2 +-
 lib/internal/Magento/Framework/Logger.php              |  2 +-
 lib/internal/Magento/Framework/View/Asset/Merged.php   |  2 +-
 lib/internal/Magento/Framework/View/Asset/Minified.php |  2 +-
 .../Magento/Framework/View/Design/Theme/Image.php      |  2 +-
 .../Magento/Framework/View/Element/AbstractBlock.php   |  2 +-
 .../Magento/Framework/View/Page/Config/Renderer.php    |  2 +-
 lib/internal/Magento/Framework/View/Result/Page.php    |  2 +-
 215 files changed, 279 insertions(+), 279 deletions(-)

diff --git a/app/code/Magento/Authorization/Model/Acl/AclRetriever.php b/app/code/Magento/Authorization/Model/Acl/AclRetriever.php
index 3837a7babb2..51bd53b2d3f 100644
--- a/app/code/Magento/Authorization/Model/Acl/AclRetriever.php
+++ b/app/code/Magento/Authorization/Model/Acl/AclRetriever.php
@@ -79,7 +79,7 @@ class AclRetriever
         } catch (AuthorizationException $e) {
             throw $e;
         } catch (\Exception $e) {
-            $this->logger->logException($e);
+            $this->logger->critical($e);
             throw new LocalizedException(
                 'Error happened while getting a list of allowed resources. Check exception log for details.'
             );
diff --git a/app/code/Magento/Authorization/Model/Resource/Rules.php b/app/code/Magento/Authorization/Model/Resource/Rules.php
index e367b05e2cf..a89e3e33d1a 100644
--- a/app/code/Magento/Authorization/Model/Resource/Rules.php
+++ b/app/code/Magento/Authorization/Model/Resource/Rules.php
@@ -116,7 +116,7 @@ class Rules extends \Magento\Framework\Model\Resource\Db\AbstractDb
             throw $e;
         } catch (\Exception $e) {
             $adapter->rollBack();
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
         }
     }
 }
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Payment/Cancel.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Payment/Cancel.php
index b9eb0414ef7..b0c979f96ef 100644
--- a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Payment/Cancel.php
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Payment/Cancel.php
@@ -51,10 +51,10 @@ class Cancel extends \Magento\Backend\App\Action
                 $this->_view
             );
         } catch (\Magento\Framework\Model\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $result['error_message'] = $e->getMessage();
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $result['error_message'] = __('Something went wrong canceling the transactions.');
         }
 
diff --git a/app/code/Magento/Authorizenet/Controller/Authorizenet/Payment/Cancel.php b/app/code/Magento/Authorizenet/Controller/Authorizenet/Payment/Cancel.php
index 6963049e7fd..72e366c7eb9 100644
--- a/app/code/Magento/Authorizenet/Controller/Authorizenet/Payment/Cancel.php
+++ b/app/code/Magento/Authorizenet/Controller/Authorizenet/Payment/Cancel.php
@@ -50,10 +50,10 @@ class Cancel extends \Magento\Framework\App\Action\Action
                 $this->_view
             );
         } catch (\Magento\Framework\Model\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $result['error_message'] = $e->getMessage();
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $result['error_message'] = __(
                 'There was an error canceling transactions. Please contact us or try again later.'
             );
diff --git a/app/code/Magento/Authorizenet/Controller/Directpost/Payment.php b/app/code/Magento/Authorizenet/Controller/Directpost/Payment.php
index b1230ac217c..2e34c219ef3 100644
--- a/app/code/Magento/Authorizenet/Controller/Directpost/Payment.php
+++ b/app/code/Magento/Authorizenet/Controller/Directpost/Payment.php
@@ -74,11 +74,11 @@ class Payment extends \Magento\Framework\App\Action\Action
             $paymentMethod->process($data);
             $result['success'] = 1;
         } catch (\Magento\Framework\Model\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $result['success'] = 0;
             $result['error_msg'] = $e->getMessage();
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $result['success'] = 0;
             $result['error_msg'] = __('We couldn\'t process your order right now. Please try again later.');
         }
diff --git a/app/code/Magento/Authorizenet/Model/Directpost.php b/app/code/Magento/Authorizenet/Model/Directpost.php
index 7013687d3e1..cfc9eed4710 100644
--- a/app/code/Magento/Authorizenet/Model/Directpost.php
+++ b/app/code/Magento/Authorizenet/Model/Directpost.php
@@ -727,7 +727,7 @@ class Directpost extends \Magento\Authorizenet\Model\Authorizenet
             $order->registerCancellation($message)->save();
         } catch (\Exception $e) {
             //quiet decline
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
         }
     }
 
@@ -766,7 +766,7 @@ class Directpost extends \Magento\Authorizenet\Model\Authorizenet
                 $order->save();
             } catch (\Exception $e) {
                 //if we couldn't capture order, just leave it as NEW order.
-                $this->_logger->logException($e);
+                $this->_logger->critical($e);
             }
         }
     }
diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Date.php b/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Date.php
index f2b3b0381aa..f9524ada793 100644
--- a/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Date.php
+++ b/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Date.php
@@ -45,7 +45,7 @@ class Date extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRe
                         \Magento\Framework\Stdlib\DateTime\TimezoneInterface::FORMAT_TYPE_MEDIUM
                     );
                 } catch (\Exception $e) {
-                    $this->_logger->logException($e);
+                    $this->_logger->critical($e);
                 }
             }
             $format = self::$_format;
diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Datetime.php b/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Datetime.php
index 3ac62cee213..8b6e3f12425 100644
--- a/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Datetime.php
+++ b/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Datetime.php
@@ -32,7 +32,7 @@ class Datetime extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\Abstra
                         \Magento\Framework\Stdlib\DateTime\TimezoneInterface::FORMAT_TYPE_MEDIUM
                     );
                 } catch (\Exception $e) {
-                    $this->_logger->logException($e);
+                    $this->_logger->critical($e);
                 }
             }
             $format = self::$_format;
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/Tunnel.php b/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/Tunnel.php
index 5a2785e0e74..f1bd26eedac 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/Tunnel.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/Tunnel.php
@@ -68,7 +68,7 @@ class Tunnel extends \Magento\Backend\Controller\Adminhtml\Dashboard
                             ->setContents($response->getBody());
                         return $resultRaw;
                     } catch (\Exception $e) {
-                        $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                        $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
                         $error = __('see error log for details');
                         $httpCode = 503;
                     }
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Status.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Status.php
index f3133d990c9..85a3aa075bf 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Status.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Status.php
@@ -80,7 +80,7 @@ class Status extends \Magento\Backend\Controller\Adminhtml\System\Config\System\
                         ) {
                             $this->_objectManager->get(
                                 'Magento\Framework\Logger'
-                            )->logException(
+                            )->critical(
                                 new \Magento\Framework\Exception(
                                     __('The timeout limit for response from synchronize process was reached.')
                                 )
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Synchronize.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Synchronize.php
index b2b6c0fff5e..f2b70585d7a 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Synchronize.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Synchronize.php
@@ -43,7 +43,7 @@ class Synchronize extends \Magento\Backend\Controller\Adminhtml\System\Config\Sy
         try {
             $this->_getSyncSingleton()->synchronize($storage);
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $flag->passError($e);
         }
 
diff --git a/app/code/Magento/Backend/Model/Menu/Config.php b/app/code/Magento/Backend/Model/Menu/Config.php
index 089f0e1315e..52b3e0f2ac8 100644
--- a/app/code/Magento/Backend/Model/Menu/Config.php
+++ b/app/code/Magento/Backend/Model/Menu/Config.php
@@ -105,13 +105,13 @@ class Config
             $this->_initMenu();
             return $this->_menu;
         } catch (\InvalidArgumentException $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
             throw $e;
         } catch (\BadMethodCallException $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
             throw $e;
         } catch (\OutOfRangeException $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
             throw $e;
         } catch (\Exception $e) {
             throw $e;
diff --git a/app/code/Magento/Backup/Model/Observer.php b/app/code/Magento/Backup/Model/Observer.php
index 0e2d75bc06e..77d66b929e1 100644
--- a/app/code/Magento/Backup/Model/Observer.php
+++ b/app/code/Magento/Backup/Model/Observer.php
@@ -144,7 +144,7 @@ class Observer
             $this->_errors[] = $e->getMessage();
             $this->_errors[] = $e->getTrace();
             $this->_logger->log($e->getMessage(), \Zend_Log::ERR);
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
         }
 
         if ($this->_scopeConfig->isSetFlag(self::XML_PATH_BACKUP_MAINTENANCE_MODE, ScopeInterface::SCOPE_STORE)) {
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Move.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Move.php
index f335af5a99d..18eda1abf61 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Move.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Move.php
@@ -77,7 +77,7 @@ class Move extends \Magento\Catalog\Controller\Adminhtml\Category
         } catch (\Exception $e) {
             $error = true;
             $this->messageManager->addError(__('There was a category move error.'));
-            $this->logger->logException($e);
+            $this->logger->critical($e);
         }
 
         if (!$error) {
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Builder.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Builder.php
index 511f9a701d5..758084c10e9 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Builder.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Builder.php
@@ -75,7 +75,7 @@ class Builder
                 $product->load($productId);
             } catch (\Exception $e) {
                 $product->setTypeId(\Magento\Catalog\Model\Product\Type::DEFAULT_TYPE);
-                $this->logger->logException($e);
+                $this->logger->critical($e);
             }
         }
 
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Duplicate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Duplicate.php
index 827d1bdce79..8c9e23a1745 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Duplicate.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Duplicate.php
@@ -53,7 +53,7 @@ class Duplicate extends \Magento\Catalog\Controller\Adminhtml\Product
             $this->messageManager->addSuccess(__('You duplicated the product.'));
             $resultRedirect->setPath('catalog/*/edit', ['_current' => true, 'id' => $newProduct->getId()]);
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->messageManager->addError($e->getMessage());
             $resultRedirect->setPath('catalog/*/edit', ['_current' => true]);
         }
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php
index 38d4776a6f6..fe6b003cb26 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php
@@ -116,7 +116,7 @@ class Save extends \Magento\Catalog\Controller\Adminhtml\Product
                 $this->_session->setProductData($data);
                 $redirectBack = true;
             } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
                 $this->messageManager->addError($e->getMessage());
                 $redirectBack = true;
             }
diff --git a/app/code/Magento/Catalog/Controller/Category/View.php b/app/code/Magento/Catalog/Controller/Category/View.php
index 4e9df866610..f256d9ae84f 100644
--- a/app/code/Magento/Catalog/Controller/Category/View.php
+++ b/app/code/Magento/Catalog/Controller/Category/View.php
@@ -123,7 +123,7 @@ class View extends \Magento\Framework\App\Action\Action
                 ['category' => $category, 'controller_action' => $this]
             );
         } catch (\Magento\Framework\Model\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             return false;
         }
 
diff --git a/app/code/Magento/Catalog/Controller/Product/View.php b/app/code/Magento/Catalog/Controller/Product/View.php
index 3f36fe958a4..4f06ccc1c86 100644
--- a/app/code/Magento/Catalog/Controller/Product/View.php
+++ b/app/code/Magento/Catalog/Controller/Product/View.php
@@ -111,7 +111,7 @@ class View extends \Magento\Catalog\Controller\Product
             if ($e->getCode() == $this->viewHelper->ERR_NO_PRODUCT_LOADED) {
                 return $this->noProductRedirect();
             } else {
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
                 $resultForward = $this->resultForwardFactory->create();
                 $resultForward->forward('noroute');
                 return $resultForward;
diff --git a/app/code/Magento/Catalog/Helper/Image.php b/app/code/Magento/Catalog/Helper/Image.php
index 9388d17fda7..e232b7280a7 100644
--- a/app/code/Magento/Catalog/Helper/Image.php
+++ b/app/code/Magento/Catalog/Helper/Image.php
@@ -417,7 +417,7 @@ class Image extends AbstractHelper
         try {
             $url = $this->_assetRepo->getUrl($this->getPlaceholder());
         } catch (\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
             $url = $this->_urlBuilder->getUrl('', ['_direct' => 'core/index/notFound']);
         }
         return $url;
diff --git a/app/code/Magento/Catalog/Helper/Product.php b/app/code/Magento/Catalog/Helper/Product.php
index 4503f58d1ec..b26f922a2ab 100644
--- a/app/code/Magento/Catalog/Helper/Product.php
+++ b/app/code/Magento/Catalog/Helper/Product.php
@@ -448,7 +448,7 @@ class Product extends \Magento\Core\Helper\Url
                 ['product' => $product, 'controller_action' => $controller]
             );
         } catch (\Magento\Framework\Model\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
             return false;
         }
 
diff --git a/app/code/Magento/Catalog/Helper/Product/Flat/Indexer.php b/app/code/Magento/Catalog/Helper/Product/Flat/Indexer.php
index 52473fe4834..e029df6c439 100644
--- a/app/code/Magento/Catalog/Helper/Product/Flat/Indexer.php
+++ b/app/code/Magento/Catalog/Helper/Product/Flat/Indexer.php
@@ -304,7 +304,7 @@ class Indexer extends \Magento\Framework\App\Helper\AbstractHelper
                     $attribute->getBackend();
                     $this->_attributes[$attributeCode] = $attribute;
                 } catch (\Exception $e) {
-                    $this->_logger->logException($e);
+                    $this->_logger->critical($e);
                 }
             }
         }
diff --git a/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php b/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php
index 4ab260e6e4c..7a23c7247e9 100644
--- a/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php
+++ b/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php
@@ -93,7 +93,7 @@ class Image extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend
             $this->getAttribute()->getEntity()->saveAttribute($object, $this->getAttribute()->getName());
         } catch (\Exception $e) {
             if ($e->getCode() != \Magento\Core\Model\File\Uploader::TMP_NAME_EMPTY) {
-                $this->_logger->logException($e);
+                $this->_logger->critical($e);
             }
         }
         return $this;
diff --git a/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php b/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php
index 645c2437f57..3e14401a39a 100644
--- a/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php
+++ b/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php
@@ -1005,7 +1005,7 @@ abstract class AbstractType
         } catch (\Magento\Framework\Model\Exception $e) {
             $errors[] = $e->getMessages();
         } catch (\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
             $errors[] = __('Something went wrong while processing the request.');
         }
 
diff --git a/app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php b/app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php
index ceaaba2fcc5..9b9feb713dc 100644
--- a/app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php
+++ b/app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php
@@ -33,7 +33,7 @@ class FinalPriceBox extends BasePriceBox
             /** @var MsrpPrice $msrpPriceType */
             $msrpPriceType = $this->getSaleableItem()->getPriceInfo()->getPrice('msrp_price');
         } catch (\InvalidArgumentException $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
             return $this->wrapResult($result);
         }
 
diff --git a/app/code/Magento/CatalogImportExport/Model/Export/Product.php b/app/code/Magento/CatalogImportExport/Model/Export/Product.php
index a8b42a77aea..125fe87f102 100644
--- a/app/code/Magento/CatalogImportExport/Model/Export/Product.php
+++ b/app/code/Magento/CatalogImportExport/Model/Export/Product.php
@@ -1103,7 +1103,7 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity
                 }
             }
         } catch (\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
         }
         return $exportData;
     }
diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
index 8f59ba1aa57..46cd4b7703a 100644
--- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php
+++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
@@ -1102,7 +1102,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
                             if ($linkedId == null) {
                                 // Import file links to a SKU which is skipped for some reason, which leads to a "NULL"
                                 // link causing fatal errors.
-                                $this->_logger->logException(
+                                $this->_logger->critical(
                                     new \Exception(
                                         sprintf(
                                             'WARNING: Orphaned link skipped: From SKU %s (ID %d) to SKU %s, ' .
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/ApplyRules.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/ApplyRules.php
index 923ce9bd10c..d93e05df6fc 100644
--- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/ApplyRules.php
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/ApplyRules.php
@@ -29,7 +29,7 @@ class ApplyRules extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
                 $this->messageManager->addError($errorMessage . ' ' . $ruleJob->getError());
             }
         } catch (\Exception $e) {
-            $this->_objectManager->create('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->create('Magento\Framework\Logger')->critical($e);
             $this->messageManager->addError($errorMessage);
         }
         $this->_redirect('catalog_rule/*');
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Delete.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Delete.php
index 440407f0e16..cf530d0bb75 100644
--- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Delete.php
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Delete.php
@@ -31,7 +31,7 @@ class Delete extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
                 $this->messageManager->addError(
                     __('An error occurred while deleting the rule. Please review the log and try again.')
                 );
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
                 $this->_redirect('catalog_rule/*/edit', ['id' => $this->getRequest()->getParam('id')]);
                 return;
             }
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php
index 7124feaa8c9..828979b6304 100644
--- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php
@@ -75,7 +75,7 @@ class Save extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
                 $this->messageManager->addError(
                     __('An error occurred while saving the rule data. Please review the log and try again.')
                 );
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
                 $this->_objectManager->get('Magento\Backend\Model\Session')->setPageData($data);
                 $this->_redirect('catalog_rule/*/edit', ['id' => $this->getRequest()->getParam('rule_id')]);
                 return;
diff --git a/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php b/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php
index 690e8e5a35c..0e5a2e3c3c2 100644
--- a/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php
+++ b/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php
@@ -129,7 +129,7 @@ class IndexBuilder
         try {
             $this->doReindexByIds($ids);
         } catch (\Exception $e) {
-            $this->logException($e);
+            $this->critical($e);
             throw new CatalogRuleException($e->getMessage(), $e->getCode(), $e);
         }
     }
@@ -162,7 +162,7 @@ class IndexBuilder
         try {
             $this->doReindexFull();
         } catch (\Exception $e) {
-            $this->logException($e);
+            $this->critical($e);
             throw new CatalogRuleException($e->getMessage(), $e->getCode(), $e);
         }
     }
@@ -551,7 +551,7 @@ class IndexBuilder
     /**
      * @param int $websiteId
      * @param int|null $productId
-     * @return \Zend\Db\Adapter\Driver\StatementInterface|\Zend_Db_Statement_Interface
+     * @return \Zend_Db_Statement_Interface
      * @throws \Magento\Eav\Exception
      */
     protected function getRuleProductsStmt($websiteId, $productId = null)
@@ -691,8 +691,8 @@ class IndexBuilder
      * @param \Exception $e
      * @return void
      */
-    protected function logException($e)
+    protected function critical($e)
     {
-        $this->logger->logException($e);
+        $this->logger->critical($e);
     }
 }
diff --git a/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index/ValidatePaymentData.php b/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index/ValidatePaymentData.php
index 20a7d48d4ee..ca56ba6eafe 100644
--- a/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index/ValidatePaymentData.php
+++ b/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index/ValidatePaymentData.php
@@ -27,7 +27,7 @@ class ValidatePaymentData extends \Magento\Centinel\Controller\Adminhtml\Centine
         } catch (\Magento\Framework\Model\Exception $e) {
             $result['message'] = $e->getMessage();
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $result['message'] = __('Validation failed.');
         }
         $this->getResponse()->representJson(
diff --git a/app/code/Magento/Checkout/Controller/Cart/Add.php b/app/code/Magento/Checkout/Controller/Cart/Add.php
index 69b4b42b53e..d65ce4d25fd 100644
--- a/app/code/Magento/Checkout/Controller/Cart/Add.php
+++ b/app/code/Magento/Checkout/Controller/Cart/Add.php
@@ -134,7 +134,7 @@ class Add extends \Magento\Checkout\Controller\Cart
             }
         } catch (\Exception $e) {
             $this->messageManager->addException($e, __('We cannot add this item to your shopping cart'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->_goBack();
         }
     }
diff --git a/app/code/Magento/Checkout/Controller/Cart/Addgroup.php b/app/code/Magento/Checkout/Controller/Cart/Addgroup.php
index 08607e38f06..658864a6afe 100644
--- a/app/code/Magento/Checkout/Controller/Cart/Addgroup.php
+++ b/app/code/Magento/Checkout/Controller/Cart/Addgroup.php
@@ -31,7 +31,7 @@ class Addgroup extends \Magento\Checkout\Controller\Cart
                     }
                 } catch (\Exception $e) {
                     $this->messageManager->addException($e, __('We cannot add this item to your shopping cart'));
-                    $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                    $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
                     $this->_goBack();
                 }
             }
diff --git a/app/code/Magento/Checkout/Controller/Cart/Configure.php b/app/code/Magento/Checkout/Controller/Cart/Configure.php
index 8731afaae8d..92b2565d72d 100644
--- a/app/code/Magento/Checkout/Controller/Cart/Configure.php
+++ b/app/code/Magento/Checkout/Controller/Cart/Configure.php
@@ -71,7 +71,7 @@ class Configure extends \Magento\Checkout\Controller\Cart
             return $resultPage;
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We cannot configure the product.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->_goBack();
             return;
         }
diff --git a/app/code/Magento/Checkout/Controller/Cart/CouponPost.php b/app/code/Magento/Checkout/Controller/Cart/CouponPost.php
index 346bb38a4a6..e9eea809d94 100644
--- a/app/code/Magento/Checkout/Controller/Cart/CouponPost.php
+++ b/app/code/Magento/Checkout/Controller/Cart/CouponPost.php
@@ -103,7 +103,7 @@ class CouponPost extends \Magento\Checkout\Controller\Cart
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We cannot apply the coupon code.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
 
         $this->_goBack();
diff --git a/app/code/Magento/Checkout/Controller/Cart/Delete.php b/app/code/Magento/Checkout/Controller/Cart/Delete.php
index 30540402d4e..a22b198f813 100644
--- a/app/code/Magento/Checkout/Controller/Cart/Delete.php
+++ b/app/code/Magento/Checkout/Controller/Cart/Delete.php
@@ -20,7 +20,7 @@ class Delete extends \Magento\Checkout\Controller\Cart
                 $this->cart->removeItem($id)->save();
             } catch (\Exception $e) {
                 $this->messageManager->addError(__('We cannot remove the item.'));
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             }
         }
         $defaultUrl = $this->_objectManager->create('Magento\Framework\UrlInterface')->getUrl('*/*');
diff --git a/app/code/Magento/Checkout/Controller/Cart/UpdateItemOptions.php b/app/code/Magento/Checkout/Controller/Cart/UpdateItemOptions.php
index 91b7c652ae3..afdedd5cf20 100644
--- a/app/code/Magento/Checkout/Controller/Cart/UpdateItemOptions.php
+++ b/app/code/Magento/Checkout/Controller/Cart/UpdateItemOptions.php
@@ -83,7 +83,7 @@ class UpdateItemOptions extends \Magento\Checkout\Controller\Cart
             }
         } catch (\Exception $e) {
             $this->messageManager->addException($e, __('We cannot update the item.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->_goBack();
         }
         $this->_redirect('*/*');
diff --git a/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php b/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php
index 753e4ac69b0..ab836be0630 100644
--- a/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php
+++ b/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php
@@ -56,7 +56,7 @@ class UpdatePost extends \Magento\Checkout\Controller\Cart
             );
         } catch (\Exception $e) {
             $this->messageManager->addException($e, __('We cannot update the shopping cart.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
     }
 
diff --git a/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php b/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php
index 18fe3c01b92..42161ccd2f7 100644
--- a/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php
+++ b/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php
@@ -63,7 +63,7 @@ class SaveOrder extends \Magento\Checkout\Controller\Onepage
             $result['goto_section'] = 'payment';
             $result['update_section'] = ['name' => 'payment-method', 'html' => $this->_getPaymentMethodsHtml()];
         } catch (\Magento\Framework\Model\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->_objectManager->get(
                 'Magento\Checkout\Helper\Data'
             )->sendPaymentFailedEmail(
@@ -91,7 +91,7 @@ class SaveOrder extends \Magento\Checkout\Controller\Onepage
                 $this->getOnepage()->getCheckout()->setUpdateSection(null);
             }
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->_objectManager->get(
                 'Magento\Checkout\Helper\Data'
             )->sendPaymentFailedEmail(
diff --git a/app/code/Magento/Checkout/Controller/Onepage/SavePayment.php b/app/code/Magento/Checkout/Controller/Onepage/SavePayment.php
index 9e14aae22b3..01b590b7345 100644
--- a/app/code/Magento/Checkout/Controller/Onepage/SavePayment.php
+++ b/app/code/Magento/Checkout/Controller/Onepage/SavePayment.php
@@ -56,7 +56,7 @@ class SavePayment extends \Magento\Checkout\Controller\Onepage
         } catch (\Magento\Framework\Model\Exception $e) {
             $result['error'] = $e->getMessage();
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $result['error'] = __('Unable to set Payment Method');
         }
         $this->getResponse()->representJson(
diff --git a/app/code/Magento/Checkout/Model/Type/Onepage.php b/app/code/Magento/Checkout/Model/Type/Onepage.php
index 1b11589918e..d4fb6787fc8 100644
--- a/app/code/Magento/Checkout/Model/Type/Onepage.php
+++ b/app/code/Magento/Checkout/Model/Type/Onepage.php
@@ -925,7 +925,7 @@ class Onepage
             try {
                 $this->_involveNewCustomer();
             } catch (\Exception $e) {
-                $this->_logger->logException($e);
+                $this->_logger->critical($e);
             }
         }
 
@@ -953,7 +953,7 @@ class Onepage
                 try {
                     $this->orderSender->send($order);
                 } catch (\Exception $e) {
-                    $this->_logger->logException($e);
+                    $this->_logger->critical($e);
                 }
             }
 
diff --git a/app/code/Magento/Checkout/Service/V1/Address/Billing/WriteService.php b/app/code/Magento/Checkout/Service/V1/Address/Billing/WriteService.php
index 8cb870b3fbd..eda52bc6725 100644
--- a/app/code/Magento/Checkout/Service/V1/Address/Billing/WriteService.php
+++ b/app/code/Magento/Checkout/Service/V1/Address/Billing/WriteService.php
@@ -105,7 +105,7 @@ class WriteService implements WriteServiceInterface
         try {
             $this->quoteRepository->save($quote);
         } catch (\Exception $e) {
-            $this->logger->logException($e);
+            $this->logger->critical($e);
             throw new InputException('Unable to save address. Please, check input data.');
         }
         return $quote->getBillingAddress()->getId();
diff --git a/app/code/Magento/Checkout/Service/V1/Address/Shipping/WriteService.php b/app/code/Magento/Checkout/Service/V1/Address/Shipping/WriteService.php
index b58cfd6bab4..233779fb691 100644
--- a/app/code/Magento/Checkout/Service/V1/Address/Shipping/WriteService.php
+++ b/app/code/Magento/Checkout/Service/V1/Address/Shipping/WriteService.php
@@ -102,7 +102,7 @@ class WriteService implements WriteServiceInterface
         try {
             $this->quoteRepository->save($quote);
         } catch (\Exception $e) {
-            $this->logger->logException($e);
+            $this->logger->critical($e);
             throw new InputException('Unable to save address. Please, check input data.');
         }
         return $quote->getShippingAddress()->getId();
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Directive.php b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Directive.php
index 87807166799..a6d90682ca4 100644
--- a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Directive.php
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Directive.php
@@ -28,7 +28,7 @@ class Directive extends \Magento\Backend\App\Action
         } catch (\Exception $e) {
             $image->open($this->_objectManager->get('Magento\Cms\Model\Wysiwyg\Config')->getSkinImagePlaceholderUrl());
             $response->setHeader('Content-Type', $image->getMimeType())->setBody($image->getImage());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
     }
 }
diff --git a/app/code/Magento/Core/Model/File/Storage/Database.php b/app/code/Magento/Core/Model/File/Storage/Database.php
index 61d9202cc4d..6484ffcb070 100644
--- a/app/code/Magento/Core/Model/File/Storage/Database.php
+++ b/app/code/Magento/Core/Model/File/Storage/Database.php
@@ -233,7 +233,7 @@ class Database extends \Magento\Core\Model\File\Storage\Database\AbstractDatabas
                 $this->_getResource()->saveFile($file);
             } catch (\Exception $e) {
                 $this->_errors[] = $e->getMessage();
-                $this->_logger->logException($e);
+                $this->_logger->critical($e);
             }
         }
 
diff --git a/app/code/Magento/Core/Model/File/Storage/Directory/Database.php b/app/code/Magento/Core/Model/File/Storage/Directory/Database.php
index be3f8cbd10a..0174d3b1c90 100644
--- a/app/code/Magento/Core/Model/File/Storage/Directory/Database.php
+++ b/app/code/Magento/Core/Model/File/Storage/Directory/Database.php
@@ -201,7 +201,7 @@ class Database extends \Magento\Core\Model\File\Storage\Database\AbstractDatabas
                     throw new \Magento\Framework\Model\Exception(__('Parent directory does not exist: %1', $dir['path']));
                 }
             } catch (\Exception $e) {
-                $this->_logger->logException($e);
+                $this->_logger->critical($e);
             }
         }
 
diff --git a/app/code/Magento/Core/Model/File/Storage/File.php b/app/code/Magento/Core/Model/File/Storage/File.php
index cbc14e1f21f..7917ade47ef 100644
--- a/app/code/Magento/Core/Model/File/Storage/File.php
+++ b/app/code/Magento/Core/Model/File/Storage/File.php
@@ -193,7 +193,7 @@ class File
             try {
                 $fileInfo = $this->_mediaHelper->collectFileInfo($this->getMediaBaseDirectory(), $fileName);
             } catch (\Exception $e) {
-                $this->_logger->logException($e);
+                $this->_logger->critical($e);
                 continue;
             }
 
@@ -221,7 +221,7 @@ class File
                 $this->{$callback}($part);
             } catch (\Exception $e) {
                 $this->_errors[] = $e->getMessage();
-                $this->_logger->logException($e);
+                $this->_logger->critical($e);
             }
         }
 
@@ -284,7 +284,7 @@ class File
 
                 return $this->_fileUtility->saveFile($filename, $file['content'], $overwrite);
             } catch (\Exception $e) {
-                $this->_logger->logException($e);
+                $this->_logger->critical($e);
                 throw new \Magento\Framework\Model\Exception(
                     __('Unable to save file "%1" at "%2"', $file['filename'], $file['directory'])
                 );
diff --git a/app/code/Magento/Core/Model/Observer.php b/app/code/Magento/Core/Model/Observer.php
index d3a9341f9f3..b8a6713dee9 100644
--- a/app/code/Magento/Core/Model/Observer.php
+++ b/app/code/Magento/Core/Model/Observer.php
@@ -102,7 +102,7 @@ class Observer
         try {
             $this->_registration->register($pathPattern);
         } catch (\Magento\Framework\Model\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
         }
         return $this;
     }
@@ -133,7 +133,7 @@ class Observer
                     $this->_pageAssets->add($identifier, $asset);
                 }
             } catch (\InvalidArgumentException $e) {
-                $this->_logger->logException($e);
+                $this->_logger->critical($e);
             }
         }
     }
diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfo.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfo.php
index 5701c366a1d..1e2366b20fb 100644
--- a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfo.php
+++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfo.php
@@ -128,7 +128,7 @@ class PersonalInfo extends \Magento\Backend\Block\Template
             );
             return $this->formatDate($date, TimezoneInterface::FORMAT_TYPE_MEDIUM, true);
         } catch (\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
             return '';
         }
     }
diff --git a/app/code/Magento/Customer/Controller/Account/LoginPost.php b/app/code/Magento/Customer/Controller/Account/LoginPost.php
index 412ed7c140d..ad470d2b4e3 100644
--- a/app/code/Magento/Customer/Controller/Account/LoginPost.php
+++ b/app/code/Magento/Customer/Controller/Account/LoginPost.php
@@ -159,7 +159,7 @@ class LoginPost extends \Magento\Customer\Controller\Account
                     $this->_getSession()->setUsername($login['username']);
                 } catch (\Exception $e) {
                     // PA DSS violation: this exception log can disclose customer password
-                    // $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                    // $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
                     $this->messageManager->addError(__('There was an error validating the login and password.'));
                 }
             } else {
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Wishlist.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Wishlist.php
index c1b141f2710..854fdfa6e0a 100644
--- a/app/code/Magento/Customer/Controller/Adminhtml/Index/Wishlist.php
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Wishlist.php
@@ -23,7 +23,7 @@ class Wishlist extends \Magento\Customer\Controller\Adminhtml\Index
             try {
                 $this->_objectManager->create('Magento\Wishlist\Model\Item')->load($itemId)->delete();
             } catch (\Exception $exception) {
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($exception);
+                $this->_objectManager->get('Magento\Framework\Logger')->critical($exception);
             }
         }
 
diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php
index b9680b1d534..6e9e80e9d4a 100644
--- a/app/code/Magento/Customer/Model/AccountManagement.php
+++ b/app/code/Magento/Customer/Model/AccountManagement.php
@@ -312,7 +312,7 @@ class AccountManagement implements AccountManagementInterface
             );
         } catch (MailException $e) {
             // If we are not able to send a new account email, this should be ignored
-            $this->logger->logException($e);
+            $this->logger->critical($e);
         }
     }
 
@@ -432,7 +432,7 @@ class AccountManagement implements AccountManagementInterface
             }
         } catch (MailException $e) {
             // If we are not able to send a reset password email, this should be ignored
-            $this->logger->logException($e);
+            $this->logger->critical($e);
         }
     }
 
@@ -585,7 +585,7 @@ class AccountManagement implements AccountManagementInterface
             }
         } catch (MailException $e) {
             // If we are not able to send a new account email, this should be ignored
-            $this->logger->logException($e);
+            $this->logger->critical($e);
         }
     }
 
@@ -639,7 +639,7 @@ class AccountManagement implements AccountManagementInterface
         try {
             $this->sendPasswordResetNotificationEmail($customer);
         } catch (MailException $e) {
-            $this->logger->logException($e);
+            $this->logger->critical($e);
         }
 
         return true;
diff --git a/app/code/Magento/Customer/Model/Metadata/Form/File.php b/app/code/Magento/Customer/Model/Metadata/Form/File.php
index 926e2078f27..c280217bcde 100644
--- a/app/code/Magento/Customer/Model/Metadata/Form/File.php
+++ b/app/code/Magento/Customer/Model/Metadata/Form/File.php
@@ -270,7 +270,7 @@ class File extends AbstractData
                 $uploader->save($mediaDir->getAbsolutePath($this->_entityTypeCode), $value['name']);
                 $result = $uploader->getUploadedFileName();
             } catch (\Exception $e) {
-                $this->_logger->logException($e);
+                $this->_logger->critical($e);
             }
         }
 
diff --git a/app/code/Magento/Customer/Model/Vat.php b/app/code/Magento/Customer/Model/Vat.php
index 0bd3d70b8d2..0b895ea65bb 100644
--- a/app/code/Magento/Customer/Model/Vat.php
+++ b/app/code/Magento/Customer/Model/Vat.php
@@ -172,7 +172,7 @@ class Vat
         );
 
         if (!extension_loaded('soap')) {
-            $this->logger->logException(new \Magento\Framework\Model\Exception(__('PHP SOAP extension is required.')));
+            $this->logger->critical(new \Magento\Framework\Model\Exception(__('PHP SOAP extension is required.')));
             return $gatewayResponse;
         }
 
diff --git a/app/code/Magento/Customer/Model/Visitor.php b/app/code/Magento/Customer/Model/Visitor.php
index 0a41a5ba682..642e33c184c 100644
--- a/app/code/Magento/Customer/Model/Visitor.php
+++ b/app/code/Magento/Customer/Model/Visitor.php
@@ -164,7 +164,7 @@ class Visitor extends \Magento\Framework\Model\AbstractModel
             $this->_eventManager->dispatch('visitor_activity_save', ['visitor' => $this]);
             $this->session->setVisitorData($this->getData());
         } catch (\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
         }
         return $this;
     }
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor.php
index 795726faba2..f7afe52525f 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor.php
@@ -123,7 +123,7 @@ class Editor extends \Magento\Backend\App\Action
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t load the list of themes.'));
             $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
     }
 
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/AssignThemeToStore.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/AssignThemeToStore.php
index 763971b0af0..75750d2bea1 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/AssignThemeToStore.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/AssignThemeToStore.php
@@ -77,7 +77,7 @@ class AssignThemeToStore extends \Magento\DesignEditor\Controller\Adminhtml\Syst
             }
             $response = ['message' => $successMessage, 'themeId' => $themeCustomization->getId()];
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $response = ['error' => true, 'message' => __('This theme is not assigned.')];
         }
         $this->getResponse()->representJson($coreHelper->jsonEncode($response));
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Duplicate.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Duplicate.php
index 2cb0ede931f..39c68bb0a40 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Duplicate.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Duplicate.php
@@ -35,9 +35,9 @@ class Duplicate extends \Magento\DesignEditor\Controller\Adminhtml\System\Design
             $this->messageManager->addSuccess(__('You saved a duplicate copy of this theme in "My Customizations."'));
         } catch (CoreException $e) {
             $this->messageManager->addError($e->getMessage());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->messageManager->addError(__('You cannot duplicate this theme.'));
         }
         $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/TreeJson.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/TreeJson.php
index e8955aa585b..101b7e11157 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/TreeJson.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/TreeJson.php
@@ -23,7 +23,7 @@ class TreeJson extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg
                 )
             );
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->getResponse()->representJson(
                 $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode([])
             );
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Launch.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Launch.php
index 14e1134e7a7..5ff329a13f0 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Launch.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Launch.php
@@ -154,12 +154,12 @@ class Launch extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Ed
             $this->_view->renderLayout();
         } catch (CoreException $e) {
             $this->messageManager->addException($e, $e->getMessage());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->_redirect('adminhtml/*/');
             return;
         } catch (\Exception $e) {
             $this->messageManager->addException($e, __('Sorry, there was an unknown error.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->_redirect('adminhtml/*/');
             return;
         }
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/LoadThemeList.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/LoadThemeList.php
index 6c4695c701b..2ccd95bbf3f 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/LoadThemeList.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/LoadThemeList.php
@@ -41,7 +41,7 @@ class LoadThemeList extends \Magento\DesignEditor\Controller\Adminhtml\System\De
 
             $response = ['content' => $this->_view->getLayout()->getOutput()];
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $response = ['error' => __('Sorry, but we can\'t load the theme list.')];
         }
         $this->getResponse()->representJson($coreHelper->jsonEncode($response));
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/QuickEdit.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/QuickEdit.php
index f690b4b7cfc..d34e1bc1c58 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/QuickEdit.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/QuickEdit.php
@@ -31,9 +31,9 @@ class QuickEdit extends \Magento\DesignEditor\Controller\Adminhtml\System\Design
             $response = ['success' => true];
         } catch (CoreException $e) {
             $response = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $response = ['error' => true, 'message' => __('This theme is not saved.')];
         }
         $this->getResponse()->representJson($coreHelper->jsonEncode($response));
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Revert.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Revert.php
index 108d9298fbb..1e39c8688dc 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Revert.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Revert.php
@@ -47,7 +47,7 @@ class Revert extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Ed
             }
             $response = ['message' => $message];
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $response = ['error' => true, 'message' => __('Unknown error')];
         }
         /** @var $coreHelper \Magento\Core\Helper\Data */
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Save.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Save.php
index 899c59803f8..07893246c8a 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Save.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Save.php
@@ -28,7 +28,7 @@ class Save extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Edit
             }
             $response = ['message' => $message];
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $response = ['error' => true, 'message' => __('Sorry, there was an unknown error.')];
         }
 
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/DeleteCustomFiles.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/DeleteCustomFiles.php
index 9d3e3918336..2515d1ef020 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/DeleteCustomFiles.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/DeleteCustomFiles.php
@@ -22,7 +22,7 @@ class DeleteCustomFiles extends \Magento\DesignEditor\Controller\Adminhtml\Syste
             $this->_forward('jsList');
         } catch (\Exception $e) {
             $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
     }
 }
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/JsList.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/JsList.php
index f815039bb3a..04954eb5fd9 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/JsList.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/JsList.php
@@ -24,7 +24,7 @@ class JsList extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Ed
                 $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
             );
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
     }
 }
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveQuickStyleImage.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveQuickStyleImage.php
index 933c7c7546b..b63a6c1c064 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveQuickStyleImage.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveQuickStyleImage.php
@@ -41,14 +41,14 @@ class RemoveQuickStyleImage extends \Magento\DesignEditor\Controller\Adminhtml\S
             $response = ['error' => false, 'content' => $result];
         } catch (CoreException $e) {
             $response = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         } catch (\Exception $e) {
             $errorMessage = __(
                 'Something went wrong uploading the image.' .
                 ' Please check the file format and try again (JPEG, GIF, or PNG).'
             );
             $response = ['error' => true, 'message' => $errorMessage];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveStoreLogo.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveStoreLogo.php
index a28c14fcc0a..4e53fd32abe 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveStoreLogo.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveStoreLogo.php
@@ -50,14 +50,14 @@ class RemoveStoreLogo extends \Magento\DesignEditor\Controller\Adminhtml\System\
             $response = ['error' => false, 'content' => []];
         } catch (CoreException $e) {
             $response = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         } catch (\Exception $e) {
             $errorMessage = __(
                 'Something went wrong uploading the image.' .
                 ' Please check the file format and try again (JPEG, GIF, or PNG).'
             );
             $response = ['error' => true, 'message' => $errorMessage];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/ReorderJs.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/ReorderJs.php
index 692a1479a96..474c1148286 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/ReorderJs.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/ReorderJs.php
@@ -27,10 +27,10 @@ class ReorderJs extends \Magento\DesignEditor\Controller\Adminhtml\System\Design
             $result = ['success' => true];
         } catch (CoreException $e) {
             $result = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         } catch (\Exception $e) {
             $result = ['error' => true, 'message' => __('We cannot upload the CSS file.')];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveCssContent.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveCssContent.php
index 6edc4c2dc49..0ee26290c8b 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveCssContent.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveCssContent.php
@@ -35,10 +35,10 @@ class SaveCssContent extends \Magento\DesignEditor\Controller\Adminhtml\System\D
             ];
         } catch (CoreException $e) {
             $response = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         } catch (\Exception $e) {
             $response = ['error' => true, 'message' => __('We can\'t save the custom css file.')];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveImageSizing.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveImageSizing.php
index c9d65e7636c..bec9dde0bb0 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveImageSizing.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveImageSizing.php
@@ -35,10 +35,10 @@ class SaveImageSizing extends \Magento\DesignEditor\Controller\Adminhtml\System\
             $result = ['success' => true, 'message' => __('We saved the image sizes.')];
         } catch (CoreException $e) {
             $result = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         } catch (\Exception $e) {
             $result = ['error' => true, 'message' => __('We can\'t save image sizes.')];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveQuickStyles.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveQuickStyles.php
index d14b8bd6365..a3444c0a3f1 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveQuickStyles.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveQuickStyles.php
@@ -31,14 +31,14 @@ class SaveQuickStyles extends \Magento\DesignEditor\Controller\Adminhtml\System\
             $response = ['success' => true];
         } catch (CoreException $e) {
             $response = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         } catch (\Exception $e) {
             $errorMessage = __(
                 'Something went wrong uploading the image.' .
                 ' Please check the file format and try again (JPEG, GIF, or PNG).'
             );
             $response = ['error' => true, 'message' => $errorMessage];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/Upload.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/Upload.php
index 928962e41e0..467d7738f7e 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/Upload.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/Upload.php
@@ -39,10 +39,10 @@ class Upload extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Ed
             ];
         } catch (CoreException $e) {
             $response = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         } catch (\Exception $e) {
             $response = ['error' => true, 'message' => __('We cannot upload the CSS file.')];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadJs.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadJs.php
index 62e7e0922a9..4cb02a7149a 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadJs.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadJs.php
@@ -33,10 +33,10 @@ class UploadJs extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\
             return;
         } catch (CoreException $e) {
             $response = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         } catch (\Exception $e) {
             $response = ['error' => true, 'message' => __('We cannot upload the JS file.')];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadQuickStyleImage.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadQuickStyleImage.php
index 113765a967d..c1431963a5b 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadQuickStyleImage.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadQuickStyleImage.php
@@ -39,14 +39,14 @@ class UploadQuickStyleImage extends \Magento\DesignEditor\Controller\Adminhtml\S
         } catch (CoreException $e) {
             $this->messageManager->addError($e->getMessage());
             $response = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         } catch (\Exception $e) {
             $errorMessage = __(
                 'Something went wrong uploading the image.' .
                 ' Please check the file format and try again (JPEG, GIF, or PNG).'
             );
             $response = ['error' => true, 'message' => $errorMessage];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadStoreLogo.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadStoreLogo.php
index fa16fc80f14..5272738b3b1 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadStoreLogo.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadStoreLogo.php
@@ -44,14 +44,14 @@ class UploadStoreLogo extends \Magento\DesignEditor\Controller\Adminhtml\System\
             $response = ['error' => false, 'content' => ['name' => basename($storeLogo->getValue())]];
         } catch (CoreException $e) {
             $response = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         } catch (\Exception $e) {
             $errorMessage = __(
                 'Something went wrong uploading the image.' .
                 ' Please check the file format and try again (JPEG, GIF, or PNG).'
             );
             $response = ['error' => true, 'message' => $errorMessage];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
diff --git a/app/code/Magento/Directory/Model/PriceCurrency.php b/app/code/Magento/Directory/Model/PriceCurrency.php
index 1768f841a49..dafb8e1faa6 100644
--- a/app/code/Magento/Directory/Model/PriceCurrency.php
+++ b/app/code/Magento/Directory/Model/PriceCurrency.php
@@ -135,7 +135,7 @@ class PriceCurrency implements \Magento\Framework\Pricing\PriceCurrencyInterface
                 $scope = $this->storeManager->getStore($scope);
             }
         } catch (\Exception $e) {
-            $this->logger->logException($e);
+            $this->logger->critical($e);
             $scope = $this->storeManager->getStore();
         }
 
diff --git a/app/code/Magento/Eav/Model/Attribute/Data/File.php b/app/code/Magento/Eav/Model/Attribute/Data/File.php
index 8ef938a8abf..0886e2d94ab 100644
--- a/app/code/Magento/Eav/Model/Attribute/Data/File.php
+++ b/app/code/Magento/Eav/Model/Attribute/Data/File.php
@@ -244,7 +244,7 @@ class File extends \Magento\Eav\Model\Attribute\Data\AbstractData
                 $fileName = $uploader->getUploadedFileName();
                 $this->getEntity()->setData($attribute->getAttributeCode(), $fileName);
             } catch (\Exception $e) {
-                $this->_logger->logException($e);
+                $this->_logger->critical($e);
             }
         }
 
diff --git a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/DefaultTemplate.php b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/DefaultTemplate.php
index cc8e45631d3..95e2cc37a65 100644
--- a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/DefaultTemplate.php
+++ b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/DefaultTemplate.php
@@ -29,7 +29,7 @@ class DefaultTemplate extends \Magento\Email\Controller\Adminhtml\Email\Template
                 $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($template->getData())
             );
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
     }
 }
diff --git a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Delete.php b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Delete.php
index 3c0b93101cc..390449040fa 100644
--- a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Delete.php
+++ b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Delete.php
@@ -38,7 +38,7 @@ class Delete extends \Magento\Email\Controller\Adminhtml\Email\Template
                 $this->messageManager->addError(
                     __('An error occurred while deleting email template data. Please review log and try again.')
                 );
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
                 // save data in session
                 $this->_objectManager->get(
                     'Magento\Backend\Model\Session'
diff --git a/app/code/Magento/Email/Model/Template/Filter.php b/app/code/Magento/Email/Model/Template/Filter.php
index 062afab9e21..23042755a42 100644
--- a/app/code/Magento/Email/Model/Template/Filter.php
+++ b/app/code/Magento/Email/Model/Template/Filter.php
@@ -615,7 +615,7 @@ class Filter extends \Magento\Framework\Filter\Template
             $value = parent::filter($value);
         } catch (\Exception $e) {
             $value = '';
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
         }
         return $value;
     }
diff --git a/app/code/Magento/Fedex/Model/Carrier.php b/app/code/Magento/Fedex/Model/Carrier.php
index 7da84404894..348362a5e74 100644
--- a/app/code/Magento/Fedex/Model/Carrier.php
+++ b/app/code/Magento/Fedex/Model/Carrier.php
@@ -459,7 +459,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
                 $debugData['result'] = $response;
             } catch (\Exception $e) {
                 $debugData['result'] = ['error' => $e->getMessage(), 'code' => $e->getCode()];
-                $this->_logger->logException($e);
+                $this->_logger->critical($e);
             }
         } else {
             $response = unserialize($response);
@@ -774,7 +774,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
                 throw new \Exception(__('Failed to parse xml document: %1', $xmlContent));
             }
         } catch (\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
             return false;
         }
     }
@@ -1038,7 +1038,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
                 $debugData['result'] = $response;
             } catch (\Exception $e) {
                 $debugData['result'] = ['error' => $e->getMessage(), 'code' => $e->getCode()];
-                $this->_logger->logException($e);
+                $this->_logger->critical($e);
             }
         } else {
             $response = unserialize($response);
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/ConfirmCaptcha.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/ConfirmCaptcha.php
index f1a1bece505..0db9bc133cb 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/ConfirmCaptcha.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/ConfirmCaptcha.php
@@ -41,7 +41,7 @@ class ConfirmCaptcha extends \Magento\GoogleShopping\Controller\Adminhtml\Google
                 )
             );
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->messageManager->addError(__('Something went wrong during Captcha confirmation.'));
         }
 
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAdd.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAdd.php
index 7b25e9e7c05..7af24ce9278 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAdd.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAdd.php
@@ -48,7 +48,7 @@ class MassAdd extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshoppin
                 __('An error has occurred while adding products to google shopping account.'),
                 $e->getMessage()
             );
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             return;
         }
 
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Refresh.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Refresh.php
index a93e723d3fc..86fefea98a0 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Refresh.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Refresh.php
@@ -55,7 +55,7 @@ class Refresh extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshoppin
                     'One or more products were not deleted from google shopping account. Refer to the log file for details.'
                 )
             );
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             return;
         }
 
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Delete.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Delete.php
index c89198bad9b..2edcfdf8e12 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Delete.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Delete.php
@@ -23,7 +23,7 @@ class Delete extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping
             }
             $this->messageManager->addSuccess(__('Attribute set mapping was deleted'));
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->messageManager->addError(__("We can't delete Attribute Set Mapping."));
         }
         $this->_redirect('adminhtml/*/index', ['store' => $this->_getStore()->getId()]);
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Edit.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Edit.php
index 9255b7fb806..becfb35dcaf 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Edit.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Edit.php
@@ -43,7 +43,7 @@ class Edit extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\T
             $this->_view->getPage()->getConfig()->getTitle()->prepend(__('Google Content Attributes'));
             $this->_view->renderLayout();
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->messageManager->addError(__("We can't edit Attribute Set Mapping."));
             $this->_redirect('adminhtml/*/index');
         }
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSets.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSets.php
index 2b9bdd82677..c76f979a21c 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSets.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSets.php
@@ -23,7 +23,7 @@ class LoadAttributeSets extends \Magento\GoogleShopping\Controller\Adminhtml\Goo
                 )->toHtml()
             );
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             // just need to output text with error
             $this->messageManager->addError(__("We can't load attribute sets."));
         }
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributes.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributes.php
index 443ea921ab7..460df0e6451 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributes.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributes.php
@@ -27,7 +27,7 @@ class LoadAttributes extends \Magento\GoogleShopping\Controller\Adminhtml\Google
                 )->toHtml()
             );
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             // just need to output text with error
             $this->messageManager->addError(__("We can't load attributes."));
         }
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/NewAction.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/NewAction.php
index ba47fa1415e..db5181519ed 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/NewAction.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/NewAction.php
@@ -26,7 +26,7 @@ class NewAction extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopp
             $this->_view->getPage()->getConfig()->getTitle()->prepend(__('New Google Content Attribute Mapping'));
             $this->_view->renderLayout();
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->messageManager->addError(__("We can't create Attribute Set Mapping."));
             $this->_redirect('adminhtml/*/index', ['store' => $this->_getStore()->getId()]);
         }
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Save.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Save.php
index 0991036ac84..b57f533e8ee 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Save.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Save.php
@@ -71,7 +71,7 @@ class Save extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\T
                 );
             }
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->messageManager->addError(__("We can't save Attribute Set Mapping."));
         }
         $this->_redirect('adminhtml/*/index', ['store' => $this->_getStore()->getId()]);
diff --git a/app/code/Magento/GoogleShopping/Model/MassOperations.php b/app/code/Magento/GoogleShopping/Model/MassOperations.php
index 6215f00c349..3e1b53b22fc 100644
--- a/app/code/Magento/GoogleShopping/Model/MassOperations.php
+++ b/app/code/Magento/GoogleShopping/Model/MassOperations.php
@@ -180,7 +180,7 @@ class MassOperations
                         $e->getMessage()
                     );
                 } catch (\Exception $e) {
-                    $this->_logger->logException($e);
+                    $this->_logger->critical($e);
                     $errors[] = __('The product "%1" hasn\'t been added to Google Content.', $product->getName());
                 }
             }
@@ -268,7 +268,7 @@ class MassOperations
                     );
                     $totalFailed++;
                 } catch (\Exception $e) {
-                    $this->_logger->logException($e);
+                    $this->_logger->critical($e);
                     $errors[] = __('The item "%1" hasn\'t been updated.', $item->getProduct()->getName());
                     $totalFailed++;
                 }
@@ -329,7 +329,7 @@ class MassOperations
                         $item->getProduct()
                     );
                 } catch (\Exception $e) {
-                    $this->_logger->logException($e);
+                    $this->_logger->critical($e);
                     $errors[] = __('The item "%1" hasn\'t been deleted.', $item->getProduct()->getName());
                 }
             }
diff --git a/app/code/Magento/GroupedProduct/Controller/Adminhtml/Edit/Popup.php b/app/code/Magento/GroupedProduct/Controller/Adminhtml/Edit/Popup.php
index 5d9ffe429bd..96e19a61b0c 100644
--- a/app/code/Magento/GroupedProduct/Controller/Adminhtml/Edit/Popup.php
+++ b/app/code/Magento/GroupedProduct/Controller/Adminhtml/Edit/Popup.php
@@ -74,7 +74,7 @@ class Popup extends \Magento\Backend\App\AbstractAction
                 $product->load($productId);
             } catch (\Exception $e) {
                 $product->setTypeId(\Magento\Catalog\Model\Product\Type::DEFAULT_TYPE);
-                $this->logger->logException($e);
+                $this->logger->critical($e);
             }
         }
 
diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Export/Export.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Export/Export.php
index d53388494c7..cf4d1863bc0 100644
--- a/app/code/Magento/ImportExport/Controller/Adminhtml/Export/Export.php
+++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Export/Export.php
@@ -48,7 +48,7 @@ class Export extends \Magento\ImportExport\Controller\Adminhtml\Export
             } catch (\Magento\Framework\Model\Exception $e) {
                 $this->messageManager->addError($e->getMessage());
             } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
                 $this->messageManager->addError(__('Please correct the data sent.'));
             }
         } else {
diff --git a/app/code/Magento/ImportExport/Model/Export.php b/app/code/Magento/ImportExport/Model/Export.php
index e31fe45df3d..44223d9e53d 100644
--- a/app/code/Magento/ImportExport/Model/Export.php
+++ b/app/code/Magento/ImportExport/Model/Export.php
@@ -94,7 +94,7 @@ class Export extends \Magento\ImportExport\Model\AbstractModel
                 try {
                     $this->_entityAdapter = $this->_entityFactory->create($entities[$this->getEntity()]['model']);
                 } catch (\Exception $e) {
-                    $this->_logger->logException($e);
+                    $this->_logger->critical($e);
                     throw new \Magento\Framework\Model\Exception(__('Please enter a correct entity model'));
                 }
                 if (!$this->_entityAdapter instanceof \Magento\ImportExport\Model\Export\Entity\AbstractEntity &&
@@ -138,7 +138,7 @@ class Export extends \Magento\ImportExport\Model\AbstractModel
                 try {
                     $this->_writer = $this->_exportAdapterFac->create($fileFormats[$this->getFileFormat()]['model']);
                 } catch (\Exception $e) {
-                    $this->_logger->logException($e);
+                    $this->_logger->critical($e);
                     throw new \Magento\Framework\Model\Exception(__('Please enter a correct entity model'));
                 }
                 if (!$this->_writer instanceof \Magento\ImportExport\Model\Export\Adapter\AbstractAdapter) {
diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php
index 6b5900c9b8f..553d4eb3450 100644
--- a/app/code/Magento/ImportExport/Model/Import.php
+++ b/app/code/Magento/ImportExport/Model/Import.php
@@ -170,7 +170,7 @@ class Import extends \Magento\ImportExport\Model\AbstractModel
                 try {
                     $this->_entityAdapter = $this->_entityFactory->create($entities[$this->getEntity()]['model']);
                 } catch (\Exception $e) {
-                    $this->_logger->logException($e);
+                    $this->_logger->critical($e);
                     throw new \Magento\Framework\Model\Exception(__('Please enter a correct entity model'));
                 }
                 if (!$this->_entityAdapter instanceof \Magento\ImportExport\Model\Import\Entity\AbstractEntity &&
diff --git a/app/code/Magento/Integration/Controller/Adminhtml/Integration/Delete.php b/app/code/Magento/Integration/Controller/Adminhtml/Integration/Delete.php
index 809323333ca..cc56199c514 100644
--- a/app/code/Magento/Integration/Controller/Adminhtml/Integration/Delete.php
+++ b/app/code/Magento/Integration/Controller/Adminhtml/Integration/Delete.php
@@ -52,7 +52,7 @@ class Delete extends \Magento\Integration\Controller\Adminhtml\Integration
         } catch (\Magento\Integration\Exception $e) {
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
         }
         $this->_redirect('*/*/');
     }
diff --git a/app/code/Magento/Integration/Controller/Adminhtml/Integration/Edit.php b/app/code/Magento/Integration/Controller/Adminhtml/Integration/Edit.php
index f7523b7c4bf..52254b3be87 100644
--- a/app/code/Magento/Integration/Controller/Adminhtml/Integration/Edit.php
+++ b/app/code/Magento/Integration/Controller/Adminhtml/Integration/Edit.php
@@ -29,7 +29,7 @@ class Edit extends \Magento\Integration\Controller\Adminhtml\Integration
                 $this->_redirect('*/*/');
                 return;
             } catch (\Exception $e) {
-                $this->_logger->logException($e);
+                $this->_logger->critical($e);
                 $this->messageManager->addError(__('Internal error. Check exception log for details.'));
                 $this->_redirect('*/*');
                 return;
diff --git a/app/code/Magento/Integration/Controller/Adminhtml/Integration/PermissionsDialog.php b/app/code/Magento/Integration/Controller/Adminhtml/Integration/PermissionsDialog.php
index 40c30063f95..8169abfebef 100644
--- a/app/code/Magento/Integration/Controller/Adminhtml/Integration/PermissionsDialog.php
+++ b/app/code/Magento/Integration/Controller/Adminhtml/Integration/PermissionsDialog.php
@@ -26,7 +26,7 @@ class PermissionsDialog extends \Magento\Integration\Controller\Adminhtml\Integr
                 $this->_redirect('*/*/');
                 return;
             } catch (\Exception $e) {
-                $this->_logger->logException($e);
+                $this->_logger->critical($e);
                 $this->messageManager->addError(__('Internal error. Check exception log for details.'));
                 $this->_redirect('*/*');
                 return;
diff --git a/app/code/Magento/Integration/Controller/Adminhtml/Integration/Save.php b/app/code/Magento/Integration/Controller/Adminhtml/Integration/Save.php
index 2f580567c2b..309b2b80699 100644
--- a/app/code/Magento/Integration/Controller/Adminhtml/Integration/Save.php
+++ b/app/code/Magento/Integration/Controller/Adminhtml/Integration/Save.php
@@ -46,7 +46,7 @@ class Save extends \Magento\Integration\Controller\Adminhtml\Integration
                     $this->_redirect('*/*/');
                     return;
                 } catch (\Exception $e) {
-                    $this->_logger->logException($e);
+                    $this->_logger->critical($e);
                     $this->messageManager->addError(__('Internal error. Check exception log for details.'));
                     $this->_redirect('*/*');
                     return;
@@ -94,7 +94,7 @@ class Save extends \Magento\Integration\Controller\Adminhtml\Integration
             $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage()));
             $this->_redirectOnSaveError();
         } catch (\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
             $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage()));
             $this->_redirectOnSaveError();
         }
diff --git a/app/code/Magento/Integration/Controller/Adminhtml/Integration/TokensDialog.php b/app/code/Magento/Integration/Controller/Adminhtml/Integration/TokensDialog.php
index 15cd3f85fc9..f8747958f2c 100644
--- a/app/code/Magento/Integration/Controller/Adminhtml/Integration/TokensDialog.php
+++ b/app/code/Magento/Integration/Controller/Adminhtml/Integration/TokensDialog.php
@@ -53,7 +53,7 @@ class TokensDialog extends \Magento\Integration\Controller\Adminhtml\Integration
             $this->_redirect('*/*');
             return;
         } catch (\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
             $this->messageManager->addError(__('Internal error. Check exception log for details.'));
             $this->_redirect('*/*');
             return;
diff --git a/app/code/Magento/Integration/Controller/Adminhtml/Integration/TokensExchange.php b/app/code/Magento/Integration/Controller/Adminhtml/Integration/TokensExchange.php
index 7ddd5e935f1..342b198336c 100644
--- a/app/code/Magento/Integration/Controller/Adminhtml/Integration/TokensExchange.php
+++ b/app/code/Magento/Integration/Controller/Adminhtml/Integration/TokensExchange.php
@@ -64,7 +64,7 @@ class TokensExchange extends \Magento\Integration\Controller\Adminhtml\Integrati
             $this->_redirect('*/*');
             return;
         } catch (\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
             $this->messageManager->addError(__('Internal error. Check exception log for details.'));
             $this->_redirect('*/*');
             return;
diff --git a/app/code/Magento/Integration/Service/V1/AuthorizationService.php b/app/code/Magento/Integration/Service/V1/AuthorizationService.php
index 177ba061c5a..e394eba6f07 100644
--- a/app/code/Magento/Integration/Service/V1/AuthorizationService.php
+++ b/app/code/Magento/Integration/Service/V1/AuthorizationService.php
@@ -101,7 +101,7 @@ class AuthorizationService implements AuthorizationServiceInterface
             }
             $this->_associateResourcesWithRole($role, $resources);
         } catch (\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
             throw new LocalizedException('Error happened while granting permissions. Check exception log for details.');
         }
     }
@@ -122,7 +122,7 @@ class AuthorizationService implements AuthorizationServiceInterface
         try {
             $this->_deleteRole($integrationId);
         } catch (\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
             throw new LocalizedException(
                 'Error happened while deleting role and permissions. Check exception log for details.'
             );
diff --git a/app/code/Magento/Integration/Service/V1/Oauth.php b/app/code/Magento/Integration/Service/V1/Oauth.php
index c3c9e30e9e0..58144ab6b2e 100644
--- a/app/code/Magento/Integration/Service/V1/Oauth.php
+++ b/app/code/Magento/Integration/Service/V1/Oauth.php
@@ -220,7 +220,7 @@ class Oauth implements OauthInterface
         } catch (\Magento\Framework\Oauth\Exception $exception) {
             throw $exception;
         } catch (\Exception $exception) {
-            $this->_logger->logException($exception);
+            $this->_logger->critical($exception);
             throw new \Magento\Framework\Oauth\Exception(
                 'Unable to post data to consumer due to an unexpected error'
             );
diff --git a/app/code/Magento/Log/Model/Visitor.php b/app/code/Magento/Log/Model/Visitor.php
index 079e1dd9775..ea33af37a29 100644
--- a/app/code/Magento/Log/Model/Visitor.php
+++ b/app/code/Magento/Log/Model/Visitor.php
@@ -209,7 +209,7 @@ class Visitor extends \Magento\Framework\Model\AbstractModel
                 $visitor->setData($this->getData());
             }
         } catch (\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
         }
         return $this;
     }
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Overview.php b/app/code/Magento/Multishipping/Controller/Checkout/Overview.php
index a49a02698a2..54d82852748 100644
--- a/app/code/Magento/Multishipping/Controller/Checkout/Overview.php
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Overview.php
@@ -41,7 +41,7 @@ class Overview extends \Magento\Multishipping\Controller\Checkout
             $this->messageManager->addError($e->getMessage());
             $this->_redirect('*/*/billing');
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->messageManager->addException($e, __('We cannot open the overview page.'));
             $this->_redirect('*/*/billing');
         }
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/OverviewPost.php b/app/code/Magento/Multishipping/Controller/Checkout/OverviewPost.php
index 1549d894a76..01b4a42a2a9 100644
--- a/app/code/Magento/Multishipping/Controller/Checkout/OverviewPost.php
+++ b/app/code/Magento/Multishipping/Controller/Checkout/OverviewPost.php
@@ -105,7 +105,7 @@ class OverviewPost extends \Magento\Multishipping\Controller\Checkout
             $this->messageManager->addError($e->getMessage());
             $this->_redirect('*/*/billing');
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->_objectManager->get(
                 'Magento\Checkout\Helper\Data'
             )->sendPaymentFailedEmail(
diff --git a/app/code/Magento/Newsletter/Model/Subscriber.php b/app/code/Magento/Newsletter/Model/Subscriber.php
index c0b2d96137a..1a29809a337 100644
--- a/app/code/Magento/Newsletter/Model/Subscriber.php
+++ b/app/code/Magento/Newsletter/Model/Subscriber.php
@@ -583,7 +583,7 @@ class Subscriber extends \Magento\Framework\Model\AbstractModel
                 }
             } catch (MailException $e) {
                 // If we are not able to send a new account email, this should be ignored
-                $this->_logger->logException($e);
+                $this->_logger->critical($e);
             }
         }
         return $this;
diff --git a/app/code/Magento/OfflineShipping/Model/Resource/Carrier/Tablerate.php b/app/code/Magento/OfflineShipping/Model/Resource/Carrier/Tablerate.php
index 9b019fd194d..3f16e68e1a8 100644
--- a/app/code/Magento/OfflineShipping/Model/Resource/Carrier/Tablerate.php
+++ b/app/code/Magento/OfflineShipping/Model/Resource/Carrier/Tablerate.php
@@ -316,7 +316,7 @@ class Tablerate extends \Magento\Framework\Model\Resource\Db\AbstractDb
         } catch (\Exception $e) {
             $adapter->rollback();
             $stream->close();
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
             throw new \Magento\Framework\Model\Exception(__('Something went wrong while importing table rates.'));
         }
 
diff --git a/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Cancel.php b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Cancel.php
index ae36bdd5b17..297802cab49 100644
--- a/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Cancel.php
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Cancel.php
@@ -26,7 +26,7 @@ class Cancel extends \Magento\Paypal\Controller\Adminhtml\Billing\Agreement
                 $this->messageManager->addError($e->getMessage());
             } catch (\Exception $e) {
                 $this->messageManager->addError(__('We could not cancel the billing agreement.'));
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             }
             $this->_redirect('paypal/*/view', ['_current' => true]);
         }
diff --git a/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Delete.php b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Delete.php
index 3d1989a2162..83abbe75ad5 100644
--- a/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Delete.php
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Delete.php
@@ -26,7 +26,7 @@ class Delete extends \Magento\Paypal\Controller\Adminhtml\Billing\Agreement
                 $this->messageManager->addError($e->getMessage());
             } catch (\Exception $e) {
                 $this->messageManager->addError(__('We could not delete the billing agreement.'));
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             }
             $this->_redirect('paypal/*/view', ['_current' => true]);
         }
diff --git a/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports/Fetch.php b/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports/Fetch.php
index a89d4e5d01f..64f34c264a9 100644
--- a/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports/Fetch.php
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports/Fetch.php
@@ -39,13 +39,13 @@ class Fetch extends \Magento\Paypal\Controller\Adminhtml\Paypal\Reports
                     $this->messageManager->addError(
                         __("We couldn't fetch reports from '%1@%2'.", $config['username'], $config['hostname'])
                     );
-                    $this->_logger->logException($e);
+                    $this->_logger->critical($e);
                 }
             }
         } catch (\Magento\Framework\Model\Exception $e) {
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
         }
         $this->_redirect('*/*/index');
     }
diff --git a/app/code/Magento/Paypal/Controller/Billing/Agreement/Cancel.php b/app/code/Magento/Paypal/Controller/Billing/Agreement/Cancel.php
index 19498688c58..f2e4f00763c 100644
--- a/app/code/Magento/Paypal/Controller/Billing/Agreement/Cancel.php
+++ b/app/code/Magento/Paypal/Controller/Billing/Agreement/Cancel.php
@@ -28,7 +28,7 @@ class Cancel extends \Magento\Paypal\Controller\Billing\Agreement
             } catch (\Magento\Framework\Model\Exception $e) {
                 $this->messageManager->addError($e->getMessage());
             } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
                 $this->messageManager->addError(__('We couldn\'t cancel the billing agreement.'));
             }
         }
diff --git a/app/code/Magento/Paypal/Controller/Billing/Agreement/ReturnWizard.php b/app/code/Magento/Paypal/Controller/Billing/Agreement/ReturnWizard.php
index a5dae10ca8a..6b760dfe907 100644
--- a/app/code/Magento/Paypal/Controller/Billing/Agreement/ReturnWizard.php
+++ b/app/code/Magento/Paypal/Controller/Billing/Agreement/ReturnWizard.php
@@ -38,7 +38,7 @@ class ReturnWizard extends \Magento\Paypal\Controller\Billing\Agreement
             } catch (\Magento\Framework\Model\Exception $e) {
                 $this->messageManager->addError($e->getMessage());
             } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
                 $this->messageManager->addError(__('We couldn\'t finish the billing agreement wizard.'));
             }
             $this->_redirect('*/*/index');
diff --git a/app/code/Magento/Paypal/Controller/Billing/Agreement/StartWizard.php b/app/code/Magento/Paypal/Controller/Billing/Agreement/StartWizard.php
index ed39ccf6763..8a688ea974a 100644
--- a/app/code/Magento/Paypal/Controller/Billing/Agreement/StartWizard.php
+++ b/app/code/Magento/Paypal/Controller/Billing/Agreement/StartWizard.php
@@ -35,7 +35,7 @@ class StartWizard extends \Magento\Paypal\Controller\Billing\Agreement
             } catch (\Magento\Framework\Model\Exception $e) {
                 $this->messageManager->addError($e->getMessage());
             } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
                 $this->messageManager->addError(__('We couldn\'t start the billing agreement wizard.'));
             }
         }
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Cancel.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Cancel.php
index d6ca046590a..2192302b16e 100644
--- a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Cancel.php
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Cancel.php
@@ -36,7 +36,7 @@ class Cancel extends \Magento\Paypal\Controller\Express\AbstractExpress
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('Unable to cancel Express Checkout'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
 
         $this->_redirect('checkout/cart');
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/PlaceOrder.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/PlaceOrder.php
index a7e90705267..6d71fbe17d4 100644
--- a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/PlaceOrder.php
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/PlaceOrder.php
@@ -66,7 +66,7 @@ class PlaceOrder extends \Magento\Paypal\Controller\Express\AbstractExpress
             $this->_redirect('*/*/review');
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t place the order.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->_redirect('*/*/review');
         }
     }
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ReturnAction.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ReturnAction.php
index 1fe28348bb3..0c990b85aff 100644
--- a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ReturnAction.php
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ReturnAction.php
@@ -34,7 +34,7 @@ class ReturnAction extends \Magento\Paypal\Controller\Express\AbstractExpress
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t process Express Checkout approval.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->_redirect('checkout/cart');
     }
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Review.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Review.php
index c12f7ad7486..a86e0f6dd0e 100644
--- a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Review.php
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Review.php
@@ -33,7 +33,7 @@ class Review extends \Magento\Paypal\Controller\Express\AbstractExpress
             $this->messageManager->addError(
                 __('We can\'t initialize Express Checkout review.')
             );
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->_redirect('checkout/cart');
     }
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/SaveShippingMethod.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/SaveShippingMethod.php
index 9d53989cb02..d359572a27f 100644
--- a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/SaveShippingMethod.php
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/SaveShippingMethod.php
@@ -29,7 +29,7 @@ class SaveShippingMethod extends \Magento\Paypal\Controller\Express\AbstractExpr
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t update shipping method.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         if ($isAjax) {
             $this->getResponse()->setBody(
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ShippingOptionsCallback.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ShippingOptionsCallback.php
index 16fd60b6392..a902eb800b2 100644
--- a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ShippingOptionsCallback.php
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ShippingOptionsCallback.php
@@ -61,7 +61,7 @@ class ShippingOptionsCallback extends \Magento\Paypal\Controller\Express\Abstrac
             $response = $this->_checkout->getShippingOptionsCallbackResponse($this->getRequest()->getParams());
             $this->getResponse()->setBody($response);
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
     }
 }
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Start.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Start.php
index a8f2082a896..c7330479e08 100644
--- a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Start.php
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Start.php
@@ -81,7 +81,7 @@ class Start extends \Magento\Paypal\Controller\Express\AbstractExpress
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t start Express Checkout.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
 
         $this->_redirect('checkout/cart');
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/UpdateShippingMethods.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/UpdateShippingMethods.php
index cee6ddc1914..9f2b22b1f4d 100644
--- a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/UpdateShippingMethods.php
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/UpdateShippingMethods.php
@@ -31,7 +31,7 @@ class UpdateShippingMethods extends \Magento\Paypal\Controller\Express\AbstractE
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t update shipping method.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->getResponse()->setBody(
             '<script type="text/javascript">window.location.href = ' . $this->_url->getUrl('*/*/review') . ';</script>'
diff --git a/app/code/Magento/Paypal/Controller/Ipn/Index.php b/app/code/Magento/Paypal/Controller/Ipn/Index.php
index 522a7a6fdea..e8578502350 100644
--- a/app/code/Magento/Paypal/Controller/Ipn/Index.php
+++ b/app/code/Magento/Paypal/Controller/Ipn/Index.php
@@ -53,12 +53,12 @@ class Index extends \Magento\Framework\App\Action\Action
             $data = $this->getRequest()->getPost();
             $this->_ipnFactory->create(['data' => $data])->processIpnRequest();
         } catch (UnavailableException $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
             $this->getResponse()->setHeader('HTTP/1.1', '503 Service Unavailable')->sendResponse();
             /** @todo eliminate usage of exit statement */
             exit;
         } catch (\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
             $this->getResponse()->setHttpResponseCode(500);
         }
     }
diff --git a/app/code/Magento/Paypal/Controller/Payflow/SilentPost.php b/app/code/Magento/Paypal/Controller/Payflow/SilentPost.php
index 3f93bd1e63e..d3e70d96b05 100644
--- a/app/code/Magento/Paypal/Controller/Payflow/SilentPost.php
+++ b/app/code/Magento/Paypal/Controller/Payflow/SilentPost.php
@@ -21,7 +21,7 @@ class SilentPost extends \Magento\Paypal\Controller\Payflow
             try {
                 $paymentModel->process($data);
             } catch (\Exception $e) {
-                $this->_logger->logException($e);
+                $this->_logger->critical($e);
             }
         }
     }
diff --git a/app/code/Magento/Paypal/Model/Api/Nvp.php b/app/code/Magento/Paypal/Model/Api/Nvp.php
index e4b4cd53ddf..05517f84e7a 100644
--- a/app/code/Magento/Paypal/Model/Api/Nvp.php
+++ b/app/code/Magento/Paypal/Model/Api/Nvp.php
@@ -1208,7 +1208,7 @@ class Nvp extends \Magento\Paypal\Model\Api\AbstractApi
 
         // handle transport error
         if ($http->getErrno()) {
-            $this->_logger->logException(
+            $this->_logger->critical(
                 new \Exception(
                     sprintf('PayPal NVP CURL connection error #%s: %s', $http->getErrno(), $http->getError())
                 )
@@ -1222,7 +1222,7 @@ class Nvp extends \Magento\Paypal\Model\Api\AbstractApi
         $http->close();
 
         if (!$this->_validateResponse($methodName, $response)) {
-            $this->_logger->logException(new \Exception(__("PayPal response hasn't required fields.")));
+            $this->_logger->critical(new \Exception(__("PayPal response hasn't required fields.")));
             throw new \Magento\Framework\Model\Exception(__('Something went wrong while processing your order.'));
         }
 
@@ -1283,7 +1283,7 @@ class Nvp extends \Magento\Paypal\Model\Api\AbstractApi
             ) : $this->_frameworkExceptionFactory->create(
                 ['message' => $exceptionLogMessage, 'code' => 0]
             );
-        $this->_logger->logException($exception);
+        $this->_logger->critical($exception);
 
         $exception->setMessage(__('PayPal gateway has rejected request. %1', $errorMessages));
 
diff --git a/app/code/Magento/Paypal/Model/Api/PayflowNvp.php b/app/code/Magento/Paypal/Model/Api/PayflowNvp.php
index c58fd46fdf4..11145aeafbf 100644
--- a/app/code/Magento/Paypal/Model/Api/PayflowNvp.php
+++ b/app/code/Magento/Paypal/Model/Api/PayflowNvp.php
@@ -650,7 +650,7 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp
         if ($response['RESULT'] != self::RESPONSE_CODE_APPROVED) {
             $message = $response['RESPMSG'];
             $e = new \Exception(sprintf('PayPal gateway errors: %s.', $message));
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
             throw new \Magento\Framework\Model\Exception(__('PayPal gateway rejected the request. %1', $message));
         }
     }
diff --git a/app/code/Magento/Paypal/Model/Express/Checkout.php b/app/code/Magento/Paypal/Model/Express/Checkout.php
index f9eff10bbdb..06492302db8 100644
--- a/app/code/Magento/Paypal/Model/Express/Checkout.php
+++ b/app/code/Magento/Paypal/Model/Express/Checkout.php
@@ -391,7 +391,7 @@ class Checkout
                     $this->_configCacheType->save($pal, $cacheId);
                 } catch (\Exception $e) {
                     $this->_configCacheType->save(self::PAL_CACHE_ID, $cacheId);
-                    $this->_logger->logException($e);
+                    $this->_logger->critical($e);
                 }
             }
         }
@@ -815,7 +815,7 @@ class Checkout
             try {
                 $this->_involveNewCustomer();
             } catch (\Exception $e) {
-                $this->_logger->logException($e);
+                $this->_logger->critical($e);
             }
         }
 
diff --git a/app/code/Magento/Paypal/Model/Observer.php b/app/code/Magento/Paypal/Model/Observer.php
index 98b0435f5f2..e68422948a5 100644
--- a/app/code/Magento/Paypal/Model/Observer.php
+++ b/app/code/Magento/Paypal/Model/Observer.php
@@ -111,11 +111,11 @@ class Observer
                 try {
                     $reports->fetchAndSave(\Magento\Paypal\Model\Report\Settlement::createConnection($config));
                 } catch (\Exception $e) {
-                    $this->_logger->logException($e);
+                    $this->_logger->critical($e);
                 }
             }
         } catch (\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
         }
     }
 
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Viewed.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Viewed.php
index 00d5e13925e..1f880f78c78 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Viewed.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Viewed.php
@@ -49,7 +49,7 @@ class Viewed extends \Magento\Reports\Controller\Adminhtml\Report\Product
             $this->messageManager->addError(
                 __('An error occurred while showing the product views report. Please review the log and try again.')
             );
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->_redirect('reports/*/viewed/');
             return;
         }
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshLifetime.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshLifetime.php
index 56ca83847b4..fb2c8545ecc 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshLifetime.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshLifetime.php
@@ -25,7 +25,7 @@ class RefreshLifetime extends \Magento\Reports\Controller\Adminhtml\Report\Stati
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t refresh lifetime statistics.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
 
         if ($this->_getSession()->isFirstPageAfterLogin()) {
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshRecent.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshRecent.php
index c66170a2e78..967006fb2fb 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshRecent.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshRecent.php
@@ -28,7 +28,7 @@ class RefreshRecent extends \Magento\Reports\Controller\Adminhtml\Report\Statist
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t refresh recent statistics.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
 
         if ($this->_getSession()->isFirstPageAfterLogin()) {
diff --git a/app/code/Magento/Reports/Model/Resource/Report/AbstractReport.php b/app/code/Magento/Reports/Model/Resource/Report/AbstractReport.php
index 62b6de167e8..1f9723f1107 100644
--- a/app/code/Magento/Reports/Model/Resource/Report/AbstractReport.php
+++ b/app/code/Magento/Reports/Model/Resource/Report/AbstractReport.php
@@ -451,7 +451,7 @@ abstract class AbstractReport extends \Magento\Framework\Model\Resource\Db\Abstr
                 $nextPeriod = $tr['time'];
             }
         } catch (\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
         }
 
         return $tzTransitions;
diff --git a/app/code/Magento/Review/Controller/Product.php b/app/code/Magento/Review/Controller/Product.php
index 35f6a85f6e8..333d558e746 100644
--- a/app/code/Magento/Review/Controller/Product.php
+++ b/app/code/Magento/Review/Controller/Product.php
@@ -195,7 +195,7 @@ class Product extends \Magento\Framework\App\Action\Action
                 ['product' => $product, 'controller_action' => $this]
             );
         } catch (\Magento\Framework\Model\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
             return false;
         }
 
diff --git a/app/code/Magento/Review/Model/Resource/Rating.php b/app/code/Magento/Review/Model/Resource/Rating.php
index afc92f067d8..535e963d972 100644
--- a/app/code/Magento/Review/Model/Resource/Rating.php
+++ b/app/code/Magento/Review/Model/Resource/Rating.php
@@ -197,7 +197,7 @@ class Rating extends \Magento\Framework\Model\Resource\Db\AbstractDb
                 }
                 $adapter->commit();
             } catch (\Exception $e) {
-                $this->_logger->logException($e);
+                $this->_logger->critical($e);
                 $adapter->rollBack();
             }
         }
@@ -233,7 +233,7 @@ class Rating extends \Magento\Framework\Model\Resource\Db\AbstractDb
 
                 $adapter->commit();
             } catch (\Exception $e) {
-                $this->_logger->logException($e);
+                $this->_logger->critical($e);
                 $adapter->rollBack();
             }
         }
diff --git a/app/code/Magento/Rss/App/Action/Plugin/BackendAuthentication.php b/app/code/Magento/Rss/App/Action/Plugin/BackendAuthentication.php
index b4b901d6673..a217415827c 100644
--- a/app/code/Magento/Rss/App/Action/Plugin/BackendAuthentication.php
+++ b/app/code/Magento/Rss/App/Action/Plugin/BackendAuthentication.php
@@ -93,7 +93,7 @@ class BackendAuthentication extends \Magento\Backend\App\Action\Plugin\Authentic
             try {
                 $this->_auth->login($login, $password);
             } catch (\Magento\Backend\Model\Auth\Exception $e) {
-                $this->logger->logException($e);
+                $this->logger->critical($e);
             }
         }
 
diff --git a/app/code/Magento/Rss/Controller/Feed.php b/app/code/Magento/Rss/Controller/Feed.php
index 889bbd05af3..84fd2cd0fd9 100644
--- a/app/code/Magento/Rss/Controller/Feed.php
+++ b/app/code/Magento/Rss/Controller/Feed.php
@@ -86,7 +86,7 @@ class Feed extends \Magento\Framework\App\Action\Action
                 $this->customerSession->setCustomerDataAsLoggedIn($customer);
                 $this->customerSession->regenerateId();
             } catch (\Exception $e) {
-                $this->logger->logException($e);
+                $this->logger->critical($e);
             }
         }
 
diff --git a/app/code/Magento/Rule/Model/Condition/Combine.php b/app/code/Magento/Rule/Model/Condition/Combine.php
index 8e9355a4957..ec15afef65d 100644
--- a/app/code/Magento/Rule/Model/Condition/Combine.php
+++ b/app/code/Magento/Rule/Model/Condition/Combine.php
@@ -215,7 +215,7 @@ class Combine extends AbstractCondition
                     $this->addCondition($condition);
                     $condition->loadArray($conditionArr, $key);
                 } catch (\Exception $e) {
-                    $this->_logger->logException($e);
+                    $this->_logger->critical($e);
                 }
             }
         }
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Cancel.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Cancel.php
index 0218e05f679..489637db0f4 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Cancel.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Cancel.php
@@ -24,7 +24,7 @@ class Cancel extends \Magento\Sales\Controller\Adminhtml\Order
                 $this->messageManager->addError($e->getMessage());
             } catch (\Exception $e) {
                 $this->messageManager->addError(__('You have not canceled the item.'));
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             }
             $this->_redirect('sales/order/view', ['order_id' => $order->getId()]);
         }
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php
index c6aea409518..d7325721c57 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php
@@ -123,7 +123,7 @@ class Save extends \Magento\Backend\App\Action
             $this->messageManager->addError($e->getMessage());
             $this->_getSession()->setFormData($data);
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->messageManager->addError(__('Cannot save the credit memo.'));
         }
         $this->_redirect('sales/*/new', ['_current' => true]);
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Email.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Email.php
index 39c33005acb..9d67b4d466e 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Email.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Email.php
@@ -29,7 +29,7 @@ class Email extends \Magento\Sales\Controller\Adminhtml\Order
                 $this->messageManager->addError($e->getMessage());
             } catch (\Exception $e) {
                 $this->messageManager->addError(__('We couldn\'t send the email order.'));
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             }
             $this->_redirect('sales/order/view', ['order_id' => $order->getId()]);
         }
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php
index 0d6cd7ddf62..061872f8f9c 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php
@@ -188,14 +188,14 @@ class Save extends \Magento\Backend\App\Action
             try {
                 $this->invoiceCommentSender->send($invoice, !empty($data['send_email']), $comment);
             } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
                 $this->messageManager->addError(__('We can\'t send the invoice email.'));
             }
             if ($shipment) {
                 try {
                     $this->shipmentSender->send($shipment, !empty($data['send_email']));
                 } catch (\Exception $e) {
-                    $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                    $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
                     $this->messageManager->addError(__('We can\'t send the shipment.'));
                 }
             }
@@ -206,7 +206,7 @@ class Save extends \Magento\Backend\App\Action
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t save the invoice.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->_redirect('sales/*/new', ['order_id' => $orderId]);
     }
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/ReviewPayment.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/ReviewPayment.php
index 6c7215245cd..5fe6d8e37dd 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/ReviewPayment.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/ReviewPayment.php
@@ -49,7 +49,7 @@ class ReviewPayment extends \Magento\Sales\Controller\Adminhtml\Order
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We couldn\'t update the payment.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->_redirect('sales/order/view', ['order_id' => $order->getId()]);
     }
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/View.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/View.php
index 20ccd84c08b..6ff2b7c428b 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/View.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/View.php
@@ -26,7 +26,7 @@ class View extends \Magento\Sales\Controller\Adminhtml\Order
                 $this->_redirect('sales/order/index');
                 return;
             } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
                 $this->messageManager->addError(__('Exception occurred during order load'));
                 $this->_redirect('sales/order/index');
                 return;
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/VoidPayment.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/VoidPayment.php
index 5a637a1ba47..ae99743a7e4 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/VoidPayment.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/VoidPayment.php
@@ -26,7 +26,7 @@ class VoidPayment extends \Magento\Sales\Controller\Adminhtml\Order
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We couldn\'t void the payment.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->_redirect('sales/*/view', ['order_id' => $order->getId()]);
     }
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Fetch.php b/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Fetch.php
index 0377fcf35b6..4399974ea79 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Fetch.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Fetch.php
@@ -28,7 +28,7 @@ class Fetch extends \Magento\Sales\Controller\Adminhtml\Transactions
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t update the transaction details.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->_redirect('sales/transactions/view', ['_current' => true]);
     }
diff --git a/app/code/Magento/Sales/Model/AbstractNotifier.php b/app/code/Magento/Sales/Model/AbstractNotifier.php
index b6e8e45610a..d25db83eed0 100644
--- a/app/code/Magento/Sales/Model/AbstractNotifier.php
+++ b/app/code/Magento/Sales/Model/AbstractNotifier.php
@@ -67,7 +67,7 @@ abstract class AbstractNotifier extends \Magento\Framework\Model\AbstractModel
                 $historyItem->save();
             }
         } catch (Exception $e) {
-            $this->logger->logException($e);
+            $this->logger->critical($e);
             return false;
         }
         return true;
diff --git a/app/code/Magento/Sales/Model/AdminOrder/Create.php b/app/code/Magento/Sales/Model/AdminOrder/Create.php
index f027b6b36e9..761cb20b95b 100644
--- a/app/code/Magento/Sales/Model/AdminOrder/Create.php
+++ b/app/code/Magento/Sales/Model/AdminOrder/Create.php
@@ -1034,7 +1034,7 @@ class Create extends \Magento\Framework\Object implements \Magento\Checkout\Mode
             $this->recollectCart();
             throw $e;
         } catch (\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
         }
         $this->recollectCart();
 
diff --git a/app/code/Magento/Sales/Model/AdminOrder/EmailSender.php b/app/code/Magento/Sales/Model/AdminOrder/EmailSender.php
index c0c32f00441..b249f7d7d63 100644
--- a/app/code/Magento/Sales/Model/AdminOrder/EmailSender.php
+++ b/app/code/Magento/Sales/Model/AdminOrder/EmailSender.php
@@ -53,7 +53,7 @@ class EmailSender
         try {
             $this->orderSender->send($order);
         } catch (\Magento\Framework\Mail\Exception $exception) {
-            $this->logger->logException($exception);
+            $this->logger->critical($exception);
             $this->messageManager->addWarning(
                 __('You did not email your customer. Please check your email settings.')
             );
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Delete.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Delete.php
index de4dc93a3a8..14fbb20f1ff 100644
--- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Delete.php
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Delete.php
@@ -29,7 +29,7 @@ class Delete extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
                 $this->messageManager->addError(
                     __('An error occurred while deleting the rule. Please review the log and try again.')
                 );
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
                 $this->_redirect('sales_rule/*/edit', ['id' => $this->getRequest()->getParam('id')]);
                 return;
             }
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php
index e2bc24c960c..4a1b23890b2 100644
--- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php
@@ -52,7 +52,7 @@ class Generate extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
                 $result['error'] = __(
                     'Something went wrong while generating coupons. Please review the log and try again.'
                 );
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             }
         }
         $this->getResponse()->representJson(
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php
index 515cfc481f1..f0867046d93 100644
--- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php
@@ -93,7 +93,7 @@ class Save extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
                 $this->messageManager->addError(
                     __('An error occurred while saving the rule data. Please review the log and try again.')
                 );
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
                 $this->_objectManager->get('Magento\Backend\Model\Session')->setPageData($data);
                 $this->_redirect('sales_rule/*/edit', ['id' => $this->getRequest()->getParam('rule_id')]);
                 return;
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/CreateLabel.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/CreateLabel.php
index ac12fa49577..3ea56bc83ab 100644
--- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/CreateLabel.php
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/CreateLabel.php
@@ -64,7 +64,7 @@ class CreateLabel extends \Magento\Backend\App\Action
             $response->setError(true);
             $response->setMessage($e->getMessage());
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $response->setError(true);
             $response->setMessage(__('An error occurred while creating shipping label.'));
         }
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintLabel.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintLabel.php
index f8223143233..453ebde07a0 100644
--- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintLabel.php
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintLabel.php
@@ -95,7 +95,7 @@ class PrintLabel extends \Magento\Backend\App\Action
         } catch (\Magento\Framework\Model\Exception $e) {
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->messageManager->addError(__('An error occurred while creating shipping label.'));
         }
         $this->_redirect(
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php
index 075c04dfff0..006e63beab5 100644
--- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php
@@ -143,7 +143,7 @@ class Save extends \Magento\Backend\App\Action
                 $this->_redirect('*/*/new', ['order_id' => $this->getRequest()->getParam('order_id')]);
             }
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             if ($isNeedCreateLabel) {
                 $responseAjax->setError(true);
                 $responseAjax->setMessage(__('An error occurred while creating shipping label.'));
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Delete.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Delete.php
index 9e3677a44a8..84520950e44 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Delete.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Delete.php
@@ -35,7 +35,7 @@ class Delete extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addException($e, __('We cannot delete the theme.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         /**
          * @todo Temporary solution. Theme module should not know about the existence of editor module.
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCss.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCss.php
index cfe13255364..909a46b10f3 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCss.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCss.php
@@ -43,7 +43,7 @@ class DownloadCss extends \Magento\Theme\Controller\Adminhtml\System\Design\Them
         } catch (\Exception $e) {
             $this->messageManager->addException($e, __('File not found: "%1".', $fileId));
             $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
     }
 }
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCustomCss.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCustomCss.php
index 36dde793b45..5f2158f8381 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCustomCss.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCustomCss.php
@@ -41,7 +41,7 @@ class DownloadCustomCss extends \Magento\Theme\Controller\Adminhtml\System\Desig
         } catch (\Exception $e) {
             $this->messageManager->addException($e, __('We cannot find file'));
             $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
     }
 }
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Edit.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Edit.php
index 86d8996180c..9305e1eb450 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Edit.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Edit.php
@@ -40,7 +40,7 @@ class Edit extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
             $this->_redirect('adminhtml/*/');
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We cannot find the theme.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->_redirect('adminhtml/*/');
         }
     }
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Save.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Save.php
index 3eb7a42afd4..91db9e41116 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Save.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Save.php
@@ -69,7 +69,7 @@ class Save extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
             $redirectBack = true;
         } catch (\Exception $e) {
             $this->messageManager->addError('The theme was not saved');
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $redirectBack ? $this->_redirect(
             'adminhtml/*/edit',
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadCss.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadCss.php
index 6d39f4e303d..14035e57241 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadCss.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadCss.php
@@ -23,7 +23,7 @@ class UploadCss extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
             $result = ['error' => true, 'message' => $e->getMessage()];
         } catch (\Exception $e) {
             $result = ['error' => true, 'message' => __('We cannot upload the CSS file.')];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadJs.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadJs.php
index efa49e8f6d6..9c40d817334 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadJs.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadJs.php
@@ -47,7 +47,7 @@ class UploadJs extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
             $result = ['error' => true, 'message' => $e->getMessage()];
         } catch (\Exception $e) {
             $result = ['error' => true, 'message' => __('We cannot upload the JS file.')];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/NewFolder.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/NewFolder.php
index d02e1326cc6..da8b2b9c47f 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/NewFolder.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/NewFolder.php
@@ -22,7 +22,7 @@ class NewFolder extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwy
             $result = ['error' => true, 'message' => $e->getMessage()];
         } catch (\Exception $e) {
             $result = ['error' => true, 'message' => __('Sorry, there was an unknown error.')];
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/PreviewImage.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/PreviewImage.php
index 2f42a5585d2..c55290767a4 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/PreviewImage.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/PreviewImage.php
@@ -27,7 +27,7 @@ class PreviewImage extends \Magento\Theme\Controller\Adminhtml\System\Design\Wys
                 DirectoryList::MEDIA
             );
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->_redirect('core/index/notFound');
         }
     }
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/TreeJson.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/TreeJson.php
index 1ee9b898053..55dd0f21069 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/TreeJson.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/TreeJson.php
@@ -23,7 +23,7 @@ class TreeJson extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg
                 )
             );
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->getResponse()->representJson(
                 $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode([])
             );
diff --git a/app/code/Magento/Theme/Model/Wysiwyg/Storage.php b/app/code/Magento/Theme/Model/Wysiwyg/Storage.php
index 7b5181a2be0..64b796628bb 100644
--- a/app/code/Magento/Theme/Model/Wysiwyg/Storage.php
+++ b/app/code/Magento/Theme/Model/Wysiwyg/Storage.php
@@ -159,7 +159,7 @@ class Storage
             $image->resize(self::THUMBNAIL_WIDTH, self::THUMBNAIL_HEIGHT);
             $image->save($this->mediaWriteDirectory->getAbsolutePath($thumbnailPath));
         } catch (\Magento\Framework\Filesystem\FilesystemException $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             return false;
         }
 
diff --git a/app/code/Magento/Webapi/Controller/ErrorProcessor.php b/app/code/Magento/Webapi/Controller/ErrorProcessor.php
index d810a58015c..35d44e282e0 100644
--- a/app/code/Magento/Webapi/Controller/ErrorProcessor.php
+++ b/app/code/Magento/Webapi/Controller/ErrorProcessor.php
@@ -134,7 +134,7 @@ class ErrorProcessor
             //if not in Dev mode, make sure the message and code is masked for unanticipated exceptions
             if (!$isDevMode) {
                 /** Log information about actual exception */
-                $reportId = $this->_logException($exception);
+                $reportId = $this->_critical($exception);
                 $message = sprintf(self::INTERNAL_SERVER_ERROR_MSG, $reportId);
                 $code = 0;
             }
@@ -166,7 +166,7 @@ class ErrorProcessor
         if ($this->_appState->getMode() == State::MODE_DEVELOPER || $exception instanceof \Magento\Webapi\Exception) {
             $this->render($exception->getMessage(), $exception->getTraceAsString(), $httpCode);
         } else {
-            $reportId = $this->_logException($exception);
+            $reportId = $this->_critical($exception);
             $this->render(
                 __('Internal Error. Details are available in Magento log file. Report ID: %1', $reportId),
                 'Trace is not available.',
@@ -182,16 +182,16 @@ class ErrorProcessor
      * @param \Exception $exception
      * @return string $reportId
      */
-    protected function _logException(\Exception $exception)
+    protected function _critical(\Exception $exception)
     {
         $exceptionClass = get_class($exception);
         $reportId = uniqid("webapi-");
         $exceptionForLog = new $exceptionClass(
-            /** Trace is added separately by logException. */
+            /** Trace is added separately by critical. */
             "Report ID: {$reportId}; Message: {$exception->getMessage()}",
             $exception->getCode()
         );
-        $this->_logger->logException($exceptionForLog);
+        $this->_logger->critical($exceptionForLog);
         return $reportId;
     }
 
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Save.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Save.php
index f756cb5d2b8..d7fd7dd28cc 100644
--- a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Save.php
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Save.php
@@ -44,7 +44,7 @@ class Save extends \Magento\Widget\Controller\Adminhtml\Widget\Instance
             return;
         } catch (\Exception $exception) {
             $this->messageManager->addError($exception->getMessage());
-            $this->_logger->logException($exception);
+            $this->_logger->critical($exception);
             $this->_redirect('adminhtml/*/edit', ['_current' => true]);
             return;
         }
diff --git a/app/code/Magento/Wishlist/Controller/Index/Add.php b/app/code/Magento/Wishlist/Controller/Index/Add.php
index 93a5a80497f..0be01dfee72 100644
--- a/app/code/Magento/Wishlist/Controller/Index/Add.php
+++ b/app/code/Magento/Wishlist/Controller/Index/Add.php
@@ -127,7 +127,7 @@ class Add extends Action\Action implements IndexInterface
             );
         } catch (\Exception $e) {
             $this->messageManager->addError(__('An error occurred while adding item to wish list.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
 
         $this->_redirect('*', ['wishlist_id' => $wishlist->getId()]);
diff --git a/app/code/Magento/Wishlist/Controller/Index/Configure.php b/app/code/Magento/Wishlist/Controller/Index/Configure.php
index d7539cd2046..0ff51f62b57 100644
--- a/app/code/Magento/Wishlist/Controller/Index/Configure.php
+++ b/app/code/Magento/Wishlist/Controller/Index/Configure.php
@@ -99,7 +99,7 @@ class Configure extends Action\Action implements IndexInterface
             return;
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t configure the product.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
             $this->_redirect('*');
             return;
         }
diff --git a/app/code/Magento/Wishlist/Controller/Index/Update.php b/app/code/Magento/Wishlist/Controller/Index/Update.php
index 3b0e7b58f09..c64ae78ed22 100644
--- a/app/code/Magento/Wishlist/Controller/Index/Update.php
+++ b/app/code/Magento/Wishlist/Controller/Index/Update.php
@@ -94,7 +94,7 @@ class Update extends Action\Action implements IndexInterface
                     try {
                         $item->delete();
                     } catch (\Exception $e) {
-                        $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                        $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
                         $this->messageManager->addError(__('Can\'t delete item from wishlist'));
                     }
                 }
diff --git a/app/code/Magento/Wishlist/Controller/Index/UpdateItemOptions.php b/app/code/Magento/Wishlist/Controller/Index/UpdateItemOptions.php
index cc5893c55da..46057776574 100644
--- a/app/code/Magento/Wishlist/Controller/Index/UpdateItemOptions.php
+++ b/app/code/Magento/Wishlist/Controller/Index/UpdateItemOptions.php
@@ -99,7 +99,7 @@ class UpdateItemOptions extends Action\Action implements IndexInterface
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('An error occurred while updating wish list.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
         }
         $this->_redirect('*/*', ['wishlist_id' => $wishlist->getId()]);
     }
diff --git a/app/code/Magento/Wishlist/Model/ItemCarrier.php b/app/code/Magento/Wishlist/Model/ItemCarrier.php
index 07a014b3ff5..5f843995d11 100644
--- a/app/code/Magento/Wishlist/Model/ItemCarrier.php
+++ b/app/code/Magento/Wishlist/Model/ItemCarrier.php
@@ -145,7 +145,7 @@ class ItemCarrier
                     $cart->getQuote()->deleteItem($cartItem);
                 }
             } catch (\Exception $e) {
-                $this->logger->logException($e);
+                $this->logger->critical($e);
                 $messages[] = __('We cannot add this item to your shopping cart.');
             }
         }
diff --git a/dev/tests/integration/testsuite/Magento/Integration/Service/V1/AuthorizationServiceTest.php b/dev/tests/integration/testsuite/Magento/Integration/Service/V1/AuthorizationServiceTest.php
index 9dfd1848d3d..11217c53e37 100644
--- a/dev/tests/integration/testsuite/Magento/Integration/Service/V1/AuthorizationServiceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Integration/Service/V1/AuthorizationServiceTest.php
@@ -26,7 +26,7 @@ class AuthorizationServiceTest extends \PHPUnit_Framework_TestCase
         parent::setUp();
         $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
         $loggerMock = $this->getMockBuilder('Magento\\Framework\\Logger')->disableOriginalConstructor()->getMock();
-        $loggerMock->expects($this->any())->method('logException')->will($this->returnSelf());
+        $loggerMock->expects($this->any())->method('critical')->will($this->returnSelf());
         $this->_service = $objectManager->create(
             'Magento\Integration\Service\V1\AuthorizationService',
             [
diff --git a/dev/tests/integration/testsuite/Magento/Translation/Model/InlineParserTest.php b/dev/tests/integration/testsuite/Magento/Translation/Model/InlineParserTest.php
index e8e777f10bf..22e3403aa81 100644
--- a/dev/tests/integration/testsuite/Magento/Translation/Model/InlineParserTest.php
+++ b/dev/tests/integration/testsuite/Magento/Translation/Model/InlineParserTest.php
@@ -63,7 +63,7 @@ class InlineParserTest extends \PHPUnit_Framework_TestCase
             $model->delete();
             \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
                 ->get('Magento\Framework\Logger')
-                ->logException($e);
+                ->critical($e);
         }
     }
 
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
index 4ffcca56075..fe7562f1cb1 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
@@ -1927,7 +1927,7 @@ return [
     ['setTablePrefix', 'Magento\Framework\App\Magento\Framework\App\Resource', 'Can be passed through constructor only'],
     ['_debugTimer', 'Magento\Framework\DB\Adapter\Pdo\Mysql', 'Magento\Framework\DB\Logger\LoggerAbstract::startTimer'],
     ['_debugStat', 'Magento\Framework\DB\Adapter\Pdo\Mysql', 'Magento\Framework\DB\Logger\File::logStats'],
-    ['_debugException', 'Magento\Framework\DB\Adapter\Pdo\Mysql', 'Magento\Framework\DB\Logger\File::logException'],
+    ['_debugException', 'Magento\Framework\DB\Adapter\Pdo\Mysql', 'Magento\Framework\DB\Logger\File::critical'],
     ['_debugWriteToFile', 'Magento\Framework\DB\Adapter\Pdo\Mysql', 'Magento\Framework\DB\Logger\File::log'],
     ['applyDataUpdates', 'Magento\Framework\Module\Setup', 'Magento\Framework\Module\DataSetup::applyDataUpdates'],
     ['_installData', 'Magento\Framework\Module\Setup', 'Magento\Framework\Module\DataSetup::_installData'],
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/Dashboard/TunnelTest.php b/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/Dashboard/TunnelTest.php
index c7a5f978517..7c5a367fbfb 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/Dashboard/TunnelTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/Dashboard/TunnelTest.php
@@ -142,8 +142,8 @@ class TunnelTest extends \PHPUnit_Framework_TestCase
             ->method('create')
             ->with('Magento\Framework\HTTP\ZendClient')
             ->will($this->throwException($exceptionMock));
-        $loggerMock = $this->getMock('Magento\Framework\Logger', ['logException'], [], '', false);
-        $loggerMock->expects($this->once())->method('logException')->with($exceptionMock);
+        $loggerMock = $this->getMock('Magento\Framework\Logger', ['critical'], [], '', false);
+        $loggerMock->expects($this->once())->method('critical')->with($exceptionMock);
         $this->_objectManager->expects($this->at(2))
             ->method('get')
             ->with('Magento\Framework\Logger')
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/ConfigTest.php
index 097ab1634eb..e3aa7a064ac 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/ConfigTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/ConfigTest.php
@@ -96,7 +96,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
 
         $this->_logger = $this->getMock(
             'Magento\Framework\Logger',
-            ['addStoreLog', 'log', 'logException'],
+            ['addStoreLog', 'log', 'critical'],
             [],
             '',
             false
@@ -210,7 +210,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
 
     public function testGetMenuGenericExceptionIsNotLogged()
     {
-        $this->_logger->expects($this->never())->method('logException');
+        $this->_logger->expects($this->never())->method('critical');
 
         $this->_menuBuilderMock->expects(
             $this->exactly(1)
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/Director/DirectorTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/Director/DirectorTest.php
index 5a459132fa4..35235a674e1 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/Director/DirectorTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/Director/DirectorTest.php
@@ -40,7 +40,7 @@ class DirectorTest extends \PHPUnit_Framework_TestCase
         $this->_builderMock = $this->getMock('Magento\Backend\Model\Menu\Builder', [], [], '', false);
         $this->_logger = $this->getMock(
             'Magento\Framework\Logger',
-            ['addStoreLog', 'log', 'logException'],
+            ['addStoreLog', 'log', 'critical'],
             [],
             '',
             false
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/BuilderTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/BuilderTest.php
index 06f8d57b4c9..aea23a0b5ca 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/BuilderTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/BuilderTest.php
@@ -179,7 +179,7 @@ class BuilderTest extends \PHPUnit_Framework_TestCase
                 $this->throwException(new \Exception())
             );
         $this->loggerMock->expects($this->once())
-            ->method('logException');
+            ->method('critical');
         $this->productMock->expects($this->once())
             ->method('setAttributeSetId')
             ->with(3)
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Render/FinalPriceBoxTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Render/FinalPriceBoxTest.php
index 610278f691b..f7b481eb9fe 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Render/FinalPriceBoxTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Render/FinalPriceBoxTest.php
@@ -187,7 +187,7 @@ class FinalPriceBoxTest extends \PHPUnit_Framework_TestCase
     public function testRenderMsrpNotRegisteredException()
     {
         $this->logger->expects($this->once())
-            ->method('logException');
+            ->method('critical');
 
         $this->priceInfo->expects($this->once())
             ->method('getPrice')
diff --git a/dev/tests/unit/testsuite/Magento/Core/Model/File/Storage/Directory/DatabaseTest.php b/dev/tests/unit/testsuite/Magento/Core/Model/File/Storage/Directory/DatabaseTest.php
index 3e0af8d3cc2..ee220db6174 100644
--- a/dev/tests/unit/testsuite/Magento/Core/Model/File/Storage/Directory/DatabaseTest.php
+++ b/dev/tests/unit/testsuite/Magento/Core/Model/File/Storage/Directory/DatabaseTest.php
@@ -175,7 +175,7 @@ class DatabaseTest extends \PHPUnit_Framework_TestCase
     {
         $this->directoryMock->expects($this->any())->method('getParentId')->will($this->returnValue(null));
 
-        $this->loggerMock->expects($this->any())->method('logException');
+        $this->loggerMock->expects($this->any())->method('critical');
 
         $this->directoryDatabase->importDirectories([]);
     }
diff --git a/dev/tests/unit/testsuite/Magento/Framework/DB/Logger/FileTest.php b/dev/tests/unit/testsuite/Magento/Framework/DB/Logger/FileTest.php
index 63c68452472..e883b622eb3 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/DB/Logger/FileTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/DB/Logger/FileTest.php
@@ -128,7 +128,7 @@ class FileTest extends \PHPUnit_Framework_TestCase
         $this->object->logStats('unknown', 'SELECT something');
     }
 
-    public function testLogException()
+    public function testcritical()
     {
         $exception = new \Exception('error message');
         $expected = "%aEXCEPTION%a'Exception'%a'error message'%a";
@@ -137,6 +137,6 @@ class FileTest extends \PHPUnit_Framework_TestCase
             ->method('write')
             ->with($this->matches($expected));
 
-        $this->object->logException($exception);
+        $this->object->critical($exception);
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Asset/MergedTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Asset/MergedTest.php
index fe0c874a755..f83923b7fe3 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/View/Asset/MergedTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/Asset/MergedTest.php
@@ -48,7 +48,7 @@ class MergedTest extends \PHPUnit_Framework_TestCase
         $this->_assetJsTwo->expects($this->any())->method('getPath')
             ->will($this->returnValue('script_two.js'));
 
-        $this->_logger = $this->getMock('Magento\Framework\Logger', ['logException'], [], '', false);
+        $this->_logger = $this->getMock('Magento\Framework\Logger', ['critical'], [], '', false);
 
         $this->_mergeStrategy = $this->getMock('Magento\Framework\View\Asset\MergeStrategyInterface');
 
@@ -100,7 +100,7 @@ class MergedTest extends \PHPUnit_Framework_TestCase
     public function testIteratorInterfaceMerge()
     {
         $assets = [$this->_assetJsOne, $this->_assetJsTwo];
-        $this->_logger->expects($this->never())->method('logException');
+        $this->_logger->expects($this->never())->method('critical');
         $merged = new \Magento\Framework\View\Asset\Merged(
             $this->_logger,
             $this->_mergeStrategy,
@@ -135,7 +135,7 @@ class MergedTest extends \PHPUnit_Framework_TestCase
             [$this->_assetJsOne, $this->_assetJsTwo, $assetBroken]
         );
 
-        $this->_logger->expects($this->once())->method('logException')->with($this->identicalTo($mergeError));
+        $this->_logger->expects($this->once())->method('critical')->with($this->identicalTo($mergeError));
 
         $expectedResult = [$this->_assetJsOne, $this->_assetJsTwo, $assetBroken];
         $this->_assertIteratorEquals($expectedResult, $merged);
diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Asset/MinifiedTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Asset/MinifiedTest.php
index 47a209618de..c9225cec514 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/View/Asset/MinifiedTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/Asset/MinifiedTest.php
@@ -210,7 +210,7 @@ class MinifiedTest extends \PHPUnit_Framework_TestCase
         $this->_asset->expects($this->once())->method('getContent')->will($this->returnValue('content'));
         $e = new \Exception('test');
         $this->_adapter->expects($this->once())->method('minify')->with('content')->will($this->throwException($e));
-        $this->_logger->expects($this->once())->method('logException');
+        $this->_logger->expects($this->once())->method('critical');
         $this->_staticViewDir->expects($this->never())->method('writeFile');
         $this->_asset->expects($this->once())->method('getFilePath')->will($this->returnValue('file_path'));
         $this->_asset->expects($this->once())->method('getContext')->will($this->returnValue('context'));
diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/RendererTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/RendererTest.php
index bb04603a205..70bfc7346e0 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/RendererTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/RendererTest.php
@@ -316,7 +316,7 @@ class RendererTest extends \PHPUnit_Framework_TestCase
             ->willReturnArgument(0);
 
         $this->loggerMock->expects($this->once())
-            ->method('logException')
+            ->method('critical')
             ->with($exception);
 
         $this->urlBuilderMock->expects($this->once())
diff --git a/dev/tests/unit/testsuite/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAddTest.php b/dev/tests/unit/testsuite/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAddTest.php
index ff679334640..4171f4a6f80 100644
--- a/dev/tests/unit/testsuite/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAddTest.php
+++ b/dev/tests/unit/testsuite/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAddTest.php
@@ -73,7 +73,7 @@ class MassAddTest extends \PHPUnit_Framework_TestCase
         $this->flag->expects($this->once())->method('lock')
             ->will($this->throwException(new \Exception('Test exception')));
 
-        $logger = $this->getMockBuilder('Magento\Framework\Logger')->setMethods(['logException'])
+        $logger = $this->getMockBuilder('Magento\Framework\Logger')->setMethods(['critical'])
             ->disableOriginalConstructor()->getMock();
         $this->controllerArguments['context']->getObjectManager()
             ->expects($this->at(2))->method('get')->with('Magento\Framework\Logger')
diff --git a/dev/tests/unit/testsuite/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/RefreshTest.php b/dev/tests/unit/testsuite/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/RefreshTest.php
index 78c569bed4f..df7ff93455d 100644
--- a/dev/tests/unit/testsuite/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/RefreshTest.php
+++ b/dev/tests/unit/testsuite/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/RefreshTest.php
@@ -67,7 +67,7 @@ class RefreshTest extends \PHPUnit_Framework_TestCase
         $this->flag->expects($this->once())->method('lock')
             ->will($this->throwException(new \Exception('Test exception')));
 
-        $logger = $this->getMockBuilder('Magento\Framework\Logger')->setMethods(['logException'])
+        $logger = $this->getMockBuilder('Magento\Framework\Logger')->setMethods(['critical'])
             ->disableOriginalConstructor()->getMock();
         $this->controllerArguments['context']->getObjectManager()->expects($this->at(1))->method('get')
             ->with('Magento\Framework\Logger')
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/IntegrationTest.php b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/IntegrationTest.php
index 4332d4ce46a..41775ba8193 100644
--- a/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/IntegrationTest.php
+++ b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/IntegrationTest.php
@@ -24,7 +24,7 @@ abstract class IntegrationTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
     protected $_objectManagerMock;
 
-    /** @var \Magento\Backend\Model\Layout\Filter\Acl|\PHPUnit_Framework_MockObject_MockObject */
+    /** @var \Magento\Backend\Model\View\Layout\Filter\Acl|\PHPUnit_Framework_MockObject_MockObject */
     protected $_layoutFilterMock;
 
     /** @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */
@@ -193,7 +193,7 @@ abstract class IntegrationTest extends \PHPUnit_Framework_TestCase
             [$this->getMock('Magento\Framework\Logger', [], [], '', false)]
         );
         $loggerMock = $this->getMockBuilder('Magento\Framework\Logger')->disableOriginalConstructor()->getMock();
-        $loggerMock->expects($this->any())->method('logException')->will($this->returnSelf());
+        $loggerMock->expects($this->any())->method('critical')->will($this->returnSelf());
         $menuMock->expects($this->any())->method('getParentItems')->will($this->returnValue([]));
         $blockMock->expects($this->any())->method('getMenuModel')->will($this->returnValue($menuMock));
         $this->_layoutMock->expects($this->any())->method('getMessagesBlock')->will($this->returnValue($blockMock));
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Helper/Oauth/ConsumerTest.php b/dev/tests/unit/testsuite/Magento/Integration/Helper/Oauth/ConsumerTest.php
index d2d4d092c67..45d3773694e 100644
--- a/dev/tests/unit/testsuite/Magento/Integration/Helper/Oauth/ConsumerTest.php
+++ b/dev/tests/unit/testsuite/Magento/Integration/Helper/Oauth/ConsumerTest.php
@@ -92,7 +92,7 @@ class ConsumerTest extends \PHPUnit_Framework_TestCase
         $this->_loggerMock = $this->getMockBuilder(
             'Magento\Framework\Logger'
         )->disableOriginalConstructor()->setMethods(
-            ['logException']
+            ['critical']
         )->getMock();
 
         $this->_oauthService = new \Magento\Integration\Service\V1\Oauth(
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Controller/Ipn/IndexTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Controller/Ipn/IndexTest.php
index 46c6dbb972f..e4234cca300 100644
--- a/dev/tests/unit/testsuite/Magento/Paypal/Controller/Ipn/IndexTest.php
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Controller/Ipn/IndexTest.php
@@ -41,7 +41,7 @@ class IndexTest extends \PHPUnit_Framework_TestCase
         $this->request->expects($this->once())->method('isPost')->will($this->returnValue(true));
         $exception = new \Exception();
         $this->request->expects($this->once())->method('getPost')->will($this->throwException($exception));
-        $this->logger->expects($this->once())->method('logException')->with($this->identicalTo($exception));
+        $this->logger->expects($this->once())->method('critical')->with($this->identicalTo($exception));
         $this->response->expects($this->once())->method('setHttpResponseCode')->with(500);
         $this->model->execute();
     }
diff --git a/dev/tests/unit/testsuite/Magento/Rule/Model/Condition/CombineTest.php b/dev/tests/unit/testsuite/Magento/Rule/Model/Condition/CombineTest.php
index f33ecb18752..25921b6990c 100644
--- a/dev/tests/unit/testsuite/Magento/Rule/Model/Condition/CombineTest.php
+++ b/dev/tests/unit/testsuite/Magento/Rule/Model/Condition/CombineTest.php
@@ -111,7 +111,7 @@ class CombineTest extends \PHPUnit_Framework_TestCase
             ->willReturn($this->conditionObjectMock);
 
         $this->loggerMock->expects($this->never())
-            ->method('logException');
+            ->method('critical');
 
         $result = $this->combine->loadArray($array);
 
@@ -138,7 +138,7 @@ class CombineTest extends \PHPUnit_Framework_TestCase
             ->willThrowException(new \Exception('everything is fine, it is test'));
 
         $this->loggerMock->expects($this->once())
-            ->method('logException')
+            ->method('critical')
             ->with();
 
         $result = $this->combine->loadArray($array);
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/EmailSenderTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/EmailSenderTest.php
index b8003b302be..4091a20ee0f 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/EmailSenderTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/EmailSenderTest.php
@@ -80,7 +80,7 @@ class EmailSenderTest extends \PHPUnit_Framework_TestCase
         $this->messageManagerMock->expects($this->once())
             ->method('addWarning');
         $this->loggerMock->expects($this->once())
-            ->method('logException');
+            ->method('critical');
 
         $this->assertFalse($this->emailSender->send($this->orderMock));
     }
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/Order/CreditmemoNotifierTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/Order/CreditmemoNotifierTest.php
index 7eb45cfe80f..5be56a6b12a 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Model/Order/CreditmemoNotifierTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/Order/CreditmemoNotifierTest.php
@@ -63,7 +63,7 @@ class CreditmemoNotifierTest extends \PHPUnit_Framework_TestCase
         );
         $this->loggerMock = $this->getMock(
             'Magento\Framework\Logger',
-            ['logException'],
+            ['critical'],
             [],
             '',
             false
@@ -139,7 +139,7 @@ class CreditmemoNotifierTest extends \PHPUnit_Framework_TestCase
             ->with($this->equalTo($this->creditmemo))
             ->will($this->throwException($exception));
         $this->loggerMock->expects($this->once())
-            ->method('logException')
+            ->method('critical')
             ->with($this->equalTo($exception));
         $this->assertFalse($this->notifier->notify($this->creditmemo));
     }
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/Order/InvoiceNotifierTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/Order/InvoiceNotifierTest.php
index b838e43bd80..416f702e22b 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Model/Order/InvoiceNotifierTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/Order/InvoiceNotifierTest.php
@@ -63,7 +63,7 @@ class InvoiceNotifierTest extends \PHPUnit_Framework_TestCase
         );
         $this->loggerMock = $this->getMock(
             'Magento\Framework\Logger',
-            ['logException'],
+            ['critical'],
             [],
             '',
             false
@@ -139,7 +139,7 @@ class InvoiceNotifierTest extends \PHPUnit_Framework_TestCase
             ->with($this->equalTo($this->invoice))
             ->will($this->throwException($exception));
         $this->loggerMock->expects($this->once())
-            ->method('logException')
+            ->method('critical')
             ->with($this->equalTo($exception));
         $this->assertFalse($this->notifier->notify($this->invoice));
     }
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/OrderNotifierTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/OrderNotifierTest.php
index c915ea7ec5c..2478cd0a11f 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Model/OrderNotifierTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/OrderNotifierTest.php
@@ -63,7 +63,7 @@ class OrderNotifierTest extends \PHPUnit_Framework_TestCase
         );
         $this->loggerMock = $this->getMock(
             'Magento\Framework\Logger',
-            ['logException'],
+            ['critical'],
             [],
             '',
             false
@@ -139,7 +139,7 @@ class OrderNotifierTest extends \PHPUnit_Framework_TestCase
             ->with($this->equalTo($this->order))
             ->will($this->throwException($exception));
         $this->loggerMock->expects($this->once())
-            ->method('logException')
+            ->method('critical')
             ->with($this->equalTo($exception));
         $this->assertFalse($this->notifier->notify($this->order));
     }
diff --git a/dev/tests/unit/testsuite/Magento/Shipping/Controller/Adminhtml/Order/Shipment/CreateLabelTest.php b/dev/tests/unit/testsuite/Magento/Shipping/Controller/Adminhtml/Order/Shipment/CreateLabelTest.php
index 4f137b020f6..42b71d2689c 100644
--- a/dev/tests/unit/testsuite/Magento/Shipping/Controller/Adminhtml/Order/Shipment/CreateLabelTest.php
+++ b/dev/tests/unit/testsuite/Magento/Shipping/Controller/Adminhtml/Order/Shipment/CreateLabelTest.php
@@ -201,7 +201,7 @@ class CreateLabelTest extends \PHPUnit_Framework_TestCase
     {
         $logerMock = $this->getMock(
             'Magento\Framework\Logger',
-            ['logException', '__wakeup'],
+            ['critical', '__wakeup'],
             [],
             '',
             false
@@ -215,7 +215,7 @@ class CreateLabelTest extends \PHPUnit_Framework_TestCase
             ->with($this->shipmentMock, $this->requestMock)
             ->will($this->returnValue(true));
         $this->shipmentMock->expects($this->once())->method('save')->will($this->throwException(new \Exception()));
-        $logerMock->expects($this->once())->method('logException');
+        $logerMock->expects($this->once())->method('critical');
         $this->objectManagerMock->expects($this->once())
             ->method('get')
             ->with('Magento\Framework\Logger')
diff --git a/dev/tests/unit/testsuite/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintLabelTest.php b/dev/tests/unit/testsuite/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintLabelTest.php
index 87df1bed2da..866d56eafe8 100644
--- a/dev/tests/unit/testsuite/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintLabelTest.php
+++ b/dev/tests/unit/testsuite/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintLabelTest.php
@@ -303,7 +303,7 @@ class PrintLabelTest extends \PHPUnit_Framework_TestCase
 
         $loggerMock = $this->getMock(
             'Magento\Framework\Logger',
-            ['logException'],
+            ['critical'],
             [],
             '',
             false
@@ -335,7 +335,7 @@ class PrintLabelTest extends \PHPUnit_Framework_TestCase
             ->with('Magento\Framework\Logger')
             ->will($this->returnValue($loggerMock));
         $loggerMock->expects($this->once())
-            ->method('logException');
+            ->method('critical');
         $this->requestMock->expects($this->at(4))
             ->method('getParam')
             ->with('shipment_id')
diff --git a/dev/tests/unit/testsuite/Magento/Shipping/Model/ShipmentNotifierTest.php b/dev/tests/unit/testsuite/Magento/Shipping/Model/ShipmentNotifierTest.php
index c37df83ef19..70b25e84321 100644
--- a/dev/tests/unit/testsuite/Magento/Shipping/Model/ShipmentNotifierTest.php
+++ b/dev/tests/unit/testsuite/Magento/Shipping/Model/ShipmentNotifierTest.php
@@ -63,7 +63,7 @@ class ShipmentNotifierTest extends \PHPUnit_Framework_TestCase
         );
         $this->loggerMock = $this->getMock(
             'Magento\Framework\Logger',
-            ['logException'],
+            ['critical'],
             [],
             '',
             false
@@ -139,7 +139,7 @@ class ShipmentNotifierTest extends \PHPUnit_Framework_TestCase
             ->with($this->equalTo($this->shipment))
             ->will($this->throwException($exception));
         $this->loggerMock->expects($this->once())
-            ->method('logException')
+            ->method('critical')
             ->with($this->equalTo($exception));
         $this->assertFalse($this->notifier->notify($this->shipment));
     }
diff --git a/dev/tests/unit/testsuite/Magento/Webapi/Controller/ErrorProcessorTest.php b/dev/tests/unit/testsuite/Magento/Webapi/Controller/ErrorProcessorTest.php
index 1411c2fc83e..0fe8d442a1c 100644
--- a/dev/tests/unit/testsuite/Magento/Webapi/Controller/ErrorProcessorTest.php
+++ b/dev/tests/unit/testsuite/Magento/Webapi/Controller/ErrorProcessorTest.php
@@ -198,7 +198,7 @@ class ErrorProcessorTest extends \PHPUnit_Framework_TestCase
     public function testMaskException($exception, $expectedHttpCode, $expectedMessage, $expectedDetails)
     {
         /** Assert that exception was logged. */
-        // TODO:MAGETWO-21077 $this->_loggerMock->expects($this->once())->method('logException');
+        // TODO:MAGETWO-21077 $this->_loggerMock->expects($this->once())->method('critical');
         $maskedException = $this->_errorProcessor->maskException($exception);
         $this->assertMaskedException(
             $maskedException,
diff --git a/lib/internal/Magento/Framework/App/Area.php b/lib/internal/Magento/Framework/App/Area.php
index f37822b1b23..07f24f415f3 100644
--- a/lib/internal/Magento/Framework/App/Area.php
+++ b/lib/internal/Magento/Framework/App/Area.php
@@ -167,7 +167,7 @@ class Area implements \Magento\Framework\App\AreaInterface
                 return true;
             }
         } catch (\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
         }
         return false;
     }
diff --git a/lib/internal/Magento/Framework/App/Bootstrap.php b/lib/internal/Magento/Framework/App/Bootstrap.php
index e271ecb3120..07666344ff8 100644
--- a/lib/internal/Magento/Framework/App/Bootstrap.php
+++ b/lib/internal/Magento/Framework/App/Bootstrap.php
@@ -410,7 +410,7 @@ class Bootstrap
                 if (!$this->objectManager) {
                     throw new \DomainException();
                 }
-                $this->objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->objectManager->get('Magento\Framework\Logger')->critical($e);
             } catch (\Exception $e) {
                 $message .= "Could not write error message to log. Please use developer mode to see the message.\n";
             }
diff --git a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
index 6f5b30cc40c..b63ca6b8f22 100644
--- a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
+++ b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
@@ -444,7 +444,7 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
 
                 if (!$retry) {
                     $this->logger->logStats(LoggerInterface::TYPE_QUERY, $sql, $bind);
-                    $this->logger->logException($e);
+                    $this->logger->critical($e);
                     throw $e;
                 }
             }
diff --git a/lib/internal/Magento/Framework/DB/Logger/File.php b/lib/internal/Magento/Framework/DB/Logger/File.php
index 70ac5f4064a..f658077b376 100644
--- a/lib/internal/Magento/Framework/DB/Logger/File.php
+++ b/lib/internal/Magento/Framework/DB/Logger/File.php
@@ -72,7 +72,7 @@ class File extends LoggerAbstract
     /**
      * {@inheritdoc}
      */
-    public function logException(\Exception $e)
+    public function critical(\Exception $e)
     {
         $this->log("EXCEPTION \n$e\n\n");
     }
diff --git a/lib/internal/Magento/Framework/DB/Logger/Null.php b/lib/internal/Magento/Framework/DB/Logger/Null.php
index 7b7dfbb1a79..8aafe5118ca 100644
--- a/lib/internal/Magento/Framework/DB/Logger/Null.php
+++ b/lib/internal/Magento/Framework/DB/Logger/Null.php
@@ -23,7 +23,7 @@ class Null implements \Magento\Framework\DB\LoggerInterface
     /**
      * {@inheritdoc}
      */
-    public function logException(\Exception $e)
+    public function critical(\Exception $e)
     {
     }
 
diff --git a/lib/internal/Magento/Framework/DB/LoggerInterface.php b/lib/internal/Magento/Framework/DB/LoggerInterface.php
index e937704ac26..28b39bc1342 100644
--- a/lib/internal/Magento/Framework/DB/LoggerInterface.php
+++ b/lib/internal/Magento/Framework/DB/LoggerInterface.php
@@ -43,5 +43,5 @@ interface LoggerInterface
      * @param \Exception $e
      * @return void
      */
-    public function logException(\Exception $e);
+    public function critical(\Exception $e);
 }
diff --git a/lib/internal/Magento/Framework/Less/PreProcessor/ErrorHandler.php b/lib/internal/Magento/Framework/Less/PreProcessor/ErrorHandler.php
index 58332f1ef3d..1096ec6a7f7 100644
--- a/lib/internal/Magento/Framework/Less/PreProcessor/ErrorHandler.php
+++ b/lib/internal/Magento/Framework/Less/PreProcessor/ErrorHandler.php
@@ -27,6 +27,6 @@ class ErrorHandler implements ErrorHandlerInterface
      */
     public function processException(\Exception $e)
     {
-        $this->logger->logException($e);
+        $this->logger->critical($e);
     }
 }
diff --git a/lib/internal/Magento/Framework/Logger.php b/lib/internal/Magento/Framework/Logger.php
index b2e848502ea..c7b70b92393 100644
--- a/lib/internal/Magento/Framework/Logger.php
+++ b/lib/internal/Magento/Framework/Logger.php
@@ -69,7 +69,7 @@ class Logger
      * @param \Exception $e
      * @return void
      */
-    public function logException(\Exception $e)
+    public function critical(\Exception $e)
     {
         $this->log("\n" . $e->__toString(), \Zend_Log::ERR);
     }
diff --git a/lib/internal/Magento/Framework/View/Asset/Merged.php b/lib/internal/Magento/Framework/View/Asset/Merged.php
index c91500992fb..4da09f0e3d2 100644
--- a/lib/internal/Magento/Framework/View/Asset/Merged.php
+++ b/lib/internal/Magento/Framework/View/Asset/Merged.php
@@ -91,7 +91,7 @@ class Merged implements \Iterator
                 $this->mergeStrategy->merge($this->assets, $mergedAsset);
                 $this->assets = [$mergedAsset];
             } catch (\Exception $e) {
-                $this->logger->logException($e);
+                $this->logger->critical($e);
             }
         }
     }
diff --git a/lib/internal/Magento/Framework/View/Asset/Minified.php b/lib/internal/Magento/Framework/View/Asset/Minified.php
index adc98daa17d..6ad6c6f151d 100644
--- a/lib/internal/Magento/Framework/View/Asset/Minified.php
+++ b/lib/internal/Magento/Framework/View/Asset/Minified.php
@@ -223,7 +223,7 @@ class Minified implements MergeableInterface
             try {
                 $this->fillPropertiesByMinifyingAsset();
             } catch (\Exception $e) {
-                $this->logger->logException(
+                $this->logger->critical(
                     new \Magento\Framework\Exception(
                         'Could not minify file: ' . $this->originalAsset->getSourceFile(),
                         0,
diff --git a/lib/internal/Magento/Framework/View/Design/Theme/Image.php b/lib/internal/Magento/Framework/View/Design/Theme/Image.php
index 1c4f224706f..4dcad824f2f 100644
--- a/lib/internal/Magento/Framework/View/Design/Theme/Image.php
+++ b/lib/internal/Magento/Framework/View/Design/Theme/Image.php
@@ -158,7 +158,7 @@ class Image
             $this->theme->setPreviewImage($destinationFileName);
         } catch (\Magento\Framework\Filesystem\FilesystemException $e) {
             $this->theme->setPreviewImage(null);
-            $this->logger->logException($e);
+            $this->logger->critical($e);
         }
         return $isCopied;
     }
diff --git a/lib/internal/Magento/Framework/View/Element/AbstractBlock.php b/lib/internal/Magento/Framework/View/Element/AbstractBlock.php
index c270bbd52af..77eaa40ec95 100644
--- a/lib/internal/Magento/Framework/View/Element/AbstractBlock.php
+++ b/lib/internal/Magento/Framework/View/Element/AbstractBlock.php
@@ -743,7 +743,7 @@ abstract class AbstractBlock extends \Magento\Framework\Object implements BlockI
             $params = array_merge(['_secure' => $this->getRequest()->isSecure()], $params);
             return $this->_assetRepo->getUrlWithParams($fileId, $params);
         } catch (\Magento\Framework\Exception $e) {
-            $this->_logger->logException($e);
+            $this->_logger->critical($e);
             return $this->_getNotFoundUrl();
         }
     }
diff --git a/lib/internal/Magento/Framework/View/Page/Config/Renderer.php b/lib/internal/Magento/Framework/View/Page/Config/Renderer.php
index 44d388ed1aa..9bec2a0bd36 100644
--- a/lib/internal/Magento/Framework/View/Page/Config/Renderer.php
+++ b/lib/internal/Magento/Framework/View/Page/Config/Renderer.php
@@ -339,7 +339,7 @@ class Renderer
                 $result .= sprintf($template, $asset->getUrl());
             }
         } catch (\Magento\Framework\Exception $e) {
-            $this->logger->logException($e);
+            $this->logger->critical($e);
             $result .= sprintf($template, $this->urlBuilder->getUrl('', ['_direct' => 'core/index/notFound']));
         }
         return $result;
diff --git a/lib/internal/Magento/Framework/View/Result/Page.php b/lib/internal/Magento/Framework/View/Result/Page.php
index c5435e9c4ce..e45eee4157f 100644
--- a/lib/internal/Magento/Framework/View/Result/Page.php
+++ b/lib/internal/Magento/Framework/View/Result/Page.php
@@ -327,7 +327,7 @@ class Page extends Layout
             $params = array_merge(['_secure' => $this->request->isSecure()], $params);
             return $this->assetRepo->getUrlWithParams($fileId, $params);
         } catch (\Magento\Framework\Exception $e) {
-            $this->logger->logException($e);
+            $this->logger->critical($e);
             return $this->urlBuilder->getUrl('', ['_direct' => 'core/index/notFound']);
         }
     }
-- 
GitLab


From e4fcf91831bbbcc94c414171b0c8b9d7a88b6c9d Mon Sep 17 00:00:00 2001
From: agurzhyi <agurzhyi@ebay.com>
Date: Thu, 18 Dec 2014 15:11:28 +0200
Subject: [PATCH 05/71] MAGETWO-31784: Tax class drop-down on New Customer
 Group page should not contain value 'none'

---
 .../Block/Adminhtml/Group/Edit/Form.php       |   2 +-
 .../Tax/Model/TaxClass/Source/Customer.php    |  19 +-
 .../Model/TaxClass/Source/CustomerTest.php    |   2 +-
 .../Model/TaxClass/Source/CustomerTest.php    | 177 ++++++++++++++++++
 4 files changed, 187 insertions(+), 13 deletions(-)
 create mode 100644 dev/tests/unit/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php

diff --git a/app/code/Magento/Customer/Block/Adminhtml/Group/Edit/Form.php b/app/code/Magento/Customer/Block/Adminhtml/Group/Edit/Form.php
index fbc41f25069..6c67a1f555e 100644
--- a/app/code/Magento/Customer/Block/Adminhtml/Group/Edit/Form.php
+++ b/app/code/Magento/Customer/Block/Adminhtml/Group/Edit/Form.php
@@ -115,7 +115,7 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
                 'title' => __('Tax Class'),
                 'class' => 'required-entry',
                 'required' => true,
-                'values' => $this->_taxCustomer->toOptionArray(true),
+                'values' => $this->_taxCustomer->toOptionArray(),
             ]
         );
 
diff --git a/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php b/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php
index 6d97a822c55..fecd324706d 100644
--- a/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php
+++ b/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php
@@ -48,12 +48,12 @@ class Customer extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
     /**
      * Retrieve all customer tax classes as an options array.
      *
-     * @param bool $withEmpty
      * @return array
      */
-    public function getAllOptions($withEmpty = true)
+    public function getAllOptions()
     {
-        if (!$this->_options) {
+        if (empty($this->_options)) {
+            $options = [];
             $filter = $this->filterBuilder
                 ->setField(TaxClass::KEY_TYPE)
                 ->setValue(TaxClassManagementInterface::TYPE_CUSTOMER)
@@ -61,20 +61,17 @@ class Customer extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
             $searchCriteria = $this->searchCriteriaBuilder->addFilter([$filter])->create();
             $searchResults = $this->taxClassRepository->getList($searchCriteria);
             foreach ($searchResults->getItems() as $taxClass) {
-                $this->_options[] = [
+                $options[] = [
                     'value' => $taxClass->getClassId(),
                     'label' => $taxClass->getClassName(),
                 ];
             }
-        }
-
-        if ($withEmpty) {
-            if (!$this->_options) {
-                return [['value' => '0', 'label' => __('None')]];
-            } else {
-                return array_merge([['value' => '0', 'label' => __('None')]], $this->_options);
+            if (empty($options)) {
+                $options = [['value' => '0', 'label' => __('None')]];
             }
+            $this->_options = $options;
         }
+
         return $this->_options;
     }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php
index 94bcf24352b..aca4b4b4c59 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php
@@ -27,7 +27,7 @@ class CustomerTest extends \PHPUnit_Framework_TestCase
         $source = Bootstrap::getObjectManager()->get('Magento\Tax\Model\TaxClass\Source\Customer');
         $this->assertEquals(
             $expectedResult,
-            $source->getAllOptions(false),
+            $source->getAllOptions(),
             'Tax Class options are invalid.'
         );
     }
diff --git a/dev/tests/unit/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php b/dev/tests/unit/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php
new file mode 100644
index 00000000000..182c1ddb283
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php
@@ -0,0 +1,177 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Tax\Model\TaxClass\Source;
+
+use Magento\TestFramework\Helper\ObjectManager;
+
+class CustomerTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Tax\Api\TaxClassRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $taxClassRepositoryMock;
+
+    /**
+     * @var \Magento\Framework\Api\SearchCriteriaBuilder|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $searchCriteriaBuilderMock;
+
+    /**
+     * @var \Magento\Framework\Api\FilterBuilder|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $filterBuilderMock;
+
+    /**
+     * @var \Magento\Tax\Model\TaxClass\Source\Customer
+     */
+    protected $customer;
+
+    /**
+     * @var ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * Set up
+     *
+     * @return void
+     */
+    protected function setUp()
+    {
+        $this->objectManager = new ObjectManager($this);
+
+        $this->taxClassRepositoryMock = $this->getMockForAbstractClass(
+            'Magento\Tax\Api\TaxClassRepositoryInterface',
+            ['getList'],
+            '',
+            false,
+            true,
+            true,
+            []
+        );
+        $this->searchCriteriaBuilderMock = $this->getMock(
+            'Magento\Framework\Api\SearchCriteriaBuilder',
+            ['addFilter', 'create'],
+            [],
+            '',
+            false
+        );
+        $this->filterBuilderMock = $this->getMock(
+            'Magento\Framework\Api\FilterBuilder',
+            ['setField', 'setValue', 'create'],
+            [],
+            '',
+            false
+        );
+
+        $this->customer = $this->objectManager->getObject(
+            'Magento\Tax\Model\TaxClass\Source\Customer',
+            [
+                'taxClassRepository' => $this->taxClassRepositoryMock,
+                'searchCriteriaBuilder' => $this->searchCriteriaBuilderMock,
+                'filterBuilder' => $this->filterBuilderMock
+            ]
+        );
+    }
+
+    /**
+     * Run test getAllOptions method
+     *
+     * @param bool $isEmpty
+     * @param array $expected
+     * @dataProvider dataProviderGetAllOptions
+     */
+    public function testGetAllOptions($isEmpty, array $expected)
+    {
+        $filterMock = $this->getMock(
+            'Magento\Framework\Api\Filter',
+            [],
+            [],
+            '',
+            false
+        );
+        $searchCriteriaMock = $this->getMock(
+            'Magento\Framework\Api\SearchCriteria',
+            [],
+            [],
+            '',
+            false
+        );
+        $searchResultsMock = $this->getMockForAbstractClass(
+            'Magento\Tax\Api\Data\TaxClassSearchResultsInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['getItems']
+        );
+        $taxClassMock = $this->getMockForAbstractClass(
+            'Magento\Tax\Api\Data\TaxClassInterface',
+            ['getClassId', 'getClassName'],
+            '',
+            false,
+            true,
+            true
+        );
+
+        $this->filterBuilderMock->expects($this->once())
+            ->method('setField')
+            ->with(\Magento\Tax\Api\Data\TaxClassInterface::KEY_TYPE)
+            ->willReturnSelf();
+        $this->filterBuilderMock->expects($this->once())
+            ->method('setValue')
+            ->with(\Magento\Tax\Api\TaxClassManagementInterface::TYPE_CUSTOMER)
+            ->willReturnSelf();
+        $this->filterBuilderMock->expects($this->once())
+            ->method('create')
+            ->willReturn($filterMock);
+        $this->searchCriteriaBuilderMock->expects($this->once())
+            ->method('addFilter')
+            ->with([$filterMock])
+            ->willReturnSelf();
+        $this->searchCriteriaBuilderMock->expects($this->once())
+            ->method('create')
+            ->willReturn($searchCriteriaMock);
+        $this->taxClassRepositoryMock->expects($this->once())
+            ->method('getList')
+            ->with($searchCriteriaMock)
+            ->willReturn($searchResultsMock);
+
+        $items = [];
+        if (!$isEmpty) {
+            $taxClassMock->expects($this->once())
+                ->method('getClassId')
+                ->willReturn(10);
+            $taxClassMock->expects($this->once())
+                ->method('getClassName')
+                ->willReturn('class-name');
+            $items = [$taxClassMock];
+        }
+
+        $searchResultsMock->expects($this->once())
+            ->method('getItems')
+            ->willReturn($items);
+
+        // checking of a lack of re-initialization
+        for ($i = 10; --$i;) {
+            $result = $this->customer->getAllOptions();
+            $this->assertEquals($expected, $result);
+        }
+    }
+
+    /**
+     * Data provider for testGetAllOptions
+     *
+     * @return array
+     */
+    public function dataProviderGetAllOptions()
+    {
+        return [
+            ['isEmpty' => false, 'expected' => [['value' => 10, 'label' => 'class-name']]],
+            ['isEmpty' => true, 'expected' => [['value' => '0', 'label' => __('None')]]]
+        ];
+    }
+}
-- 
GitLab


From f2b26d95e9e3274bdb913c7e466df4662bddd076 Mon Sep 17 00:00:00 2001
From: Andriy Nasinnyk <anasinnyk@ebay.com>
Date: Thu, 18 Dec 2014 16:25:18 +0200
Subject: [PATCH 06/71] MAGETWO-13915: PSR-3: common interface for logging
 libraries.

 - renamed log to info
 - renamed logFile to debug
 - renamed logDebug to debug
---
 app/code/Magento/Backend/Model/Menu.php       |   4 +-
 .../Backend/Model/Menu/Director/Director.php  |   2 +-
 app/code/Magento/Backup/Model/Observer.php    |   4 +-
 app/code/Magento/Core/Model/Layout/Merge.php  |   7 +-
 .../Core/Model/Resource/File/Storage/File.php |   4 +-
 app/code/Magento/Dhl/Model/Carrier.php        |   6 +-
 app/code/Magento/Fedex/Model/Carrier.php      |   6 +-
 .../ImportExport/Model/AbstractModel.php      |  41 +-----
 .../Magento/ImportExport/Model/Export.php     |   4 +-
 .../Magento/ImportExport/Model/Import.php     |   4 +-
 .../Model/Carrier/Flatrate.php                |   6 +-
 .../Model/Carrier/Freeshipping.php            |   6 +-
 .../OfflineShipping/Model/Carrier/Pickup.php  |   6 +-
 .../Model/Carrier/Tablerate.php               |   6 +-
 .../Model/Carrier/AbstractCarrier.php         |  18 +--
 .../Model/Carrier/AbstractCarrierOnline.php   |   6 +-
 app/code/Magento/Ups/Model/Carrier.php        |   8 +-
 app/code/Magento/Usps/Model/Carrier.php       |   6 +-
 .../Magento/TestFramework/ErrorLog/Logger.php |  19 +--
 .../Model/Menu/Director/DirectorTest.php      |   4 +-
 .../Magento/Backend/Model/MenuTest.php        |   8 +-
 .../Magento/Core/Model/Layout/MergeTest.php   |  14 +-
 .../Framework/Data/Collection/DbTest.php      |   4 +-
 .../Magento/Framework/Message/ManagerTest.php |  20 ---
 .../Magento/ImportExport/Model/ExportTest.php |   3 +-
 .../Magento/Tools/View/Deployer/LogTest.php   |   2 -
 .../Magento/Framework/Data/Collection/Db.php  |   2 +-
 .../Image/Adapter/AbstractAdapter.php         |   2 +-
 lib/internal/Magento/Framework/Logger.php     |  34 +----
 .../Magento/Framework/Logger/Adapter.php      | 124 ------------------
 .../Magento/Framework/Logger/README.md        |   5 -
 .../Magento/Framework/Message/Manager.php     |   2 +-
 .../Magento/Framework/Module/DataSetup.php    |   4 +-
 .../Framework/View/Element/Template.php       |   2 +-
 .../Framework/View/Layout/Data/Structure.php  |   5 +-
 .../Framework/View/Layout/Generator/Block.php |   2 +-
 .../View/Layout/ScheduledStructure/Helper.php |   9 +-
 37 files changed, 85 insertions(+), 324 deletions(-)
 delete mode 100644 lib/internal/Magento/Framework/Logger/Adapter.php
 delete mode 100644 lib/internal/Magento/Framework/Logger/README.md

diff --git a/app/code/Magento/Backend/Model/Menu.php b/app/code/Magento/Backend/Model/Menu.php
index f70c0b69826..2851ae2c338 100644
--- a/app/code/Magento/Backend/Model/Menu.php
+++ b/app/code/Magento/Backend/Model/Menu.php
@@ -60,7 +60,7 @@ class Menu extends \ArrayObject
             $index = intval($index);
             if (!isset($this[$index])) {
                 $this->offsetSet($index, $item);
-                $this->_logger->logDebug(
+                $this->_logger->debug(
                     sprintf('Add of item with id %s was processed', $item->getId()),
                     self::LOGGER_KEY
                 );
@@ -126,7 +126,7 @@ class Menu extends \ArrayObject
             if ($item->getId() == $itemId) {
                 unset($this[$key]);
                 $result = true;
-                $this->_logger->logDebug(
+                $this->_logger->debug(
                     sprintf('Remove on item with id %s was processed', $item->getId()),
                     self::LOGGER_KEY
                 );
diff --git a/app/code/Magento/Backend/Model/Menu/Director/Director.php b/app/code/Magento/Backend/Model/Menu/Director/Director.php
index dc1854a5ddf..763495180bf 100644
--- a/app/code/Magento/Backend/Model/Menu/Director/Director.php
+++ b/app/code/Magento/Backend/Model/Menu/Director/Director.php
@@ -24,7 +24,7 @@ class Director extends \Magento\Backend\Model\Menu\AbstractDirector
     {
         $command = $this->_commandFactory->create($data['type'], ['data' => $data]);
         if (isset($this->_messagePatterns[$data['type']])) {
-            $logger->logDebug(
+            $logger->debug(
                 sprintf($this->_messagePatterns[$data['type']], $command->getId()),
                 \Magento\Backend\Model\Menu::LOGGER_KEY
             );
diff --git a/app/code/Magento/Backup/Model/Observer.php b/app/code/Magento/Backup/Model/Observer.php
index 77d66b929e1..56cf013ebaa 100644
--- a/app/code/Magento/Backup/Model/Observer.php
+++ b/app/code/Magento/Backup/Model/Observer.php
@@ -139,11 +139,11 @@ class Observer
 
             $backupManager->create();
             $message = $this->_backupData->getCreateSuccessMessageByType($type);
-            $this->_logger->log($message);
+            $this->_logger->info($message);
         } catch (\Exception $e) {
             $this->_errors[] = $e->getMessage();
             $this->_errors[] = $e->getTrace();
-            $this->_logger->log($e->getMessage(), \Zend_Log::ERR);
+            $this->_logger->info($e->getMessage());
             $this->_logger->critical($e);
         }
 
diff --git a/app/code/Magento/Core/Model/Layout/Merge.php b/app/code/Magento/Core/Model/Layout/Merge.php
index b703560efd4..b23f5e4b2a3 100644
--- a/app/code/Magento/Core/Model/Layout/Merge.php
+++ b/app/code/Magento/Core/Model/Layout/Merge.php
@@ -436,7 +436,7 @@ class Merge implements \Magento\Framework\View\Layout\ProcessorInterface
                 $messages = $this->_layoutValidator->getMessages();
                 //Add first message to exception
                 $message = reset($messages);
-                $this->_logger->log('Cache file with merged layout: ' . $cacheId . ': ' . $message, \Zend_Log::ERR);
+                $this->_logger->info('Cache file with merged layout: ' . $cacheId . ': ' . $message);
             }
         }
         return $this;
@@ -696,9 +696,8 @@ class Merge implements \Magento\Framework\View\Layout\ProcessorInterface
                 $errors[] = "{$error->message} Line: {$error->line}";
             }
 
-            $this->_logger->log(
-                sprintf("Theme layout update file '%s' is not valid.\n%s", $fileName, implode("\n", $errors)),
-                \Zend_Log::ERR
+            $this->_logger->info(
+                sprintf("Theme layout update file '%s' is not valid.\n%s", $fileName, implode("\n", $errors))
             );
         }
     }
diff --git a/app/code/Magento/Core/Model/Resource/File/Storage/File.php b/app/code/Magento/Core/Model/Resource/File/Storage/File.php
index c2bb3fadf75..e605745b233 100644
--- a/app/code/Magento/Core/Model/Resource/File/Storage/File.php
+++ b/app/code/Magento/Core/Model/Resource/File/Storage/File.php
@@ -98,7 +98,7 @@ class File
         try {
             $this->_filesystem->getDirectoryWrite(DirectoryList::MEDIA)->create($path);
         } catch (\Exception $e) {
-            $this->_logger->log($e->getMessage());
+            $this->_logger->info($e->getMessage());
             throw new \Magento\Framework\Model\Exception(
                 __('Unable to create directory: %1', DirectoryList::MEDIA . '/' . $path)
             );
@@ -125,7 +125,7 @@ class File
                 return true;
             }
         } catch (\Magento\Framework\Filesystem\FilesystemException $e) {
-            $this->_logger->log($e->getMessage());
+            $this->_logger->info($e->getMessage());
             throw new \Magento\Framework\Model\Exception(__('Unable to save file: %1', $filePath));
         }
 
diff --git a/app/code/Magento/Dhl/Model/Carrier.php b/app/code/Magento/Dhl/Model/Carrier.php
index e5dd061c91d..192050fe5fe 100644
--- a/app/code/Magento/Dhl/Model/Carrier.php
+++ b/app/code/Magento/Dhl/Model/Carrier.php
@@ -184,7 +184,7 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Magento\Framework\Logger $logger
      * @param \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateFactory
      * @param \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
@@ -210,7 +210,7 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Magento\Framework\Logger $logger,
         \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory,
         \Magento\Shipping\Model\Rate\ResultFactory $rateFactory,
         \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
@@ -245,7 +245,7 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin
         parent::__construct(
             $scopeConfig,
             $rateErrorFactory,
-            $logAdapterFactory,
+            $logger,
             $xmlElFactory,
             $rateFactory,
             $rateMethodFactory,
diff --git a/app/code/Magento/Fedex/Model/Carrier.php b/app/code/Magento/Fedex/Model/Carrier.php
index 348362a5e74..20930f428c3 100644
--- a/app/code/Magento/Fedex/Model/Carrier.php
+++ b/app/code/Magento/Fedex/Model/Carrier.php
@@ -119,7 +119,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Magento\Framework\Logger $logger
      * @param \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateFactory
      * @param \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
@@ -142,7 +142,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Magento\Framework\Logger $logger,
         \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory,
         \Magento\Shipping\Model\Rate\ResultFactory $rateFactory,
         \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
@@ -165,7 +165,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
         parent::__construct(
             $scopeConfig,
             $rateErrorFactory,
-            $logAdapterFactory,
+            $logger,
             $xmlElFactory,
             $rateFactory,
             $rateMethodFactory,
diff --git a/app/code/Magento/ImportExport/Model/AbstractModel.php b/app/code/Magento/ImportExport/Model/AbstractModel.php
index ca62620295e..9aa76d99cab 100644
--- a/app/code/Magento/ImportExport/Model/AbstractModel.php
+++ b/app/code/Magento/ImportExport/Model/AbstractModel.php
@@ -20,12 +20,6 @@ abstract class AbstractModel extends \Magento\Framework\Object
      */
     protected $_debugMode = false;
 
-    /**
-     * Logger instance
-     * @var \Magento\Framework\Logger\Adapter
-     */
-    protected $_logInstance;
-
     /**
      * Fields that should be replaced in debug with '***'
      *
@@ -50,26 +44,18 @@ abstract class AbstractModel extends \Magento\Framework\Object
      */
     protected $_varDirectory;
 
-    /**
-     * @var \Magento\Framework\Logger\AdapterFactory
-     */
-    protected $_adapterFactory;
-
     /**
      * @param \Magento\Framework\Logger $logger
      * @param \Magento\Framework\Filesystem $filesystem
-     * @param \Magento\Framework\Logger\AdapterFactory $adapterFactory
      * @param array $data
      */
     public function __construct(
         \Magento\Framework\Logger $logger,
         \Magento\Framework\Filesystem $filesystem,
-        \Magento\Framework\Logger\AdapterFactory $adapterFactory,
         array $data = []
     ) {
         $this->_logger = $logger;
         $this->_varDirectory = $filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
-        $this->_adapterFactory = $adapterFactory;
         parent::__construct($data);
     }
 
@@ -87,32 +73,11 @@ abstract class AbstractModel extends \Magento\Framework\Object
         } else {
             $this->_logTrace[] = $debugData;
         }
-        if (!$this->_debugMode) {
-            return $this;
-        }
 
-        if (!$this->_logInstance) {
-            $dirName = date('Y/m/d/');
-            $fileName = join(
-                '_',
-                [
-                    str_replace(':', '-', $this->getRunAt()),
-                    $this->getScheduledOperationId(),
-                    $this->getOperationType(),
-                    $this->getEntity()
-                ]
-            );
-            $path = 'import_export/' . $dirName;
-            $this->_varDirectory->create($path);
-
-            $fileName = $path . $fileName . '.log';
-            $this->_logInstance = $this->_adapterFactory->create(
-                ['fileName' => $this->_varDirectory->getAbsolutePath($fileName)]
-            )->setFilterDataKeys(
-                $this->_debugReplacePrivateDataKeys
-            );
+        if ($this->_debugMode) {
+            $this->_logger->debug($debugData);
         }
-        $this->_logInstance->log($debugData);
+
         return $this;
     }
 
diff --git a/app/code/Magento/ImportExport/Model/Export.php b/app/code/Magento/ImportExport/Model/Export.php
index 44223d9e53d..29f23a022ea 100644
--- a/app/code/Magento/ImportExport/Model/Export.php
+++ b/app/code/Magento/ImportExport/Model/Export.php
@@ -58,7 +58,6 @@ class Export extends \Magento\ImportExport\Model\AbstractModel
     /**
      * @param \Magento\Framework\Logger $logger
      * @param \Magento\Framework\Filesystem $filesystem
-     * @param \Magento\Framework\Logger\AdapterFactory $adapterFactory
      * @param \Magento\ImportExport\Model\Export\ConfigInterface $exportConfig
      * @param \Magento\ImportExport\Model\Export\Entity\Factory $entityFactory
      * @param \Magento\ImportExport\Model\Export\Adapter\Factory $exportAdapterFac
@@ -67,7 +66,6 @@ class Export extends \Magento\ImportExport\Model\AbstractModel
     public function __construct(
         \Magento\Framework\Logger $logger,
         \Magento\Framework\Filesystem $filesystem,
-        \Magento\Framework\Logger\AdapterFactory $adapterFactory,
         \Magento\ImportExport\Model\Export\ConfigInterface $exportConfig,
         \Magento\ImportExport\Model\Export\Entity\Factory $entityFactory,
         \Magento\ImportExport\Model\Export\Adapter\Factory $exportAdapterFac,
@@ -76,7 +74,7 @@ class Export extends \Magento\ImportExport\Model\AbstractModel
         $this->_exportConfig = $exportConfig;
         $this->_entityFactory = $entityFactory;
         $this->_exportAdapterFac = $exportAdapterFac;
-        parent::__construct($logger, $filesystem, $adapterFactory, $data);
+        parent::__construct($logger, $filesystem, $data);
     }
 
     /**
diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php
index 553d4eb3450..88b8226e498 100644
--- a/app/code/Magento/ImportExport/Model/Import.php
+++ b/app/code/Magento/ImportExport/Model/Import.php
@@ -112,7 +112,6 @@ class Import extends \Magento\ImportExport\Model\AbstractModel
     /**
      * @param \Magento\Framework\Logger $logger
      * @param \Magento\Framework\Filesystem $filesystem
-     * @param \Magento\Framework\Logger\AdapterFactory $adapterFactory
      * @param \Magento\ImportExport\Helper\Data $importExportData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $coreConfig
      * @param Import\ConfigInterface $importConfig
@@ -128,7 +127,6 @@ class Import extends \Magento\ImportExport\Model\AbstractModel
     public function __construct(
         \Magento\Framework\Logger $logger,
         \Magento\Framework\Filesystem $filesystem,
-        \Magento\Framework\Logger\AdapterFactory $adapterFactory,
         \Magento\ImportExport\Helper\Data $importExportData,
         \Magento\Framework\App\Config\ScopeConfigInterface $coreConfig,
         \Magento\ImportExport\Model\Import\ConfigInterface $importConfig,
@@ -152,7 +150,7 @@ class Import extends \Magento\ImportExport\Model\AbstractModel
         $this->indexerRegistry = $indexerRegistry;
         $this->_behaviorFactory = $behaviorFactory;
         $this->_filesystem = $filesystem;
-        parent::__construct($logger, $filesystem, $adapterFactory, $data);
+        parent::__construct($logger, $filesystem, $data);
     }
 
     /**
diff --git a/app/code/Magento/OfflineShipping/Model/Carrier/Flatrate.php b/app/code/Magento/OfflineShipping/Model/Carrier/Flatrate.php
index 76e0436d791..b7cb5714f64 100644
--- a/app/code/Magento/OfflineShipping/Model/Carrier/Flatrate.php
+++ b/app/code/Magento/OfflineShipping/Model/Carrier/Flatrate.php
@@ -35,7 +35,7 @@ class Flatrate extends \Magento\Shipping\Model\Carrier\AbstractCarrier implement
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Magento\Framework\Logger $logger
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory
      * @param \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
      * @param array $data
@@ -43,14 +43,14 @@ class Flatrate extends \Magento\Shipping\Model\Carrier\AbstractCarrier implement
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Magento\Framework\Logger $logger,
         \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
         \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
         array $data = []
     ) {
         $this->_rateResultFactory = $rateResultFactory;
         $this->_rateMethodFactory = $rateMethodFactory;
-        parent::__construct($scopeConfig, $rateErrorFactory, $logAdapterFactory, $data);
+        parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
     }
 
     /**
diff --git a/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php b/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php
index 0e9274eb726..3726bb282e3 100644
--- a/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php
+++ b/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php
@@ -36,7 +36,7 @@ class Freeshipping extends \Magento\Shipping\Model\Carrier\AbstractCarrier imple
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Magento\Framework\Logger $logger
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory
      * @param \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
      * @param array $data
@@ -44,14 +44,14 @@ class Freeshipping extends \Magento\Shipping\Model\Carrier\AbstractCarrier imple
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Magento\Framework\Logger $logger,
         \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
         \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
         array $data = []
     ) {
         $this->_rateResultFactory = $rateResultFactory;
         $this->_rateMethodFactory = $rateMethodFactory;
-        parent::__construct($scopeConfig, $rateErrorFactory, $logAdapterFactory, $data);
+        parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
     }
 
     /**
diff --git a/app/code/Magento/OfflineShipping/Model/Carrier/Pickup.php b/app/code/Magento/OfflineShipping/Model/Carrier/Pickup.php
index 16a86670b81..133816020ee 100644
--- a/app/code/Magento/OfflineShipping/Model/Carrier/Pickup.php
+++ b/app/code/Magento/OfflineShipping/Model/Carrier/Pickup.php
@@ -30,7 +30,7 @@ class Pickup extends \Magento\Shipping\Model\Carrier\AbstractCarrier implements
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Magento\Framework\Logger $logger
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory
      * @param \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
      * @param array $data
@@ -38,14 +38,14 @@ class Pickup extends \Magento\Shipping\Model\Carrier\AbstractCarrier implements
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Magento\Framework\Logger $logger,
         \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
         \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
         array $data = []
     ) {
         $this->_rateResultFactory = $rateResultFactory;
         $this->_rateMethodFactory = $rateMethodFactory;
-        parent::__construct($scopeConfig, $rateErrorFactory, $logAdapterFactory, $data);
+        parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
     }
 
     /**
diff --git a/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php b/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php
index 60cb1f3faa3..aa61363567b 100644
--- a/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php
+++ b/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php
@@ -45,7 +45,7 @@ class Tablerate extends \Magento\Shipping\Model\Carrier\AbstractCarrier implemen
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Magento\Framework\Logger $logger
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory
      * @param \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $resultMethodFactory
      * @param \Magento\OfflineShipping\Model\Resource\Carrier\TablerateFactory $tablerateFactory
@@ -54,7 +54,7 @@ class Tablerate extends \Magento\Shipping\Model\Carrier\AbstractCarrier implemen
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Magento\Framework\Logger $logger,
         \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
         \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $resultMethodFactory,
         \Magento\OfflineShipping\Model\Resource\Carrier\TablerateFactory $tablerateFactory,
@@ -63,7 +63,7 @@ class Tablerate extends \Magento\Shipping\Model\Carrier\AbstractCarrier implemen
         $this->_rateResultFactory = $rateResultFactory;
         $this->_resultMethodFactory = $resultMethodFactory;
         $this->_tablerateFactory = $tablerateFactory;
-        parent::__construct($scopeConfig, $rateErrorFactory, $logAdapterFactory, $data);
+        parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
         foreach ($this->getCode('condition_name') as $k => $v) {
             $this->_conditionNames[] = $k;
         }
diff --git a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrier.php b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrier.php
index 4cf071e4aca..7efca7af945 100644
--- a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrier.php
+++ b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrier.php
@@ -86,26 +86,26 @@ abstract class AbstractCarrier extends \Magento\Framework\Object implements Abst
     protected $_rateErrorFactory;
 
     /**
-     * @var \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory
+     * @var \Magento\Framework\Logger
      */
-    protected $_logAdapterFactory;
+    protected $_logger;
 
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Magento\Framework\Logger $logger
      * @param array $data
      */
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Magento\Framework\Logger $logger,
         array $data = []
     ) {
         parent::__construct($data);
         $this->_scopeConfig = $scopeConfig;
         $this->_rateErrorFactory = $rateErrorFactory;
-        $this->_logAdapterFactory = $logAdapterFactory;
+        $this->_logger = $logger;
     }
 
     /**
@@ -568,13 +568,7 @@ abstract class AbstractCarrier extends \Magento\Framework\Object implements Abst
     protected function _debug($debugData)
     {
         if ($this->getDebugFlag()) {
-            $this->_logAdapterFactory->create(
-                ['fileName' => 'shipping_' . $this->getCarrierCode() . '.log']
-            )->setFilterDataKeys(
-                $this->_debugReplacePrivateDataKeys
-            )->log(
-                $debugData
-            );
+            $this->_logger->log($debugData);
         }
     }
 
diff --git a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php
index 7337c2a96e1..061e953250e 100644
--- a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php
+++ b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php
@@ -103,7 +103,7 @@ abstract class AbstractCarrierOnline extends AbstractCarrier
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Magento\Framework\Logger $logger
      * @param \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateFactory
      * @param \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
@@ -122,7 +122,7 @@ abstract class AbstractCarrierOnline extends AbstractCarrier
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Magento\Framework\Logger $logger,
         \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory,
         \Magento\Shipping\Model\Rate\ResultFactory $rateFactory,
         \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
@@ -147,7 +147,7 @@ abstract class AbstractCarrierOnline extends AbstractCarrier
         $this->_currencyFactory = $currencyFactory;
         $this->_directoryData = $directoryData;
         $this->stockRegistry = $stockRegistry;
-        parent::__construct($scopeConfig, $rateErrorFactory, $logAdapterFactory, $data);
+        parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
     }
 
     /**
diff --git a/app/code/Magento/Ups/Model/Carrier.php b/app/code/Magento/Ups/Model/Carrier.php
index 6b72c10d40d..733cefd503f 100644
--- a/app/code/Magento/Ups/Model/Carrier.php
+++ b/app/code/Magento/Ups/Model/Carrier.php
@@ -117,7 +117,7 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Magento\Framework\Logger $logger
      * @param \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateFactory
      * @param \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
@@ -139,7 +139,7 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Magento\Framework\Logger $logger,
         \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory,
         \Magento\Shipping\Model\Rate\ResultFactory $rateFactory,
         \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
@@ -162,7 +162,7 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface
         parent::__construct(
             $scopeConfig,
             $rateErrorFactory,
-            $logAdapterFactory,
+            $logger,
             $xmlElFactory,
             $rateFactory,
             $rateMethodFactory,
@@ -518,7 +518,7 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface
                         $message = __(
                             'Sorry, something went wrong. Please try again or contact us and we\'ll try to help.'
                         );
-                        $this->_logger->log($message . ': ' . $errorTitle);
+                        $this->_logger->info($message . ': ' . $errorTitle);
                         break;
                     case 6:
                         if (in_array($row[3], $allowedMethods)) {
diff --git a/app/code/Magento/Usps/Model/Carrier.php b/app/code/Magento/Usps/Model/Carrier.php
index 14b501c6e31..11e7aa0a4ef 100644
--- a/app/code/Magento/Usps/Model/Carrier.php
+++ b/app/code/Magento/Usps/Model/Carrier.php
@@ -115,7 +115,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Magento\Framework\Logger $logger
      * @param \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateFactory
      * @param \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
@@ -137,7 +137,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Magento\Framework\Logger $logger,
         \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory,
         \Magento\Shipping\Model\Rate\ResultFactory $rateFactory,
         \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
@@ -160,7 +160,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
         parent::__construct(
             $scopeConfig,
             $rateErrorFactory,
-            $logAdapterFactory,
+            $logger,
             $xmlElFactory,
             $rateFactory,
             $rateMethodFactory,
diff --git a/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Logger.php b/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Logger.php
index 31f4202d628..6cef1344d10 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Logger.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Logger.php
@@ -18,13 +18,8 @@ class Logger extends \Magento\Framework\Logger
      */
     protected $minimumErrorLevel;
 
-    /**
-     * @param \Magento\Framework\Filesystem $filesystem
-     * @param string $defaultFile
-     */
-    public function __construct(\Magento\Framework\Filesystem $filesystem, $defaultFile = '')
+    public function __construct()
     {
-        parent::__construct($filesystem, $defaultFile);
         $this->minimumErrorLevel = defined('TESTS_ERROR_LOG_LISTENER_LEVEL') ? TESTS_ERROR_LOG_LISTENER_LEVEL : -1;
     }
 
@@ -46,16 +41,10 @@ class Logger extends \Magento\Framework\Logger
 
     /**
      * @param string $message
-     * @param int $level
+     * @internal param int $level
      */
-    public function log($message, $level = \Zend_Log::DEBUG)
+    public function info($message)
     {
-        if ($level <= $this->minimumErrorLevel) {
-            $this->messages[] = [
-                'level' => $level,
-                'message' => $message,
-            ];
-        }
-        parent::log($message, $level);
+        parent::info($message);
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/Director/DirectorTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/Director/DirectorTest.php
index 35235a674e1..452d3d5071f 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/Director/DirectorTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/Director/DirectorTest.php
@@ -40,7 +40,7 @@ class DirectorTest extends \PHPUnit_Framework_TestCase
         $this->_builderMock = $this->getMock('Magento\Backend\Model\Menu\Builder', [], [], '', false);
         $this->_logger = $this->getMock(
             'Magento\Framework\Logger',
-            ['addStoreLog', 'log', 'critical'],
+            ['debug', 'info', 'critical'],
             [],
             '',
             false
@@ -75,7 +75,7 @@ class DirectorTest extends \PHPUnit_Framework_TestCase
     {
         $config = [['type' => 'update'], ['type' => 'remove'], ['type' => 'added']];
         $this->_builderMock->expects($this->at(2))->method('processCommand')->with($this->_commandMock);
-        $this->_logger->expects($this->at(1))->method('logDebug');
+        $this->_logger->expects($this->at(1))->method('debug');
         $this->_commandMock->expects($this->at(1))->method('getId');
         $this->_model->direct($config, $this->_builderMock, $this->_logger);
     }
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/MenuTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/MenuTest.php
index ade079a7984..3812e291ded 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/MenuTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/MenuTest.php
@@ -32,7 +32,7 @@ class MenuTest extends \PHPUnit_Framework_TestCase
         $this->_items['item3'] = $this->getMock('Magento\Backend\Model\Menu\Item', [], [], '', false);
         $this->_items['item3']->expects($this->any())->method('getId')->will($this->returnValue('item3'));
 
-        $this->_logger = $this->getMock('Magento\Framework\Logger', ['log'], [], '', false);
+        $this->_logger = $this->getMock('Magento\Framework\Logger', ['info'], [], '', false);
 
         $this->_model = new \Magento\Backend\Model\Menu($this->_logger);
     }
@@ -50,7 +50,7 @@ class MenuTest extends \PHPUnit_Framework_TestCase
         $this->_logger->expects(
             $this->once()
         )->method(
-            'log'
+            'info'
         )->with(
             $this->equalTo(sprintf('Add of item with id %s was processed', $this->_items['item1']->getId()))
         );
@@ -207,7 +207,7 @@ class MenuTest extends \PHPUnit_Framework_TestCase
         $this->_logger->expects(
             $this->once()
         )->method(
-            'log'
+            'info'
         )->with(
             $this->equalTo(sprintf('Remove on item with id %s was processed', $this->_items['item1']->getId()))
         );
@@ -335,7 +335,7 @@ class MenuTest extends \PHPUnit_Framework_TestCase
     public function testSerialize()
     {
         $this->assertNotEmpty($this->_model->serialize());
-        $this->_logger->expects($this->once())->method('log');
+        $this->_logger->expects($this->once())->method('info');
         $this->_model->add($this->_items['item1']);
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Core/Model/Layout/MergeTest.php b/dev/tests/unit/testsuite/Magento/Core/Model/Layout/MergeTest.php
index df6071a6b64..e64c7edb5c8 100644
--- a/dev/tests/unit/testsuite/Magento/Core/Model/Layout/MergeTest.php
+++ b/dev/tests/unit/testsuite/Magento/Core/Model/Layout/MergeTest.php
@@ -294,11 +294,8 @@ class MergeTest extends \PHPUnit_Framework_TestCase
     public function testGetFileLayoutUpdatesXml()
     {
         $errorString = "Theme layout update file '" . __DIR__ . "/_files/layout/file_wrong.xml' is not valid.";
-        $this->_logger->expects($this->atLeastOnce())->method('log')
-            ->with(
-                $this->stringStartsWith($errorString),
-                \Zend_Log::ERR
-            );
+        $this->_logger->expects($this->atLeastOnce())->method('info')
+            ->with($this->stringStartsWith($errorString));
 
         $actualXml = $this->_model->getFileLayoutUpdatesXml();
         $this->assertXmlStringEqualsXmlFile(__DIR__ . '/_files/merged.xml', $actualXml->asNiceXml());
@@ -405,11 +402,8 @@ class MergeTest extends \PHPUnit_Framework_TestCase
         $messages = $this->_layoutValidator->getMessages();
 
         // Testing error message is logged with logger
-        $this->_logger->expects($this->once())->method('log')
-            ->with(
-                'Cache file with merged layout: ' . $cacheId . ': ' . array_shift($messages),
-                \Zend_Log::ERR
-            );
+        $this->_logger->expects($this->once())->method('info')
+            ->with('Cache file with merged layout: ' . $cacheId . ': ' . array_shift($messages));
 
         $this->_model->load();
     }
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Data/Collection/DbTest.php b/dev/tests/unit/testsuite/Magento/Framework/Data/Collection/DbTest.php
index 526254a8ddb..a261fa3694d 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Data/Collection/DbTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Data/Collection/DbTest.php
@@ -34,7 +34,7 @@ class DbTest extends \PHPUnit_Framework_TestCase
         $this->entityFactoryMock = $this->getMock(
             'Magento\Core\Model\EntityFactory', ['create'], [], '', false
         );
-        $this->loggerMock = $this->getMock('Magento\Framework\Logger', ['log'], [], '', false);
+        $this->loggerMock = $this->getMock('Magento\Framework\Logger', ['info'], [], '', false);
         $this->collection = new \Magento\Framework\Data\Collection\Db(
             $this->entityFactoryMock,
             $this->loggerMock,
@@ -306,7 +306,7 @@ class DbTest extends \PHPUnit_Framework_TestCase
     public function testPrintLogQueryLogging($logQuery, $logFlag, $expectedCalls)
     {
         $this->collection->setFlag('log_query', $logFlag);
-        $this->loggerMock->expects($this->exactly($expectedCalls))->method('log');
+        $this->loggerMock->expects($this->exactly($expectedCalls))->method('info');
         $this->collection->printLogQuery(false, $logQuery, 'some_query');
     }
 
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Message/ManagerTest.php b/dev/tests/unit/testsuite/Magento/Framework/Message/ManagerTest.php
index 265e3a3197a..32e6638df24 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Message/ManagerTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Message/ManagerTest.php
@@ -29,11 +29,6 @@ class ManagerTest extends \PHPUnit_Framework_TestCase
      */
     protected $session;
 
-    /**
-     * @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $logger;
-
     /**
      * @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
@@ -66,11 +61,6 @@ class ManagerTest extends \PHPUnit_Framework_TestCase
         )->disableOriginalConstructor()->setMethods(
             ['getData', 'setData']
         )->getMock();
-        $this->logger = $this->getMockBuilder(
-            'Magento\Framework\Logger'
-        )->setMethods(
-            ['logFile']
-        )->disableOriginalConstructor()->getMock();
         $this->eventManager = $this->getMockBuilder(
             'Magento\Framework\Event\Manager'
         )->setMethods(
@@ -86,7 +76,6 @@ class ManagerTest extends \PHPUnit_Framework_TestCase
                 'messageFactory' => $this->messageFactory,
                 'session' => $this->session,
                 'eventManager' => $this->eventManager,
-                'logger' => $this->logger
             ]
         );
     }
@@ -201,15 +190,6 @@ class ManagerTest extends \PHPUnit_Framework_TestCase
             $this->returnValue($messageError)
         );
 
-        $this->logger->expects(
-            $this->atLeastOnce()
-        )->method(
-            'logFile'
-        )->with(
-            $this->stringStartsWith($logText),
-            \Zend_Log::DEBUG
-        );
-
         $messageCollection = $this->getMockBuilder(
             'Magento\Framework\Message\Collection'
         )->disableOriginalConstructor()->setMethods(
diff --git a/dev/tests/unit/testsuite/Magento/ImportExport/Model/ExportTest.php b/dev/tests/unit/testsuite/Magento/ImportExport/Model/ExportTest.php
index 582bfb71114..8b0f5e49a1f 100644
--- a/dev/tests/unit/testsuite/Magento/ImportExport/Model/ExportTest.php
+++ b/dev/tests/unit/testsuite/Magento/ImportExport/Model/ExportTest.php
@@ -59,7 +59,6 @@ class ExportTest extends \PHPUnit_Framework_TestCase
 
         $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
         $filesystem = $this->getMock('Magento\Framework\Filesystem', [], [], '', false);
-        $adapterFactory = $this->getMock('Magento\Framework\Logger\AdapterFactory', [], [], '', false);
         $entityFactory = $this->getMock(
             'Magento\ImportExport\Model\Export\Entity\Factory',
             [],
@@ -78,7 +77,7 @@ class ExportTest extends \PHPUnit_Framework_TestCase
         $mockModelExport = $this->getMock(
             'Magento\ImportExport\Model\Export',
             ['getEntityAdapter', '_getEntityAdapter', '_getWriter'],
-            [$logger, $filesystem, $adapterFactory, $this->_exportConfigMock, $entityFactory, $exportAdapterFac]
+            [$logger, $filesystem, $this->_exportConfigMock, $entityFactory, $exportAdapterFac]
         );
         $mockModelExport->expects(
             $this->any()
diff --git a/dev/tests/unit/testsuite/Magento/Tools/View/Deployer/LogTest.php b/dev/tests/unit/testsuite/Magento/Tools/View/Deployer/LogTest.php
index eadc24150ac..b6368b2c889 100644
--- a/dev/tests/unit/testsuite/Magento/Tools/View/Deployer/LogTest.php
+++ b/dev/tests/unit/testsuite/Magento/Tools/View/Deployer/LogTest.php
@@ -5,8 +5,6 @@
 
 namespace Magento\Tools\View\Deployer;
 
-use Magento\Tools\View\Deployer\Log;
-
 class LogTest extends \PHPUnit_Framework_TestCase
 {
     /**
diff --git a/lib/internal/Magento/Framework/Data/Collection/Db.php b/lib/internal/Magento/Framework/Data/Collection/Db.php
index 2d756703476..5694e470cf0 100644
--- a/lib/internal/Magento/Framework/Data/Collection/Db.php
+++ b/lib/internal/Magento/Framework/Data/Collection/Db.php
@@ -709,7 +709,7 @@ class Db extends \Magento\Framework\Data\Collection
      */
     protected function _logQuery($sql)
     {
-        $this->_logger->log(is_null($sql) ? $this->getSelect()->__toString() : $sql);
+        $this->_logger->info(is_null($sql) ? $this->getSelect()->__toString() : $sql);
     }
 
     /**
diff --git a/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php b/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php
index e79cdf57d8a..29883baa622 100644
--- a/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php
+++ b/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php
@@ -675,7 +675,7 @@ abstract class AbstractAdapter implements AdapterInterface
             try {
                 $this->directoryWrite->create($this->directoryWrite->getRelativePath($destination));
             } catch (\Magento\Framework\Filesystem\FilesystemException $e) {
-                $this->logger->log($e->getMessage());
+                $this->logger->info($e->getMessage());
                 throw new \Exception('Unable to write file into directory ' . $destination . '. Access forbidden.');
             }
         }
diff --git a/lib/internal/Magento/Framework/Logger.php b/lib/internal/Magento/Framework/Logger.php
index c7b70b92393..bc9b11ab1a5 100644
--- a/lib/internal/Magento/Framework/Logger.php
+++ b/lib/internal/Magento/Framework/Logger.php
@@ -20,47 +20,25 @@ class Logger
      * Log a message
      *
      * @param string $message
-     * @param int $level
-     * @return void
+     * @internal param int $level
      */
-    public function log($message, $level = \Zend_Log::DEBUG)
+    public function info($message)
     {
         if (is_array($message) || is_object($message)) {
             $message = print_r($message, true);
         }
-        $this->log($message, $level);
-    }
-
-    /**
-     * Log a message in specific file
-     *
-     * @param string $message
-     * @param int $level
-     * @param string $file
-     * @return void
-     */
-    public function logFile($message, $level = \Zend_Log::DEBUG, $file = '')
-    {
-        if (!isset($file)) {
-            $this->log($message, $level);
-        }
-        if (is_array($message) || is_object($message)) {
-            $message = print_r($message, true);
-        }
-        /** @var $logger \Zend_Log */
-        $this->log($message, $level, $file);
+        //$this->log($message, $level);
     }
 
     /**
      * Log a message with "debug" level
      *
      * @param string $message
-     * @param string $loggerKey
      * @return void
      */
-    public function logDebug($message)
+    public function debug($message)
     {
-        $this->log($message, \Zend_Log::DEBUG);
+        $this->info($message);
     }
 
     /**
@@ -71,6 +49,6 @@ class Logger
      */
     public function critical(\Exception $e)
     {
-        $this->log("\n" . $e->__toString(), \Zend_Log::ERR);
+        $this->info("\n" . $e->__toString());
     }
 }
diff --git a/lib/internal/Magento/Framework/Logger/Adapter.php b/lib/internal/Magento/Framework/Logger/Adapter.php
deleted file mode 100644
index 404795cde9b..00000000000
--- a/lib/internal/Magento/Framework/Logger/Adapter.php
+++ /dev/null
@@ -1,124 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- */
-namespace Magento\Framework\Logger;
-
-/**
- * Log Adapter
- */
-class Adapter
-{
-    /**
-     * Log file name
-     *
-     * @var string
-     */
-    protected $_logFileName = '';
-
-    /**
-     * Data to log
-     *
-     * @var array
-     */
-    protected $_data = [];
-
-    /**
-     * Fields that should be replaced in debug data with '***'
-     *
-     * @var array
-     */
-    protected $_debugReplacePrivateDataKeys = [];
-
-    /**
-     * @var \Magento\Framework\Logger
-     */
-    protected $_logger;
-
-    /**
-     * Set log file name
-     *
-     * @param \Magento\Framework\Logger $logger
-     * @param string $fileName
-     */
-    public function __construct(\Magento\Framework\Logger $logger, $fileName)
-    {
-        $this->_logFileName = $fileName;
-        $this->_logger = $logger;
-    }
-
-    /**
-     * Perform forced log data to file
-     *
-     * @param mixed $data
-     * @return $this
-     */
-    public function log($data = null)
-    {
-        if ($data === null) {
-            $data = $this->_data;
-        } else {
-            if (!is_array($data)) {
-                $data = [$data];
-            }
-        }
-        $data = $this->_filterDebugData($data);
-        $data['__pid'] = getmypid();
-        $this->_logger->logFile($data, \Zend_Log::DEBUG, $this->_logFileName);
-        return $this;
-    }
-
-    /**
-     * Log data setter
-     *
-     * @param string|array $key
-     * @param mixed $value
-     * @return $this
-     */
-    public function setData($key, $value = null)
-    {
-        if (is_array($key)) {
-            $this->_data = $key;
-        } else {
-            $this->_data[$key] = $value;
-        }
-        return $this;
-    }
-
-    /**
-     * Setter for private data keys, that should be replaced in debug data with '***'
-     *
-     * @param array $keys
-     * @return $this
-     */
-    public function setFilterDataKeys($keys)
-    {
-        if (!is_array($keys)) {
-            $keys = [$keys];
-        }
-        $this->_debugReplacePrivateDataKeys = $keys;
-        return $this;
-    }
-
-    /**
-     * Recursive filter data by private conventions
-     *
-     * @param mixed $debugData
-     * @return string|array
-     */
-    protected function _filterDebugData($debugData)
-    {
-        if (is_array($debugData) && is_array($this->_debugReplacePrivateDataKeys)) {
-            foreach ($debugData as $key => $value) {
-                if (in_array($key, $this->_debugReplacePrivateDataKeys)) {
-                    $debugData[$key] = '****';
-                } else {
-                    if (is_array($debugData[$key])) {
-                        $debugData[$key] = $this->_filterDebugData($debugData[$key]);
-                    }
-                }
-            }
-        }
-        return $debugData;
-    }
-}
diff --git a/lib/internal/Magento/Framework/Logger/README.md b/lib/internal/Magento/Framework/Logger/README.md
deleted file mode 100644
index 09eb8ee4505..00000000000
--- a/lib/internal/Magento/Framework/Logger/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Logger
-
-**Logger** provides a standard mechanism to log to system and error logs.
-
-* **Adapter** will filter out debug information.
\ No newline at end of file
diff --git a/lib/internal/Magento/Framework/Message/Manager.php b/lib/internal/Magento/Framework/Message/Manager.php
index 9b94a8ec22e..4ea6187585b 100644
--- a/lib/internal/Magento/Framework/Message/Manager.php
+++ b/lib/internal/Magento/Framework/Message/Manager.php
@@ -258,7 +258,7 @@ class Manager implements ManagerInterface
             $exception->getTraceAsString()
         );
 
-        $this->logger->logFile($message, \Zend_Log::DEBUG);
+        $this->logger->debug($message);
         $this->addMessage($this->messageFactory->create(MessageInterface::TYPE_ERROR, $alternativeText), $group);
         return $this;
     }
diff --git a/lib/internal/Magento/Framework/Module/DataSetup.php b/lib/internal/Magento/Framework/Module/DataSetup.php
index 2e2a93ccc93..ab81a996487 100644
--- a/lib/internal/Magento/Framework/Module/DataSetup.php
+++ b/lib/internal/Magento/Framework/Module/DataSetup.php
@@ -223,9 +223,9 @@ class DataSetup extends \Magento\Framework\Module\Setup implements \Magento\Fram
 
                 if ($result) {
                     $this->_resource->setDataVersion($this->_resourceName, $file['toVersion']);
-                    $this->_logger->log($fileName);
+                    $this->_logger->info($fileName);
                 } else {
-                    $this->_logger->log("Failed resource setup: {$fileName}");
+                    $this->_logger->info("Failed resource setup: {$fileName}");
                 }
             } catch (\Exception $e) {
                 throw new \Magento\Framework\Exception(
diff --git a/lib/internal/Magento/Framework/View/Element/Template.php b/lib/internal/Magento/Framework/View/Element/Template.php
index e4cc6b45156..83f9c102cf2 100644
--- a/lib/internal/Magento/Framework/View/Element/Template.php
+++ b/lib/internal/Magento/Framework/View/Element/Template.php
@@ -251,7 +251,7 @@ class Template extends AbstractBlock
             $html = $templateEngine->render($this->templateContext, $fileName, $this->_viewVars);
         } else {
             $html = '';
-            $this->_logger->log("Invalid template file: '{$fileName}'", \Zend_Log::CRIT);
+            $this->_logger->info("Invalid template file: '{$fileName}'");
         }
 
         \Magento\Framework\Profiler::stop('TEMPLATE:' . $fileName);
diff --git a/lib/internal/Magento/Framework/View/Layout/Data/Structure.php b/lib/internal/Magento/Framework/View/Layout/Data/Structure.php
index d9ae103f162..641c7ea5437 100644
--- a/lib/internal/Magento/Framework/View/Layout/Data/Structure.php
+++ b/lib/internal/Magento/Framework/View/Layout/Data/Structure.php
@@ -108,10 +108,9 @@ class Structure extends DataStructure
             if ($childName !== $sibling) {
                 $siblingParentName = $this->getParentId($sibling);
                 if ($parentName !== $siblingParentName) {
-                    $this->logger->log(
+                    $this->logger->info(
                         "Broken reference: the '{$childName}' tries to reorder itself towards '{$sibling}', but " .
-                        "their parents are different: '{$parentName}' and '{$siblingParentName}' respectively.",
-                        \Zend_Log::CRIT
+                        "their parents are different: '{$parentName}' and '{$siblingParentName}' respectively."
                     );
                     return;
                 }
diff --git a/lib/internal/Magento/Framework/View/Layout/Generator/Block.php b/lib/internal/Magento/Framework/View/Layout/Generator/Block.php
index 3e632e331a6..15e7e4b2603 100644
--- a/lib/internal/Magento/Framework/View/Layout/Generator/Block.php
+++ b/lib/internal/Magento/Framework/View/Layout/Generator/Block.php
@@ -172,7 +172,7 @@ class Block implements Layout\GeneratorInterface
             try {
                 $block = $this->blockFactory->createBlock($block, $arguments);
             } catch (\ReflectionException $e) {
-                $this->logger->log($e->getMessage());
+                $this->logger->info($e->getMessage());
             }
         }
         if (!$block instanceof \Magento\Framework\View\Element\AbstractBlock) {
diff --git a/lib/internal/Magento/Framework/View/Layout/ScheduledStructure/Helper.php b/lib/internal/Magento/Framework/View/Layout/ScheduledStructure/Helper.php
index b5b5e512481..0e5a9253b39 100644
--- a/lib/internal/Magento/Framework/View/Layout/ScheduledStructure/Helper.php
+++ b/lib/internal/Magento/Framework/View/Layout/ScheduledStructure/Helper.php
@@ -169,7 +169,7 @@ class Helper
         $data = $scheduledStructure->getStructureElementData($key);
         // if we have reference container to not existed element
         if (!isset($row[self::SCHEDULED_STRUCTURE_INDEX_TYPE])) {
-            $this->logger->log("Broken reference: missing declaration of the element '{$key}'.", \Zend_Log::CRIT);
+            $this->logger->info("Broken reference: missing declaration of the element '{$key}'.");
             $scheduledStructure->unsetPathElement($key);
             $scheduledStructure->unsetStructureElement($key);
             return;
@@ -185,13 +185,12 @@ class Helper
                 try {
                     $structure->setAsChild($name, $parentName, $alias);
                 } catch (\Exception $e) {
-                    $this->logger->log($e->getMessage());
+                    $this->logger->info($e->getMessage());
                 }
             } else {
-                $this->logger->log(
+                $this->logger->info(
                     "Broken reference: the '{$name}' element cannot be added as child to '{$parentName}', " .
-                    'because the latter doesn\'t exist',
-                    \Zend_Log::CRIT
+                    'because the latter doesn\'t exist'
                 );
             }
         }
-- 
GitLab


From c78ad80c74c06b4acd5c8faf7fc46078c79104db Mon Sep 17 00:00:00 2001
From: Andriy Nasinnyk <anasinnyk@ebay.com>
Date: Thu, 18 Dec 2014 16:34:32 +0200
Subject: [PATCH 07/71] MAGETWO-13915: PSR-3: common interface for logging
 libraries.

 - fixed unit tests
---
 app/code/Magento/Fedex/Model/Carrier.php                     | 3 ---
 app/code/Magento/Ups/Model/Carrier.php                       | 3 ---
 dev/tests/unit/testsuite/Magento/Fedex/Model/CarrierTest.php | 3 +--
 3 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/app/code/Magento/Fedex/Model/Carrier.php b/app/code/Magento/Fedex/Model/Carrier.php
index 20930f428c3..74c42bf5476 100644
--- a/app/code/Magento/Fedex/Model/Carrier.php
+++ b/app/code/Magento/Fedex/Model/Carrier.php
@@ -131,7 +131,6 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
      * @param \Magento\Directory\Model\CurrencyFactory $currencyFactory
      * @param \Magento\Directory\Helper\Data $directoryData
      * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry
-     * @param \Magento\Framework\Logger $logger
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\Module\Dir\Reader $configReader
      * @param \Magento\Catalog\Model\Resource\Product\CollectionFactory $productCollectionFactory
@@ -154,7 +153,6 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
         \Magento\Directory\Model\CurrencyFactory $currencyFactory,
         \Magento\Directory\Helper\Data $directoryData,
         \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry,
-        \Magento\Framework\Logger $logger,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\Module\Dir\Reader $configReader,
         \Magento\Catalog\Model\Resource\Product\CollectionFactory $productCollectionFactory,
@@ -183,7 +181,6 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
         $this->_shipServiceWsdl = $wsdlBasePath . 'ShipService_v10.wsdl';
         $this->_rateServiceWsdl = $wsdlBasePath . 'RateService_v10.wsdl';
         $this->_trackServiceWsdl = $wsdlBasePath . 'TrackService_v5.wsdl';
-        $this->_logger = $logger;
     }
 
     /**
diff --git a/app/code/Magento/Ups/Model/Carrier.php b/app/code/Magento/Ups/Model/Carrier.php
index 733cefd503f..91cf8654565 100644
--- a/app/code/Magento/Ups/Model/Carrier.php
+++ b/app/code/Magento/Ups/Model/Carrier.php
@@ -129,7 +129,6 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface
      * @param \Magento\Directory\Model\CurrencyFactory $currencyFactory
      * @param \Magento\Directory\Helper\Data $directoryData
      * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry
-     * @param \Magento\Framework\Logger $logger
      * @param \Magento\Framework\Locale\FormatInterface $localeFormat
      * @param Config $configHelper
      * @param array $data
@@ -151,12 +150,10 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface
         \Magento\Directory\Model\CurrencyFactory $currencyFactory,
         \Magento\Directory\Helper\Data $directoryData,
         \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry,
-        \Magento\Framework\Logger $logger,
         \Magento\Framework\Locale\FormatInterface $localeFormat,
         Config $configHelper,
         array $data = []
     ) {
-        $this->_logger = $logger;
         $this->_localeFormat = $localeFormat;
         $this->configHelper = $configHelper;
         parent::__construct(
diff --git a/dev/tests/unit/testsuite/Magento/Fedex/Model/CarrierTest.php b/dev/tests/unit/testsuite/Magento/Fedex/Model/CarrierTest.php
index 1ed68fb871b..4bb9d7ee7e9 100644
--- a/dev/tests/unit/testsuite/Magento/Fedex/Model/CarrierTest.php
+++ b/dev/tests/unit/testsuite/Magento/Fedex/Model/CarrierTest.php
@@ -77,7 +77,7 @@ class CarrierTest extends \PHPUnit_Framework_TestCase
                 'scopeConfig' => $scopeConfig,
                 'rateErrorFactory' =>
                     $this->getMock('Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory', [], [], '', false),
-                'logAdapterFactory' => $this->getMock('Magento\Framework\Logger\AdapterFactory', [], [], '', false),
+                'logger' => $this->getMock('Magento\Framework\Logger', [], [], '', false),
                 'xmlElFactory' => $this->getMock('Magento\Shipping\Model\Simplexml\ElementFactory', [], [], '', false),
                 'rateFactory' => $rateFactory,
                 'rateMethodFactory' => $rateMethodFactory,
@@ -91,7 +91,6 @@ class CarrierTest extends \PHPUnit_Framework_TestCase
                 'currencyFactory' => $this->getMock('Magento\Directory\Model\CurrencyFactory', [], [], '', false),
                 'directoryData' => $this->getMock('Magento\Directory\Helper\Data', [], [], '', false),
                 'stockRegistry' => $this->getMock('Magento\CatalogInventory\Model\StockRegistry', [], [], '', false),
-                'logger' => $this->getMock('Magento\Framework\Logger', [], [], '', false),
                 'storeManager' => $storeManager,
                 'configReader' => $this->getMock('Magento\Framework\Module\Dir\Reader', [], [], '', false),
                 'productCollectionFactory' =>
-- 
GitLab


From d2391f5945fd4fa210dbf38f015c2950f9398a3f Mon Sep 17 00:00:00 2001
From: Dmytro Aponasenko <daponasenko@ebay.com>
Date: Thu, 18 Dec 2014 18:50:39 +0200
Subject: [PATCH 08/71] MTA-588: Re-factor Test for Advanced Search

---
 .../Test/Fixture/CatalogCategory/ParentId.php |  2 +-
 .../CreateCategoryEntityTest/test.csv         |  4 +-
 .../TestCase/AdvancedSearchEntityTest.php     |  9 +--
 .../AdvancedSearchEntityTest/test.csv         | 27 +++++----
 .../Test/TestCase/AdvancedSearchTest.php      | 49 ---------------
 ...AssertConfigurableProductDuplicateForm.php |  4 ++
 .../testCreateCustomerBackendEntity.csv       |  2 +-
 .../testUpdateCustomerBackendEntity.csv       |  8 +--
 .../testsuites/Mtf/TestSuite/BatCETests.php   | 31 ----------
 .../Mtf/TestSuite/EndToEndCETests.php         | 60 -------------------
 .../Mtf/TestSuite/InjectableTests/bat_ce.xml  | 28 +++++++++
 .../InjectableTests/end_to_end_ce.xml         | 53 ++++++++++++++++
 12 files changed, 109 insertions(+), 168 deletions(-)
 delete mode 100644 dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchTest.php
 delete mode 100644 dev/tests/functional/testsuites/Mtf/TestSuite/BatCETests.php
 delete mode 100755 dev/tests/functional/testsuites/Mtf/TestSuite/EndToEndCETests.php
 create mode 100644 dev/tests/functional/testsuites/Mtf/TestSuite/InjectableTests/bat_ce.xml
 create mode 100644 dev/tests/functional/testsuites/Mtf/TestSuite/InjectableTests/end_to_end_ce.xml

diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory/ParentId.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory/ParentId.php
index c8f66313c08..01ba2f41397 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory/ParentId.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory/ParentId.php
@@ -38,7 +38,7 @@ class ParentId implements FixtureInterface
     public function __construct(FixtureFactory $fixtureFactory, array $params, $data = [])
     {
         $this->params = $params;
-        if ($data['dataSet']) {
+        if (isset($data['dataSet']) && $data['dataSet'] !== '-') {
             $this->parentCategory = $fixtureFactory->createByCode('catalogCategory', ['dataSet' => $data['dataSet']]);
             if (!$this->parentCategory->hasData('id')) {
                 $this->parentCategory->persist();
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest/test.csv
index 6252e245405..f3e9d14a6db 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest/test.csv
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest/test.csv
@@ -1,6 +1,6 @@
 "addCategory";"category/data/parent_id/dataSet";"category/data/name";"category/data/url_key";"category/data/is_active";"category/data/description";"category/data/meta_title";"category/data/include_in_menu";"category/data/display_mode";"category/data/landing_page";"category/data/is_anchor";"category/data/available_product_listing_config";"category/data/available_sort_by/sort_0";"category/data/available_sort_by/sort_1";"category/data/available_sort_by/sort_2";"category/data/default_product_listing_config";"category/data/default_sort_by";"category/data/use_config_price_range";"category/data/layered_navigation_price_step";"category/data/category_products_data/preset";"category/data/category_products/dataSet";"constraint"
-"addRootCategory";"1";"RootCategory%isolation%";"RootCategory%isolation%";"Yes";"RootCategory Required ";"-";"-";"-";"-";"-";"No";"Position";"Name";"Price";"-";"-";"-";"-";"-";"-";"assertCategorySaveMessage, assertCategoryForm"
-"addRootCategory";"1";"RootCategory%isolation%";"RootCategory%isolation%";"Yes";"RootCategory All Fields ";"RootCategory Page Title";"Yes";"Static block and products";"Catalog Events Lister";"Yes";"No";"Position";"Name";"Price";"No";"Name";"No";"50";"-";"-";"assertCategorySaveMessage, assertCategoryForm"
+"addRootCategory";"-";"RootCategory%isolation%";"RootCategory%isolation%";"Yes";"RootCategory Required ";"-";"-";"-";"-";"-";"No";"Position";"Name";"Price";"-";"-";"-";"-";"-";"-";"assertCategorySaveMessage, assertCategoryForm"
+"addRootCategory";"-";"RootCategory%isolation%";"RootCategory%isolation%";"Yes";"RootCategory All Fields ";"RootCategory Page Title";"Yes";"Static block and products";"Catalog Events Lister";"Yes";"No";"Position";"Name";"Price";"No";"Name";"No";"50";"-";"-";"assertCategorySaveMessage, assertCategoryForm"
 "addSubcategory";"default_category";"Subcategory%isolation%";"Subcategory%isolation%";"Yes";"Subcategory Required";"-";"-";"-";"-";"-";"Yes";"-";"-";"-";"-";"-";"-";"-";"-";"-";"assertCategorySaveMessage, assertCategoryForm, assertCategoryPage"
 "addSubcategory";"default_category";"Subcategory%isolation%";"Subcategory%isolation%";"Yes";"Subcategory For Anchor Subcategory";"-";"Yes";"-";"-";"No";"Yes";"-";"-";"-";"Yes";"-";"Yes";"-";"default";"catalogProductSimple::default,catalogProductSimple::default";"assertCategorySaveMessage, assertCategoryForm, assertCategoryPage, assertCategoryForAssignedProducts"
 "addSubcategory";"default_category";"Subcategory%isolation%";"Subcategory%isolation%";"Yes";"Anchor Subcategory All Fields";"Subcategory Page Title";"Yes";"Products only";"Catalog Events Lister";"Yes";"No";"Position";"Name";"Price";"No";"Price";"No";"50";"default";"catalogProductSimple::default,catalogProductSimple::default";"assertCategorySaveMessage, assertCategoryForm, assertCategoryPage, assertCategoryForAssignedProducts"
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchEntityTest.php
index ac620bd1c9e..c3f21df8d2f 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchEntityTest.php
@@ -12,7 +12,6 @@ use Mtf\Fixture\FixtureFactory;
 use Mtf\TestCase\Injectable;
 
 /**
- * Test Flow:
  * Preconditions:
  * 1. Two specific simple product is created(unique sku,name,short/full description, tax class)
  *
@@ -29,7 +28,7 @@ use Mtf\TestCase\Injectable;
 class AdvancedSearchEntityTest extends Injectable
 {
     /**
-     * Prepare data
+     * Prepare data.
      *
      * @param FixtureFactory $fixtureFactory
      * @return array
@@ -59,18 +58,14 @@ class AdvancedSearchEntityTest extends Injectable
     }
 
     /**
-     * Run test creation for advanced search entity
+     * Run test creation for advanced search entity.
      *
-     * @param array $products
      * @param CatalogProductSimple $productSearch
      * @param CmsIndex $cmsIndex
      * @param AdvancedSearch $searchPage
      * @return void
-     *
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function test(
-        array $products,
         CatalogProductSimple $productSearch,
         CmsIndex $cmsIndex,
         AdvancedSearch $searchPage
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchEntityTest/test.csv
index 687344b622b..76eb2b4ead5 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchEntityTest/test.csv
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchEntityTest/test.csv
@@ -1,13 +1,14 @@
-"products/simple_1";"products/simple_2";"productSearch/data/name";"productSearch/data/sku";"productSearch/data/description";"productSearch/data/short_description";"productSearch/data/price/value/price_from";"productSearch/data/price/value/price_to";"constraint"
-"Yes";"-";"abc_dfj";"abc_dfj";"adc_Full";"abc_short";49;500;"assertAdvancedSearchProductsResult"
-"Yes";"-";"abc";"-";"-";"-";"-";"-";"assertAdvancedSearchProductsResult"
-"-";"Yes";"adc_123";"-";"-";"-";"-";"-";"assertAdvancedSearchProductsResult"
-"Yes";"-";"-";"abc";"-";"-";"-";"-";"assertAdvancedSearchProductsResult"
-"Yes";"-";"-";"abc_dfj";"-";"-";"-";"-";"assertAdvancedSearchProductsResult"
-"Yes";"-";"-";"abc";"adc_full";"-";"-";"-";"assertAdvancedSearchProductsResult"
-"-";"Yes";"-";"-";"dfj_full";"-";"-";"-";"assertAdvancedSearchProductsResult"
-"Yes";"-";"-";"-";"-";"abc_short";"-";"-";"assertAdvancedSearchProductsResult"
-"-";"-";"-";"-";"-";"dfj_short";"-";"-";"assertAdvancedSearchProductsResult"
-"Yes";"-";"-";"-";"-";"-";50;50;"assertAdvancedSearchProductsResult"
-"Yes";"Yes";"-";"-";"-";"-";"-";100;"assertAdvancedSearchProductsResult"
-"Yes";"-";"abc_dfj";"abc_dfj";"adc_Full";"abc_short";49;50;"assertAdvancedSearchProductsResult"
+"description";"products/simple_1";"products/simple_2";"productSearch/data/name";"productSearch/data/sku";"productSearch/data/description";"productSearch/data/short_description";"productSearch/data/price/value/price_from";"productSearch/data/price/value/price_to";"constraint";"tag"
+"MAGETWO-12421: Use Advanced Search to Find the Product";"Yes";"-";"abc_dfj";"abc_dfj";"-";"-";"-";"-";"assertAdvancedSearchProductsResult";"bamboo_plan:end_to_end"
+"Search product in advanced search by name";"-";"Yes";"adc_123";"-";"-";"-";"-";"-";"assertAdvancedSearchProductsResult";""
+"Search product in advanced search by partial name";"Yes";"-";"abc";"-";"-";"-";"-";"-";"assertAdvancedSearchProductsResult";""
+"Search product in advanced search by sku";"Yes";"-";"-";"abc_dfj";"-";"-";"-";"-";"assertAdvancedSearchProductsResult";""
+"Search product in advanced search by partial sku";"Yes";"-";"-";"abc";"-";"-";"-";"-";"assertAdvancedSearchProductsResult";""
+"Search product in advanced search by partial sku and description";"Yes";"-";"-";"abc";"adc_full";"-";"-";"-";"assertAdvancedSearchProductsResult";""
+"Search product in advanced search by description";"-";"Yes";"-";"-";"dfj_full";"-";"-";"-";"assertAdvancedSearchProductsResult";""
+"Search product in advanced search by short description";"-";"-";"-";"-";"-";"dfj_short";"-";"-";"assertAdvancedSearchProductsResult";""
+"Search product in advanced search by partial short description";"Yes";"-";"-";"-";"-";"abc_short";"-";"-";"assertAdvancedSearchProductsResult";""
+"Search product in advanced search by price to";"Yes";"Yes";"-";"-";"-";"-";"-";100;"assertAdvancedSearchProductsResult";""
+"Search product in advanced search by price from and price to";"Yes";"-";"-";"-";"-";"-";50;50;"assertAdvancedSearchProductsResult";""
+"Search product in advanced search by name, sku, description, short description, price from and price to";"Yes";"-";"abc_dfj";"abc_dfj";"adc_Full";"abc_short";49;500;"assertAdvancedSearchProductsResult";""
+"Search product in advanced search by name, sku, description, short description, price from and price to";"Yes";"-";"abc_dfj";"abc_dfj";"adc_Full";"abc_short";49;50;"assertAdvancedSearchProductsResult";""
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchTest.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchTest.php
deleted file mode 100644
index fe1a1216829..00000000000
--- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/AdvancedSearchTest.php
+++ /dev/null
@@ -1,49 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- */
-
-namespace Magento\CatalogSearch\Test\TestCase;
-
-use Mtf\Factory\Factory;
-use Mtf\TestCase\Functional;
-
-/**
- * Class AdvancedSearchTest
- * Searching product in the Frontend via advanced search
- */
-class AdvancedSearchTest extends Functional
-{
-    /**
-     * Advanced search product on frontend by product name
-     *
-     * @ZephyrId MAGETWO-12421
-     */
-    public function testProductSearch()
-    {
-        //Data
-        $productFixture = Factory::getFixtureFactory()->getMagentoCatalogSimpleProduct();
-        $productFixture->switchData('simple');
-        $productFixture->persist();
-
-        //Pages
-        $homePage = Factory::getPageFactory()->getCmsIndexIndex();
-        $advancedSearchPage = Factory::getPageFactory()->getCatalogsearchAdvanced();
-        $advancedSearchResultPage = Factory::getPageFactory()->getCatalogsearchResult();
-
-        //Steps
-        $homePage->open();
-        $homePage->getSearchBlock()->clickAdvancedSearchButton();
-        $searchForm = $advancedSearchPage->getForm();
-        $this->assertTrue($searchForm->isVisible(), '"Advanced Search" form is not opened');
-        $searchForm->fillCustom($productFixture, ['name', 'sku']);
-        $searchForm->submit();
-
-        //Verifying
-        $productName = $productFixture->getName();
-        $this->assertTrue(
-            $advancedSearchResultPage->getListProductBlock()->isProductVisible($productName),
-            sprintf('Product "%s" is not displayed on the "Catalog Advanced Search" results page."', $productName)
-        );
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductDuplicateForm.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductDuplicateForm.php
index 4c6ea9e268e..daea7ea002c 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductDuplicateForm.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableProductDuplicateForm.php
@@ -39,6 +39,10 @@ class AssertConfigurableProductDuplicateForm extends AssertConfigurableProductFo
         $productData = $product->getData();
         $productData['sku'] = $duplicateProductSku;
         $productData['status'] = 'Product offline';
+        if (isset($compareData['quantity_and_stock_status']['qty'])) {
+            $compareData['quantity_and_stock_status']['qty'] = '';
+            $compareData['quantity_and_stock_status']['is_in_stock'] = 'Out of Stock';
+        }
         $fixtureData = $this->prepareFixtureData($productData, $this->sortFields);
         $formData = $this->prepareFormData($productPage->getProductForm()->getData($product), $this->sortFields);
         $error = $this->verifyData($fixtureData, $formData);
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest/testCreateCustomerBackendEntity.csv b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest/testCreateCustomerBackendEntity.csv
index 47b35a7511a..3474c0f0765 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest/testCreateCustomerBackendEntity.csv
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest/testCreateCustomerBackendEntity.csv
@@ -1,6 +1,6 @@
 "customer/data/website_id";"customer/data/group_id/dataSet";"customer/data/prefix";"customer/data/firstname";"customer/data/middlename";"customer/data/lastname";"customer/data/suffix";"customer/data/email";"customer/data/dob";"customer/data/taxvat";"customer/data/gender";"address/data/firstname";"address/data/lastname";"address/data/street";"address/data/city";"address/data/country_id";"address/data/region_id";"address/data/postcode";"address/data/telephone";"constraint"
 "Main Website";"General";"-";"John%isolation%";"-";"Doe%isolation%";"-";"JohnDoe%isolation%@example.com";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"assertCustomerSuccessSaveMessage, assertCustomerInGrid, assertCustomerForm"
-"Admin";"Wholesale";"M";"John%isolation%";"Jack";"Doe%isolation%";"S";"JohnDoe%isolation%@example.com";"3/16/2004";"-";"Male";"-";"-";"-";"-";"-";"-";"-";"-";"assertCustomerSuccessSaveMessage, assertCustomerInGrid, assertCustomerForm"
+"Admin";"Wholesale";"M";"John%isolation%";"Jack";"Doe%isolation%";"S";"JohnDoe%isolation%@example.com";"03/16/2004";"-";"Male";"-";"-";"-";"-";"-";"-";"-";"-";"assertCustomerSuccessSaveMessage, assertCustomerInGrid, assertCustomerForm"
 "Main Website";"General";"-";"John%isolation%";"-";"Doe%isolation%";"-";"JohnDoe%isolation%@example.com";"-";"-";"-";"Joe";"Doe";"1 Main Street";"Culver City";"United States";"California";"90230";"3109450345";"assertCustomerSuccessSaveMessage, assertCustomerInGrid, assertCustomerForm"
 "Main Website";"Retailer";"-";"John%isolation%";"-";"Doe%isolation%";"-";"JohnDoe%isolation%@example.ccc";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"assertCustomerInvalidEmail"
 "Main Website";"General";"-";"Thomas%isolation%";"-";"Oster%isolation%";"-";"Thomas%isolation%@example.com";"-";"5250008057";"-";"Thomas";"Oster";"Chmielna 113";"Bielsko-Biala";"Poland";"-";"43-310 ";"799885616";"assertCustomerSuccessSaveMessage, assertCustomerInGrid, assertCustomerForm"
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest/testUpdateCustomerBackendEntity.csv b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest/testUpdateCustomerBackendEntity.csv
index 649c9f7842c..45730686724 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest/testUpdateCustomerBackendEntity.csv
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest/testUpdateCustomerBackendEntity.csv
@@ -1,4 +1,4 @@
-"initialCustomer/dataSet";"customer/data/group_id/dataSet";"customer/data/prefix";"customer/data/firstname";"customer/data/middlename";"customer/data/lastname";"customer/data/suffix";"customer/data/email";"customer/data/dob";"customer/data/taxvat";"customer/data/gender";"address/data/prefix";"address/data/firstname";"address/data/middlename";"address/data/lastname";"address/data/suffix";"address/data/company";"address/data/street";"address/data/city";"address/data/country_id";"address/data/region_id";"address/data/region";"address/data/postcode";"address/data/telephone";"address/data/fax";"address/data/vat_id";"constraint";"issue"
-"default";"Wholesale";"%isolation%Prefix_";"John_%isolation%";"Middle Name %isolation%";"Doe%isolation%";"_Suffix%isolation%";"JohnDoe%isolation%@example.com";1/8/1986;123456789001;"Male";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"assertCustomerSuccessSaveMessage, assertCustomerForm, assertCustomerInGrid";"Bug: MAGETWO-31689"
-"default";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"Prefix%isolation%_";"Doe%isolation%";"Middle Name %isolation%";"Doe%isolation%";"_Suffix%isolation%";"Company%isolation%";"3962 Horner Street";"Dothan";"United States";"Alabama";"-";36303;"334-200-4060";"555-666-777-8910";"U1234567890";"assertCustomerSuccessSaveMessage, assertCustomerForm, assertCustomerInGrid";""
-"default";"Retailer";"%isolation%Prefix_";"Jane_%isolation%";"Jane Middle Name %isolation%";"Doe%isolation%";"_JaneSuffix%isolation%";"Jane%isolation%@example.com";1/12/2000;987654321;"Female";"Prefix%isolation%_";"Doe%isolation%";"Middle Name %isolation%";"Doe%isolation%";"_Suffix%isolation%";"Company%isolation%";"39 Northgate Street";"BICKTON";"United Kingdom";"-";"PINMINNOCH";"KA26 1PF ";"999-777-111-2345";"-";987654321;"assertCustomerSuccessSaveMessage, assertCustomerForm, assertCustomerInGrid";""
+"initialCustomer/dataSet";"customer/data/group_id/dataSet";"customer/data/prefix";"customer/data/firstname";"customer/data/middlename";"customer/data/lastname";"customer/data/suffix";"customer/data/email";"customer/data/dob";"customer/data/taxvat";"customer/data/gender";"address/data/prefix";"address/data/firstname";"address/data/middlename";"address/data/lastname";"address/data/suffix";"address/data/company";"address/data/street";"address/data/city";"address/data/country_id";"address/data/region_id";"address/data/region";"address/data/postcode";"address/data/telephone";"address/data/fax";"address/data/vat_id";"constraint"
+"default";"Wholesale";"%isolation%Prefix_";"John_%isolation%";"Middle Name %isolation%";"Doe%isolation%";"_Suffix%isolation%";"JohnDoe%isolation%@example.com";01/08/1986;123456789001;"Male";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"assertCustomerSuccessSaveMessage, assertCustomerForm, assertCustomerInGrid"
+"default";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"Prefix%isolation%_";"Doe%isolation%";"Middle Name %isolation%";"Doe%isolation%";"_Suffix%isolation%";"Company%isolation%";"3962 Horner Street";"Dothan";"United States";"Alabama";"-";36303;"334-200-4060";"555-666-777-8910";"U1234567890";"assertCustomerSuccessSaveMessage, assertCustomerForm, assertCustomerInGrid"
+"default";"Retailer";"%isolation%Prefix_";"Jane_%isolation%";"Jane Middle Name %isolation%";"Doe%isolation%";"_JaneSuffix%isolation%";"Jane%isolation%@example.com";01/12/2000;987654321;"Female";"Prefix%isolation%_";"Doe%isolation%";"Middle Name %isolation%";"Doe%isolation%";"_Suffix%isolation%";"Company%isolation%";"39 Northgate Street";"BICKTON";"United Kingdom";"-";"PINMINNOCH";"KA26 1PF ";"999-777-111-2345";"-";987654321;"assertCustomerSuccessSaveMessage, assertCustomerForm, assertCustomerInGrid"
diff --git a/dev/tests/functional/testsuites/Mtf/TestSuite/BatCETests.php b/dev/tests/functional/testsuites/Mtf/TestSuite/BatCETests.php
deleted file mode 100644
index d5d16fc2cb8..00000000000
--- a/dev/tests/functional/testsuites/Mtf/TestSuite/BatCETests.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-/**
- * BAT CE
- *
- * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- */
-
-namespace Mtf\TestSuite;
-
-class BatCETests
-{
-    public static function suite()
-    {
-        $suite = new TestSuite('BAT CE');
-
-        // Product
-        $suite->addTestSuite('Magento\Bundle\Test\TestCase\BundleFixedTest');
-        $suite->addTestSuite('Magento\Catalog\Test\TestCase\Product\CreateTest');
-        $suite->addTestSuite('Magento\ConfigurableProduct\Test\TestCase\CreateConfigurableTest');
-        $suite->addTestSuite('Magento\ConfigurableProduct\Test\TestCase\CreateWithAttributeTest');
-        $suite->addTestSuite('Magento\Catalog\Test\TestCase\Product\CreateSimpleWithCustomOptionsAndCategoryTest');
-
-        // Category
-        $suite->addTestSuite('Magento\Catalog\Test\TestCase\Category\CreateTest');
-
-        // Stores
-        $suite->addTestSuite('Magento\Store\Test\TestCase\StoreTest');
-
-        return $suite;
-    }
-}
diff --git a/dev/tests/functional/testsuites/Mtf/TestSuite/EndToEndCETests.php b/dev/tests/functional/testsuites/Mtf/TestSuite/EndToEndCETests.php
deleted file mode 100755
index a02b42d41ea..00000000000
--- a/dev/tests/functional/testsuites/Mtf/TestSuite/EndToEndCETests.php
+++ /dev/null
@@ -1,60 +0,0 @@
-<?php
-/**
- * End-to-end scenarios without 3-rd party solutions for CE
- *
- * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- */
-
-namespace Mtf\TestSuite;
-
-class EndToEndCETests
-{
-    public static function suite()
-    {
-        $suite = new TestSuite('End-to-end Scenarios without 3-rd Party Solutions for CE');
-
-        // Products
-        // Simple
-        $suite->addTestSuite('Magento\Catalog\Test\TestCase\Product\CreateProductTest');
-        $suite->addTestSuite('Magento\Catalog\Test\TestCase\Product\EditSimpleProductTest');
-        $suite->addTestSuite('Magento\Catalog\Test\TestCase\Product\CreateSimpleWithCategoryTest');
-        $suite->addTestSuite('Magento\Catalog\Test\TestCase\Product\UnassignCategoryTest');
-        // Grouped
-        $suite->addTestSuite('Magento\GroupedProduct\Test\TestCase\CreateGroupedTest');
-        // Virtual
-        $suite->addTestSuite('Magento\Catalog\Test\TestCase\Product\CreateVirtualTest');
-        // Configurable
-        $suite->addTestSuite('Magento\ConfigurableProduct\Test\TestCase\EditConfigurableTest');
-        // Downloadable
-        $suite->addTestSuite('Magento\Downloadable\Test\TestCase\Create\LinksPurchasedSeparatelyTest');
-        // Bundle
-        $suite->addTestSuite('Magento\Bundle\Test\TestCase\BundleDynamicTest');
-        $suite->addTestSuite('Magento\Bundle\Test\TestCase\EditBundleTest');
-
-        $suite->addTestSuite('Magento\Catalog\Test\TestCase\Product\UpsellTest');
-        $suite->addTestSuite('Magento\Catalog\Test\TestCase\Product\CrosssellTest');
-        $suite->addTestSuite('Magento\Catalog\Test\TestCase\Product\RelatedProductTest');
-
-        // Product search
-        $suite->addTestSuite('Magento\CatalogSearch\Test\TestCase\AdvancedSearchTest');
-
-        // Url rewrites
-        $suite->addTestSuite('Magento\Urlrewrite\Test\TestCase\ProductTest');
-        $suite->addTestSuite('Magento\Urlrewrite\Test\TestCase\CategoryTest');
-
-        // Customer
-        $suite->addTestSuite('Magento\Customer\Test\TestCase\BackendCustomerCreateTest');
-        $suite->addTestSuite('Magento\Customer\Test\TestCase\CreateOnFrontendTest');
-
-        // Review
-        $suite->addTestSuite('Magento\Review\Test\TestCase\ReviewTest');
-
-        // Tax
-        $suite->addTestSuite('Magento\Tax\Test\TestCase\TaxRuleTest');
-
-        // Assign products to a category
-        $suite->addTestSuite('Magento\Catalog\Test\TestCase\Category\AssignProductTest');
-
-        return $suite;
-    }
-}
diff --git a/dev/tests/functional/testsuites/Mtf/TestSuite/InjectableTests/bat_ce.xml b/dev/tests/functional/testsuites/Mtf/TestSuite/InjectableTests/bat_ce.xml
new file mode 100644
index 00000000000..4f1bd6dcb30
--- /dev/null
+++ b/dev/tests/functional/testsuites/Mtf/TestSuite/InjectableTests/bat_ce.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:noNamespaceSchemaLocation="../../../../vendor/magento/mtf/Mtf/TestRunner/etc/testRunner.xsd">
+    <rule scope="testsuite">
+        <allow>
+            <!--Products-->
+            <class value="Magento\Bundle\Test\TestCase\BundleFixedTest" />
+            <class value="Magento\Catalog\Test\TestCase\Product\CreateTest" />
+            <class value="Magento\ConfigurableProduct\Test\TestCase\CreateConfigurableTest" />
+            <class value="Magento\ConfigurableProduct\Test\TestCase\CreateWithAttributeTest" />
+            <class value="Magento\Catalog\Test\TestCase\Product\CreateSimpleWithCustomOptionsAndCategoryTest" />
+            <!--Category-->
+            <class value="Magento\Catalog\Test\TestCase\Category\CreateTest" />
+            <!--Stores-->
+            <class value="Magento\Store\Test\TestCase\StoreTest" />
+        </allow>
+    </rule>
+    <rule scope="variation">
+        <allow>
+            <tag group="bamboo_plan" value="BAT" />
+        </allow>
+    </rule>
+</config>
diff --git a/dev/tests/functional/testsuites/Mtf/TestSuite/InjectableTests/end_to_end_ce.xml b/dev/tests/functional/testsuites/Mtf/TestSuite/InjectableTests/end_to_end_ce.xml
new file mode 100644
index 00000000000..00c581aebaf
--- /dev/null
+++ b/dev/tests/functional/testsuites/Mtf/TestSuite/InjectableTests/end_to_end_ce.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:noNamespaceSchemaLocation="../../../../vendor/magento/mtf/Mtf/TestRunner/etc/testRunner.xsd">
+    <rule scope="testsuite">
+        <allow>
+            <!--Product search-->
+            <class value="Magento\CatalogSearch\Test\TestCase\AdvancedSearchEntityTest" />
+            <!--Products-->
+            <!--Simple-->
+            <class value="Magento\Catalog\Test\TestCase\Product\CreateProductTest" />
+            <class value="Magento\Catalog\Test\TestCase\Product\EditSimpleProductTest" />
+            <class value="Magento\Catalog\Test\TestCase\Product\CreateSimpleWithCategoryTest" />
+            <class value="Magento\Catalog\Test\TestCase\Product\UnassignCategoryTest" />
+            <!--Grouped-->
+            <class value="Magento\GroupedProduct\Test\TestCase\CreateGroupedTest" />
+            <!--Virtual-->
+            <class value="Magento\Catalog\Test\TestCase\Product\CreateVirtualTest" />
+            <!--Configurable-->
+            <class value="Magento\ConfigurableProduct\Test\TestCase\EditConfigurableTest" />
+            <!--Downloadable-->
+            <class value="Magento\Downloadable\Test\TestCase\Create\LinksPurchasedSeparatelyTest" />
+            <!--Bundle-->
+            <class value="Magento\Bundle\Test\TestCase\BundleDynamicTest" />
+            <class value="Magento\Bundle\Test\TestCase\EditBundleTest" />
+            <!--Related Products-->
+            <class value="Magento\Catalog\Test\TestCase\Product\UpsellTest" />
+            <class value="Magento\Catalog\Test\TestCase\Product\CrosssellTest" />
+            <class value="Magento\Catalog\Test\TestCase\Product\RelatedProductTest" />
+            <!--Url rewrites-->
+            <class value="Magento\Urlrewrite\Test\TestCase\ProductTest" />
+            <class value="Magento\Urlrewrite\Test\TestCase\CategoryTest" />
+            <!--Customer-->
+            <class value="Magento\Customer\Test\TestCase\BackendCustomerCreateTest" />
+            <class value="Magento\Customer\Test\TestCase\CreateOnFrontendTest" />
+            <!--Review-->
+            <class value="Magento\Review\Test\TestCase\ReviewTest" />
+            <!--Tax-->
+            <class value="Magento\Tax\Test\TestCase\TaxRuleTest" />
+            <!--Assign products to a category-->
+            <class value="Magento\Catalog\Test\TestCase\Category\AssignProductTest" />
+        </allow>
+    </rule>
+    <rule scope="variation">
+        <allow>
+            <tag group="bamboo_plan" value="end_to_end" />
+        </allow>
+    </rule>
+</config>
-- 
GitLab


From 39fb93a54d5878d9e24551f43b01daa8e8fbe21e Mon Sep 17 00:00:00 2001
From: Alexander Paliarush <apaliarush@ebay.com>
Date: Mon, 15 Dec 2014 14:02:24 +0200
Subject: [PATCH 09/71] MAGETWO-25098: Admin has no possibility to active an
 integration after editing URLs for integration

- In addition: Eliminated excessive factory, which could be auto-generated
---
 .../Integration/Model/Oauth/Token/Factory.php | 35 -------------------
 .../Model/Oauth/Token/Provider.php            | 20 ++++-------
 .../Service/V1/AdminTokenService.php          |  2 +-
 .../Service/V1/CustomerTokenService.php       |  2 +-
 .../Magento/Integration/Service/V1/Oauth.php  |  2 +-
 .../Test/Legacy/_files/obsolete_classes.php   |  1 +
 .../Integration/Helper/Oauth/ConsumerTest.php |  4 +--
 .../Magento/Integration/Oauth/OauthTest.php   |  4 +--
 .../Service/V1/AdminTokenServiceTest.php      |  4 +--
 .../Service/V1/CustomerTokenServiceTest.php   |  4 +--
 .../Integration/Service/V1/OauthTest.php      |  4 +--
 11 files changed, 21 insertions(+), 61 deletions(-)
 delete mode 100644 app/code/Magento/Integration/Model/Oauth/Token/Factory.php

diff --git a/app/code/Magento/Integration/Model/Oauth/Token/Factory.php b/app/code/Magento/Integration/Model/Oauth/Token/Factory.php
deleted file mode 100644
index 0ef69a3d4e1..00000000000
--- a/app/code/Magento/Integration/Model/Oauth/Token/Factory.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- */
-namespace Magento\Integration\Model\Oauth\Token;
-
-/**
- * Token builder factory
- */
-class Factory
-{
-    /**
-     * @var \Magento\Framework\ObjectManagerInterface
-     */
-    protected $_objectManager;
-
-    /**
-     * @param \Magento\Framework\ObjectManagerInterface $objectManager
-     */
-    public function __construct(\Magento\Framework\ObjectManagerInterface $objectManager)
-    {
-        $this->_objectManager = $objectManager;
-    }
-
-    /**
-     * Create token model.
-     *
-     * @param array $arguments
-     * @return \Magento\Integration\Model\Oauth\Token
-     */
-    public function create($arguments = [])
-    {
-        return $this->_objectManager->create('Magento\Integration\Model\Oauth\Token', $arguments);
-    }
-}
diff --git a/app/code/Magento/Integration/Model/Oauth/Token/Provider.php b/app/code/Magento/Integration/Model/Oauth/Token/Provider.php
index e4a0d7134d7..54938d57a21 100644
--- a/app/code/Magento/Integration/Model/Oauth/Token/Provider.php
+++ b/app/code/Magento/Integration/Model/Oauth/Token/Provider.php
@@ -17,7 +17,7 @@ class Provider implements TokenProviderInterface
     protected $_consumerFactory;
 
     /**
-     * @var \Magento\Integration\Model\Oauth\Token\Factory
+     * @var \Magento\Integration\Model\Oauth\TokenFactory
      */
     protected $_tokenFactory;
 
@@ -31,30 +31,22 @@ class Provider implements TokenProviderInterface
      */
     protected $_date;
 
-    /**
-     * @var Token
-     */
-    protected $token;
-
     /**
      * @param \Magento\Integration\Model\Oauth\Consumer\Factory $consumerFactory
-     * @param \Magento\Integration\Model\Oauth\Token\Factory $tokenFactory
+     * @param \Magento\Integration\Model\Oauth\TokenFactory $tokenFactory
      * @param \Magento\Integration\Helper\Oauth\Data $dataHelper
      * @param \Magento\Framework\Stdlib\DateTime\DateTime $date
-     * @param Token $token
      */
     public function __construct(
         \Magento\Integration\Model\Oauth\Consumer\Factory $consumerFactory,
-        \Magento\Integration\Model\Oauth\Token\Factory $tokenFactory,
+        \Magento\Integration\Model\Oauth\TokenFactory $tokenFactory,
         \Magento\Integration\Helper\Oauth\Data $dataHelper,
-        \Magento\Framework\Stdlib\DateTime\DateTime $date,
-        Token $token
+        \Magento\Framework\Stdlib\DateTime\DateTime $date
     ) {
         $this->_consumerFactory = $consumerFactory;
         $this->_tokenFactory = $tokenFactory;
         $this->_dataHelper = $dataHelper;
         $this->_date = $date;
-        $this->token = $token;
     }
 
     /**
@@ -293,7 +285,9 @@ class Provider implements TokenProviderInterface
      */
     public function getIntegrationTokenByConsumerId($consumerId)
     {
-        $token = $this->token->loadByConsumerIdAndUserType($consumerId, UserContextInterface::USER_TYPE_INTEGRATION);
+        /** @var \Magento\Integration\Model\Oauth\Token $token */
+        $token = $this->_tokenFactory->create();
+        $token->loadByConsumerIdAndUserType($consumerId, UserContextInterface::USER_TYPE_INTEGRATION);
 
         if (!$token->getId()) {
             throw new \Magento\Framework\Oauth\Exception(
diff --git a/app/code/Magento/Integration/Service/V1/AdminTokenService.php b/app/code/Magento/Integration/Service/V1/AdminTokenService.php
index 06d08c2995d..4629800f46f 100644
--- a/app/code/Magento/Integration/Service/V1/AdminTokenService.php
+++ b/app/code/Magento/Integration/Service/V1/AdminTokenService.php
@@ -9,7 +9,7 @@ use Magento\Framework\Exception\AuthenticationException;
 use Magento\Framework\Exception\LocalizedException;
 use Magento\Integration\Helper\Validator;
 use Magento\Integration\Model\Oauth\Token as Token;
-use Magento\Integration\Model\Oauth\Token\Factory as TokenModelFactory;
+use Magento\Integration\Model\Oauth\TokenFactory as TokenModelFactory;
 use Magento\Integration\Model\Resource\Oauth\Token\CollectionFactory as TokenCollectionFactory;
 use Magento\User\Model\User as UserModel;
 
diff --git a/app/code/Magento/Integration/Service/V1/CustomerTokenService.php b/app/code/Magento/Integration/Service/V1/CustomerTokenService.php
index 6d1c08cefd3..d37e2910141 100644
--- a/app/code/Magento/Integration/Service/V1/CustomerTokenService.php
+++ b/app/code/Magento/Integration/Service/V1/CustomerTokenService.php
@@ -9,7 +9,7 @@ use Magento\Customer\Api\AccountManagementInterface;
 use Magento\Framework\Exception\LocalizedException;
 use Magento\Integration\Helper\Validator;
 use Magento\Integration\Model\Oauth\Token as Token;
-use Magento\Integration\Model\Oauth\Token\Factory as TokenModelFactory;
+use Magento\Integration\Model\Oauth\TokenFactory as TokenModelFactory;
 use Magento\Integration\Model\Resource\Oauth\Token\CollectionFactory as TokenCollectionFactory;
 
 class CustomerTokenService implements CustomerTokenServiceInterface
diff --git a/app/code/Magento/Integration/Service/V1/Oauth.php b/app/code/Magento/Integration/Service/V1/Oauth.php
index c3c9e30e9e0..0e02997ccb9 100644
--- a/app/code/Magento/Integration/Service/V1/Oauth.php
+++ b/app/code/Magento/Integration/Service/V1/Oauth.php
@@ -9,7 +9,7 @@ use Magento\Integration\Helper\Oauth\Data as IntegrationOauthHelper;
 use Magento\Integration\Model\Oauth\Consumer as ConsumerModel;
 use Magento\Integration\Model\Oauth\Consumer\Factory as ConsumerFactory;
 use Magento\Integration\Model\Oauth\Token as OauthTokenModel;
-use Magento\Integration\Model\Oauth\Token\Factory as TokenFactory;
+use Magento\Integration\Model\Oauth\TokenFactory as TokenFactory;
 use Magento\Integration\Model\Oauth\Token\Provider as TokenProvider;
 
 /**
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
index 68e501b6893..2baabc9440a 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
@@ -2329,6 +2329,7 @@ return [
     ['Magento\TranslateInterface', 'Magento\Framework\TranslateInterface'],
     ['Magento\Locale', 'Magento\Framework\Locale'],
     ['Magento\LocaleFactory', 'Magento\Framework\LocaleFactory'],
+    ['Magento\Integration\Model\Oauth\Token\Factory', 'Magento\Integration\Model\Oauth\TokenFactory'],
     ['Magento\LocaleInterface', 'Magento\Framework\LocaleInterface'],
     ['Magento\Logger', 'Magento\Framework\Logger'],
     ['Magento\Phrase', 'Magento\Framework\Phrase'],
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Helper/Oauth/ConsumerTest.php b/dev/tests/unit/testsuite/Magento/Integration/Helper/Oauth/ConsumerTest.php
index d2d4d092c67..fc9b031f62a 100644
--- a/dev/tests/unit/testsuite/Magento/Integration/Helper/Oauth/ConsumerTest.php
+++ b/dev/tests/unit/testsuite/Magento/Integration/Helper/Oauth/ConsumerTest.php
@@ -18,7 +18,7 @@ class ConsumerTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Framework\HTTP\ZendClient */
     protected $_httpClientMock;
 
-    /** @var \Magento\Integration\Model\Oauth\Token\Factory */
+    /** @var \Magento\Integration\Model\Oauth\TokenFactory */
     protected $_tokenFactory;
 
     /** @var \Magento\Integration\Model\Oauth\Token */
@@ -53,7 +53,7 @@ class ConsumerTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->_tokenFactory = $this->getMockBuilder(
-            'Magento\Integration\Model\Oauth\Token\Factory'
+            'Magento\Integration\Model\Oauth\TokenFactory'
         )->disableOriginalConstructor()->getMock();
         $this->_tokenMock = $this->getMockBuilder(
             'Magento\Integration\Model\Oauth\Token'
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Oauth/OauthTest.php b/dev/tests/unit/testsuite/Magento/Integration/Oauth/OauthTest.php
index b510a867cd1..362b6788379 100644
--- a/dev/tests/unit/testsuite/Magento/Integration/Oauth/OauthTest.php
+++ b/dev/tests/unit/testsuite/Magento/Integration/Oauth/OauthTest.php
@@ -15,7 +15,7 @@ class OauthTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Integration\Model\Oauth\Nonce\Factory */
     private $_nonceFactory;
 
-    /** @var \Magento\Integration\Model\Oauth\Token\Factory */
+    /** @var \Magento\Integration\Model\Oauth\TokenFactory */
     private $_tokenFactory;
 
     /** @var \Magento\Integration\Model\Oauth\Consumer */
@@ -76,7 +76,7 @@ class OauthTest extends \PHPUnit_Framework_TestCase
             'Magento\Integration\Model\Oauth\Nonce\Factory'
         )->disableOriginalConstructor()->getMock();
         $this->_tokenFactory = $this->getMockBuilder(
-            'Magento\Integration\Model\Oauth\Token\Factory'
+            'Magento\Integration\Model\Oauth\TokenFactory'
         )->disableOriginalConstructor()->getMock();
         $this->_tokenMock = $this->getMockBuilder('Magento\Integration\Model\Oauth\Token')
             ->disableOriginalConstructor()
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Service/V1/AdminTokenServiceTest.php b/dev/tests/unit/testsuite/Magento/Integration/Service/V1/AdminTokenServiceTest.php
index fd528c328f0..178183876f8 100644
--- a/dev/tests/unit/testsuite/Magento/Integration/Service/V1/AdminTokenServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Integration/Service/V1/AdminTokenServiceTest.php
@@ -15,7 +15,7 @@ class AdminTokenServiceTest extends \PHPUnit_Framework_TestCase
     /** \Magento\Integration\Service\V1\AdminTokenService */
     protected $_tokenService;
 
-    /** \Magento\Integration\Model\Oauth\Token\Factory|\PHPUnit_Framework_MockObject_MockObject */
+    /** \Magento\Integration\Model\Oauth\TokenFactory|\PHPUnit_Framework_MockObject_MockObject */
     protected $_tokenModelFactoryMock;
 
     /** \Magento\User\Model\User|\PHPUnit_Framework_MockObject_MockObject */
@@ -35,7 +35,7 @@ class AdminTokenServiceTest extends \PHPUnit_Framework_TestCase
 
     protected function setUp()
     {
-        $this->_tokenModelFactoryMock = $this->getMockBuilder('Magento\Integration\Model\Oauth\Token\Factory')
+        $this->_tokenModelFactoryMock = $this->getMockBuilder('Magento\Integration\Model\Oauth\TokenFactory')
             ->setMethods(['create'])
             ->disableOriginalConstructor()
             ->getMock();
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Service/V1/CustomerTokenServiceTest.php b/dev/tests/unit/testsuite/Magento/Integration/Service/V1/CustomerTokenServiceTest.php
index 5e4581da452..4e189ffbe56 100644
--- a/dev/tests/unit/testsuite/Magento/Integration/Service/V1/CustomerTokenServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Integration/Service/V1/CustomerTokenServiceTest.php
@@ -15,7 +15,7 @@ class CustomerTokenServiceTest extends \PHPUnit_Framework_TestCase
     /** \Magento\Integration\Service\V1\CustomerTokenService */
     protected $_tokenService;
 
-    /** \Magento\Integration\Model\Oauth\Token\Factory|\PHPUnit_Framework_MockObject_MockObject */
+    /** \Magento\Integration\Model\Oauth\TokenFactory|\PHPUnit_Framework_MockObject_MockObject */
     protected $_tokenModelFactoryMock;
 
     /** \Magento\Customer\Api\AccountManagementInterface|\PHPUnit_Framework_MockObject_MockObject */
@@ -35,7 +35,7 @@ class CustomerTokenServiceTest extends \PHPUnit_Framework_TestCase
 
     protected function setUp()
     {
-        $this->_tokenModelFactoryMock = $this->getMockBuilder('Magento\Integration\Model\Oauth\Token\Factory')
+        $this->_tokenModelFactoryMock = $this->getMockBuilder('Magento\Integration\Model\Oauth\TokenFactory')
             ->setMethods(['create'])
             ->disableOriginalConstructor()
             ->getMock();
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Service/V1/OauthTest.php b/dev/tests/unit/testsuite/Magento/Integration/Service/V1/OauthTest.php
index eaeb90e7e17..1ee44f62ad4 100644
--- a/dev/tests/unit/testsuite/Magento/Integration/Service/V1/OauthTest.php
+++ b/dev/tests/unit/testsuite/Magento/Integration/Service/V1/OauthTest.php
@@ -41,7 +41,7 @@ class OauthTest extends \PHPUnit_Framework_TestCase
     private $_consumerData;
 
     /**
-     * @var \Magento\Integration\Model\Oauth\Token\Factory|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Integration\Model\Oauth\TokenFactory|\PHPUnit_Framework_MockObject_MockObject
      */
     private $_tokenFactoryMock;
 
@@ -60,7 +60,7 @@ class OauthTest extends \PHPUnit_Framework_TestCase
         )->getMock();
 
         $this->_tokenFactoryMock = $this->getMock(
-            'Magento\Integration\Model\Oauth\Token\Factory',
+            'Magento\Integration\Model\Oauth\TokenFactory',
             [],
             [],
             '',
-- 
GitLab


From 5f7677d61995aac1b5ae60c36432275c43afb1a5 Mon Sep 17 00:00:00 2001
From: Alexander Paliarush <apaliarush@ebay.com>
Date: Wed, 17 Dec 2014 12:31:49 +0200
Subject: [PATCH 10/71] MAGETWO-25098: Admin has no possibility to active an
 integration after editing URLs for integration

- Fixed unit tests
---
 .../Magento/Integration/Helper/Oauth/ConsumerTest.php      | 2 +-
 .../unit/testsuite/Magento/Integration/Oauth/OauthTest.php | 5 ++---
 .../Integration/Service/V1/AdminTokenServiceTest.php       | 7 ++++---
 .../Integration/Service/V1/CustomerTokenServiceTest.php    | 7 ++++---
 .../testsuite/Magento/Integration/Service/V1/OauthTest.php | 3 ++-
 5 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/dev/tests/unit/testsuite/Magento/Integration/Helper/Oauth/ConsumerTest.php b/dev/tests/unit/testsuite/Magento/Integration/Helper/Oauth/ConsumerTest.php
index fc9b031f62a..5fd47defc11 100644
--- a/dev/tests/unit/testsuite/Magento/Integration/Helper/Oauth/ConsumerTest.php
+++ b/dev/tests/unit/testsuite/Magento/Integration/Helper/Oauth/ConsumerTest.php
@@ -54,7 +54,7 @@ class ConsumerTest extends \PHPUnit_Framework_TestCase
 
         $this->_tokenFactory = $this->getMockBuilder(
             'Magento\Integration\Model\Oauth\TokenFactory'
-        )->disableOriginalConstructor()->getMock();
+        )->disableOriginalConstructor()->setMethods(['create'])->getMock();
         $this->_tokenMock = $this->getMockBuilder(
             'Magento\Integration\Model\Oauth\Token'
         )->disableOriginalConstructor()->getMock();
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Oauth/OauthTest.php b/dev/tests/unit/testsuite/Magento/Integration/Oauth/OauthTest.php
index 362b6788379..9daf41a124f 100644
--- a/dev/tests/unit/testsuite/Magento/Integration/Oauth/OauthTest.php
+++ b/dev/tests/unit/testsuite/Magento/Integration/Oauth/OauthTest.php
@@ -77,7 +77,7 @@ class OauthTest extends \PHPUnit_Framework_TestCase
         )->disableOriginalConstructor()->getMock();
         $this->_tokenFactory = $this->getMockBuilder(
             'Magento\Integration\Model\Oauth\TokenFactory'
-        )->disableOriginalConstructor()->getMock();
+        )->disableOriginalConstructor()->setMethods(['create'])->getMock();
         $this->_tokenMock = $this->getMockBuilder('Magento\Integration\Model\Oauth\Token')
             ->disableOriginalConstructor()
             ->setMethods(
@@ -122,8 +122,7 @@ class OauthTest extends \PHPUnit_Framework_TestCase
             $this->_consumerFactory,
             $this->_tokenFactory,
             $this->_dataHelperMock,
-            $this->_dateMock,
-            $this->_tokenMock
+            $this->_dateMock
         );
         $this->_oauth = new \Magento\Framework\Oauth\Oauth(
             $this->_oauthHelperMock,
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Service/V1/AdminTokenServiceTest.php b/dev/tests/unit/testsuite/Magento/Integration/Service/V1/AdminTokenServiceTest.php
index 178183876f8..e69c373d791 100644
--- a/dev/tests/unit/testsuite/Magento/Integration/Service/V1/AdminTokenServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Integration/Service/V1/AdminTokenServiceTest.php
@@ -16,7 +16,7 @@ class AdminTokenServiceTest extends \PHPUnit_Framework_TestCase
     protected $_tokenService;
 
     /** \Magento\Integration\Model\Oauth\TokenFactory|\PHPUnit_Framework_MockObject_MockObject */
-    protected $_tokenModelFactoryMock;
+    protected $_tokenFactoryMock;
 
     /** \Magento\User\Model\User|\PHPUnit_Framework_MockObject_MockObject */
     protected $_userModelMock;
@@ -35,10 +35,11 @@ class AdminTokenServiceTest extends \PHPUnit_Framework_TestCase
 
     protected function setUp()
     {
-        $this->_tokenModelFactoryMock = $this->getMockBuilder('Magento\Integration\Model\Oauth\TokenFactory')
+        $this->_tokenFactoryMock = $this->getMockBuilder('Magento\Integration\Model\Oauth\TokenFactory')
             ->setMethods(['create'])
             ->disableOriginalConstructor()
             ->getMock();
+        $this->_tokenFactoryMock->expects($this->any())->method('create')->will($this->returnValue($this->_tokenMock));
 
         $this->_userModelMock = $this->getMockBuilder('Magento\User\Model\User')
             ->disableOriginalConstructor()
@@ -67,7 +68,7 @@ class AdminTokenServiceTest extends \PHPUnit_Framework_TestCase
         )->disableOriginalConstructor()->getMock();
 
         $this->_tokenService = new \Magento\Integration\Service\V1\AdminTokenService(
-            $this->_tokenModelFactoryMock,
+            $this->_tokenFactoryMock,
             $this->_userModelMock,
             $this->_tokenModelCollectionFactoryMock,
             $this->validatorHelperMock
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Service/V1/CustomerTokenServiceTest.php b/dev/tests/unit/testsuite/Magento/Integration/Service/V1/CustomerTokenServiceTest.php
index 4e189ffbe56..43704ebb9e0 100644
--- a/dev/tests/unit/testsuite/Magento/Integration/Service/V1/CustomerTokenServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Integration/Service/V1/CustomerTokenServiceTest.php
@@ -16,7 +16,7 @@ class CustomerTokenServiceTest extends \PHPUnit_Framework_TestCase
     protected $_tokenService;
 
     /** \Magento\Integration\Model\Oauth\TokenFactory|\PHPUnit_Framework_MockObject_MockObject */
-    protected $_tokenModelFactoryMock;
+    protected $_tokenFactoryMock;
 
     /** \Magento\Customer\Api\AccountManagementInterface|\PHPUnit_Framework_MockObject_MockObject */
     protected $_accountManagementMock;
@@ -35,10 +35,11 @@ class CustomerTokenServiceTest extends \PHPUnit_Framework_TestCase
 
     protected function setUp()
     {
-        $this->_tokenModelFactoryMock = $this->getMockBuilder('Magento\Integration\Model\Oauth\TokenFactory')
+        $this->_tokenFactoryMock = $this->getMockBuilder('Magento\Integration\Model\Oauth\TokenFactory')
             ->setMethods(['create'])
             ->disableOriginalConstructor()
             ->getMock();
+        $this->_tokenFactoryMock->expects($this->any())->method('create')->will($this->returnValue($this->_tokenMock));
 
         $this->_accountManagementMock = $this
             ->getMockBuilder('Magento\Customer\Api\AccountManagementInterface')
@@ -68,7 +69,7 @@ class CustomerTokenServiceTest extends \PHPUnit_Framework_TestCase
         )->disableOriginalConstructor()->getMock();
 
         $this->_tokenService = new \Magento\Integration\Service\V1\CustomerTokenService(
-            $this->_tokenModelFactoryMock,
+            $this->_tokenFactoryMock,
             $this->_accountManagementMock,
             $this->_tokenModelCollectionFactoryMock,
             $this->validatorHelperMock
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Service/V1/OauthTest.php b/dev/tests/unit/testsuite/Magento/Integration/Service/V1/OauthTest.php
index 1ee44f62ad4..b729d1a3626 100644
--- a/dev/tests/unit/testsuite/Magento/Integration/Service/V1/OauthTest.php
+++ b/dev/tests/unit/testsuite/Magento/Integration/Service/V1/OauthTest.php
@@ -61,11 +61,12 @@ class OauthTest extends \PHPUnit_Framework_TestCase
 
         $this->_tokenFactoryMock = $this->getMock(
             'Magento\Integration\Model\Oauth\TokenFactory',
-            [],
+            ['create'],
             [],
             '',
             false
         );
+        $this->_tokenFactoryMock->expects($this->any())->method('create')->will($this->returnValue($this->_tokenMock));
         $this->_consumerMock = $this->getMockBuilder(
             'Magento\Integration\Model\Oauth\Consumer'
         )->disableOriginalConstructor()->setMethods(
-- 
GitLab


From 1286c6a0361d2f8a54e5fcf02e7d3b0aed9d8d6d Mon Sep 17 00:00:00 2001
From: Sviatoslav Mankivskyi <smankivskyi@ebay.com>
Date: Fri, 19 Dec 2014 11:03:01 +0200
Subject: [PATCH 11/71] MAGETWO-31961: Exception when add configurable product
 from wishlist into cart(problem with product id and item_id)

---
 .../layout/wishlist_index_configure.xml        | 15 +++++++++++++++
 .../Magento/Wishlist/Controller/Index/Cart.php | 18 +++++++++++++++---
 2 files changed, 30 insertions(+), 3 deletions(-)
 create mode 100644 app/code/Magento/Review/view/frontend/layout/wishlist_index_configure.xml

diff --git a/app/code/Magento/Review/view/frontend/layout/wishlist_index_configure.xml b/app/code/Magento/Review/view/frontend/layout/wishlist_index_configure.xml
new file mode 100644
index 00000000000..94b9ab84772
--- /dev/null
+++ b/app/code/Magento/Review/view/frontend/layout/wishlist_index_configure.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+    <body>
+        <referenceBlock name="reviews.tab">
+            <block class="Magento\Review\Block\Form\Configure" name="product.review.form" as="review_form">
+                <container name="product.review.form.fields.before" as="form_fields_before" label="Review Form Fields Before"/>
+            </block>
+        </referenceBlock>
+    </body>
+</page>
diff --git a/app/code/Magento/Wishlist/Controller/Index/Cart.php b/app/code/Magento/Wishlist/Controller/Index/Cart.php
index e0508e6c0e2..27e2885c753 100644
--- a/app/code/Magento/Wishlist/Controller/Index/Cart.php
+++ b/app/code/Magento/Wishlist/Controller/Index/Cart.php
@@ -114,7 +114,7 @@ class Cart extends Action\Action implements IndexInterface
                 $refererUrl = $this->_redirect->getRefererUrl();
                 if ($refererUrl &&
                     ($refererUrl != $this->_objectManager->get('Magento\Framework\UrlInterface')
-                            ->getUrl('*/*/configure/', ['id' => $item->getId()])
+                            ->getUrl('*/*/configure/', ['id' => $item->getId(), 'product_id' => $item->getProductId()])
                     )
                 ) {
                     $redirectUrl = $refererUrl;
@@ -126,10 +126,22 @@ class Cart extends Action\Action implements IndexInterface
                 $this->messageManager->addError(__('This product(s) is out of stock.'));
             } elseif ($e->getCode() == \Magento\Wishlist\Model\Item::EXCEPTION_CODE_HAS_REQUIRED_OPTIONS) {
                 $this->messageManager->addNotice($e->getMessage());
-                $redirectUrl = $this->_url->getUrl('*/*/configure/', ['id' => $item->getId()]);
+                $redirectUrl = $this->_url->getUrl(
+                    '*/*/configure/',
+                    [
+                        'id' => $item->getId(),
+                        'product_id' => $item->getProductId(),
+                    ]
+                );
             } else {
                 $this->messageManager->addNotice($e->getMessage());
-                $redirectUrl = $this->_url->getUrl('*/*/configure/', ['id' => $item->getId()]);
+                $redirectUrl = $this->_url->getUrl(
+                    '*/*/configure/',
+                    [
+                        'id' => $item->getId(),
+                        'product_id' => $item->getProductId(),
+                    ]
+                );
             }
         } catch (\Exception $e) {
             $this->messageManager->addException($e, __('Cannot add item to shopping cart'));
-- 
GitLab


From b6d73d5bda49fbaa4b3432300e7eb45b983f1b02 Mon Sep 17 00:00:00 2001
From: agurzhyi <agurzhyi@ebay.com>
Date: Fri, 19 Dec 2014 11:07:57 +0200
Subject: [PATCH 12/71] MAGETWO-31784: Tax class drop-down on New Customer
 Group page should not contain value 'none'

---
 app/code/Magento/Tax/Model/TaxClass/Source/Customer.php | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php b/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php
index fecd324706d..3fd2d7ae699 100644
--- a/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php
+++ b/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php
@@ -5,8 +5,9 @@
 
 namespace Magento\Tax\Model\TaxClass\Source;
 
-use Magento\Tax\Api\Data\TaxClassInterface as TaxClass;
+use Magento\Framework\Exception\StateException;
 use Magento\Tax\Api\TaxClassManagementInterface;
+use Magento\Tax\Api\Data\TaxClassInterface as TaxClass;
 
 /**
  * Customer tax class source model.
@@ -49,13 +50,13 @@ class Customer extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
      * Retrieve all customer tax classes as an options array.
      *
      * @return array
+     * @throws StateException
      */
     public function getAllOptions()
     {
         if (empty($this->_options)) {
             $options = [];
-            $filter = $this->filterBuilder
-                ->setField(TaxClass::KEY_TYPE)
+            $filter = $this->filterBuilder->setField(TaxClass::KEY_TYPE)
                 ->setValue(TaxClassManagementInterface::TYPE_CUSTOMER)
                 ->create();
             $searchCriteria = $this->searchCriteriaBuilder->addFilter([$filter])->create();
@@ -67,7 +68,7 @@ class Customer extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
                 ];
             }
             if (empty($options)) {
-                $options = [['value' => '0', 'label' => __('None')]];
+                throw new StateException('Customer tax class cannot does not exist.');
             }
             $this->_options = $options;
         }
-- 
GitLab


From 60be08a73178acf24ba5c49470a8744ef1327604 Mon Sep 17 00:00:00 2001
From: Dmytro Aponasenko <daponasenko@ebay.com>
Date: Fri, 19 Dec 2014 12:14:14 +0200
Subject: [PATCH 13/71] MTA-589: Re-factor Test for Quick Search

---
 .../Constraint/AssertCatalogSearchResult.php  |  32 ++----
 ...sertProductCanBeOpenedFromSearchResult.php |  60 ++++++++++
 .../Test/Fixture/CatalogSearchQuery.php       |   2 +-
 .../Fixture/CatalogSearchQuery/QueryText.php  | 105 ++++++++++++++++++
 .../Fixture/CatalogSearchQuery/SearchData.php |  75 -------------
 .../Test/TestCase/SearchEntityResultsTest.php |  55 +++++++++
 .../TestCase/SearchEntityResultsTest/test.csv |   9 ++
 .../testSearch.csv                            |   4 +-
 .../CatalogSearch/Test/etc/constraint.xml     |   8 ++
 .../Test/Page/Adminhtml/SearchIndex.xml       |   2 +-
 .../TestCase/SearchTermsReportEntityTest.php  |   1 -
 .../Mtf/TestSuite/InjectableTests/bat_ce.xml  |   2 +
 .../InjectableTests/end_to_end_ce.xml         |   4 +-
 13 files changed, 257 insertions(+), 102 deletions(-)
 create mode 100644 dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertProductCanBeOpenedFromSearchResult.php
 create mode 100644 dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery/QueryText.php
 delete mode 100644 dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery/SearchData.php
 create mode 100644 dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SearchEntityResultsTest.php
 create mode 100644 dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SearchEntityResultsTest/test.csv

diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertCatalogSearchResult.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertCatalogSearchResult.php
index 03035ce728f..bc0d8f4c5c5 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertCatalogSearchResult.php
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertCatalogSearchResult.php
@@ -5,11 +5,12 @@
 
 namespace Magento\CatalogSearch\Test\Constraint;
 
+use Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery;
 use Magento\CatalogSearch\Test\Page\AdvancedResult;
 use Mtf\Constraint\AbstractConstraint;
 
 /**
- * Class AssertCatalogSearchResult
+ * Assert search results.
  */
 class AssertCatalogSearchResult extends AbstractConstraint
 {
@@ -18,40 +19,31 @@ class AssertCatalogSearchResult extends AbstractConstraint
     /* end tags */
 
     /**
-     * Assert that result page contains all products, according to search request, from fixture
+     * Assert that result page contains product, according to search request from fixture.
      *
-     * @param array $products
+     * @param CatalogSearchQuery $catalogSearch
      * @param AdvancedResult $resultPage
      * @return void
      */
-    public function processAssert(array $products, AdvancedResult $resultPage)
+    public function processAssert(CatalogSearchQuery $catalogSearch, AdvancedResult $resultPage)
     {
-        $errors = [];
-        foreach ($products as $product) {
-            $name = $product->getName();
+        $product = $catalogSearch->getDataFieldConfig('query_text')['source']->getProduct();
+        $name = $product->getName();
+        $isProductVisible = $resultPage->getListProductBlock()->isProductVisible($name);
+        while (!$isProductVisible && $resultPage->getBottomToolbar()->nextPage()) {
             $isProductVisible = $resultPage->getListProductBlock()->isProductVisible($name);
-            while (!$isProductVisible && $resultPage->getBottomToolbar()->nextPage()) {
-                $isProductVisible = $resultPage->getListProductBlock()->isProductVisible($name);
-            }
-
-            if ($isProductVisible === false) {
-                $errors[] = '- ' . $name;
-            }
         }
 
-        \PHPUnit_Framework_Assert::assertTrue(
-            empty($errors),
-            'Were not found the following products:' . implode("\n", $errors)
-        );
+        \PHPUnit_Framework_Assert::assertTrue($isProductVisible, "A product with name '$name' was not found.");
     }
 
     /**
-     * Returns a string representation of the object
+     * Returns a string representation of the object.
      *
      * @return string
      */
     public function toString()
     {
-        return 'All products have been successfully found.';
+        return 'Searched product has been successfully found.';
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertProductCanBeOpenedFromSearchResult.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertProductCanBeOpenedFromSearchResult.php
new file mode 100644
index 00000000000..8363237b6ac
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertProductCanBeOpenedFromSearchResult.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\CatalogSearch\Test\Constraint;
+
+use Mtf\Constraint\AbstractConstraint;
+use Magento\CatalogSearch\Test\Page\AdvancedResult;
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
+use Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery;
+
+/**
+ * Assert product can be opened from search results page.
+ */
+class AssertProductCanBeOpenedFromSearchResult extends AbstractConstraint
+{
+    /* tags */
+    const SEVERITY = 'high';
+    /* end tags */
+
+    /**
+     * Assert product can be opened from search results page.
+     *
+     * @param CatalogSearchQuery $catalogSearch
+     * @param AdvancedResult $resultPage
+     * @param CatalogProductView $catalogProductViewPage
+     * @return void
+     */
+    public function processAssert(
+        CatalogSearchQuery $catalogSearch,
+        AdvancedResult $resultPage,
+        CatalogProductView $catalogProductViewPage
+    ) {
+        $product = $catalogSearch->getDataFieldConfig('query_text')['source']->getProduct();
+        $productName = $product->getName();
+        $isProductVisible = $resultPage->getListProductBlock()->isProductVisible($productName);
+        while (!$isProductVisible && $resultPage->getBottomToolbar()->nextPage()) {
+            $isProductVisible = $resultPage->getListProductBlock()->isProductVisible($productName);
+        }
+        \PHPUnit_Framework_Assert::assertTrue($isProductVisible, "A product with name $productName was not found.");
+
+        $resultPage->getListProductBlock()->openProductViewPage($productName);
+        \PHPUnit_Framework_Assert::assertEquals(
+            $productName,
+            $catalogProductViewPage->getViewBlock()->getProductName(),
+            'Wrong product page has been opened.'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Product can be opened from search results page.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery.php
index 6fa48c95845..a7cf9414dd9 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery.php
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery.php
@@ -42,7 +42,7 @@ class CatalogSearchQuery extends InjectableFixture
         'is_required' => '',
         'default_value' => '',
         'input' => '',
-        'source' => 'Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery\SearchData',
+        'source' => 'Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery\QueryText',
     ];
 
     protected $num_results = [
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery/QueryText.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery/QueryText.php
new file mode 100644
index 00000000000..5018a19a16d
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery/QueryText.php
@@ -0,0 +1,105 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery;
+
+use Mtf\Fixture\FixtureFactory;
+use Mtf\Fixture\FixtureInterface;
+use Mtf\Fixture\InjectableFixture;
+
+/**
+ * Data to search for.
+ * Possible templates:
+ * - {value}
+ * - {product}::{product_property_to_search}
+ * - {product}::{product_dataSet}::{product_property_to_search}
+ */
+class QueryText implements FixtureInterface
+{
+    /**
+     * Entity to search.
+     *
+     * @var InjectableFixture
+     */
+    protected $product;
+
+    /**
+     * Resource data.
+     *
+     * @var string
+     */
+    protected $data;
+
+    /**
+     * @param FixtureFactory $fixtureFactory
+     * @param array $params
+     * @param array $data
+     */
+    public function __construct(FixtureFactory $fixtureFactory, array $params, array $data = [])
+    {
+        $this->params = $params;
+        $explodeValue = explode('::', $data['value']);
+        if (!empty($explodeValue) && count($explodeValue) > 1) {
+            $fixtureCode = $explodeValue[0];
+            $dataSet = isset($explodeValue[2]) ? $explodeValue[1] : '';
+            $searchValue = isset($explodeValue[2]) ? $explodeValue[2] : $explodeValue[1];
+            $this->product = $fixtureFactory->createByCode($fixtureCode, ['dataSet' => $dataSet]);
+            if (!$this->product->hasData('id')) {
+                $this->product->persist();
+            }
+            if ($this->product->hasData($searchValue)) {
+                $getProperty = 'get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $searchValue)));
+                $this->data = $this->product->$getProperty();
+            } else {
+                $this->data = $searchValue;
+            }
+        } else {
+            $this->data = strval($data['value']);
+        }
+    }
+
+    /**
+     * Persist custom selections products.
+     *
+     * @return void
+     */
+    public function persist()
+    {
+        //
+    }
+
+    /**
+     * Return prepared data.
+     *
+     * @param string|null $key
+     * @return string
+     *
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function getData($key = null)
+    {
+        return $this->data;
+    }
+
+    /**
+     * Return data set configuration settings.
+     *
+     * @return array
+     */
+    public function getDataConfig()
+    {
+        return $this->params;
+    }
+
+    /**
+     * Get product fixture to search.
+     *
+     * @return InjectableFixture
+     */
+    public function getProduct()
+    {
+        return $this->product;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery/SearchData.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery/SearchData.php
deleted file mode 100644
index ca125d27cd2..00000000000
--- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery/SearchData.php
+++ /dev/null
@@ -1,75 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- */
-
-namespace Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery;
-
-use Mtf\Fixture\FixtureFactory;
-use Mtf\Fixture\FixtureInterface;
-
-/**
- * Class SearchData
- * Data to search for
- */
-class SearchData implements FixtureInterface
-{
-    /**
-     * Resource data
-     *
-     * @var string
-     */
-    protected $data;
-
-    /**
-     * @param FixtureFactory $fixtureFactory
-     * @param array $params
-     * @param array $data
-     */
-    public function __construct(FixtureFactory $fixtureFactory, array $params, array $data = [])
-    {
-        $this->params = $params;
-        $explodeValue = explode('::', $data['value']);
-        if (!empty($explodeValue) && count($explodeValue) > 1) {
-            /** @var FixtureInterface $fixture */
-            $fixture = $fixtureFactory->createByCode($explodeValue[0]);
-            $fixture->persist();
-            $this->data = $fixture->$explodeValue[1]();
-        } else {
-            $this->data = strval($data['value']);
-        }
-    }
-
-    /**
-     * Persist custom selections products
-     *
-     * @return void
-     */
-    public function persist()
-    {
-        //
-    }
-
-    /**
-     * Return prepared data
-     *
-     * @param string|null $key
-     * @return string
-     *
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
-     */
-    public function getData($key = null)
-    {
-        return $this->data;
-    }
-
-    /**
-     * Return data set configuration settings
-     *
-     * @return array
-     */
-    public function getDataConfig()
-    {
-        return $this->params;
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SearchEntityResultsTest.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SearchEntityResultsTest.php
new file mode 100644
index 00000000000..c04b3e6d309
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SearchEntityResultsTest.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\CatalogSearch\Test\TestCase;
+
+use Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery;
+use Magento\Cms\Test\Page\CmsIndex;
+use Mtf\TestCase\Injectable;
+
+/**
+ * Preconditions:
+ * 1. All product types are created.
+ *
+ * Steps:
+ * 1. Navigate to frontend on index page.
+ * 2. Input test data into "search field" and press Enter key.
+ * 3. Perform all assertions.
+ *
+ * @group Search_Frontend_(MX)
+ * @ZephyrId MAGETWO-25095
+ */
+class SearchEntityResultsTest extends Injectable
+{
+    /**
+     * CMS index page.
+     *
+     * @var CmsIndex
+     */
+    protected $cmsIndex;
+
+    /**
+     * Inject data.
+     *
+     * @param CmsIndex $cmsIndex
+     * @return void
+     */
+    public function __inject(CmsIndex $cmsIndex)
+    {
+        $this->cmsIndex = $cmsIndex;
+    }
+
+    /**
+     * Run searching result test.
+     *
+     * @param CatalogSearchQuery $catalogSearch
+     * @return void
+     */
+    public function test(CatalogSearchQuery $catalogSearch)
+    {
+        $this->cmsIndex->open();
+        $this->cmsIndex->getSearchBlock()->search($catalogSearch->getQueryText());
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SearchEntityResultsTest/test.csv b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SearchEntityResultsTest/test.csv
new file mode 100644
index 00000000000..cf840f41556
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SearchEntityResultsTest/test.csv
@@ -0,0 +1,9 @@
+"description";"catalogSearch/data/query_text/value";"constraint";"tag"
+"MAGETWO-12420: Use Quick Search to Find the Product";"catalogProductSimple::default::sku";"","bamboo_plan:BAT"
+"Search simple product";"catalogProductSimple::default::simple";"assertCatalogSearchResult";""
+"Search virtual product";"catalogProductVirtual::default::virtual";"assertCatalogSearchResult";""
+"Search configurable product";"configurableProductInjectable::default::configurable";"assertCatalogSearchResult";""
+"Search downloadable product";"downloadableProductInjectable::default::downloadable";"assertCatalogSearchResult";""
+"Search grouped product";"groupedProductInjectable::default::grouped";"assertCatalogSearchResult";""
+"Search bundle dynamic product";"bundleProduct::bundle_dynamic_product::bundle";"assertCatalogSearchResult";""
+"Search fixed product";"bundleProduct::bundle_fixed_product::bundle";"assertCatalogSearchResult";""
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest/testSearch.csv b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest/testSearch.csv
index 2843f836b27..73e196ce0a2 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest/testSearch.csv
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest/testSearch.csv
@@ -1,3 +1,3 @@
 "catalogSearch/data/query_text/value";"catalogSearch/data/num_results";"constraint"
-"catalogProductSimple::getName";"-";"assertSuggestSearchingResult"
-"catalogProductSimple::getSku";"1";"assertSuggestSearchingResult"
+"catalogProductSimple::name";"-";"assertSuggestSearchingResult"
+"catalogProductSimple::sku";"1";"assertSuggestSearchingResult"
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/constraint.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/constraint.xml
index 5cb45afd90e..f4d04cfadc0 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/constraint.xml
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/constraint.xml
@@ -119,4 +119,12 @@
             <browser class="Mtf\Client\Browser" />
         </require>
     </assertSearchSynonymMassActionNotOnFrontend>
+    <assertProductCanBeOpenedFromSearchResult>
+        <severity>high</severity>
+        <require>
+            <catalogSearch class="Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery" />
+            <resultPage class="Magento\CatalogSearch\Test\Page\AdvancedResult" />
+            <catalogProductViewPage class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
+        </require>
+    </assertProductCanBeOpenedFromSearchResult>
 </constraint>
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/SearchIndex.xml b/dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/SearchIndex.xml
index a8287d2ce08..bbc913577f0 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/SearchIndex.xml
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/Page/Adminhtml/SearchIndex.xml
@@ -4,7 +4,7 @@
  * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  */
 -->
-<page mca="reports/index/search" module="Magento_Reports">
+<page mca="search/term/report/" module="Magento_Reports">
     <blocks>
         <searchGrid>
             <class>Magento\Reports\Test\Block\Adminhtml\SearchTermsGrid</class>
diff --git a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SearchTermsReportEntityTest.php b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SearchTermsReportEntityTest.php
index a1701cccd3a..dca52650288 100644
--- a/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SearchTermsReportEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Reports/Test/TestCase/SearchTermsReportEntityTest.php
@@ -72,7 +72,6 @@ class SearchTermsReportEntityTest extends Injectable
      */
     public function test($product, $countProducts, $countSearch)
     {
-        $this->markTestIncomplete('MAGETWO-30246');
         // Preconditions
         $productName = $this->createProducts($product, $countProducts);
 
diff --git a/dev/tests/functional/testsuites/Mtf/TestSuite/InjectableTests/bat_ce.xml b/dev/tests/functional/testsuites/Mtf/TestSuite/InjectableTests/bat_ce.xml
index 4f1bd6dcb30..78345d2193a 100644
--- a/dev/tests/functional/testsuites/Mtf/TestSuite/InjectableTests/bat_ce.xml
+++ b/dev/tests/functional/testsuites/Mtf/TestSuite/InjectableTests/bat_ce.xml
@@ -18,6 +18,8 @@
             <class value="Magento\Catalog\Test\TestCase\Category\CreateTest" />
             <!--Stores-->
             <class value="Magento\Store\Test\TestCase\StoreTest" />
+            <!--Quick Search-->
+            <class value="Magento\CatalogSearch\Test\TestCase\SearchEntityResultsTest" />
         </allow>
     </rule>
     <rule scope="variation">
diff --git a/dev/tests/functional/testsuites/Mtf/TestSuite/InjectableTests/end_to_end_ce.xml b/dev/tests/functional/testsuites/Mtf/TestSuite/InjectableTests/end_to_end_ce.xml
index 00c581aebaf..bd0624be9d6 100644
--- a/dev/tests/functional/testsuites/Mtf/TestSuite/InjectableTests/end_to_end_ce.xml
+++ b/dev/tests/functional/testsuites/Mtf/TestSuite/InjectableTests/end_to_end_ce.xml
@@ -32,8 +32,8 @@
             <class value="Magento\Catalog\Test\TestCase\Product\CrosssellTest" />
             <class value="Magento\Catalog\Test\TestCase\Product\RelatedProductTest" />
             <!--Url rewrites-->
-            <class value="Magento\Urlrewrite\Test\TestCase\ProductTest" />
-            <class value="Magento\Urlrewrite\Test\TestCase\CategoryTest" />
+            <class value="Magento\UrlRewrite\Test\TestCase\ProductTest" />
+            <class value="Magento\UrlRewrite\Test\TestCase\CategoryTest" />
             <!--Customer-->
             <class value="Magento\Customer\Test\TestCase\BackendCustomerCreateTest" />
             <class value="Magento\Customer\Test\TestCase\CreateOnFrontendTest" />
-- 
GitLab


From bd1301184813e6fb858fdb26e7b4d1fb6abdb652 Mon Sep 17 00:00:00 2001
From: agurzhyi <agurzhyi@ebay.com>
Date: Fri, 19 Dec 2014 12:22:54 +0200
Subject: [PATCH 14/71] MAGETWO-31784: Tax class drop-down on New Customer
 Group page should not contain value 'none'

---
 .../Model/TaxClass/Source/CustomerTest.php    | 30 ++++++++++++-------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/dev/tests/unit/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php b/dev/tests/unit/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php
index 182c1ddb283..4ccee7bf5b7 100644
--- a/dev/tests/unit/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php
+++ b/dev/tests/unit/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php
@@ -140,7 +140,6 @@ class CustomerTest extends \PHPUnit_Framework_TestCase
             ->with($searchCriteriaMock)
             ->willReturn($searchResultsMock);
 
-        $items = [];
         if (!$isEmpty) {
             $taxClassMock->expects($this->once())
                 ->method('getClassId')
@@ -148,17 +147,28 @@ class CustomerTest extends \PHPUnit_Framework_TestCase
             $taxClassMock->expects($this->once())
                 ->method('getClassName')
                 ->willReturn('class-name');
-            $items = [$taxClassMock];
-        }
 
-        $searchResultsMock->expects($this->once())
-            ->method('getItems')
-            ->willReturn($items);
+            $items = [$taxClassMock];
+            $searchResultsMock->expects($this->once())
+                ->method('getItems')
+                ->willReturn($items);
 
-        // checking of a lack of re-initialization
-        for ($i = 10; --$i;) {
-            $result = $this->customer->getAllOptions();
-            $this->assertEquals($expected, $result);
+            // checking of a lack of re-initialization
+            for ($i = 10; --$i;) {
+                $result = $this->customer->getAllOptions();
+                $this->assertEquals($expected, $result);
+            }
+        } else {
+            $items = [];
+            $searchResultsMock->expects($this->once())
+                ->method('getItems')
+                ->willReturn($items);
+            // checking exception
+            try {
+                $this->customer->getAllOptions();
+            } catch (\Exception $e) {
+                $this->assertInstanceOf('Magento\Framework\Exception\StateException', $e);
+            }
         }
     }
 
-- 
GitLab


From b788e28848a940509bb064266201d94a98312806 Mon Sep 17 00:00:00 2001
From: Andriy Nasinnyk <anasinnyk@ebay.com>
Date: Fri, 19 Dec 2014 13:29:28 +0200
Subject: [PATCH 15/71] MAGETWO-13915: PSR-3: common interface for logging
 libraries.

 - replace Magento\Framework\Logger to Psr\Log\LoggerInterface
---
 .../Resource/System/Message/Collection.php    |  4 +--
 .../Authorization/Model/Acl/AclRetriever.php  |  2 +-
 .../Authorization/Model/Resource/Rules.php    |  6 ++---
 .../Adminhtml/Authorizenet/Payment/Cancel.php |  4 +--
 .../Authorizenet/Payment/Cancel.php           |  4 +--
 .../Controller/Directpost/Payment.php         |  4 +--
 .../Authorizenet/Model/Authorizenet.php       |  8 +++---
 .../Magento/Authorizenet/Model/Directpost.php |  8 +++---
 app/code/Magento/Backend/Block/Context.php    |  4 +--
 .../Backend/Block/Template/Context.php        |  4 +--
 .../Magento/Backend/Block/Widget/Context.php  |  4 +--
 .../Controller/Adminhtml/Dashboard/Tunnel.php |  2 +-
 .../System/Config/System/Storage/Status.php   |  2 +-
 .../Config/System/Storage/Synchronize.php     |  2 +-
 app/code/Magento/Backend/Model/Menu.php       | 17 ++++--------
 .../Backend/Model/Menu/AbstractDirector.php   |  4 +--
 .../Magento/Backend/Model/Menu/Config.php     |  6 ++---
 .../Backend/Model/Menu/Director/Director.php  |  9 +++----
 .../Magento/Backend/etc/adminhtml/system.xml  |  4 +--
 app/code/Magento/Backend/i18n/de_DE.csv       |  2 +-
 app/code/Magento/Backend/i18n/en_US.csv       |  2 +-
 app/code/Magento/Backend/i18n/es_ES.csv       |  2 +-
 app/code/Magento/Backend/i18n/fr_FR.csv       |  2 +-
 app/code/Magento/Backend/i18n/nl_NL.csv       |  2 +-
 app/code/Magento/Backend/i18n/pt_BR.csv       |  2 +-
 app/code/Magento/Backend/i18n/zh_CN.csv       |  2 +-
 .../Controller/Adminhtml/Index/Create.php     |  4 +--
 .../Controller/Adminhtml/Index/Rollback.php   |  4 +--
 app/code/Magento/Backup/Model/Observer.php    |  6 ++---
 .../Magento/Bundle/Model/Product/Type.php     |  4 +--
 .../Magento/Catalog/Block/Product/Context.php |  4 +--
 .../Controller/Adminhtml/Category/Move.php    |  6 ++---
 .../Controller/Adminhtml/Product/Builder.php  |  4 +--
 .../Adminhtml/Product/Duplicate.php           |  2 +-
 .../Controller/Adminhtml/Product/Save.php     |  2 +-
 .../Catalog/Controller/Category/View.php      |  2 +-
 .../Catalog/Controller/Product/View.php       |  2 +-
 .../Category/Attribute/Backend/Image.php      |  6 ++---
 .../Model/Product/Type/AbstractType.php       |  6 ++---
 .../Category/Attribute/Collection.php         |  4 +--
 .../Resource/Category/Flat/Collection.php     |  2 +-
 .../Collection/AbstractCollection.php         |  4 +--
 .../Resource/Product/Attribute/Collection.php |  4 +--
 .../Model/Resource/Product/Collection.php     |  4 +--
 .../Product/Compare/Item/Collection.php       |  4 +--
 .../Resource/Product/Option/Collection.php    |  4 +--
 .../Magento/Catalog/Model/Resource/Url.php    |  6 ++---
 .../Model/Export/Product.php                  |  6 ++---
 .../Model/Import/Product.php                  |  6 ++---
 .../Stock/Item/StockItemCriteriaMapper.php    |  2 +-
 .../Adminhtml/Promo/Catalog/ApplyRules.php    |  2 +-
 .../Adminhtml/Promo/Catalog/Delete.php        |  2 +-
 .../Adminhtml/Promo/Catalog/Save.php          |  2 +-
 .../Model/Indexer/IndexBuilder.php            |  6 ++---
 .../CatalogRule/Model/Resource/Rule.php       |  6 ++---
 .../Model/Resource/Advanced/Collection.php    |  4 +--
 .../Model/Resource/Fulltext/Collection.php    |  4 +--
 .../Model/Resource/Search/Collection.php      |  4 +--
 .../Centinel/Index/ValidatePaymentData.php    |  2 +-
 app/code/Magento/Centinel/Model/Api.php       |  6 ++---
 .../Magento/Checkout/Controller/Cart/Add.php  |  2 +-
 .../Checkout/Controller/Cart/Addgroup.php     |  2 +-
 .../Checkout/Controller/Cart/Configure.php    |  2 +-
 .../Checkout/Controller/Cart/CouponPost.php   |  2 +-
 .../Checkout/Controller/Cart/Delete.php       |  2 +-
 .../Controller/Cart/UpdateItemOptions.php     |  2 +-
 .../Checkout/Controller/Cart/UpdatePost.php   |  2 +-
 .../Checkout/Controller/Onepage/SaveOrder.php |  4 +--
 .../Controller/Onepage/SavePayment.php        |  2 +-
 .../Magento/Checkout/Model/Type/Onepage.php   |  6 ++---
 .../V1/Address/Billing/WriteService.php       |  2 +-
 .../V1/Address/Shipping/WriteService.php      |  2 +-
 .../Adminhtml/Wysiwyg/Directive.php           |  2 +-
 .../Model/Resource/Page/Grid/Collection.php   |  4 +--
 .../Model/Product/Type/Configurable.php       |  4 +--
 .../Product/Collection/AssociatedProduct.php  |  4 +--
 .../Configurable/Attribute/Collection.php     |  4 +--
 .../Magento/Core/Model/File/Storage/File.php  |  6 ++---
 app/code/Magento/Core/Model/Layout/Merge.php  |  6 ++---
 app/code/Magento/Core/Model/Observer.php      |  6 ++---
 .../Core/Model/Resource/Design/Collection.php |  4 +--
 .../Core/Model/Resource/File/Storage/File.php |  6 ++---
 .../Model/Resource/Layout/Link/Collection.php |  4 +--
 .../Resource/Layout/Update/Collection.php     |  4 +--
 .../Customer/Controller/Account/LoginPost.php |  2 +-
 .../Controller/Adminhtml/Index/Wishlist.php   |  2 +-
 .../Customer/Model/AccountManagement.php      |  2 +-
 .../Model/Attribute/Data/Postcode.php         |  2 +-
 .../Model/Metadata/Form/AbstractData.php      |  6 ++---
 .../Customer/Model/Metadata/Form/File.php     |  4 +--
 .../Customer/Model/Metadata/Form/Postcode.php |  2 +-
 .../Customer/Model/Metadata/Form/Text.php     |  4 +--
 .../Model/Resource/Customer/Collection.php    |  4 +--
 app/code/Magento/Customer/Model/Vat.php       |  2 +-
 .../Adminhtml/System/Design/Editor.php        |  2 +-
 .../Design/Editor/AssignThemeToStore.php      |  2 +-
 .../System/Design/Editor/Duplicate.php        |  4 +--
 .../System/Design/Editor/Files/TreeJson.php   |  2 +-
 .../Adminhtml/System/Design/Editor/Launch.php |  4 +--
 .../System/Design/Editor/LoadThemeList.php    |  2 +-
 .../System/Design/Editor/QuickEdit.php        |  4 +--
 .../Adminhtml/System/Design/Editor/Revert.php |  2 +-
 .../Adminhtml/System/Design/Editor/Save.php   |  2 +-
 .../Design/Editor/Tools/DeleteCustomFiles.php |  2 +-
 .../System/Design/Editor/Tools/JsList.php     |  2 +-
 .../Editor/Tools/RemoveQuickStyleImage.php    |  4 +--
 .../Design/Editor/Tools/RemoveStoreLogo.php   |  4 +--
 .../System/Design/Editor/Tools/ReorderJs.php  |  4 +--
 .../Design/Editor/Tools/SaveCssContent.php    |  4 +--
 .../Design/Editor/Tools/SaveImageSizing.php   |  4 +--
 .../Design/Editor/Tools/SaveQuickStyles.php   |  4 +--
 .../System/Design/Editor/Tools/Upload.php     |  4 +--
 .../System/Design/Editor/Tools/UploadJs.php   |  4 +--
 .../Editor/Tools/UploadQuickStyleImage.php    |  4 +--
 .../Design/Editor/Tools/UploadStoreLogo.php   |  4 +--
 app/code/Magento/Dhl/Model/Carrier.php        |  4 +--
 .../Magento/Directory/Model/PriceCurrency.php |  2 +-
 .../Model/Resource/Country/Collection.php     |  4 +--
 .../Model/Resource/Region/Collection.php      |  4 +--
 .../Downloadable/Model/Product/Type.php       |  4 +--
 .../Eav/Model/Attribute/Data/AbstractData.php |  6 ++---
 .../Magento/Eav/Model/Attribute/Data/File.php |  4 +--
 .../Magento/Eav/Model/Attribute/Data/Text.php |  4 +--
 .../Entity/Collection/AbstractCollection.php  |  4 +--
 .../Eav/Model/Entity/Setup/Context.php        |  4 +--
 .../Model/Resource/Attribute/Collection.php   |  4 +--
 .../Resource/Entity/Attribute/Collection.php  |  4 +--
 .../Entity/Attribute/Grid/Collection.php      |  4 +--
 .../Entity/Attribute/Option/Collection.php    |  4 +--
 .../Resource/Form/Attribute/Collection.php    |  4 +--
 .../Resource/Form/Fieldset/Collection.php     |  2 +-
 .../Email/Template/DefaultTemplate.php        |  2 +-
 .../Adminhtml/Email/Template/Delete.php       |  2 +-
 .../Magento/Email/Model/Template/Filter.php   |  6 ++---
 app/code/Magento/Fedex/Model/Carrier.php      |  6 ++---
 .../Googleshopping/Items/ConfirmCaptcha.php   |  2 +-
 .../Googleshopping/Items/MassAdd.php          |  2 +-
 .../Googleshopping/Items/Refresh.php          |  2 +-
 .../Adminhtml/Googleshopping/Types/Delete.php |  2 +-
 .../Adminhtml/Googleshopping/Types/Edit.php   |  2 +-
 .../Types/LoadAttributeSets.php               |  2 +-
 .../Googleshopping/Types/LoadAttributes.php   |  2 +-
 .../Googleshopping/Types/NewAction.php        |  2 +-
 .../Adminhtml/Googleshopping/Types/Save.php   |  2 +-
 .../GoogleShopping/Model/MassOperations.php   |  6 ++---
 .../Model/Resource/Item/Collection.php        |  4 +--
 .../Magento/GoogleShopping/Model/Service.php  |  6 ++---
 .../GoogleShopping/Model/Service/Item.php     |  4 +--
 .../Controller/Adminhtml/Edit/Popup.php       |  6 ++---
 .../Model/Product/Type/Grouped.php            |  4 +--
 .../Grouped/AssociatedProductsCollection.php  |  4 +--
 .../Controller/Adminhtml/Export/Export.php    |  2 +-
 .../ImportExport/Model/AbstractModel.php      |  6 ++---
 .../Magento/ImportExport/Model/Export.php     |  4 +--
 .../Magento/ImportExport/Model/Import.php     |  4 +--
 .../Controller/Adminhtml/Integration.php      |  6 ++---
 .../Service/V1/AuthorizationService.php       |  2 +-
 .../Magento/Integration/Service/V1/Oauth.php  |  6 ++---
 .../Resource/Visitor/Online/Collection.php    |  4 +--
 .../Visitor/Online/Grid/Collection.php        |  4 +--
 .../Controller/Checkout/Overview.php          |  2 +-
 .../Controller/Checkout/OverviewPost.php      |  2 +-
 .../Model/Resource/Problem/Collection.php     |  4 +--
 .../Model/Resource/Queue/Collection.php       |  4 +--
 .../Model/Resource/Subscriber/Collection.php  |  4 +--
 .../Model/Carrier/Flatrate.php                |  4 +--
 .../Model/Carrier/Freeshipping.php            |  4 +--
 .../OfflineShipping/Model/Carrier/Pickup.php  |  4 +--
 .../Model/Carrier/Tablerate.php               |  4 +--
 .../Model/Resource/Carrier/Tablerate.php      |  6 ++---
 app/code/Magento/Ogone/Model/Api.php          |  4 +--
 .../Payment/Model/Method/AbstractMethod.php   |  6 ++---
 app/code/Magento/Payment/Model/Method/Cc.php  | 10 +++----
 .../Magento/Payment/Model/Method/Free.php     |  4 +--
 .../Adminhtml/Billing/Agreement/Cancel.php    |  2 +-
 .../Adminhtml/Billing/Agreement/Delete.php    |  2 +-
 .../Controller/Adminhtml/Paypal/Reports.php   |  6 ++---
 .../Controller/Billing/Agreement/Cancel.php   |  2 +-
 .../Billing/Agreement/ReturnWizard.php        |  2 +-
 .../Billing/Agreement/StartWizard.php         |  2 +-
 .../Express/AbstractExpress/Cancel.php        |  2 +-
 .../Express/AbstractExpress/PlaceOrder.php    |  2 +-
 .../Express/AbstractExpress/ReturnAction.php  |  2 +-
 .../Express/AbstractExpress/Review.php        |  2 +-
 .../AbstractExpress/SaveShippingMethod.php    |  2 +-
 .../ShippingOptionsCallback.php               |  2 +-
 .../Express/AbstractExpress/Start.php         |  2 +-
 .../AbstractExpress/UpdateShippingMethods.php |  2 +-
 .../Magento/Paypal/Controller/Ipn/Index.php   |  6 ++---
 .../Magento/Paypal/Controller/Payflow.php     |  6 ++---
 app/code/Magento/Paypal/Model/AbstractIpn.php |  4 +--
 .../Magento/Paypal/Model/Api/AbstractApi.php  | 12 ++++-----
 app/code/Magento/Paypal/Model/Api/Nvp.php     |  8 +++---
 .../Magento/Paypal/Model/Api/PayflowNvp.php   |  8 +++---
 app/code/Magento/Paypal/Model/Direct.php      |  8 +++---
 app/code/Magento/Paypal/Model/Express.php     |  4 +--
 .../Magento/Paypal/Model/Express/Checkout.php | 12 ++++-----
 app/code/Magento/Paypal/Model/Hostedpro.php   |  8 +++---
 app/code/Magento/Paypal/Model/Ipn.php         |  4 +--
 .../Magento/Paypal/Model/Method/Agreement.php |  4 +--
 app/code/Magento/Paypal/Model/Observer.php    |  6 ++---
 .../Magento/Paypal/Model/PayflowExpress.php   |  4 +--
 app/code/Magento/Paypal/Model/Payflowlink.php |  8 +++---
 app/code/Magento/Paypal/Model/Payflowpro.php  |  8 +++---
 .../Method/Billing/AbstractAgreement.php      |  4 +--
 .../Resource/Billing/Agreement/Collection.php |  4 +--
 app/code/Magento/Paypal/Model/Standard.php    |  4 +--
 .../Adminhtml/Report/Product/Viewed.php       |  2 +-
 .../Report/Statistics/RefreshLifetime.php     |  2 +-
 .../Report/Statistics/RefreshRecent.php       |  2 +-
 .../Model/Resource/Customer/Collection.php    |  4 +--
 .../Model/Resource/Order/Collection.php       |  4 +--
 .../Model/Resource/Product/Collection.php     |  4 +--
 .../Index/Collection/AbstractCollection.php   |  4 +--
 .../Resource/Product/Lowstock/Collection.php  |  4 +--
 .../Model/Resource/Quote/Collection.php       |  4 +--
 .../Model/Resource/Report/AbstractReport.php  |  6 ++---
 .../Model/Resource/Report/Product/Viewed.php  |  4 +--
 .../Report/Product/Viewed/Collection.php      |  4 +--
 .../Resource/Review/Customer/Collection.php   |  4 +--
 .../Model/Resource/Wishlist/Collection.php    |  4 +--
 .../Magento/Review/Controller/Product.php     |  6 ++---
 .../Magento/Review/Model/Resource/Rating.php  |  6 ++---
 .../Model/Resource/Rating/Collection.php      |  4 +--
 .../Model/Resource/Rating/Grid/Collection.php |  4 +--
 .../Rating/Option/Vote/Collection.php         |  4 +--
 .../Model/Resource/Review/Collection.php      |  4 +--
 .../Resource/Review/Product/Collection.php    |  4 +--
 .../Resource/Review/Summary/Collection.php    |  4 +--
 .../Action/Plugin/BackendAuthentication.php   |  6 ++---
 app/code/Magento/Rss/Controller/Feed.php      |  6 ++---
 .../Magento/Rule/Model/Condition/Combine.php  |  2 +-
 .../Magento/Rule/Model/Condition/Context.php  |  8 +++---
 .../Controller/Adminhtml/Order/Cancel.php     |  2 +-
 .../Adminhtml/Order/Creditmemo/Save.php       |  2 +-
 .../Controller/Adminhtml/Order/Email.php      |  2 +-
 .../Adminhtml/Order/Invoice/Save.php          |  6 ++---
 .../Adminhtml/Order/ReviewPayment.php         |  2 +-
 .../Sales/Controller/Adminhtml/Order/View.php |  2 +-
 .../Adminhtml/Order/VoidPayment.php           |  2 +-
 .../Adminhtml/Transactions/Fetch.php          |  2 +-
 .../Magento/Sales/Model/AbstractNotifier.php  |  4 +--
 .../Magento/Sales/Model/AdminOrder/Create.php |  6 ++---
 .../Sales/Model/AdminOrder/EmailSender.php    |  2 +-
 .../Magento/Sales/Model/Config/Ordered.php    |  6 ++---
 .../Sales/Model/Order/CreditmemoNotifier.php  |  4 +--
 .../Sales/Model/Order/InvoiceNotifier.php     |  4 +--
 .../Sales/Model/Order/Total/Config/Base.php   |  4 +--
 .../Magento/Sales/Model/OrderNotifier.php     |  4 +--
 .../Model/Quote/Address/Total/Collector.php   |  4 +--
 .../Sales/Model/Resource/Order/Collection.php |  4 +--
 .../Creditmemo/Order/Grid/Collection.php      |  4 +--
 .../Order/Invoice/Orders/Grid/Collection.php  |  4 +--
 .../Resource/Order/Payment/Collection.php     |  4 +--
 .../Order/Shipment/Order/Grid/Collection.php  |  4 +--
 .../Sales/Model/Resource/Order/Status.php     |  4 +--
 .../Quote/Address/Rate/Collection.php         |  4 +--
 .../Model/Resource/Quote/Item/Collection.php  |  4 +--
 .../Resource/Quote/Payment/Collection.php     |  4 +--
 .../Model/Resource/Report/Bestsellers.php     |  4 +--
 .../Report/Bestsellers/Collection.php         |  4 +--
 .../Report/Collection/AbstractCollection.php  |  4 +--
 .../Report/Invoiced/Collection/Invoiced.php   |  4 +--
 .../Report/Invoiced/Collection/Order.php      |  4 +--
 .../Sales/Model/Resource/Report/Order.php     |  4 +--
 .../Resource/Report/Order/Collection.php      |  4 +--
 .../Report/Refunded/Collection/Order.php      |  4 +--
 .../Report/Refunded/Collection/Refunded.php   |  4 +--
 .../Report/Shipping/Collection/Order.php      |  4 +--
 .../Report/Shipping/Collection/Shipment.php   |  4 +--
 .../Sales/Model/Resource/Sale/Collection.php  |  2 +-
 .../Resource/Transaction/Grid/Collection.php  |  4 +--
 .../Adminhtml/Promo/Quote/Delete.php          |  2 +-
 .../Adminhtml/Promo/Quote/Generate.php        |  2 +-
 .../Controller/Adminhtml/Promo/Quote/Save.php |  2 +-
 .../Model/Resource/Report/Collection.php      |  4 +--
 .../SalesRule/Model/Resource/Report/Rule.php  |  4 +--
 .../Model/Resource/Rule/Collection.php        |  4 +--
 .../Model/Resource/Query/Collection.php       |  4 +--
 .../Adminhtml/Order/Shipment/CreateLabel.php  |  2 +-
 .../Adminhtml/Order/Shipment/PrintLabel.php   |  2 +-
 .../Adminhtml/Order/Shipment/Save.php         |  2 +-
 .../Model/Carrier/AbstractCarrier.php         |  6 ++---
 .../Model/Carrier/AbstractCarrierOnline.php   |  4 +--
 .../Shipping/Model/ShipmentNotifier.php       |  4 +--
 .../Resource/Config/Collection/Scoped.php     |  4 +--
 .../Magento/Store/Model/StorageFactory.php    |  2 +-
 .../Resource/Calculation/Rate/Collection.php  |  4 +--
 .../Tax/Model/Resource/Report/Collection.php  |  4 +--
 .../Magento/Tax/Model/Resource/Report/Tax.php |  4 +--
 .../Adminhtml/System/Design/Theme/Delete.php  |  2 +-
 .../System/Design/Theme/DownloadCss.php       |  2 +-
 .../System/Design/Theme/DownloadCustomCss.php |  2 +-
 .../Adminhtml/System/Design/Theme/Edit.php    |  2 +-
 .../Adminhtml/System/Design/Theme/Save.php    |  2 +-
 .../System/Design/Theme/UploadCss.php         |  2 +-
 .../System/Design/Theme/UploadJs.php          |  2 +-
 .../System/Design/Wysiwyg/Files/NewFolder.php |  2 +-
 .../Design/Wysiwyg/Files/PreviewImage.php     |  2 +-
 .../System/Design/Wysiwyg/Files/TreeJson.php  |  2 +-
 .../Magento/Theme/Model/Wysiwyg/Storage.php   |  2 +-
 app/code/Magento/Ups/Model/Carrier.php        |  6 ++---
 .../Model/Resource/UrlRewriteCollection.php   |  4 +--
 app/code/Magento/Usps/Model/Carrier.php       |  4 +--
 .../Webapi/Controller/ErrorProcessor.php      |  6 ++---
 .../Controller/Adminhtml/Widget/Instance.php  |  6 ++---
 .../Magento/Widget/Model/Template/Filter.php  |  4 +--
 .../Magento/Wishlist/Controller/Index/Add.php |  2 +-
 .../Wishlist/Controller/Index/Configure.php   |  2 +-
 .../Wishlist/Controller/Index/Update.php      |  2 +-
 .../Controller/Index/UpdateItemOptions.php    |  2 +-
 .../Magento/Wishlist/Model/ItemCarrier.php    |  4 +--
 .../Model/Resource/Item/Collection.php        |  4 +--
 .../Model/Resource/Item/Collection/Grid.php   |  4 +--
 .../Generate/Repository/TableCollection.php   |  4 +--
 .../Magento/TestFramework/Application.php     |  6 ++---
 .../TestFramework/ErrorLog/Listener.php       |  2 +-
 .../Magento/TestFramework/ErrorLog/Logger.php |  2 +-
 .../Magento/Backend/Model/SessionTest.php     |  2 +-
 .../Model/Product/Type/AbstractTypeTest.php   |  2 +-
 .../Customer/Controller/AddressTest.php       |  2 +-
 .../Resource/Db/Collection/AbstractTest.php   |  2 +-
 .../Multishipping/Controller/CheckoutTest.php |  2 +-
 .../Magento/Paypal/Model/VoidTest.php         |  4 +--
 .../Magento/Sendfriend/Block/SendTest.php     |  2 +-
 .../Translation/Model/InlineParserTest.php    |  2 +-
 .../Magento/Wishlist/Controller/IndexTest.php |  2 +-
 .../Test/Legacy/_files/obsolete_classes.php   |  6 ++---
 .../Legacy/_files/obsolete_namespaces.php     |  2 +-
 .../Legacy/_files/obsolete_properties.php     |  2 +-
 .../Magento/Test/Block/Adminhtml.php          |  2 +-
 .../Model/Acl/AclRetrieverTest.php            |  2 +-
 .../Adminhtml/Dashboard/TunnelTest.php        |  4 +--
 .../Model/Config/Backend/BaseurlTest.php      |  2 +-
 .../Model/Config/Backend/SecureTest.php       |  2 +-
 .../Model/Config/Source/Admin/PageTest.php    |  2 +-
 .../Backend/Model/Menu/BuilderTest.php        |  2 +-
 .../Magento/Backend/Model/Menu/ConfigTest.php | 10 ++-----
 .../Model/Menu/Director/DirectorTest.php      |  8 +-----
 .../Model/Menu/Filter/IteratorTest.php        |  2 +-
 .../Magento/Backend/Model/Menu/ItemTest.php   |  2 +-
 .../Magento/Backend/Model/MenuTest.php        | 26 +++----------------
 .../Magento/Backend/Model/UrlTest.php         |  2 +-
 .../Adminhtml/Product/BuilderTest.php         |  2 +-
 .../Catalog/Model/Product/Type/SimpleTest.php |  2 +-
 .../Model/Product/Type/VirtualTest.php        |  2 +-
 .../Product/Link/Product/CollectionTest.php   |  2 +-
 .../Product/Option/CollectionTest.php         |  4 +--
 .../Pricing/Render/FinalPriceBoxTest.php      |  4 +--
 .../Model/Import/Product/Type/OptionTest.php  |  2 +-
 .../Checkout/Model/Type/OnepageTest.php       |  4 +--
 .../V1/Address/Billing/WriteServiceTest.php   |  2 +-
 .../Model/Resource/PageCriteriaMapperTest.php | 10 ++-----
 .../Model/Product/Type/ConfigurableTest.php   |  2 +-
 .../File/Storage/Directory/DatabaseTest.php   |  4 +--
 .../Core/Model/File/Storage/MediaTest.php     |  2 +-
 .../Magento/Core/Model/Layout/MergeTest.php   |  2 +-
 .../Model/Resource/File/Storage/FileTest.php  |  2 +-
 .../Resource/Layout/Link/CollectionTest.php   |  2 +-
 .../Resource/Layout/Update/CollectionTest.php |  2 +-
 .../Model/Attribute/Data/PostcodeTest.php     |  5 ++--
 .../Attribute/Backend/BillingTest.php         |  4 +--
 .../Attribute/Backend/ShippingTest.php        |  4 +--
 .../Model/Metadata/Form/AbstractDataTest.php  |  4 +--
 .../Metadata/Form/AbstractFormTestCase.php    |  4 +--
 .../Directory/Model/PriceCurrencyTest.php     |  3 +--
 .../Model/Resource/Country/CollectionTest.php |  2 +-
 .../Downloadable/Model/Product/TypeTest.php   |  2 +-
 .../Model/Attribute/Data/AbstractDataTest.php |  2 +-
 .../Eav/Model/Attribute/Data/BooleanTest.php  |  2 +-
 .../Eav/Model/Attribute/Data/DateTest.php     |  2 +-
 .../Eav/Model/Attribute/Data/FileTest.php     |  2 +-
 .../Eav/Model/Attribute/Data/ImageTest.php    |  2 +-
 .../Model/Attribute/Data/MultilineTest.php    |  2 +-
 .../Model/Attribute/Data/MultiselectTest.php  |  2 +-
 .../Eav/Model/Attribute/Data/SelectTest.php   |  2 +-
 .../Eav/Model/Attribute/Data/TextTest.php     |  2 +-
 .../Entity/Attribute/Backend/ArrayTest.php    |  2 +-
 .../Collection/AbstractCollectionTest.php     |  4 +--
 .../Resource/Attribute/CollectionTest.php     |  4 +--
 .../Attribute/Option/CollectionTest.php       |  4 +--
 .../Block/Adminhtml/Template/EditTest.php     |  2 +-
 .../Magento/Fedex/Model/CarrierTest.php       |  2 +-
 .../Magento/Framework/App/BootstrapTest.php   |  6 ++---
 .../Framework/DB/AbstractMapperTest.php       | 10 ++-----
 .../Magento/Framework/DB/QueryTest.php        | 10 ++-----
 .../Framework/Data/Collection/DbTest.php      |  4 +--
 .../Model/AbstractExtensibleModelTest.php     |  2 +-
 .../Framework/Model/AbstractModelTest.php     |  2 +-
 .../Db/Collection/AbstractCollectionTest.php  |  4 +--
 .../Framework/Module/Setup/MigrationTest.php  |  4 +--
 .../Framework/View/Asset/MergedTest.php       |  2 +-
 .../Framework/View/Asset/MinifiedTest.php     |  4 +--
 .../Magento/Framework/View/ContextTest.php    |  2 +-
 .../Framework/View/Design/Theme/ImageTest.php |  2 +-
 .../View/Page/Config/RendererTest.php         |  5 ++--
 .../Googleshopping/Items/MassAddTest.php      |  5 ++--
 .../Googleshopping/Items/RefreshTest.php      |  5 ++--
 .../Model/MassOperationsTest.php              |  4 +--
 .../Model/Product/Type/GroupedTest.php        |  2 +-
 .../Magento/ImportExport/Model/ExportTest.php |  2 +-
 .../CollectionByPagesIteratorTest.php         |  2 +-
 .../Controller/Adminhtml/IntegrationTest.php  |  4 +--
 .../Integration/Helper/Oauth/ConsumerTest.php |  6 ++---
 .../Service/V1/AuthorizationServiceTest.php   |  2 +-
 .../Integration/Service/V1/OauthTest.php      |  2 +-
 .../Model/BanktransferTest.php                |  2 +-
 .../Model/CashondeliveryTest.php              |  2 +-
 .../testsuite/Magento/Ogone/Model/ApiTest.php |  2 +-
 .../Block/Info/ContainerAbstractTest.php      |  2 +-
 .../Magento/Payment/Model/Method/FreeTest.php |  2 +-
 .../Paypal/Controller/Ipn/IndexTest.php       |  4 +--
 .../Magento/Paypal/Model/Api/NvpTest.php      |  6 ++---
 .../Magento/Paypal/Model/IpnTest.php          |  4 +--
 .../Collection/AbstractCollectionTest.php     |  2 +-
 .../Review/Summary/CollectionTest.php         |  4 +--
 .../Rule/Model/Condition/CombineTest.php      |  4 +--
 .../Collection/AbstractCollectionTest.php     |  4 +--
 .../Sales/Model/AdminOrder/CreateTest.php     |  2 +-
 .../Model/AdminOrder/EmailSenderTest.php      |  2 +-
 .../Model/Order/CreditmemoNotifierTest.php    |  8 +-----
 .../Sales/Model/Order/InvoiceNotifierTest.php |  8 +-----
 .../Model/Order/Total/Config/BaseTest.php     |  4 +--
 .../Magento/Sales/Model/OrderNotifierTest.php |  8 +-----
 .../Order/Status/History/CollectionTest.php   |  2 +-
 .../Model/Resource/Report/CollectionTest.php  |  8 +-----
 .../Order/Shipment/CreateLabelTest.php        | 10 ++-----
 .../Order/Shipment/PrintLabelTest.php         | 10 ++-----
 .../Shipping/Model/ShipmentNotifierTest.php   |  8 +-----
 .../System/Design/Theme/IndexTest.php         |  2 +-
 .../Webapi/Controller/ErrorProcessorTest.php  |  4 +--
 lib/internal/Magento/Framework/App/Area.php   |  6 ++---
 .../Magento/Framework/App/Bootstrap.php       |  2 +-
 .../Framework/App/Helper/AbstractHelper.php   |  2 +-
 .../Magento/Framework/App/Helper/Context.php  |  8 +++---
 .../Magento/Framework/DB/AbstractMapper.php   |  2 +-
 lib/internal/Magento/Framework/DB/Query.php   |  2 +-
 .../Data/AbstractSearchCriteriaBuilder.php    |  2 +-
 .../Magento/Framework/Data/Collection/Db.php  |  2 +-
 .../Image/Adapter/AbstractAdapter.php         |  2 +-
 .../Less/PreProcessor/ErrorHandler.php        |  6 ++---
 .../Magento/Framework/Message/Manager.php     |  2 +-
 .../Magento/Framework/Model/AbstractModel.php |  2 +-
 .../Magento/Framework/Model/Context.php       |  8 +++---
 .../Db/Collection/AbstractCollection.php      |  4 +--
 .../Magento/Framework/Module/DataSetup.php    |  2 +-
 .../Framework/Module/Setup/Context.php        |  8 +++---
 .../Magento/Framework/View/Asset/Merged.php   |  6 ++---
 .../Magento/Framework/View/Asset/Minified.php |  6 ++---
 .../Magento/Framework/View/Context.php        |  6 ++---
 .../Framework/View/Design/Theme/Image.php     |  6 ++---
 .../Framework/View/Element/AbstractBlock.php  |  2 +-
 .../Framework/View/Element/Context.php        |  8 +++---
 .../View/Element/Template/Context.php         |  8 +++---
 .../Framework/View/Layout/Data/Structure.php  |  6 ++---
 .../Framework/View/Layout/Generator/Block.php |  6 ++---
 .../View/Layout/ScheduledStructure/Helper.php |  6 ++---
 .../Framework/View/Page/Config/Renderer.php   |  6 ++---
 458 files changed, 825 insertions(+), 930 deletions(-)

diff --git a/app/code/Magento/AdminNotification/Model/Resource/System/Message/Collection.php b/app/code/Magento/AdminNotification/Model/Resource/System/Message/Collection.php
index 230934526fb..ff450f73792 100644
--- a/app/code/Magento/AdminNotification/Model/Resource/System/Message/Collection.php
+++ b/app/code/Magento/AdminNotification/Model/Resource/System/Message/Collection.php
@@ -22,7 +22,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\Notification\MessageList $messageList
@@ -31,7 +31,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Framework\Notification\MessageList $messageList,
diff --git a/app/code/Magento/Authorization/Model/Acl/AclRetriever.php b/app/code/Magento/Authorization/Model/Acl/AclRetriever.php
index 51bd53b2d3f..bbe4491d5cf 100644
--- a/app/code/Magento/Authorization/Model/Acl/AclRetriever.php
+++ b/app/code/Magento/Authorization/Model/Acl/AclRetriever.php
@@ -12,7 +12,7 @@ use Magento\Authorization\Model\UserContextInterface;
 use Magento\Framework\Acl\Builder as AclBuilder;
 use Magento\Framework\Exception\AuthorizationException;
 use Magento\Framework\Exception\LocalizedException;
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 
 /**
  * Permission tree retriever
diff --git a/app/code/Magento/Authorization/Model/Resource/Rules.php b/app/code/Magento/Authorization/Model/Resource/Rules.php
index a89e3e33d1a..d1f16dbe54a 100644
--- a/app/code/Magento/Authorization/Model/Resource/Rules.php
+++ b/app/code/Magento/Authorization/Model/Resource/Rules.php
@@ -29,21 +29,21 @@ class Rules extends \Magento\Framework\Model\Resource\Db\AbstractDb
     protected $_aclBuilder;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
     /**
      * @param \Magento\Framework\App\Resource $resource
      * @param \Magento\Framework\Acl\Builder $aclBuilder
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Acl\RootResource $rootResource
      * @param \Magento\Framework\Acl\CacheInterface $aclCache
      */
     public function __construct(
         \Magento\Framework\App\Resource $resource,
         \Magento\Framework\Acl\Builder $aclBuilder,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Acl\RootResource $rootResource,
         \Magento\Framework\Acl\CacheInterface $aclCache
     ) {
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Payment/Cancel.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Payment/Cancel.php
index b0c979f96ef..6b0cea21633 100644
--- a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Payment/Cancel.php
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Payment/Cancel.php
@@ -51,10 +51,10 @@ class Cancel extends \Magento\Backend\App\Action
                 $this->_view
             );
         } catch (\Magento\Framework\Model\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $result['error_message'] = $e->getMessage();
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $result['error_message'] = __('Something went wrong canceling the transactions.');
         }
 
diff --git a/app/code/Magento/Authorizenet/Controller/Authorizenet/Payment/Cancel.php b/app/code/Magento/Authorizenet/Controller/Authorizenet/Payment/Cancel.php
index 72e366c7eb9..4efac0717ec 100644
--- a/app/code/Magento/Authorizenet/Controller/Authorizenet/Payment/Cancel.php
+++ b/app/code/Magento/Authorizenet/Controller/Authorizenet/Payment/Cancel.php
@@ -50,10 +50,10 @@ class Cancel extends \Magento\Framework\App\Action\Action
                 $this->_view
             );
         } catch (\Magento\Framework\Model\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $result['error_message'] = $e->getMessage();
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $result['error_message'] = __(
                 'There was an error canceling transactions. Please contact us or try again later.'
             );
diff --git a/app/code/Magento/Authorizenet/Controller/Directpost/Payment.php b/app/code/Magento/Authorizenet/Controller/Directpost/Payment.php
index 2e34c219ef3..a5e093e23d8 100644
--- a/app/code/Magento/Authorizenet/Controller/Directpost/Payment.php
+++ b/app/code/Magento/Authorizenet/Controller/Directpost/Payment.php
@@ -74,11 +74,11 @@ class Payment extends \Magento\Framework\App\Action\Action
             $paymentMethod->process($data);
             $result['success'] = 1;
         } catch (\Magento\Framework\Model\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $result['success'] = 0;
             $result['error_msg'] = $e->getMessage();
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $result['success'] = 0;
             $result['error_msg'] = __('We couldn\'t process your order right now. Please try again later.');
         }
diff --git a/app/code/Magento/Authorizenet/Model/Authorizenet.php b/app/code/Magento/Authorizenet/Model/Authorizenet.php
index 36ff1c26ee8..db9df42b623 100644
--- a/app/code/Magento/Authorizenet/Model/Authorizenet.php
+++ b/app/code/Magento/Authorizenet/Model/Authorizenet.php
@@ -296,8 +296,8 @@ class Authorizenet extends \Magento\Payment\Model\Method\Cc
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Module\ModuleListInterface $moduleList
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Centinel\Model\Service $centinelService
@@ -315,8 +315,8 @@ class Authorizenet extends \Magento\Payment\Model\Method\Cc
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Module\ModuleListInterface $moduleList,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Centinel\Model\Service $centinelService,
diff --git a/app/code/Magento/Authorizenet/Model/Directpost.php b/app/code/Magento/Authorizenet/Model/Directpost.php
index cfc9eed4710..71b481ba5f1 100644
--- a/app/code/Magento/Authorizenet/Model/Directpost.php
+++ b/app/code/Magento/Authorizenet/Model/Directpost.php
@@ -82,8 +82,8 @@ class Directpost extends \Magento\Authorizenet\Model\Authorizenet
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Module\ModuleListInterface $moduleList
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Centinel\Model\Service $centinelService
@@ -107,8 +107,8 @@ class Directpost extends \Magento\Authorizenet\Model\Authorizenet
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Module\ModuleListInterface $moduleList,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Centinel\Model\Service $centinelService,
diff --git a/app/code/Magento/Backend/Block/Context.php b/app/code/Magento/Backend/Block/Context.php
index 4e7548cde61..988a0d22efd 100644
--- a/app/code/Magento/Backend/Block/Context.php
+++ b/app/code/Magento/Backend/Block/Context.php
@@ -32,7 +32,7 @@ class Context extends \Magento\Framework\View\Element\Context
      * @param \Magento\Framework\View\Asset\Repository $assetRepo
      * @param \Magento\Framework\View\ConfigInterface $viewConfig
      * @param \Magento\Framework\App\Cache\StateInterface $cacheState
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Escaper $escaper
      * @param \Magento\Framework\Filter\FilterManager $filterManager
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
@@ -55,7 +55,7 @@ class Context extends \Magento\Framework\View\Element\Context
         \Magento\Framework\View\Asset\Repository $assetRepo,
         \Magento\Framework\View\ConfigInterface $viewConfig,
         \Magento\Framework\App\Cache\StateInterface $cacheState,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Escaper $escaper,
         \Magento\Framework\Filter\FilterManager $filterManager,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
diff --git a/app/code/Magento/Backend/Block/Template/Context.php b/app/code/Magento/Backend/Block/Template/Context.php
index 16e3bc65b5a..b16288e76d2 100644
--- a/app/code/Magento/Backend/Block/Template/Context.php
+++ b/app/code/Magento/Backend/Block/Template/Context.php
@@ -56,7 +56,7 @@ class Context extends \Magento\Framework\View\Element\Template\Context
      * @param \Magento\Framework\View\Asset\Repository $assetRepo
      * @param \Magento\Framework\View\ConfigInterface $viewConfig
      * @param \Magento\Framework\App\Cache\StateInterface $cacheState
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Escaper $escaper
      * @param \Magento\Framework\Filter\FilterManager $filterManager
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
@@ -89,7 +89,7 @@ class Context extends \Magento\Framework\View\Element\Template\Context
         \Magento\Framework\View\Asset\Repository $assetRepo,
         \Magento\Framework\View\ConfigInterface $viewConfig,
         \Magento\Framework\App\Cache\StateInterface $cacheState,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Escaper $escaper,
         \Magento\Framework\Filter\FilterManager $filterManager,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
diff --git a/app/code/Magento/Backend/Block/Widget/Context.php b/app/code/Magento/Backend/Block/Widget/Context.php
index 7fd088cb03e..549f433d313 100644
--- a/app/code/Magento/Backend/Block/Widget/Context.php
+++ b/app/code/Magento/Backend/Block/Widget/Context.php
@@ -39,7 +39,7 @@ class Context extends \Magento\Backend\Block\Template\Context
      * @param \Magento\Framework\View\Asset\Repository $assetRepo
      * @param \Magento\Framework\View\ConfigInterface $viewConfig
      * @param \Magento\Framework\App\Cache\StateInterface $cacheState
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Escaper $escaper
      * @param \Magento\Framework\Filter\FilterManager $filterManager
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
@@ -74,7 +74,7 @@ class Context extends \Magento\Backend\Block\Template\Context
         \Magento\Framework\View\Asset\Repository $assetRepo,
         \Magento\Framework\View\ConfigInterface $viewConfig,
         \Magento\Framework\App\Cache\StateInterface $cacheState,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Escaper $escaper,
         \Magento\Framework\Filter\FilterManager $filterManager,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/Tunnel.php b/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/Tunnel.php
index f1bd26eedac..94752f8e1e4 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/Tunnel.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/Tunnel.php
@@ -68,7 +68,7 @@ class Tunnel extends \Magento\Backend\Controller\Adminhtml\Dashboard
                             ->setContents($response->getBody());
                         return $resultRaw;
                     } catch (\Exception $e) {
-                        $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                        $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                         $error = __('see error log for details');
                         $httpCode = 503;
                     }
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Status.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Status.php
index 85a3aa075bf..fa14e28e5c5 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Status.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Status.php
@@ -79,7 +79,7 @@ class Status extends \Magento\Backend\Controller\Adminhtml\System\Config\System\
                         ) && $flagData['timeout_reached'])
                         ) {
                             $this->_objectManager->get(
-                                'Magento\Framework\Logger'
+                                'Psr\Log\LoggerInterface'
                             )->critical(
                                 new \Magento\Framework\Exception(
                                     __('The timeout limit for response from synchronize process was reached.')
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Synchronize.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Synchronize.php
index f2b70585d7a..f7f1615bf25 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Synchronize.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Synchronize.php
@@ -43,7 +43,7 @@ class Synchronize extends \Magento\Backend\Controller\Adminhtml\System\Config\Sy
         try {
             $this->_getSyncSingleton()->synchronize($storage);
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $flag->passError($e);
         }
 
diff --git a/app/code/Magento/Backend/Model/Menu.php b/app/code/Magento/Backend/Model/Menu.php
index 2851ae2c338..582ab34871e 100644
--- a/app/code/Magento/Backend/Model/Menu.php
+++ b/app/code/Magento/Backend/Model/Menu.php
@@ -9,11 +9,6 @@ namespace Magento\Backend\Model;
  */
 class Menu extends \ArrayObject
 {
-    /**
-     * Name of special logger key for debugging building menu
-     */
-    const LOGGER_KEY = 'menu-debug';
-
     /**
      * Path in tree structure
      *
@@ -22,15 +17,15 @@ class Menu extends \ArrayObject
     protected $_path = '';
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
     /**
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param string $pathInMenuStructure
      */
-    public function __construct(\Magento\Framework\Logger $logger, $pathInMenuStructure = '')
+    public function __construct(\Psr\Log\LoggerInterface $logger, $pathInMenuStructure = '')
     {
         if ($pathInMenuStructure) {
             $this->_path = $pathInMenuStructure . '/';
@@ -61,8 +56,7 @@ class Menu extends \ArrayObject
             if (!isset($this[$index])) {
                 $this->offsetSet($index, $item);
                 $this->_logger->debug(
-                    sprintf('Add of item with id %s was processed', $item->getId()),
-                    self::LOGGER_KEY
+                    sprintf('Add of item with id %s was processed', $item->getId())
                 );
             } else {
                 $this->add($item, $parentId, $index + 1);
@@ -127,8 +121,7 @@ class Menu extends \ArrayObject
                 unset($this[$key]);
                 $result = true;
                 $this->_logger->debug(
-                    sprintf('Remove on item with id %s was processed', $item->getId()),
-                    self::LOGGER_KEY
+                    sprintf('Remove on item with id %s was processed', $item->getId())
                 );
                 break;
             }
diff --git a/app/code/Magento/Backend/Model/Menu/AbstractDirector.php b/app/code/Magento/Backend/Model/Menu/AbstractDirector.php
index f00a30085e0..fa434a36aa8 100644
--- a/app/code/Magento/Backend/Model/Menu/AbstractDirector.php
+++ b/app/code/Magento/Backend/Model/Menu/AbstractDirector.php
@@ -25,12 +25,12 @@ abstract class AbstractDirector
      *
      * @param array $config
      * @param \Magento\Backend\Model\Menu\Builder $builder
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @return void
      */
     abstract public function direct(
         array $config,
         \Magento\Backend\Model\Menu\Builder $builder,
-        \Magento\Framework\Logger $logger
+        \Psr\Log\LoggerInterface $logger
     );
 }
diff --git a/app/code/Magento/Backend/Model/Menu/Config.php b/app/code/Magento/Backend/Model/Menu/Config.php
index 52b3e0f2ac8..19f9c2526a7 100644
--- a/app/code/Magento/Backend/Model/Menu/Config.php
+++ b/app/code/Magento/Backend/Model/Menu/Config.php
@@ -33,7 +33,7 @@ class Config
     protected $_menu;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -64,7 +64,7 @@ class Config
      * @param \Magento\Backend\Model\Menu\Config\Reader $configReader
      * @param \Magento\Framework\App\Cache\Type\Config $configCacheType
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Framework\App\State $appState
      */
@@ -75,7 +75,7 @@ class Config
         \Magento\Backend\Model\Menu\Config\Reader $configReader,
         \Magento\Framework\App\Cache\Type\Config $configCacheType,
         \Magento\Framework\Event\ManagerInterface $eventManager,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Framework\App\State $appState
     ) {
diff --git a/app/code/Magento/Backend/Model/Menu/Director/Director.php b/app/code/Magento/Backend/Model/Menu/Director/Director.php
index 763495180bf..ccd4f69f11e 100644
--- a/app/code/Magento/Backend/Model/Menu/Director/Director.php
+++ b/app/code/Magento/Backend/Model/Menu/Director/Director.php
@@ -17,7 +17,7 @@ class Director extends \Magento\Backend\Model\Menu\AbstractDirector
      * Get command object
      *
      * @param array $data command params
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @return \Magento\Backend\Model\Menu\Builder\AbstractCommand
      */
     protected function _getCommand($data, $logger)
@@ -25,8 +25,7 @@ class Director extends \Magento\Backend\Model\Menu\AbstractDirector
         $command = $this->_commandFactory->create($data['type'], ['data' => $data]);
         if (isset($this->_messagePatterns[$data['type']])) {
             $logger->debug(
-                sprintf($this->_messagePatterns[$data['type']], $command->getId()),
-                \Magento\Backend\Model\Menu::LOGGER_KEY
+                sprintf($this->_messagePatterns[$data['type']], $command->getId())
             );
         }
         return $command;
@@ -37,10 +36,10 @@ class Director extends \Magento\Backend\Model\Menu\AbstractDirector
      *
      * @param array $config
      * @param \Magento\Backend\Model\Menu\Builder $builder
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @return void
      */
-    public function direct(array $config, \Magento\Backend\Model\Menu\Builder $builder, \Magento\Framework\Logger $logger)
+    public function direct(array $config, \Magento\Backend\Model\Menu\Builder $builder, \Psr\Log\LoggerInterface $logger)
     {
         foreach ($config as $data) {
             $builder->processCommand($this->_getCommand($data, $logger));
diff --git a/app/code/Magento/Backend/etc/adminhtml/system.xml b/app/code/Magento/Backend/etc/adminhtml/system.xml
index 85606547aad..cabd82f8793 100644
--- a/app/code/Magento/Backend/etc/adminhtml/system.xml
+++ b/app/code/Magento/Backend/etc/adminhtml/system.xml
@@ -202,12 +202,12 @@
                 <field id="file" translate="label comment" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
                     <label>System Log File Name</label>
                     <backend_model>Magento\Backend\Model\Config\Backend\Filename</backend_model>
-                    <comment>Logging from \Magento\Framework\Logger. File is located in {{base_dir}}/var/log</comment>
+                    <comment>Logging from \Psr\Log\LoggerInterface. File is located in {{base_dir}}/var/log</comment>
                 </field>
                 <field id="exception_file" translate="label comment" type="text" sortOrder="3" showInDefault="1" showInWebsite="1" showInStore="1">
                     <label>Exceptions Log File Name</label>
                     <backend_model>Magento\Backend\Model\Config\Backend\Filename</backend_model>
-                    <comment>Logging from \Magento\Framework\Logger. File is located in {{base_dir}}/var/log</comment>
+                    <comment>Logging from \Psr\Log\LoggerInterface. File is located in {{base_dir}}/var/log</comment>
                 </field>
             </group>
             <group id="js" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1">
diff --git a/app/code/Magento/Backend/i18n/de_DE.csv b/app/code/Magento/Backend/i18n/de_DE.csv
index 7a956dbcdcf..9e12e495d09 100644
--- a/app/code/Magento/Backend/i18n/de_DE.csv
+++ b/app/code/Magento/Backend/i18n/de_DE.csv
@@ -504,7 +504,7 @@ Developer,Developer
 "Translate, blocks and other output caches should be disabled for both frontend and admin inline translations.","Translate, blocks and other output caches should be disabled for both frontend and admin inline translations."
 "Log Settings","Log Settings"
 "System Log File Name","System Log File Name"
-"Logging from \Magento\Framework\Logger. File is located in {{base_dir}}/var/log","Logging from \Magento\Framework\Logger. File is located in {{base_dir}}/var/log"
+"Logging from \Psr\Log\LoggerInterface. File is located in {{base_dir}}/var/log","Logging from \Psr\Log\LoggerInterface. File is located in {{base_dir}}/var/log"
 "Exceptions Log File Name","Exceptions Log File Name"
 "JavaScript Settings","JavaScript Settings"
 "Merge JavaScript Files","Merge JavaScript Files"
diff --git a/app/code/Magento/Backend/i18n/en_US.csv b/app/code/Magento/Backend/i18n/en_US.csv
index 7a956dbcdcf..9e12e495d09 100644
--- a/app/code/Magento/Backend/i18n/en_US.csv
+++ b/app/code/Magento/Backend/i18n/en_US.csv
@@ -504,7 +504,7 @@ Developer,Developer
 "Translate, blocks and other output caches should be disabled for both frontend and admin inline translations.","Translate, blocks and other output caches should be disabled for both frontend and admin inline translations."
 "Log Settings","Log Settings"
 "System Log File Name","System Log File Name"
-"Logging from \Magento\Framework\Logger. File is located in {{base_dir}}/var/log","Logging from \Magento\Framework\Logger. File is located in {{base_dir}}/var/log"
+"Logging from \Psr\Log\LoggerInterface. File is located in {{base_dir}}/var/log","Logging from \Psr\Log\LoggerInterface. File is located in {{base_dir}}/var/log"
 "Exceptions Log File Name","Exceptions Log File Name"
 "JavaScript Settings","JavaScript Settings"
 "Merge JavaScript Files","Merge JavaScript Files"
diff --git a/app/code/Magento/Backend/i18n/es_ES.csv b/app/code/Magento/Backend/i18n/es_ES.csv
index 7a956dbcdcf..9e12e495d09 100644
--- a/app/code/Magento/Backend/i18n/es_ES.csv
+++ b/app/code/Magento/Backend/i18n/es_ES.csv
@@ -504,7 +504,7 @@ Developer,Developer
 "Translate, blocks and other output caches should be disabled for both frontend and admin inline translations.","Translate, blocks and other output caches should be disabled for both frontend and admin inline translations."
 "Log Settings","Log Settings"
 "System Log File Name","System Log File Name"
-"Logging from \Magento\Framework\Logger. File is located in {{base_dir}}/var/log","Logging from \Magento\Framework\Logger. File is located in {{base_dir}}/var/log"
+"Logging from \Psr\Log\LoggerInterface. File is located in {{base_dir}}/var/log","Logging from \Psr\Log\LoggerInterface. File is located in {{base_dir}}/var/log"
 "Exceptions Log File Name","Exceptions Log File Name"
 "JavaScript Settings","JavaScript Settings"
 "Merge JavaScript Files","Merge JavaScript Files"
diff --git a/app/code/Magento/Backend/i18n/fr_FR.csv b/app/code/Magento/Backend/i18n/fr_FR.csv
index 7a956dbcdcf..9e12e495d09 100644
--- a/app/code/Magento/Backend/i18n/fr_FR.csv
+++ b/app/code/Magento/Backend/i18n/fr_FR.csv
@@ -504,7 +504,7 @@ Developer,Developer
 "Translate, blocks and other output caches should be disabled for both frontend and admin inline translations.","Translate, blocks and other output caches should be disabled for both frontend and admin inline translations."
 "Log Settings","Log Settings"
 "System Log File Name","System Log File Name"
-"Logging from \Magento\Framework\Logger. File is located in {{base_dir}}/var/log","Logging from \Magento\Framework\Logger. File is located in {{base_dir}}/var/log"
+"Logging from \Psr\Log\LoggerInterface. File is located in {{base_dir}}/var/log","Logging from \Psr\Log\LoggerInterface. File is located in {{base_dir}}/var/log"
 "Exceptions Log File Name","Exceptions Log File Name"
 "JavaScript Settings","JavaScript Settings"
 "Merge JavaScript Files","Merge JavaScript Files"
diff --git a/app/code/Magento/Backend/i18n/nl_NL.csv b/app/code/Magento/Backend/i18n/nl_NL.csv
index 7a956dbcdcf..9e12e495d09 100644
--- a/app/code/Magento/Backend/i18n/nl_NL.csv
+++ b/app/code/Magento/Backend/i18n/nl_NL.csv
@@ -504,7 +504,7 @@ Developer,Developer
 "Translate, blocks and other output caches should be disabled for both frontend and admin inline translations.","Translate, blocks and other output caches should be disabled for both frontend and admin inline translations."
 "Log Settings","Log Settings"
 "System Log File Name","System Log File Name"
-"Logging from \Magento\Framework\Logger. File is located in {{base_dir}}/var/log","Logging from \Magento\Framework\Logger. File is located in {{base_dir}}/var/log"
+"Logging from \Psr\Log\LoggerInterface. File is located in {{base_dir}}/var/log","Logging from \Psr\Log\LoggerInterface. File is located in {{base_dir}}/var/log"
 "Exceptions Log File Name","Exceptions Log File Name"
 "JavaScript Settings","JavaScript Settings"
 "Merge JavaScript Files","Merge JavaScript Files"
diff --git a/app/code/Magento/Backend/i18n/pt_BR.csv b/app/code/Magento/Backend/i18n/pt_BR.csv
index 7a956dbcdcf..9e12e495d09 100644
--- a/app/code/Magento/Backend/i18n/pt_BR.csv
+++ b/app/code/Magento/Backend/i18n/pt_BR.csv
@@ -504,7 +504,7 @@ Developer,Developer
 "Translate, blocks and other output caches should be disabled for both frontend and admin inline translations.","Translate, blocks and other output caches should be disabled for both frontend and admin inline translations."
 "Log Settings","Log Settings"
 "System Log File Name","System Log File Name"
-"Logging from \Magento\Framework\Logger. File is located in {{base_dir}}/var/log","Logging from \Magento\Framework\Logger. File is located in {{base_dir}}/var/log"
+"Logging from \Psr\Log\LoggerInterface. File is located in {{base_dir}}/var/log","Logging from \Psr\Log\LoggerInterface. File is located in {{base_dir}}/var/log"
 "Exceptions Log File Name","Exceptions Log File Name"
 "JavaScript Settings","JavaScript Settings"
 "Merge JavaScript Files","Merge JavaScript Files"
diff --git a/app/code/Magento/Backend/i18n/zh_CN.csv b/app/code/Magento/Backend/i18n/zh_CN.csv
index 7a956dbcdcf..9e12e495d09 100644
--- a/app/code/Magento/Backend/i18n/zh_CN.csv
+++ b/app/code/Magento/Backend/i18n/zh_CN.csv
@@ -504,7 +504,7 @@ Developer,Developer
 "Translate, blocks and other output caches should be disabled for both frontend and admin inline translations.","Translate, blocks and other output caches should be disabled for both frontend and admin inline translations."
 "Log Settings","Log Settings"
 "System Log File Name","System Log File Name"
-"Logging from \Magento\Framework\Logger. File is located in {{base_dir}}/var/log","Logging from \Magento\Framework\Logger. File is located in {{base_dir}}/var/log"
+"Logging from \Psr\Log\LoggerInterface. File is located in {{base_dir}}/var/log","Logging from \Psr\Log\LoggerInterface. File is located in {{base_dir}}/var/log"
 "Exceptions Log File Name","Exceptions Log File Name"
 "JavaScript Settings","JavaScript Settings"
 "Merge JavaScript Files","Merge JavaScript Files"
diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index/Create.php b/app/code/Magento/Backup/Controller/Adminhtml/Index/Create.php
index ebcf25e8637..654697d038d 100644
--- a/app/code/Magento/Backup/Controller/Adminhtml/Index/Create.php
+++ b/app/code/Magento/Backup/Controller/Adminhtml/Index/Create.php
@@ -86,10 +86,10 @@ class Create extends \Magento\Backup\Controller\Adminhtml\Index
         } catch (\Magento\Framework\Backup\Exception\NotEnoughFreeSpace $e) {
             $errorMessage = __('You need more free space to create a backup.');
         } catch (\Magento\Framework\Backup\Exception\NotEnoughPermissions $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->log($e->getMessage());
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->log($e->getMessage());
             $errorMessage = __('You need more permissions to create a backup.');
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->log($e->getMessage());
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->log($e->getMessage());
             $errorMessage = __('Something went wrong creating the backup.');
         }
 
diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index/Rollback.php b/app/code/Magento/Backup/Controller/Adminhtml/Index/Rollback.php
index 86c130e0075..c10b5b37c5b 100644
--- a/app/code/Magento/Backup/Controller/Adminhtml/Index/Rollback.php
+++ b/app/code/Magento/Backup/Controller/Adminhtml/Index/Rollback.php
@@ -122,10 +122,10 @@ class Rollback extends \Magento\Backup\Controller\Adminhtml\Index
         } catch (\Magento\Framework\Backup\Exception\FtpValidationFailed $e) {
             $errorMsg = __('Failed to validate FTP');
         } catch (\Magento\Framework\Backup\Exception\NotEnoughPermissions $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->log($e->getMessage());
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->log($e->getMessage());
             $errorMsg = __('Not enough permissions to perform rollback.');
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->log($e->getMessage());
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->log($e->getMessage());
             $errorMsg = __('Failed to rollback');
         }
 
diff --git a/app/code/Magento/Backup/Model/Observer.php b/app/code/Magento/Backup/Model/Observer.php
index 56cf013ebaa..c6e408ce4e9 100644
--- a/app/code/Magento/Backup/Model/Observer.php
+++ b/app/code/Magento/Backup/Model/Observer.php
@@ -43,7 +43,7 @@ class Observer
     protected $_coreRegistry = null;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -74,7 +74,7 @@ class Observer
     /**
      * @param \Magento\Backup\Helper\Data $backupData
      * @param \Magento\Framework\Registry $coreRegistry
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Framework\Filesystem $filesystem
      * @param \Magento\Framework\Backup\Factory $backupFactory
@@ -83,7 +83,7 @@ class Observer
     public function __construct(
         \Magento\Backup\Helper\Data $backupData,
         \Magento\Framework\Registry $coreRegistry,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Framework\Filesystem $filesystem,
         \Magento\Framework\Backup\Factory $backupFactory,
diff --git a/app/code/Magento/Bundle/Model/Product/Type.php b/app/code/Magento/Bundle/Model/Product/Type.php
index d347baa277f..adcd9dd07f4 100644
--- a/app/code/Magento/Bundle/Model/Product/Type.php
+++ b/app/code/Magento/Bundle/Model/Product/Type.php
@@ -141,7 +141,7 @@ class Type extends \Magento\Catalog\Model\Product\Type\AbstractType
      * @param \Magento\Core\Helper\File\Storage\Database $fileStorageDb
      * @param \Magento\Framework\Filesystem $filesystem
      * @param \Magento\Framework\Registry $coreRegistry
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param ProductRepositoryInterface $productRepository
      * @param \Magento\Catalog\Helper\Product $catalogProduct
      * @param \Magento\Catalog\Helper\Data $catalogData
@@ -167,7 +167,7 @@ class Type extends \Magento\Catalog\Model\Product\Type\AbstractType
         \Magento\Core\Helper\File\Storage\Database $fileStorageDb,
         \Magento\Framework\Filesystem $filesystem,
         \Magento\Framework\Registry $coreRegistry,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         ProductRepositoryInterface $productRepository,
         \Magento\Catalog\Helper\Product $catalogProduct,
         \Magento\Catalog\Helper\Data $catalogData,
diff --git a/app/code/Magento/Catalog/Block/Product/Context.php b/app/code/Magento/Catalog/Block/Product/Context.php
index 916e5c5fff6..14ae9729f3e 100644
--- a/app/code/Magento/Catalog/Block/Product/Context.php
+++ b/app/code/Magento/Catalog/Block/Product/Context.php
@@ -83,7 +83,7 @@ class Context extends \Magento\Framework\View\Element\Template\Context
      * @param \Magento\Framework\View\Asset\Repository $assetRepo
      * @param \Magento\Framework\View\ConfigInterface $viewConfig
      * @param \Magento\Framework\App\Cache\StateInterface $cacheState
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Escaper $escaper
      * @param \Magento\Framework\Filter\FilterManager $filterManager
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
@@ -122,7 +122,7 @@ class Context extends \Magento\Framework\View\Element\Template\Context
         \Magento\Framework\View\Asset\Repository $assetRepo,
         \Magento\Framework\View\ConfigInterface $viewConfig,
         \Magento\Framework\App\Cache\StateInterface $cacheState,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Escaper $escaper,
         \Magento\Framework\Filter\FilterManager $filterManager,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Move.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Move.php
index 18eda1abf61..8b4683d0fb4 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Move.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Move.php
@@ -18,7 +18,7 @@ class Move extends \Magento\Catalog\Controller\Adminhtml\Category
     protected $layoutFactory;
 
     /**
-     * @var \Magento\Framework\Logger $logger
+     * @var \Psr\Log\LoggerInterface $logger
      */
     protected $logger;
 
@@ -27,14 +27,14 @@ class Move extends \Magento\Catalog\Controller\Adminhtml\Category
      * @param \Magento\Backend\Model\View\Result\RedirectFactory $resultRedirectFactory
      * @param \Magento\Framework\Controller\Result\JSONFactory $resultJsonFactory
      * @param \Magento\Framework\View\LayoutFactory $layoutFactory,
-     * @param \Magento\Framework\Logger $logger,
+     * @param \Psr\Log\LoggerInterface $logger,
      */
     public function __construct(
         \Magento\Backend\App\Action\Context $context,
         \Magento\Backend\Model\View\Result\RedirectFactory $resultRedirectFactory,
         \Magento\Framework\Controller\Result\JSONFactory $resultJsonFactory,
         \Magento\Framework\View\LayoutFactory $layoutFactory,
-        \Magento\Framework\Logger $logger
+        \Psr\Log\LoggerInterface $logger
     ) {
         parent::__construct($context, $resultRedirectFactory);
         $this->resultJsonFactory = $resultJsonFactory;
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Builder.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Builder.php
index 758084c10e9..0f712c177e2 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Builder.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Builder.php
@@ -8,7 +8,7 @@ namespace Magento\Catalog\Controller\Adminhtml\Product;
 use Magento\Catalog\Model\ProductFactory;
 use Magento\Cms\Model\Wysiwyg as WysiwygModel;
 use Magento\Framework\App\RequestInterface;
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 use Magento\Framework\Registry;
 
 class Builder
@@ -19,7 +19,7 @@ class Builder
     protected $productFactory;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Duplicate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Duplicate.php
index 8c9e23a1745..618b90846c5 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Duplicate.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Duplicate.php
@@ -53,7 +53,7 @@ class Duplicate extends \Magento\Catalog\Controller\Adminhtml\Product
             $this->messageManager->addSuccess(__('You duplicated the product.'));
             $resultRedirect->setPath('catalog/*/edit', ['_current' => true, 'id' => $newProduct->getId()]);
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->messageManager->addError($e->getMessage());
             $resultRedirect->setPath('catalog/*/edit', ['_current' => true]);
         }
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php
index fe6b003cb26..4a7ac5bc14e 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php
@@ -116,7 +116,7 @@ class Save extends \Magento\Catalog\Controller\Adminhtml\Product
                 $this->_session->setProductData($data);
                 $redirectBack = true;
             } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                 $this->messageManager->addError($e->getMessage());
                 $redirectBack = true;
             }
diff --git a/app/code/Magento/Catalog/Controller/Category/View.php b/app/code/Magento/Catalog/Controller/Category/View.php
index f256d9ae84f..d6db2447de5 100644
--- a/app/code/Magento/Catalog/Controller/Category/View.php
+++ b/app/code/Magento/Catalog/Controller/Category/View.php
@@ -123,7 +123,7 @@ class View extends \Magento\Framework\App\Action\Action
                 ['category' => $category, 'controller_action' => $this]
             );
         } catch (\Magento\Framework\Model\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             return false;
         }
 
diff --git a/app/code/Magento/Catalog/Controller/Product/View.php b/app/code/Magento/Catalog/Controller/Product/View.php
index 4f06ccc1c86..de750fd1151 100644
--- a/app/code/Magento/Catalog/Controller/Product/View.php
+++ b/app/code/Magento/Catalog/Controller/Product/View.php
@@ -111,7 +111,7 @@ class View extends \Magento\Catalog\Controller\Product
             if ($e->getCode() == $this->viewHelper->ERR_NO_PRODUCT_LOADED) {
                 return $this->noProductRedirect();
             } else {
-                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                 $resultForward = $this->resultForwardFactory->create();
                 $resultForward->forward('noroute');
                 return $resultForward;
diff --git a/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php b/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php
index 7a23c7247e9..2b326723925 100644
--- a/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php
+++ b/app/code/Magento/Catalog/Model/Category/Attribute/Backend/Image.php
@@ -34,19 +34,19 @@ class Image extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend
     protected $_fileUploaderFactory;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
     /**
      * Construct
      *
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Filesystem $filesystem
      * @param \Magento\Core\Model\File\UploaderFactory $fileUploaderFactory
      */
     public function __construct(
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Filesystem $filesystem,
         \Magento\Core\Model\File\UploaderFactory $fileUploaderFactory
     ) {
diff --git a/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php b/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php
index 3e14401a39a..1b9fcdff10f 100644
--- a/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php
+++ b/app/code/Magento/Catalog/Model/Product/Type/AbstractType.php
@@ -123,7 +123,7 @@ abstract class AbstractType
     protected $_eventManager;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -164,7 +164,7 @@ abstract class AbstractType
      * @param \Magento\Core\Helper\File\Storage\Database $fileStorageDb
      * @param \Magento\Framework\Filesystem $filesystem
      * @param \Magento\Framework\Registry $coreRegistry
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param ProductRepositoryInterface $productRepository
      */
     public function __construct(
@@ -176,7 +176,7 @@ abstract class AbstractType
         \Magento\Core\Helper\File\Storage\Database $fileStorageDb,
         \Magento\Framework\Filesystem $filesystem,
         \Magento\Framework\Registry $coreRegistry,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         ProductRepositoryInterface $productRepository
     ) {
         $this->_catalogProductOption = $catalogProductOption;
diff --git a/app/code/Magento/Catalog/Model/Resource/Category/Attribute/Collection.php b/app/code/Magento/Catalog/Model/Resource/Category/Attribute/Collection.php
index bd7a18f5d3d..8f45e927424 100644
--- a/app/code/Magento/Catalog/Model/Resource/Category/Attribute/Collection.php
+++ b/app/code/Magento/Catalog/Model/Resource/Category/Attribute/Collection.php
@@ -20,7 +20,7 @@ class Collection extends \Magento\Eav\Model\Resource\Entity\Attribute\Collection
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\EntityFactory $eavEntityFactory
@@ -30,7 +30,7 @@ class Collection extends \Magento\Eav\Model\Resource\Entity\Attribute\Collection
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Model\Config $eavConfig,
diff --git a/app/code/Magento/Catalog/Model/Resource/Category/Flat/Collection.php b/app/code/Magento/Catalog/Model/Resource/Category/Flat/Collection.php
index 19cf99775d6..24ba5f44277 100644
--- a/app/code/Magento/Catalog/Model/Resource/Category/Flat/Collection.php
+++ b/app/code/Magento/Catalog/Model/Resource/Category/Flat/Collection.php
@@ -9,7 +9,7 @@ use Magento\Core\Model\EntityFactory;
 use Magento\Framework\Event\ManagerInterface;
 use Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
 use Magento\Framework\Model\Resource\Db\AbstractDb;
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 use Magento\Store\Model\StoreManagerInterface;
 
 /**
diff --git a/app/code/Magento/Catalog/Model/Resource/Collection/AbstractCollection.php b/app/code/Magento/Catalog/Model/Resource/Collection/AbstractCollection.php
index a70a1aa239c..996f805d3ef 100644
--- a/app/code/Magento/Catalog/Model/Resource/Collection/AbstractCollection.php
+++ b/app/code/Magento/Catalog/Model/Resource/Collection/AbstractCollection.php
@@ -28,7 +28,7 @@ class AbstractCollection extends \Magento\Eav\Model\Entity\Collection\AbstractCo
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\Config $eavConfig
@@ -43,7 +43,7 @@ class AbstractCollection extends \Magento\Eav\Model\Entity\Collection\AbstractCo
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Model\Config $eavConfig,
diff --git a/app/code/Magento/Catalog/Model/Resource/Product/Attribute/Collection.php b/app/code/Magento/Catalog/Model/Resource/Product/Attribute/Collection.php
index 5650e22e543..6183326f86b 100644
--- a/app/code/Magento/Catalog/Model/Resource/Product/Attribute/Collection.php
+++ b/app/code/Magento/Catalog/Model/Resource/Product/Attribute/Collection.php
@@ -18,7 +18,7 @@ class Collection extends \Magento\Eav\Model\Resource\Entity\Attribute\Collection
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\EntityFactory $eavEntityFactory
@@ -28,7 +28,7 @@ class Collection extends \Magento\Eav\Model\Resource\Entity\Attribute\Collection
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Model\Config $eavConfig,
diff --git a/app/code/Magento/Catalog/Model/Resource/Product/Collection.php b/app/code/Magento/Catalog/Model/Resource/Product/Collection.php
index 0d5d6565704..73b7c3cb603 100644
--- a/app/code/Magento/Catalog/Model/Resource/Product/Collection.php
+++ b/app/code/Magento/Catalog/Model/Resource/Product/Collection.php
@@ -248,7 +248,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Collection\AbstractColl
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\Config $eavConfig
@@ -272,7 +272,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Collection\AbstractColl
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Model\Config $eavConfig,
diff --git a/app/code/Magento/Catalog/Model/Resource/Product/Compare/Item/Collection.php b/app/code/Magento/Catalog/Model/Resource/Product/Compare/Item/Collection.php
index 46e9df4738f..c82e9ed4d6f 100644
--- a/app/code/Magento/Catalog/Model/Resource/Product/Compare/Item/Collection.php
+++ b/app/code/Magento/Catalog/Model/Resource/Product/Compare/Item/Collection.php
@@ -49,7 +49,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Product\Collection
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\Config $eavConfig
@@ -75,7 +75,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Product\Collection
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Model\Config $eavConfig,
diff --git a/app/code/Magento/Catalog/Model/Resource/Product/Option/Collection.php b/app/code/Magento/Catalog/Model/Resource/Product/Option/Collection.php
index 645ab02c2ad..550aa2c1ae5 100644
--- a/app/code/Magento/Catalog/Model/Resource/Product/Option/Collection.php
+++ b/app/code/Magento/Catalog/Model/Resource/Product/Option/Collection.php
@@ -27,7 +27,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Catalog\Model\Resource\Product\Option\Value\CollectionFactory $optionValueCollectionFactory
@@ -37,7 +37,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Catalog\Model\Resource\Product\Option\Value\CollectionFactory $optionValueCollectionFactory,
diff --git a/app/code/Magento/Catalog/Model/Resource/Url.php b/app/code/Magento/Catalog/Model/Resource/Url.php
index d59abd1efea..eacf7eceddc 100644
--- a/app/code/Magento/Catalog/Model/Resource/Url.php
+++ b/app/code/Magento/Catalog/Model/Resource/Url.php
@@ -49,7 +49,7 @@ class Url extends \Magento\Framework\Model\Resource\Db\AbstractDb
     protected $_rootChildrenIds = [];
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -92,7 +92,7 @@ class Url extends \Magento\Framework\Model\Resource\Db\AbstractDb
      * @param \Magento\Eav\Model\Config $eavConfig
      * @param Product $productResource
      * @param \Magento\Catalog\Model\Category $catalogCategory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      */
     public function __construct(
         \Magento\Framework\App\Resource $resource,
@@ -100,7 +100,7 @@ class Url extends \Magento\Framework\Model\Resource\Db\AbstractDb
         \Magento\Eav\Model\Config $eavConfig,
         Product $productResource,
         \Magento\Catalog\Model\Category $catalogCategory,
-        \Magento\Framework\Logger $logger
+        \Psr\Log\LoggerInterface $logger
     ) {
         $this->_storeManager = $storeManager;
         $this->_eavConfig = $eavConfig;
diff --git a/app/code/Magento/CatalogImportExport/Model/Export/Product.php b/app/code/Magento/CatalogImportExport/Model/Export/Product.php
index 125fe87f102..10d107b6ca0 100644
--- a/app/code/Magento/CatalogImportExport/Model/Export/Product.php
+++ b/app/code/Magento/CatalogImportExport/Model/Export/Product.php
@@ -139,7 +139,7 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity
     protected $_exportConfig;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -200,7 +200,7 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity
      * @param \Magento\Eav\Model\Config $config
      * @param \Magento\Framework\App\Resource $resource
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Catalog\Model\Resource\Product\Collection $collection
      * @param \Magento\ImportExport\Model\Export\ConfigInterface $exportConfig
      * @param \Magento\Catalog\Model\Resource\ProductFactory $productFactory
@@ -218,7 +218,7 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity
         \Magento\Eav\Model\Config $config,
         \Magento\Framework\App\Resource $resource,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Catalog\Model\Resource\Product\Collection $collection,
         \Magento\ImportExport\Model\Export\ConfigInterface $exportConfig,
         \Magento\Catalog\Model\Resource\ProductFactory $productFactory,
diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
index 46cd4b7703a..60bcd0528cf 100644
--- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php
+++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
@@ -481,7 +481,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
     protected $indexerRegistry;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     private $_logger;
 
@@ -520,7 +520,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
      * @param \Magento\CatalogInventory\Model\Resource\Stock\ItemFactory $stockResItemFac
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Indexer\Model\IndexerRegistry $indexerRegistry
      * @param array $data
      * @throws \Magento\Framework\Model\Exception
@@ -555,7 +555,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
         \Magento\CatalogInventory\Model\Resource\Stock\ItemFactory $stockResItemFac,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Framework\Stdlib\DateTime $dateTime,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Indexer\Model\IndexerRegistry $indexerRegistry,
         array $data = []
     ) {
diff --git a/app/code/Magento/CatalogInventory/Model/Resource/Stock/Item/StockItemCriteriaMapper.php b/app/code/Magento/CatalogInventory/Model/Resource/Stock/Item/StockItemCriteriaMapper.php
index 14c56cf1140..5c67e12811e 100644
--- a/app/code/Magento/CatalogInventory/Model/Resource/Stock/Item/StockItemCriteriaMapper.php
+++ b/app/code/Magento/CatalogInventory/Model/Resource/Stock/Item/StockItemCriteriaMapper.php
@@ -10,7 +10,7 @@ use Magento\Framework\DB\MapperFactory;
 use Magento\Framework\DB\Select;
 use Magento\Framework\Data\ObjectFactory;
 use Magento\Store\Model\StoreManagerInterface;
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 use Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
 
 /**
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/ApplyRules.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/ApplyRules.php
index d93e05df6fc..3d8804ff6d7 100644
--- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/ApplyRules.php
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/ApplyRules.php
@@ -29,7 +29,7 @@ class ApplyRules extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
                 $this->messageManager->addError($errorMessage . ' ' . $ruleJob->getError());
             }
         } catch (\Exception $e) {
-            $this->_objectManager->create('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->create('Psr\Log\LoggerInterface')->critical($e);
             $this->messageManager->addError($errorMessage);
         }
         $this->_redirect('catalog_rule/*');
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Delete.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Delete.php
index cf530d0bb75..fb7a1fc6b31 100644
--- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Delete.php
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Delete.php
@@ -31,7 +31,7 @@ class Delete extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
                 $this->messageManager->addError(
                     __('An error occurred while deleting the rule. Please review the log and try again.')
                 );
-                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                 $this->_redirect('catalog_rule/*/edit', ['id' => $this->getRequest()->getParam('id')]);
                 return;
             }
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php
index 828979b6304..70f07b81bfb 100644
--- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php
@@ -75,7 +75,7 @@ class Save extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
                 $this->messageManager->addError(
                     __('An error occurred while saving the rule data. Please review the log and try again.')
                 );
-                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                 $this->_objectManager->get('Magento\Backend\Model\Session')->setPageData($data);
                 $this->_redirect('catalog_rule/*/edit', ['id' => $this->getRequest()->getParam('rule_id')]);
                 return;
diff --git a/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php b/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php
index 0e5a2e3c3c2..9c5cbbedb2b 100644
--- a/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php
+++ b/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php
@@ -31,7 +31,7 @@ class IndexBuilder
     protected $ruleCollectionFactory;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
@@ -75,7 +75,7 @@ class IndexBuilder
      * @param PriceCurrencyInterface $priceCurrency
      * @param \Magento\Framework\App\Resource $resource
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Eav\Model\Config $eavConfig
      * @param \Magento\Framework\Stdlib\DateTime $dateFormat
      * @param \Magento\Framework\Stdlib\DateTime\DateTime $dateTime
@@ -87,7 +87,7 @@ class IndexBuilder
         PriceCurrencyInterface $priceCurrency,
         \Magento\Framework\App\Resource $resource,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Eav\Model\Config $eavConfig,
         \Magento\Framework\Stdlib\DateTime $dateFormat,
         \Magento\Framework\Stdlib\DateTime\DateTime $dateTime,
diff --git a/app/code/Magento/CatalogRule/Model/Resource/Rule.php b/app/code/Magento/CatalogRule/Model/Resource/Rule.php
index edc600c5faa..8d2f50e3fd9 100644
--- a/app/code/Magento/CatalogRule/Model/Resource/Rule.php
+++ b/app/code/Magento/CatalogRule/Model/Resource/Rule.php
@@ -22,7 +22,7 @@ class Rule extends \Magento\Rule\Model\Resource\AbstractResource
     const SECONDS_IN_DAY = 86400;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -96,7 +96,7 @@ class Rule extends \Magento\Rule\Model\Resource\AbstractResource
      * @param \Magento\Eav\Model\Config $eavConfig
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\CatalogRule\Helper\Data $catalogRuleData
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
      * @param PriceCurrencyInterface $priceCurrency
      */
@@ -108,7 +108,7 @@ class Rule extends \Magento\Rule\Model\Resource\AbstractResource
         \Magento\Eav\Model\Config $eavConfig,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\CatalogRule\Helper\Data $catalogRuleData,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Stdlib\DateTime $dateTime,
         PriceCurrencyInterface $priceCurrency
     ) {
diff --git a/app/code/Magento/CatalogSearch/Model/Resource/Advanced/Collection.php b/app/code/Magento/CatalogSearch/Model/Resource/Advanced/Collection.php
index 397bef86191..f8d25720209 100644
--- a/app/code/Magento/CatalogSearch/Model/Resource/Advanced/Collection.php
+++ b/app/code/Magento/CatalogSearch/Model/Resource/Advanced/Collection.php
@@ -31,7 +31,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Product\Collection
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\Config $eavConfig
@@ -56,7 +56,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Product\Collection
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Model\Config $eavConfig,
diff --git a/app/code/Magento/CatalogSearch/Model/Resource/Fulltext/Collection.php b/app/code/Magento/CatalogSearch/Model/Resource/Fulltext/Collection.php
index 8fcdb929eb6..ef409d3af85 100644
--- a/app/code/Magento/CatalogSearch/Model/Resource/Fulltext/Collection.php
+++ b/app/code/Magento/CatalogSearch/Model/Resource/Fulltext/Collection.php
@@ -48,7 +48,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Product\Collection
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\Config $eavConfig
@@ -75,7 +75,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Product\Collection
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Model\Config $eavConfig,
diff --git a/app/code/Magento/CatalogSearch/Model/Resource/Search/Collection.php b/app/code/Magento/CatalogSearch/Model/Resource/Search/Collection.php
index b5c31a4afac..2880a05ef46 100644
--- a/app/code/Magento/CatalogSearch/Model/Resource/Search/Collection.php
+++ b/app/code/Magento/CatalogSearch/Model/Resource/Search/Collection.php
@@ -34,7 +34,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Product\Collection impl
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\Config $eavConfig
@@ -59,7 +59,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Product\Collection impl
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Model\Config $eavConfig,
diff --git a/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index/ValidatePaymentData.php b/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index/ValidatePaymentData.php
index ca56ba6eafe..1cb27e4d7b6 100644
--- a/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index/ValidatePaymentData.php
+++ b/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index/ValidatePaymentData.php
@@ -27,7 +27,7 @@ class ValidatePaymentData extends \Magento\Centinel\Controller\Adminhtml\Centine
         } catch (\Magento\Framework\Model\Exception $e) {
             $result['message'] = $e->getMessage();
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $result['message'] = __('Validation failed.');
         }
         $this->getResponse()->representJson(
diff --git a/app/code/Magento/Centinel/Model/Api.php b/app/code/Magento/Centinel/Model/Api.php
index bb2b990ab7d..223b299e43d 100644
--- a/app/code/Magento/Centinel/Model/Api.php
+++ b/app/code/Magento/Centinel/Model/Api.php
@@ -215,15 +215,15 @@ class Api extends \Magento\Framework\Object
     /**
      * Log adapter factory
      *
-     * @var \Magento\Framework\Logger\AdapterFactory
+     * @var \Psr\Log\LoggerInterface\AdapterFactory
      */
     protected $_logFactory;
 
     /**
-     * @param \Magento\Framework\Logger\AdapterFactory $logFactory
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logFactory
      * @param array $data
      */
-    public function __construct(\Magento\Framework\Logger\AdapterFactory $logFactory, array $data = [])
+    public function __construct(\Psr\Log\LoggerInterface\AdapterFactory $logFactory, array $data = [])
     {
         $this->_logFactory = $logFactory;
         parent::__construct($data);
diff --git a/app/code/Magento/Checkout/Controller/Cart/Add.php b/app/code/Magento/Checkout/Controller/Cart/Add.php
index d65ce4d25fd..64abe026ff2 100644
--- a/app/code/Magento/Checkout/Controller/Cart/Add.php
+++ b/app/code/Magento/Checkout/Controller/Cart/Add.php
@@ -134,7 +134,7 @@ class Add extends \Magento\Checkout\Controller\Cart
             }
         } catch (\Exception $e) {
             $this->messageManager->addException($e, __('We cannot add this item to your shopping cart'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->_goBack();
         }
     }
diff --git a/app/code/Magento/Checkout/Controller/Cart/Addgroup.php b/app/code/Magento/Checkout/Controller/Cart/Addgroup.php
index 658864a6afe..4911ebfd7ff 100644
--- a/app/code/Magento/Checkout/Controller/Cart/Addgroup.php
+++ b/app/code/Magento/Checkout/Controller/Cart/Addgroup.php
@@ -31,7 +31,7 @@ class Addgroup extends \Magento\Checkout\Controller\Cart
                     }
                 } catch (\Exception $e) {
                     $this->messageManager->addException($e, __('We cannot add this item to your shopping cart'));
-                    $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                    $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                     $this->_goBack();
                 }
             }
diff --git a/app/code/Magento/Checkout/Controller/Cart/Configure.php b/app/code/Magento/Checkout/Controller/Cart/Configure.php
index 92b2565d72d..99fd6f18230 100644
--- a/app/code/Magento/Checkout/Controller/Cart/Configure.php
+++ b/app/code/Magento/Checkout/Controller/Cart/Configure.php
@@ -71,7 +71,7 @@ class Configure extends \Magento\Checkout\Controller\Cart
             return $resultPage;
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We cannot configure the product.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->_goBack();
             return;
         }
diff --git a/app/code/Magento/Checkout/Controller/Cart/CouponPost.php b/app/code/Magento/Checkout/Controller/Cart/CouponPost.php
index e9eea809d94..4bb72d37dae 100644
--- a/app/code/Magento/Checkout/Controller/Cart/CouponPost.php
+++ b/app/code/Magento/Checkout/Controller/Cart/CouponPost.php
@@ -103,7 +103,7 @@ class CouponPost extends \Magento\Checkout\Controller\Cart
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We cannot apply the coupon code.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
 
         $this->_goBack();
diff --git a/app/code/Magento/Checkout/Controller/Cart/Delete.php b/app/code/Magento/Checkout/Controller/Cart/Delete.php
index a22b198f813..0e57262dd25 100644
--- a/app/code/Magento/Checkout/Controller/Cart/Delete.php
+++ b/app/code/Magento/Checkout/Controller/Cart/Delete.php
@@ -20,7 +20,7 @@ class Delete extends \Magento\Checkout\Controller\Cart
                 $this->cart->removeItem($id)->save();
             } catch (\Exception $e) {
                 $this->messageManager->addError(__('We cannot remove the item.'));
-                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             }
         }
         $defaultUrl = $this->_objectManager->create('Magento\Framework\UrlInterface')->getUrl('*/*');
diff --git a/app/code/Magento/Checkout/Controller/Cart/UpdateItemOptions.php b/app/code/Magento/Checkout/Controller/Cart/UpdateItemOptions.php
index afdedd5cf20..7cc5528e1a4 100644
--- a/app/code/Magento/Checkout/Controller/Cart/UpdateItemOptions.php
+++ b/app/code/Magento/Checkout/Controller/Cart/UpdateItemOptions.php
@@ -83,7 +83,7 @@ class UpdateItemOptions extends \Magento\Checkout\Controller\Cart
             }
         } catch (\Exception $e) {
             $this->messageManager->addException($e, __('We cannot update the item.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->_goBack();
         }
         $this->_redirect('*/*');
diff --git a/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php b/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php
index ab836be0630..314755827a7 100644
--- a/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php
+++ b/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php
@@ -56,7 +56,7 @@ class UpdatePost extends \Magento\Checkout\Controller\Cart
             );
         } catch (\Exception $e) {
             $this->messageManager->addException($e, __('We cannot update the shopping cart.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
     }
 
diff --git a/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php b/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php
index 42161ccd2f7..1fa75bfe5cc 100644
--- a/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php
+++ b/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php
@@ -63,7 +63,7 @@ class SaveOrder extends \Magento\Checkout\Controller\Onepage
             $result['goto_section'] = 'payment';
             $result['update_section'] = ['name' => 'payment-method', 'html' => $this->_getPaymentMethodsHtml()];
         } catch (\Magento\Framework\Model\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->_objectManager->get(
                 'Magento\Checkout\Helper\Data'
             )->sendPaymentFailedEmail(
@@ -91,7 +91,7 @@ class SaveOrder extends \Magento\Checkout\Controller\Onepage
                 $this->getOnepage()->getCheckout()->setUpdateSection(null);
             }
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->_objectManager->get(
                 'Magento\Checkout\Helper\Data'
             )->sendPaymentFailedEmail(
diff --git a/app/code/Magento/Checkout/Controller/Onepage/SavePayment.php b/app/code/Magento/Checkout/Controller/Onepage/SavePayment.php
index 01b590b7345..28e561ecaa5 100644
--- a/app/code/Magento/Checkout/Controller/Onepage/SavePayment.php
+++ b/app/code/Magento/Checkout/Controller/Onepage/SavePayment.php
@@ -56,7 +56,7 @@ class SavePayment extends \Magento\Checkout\Controller\Onepage
         } catch (\Magento\Framework\Model\Exception $e) {
             $result['error'] = $e->getMessage();
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $result['error'] = __('Unable to set Payment Method');
         }
         $this->getResponse()->representJson(
diff --git a/app/code/Magento/Checkout/Model/Type/Onepage.php b/app/code/Magento/Checkout/Model/Type/Onepage.php
index d4fb6787fc8..ec1ea9cafb0 100644
--- a/app/code/Magento/Checkout/Model/Type/Onepage.php
+++ b/app/code/Magento/Checkout/Model/Type/Onepage.php
@@ -51,7 +51,7 @@ class Onepage
     protected $_helper;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -168,7 +168,7 @@ class Onepage
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Checkout\Helper\Data $helper
      * @param \Magento\Customer\Model\Url $customerUrl
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
@@ -196,7 +196,7 @@ class Onepage
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Checkout\Helper\Data $helper,
         \Magento\Customer\Model\Url $customerUrl,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Checkout\Model\Session $checkoutSession,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
diff --git a/app/code/Magento/Checkout/Service/V1/Address/Billing/WriteService.php b/app/code/Magento/Checkout/Service/V1/Address/Billing/WriteService.php
index eda52bc6725..2a5e12158c6 100644
--- a/app/code/Magento/Checkout/Service/V1/Address/Billing/WriteService.php
+++ b/app/code/Magento/Checkout/Service/V1/Address/Billing/WriteService.php
@@ -9,7 +9,7 @@ use Magento\Checkout\Service\V1\Address\Validator;
 use Magento\Sales\Model\Quote\AddressFactory;
 use Magento\Sales\Model\QuoteRepository;
 use Magento\Framework\Exception\InputException;
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 
 /** Quote billing address write service object. */
 class WriteService implements WriteServiceInterface
diff --git a/app/code/Magento/Checkout/Service/V1/Address/Shipping/WriteService.php b/app/code/Magento/Checkout/Service/V1/Address/Shipping/WriteService.php
index 233779fb691..779e2001910 100644
--- a/app/code/Magento/Checkout/Service/V1/Address/Shipping/WriteService.php
+++ b/app/code/Magento/Checkout/Service/V1/Address/Shipping/WriteService.php
@@ -6,7 +6,7 @@ namespace Magento\Checkout\Service\V1\Address\Shipping;
 
 use Magento\Framework\Exception\InputException;
 use Magento\Framework\Exception\NoSuchEntityException;
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 
 /** Quote shipping address write service object. */
 class WriteService implements WriteServiceInterface
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Directive.php b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Directive.php
index a6d90682ca4..956bf2f9719 100644
--- a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Directive.php
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Directive.php
@@ -28,7 +28,7 @@ class Directive extends \Magento\Backend\App\Action
         } catch (\Exception $e) {
             $image->open($this->_objectManager->get('Magento\Cms\Model\Wysiwyg\Config')->getSkinImagePlaceholderUrl());
             $response->setHeader('Content-Type', $image->getMimeType())->setBody($image->getImage());
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
     }
 }
diff --git a/app/code/Magento/Cms/Model/Resource/Page/Grid/Collection.php b/app/code/Magento/Cms/Model/Resource/Page/Grid/Collection.php
index d0610198550..4c97a28717c 100644
--- a/app/code/Magento/Cms/Model/Resource/Page/Grid/Collection.php
+++ b/app/code/Magento/Cms/Model/Resource/Page/Grid/Collection.php
@@ -27,7 +27,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
@@ -36,7 +36,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
index 688d04e2f09..961e7861f02 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
@@ -163,7 +163,7 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType
      * @param \Magento\Core\Helper\File\Storage\Database $fileStorageDb
      * @param \Magento\Framework\Filesystem $filesystem
      * @param \Magento\Framework\Registry $coreRegistry
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param ProductRepositoryInterface $productRepository
      * @param \Magento\ConfigurableProduct\Model\Resource\Product\Type\ConfigurableFactory $typeConfigurableFactory
      * @param \Magento\Eav\Model\EntityFactory $entityFactory
@@ -187,7 +187,7 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType
         \Magento\Core\Helper\File\Storage\Database $fileStorageDb,
         \Magento\Framework\Filesystem $filesystem,
         \Magento\Framework\Registry $coreRegistry,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         ProductRepositoryInterface $productRepository,
         \Magento\ConfigurableProduct\Model\Resource\Product\Type\ConfigurableFactory $typeConfigurableFactory,
         \Magento\Eav\Model\EntityFactory $entityFactory,
diff --git a/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Collection/AssociatedProduct.php b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Collection/AssociatedProduct.php
index 3a6ea1b12da..c9c9e020bd5 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Collection/AssociatedProduct.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Collection/AssociatedProduct.php
@@ -40,7 +40,7 @@ class AssociatedProduct extends \Magento\Catalog\Model\Resource\Product\Collecti
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\Config $eavConfig
@@ -67,7 +67,7 @@ class AssociatedProduct extends \Magento\Catalog\Model\Resource\Product\Collecti
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Model\Config $eavConfig,
diff --git a/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Collection.php b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Collection.php
index 7ccbfe16b59..2d8efc12b7a 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Collection.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable/Attribute/Collection.php
@@ -66,7 +66,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
@@ -79,7 +79,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
diff --git a/app/code/Magento/Core/Model/File/Storage/File.php b/app/code/Magento/Core/Model/File/Storage/File.php
index 7917ade47ef..66ac32332d0 100644
--- a/app/code/Magento/Core/Model/File/Storage/File.php
+++ b/app/code/Magento/Core/Model/File/Storage/File.php
@@ -50,18 +50,18 @@ class File
     protected $_errors = [];
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
     /**
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Core\Helper\File\Storage\Database $storageHelper
      * @param \Magento\Core\Helper\File\Media $mediaHelper
      * @param \Magento\Core\Model\Resource\File\Storage\File $fileUtility
      */
     public function __construct(
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Core\Helper\File\Storage\Database $storageHelper,
         \Magento\Core\Helper\File\Media $mediaHelper,
         \Magento\Core\Model\Resource\File\Storage\File $fileUtility
diff --git a/app/code/Magento/Core/Model/Layout/Merge.php b/app/code/Magento/Core/Model/Layout/Merge.php
index b23f5e4b2a3..7b643b265fe 100644
--- a/app/code/Magento/Core/Model/Layout/Merge.php
+++ b/app/code/Magento/Core/Model/Layout/Merge.php
@@ -113,7 +113,7 @@ class Merge implements \Magento\Framework\View\Layout\ProcessorInterface
     protected $_layoutValidator;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -143,7 +143,7 @@ class Merge implements \Magento\Framework\View\Layout\ProcessorInterface
      * @param \Magento\Framework\App\State $appState
      * @param \Magento\Framework\Cache\FrontendInterface $cache
      * @param \Magento\Core\Model\Layout\Update\Validator $validator
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Filesystem $filesystem
      * @param \Magento\Framework\View\Design\ThemeInterface $theme Non-injectable theme instance
      * @param string $cacheSuffix
@@ -157,7 +157,7 @@ class Merge implements \Magento\Framework\View\Layout\ProcessorInterface
         \Magento\Framework\App\State $appState,
         \Magento\Framework\Cache\FrontendInterface $cache,
         \Magento\Core\Model\Layout\Update\Validator $validator,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Filesystem $filesystem,
         \Magento\Framework\View\Design\ThemeInterface $theme = null,
         $cacheSuffix = ''
diff --git a/app/code/Magento/Core/Model/Observer.php b/app/code/Magento/Core/Model/Observer.php
index b8a6713dee9..9f67373acca 100644
--- a/app/code/Magento/Core/Model/Observer.php
+++ b/app/code/Magento/Core/Model/Observer.php
@@ -44,7 +44,7 @@ class Observer
     protected $_registration;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -55,7 +55,7 @@ class Observer
      * @param \Magento\Framework\App\Config\ReinitableConfigInterface $config
      * @param \Magento\Framework\View\Asset\Repository $assetRepo
      * @param Theme\Registration $registration
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      */
     public function __construct(
         \Magento\Framework\App\Cache\Frontend\Pool $cacheFrontendPool,
@@ -64,7 +64,7 @@ class Observer
         \Magento\Framework\App\Config\ReinitableConfigInterface $config,
         \Magento\Framework\View\Asset\Repository $assetRepo,
         \Magento\Core\Model\Theme\Registration $registration,
-        \Magento\Framework\Logger $logger
+        \Psr\Log\LoggerInterface $logger
     ) {
         $this->_cacheFrontendPool = $cacheFrontendPool;
         $this->_currentTheme = $design->getDesignTheme();
diff --git a/app/code/Magento/Core/Model/Resource/Design/Collection.php b/app/code/Magento/Core/Model/Resource/Design/Collection.php
index 05c1d98f23e..4d0f641ead4 100644
--- a/app/code/Magento/Core/Model/Resource/Design/Collection.php
+++ b/app/code/Magento/Core/Model/Resource/Design/Collection.php
@@ -16,7 +16,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
@@ -25,7 +25,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Framework\Stdlib\DateTime $dateTime,
diff --git a/app/code/Magento/Core/Model/Resource/File/Storage/File.php b/app/code/Magento/Core/Model/Resource/File/Storage/File.php
index e605745b233..74e1eb3c16b 100644
--- a/app/code/Magento/Core/Model/Resource/File/Storage/File.php
+++ b/app/code/Magento/Core/Model/Resource/File/Storage/File.php
@@ -17,15 +17,15 @@ class File
     protected $_filesystem;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
     /**
      * @param \Magento\Framework\Filesystem $filesystem
-     * @param \Magento\Framework\Logger $log
+     * @param \Psr\Log\LoggerInterface $log
      */
-    public function __construct(\Magento\Framework\Filesystem $filesystem, \Magento\Framework\Logger $log)
+    public function __construct(\Magento\Framework\Filesystem $filesystem, \Psr\Log\LoggerInterface $log)
     {
         $this->_logger = $log;
         $this->_filesystem = $filesystem;
diff --git a/app/code/Magento/Core/Model/Resource/Layout/Link/Collection.php b/app/code/Magento/Core/Model/Resource/Layout/Link/Collection.php
index 0669794c3c7..926b672c14a 100644
--- a/app/code/Magento/Core/Model/Resource/Layout/Link/Collection.php
+++ b/app/code/Magento/Core/Model/Resource/Layout/Link/Collection.php
@@ -15,7 +15,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
     protected $dateTime;
 
     /**
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
@@ -25,7 +25,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Framework\Stdlib\DateTime $dateTime,
diff --git a/app/code/Magento/Core/Model/Resource/Layout/Update/Collection.php b/app/code/Magento/Core/Model/Resource/Layout/Update/Collection.php
index 01a14102107..3254d1aa002 100644
--- a/app/code/Magento/Core/Model/Resource/Layout/Update/Collection.php
+++ b/app/code/Magento/Core/Model/Resource/Layout/Update/Collection.php
@@ -30,7 +30,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
@@ -39,7 +39,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Framework\Stdlib\DateTime $dateTime,
diff --git a/app/code/Magento/Customer/Controller/Account/LoginPost.php b/app/code/Magento/Customer/Controller/Account/LoginPost.php
index ad470d2b4e3..e409febe60f 100644
--- a/app/code/Magento/Customer/Controller/Account/LoginPost.php
+++ b/app/code/Magento/Customer/Controller/Account/LoginPost.php
@@ -159,7 +159,7 @@ class LoginPost extends \Magento\Customer\Controller\Account
                     $this->_getSession()->setUsername($login['username']);
                 } catch (\Exception $e) {
                     // PA DSS violation: this exception log can disclose customer password
-                    // $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                    // $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                     $this->messageManager->addError(__('There was an error validating the login and password.'));
                 }
             } else {
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Wishlist.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Wishlist.php
index 854fdfa6e0a..c0b15e0b436 100644
--- a/app/code/Magento/Customer/Controller/Adminhtml/Index/Wishlist.php
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Wishlist.php
@@ -23,7 +23,7 @@ class Wishlist extends \Magento\Customer\Controller\Adminhtml\Index
             try {
                 $this->_objectManager->create('Magento\Wishlist\Model\Item')->load($itemId)->delete();
             } catch (\Exception $exception) {
-                $this->_objectManager->get('Magento\Framework\Logger')->critical($exception);
+                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($exception);
             }
         }
 
diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php
index 6e9e80e9d4a..d1c565944b7 100644
--- a/app/code/Magento/Customer/Model/AccountManagement.php
+++ b/app/code/Magento/Customer/Model/AccountManagement.php
@@ -25,7 +25,7 @@ use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Framework\Exception\State\ExpiredException;
 use Magento\Framework\Exception\State\InputMismatchException;
 use Magento\Framework\Exception\State\InvalidTransitionException;
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 use Magento\Framework\Mail\Exception as MailException;
 use Magento\Framework\Mail\Template\TransportBuilder;
 use Magento\Framework\Math\Random;
diff --git a/app/code/Magento/Customer/Model/Attribute/Data/Postcode.php b/app/code/Magento/Customer/Model/Attribute/Data/Postcode.php
index f492c92be48..489c138cef5 100644
--- a/app/code/Magento/Customer/Model/Attribute/Data/Postcode.php
+++ b/app/code/Magento/Customer/Model/Attribute/Data/Postcode.php
@@ -8,7 +8,7 @@ use Magento\Directory\Helper\Data as DirectoryHelper;
 use Magento\Eav\Model\AttributeDataFactory;
 use Magento\Framework\App\RequestInterface;
 use Magento\Framework\Locale\ResolverInterface;
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 use Magento\Framework\Stdlib\DateTime\TimezoneInterface as MagentoTimezone;
 
 /**
diff --git a/app/code/Magento/Customer/Model/Metadata/Form/AbstractData.php b/app/code/Magento/Customer/Model/Metadata/Form/AbstractData.php
index b7f66440bf4..e5c0978f140 100644
--- a/app/code/Magento/Customer/Model/Metadata/Form/AbstractData.php
+++ b/app/code/Magento/Customer/Model/Metadata/Form/AbstractData.php
@@ -57,7 +57,7 @@ abstract class AbstractData
     protected $_localeResolver;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -78,7 +78,7 @@ abstract class AbstractData
 
     /**
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Customer\Api\Data\AttributeMetadataInterface $attribute
      * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
      * @param string|int|bool $value
@@ -87,7 +87,7 @@ abstract class AbstractData
      */
     public function __construct(
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Customer\Api\Data\AttributeMetadataInterface $attribute,
         \Magento\Framework\Locale\ResolverInterface $localeResolver,
         $value,
diff --git a/app/code/Magento/Customer/Model/Metadata/Form/File.php b/app/code/Magento/Customer/Model/Metadata/Form/File.php
index c280217bcde..2d8f7a9b78f 100644
--- a/app/code/Magento/Customer/Model/Metadata/Form/File.php
+++ b/app/code/Magento/Customer/Model/Metadata/Form/File.php
@@ -44,7 +44,7 @@ class File extends AbstractData
 
     /**
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Customer\Api\Data\AttributeMetadataInterface $attribute
      * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
      * @param null $value
@@ -57,7 +57,7 @@ class File extends AbstractData
      */
     public function __construct(
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Customer\Api\Data\AttributeMetadataInterface $attribute,
         \Magento\Framework\Locale\ResolverInterface $localeResolver,
         $value,
diff --git a/app/code/Magento/Customer/Model/Metadata/Form/Postcode.php b/app/code/Magento/Customer/Model/Metadata/Form/Postcode.php
index 8cd0d39d0ea..531f5981928 100644
--- a/app/code/Magento/Customer/Model/Metadata/Form/Postcode.php
+++ b/app/code/Magento/Customer/Model/Metadata/Form/Postcode.php
@@ -8,7 +8,7 @@ use Magento\Customer\Api\Data\AttributeMetadataInterface;
 use Magento\Customer\Model\Metadata\ElementFactory;
 use Magento\Directory\Helper\Data as DirectoryHelper;
 use Magento\Framework\Locale\ResolverInterface;
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 use Magento\Framework\Stdlib\DateTime\TimezoneInterface as MagentoTimezone;
 
 /**
diff --git a/app/code/Magento/Customer/Model/Metadata/Form/Text.php b/app/code/Magento/Customer/Model/Metadata/Form/Text.php
index b9aa5340786..34802ae362c 100644
--- a/app/code/Magento/Customer/Model/Metadata/Form/Text.php
+++ b/app/code/Magento/Customer/Model/Metadata/Form/Text.php
@@ -17,7 +17,7 @@ class Text extends AbstractData
 
     /**
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Customer\Api\Data\AttributeMetadataInterface $attribute
      * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
      * @param string $value
@@ -27,7 +27,7 @@ class Text extends AbstractData
      */
     public function __construct(
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Customer\Api\Data\AttributeMetadataInterface $attribute,
         \Magento\Framework\Locale\ResolverInterface $localeResolver,
         $value,
diff --git a/app/code/Magento/Customer/Model/Resource/Customer/Collection.php b/app/code/Magento/Customer/Model/Resource/Customer/Collection.php
index ab1f24796f9..dfd228083a1 100644
--- a/app/code/Magento/Customer/Model/Resource/Customer/Collection.php
+++ b/app/code/Magento/Customer/Model/Resource/Customer/Collection.php
@@ -28,7 +28,7 @@ class Collection extends \Magento\Eav\Model\Entity\Collection\AbstractCollection
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\Config $eavConfig
@@ -44,7 +44,7 @@ class Collection extends \Magento\Eav\Model\Entity\Collection\AbstractCollection
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Model\Config $eavConfig,
diff --git a/app/code/Magento/Customer/Model/Vat.php b/app/code/Magento/Customer/Model/Vat.php
index 0b895ea65bb..de7be3cc606 100644
--- a/app/code/Magento/Customer/Model/Vat.php
+++ b/app/code/Magento/Customer/Model/Vat.php
@@ -5,7 +5,7 @@
 namespace Magento\Customer\Model;
 
 use Magento\Framework\App\Config\ScopeConfigInterface;
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 use Magento\Store\Model\ScopeInterface;
 
 /**
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor.php
index f7afe52525f..c412dc0c274 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor.php
@@ -123,7 +123,7 @@ class Editor extends \Magento\Backend\App\Action
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t load the list of themes.'));
             $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
     }
 
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/AssignThemeToStore.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/AssignThemeToStore.php
index 75750d2bea1..f5083bc5691 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/AssignThemeToStore.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/AssignThemeToStore.php
@@ -77,7 +77,7 @@ class AssignThemeToStore extends \Magento\DesignEditor\Controller\Adminhtml\Syst
             }
             $response = ['message' => $successMessage, 'themeId' => $themeCustomization->getId()];
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $response = ['error' => true, 'message' => __('This theme is not assigned.')];
         }
         $this->getResponse()->representJson($coreHelper->jsonEncode($response));
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Duplicate.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Duplicate.php
index 39c68bb0a40..eca41fcefbf 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Duplicate.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Duplicate.php
@@ -35,9 +35,9 @@ class Duplicate extends \Magento\DesignEditor\Controller\Adminhtml\System\Design
             $this->messageManager->addSuccess(__('You saved a duplicate copy of this theme in "My Customizations."'));
         } catch (CoreException $e) {
             $this->messageManager->addError($e->getMessage());
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->messageManager->addError(__('You cannot duplicate this theme.'));
         }
         $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/TreeJson.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/TreeJson.php
index 101b7e11157..a6623aded0a 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/TreeJson.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/TreeJson.php
@@ -23,7 +23,7 @@ class TreeJson extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg
                 )
             );
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->getResponse()->representJson(
                 $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode([])
             );
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Launch.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Launch.php
index 5ff329a13f0..2de06eed51e 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Launch.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Launch.php
@@ -154,12 +154,12 @@ class Launch extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Ed
             $this->_view->renderLayout();
         } catch (CoreException $e) {
             $this->messageManager->addException($e, $e->getMessage());
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->_redirect('adminhtml/*/');
             return;
         } catch (\Exception $e) {
             $this->messageManager->addException($e, __('Sorry, there was an unknown error.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->_redirect('adminhtml/*/');
             return;
         }
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/LoadThemeList.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/LoadThemeList.php
index 2ccd95bbf3f..a33bd2d476d 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/LoadThemeList.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/LoadThemeList.php
@@ -41,7 +41,7 @@ class LoadThemeList extends \Magento\DesignEditor\Controller\Adminhtml\System\De
 
             $response = ['content' => $this->_view->getLayout()->getOutput()];
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $response = ['error' => __('Sorry, but we can\'t load the theme list.')];
         }
         $this->getResponse()->representJson($coreHelper->jsonEncode($response));
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/QuickEdit.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/QuickEdit.php
index d34e1bc1c58..191ba153fba 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/QuickEdit.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/QuickEdit.php
@@ -31,9 +31,9 @@ class QuickEdit extends \Magento\DesignEditor\Controller\Adminhtml\System\Design
             $response = ['success' => true];
         } catch (CoreException $e) {
             $response = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $response = ['error' => true, 'message' => __('This theme is not saved.')];
         }
         $this->getResponse()->representJson($coreHelper->jsonEncode($response));
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Revert.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Revert.php
index 1e39c8688dc..7440420675a 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Revert.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Revert.php
@@ -47,7 +47,7 @@ class Revert extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Ed
             }
             $response = ['message' => $message];
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $response = ['error' => true, 'message' => __('Unknown error')];
         }
         /** @var $coreHelper \Magento\Core\Helper\Data */
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Save.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Save.php
index 07893246c8a..6594a57ebe5 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Save.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Save.php
@@ -28,7 +28,7 @@ class Save extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Edit
             }
             $response = ['message' => $message];
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $response = ['error' => true, 'message' => __('Sorry, there was an unknown error.')];
         }
 
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/DeleteCustomFiles.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/DeleteCustomFiles.php
index 2515d1ef020..fec2fb908a9 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/DeleteCustomFiles.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/DeleteCustomFiles.php
@@ -22,7 +22,7 @@ class DeleteCustomFiles extends \Magento\DesignEditor\Controller\Adminhtml\Syste
             $this->_forward('jsList');
         } catch (\Exception $e) {
             $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
     }
 }
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/JsList.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/JsList.php
index 04954eb5fd9..b260d9e175d 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/JsList.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/JsList.php
@@ -24,7 +24,7 @@ class JsList extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Ed
                 $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
             );
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
     }
 }
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveQuickStyleImage.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveQuickStyleImage.php
index b63a6c1c064..12b8a161c67 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveQuickStyleImage.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveQuickStyleImage.php
@@ -41,14 +41,14 @@ class RemoveQuickStyleImage extends \Magento\DesignEditor\Controller\Adminhtml\S
             $response = ['error' => false, 'content' => $result];
         } catch (CoreException $e) {
             $response = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         } catch (\Exception $e) {
             $errorMessage = __(
                 'Something went wrong uploading the image.' .
                 ' Please check the file format and try again (JPEG, GIF, or PNG).'
             );
             $response = ['error' => true, 'message' => $errorMessage];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveStoreLogo.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveStoreLogo.php
index 4e53fd32abe..1d2e9666f08 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveStoreLogo.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveStoreLogo.php
@@ -50,14 +50,14 @@ class RemoveStoreLogo extends \Magento\DesignEditor\Controller\Adminhtml\System\
             $response = ['error' => false, 'content' => []];
         } catch (CoreException $e) {
             $response = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         } catch (\Exception $e) {
             $errorMessage = __(
                 'Something went wrong uploading the image.' .
                 ' Please check the file format and try again (JPEG, GIF, or PNG).'
             );
             $response = ['error' => true, 'message' => $errorMessage];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/ReorderJs.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/ReorderJs.php
index 474c1148286..f7fb123df04 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/ReorderJs.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/ReorderJs.php
@@ -27,10 +27,10 @@ class ReorderJs extends \Magento\DesignEditor\Controller\Adminhtml\System\Design
             $result = ['success' => true];
         } catch (CoreException $e) {
             $result = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         } catch (\Exception $e) {
             $result = ['error' => true, 'message' => __('We cannot upload the CSS file.')];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveCssContent.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveCssContent.php
index 0ee26290c8b..8e2d1de1c79 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveCssContent.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveCssContent.php
@@ -35,10 +35,10 @@ class SaveCssContent extends \Magento\DesignEditor\Controller\Adminhtml\System\D
             ];
         } catch (CoreException $e) {
             $response = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         } catch (\Exception $e) {
             $response = ['error' => true, 'message' => __('We can\'t save the custom css file.')];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveImageSizing.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveImageSizing.php
index bec9dde0bb0..d29d45cdedc 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveImageSizing.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveImageSizing.php
@@ -35,10 +35,10 @@ class SaveImageSizing extends \Magento\DesignEditor\Controller\Adminhtml\System\
             $result = ['success' => true, 'message' => __('We saved the image sizes.')];
         } catch (CoreException $e) {
             $result = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         } catch (\Exception $e) {
             $result = ['error' => true, 'message' => __('We can\'t save image sizes.')];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveQuickStyles.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveQuickStyles.php
index a3444c0a3f1..53b8cbb3026 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveQuickStyles.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveQuickStyles.php
@@ -31,14 +31,14 @@ class SaveQuickStyles extends \Magento\DesignEditor\Controller\Adminhtml\System\
             $response = ['success' => true];
         } catch (CoreException $e) {
             $response = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         } catch (\Exception $e) {
             $errorMessage = __(
                 'Something went wrong uploading the image.' .
                 ' Please check the file format and try again (JPEG, GIF, or PNG).'
             );
             $response = ['error' => true, 'message' => $errorMessage];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/Upload.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/Upload.php
index 467d7738f7e..b6bce92f570 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/Upload.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/Upload.php
@@ -39,10 +39,10 @@ class Upload extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Ed
             ];
         } catch (CoreException $e) {
             $response = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         } catch (\Exception $e) {
             $response = ['error' => true, 'message' => __('We cannot upload the CSS file.')];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadJs.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadJs.php
index 4cb02a7149a..53120e8379b 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadJs.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadJs.php
@@ -33,10 +33,10 @@ class UploadJs extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\
             return;
         } catch (CoreException $e) {
             $response = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         } catch (\Exception $e) {
             $response = ['error' => true, 'message' => __('We cannot upload the JS file.')];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadQuickStyleImage.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadQuickStyleImage.php
index c1431963a5b..9ffd1d2e8cb 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadQuickStyleImage.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadQuickStyleImage.php
@@ -39,14 +39,14 @@ class UploadQuickStyleImage extends \Magento\DesignEditor\Controller\Adminhtml\S
         } catch (CoreException $e) {
             $this->messageManager->addError($e->getMessage());
             $response = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         } catch (\Exception $e) {
             $errorMessage = __(
                 'Something went wrong uploading the image.' .
                 ' Please check the file format and try again (JPEG, GIF, or PNG).'
             );
             $response = ['error' => true, 'message' => $errorMessage];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadStoreLogo.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadStoreLogo.php
index 5272738b3b1..ee93ce4c57b 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadStoreLogo.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadStoreLogo.php
@@ -44,14 +44,14 @@ class UploadStoreLogo extends \Magento\DesignEditor\Controller\Adminhtml\System\
             $response = ['error' => false, 'content' => ['name' => basename($storeLogo->getValue())]];
         } catch (CoreException $e) {
             $response = ['error' => true, 'message' => $e->getMessage()];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         } catch (\Exception $e) {
             $errorMessage = __(
                 'Something went wrong uploading the image.' .
                 ' Please check the file format and try again (JPEG, GIF, or PNG).'
             );
             $response = ['error' => true, 'message' => $errorMessage];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
diff --git a/app/code/Magento/Dhl/Model/Carrier.php b/app/code/Magento/Dhl/Model/Carrier.php
index 192050fe5fe..b81ffca5c10 100644
--- a/app/code/Magento/Dhl/Model/Carrier.php
+++ b/app/code/Magento/Dhl/Model/Carrier.php
@@ -184,7 +184,7 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateFactory
      * @param \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
@@ -210,7 +210,7 @@ class Carrier extends \Magento\Dhl\Model\AbstractDhl implements \Magento\Shippin
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory,
         \Magento\Shipping\Model\Rate\ResultFactory $rateFactory,
         \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
diff --git a/app/code/Magento/Directory/Model/PriceCurrency.php b/app/code/Magento/Directory/Model/PriceCurrency.php
index dafb8e1faa6..3cc16e54ca6 100644
--- a/app/code/Magento/Directory/Model/PriceCurrency.php
+++ b/app/code/Magento/Directory/Model/PriceCurrency.php
@@ -6,7 +6,7 @@ namespace Magento\Directory\Model;
 
 use Magento\Framework\App\ScopeInterface;
 use Magento\Store\Model\StoreManagerInterface;
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 use Magento\Store\Model\Store;
 
 /**
diff --git a/app/code/Magento/Directory/Model/Resource/Country/Collection.php b/app/code/Magento/Directory/Model/Resource/Country/Collection.php
index dbf8bbd6c59..ed505ab7aa0 100644
--- a/app/code/Magento/Directory/Model/Resource/Country/Collection.php
+++ b/app/code/Magento/Directory/Model/Resource/Country/Collection.php
@@ -43,7 +43,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\Locale\ListsInterface $localeLists
@@ -56,7 +56,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Framework\Locale\ListsInterface $localeLists,
diff --git a/app/code/Magento/Directory/Model/Resource/Region/Collection.php b/app/code/Magento/Directory/Model/Resource/Region/Collection.php
index 3669796392e..25e32fd40f5 100644
--- a/app/code/Magento/Directory/Model/Resource/Region/Collection.php
+++ b/app/code/Magento/Directory/Model/Resource/Region/Collection.php
@@ -31,7 +31,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
@@ -40,7 +40,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Framework\Locale\ResolverInterface $localeResolver,
diff --git a/app/code/Magento/Downloadable/Model/Product/Type.php b/app/code/Magento/Downloadable/Model/Product/Type.php
index 054db0e1eb8..3fa35f6189e 100644
--- a/app/code/Magento/Downloadable/Model/Product/Type.php
+++ b/app/code/Magento/Downloadable/Model/Product/Type.php
@@ -63,7 +63,7 @@ class Type extends \Magento\Catalog\Model\Product\Type\Virtual
      * @param \Magento\Core\Helper\File\Storage\Database $fileStorageDb
      * @param \Magento\Framework\Filesystem $filesystem
      * @param \Magento\Framework\Registry $coreRegistry
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param ProductRepositoryInterface $productRepository
      * @param \Magento\Downloadable\Helper\File $downloadableFile
      * @param \Magento\Downloadable\Model\Resource\SampleFactory $sampleResFactory
@@ -82,7 +82,7 @@ class Type extends \Magento\Catalog\Model\Product\Type\Virtual
         \Magento\Core\Helper\File\Storage\Database $fileStorageDb,
         \Magento\Framework\Filesystem $filesystem,
         \Magento\Framework\Registry $coreRegistry,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         ProductRepositoryInterface $productRepository,
         \Magento\Downloadable\Helper\File $downloadableFile,
         \Magento\Downloadable\Model\Resource\SampleFactory $sampleResFactory,
diff --git a/app/code/Magento/Eav/Model/Attribute/Data/AbstractData.php b/app/code/Magento/Eav/Model/Attribute/Data/AbstractData.php
index d27bd6c5781..f8a52ed7bde 100644
--- a/app/code/Magento/Eav/Model/Attribute/Data/AbstractData.php
+++ b/app/code/Magento/Eav/Model/Attribute/Data/AbstractData.php
@@ -75,18 +75,18 @@ abstract class AbstractData
     protected $_localeResolver;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
     /**
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
      */
     public function __construct(
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Locale\ResolverInterface $localeResolver
     ) {
         $this->_localeDate = $localeDate;
diff --git a/app/code/Magento/Eav/Model/Attribute/Data/File.php b/app/code/Magento/Eav/Model/Attribute/Data/File.php
index 0886e2d94ab..94b0e6ff1c6 100644
--- a/app/code/Magento/Eav/Model/Attribute/Data/File.php
+++ b/app/code/Magento/Eav/Model/Attribute/Data/File.php
@@ -38,7 +38,7 @@ class File extends \Magento\Eav\Model\Attribute\Data\AbstractData
 
     /**
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
      * @param \Magento\Framework\Url\EncoderInterface $urlEncoder
      * @param \Magento\Core\Model\File\Validator\NotProtectedExtension $fileValidator
@@ -46,7 +46,7 @@ class File extends \Magento\Eav\Model\Attribute\Data\AbstractData
      */
     public function __construct(
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Locale\ResolverInterface $localeResolver,
         \Magento\Framework\Url\EncoderInterface $urlEncoder,
         \Magento\Core\Model\File\Validator\NotProtectedExtension $fileValidator,
diff --git a/app/code/Magento/Eav/Model/Attribute/Data/Text.php b/app/code/Magento/Eav/Model/Attribute/Data/Text.php
index 32e14853536..e32506f45dd 100644
--- a/app/code/Magento/Eav/Model/Attribute/Data/Text.php
+++ b/app/code/Magento/Eav/Model/Attribute/Data/Text.php
@@ -20,13 +20,13 @@ class Text extends \Magento\Eav\Model\Attribute\Data\AbstractData
 
     /**
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
      * @param \Magento\Framework\Stdlib\String $stringHelper
      */
     public function __construct(
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Locale\ResolverInterface $localeResolver,
         \Magento\Framework\Stdlib\String $stringHelper
     ) {
diff --git a/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php b/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php
index 4d4709d1ef6..9c10fc846bc 100644
--- a/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php
+++ b/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php
@@ -115,7 +115,7 @@ abstract class AbstractCollection extends \Magento\Framework\Data\Collection\Db
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\Config $eavConfig
@@ -127,7 +127,7 @@ abstract class AbstractCollection extends \Magento\Framework\Data\Collection\Db
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Model\Config $eavConfig,
diff --git a/app/code/Magento/Eav/Model/Entity/Setup/Context.php b/app/code/Magento/Eav/Model/Entity/Setup/Context.php
index 2ce7e2f7411..b08b99d84ab 100644
--- a/app/code/Magento/Eav/Model/Entity/Setup/Context.php
+++ b/app/code/Magento/Eav/Model/Entity/Setup/Context.php
@@ -14,7 +14,7 @@ class Context extends \Magento\Framework\Module\Setup\Context
     protected $attributeMapper;
 
     /**
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\App\Resource $appResource
      * @param \Magento\Framework\Module\Dir\Reader $modulesReader
@@ -26,7 +26,7 @@ class Context extends \Magento\Framework\Module\Setup\Context
      * @param PropertyMapperInterface $attributeMapper
      */
     public function __construct(
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Framework\App\Resource $appResource,
         \Magento\Framework\Module\Dir\Reader $modulesReader,
diff --git a/app/code/Magento/Eav/Model/Resource/Attribute/Collection.php b/app/code/Magento/Eav/Model/Resource/Attribute/Collection.php
index 0a9317b4f9f..6cb28f94a1c 100644
--- a/app/code/Magento/Eav/Model/Resource/Attribute/Collection.php
+++ b/app/code/Magento/Eav/Model/Resource/Attribute/Collection.php
@@ -39,7 +39,7 @@ abstract class Collection extends \Magento\Eav\Model\Resource\Entity\Attribute\C
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\Config $eavConfig
@@ -49,7 +49,7 @@ abstract class Collection extends \Magento\Eav\Model\Resource\Entity\Attribute\C
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Model\Config $eavConfig,
diff --git a/app/code/Magento/Eav/Model/Resource/Entity/Attribute/Collection.php b/app/code/Magento/Eav/Model/Resource/Entity/Attribute/Collection.php
index 8a98da583ab..240a6419a32 100644
--- a/app/code/Magento/Eav/Model/Resource/Entity/Attribute/Collection.php
+++ b/app/code/Magento/Eav/Model/Resource/Entity/Attribute/Collection.php
@@ -27,7 +27,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\Config $eavConfig
@@ -36,7 +36,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Model\Config $eavConfig,
diff --git a/app/code/Magento/Eav/Model/Resource/Entity/Attribute/Grid/Collection.php b/app/code/Magento/Eav/Model/Resource/Entity/Attribute/Grid/Collection.php
index a6ac2254c5e..5aa44c5e823 100644
--- a/app/code/Magento/Eav/Model/Resource/Entity/Attribute/Grid/Collection.php
+++ b/app/code/Magento/Eav/Model/Resource/Entity/Attribute/Grid/Collection.php
@@ -20,7 +20,7 @@ class Collection extends \Magento\Eav\Model\Resource\Entity\Attribute\Set\Collec
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\Registry $registryManager
@@ -29,7 +29,7 @@ class Collection extends \Magento\Eav\Model\Resource\Entity\Attribute\Set\Collec
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Framework\Registry $registryManager,
diff --git a/app/code/Magento/Eav/Model/Resource/Entity/Attribute/Option/Collection.php b/app/code/Magento/Eav/Model/Resource/Entity/Attribute/Option/Collection.php
index 103f98ab770..63f6ace2580 100644
--- a/app/code/Magento/Eav/Model/Resource/Entity/Attribute/Option/Collection.php
+++ b/app/code/Magento/Eav/Model/Resource/Entity/Attribute/Option/Collection.php
@@ -30,7 +30,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\App\Resource $coreResource
@@ -40,7 +40,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Framework\App\Resource $coreResource,
diff --git a/app/code/Magento/Eav/Model/Resource/Form/Attribute/Collection.php b/app/code/Magento/Eav/Model/Resource/Form/Attribute/Collection.php
index 780c1e81c7b..269fd414ecc 100644
--- a/app/code/Magento/Eav/Model/Resource/Form/Attribute/Collection.php
+++ b/app/code/Magento/Eav/Model/Resource/Form/Attribute/Collection.php
@@ -51,7 +51,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\Config $eavConfig
@@ -61,7 +61,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Model\Config $eavConfig,
diff --git a/app/code/Magento/Eav/Model/Resource/Form/Fieldset/Collection.php b/app/code/Magento/Eav/Model/Resource/Form/Fieldset/Collection.php
index 5cd3436044b..33a959f9b95 100644
--- a/app/code/Magento/Eav/Model/Resource/Form/Fieldset/Collection.php
+++ b/app/code/Magento/Eav/Model/Resource/Form/Fieldset/Collection.php
@@ -16,7 +16,7 @@ use Magento\Eav\Model\Form\Type;
 use Magento\Framework\Event\ManagerInterface;
 use Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
 use Magento\Framework\Model\Resource\Db\AbstractDb;
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 use Magento\Store\Model\StoreManagerInterface;
 
 class Collection extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCollection
diff --git a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/DefaultTemplate.php b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/DefaultTemplate.php
index 95e2cc37a65..8ffde1bd2a1 100644
--- a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/DefaultTemplate.php
+++ b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/DefaultTemplate.php
@@ -29,7 +29,7 @@ class DefaultTemplate extends \Magento\Email\Controller\Adminhtml\Email\Template
                 $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($template->getData())
             );
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
     }
 }
diff --git a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Delete.php b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Delete.php
index 390449040fa..1e2c4d36964 100644
--- a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Delete.php
+++ b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Delete.php
@@ -38,7 +38,7 @@ class Delete extends \Magento\Email\Controller\Adminhtml\Email\Template
                 $this->messageManager->addError(
                     __('An error occurred while deleting email template data. Please review log and try again.')
                 );
-                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                 // save data in session
                 $this->_objectManager->get(
                     'Magento\Backend\Model\Session'
diff --git a/app/code/Magento/Email/Model/Template/Filter.php b/app/code/Magento/Email/Model/Template/Filter.php
index 23042755a42..5bdfa48d884 100644
--- a/app/code/Magento/Email/Model/Template/Filter.php
+++ b/app/code/Magento/Email/Model/Template/Filter.php
@@ -51,7 +51,7 @@ class Filter extends \Magento\Framework\Filter\Template
     protected $_assetRepo;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -111,7 +111,7 @@ class Filter extends \Magento\Framework\Filter\Template
 
     /**
      * @param \Magento\Framework\Stdlib\String $string
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Escaper $escaper
      * @param \Magento\Framework\View\Asset\Repository $assetRepo
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
@@ -127,7 +127,7 @@ class Filter extends \Magento\Framework\Filter\Template
      */
     public function __construct(
         \Magento\Framework\Stdlib\String $string,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Escaper $escaper,
         \Magento\Framework\View\Asset\Repository $assetRepo,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
diff --git a/app/code/Magento/Fedex/Model/Carrier.php b/app/code/Magento/Fedex/Model/Carrier.php
index 74c42bf5476..7b94207a152 100644
--- a/app/code/Magento/Fedex/Model/Carrier.php
+++ b/app/code/Magento/Fedex/Model/Carrier.php
@@ -107,7 +107,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
     protected $_storeManager;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -119,7 +119,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateFactory
      * @param \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
@@ -141,7 +141,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory,
         \Magento\Shipping\Model\Rate\ResultFactory $rateFactory,
         \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/ConfirmCaptcha.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/ConfirmCaptcha.php
index 0db9bc133cb..233891f88b2 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/ConfirmCaptcha.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/ConfirmCaptcha.php
@@ -41,7 +41,7 @@ class ConfirmCaptcha extends \Magento\GoogleShopping\Controller\Adminhtml\Google
                 )
             );
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->messageManager->addError(__('Something went wrong during Captcha confirmation.'));
         }
 
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAdd.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAdd.php
index 7af24ce9278..d9b56660354 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAdd.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAdd.php
@@ -48,7 +48,7 @@ class MassAdd extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshoppin
                 __('An error has occurred while adding products to google shopping account.'),
                 $e->getMessage()
             );
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             return;
         }
 
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Refresh.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Refresh.php
index 86fefea98a0..8d9a12f1ee3 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Refresh.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Refresh.php
@@ -55,7 +55,7 @@ class Refresh extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshoppin
                     'One or more products were not deleted from google shopping account. Refer to the log file for details.'
                 )
             );
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             return;
         }
 
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Delete.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Delete.php
index 2edcfdf8e12..57fc8b200a6 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Delete.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Delete.php
@@ -23,7 +23,7 @@ class Delete extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping
             }
             $this->messageManager->addSuccess(__('Attribute set mapping was deleted'));
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->messageManager->addError(__("We can't delete Attribute Set Mapping."));
         }
         $this->_redirect('adminhtml/*/index', ['store' => $this->_getStore()->getId()]);
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Edit.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Edit.php
index becfb35dcaf..1817702a5c7 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Edit.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Edit.php
@@ -43,7 +43,7 @@ class Edit extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\T
             $this->_view->getPage()->getConfig()->getTitle()->prepend(__('Google Content Attributes'));
             $this->_view->renderLayout();
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->messageManager->addError(__("We can't edit Attribute Set Mapping."));
             $this->_redirect('adminhtml/*/index');
         }
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSets.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSets.php
index c76f979a21c..3daee5428e1 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSets.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSets.php
@@ -23,7 +23,7 @@ class LoadAttributeSets extends \Magento\GoogleShopping\Controller\Adminhtml\Goo
                 )->toHtml()
             );
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             // just need to output text with error
             $this->messageManager->addError(__("We can't load attribute sets."));
         }
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributes.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributes.php
index 460df0e6451..e427a4664df 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributes.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributes.php
@@ -27,7 +27,7 @@ class LoadAttributes extends \Magento\GoogleShopping\Controller\Adminhtml\Google
                 )->toHtml()
             );
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             // just need to output text with error
             $this->messageManager->addError(__("We can't load attributes."));
         }
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/NewAction.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/NewAction.php
index db5181519ed..2d56b33d667 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/NewAction.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/NewAction.php
@@ -26,7 +26,7 @@ class NewAction extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopp
             $this->_view->getPage()->getConfig()->getTitle()->prepend(__('New Google Content Attribute Mapping'));
             $this->_view->renderLayout();
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->messageManager->addError(__("We can't create Attribute Set Mapping."));
             $this->_redirect('adminhtml/*/index', ['store' => $this->_getStore()->getId()]);
         }
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Save.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Save.php
index b57f533e8ee..f2ee9b58d4b 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Save.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Save.php
@@ -71,7 +71,7 @@ class Save extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\T
                 );
             }
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->messageManager->addError(__("We can't save Attribute Set Mapping."));
         }
         $this->_redirect('adminhtml/*/index', ['store' => $this->_getStore()->getId()]);
diff --git a/app/code/Magento/GoogleShopping/Model/MassOperations.php b/app/code/Magento/GoogleShopping/Model/MassOperations.php
index 3e1b53b22fc..52c6f69d1e9 100644
--- a/app/code/Magento/GoogleShopping/Model/MassOperations.php
+++ b/app/code/Magento/GoogleShopping/Model/MassOperations.php
@@ -69,7 +69,7 @@ class MassOperations
      * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
      * @param \Magento\Framework\Notification\NotifierInterface $notifier
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\GoogleShopping\Helper\Data $gleShoppingData
      * @param \Magento\GoogleShopping\Helper\Category $gleShoppingCategory
      * @param array $data
@@ -80,7 +80,7 @@ class MassOperations
         \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
         \Magento\Framework\Notification\NotifierInterface $notifier,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\GoogleShopping\Helper\Data $gleShoppingData,
         \Magento\GoogleShopping\Helper\Category $gleShoppingCategory,
         array $data = []
@@ -119,7 +119,7 @@ class MassOperations
     /**
      * Logger
      *
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
diff --git a/app/code/Magento/GoogleShopping/Model/Resource/Item/Collection.php b/app/code/Magento/GoogleShopping/Model/Resource/Item/Collection.php
index 345e68b911d..4b932e02a34 100644
--- a/app/code/Magento/GoogleShopping/Model/Resource/Item/Collection.php
+++ b/app/code/Magento/GoogleShopping/Model/Resource/Item/Collection.php
@@ -27,7 +27,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\DB\Helper $resourceHelper
@@ -37,7 +37,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Framework\DB\Helper $resourceHelper,
diff --git a/app/code/Magento/GoogleShopping/Model/Service.php b/app/code/Magento/GoogleShopping/Model/Service.php
index 511b5d59983..e421d731a06 100644
--- a/app/code/Magento/GoogleShopping/Model/Service.php
+++ b/app/code/Magento/GoogleShopping/Model/Service.php
@@ -35,7 +35,7 @@ class Service extends \Magento\Framework\Object
     /**
      * Log adapter factory
      *
-     * @var \Magento\Framework\Logger\AdapterFactory
+     * @var \Psr\Log\LoggerInterface\AdapterFactory
      */
     protected $_logAdapterFactory;
 
@@ -57,14 +57,14 @@ class Service extends \Magento\Framework\Object
      * By default is looking for first argument as array and assigns it as object
      * attributes This behavior may change in child classes
      *
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param \Magento\Framework\Registry $coreRegistry
      * @param \Magento\GoogleShopping\Model\Config $config
      * @param \Magento\Framework\Gdata\Gshopping\ContentFactory $contentFactory
      * @param array $data
      */
     public function __construct(
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         \Magento\Framework\Registry $coreRegistry,
         \Magento\GoogleShopping\Model\Config $config,
         \Magento\Framework\Gdata\Gshopping\ContentFactory $contentFactory,
diff --git a/app/code/Magento/GoogleShopping/Model/Service/Item.php b/app/code/Magento/GoogleShopping/Model/Service/Item.php
index d00483fe86c..3ee511cb4f3 100644
--- a/app/code/Magento/GoogleShopping/Model/Service/Item.php
+++ b/app/code/Magento/GoogleShopping/Model/Service/Item.php
@@ -24,7 +24,7 @@ class Item extends \Magento\GoogleShopping\Model\Service
     protected $_date;
 
     /**
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param \Magento\Framework\Registry $coreRegistry
      * @param \Magento\GoogleShopping\Model\Config $config
      * @param \Magento\Framework\Gdata\Gshopping\ContentFactory $contentFactory
@@ -33,7 +33,7 @@ class Item extends \Magento\GoogleShopping\Model\Service
      * @param array $data
      */
     public function __construct(
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         \Magento\Framework\Registry $coreRegistry,
         \Magento\GoogleShopping\Model\Config $config,
         \Magento\Framework\Gdata\Gshopping\ContentFactory $contentFactory,
diff --git a/app/code/Magento/GroupedProduct/Controller/Adminhtml/Edit/Popup.php b/app/code/Magento/GroupedProduct/Controller/Adminhtml/Edit/Popup.php
index 96e19a61b0c..350cc7bb441 100644
--- a/app/code/Magento/GroupedProduct/Controller/Adminhtml/Edit/Popup.php
+++ b/app/code/Magento/GroupedProduct/Controller/Adminhtml/Edit/Popup.php
@@ -18,7 +18,7 @@ class Popup extends \Magento\Backend\App\AbstractAction
     protected $factory;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
@@ -26,13 +26,13 @@ class Popup extends \Magento\Backend\App\AbstractAction
      * @param \Magento\Backend\App\Action\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param \Magento\Catalog\Model\ProductFactory $factory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      */
     public function __construct(
         \Magento\Backend\App\Action\Context $context,
         \Magento\Framework\Registry $registry,
         \Magento\Catalog\Model\ProductFactory $factory,
-        \Magento\Framework\Logger $logger
+        \Psr\Log\LoggerInterface $logger
     ) {
         $this->registry = $registry;
         $this->factory = $factory;
diff --git a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php
index 34a82a60b5c..4a6f83b3ffd 100644
--- a/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php
+++ b/app/code/Magento/GroupedProduct/Model/Product/Type/Grouped.php
@@ -88,7 +88,7 @@ class Grouped extends \Magento\Catalog\Model\Product\Type\AbstractType
      * @param \Magento\Core\Helper\File\Storage\Database $fileStorageDb
      * @param \Magento\Framework\Filesystem $filesystem
      * @param \Magento\Framework\Registry $coreRegistry
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param ProductRepositoryInterface $productRepository
      * @param \Magento\GroupedProduct\Model\Resource\Product\Link $catalogProductLink
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
@@ -107,7 +107,7 @@ class Grouped extends \Magento\Catalog\Model\Product\Type\AbstractType
         \Magento\Core\Helper\File\Storage\Database $fileStorageDb,
         \Magento\Framework\Filesystem $filesystem,
         \Magento\Framework\Registry $coreRegistry,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         ProductRepositoryInterface $productRepository,
         \Magento\GroupedProduct\Model\Resource\Product\Link $catalogProductLink,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
diff --git a/app/code/Magento/GroupedProduct/Model/Resource/Product/Type/Grouped/AssociatedProductsCollection.php b/app/code/Magento/GroupedProduct/Model/Resource/Product/Type/Grouped/AssociatedProductsCollection.php
index 923420bb700..c66cd3d23f3 100644
--- a/app/code/Magento/GroupedProduct/Model/Resource/Product/Type/Grouped/AssociatedProductsCollection.php
+++ b/app/code/Magento/GroupedProduct/Model/Resource/Product/Type/Grouped/AssociatedProductsCollection.php
@@ -27,7 +27,7 @@ class AssociatedProductsCollection extends \Magento\Catalog\Model\Resource\Produ
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\Config $eavConfig
@@ -53,7 +53,7 @@ class AssociatedProductsCollection extends \Magento\Catalog\Model\Resource\Produ
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Model\Config $eavConfig,
diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Export/Export.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Export/Export.php
index cf4d1863bc0..1ed8b3eb9e2 100644
--- a/app/code/Magento/ImportExport/Controller/Adminhtml/Export/Export.php
+++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Export/Export.php
@@ -48,7 +48,7 @@ class Export extends \Magento\ImportExport\Controller\Adminhtml\Export
             } catch (\Magento\Framework\Model\Exception $e) {
                 $this->messageManager->addError($e->getMessage());
             } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                 $this->messageManager->addError(__('Please correct the data sent.'));
             }
         } else {
diff --git a/app/code/Magento/ImportExport/Model/AbstractModel.php b/app/code/Magento/ImportExport/Model/AbstractModel.php
index 9aa76d99cab..987884e46fa 100644
--- a/app/code/Magento/ImportExport/Model/AbstractModel.php
+++ b/app/code/Magento/ImportExport/Model/AbstractModel.php
@@ -35,7 +35,7 @@ abstract class AbstractModel extends \Magento\Framework\Object
     protected $_logTrace = [];
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -45,12 +45,12 @@ abstract class AbstractModel extends \Magento\Framework\Object
     protected $_varDirectory;
 
     /**
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Filesystem $filesystem
      * @param array $data
      */
     public function __construct(
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Filesystem $filesystem,
         array $data = []
     ) {
diff --git a/app/code/Magento/ImportExport/Model/Export.php b/app/code/Magento/ImportExport/Model/Export.php
index 29f23a022ea..d4555391afd 100644
--- a/app/code/Magento/ImportExport/Model/Export.php
+++ b/app/code/Magento/ImportExport/Model/Export.php
@@ -56,7 +56,7 @@ class Export extends \Magento\ImportExport\Model\AbstractModel
     protected $_exportAdapterFac;
 
     /**
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Filesystem $filesystem
      * @param \Magento\ImportExport\Model\Export\ConfigInterface $exportConfig
      * @param \Magento\ImportExport\Model\Export\Entity\Factory $entityFactory
@@ -64,7 +64,7 @@ class Export extends \Magento\ImportExport\Model\AbstractModel
      * @param array $data
      */
     public function __construct(
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Filesystem $filesystem,
         \Magento\ImportExport\Model\Export\ConfigInterface $exportConfig,
         \Magento\ImportExport\Model\Export\Entity\Factory $entityFactory,
diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php
index 88b8226e498..37f63e1ce29 100644
--- a/app/code/Magento/ImportExport/Model/Import.php
+++ b/app/code/Magento/ImportExport/Model/Import.php
@@ -110,7 +110,7 @@ class Import extends \Magento\ImportExport\Model\AbstractModel
     protected $_filesystem;
 
     /**
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Filesystem $filesystem
      * @param \Magento\ImportExport\Helper\Data $importExportData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $coreConfig
@@ -125,7 +125,7 @@ class Import extends \Magento\ImportExport\Model\AbstractModel
      * @param array $data
      */
     public function __construct(
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Filesystem $filesystem,
         \Magento\ImportExport\Helper\Data $importExportData,
         \Magento\Framework\App\Config\ScopeConfigInterface $coreConfig,
diff --git a/app/code/Magento/Integration/Controller/Adminhtml/Integration.php b/app/code/Magento/Integration/Controller/Adminhtml/Integration.php
index 8e8b39726f7..2e1acd13200 100644
--- a/app/code/Magento/Integration/Controller/Adminhtml/Integration.php
+++ b/app/code/Magento/Integration/Controller/Adminhtml/Integration.php
@@ -27,7 +27,7 @@ class Integration extends Action
      */
     protected $_registry;
 
-    /** @var \Magento\Framework\Logger */
+    /** @var \Psr\Log\LoggerInterface */
     protected $_logger;
 
     /** @var \Magento\Integration\Service\V1\IntegrationInterface */
@@ -53,7 +53,7 @@ class Integration extends Action
     /**
      * @param \Magento\Backend\App\Action\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Integration\Service\V1\IntegrationInterface $integrationService
      * @param IntegrationOauthService $oauthService
      * @param \Magento\Core\Helper\Data $coreHelper
@@ -64,7 +64,7 @@ class Integration extends Action
     public function __construct(
         \Magento\Backend\App\Action\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Integration\Service\V1\IntegrationInterface $integrationService,
         IntegrationOauthService $oauthService,
         \Magento\Core\Helper\Data $coreHelper,
diff --git a/app/code/Magento/Integration/Service/V1/AuthorizationService.php b/app/code/Magento/Integration/Service/V1/AuthorizationService.php
index e394eba6f07..b6aed4022ff 100644
--- a/app/code/Magento/Integration/Service/V1/AuthorizationService.php
+++ b/app/code/Magento/Integration/Service/V1/AuthorizationService.php
@@ -15,7 +15,7 @@ use Magento\Framework\Acl;
 use Magento\Framework\Acl\Builder as AclBuilder;
 use Magento\Framework\Acl\RootResource as RootAclResource;
 use Magento\Framework\Exception\LocalizedException;
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 
 /**
  * Service for integration permissions management.
diff --git a/app/code/Magento/Integration/Service/V1/Oauth.php b/app/code/Magento/Integration/Service/V1/Oauth.php
index 58144ab6b2e..85f72fca0d0 100644
--- a/app/code/Magento/Integration/Service/V1/Oauth.php
+++ b/app/code/Magento/Integration/Service/V1/Oauth.php
@@ -46,7 +46,7 @@ class Oauth implements OauthInterface
     protected $_httpClient;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -68,7 +68,7 @@ class Oauth implements OauthInterface
      * @param TokenFactory $tokenFactory
      * @param IntegrationOauthHelper $dataHelper
      * @param \Magento\Framework\HTTP\ZendClient $httpClient
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param OauthHelper $oauthHelper
      * @param TokenProvider $tokenProvider
      */
@@ -78,7 +78,7 @@ class Oauth implements OauthInterface
         TokenFactory $tokenFactory,
         IntegrationOauthHelper $dataHelper,
         \Magento\Framework\HTTP\ZendClient $httpClient,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         OauthHelper $oauthHelper,
         TokenProvider $tokenProvider
     ) {
diff --git a/app/code/Magento/Log/Model/Resource/Visitor/Online/Collection.php b/app/code/Magento/Log/Model/Resource/Visitor/Online/Collection.php
index cfdaae9d44b..f0188880781 100644
--- a/app/code/Magento/Log/Model/Resource/Visitor/Online/Collection.php
+++ b/app/code/Magento/Log/Model/Resource/Visitor/Online/Collection.php
@@ -25,7 +25,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Helper\Data $eavHelper
@@ -34,7 +34,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Helper\Data $eavHelper,
diff --git a/app/code/Magento/Log/Model/Resource/Visitor/Online/Grid/Collection.php b/app/code/Magento/Log/Model/Resource/Visitor/Online/Grid/Collection.php
index 32971b43e8d..43ad1191785 100644
--- a/app/code/Magento/Log/Model/Resource/Visitor/Online/Grid/Collection.php
+++ b/app/code/Magento/Log/Model/Resource/Visitor/Online/Grid/Collection.php
@@ -15,7 +15,7 @@ class Collection extends \Magento\Log\Model\Resource\Visitor\Online\Collection
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Helper\Data $eavHelper
@@ -25,7 +25,7 @@ class Collection extends \Magento\Log\Model\Resource\Visitor\Online\Collection
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Helper\Data $eavHelper,
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Overview.php b/app/code/Magento/Multishipping/Controller/Checkout/Overview.php
index 54d82852748..23474bac028 100644
--- a/app/code/Magento/Multishipping/Controller/Checkout/Overview.php
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Overview.php
@@ -41,7 +41,7 @@ class Overview extends \Magento\Multishipping\Controller\Checkout
             $this->messageManager->addError($e->getMessage());
             $this->_redirect('*/*/billing');
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->messageManager->addException($e, __('We cannot open the overview page.'));
             $this->_redirect('*/*/billing');
         }
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/OverviewPost.php b/app/code/Magento/Multishipping/Controller/Checkout/OverviewPost.php
index 01b4a42a2a9..22b3cad9e9a 100644
--- a/app/code/Magento/Multishipping/Controller/Checkout/OverviewPost.php
+++ b/app/code/Magento/Multishipping/Controller/Checkout/OverviewPost.php
@@ -105,7 +105,7 @@ class OverviewPost extends \Magento\Multishipping\Controller\Checkout
             $this->messageManager->addError($e->getMessage());
             $this->_redirect('*/*/billing');
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->_objectManager->get(
                 'Magento\Checkout\Helper\Data'
             )->sendPaymentFailedEmail(
diff --git a/app/code/Magento/Newsletter/Model/Resource/Problem/Collection.php b/app/code/Magento/Newsletter/Model/Resource/Problem/Collection.php
index 2725043fc12..57fbf47df91 100644
--- a/app/code/Magento/Newsletter/Model/Resource/Problem/Collection.php
+++ b/app/code/Magento/Newsletter/Model/Resource/Problem/Collection.php
@@ -56,7 +56,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param CustomerRepository $customerRepository
@@ -66,7 +66,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         CustomerRepository $customerRepository,
diff --git a/app/code/Magento/Newsletter/Model/Resource/Queue/Collection.php b/app/code/Magento/Newsletter/Model/Resource/Queue/Collection.php
index c967aa6e7ba..99ad006db65 100644
--- a/app/code/Magento/Newsletter/Model/Resource/Queue/Collection.php
+++ b/app/code/Magento/Newsletter/Model/Resource/Queue/Collection.php
@@ -34,7 +34,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\Stdlib\DateTime\DateTime $date
@@ -43,7 +43,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Framework\Stdlib\DateTime\DateTime $date,
diff --git a/app/code/Magento/Newsletter/Model/Resource/Subscriber/Collection.php b/app/code/Magento/Newsletter/Model/Resource/Subscriber/Collection.php
index 6b405f08c38..1da9cb8fd70 100644
--- a/app/code/Magento/Newsletter/Model/Resource/Subscriber/Collection.php
+++ b/app/code/Magento/Newsletter/Model/Resource/Subscriber/Collection.php
@@ -57,7 +57,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Helper\Data $customerHelperData
@@ -66,7 +66,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Helper\Data $customerHelperData,
diff --git a/app/code/Magento/OfflineShipping/Model/Carrier/Flatrate.php b/app/code/Magento/OfflineShipping/Model/Carrier/Flatrate.php
index b7cb5714f64..559102029f3 100644
--- a/app/code/Magento/OfflineShipping/Model/Carrier/Flatrate.php
+++ b/app/code/Magento/OfflineShipping/Model/Carrier/Flatrate.php
@@ -35,7 +35,7 @@ class Flatrate extends \Magento\Shipping\Model\Carrier\AbstractCarrier implement
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory
      * @param \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
      * @param array $data
@@ -43,7 +43,7 @@ class Flatrate extends \Magento\Shipping\Model\Carrier\AbstractCarrier implement
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
         \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
         array $data = []
diff --git a/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php b/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php
index 3726bb282e3..5fac8565bab 100644
--- a/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php
+++ b/app/code/Magento/OfflineShipping/Model/Carrier/Freeshipping.php
@@ -36,7 +36,7 @@ class Freeshipping extends \Magento\Shipping\Model\Carrier\AbstractCarrier imple
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory
      * @param \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
      * @param array $data
@@ -44,7 +44,7 @@ class Freeshipping extends \Magento\Shipping\Model\Carrier\AbstractCarrier imple
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
         \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
         array $data = []
diff --git a/app/code/Magento/OfflineShipping/Model/Carrier/Pickup.php b/app/code/Magento/OfflineShipping/Model/Carrier/Pickup.php
index 133816020ee..d689bef7b95 100644
--- a/app/code/Magento/OfflineShipping/Model/Carrier/Pickup.php
+++ b/app/code/Magento/OfflineShipping/Model/Carrier/Pickup.php
@@ -30,7 +30,7 @@ class Pickup extends \Magento\Shipping\Model\Carrier\AbstractCarrier implements
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory
      * @param \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
      * @param array $data
@@ -38,7 +38,7 @@ class Pickup extends \Magento\Shipping\Model\Carrier\AbstractCarrier implements
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
         \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
         array $data = []
diff --git a/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php b/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php
index aa61363567b..710c6b45ff3 100644
--- a/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php
+++ b/app/code/Magento/OfflineShipping/Model/Carrier/Tablerate.php
@@ -45,7 +45,7 @@ class Tablerate extends \Magento\Shipping\Model\Carrier\AbstractCarrier implemen
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory
      * @param \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $resultMethodFactory
      * @param \Magento\OfflineShipping\Model\Resource\Carrier\TablerateFactory $tablerateFactory
@@ -54,7 +54,7 @@ class Tablerate extends \Magento\Shipping\Model\Carrier\AbstractCarrier implemen
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
         \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $resultMethodFactory,
         \Magento\OfflineShipping\Model\Resource\Carrier\TablerateFactory $tablerateFactory,
diff --git a/app/code/Magento/OfflineShipping/Model/Resource/Carrier/Tablerate.php b/app/code/Magento/OfflineShipping/Model/Resource/Carrier/Tablerate.php
index 3f16e68e1a8..ee3d001166f 100644
--- a/app/code/Magento/OfflineShipping/Model/Resource/Carrier/Tablerate.php
+++ b/app/code/Magento/OfflineShipping/Model/Resource/Carrier/Tablerate.php
@@ -85,7 +85,7 @@ class Tablerate extends \Magento\Framework\Model\Resource\Db\AbstractDb
     protected $_coreConfig;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -118,7 +118,7 @@ class Tablerate extends \Magento\Framework\Model\Resource\Db\AbstractDb
 
     /**
      * @param \Magento\Framework\App\Resource $resource
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $coreConfig
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\OfflineShipping\Model\Carrier\Tablerate $carrierTablerate
@@ -128,7 +128,7 @@ class Tablerate extends \Magento\Framework\Model\Resource\Db\AbstractDb
      */
     public function __construct(
         \Magento\Framework\App\Resource $resource,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\App\Config\ScopeConfigInterface $coreConfig,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\OfflineShipping\Model\Carrier\Tablerate $carrierTablerate,
diff --git a/app/code/Magento/Ogone/Model/Api.php b/app/code/Magento/Ogone/Model/Api.php
index 49ef1de05d9..4943812f894 100644
--- a/app/code/Magento/Ogone/Model/Api.php
+++ b/app/code/Magento/Ogone/Model/Api.php
@@ -456,7 +456,7 @@ class Api extends \Magento\Payment\Model\Method\AbstractMethod
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
      * @param \Magento\Framework\UrlInterface $urlBuilder
@@ -468,7 +468,7 @@ class Api extends \Magento\Payment\Model\Method\AbstractMethod
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\Locale\ResolverInterface $localeResolver,
         \Magento\Framework\UrlInterface $urlBuilder,
diff --git a/app/code/Magento/Payment/Model/Method/AbstractMethod.php b/app/code/Magento/Payment/Model/Method/AbstractMethod.php
index 993666627b4..c50920b5d3d 100644
--- a/app/code/Magento/Payment/Model/Method/AbstractMethod.php
+++ b/app/code/Magento/Payment/Model/Method/AbstractMethod.php
@@ -199,7 +199,7 @@ abstract class AbstractMethod extends \Magento\Framework\Object implements Metho
     /**
      * Log adapter factory
      *
-     * @var \Magento\Framework\Logger\AdapterFactory
+     * @var \Psr\Log\LoggerInterface\AdapterFactory
      */
     protected $_logAdapterFactory;
 
@@ -209,14 +209,14 @@ abstract class AbstractMethod extends \Magento\Framework\Object implements Metho
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param array $data
      */
     public function __construct(
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         array $data = []
     ) {
         parent::__construct($data);
diff --git a/app/code/Magento/Payment/Model/Method/Cc.php b/app/code/Magento/Payment/Model/Method/Cc.php
index 457911b28ea..8cb5cbc0089 100644
--- a/app/code/Magento/Payment/Model/Method/Cc.php
+++ b/app/code/Magento/Payment/Model/Method/Cc.php
@@ -41,7 +41,7 @@ class Cc extends \Magento\Payment\Model\Method\AbstractMethod
     /**
      * Construct
      *
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -49,8 +49,8 @@ class Cc extends \Magento\Payment\Model\Method\AbstractMethod
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Module\ModuleListInterface $moduleList
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Centinel\Model\Service $centinelService
@@ -60,8 +60,8 @@ class Cc extends \Magento\Payment\Model\Method\AbstractMethod
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Module\ModuleListInterface $moduleList,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Centinel\Model\Service $centinelService,
diff --git a/app/code/Magento/Payment/Model/Method/Free.php b/app/code/Magento/Payment/Model/Method/Free.php
index e5bf9c1ba6e..3a3bde6cd32 100644
--- a/app/code/Magento/Payment/Model/Method/Free.php
+++ b/app/code/Magento/Payment/Model/Method/Free.php
@@ -43,7 +43,7 @@ class Free extends \Magento\Payment\Model\Method\AbstractMethod
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param PriceCurrencyInterface $priceCurrency
      * @param array $data
      */
@@ -51,7 +51,7 @@ class Free extends \Magento\Payment\Model\Method\AbstractMethod
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         PriceCurrencyInterface $priceCurrency,
         array $data = []
     ) {
diff --git a/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Cancel.php b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Cancel.php
index 297802cab49..95a5c9f4d08 100644
--- a/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Cancel.php
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Cancel.php
@@ -26,7 +26,7 @@ class Cancel extends \Magento\Paypal\Controller\Adminhtml\Billing\Agreement
                 $this->messageManager->addError($e->getMessage());
             } catch (\Exception $e) {
                 $this->messageManager->addError(__('We could not cancel the billing agreement.'));
-                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             }
             $this->_redirect('paypal/*/view', ['_current' => true]);
         }
diff --git a/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Delete.php b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Delete.php
index 83abbe75ad5..78a8e6b40ae 100644
--- a/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Delete.php
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Delete.php
@@ -26,7 +26,7 @@ class Delete extends \Magento\Paypal\Controller\Adminhtml\Billing\Agreement
                 $this->messageManager->addError($e->getMessage());
             } catch (\Exception $e) {
                 $this->messageManager->addError(__('We could not delete the billing agreement.'));
-                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             }
             $this->_redirect('paypal/*/view', ['_current' => true]);
         }
diff --git a/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports.php b/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports.php
index e764c773c4a..3c7cf5a5b1c 100644
--- a/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports.php
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports.php
@@ -27,7 +27,7 @@ class Reports extends \Magento\Backend\App\Action
     protected $_settlementFactory;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -36,14 +36,14 @@ class Reports extends \Magento\Backend\App\Action
      * @param \Magento\Framework\Registry $coreRegistry
      * @param \Magento\Paypal\Model\Report\Settlement\RowFactory $rowFactory
      * @param \Magento\Paypal\Model\Report\SettlementFactory $settlementFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      */
     public function __construct(
         \Magento\Backend\App\Action\Context $context,
         \Magento\Framework\Registry $coreRegistry,
         \Magento\Paypal\Model\Report\Settlement\RowFactory $rowFactory,
         \Magento\Paypal\Model\Report\SettlementFactory $settlementFactory,
-        \Magento\Framework\Logger $logger
+        \Psr\Log\LoggerInterface $logger
     ) {
         $this->_coreRegistry = $coreRegistry;
         $this->_rowFactory = $rowFactory;
diff --git a/app/code/Magento/Paypal/Controller/Billing/Agreement/Cancel.php b/app/code/Magento/Paypal/Controller/Billing/Agreement/Cancel.php
index f2e4f00763c..c21a26403ec 100644
--- a/app/code/Magento/Paypal/Controller/Billing/Agreement/Cancel.php
+++ b/app/code/Magento/Paypal/Controller/Billing/Agreement/Cancel.php
@@ -28,7 +28,7 @@ class Cancel extends \Magento\Paypal\Controller\Billing\Agreement
             } catch (\Magento\Framework\Model\Exception $e) {
                 $this->messageManager->addError($e->getMessage());
             } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                 $this->messageManager->addError(__('We couldn\'t cancel the billing agreement.'));
             }
         }
diff --git a/app/code/Magento/Paypal/Controller/Billing/Agreement/ReturnWizard.php b/app/code/Magento/Paypal/Controller/Billing/Agreement/ReturnWizard.php
index 6b760dfe907..e4bc1047856 100644
--- a/app/code/Magento/Paypal/Controller/Billing/Agreement/ReturnWizard.php
+++ b/app/code/Magento/Paypal/Controller/Billing/Agreement/ReturnWizard.php
@@ -38,7 +38,7 @@ class ReturnWizard extends \Magento\Paypal\Controller\Billing\Agreement
             } catch (\Magento\Framework\Model\Exception $e) {
                 $this->messageManager->addError($e->getMessage());
             } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                 $this->messageManager->addError(__('We couldn\'t finish the billing agreement wizard.'));
             }
             $this->_redirect('*/*/index');
diff --git a/app/code/Magento/Paypal/Controller/Billing/Agreement/StartWizard.php b/app/code/Magento/Paypal/Controller/Billing/Agreement/StartWizard.php
index 8a688ea974a..cea550f957d 100644
--- a/app/code/Magento/Paypal/Controller/Billing/Agreement/StartWizard.php
+++ b/app/code/Magento/Paypal/Controller/Billing/Agreement/StartWizard.php
@@ -35,7 +35,7 @@ class StartWizard extends \Magento\Paypal\Controller\Billing\Agreement
             } catch (\Magento\Framework\Model\Exception $e) {
                 $this->messageManager->addError($e->getMessage());
             } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                 $this->messageManager->addError(__('We couldn\'t start the billing agreement wizard.'));
             }
         }
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Cancel.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Cancel.php
index 2192302b16e..b1df8c4a4ea 100644
--- a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Cancel.php
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Cancel.php
@@ -36,7 +36,7 @@ class Cancel extends \Magento\Paypal\Controller\Express\AbstractExpress
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('Unable to cancel Express Checkout'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
 
         $this->_redirect('checkout/cart');
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/PlaceOrder.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/PlaceOrder.php
index 6d71fbe17d4..706b037c43c 100644
--- a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/PlaceOrder.php
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/PlaceOrder.php
@@ -66,7 +66,7 @@ class PlaceOrder extends \Magento\Paypal\Controller\Express\AbstractExpress
             $this->_redirect('*/*/review');
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t place the order.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->_redirect('*/*/review');
         }
     }
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ReturnAction.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ReturnAction.php
index 0c990b85aff..da952231c7e 100644
--- a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ReturnAction.php
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ReturnAction.php
@@ -34,7 +34,7 @@ class ReturnAction extends \Magento\Paypal\Controller\Express\AbstractExpress
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t process Express Checkout approval.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->_redirect('checkout/cart');
     }
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Review.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Review.php
index a86e0f6dd0e..043ccc2dfc5 100644
--- a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Review.php
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Review.php
@@ -33,7 +33,7 @@ class Review extends \Magento\Paypal\Controller\Express\AbstractExpress
             $this->messageManager->addError(
                 __('We can\'t initialize Express Checkout review.')
             );
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->_redirect('checkout/cart');
     }
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/SaveShippingMethod.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/SaveShippingMethod.php
index d359572a27f..3819bab5e06 100644
--- a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/SaveShippingMethod.php
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/SaveShippingMethod.php
@@ -29,7 +29,7 @@ class SaveShippingMethod extends \Magento\Paypal\Controller\Express\AbstractExpr
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t update shipping method.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         if ($isAjax) {
             $this->getResponse()->setBody(
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ShippingOptionsCallback.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ShippingOptionsCallback.php
index a902eb800b2..827339d56fb 100644
--- a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ShippingOptionsCallback.php
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ShippingOptionsCallback.php
@@ -61,7 +61,7 @@ class ShippingOptionsCallback extends \Magento\Paypal\Controller\Express\Abstrac
             $response = $this->_checkout->getShippingOptionsCallbackResponse($this->getRequest()->getParams());
             $this->getResponse()->setBody($response);
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
     }
 }
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Start.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Start.php
index c7330479e08..3daf6b43b7a 100644
--- a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Start.php
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Start.php
@@ -81,7 +81,7 @@ class Start extends \Magento\Paypal\Controller\Express\AbstractExpress
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t start Express Checkout.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
 
         $this->_redirect('checkout/cart');
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/UpdateShippingMethods.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/UpdateShippingMethods.php
index 9f2b22b1f4d..979100f869f 100644
--- a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/UpdateShippingMethods.php
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/UpdateShippingMethods.php
@@ -31,7 +31,7 @@ class UpdateShippingMethods extends \Magento\Paypal\Controller\Express\AbstractE
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t update shipping method.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->getResponse()->setBody(
             '<script type="text/javascript">window.location.href = ' . $this->_url->getUrl('*/*/review') . ';</script>'
diff --git a/app/code/Magento/Paypal/Controller/Ipn/Index.php b/app/code/Magento/Paypal/Controller/Ipn/Index.php
index e8578502350..06713f42052 100644
--- a/app/code/Magento/Paypal/Controller/Ipn/Index.php
+++ b/app/code/Magento/Paypal/Controller/Ipn/Index.php
@@ -14,7 +14,7 @@ use Magento\Paypal\UnavailableException;
 class Index extends \Magento\Framework\App\Action\Action
 {
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -26,12 +26,12 @@ class Index extends \Magento\Framework\App\Action\Action
     /**
      * @param \Magento\Framework\App\Action\Context $context
      * @param \Magento\Paypal\Model\IpnFactory $ipnFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      */
     public function __construct(
         \Magento\Framework\App\Action\Context $context,
         \Magento\Paypal\Model\IpnFactory $ipnFactory,
-        \Magento\Framework\Logger $logger
+        \Psr\Log\LoggerInterface $logger
     ) {
         $this->_logger = $logger;
         $this->_ipnFactory = $ipnFactory;
diff --git a/app/code/Magento/Paypal/Controller/Payflow.php b/app/code/Magento/Paypal/Controller/Payflow.php
index b63f9b0acda..c46f9ce124f 100644
--- a/app/code/Magento/Paypal/Controller/Payflow.php
+++ b/app/code/Magento/Paypal/Controller/Payflow.php
@@ -20,7 +20,7 @@ class Payflow extends \Magento\Framework\App\Action\Action
     protected $_orderFactory;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -46,7 +46,7 @@ class Payflow extends \Magento\Framework\App\Action\Action
      * @param \Magento\Sales\Model\OrderFactory $orderFactory
      * @param \Magento\Paypal\Model\PayflowlinkFactory $payflowModelFactory
      * @param \Magento\Paypal\Helper\Checkout $checkoutHelper
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      */
     public function __construct(
         \Magento\Framework\App\Action\Context $context,
@@ -54,7 +54,7 @@ class Payflow extends \Magento\Framework\App\Action\Action
         \Magento\Sales\Model\OrderFactory $orderFactory,
         \Magento\Paypal\Model\PayflowlinkFactory $payflowModelFactory,
         \Magento\Paypal\Helper\Checkout $checkoutHelper,
-        \Magento\Framework\Logger $logger
+        \Psr\Log\LoggerInterface $logger
     ) {
         $this->_checkoutSession = $checkoutSession;
         $this->_orderFactory = $orderFactory;
diff --git a/app/code/Magento/Paypal/Model/AbstractIpn.php b/app/code/Magento/Paypal/Model/AbstractIpn.php
index 72ce4efddd7..583227b62bc 100644
--- a/app/code/Magento/Paypal/Model/AbstractIpn.php
+++ b/app/code/Magento/Paypal/Model/AbstractIpn.php
@@ -45,13 +45,13 @@ class AbstractIpn
 
     /**
      * @param \Magento\Paypal\Model\ConfigFactory $configFactory
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param \Magento\Framework\HTTP\Adapter\CurlFactory $curlFactory
      * @param array $data
      */
     public function __construct(
         \Magento\Paypal\Model\ConfigFactory $configFactory,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         \Magento\Framework\HTTP\Adapter\CurlFactory $curlFactory,
         array $data = []
     ) {
diff --git a/app/code/Magento/Paypal/Model/Api/AbstractApi.php b/app/code/Magento/Paypal/Model/Api/AbstractApi.php
index 7266783031f..aa974746bb7 100644
--- a/app/code/Magento/Paypal/Model/Api/AbstractApi.php
+++ b/app/code/Magento/Paypal/Model/Api/AbstractApi.php
@@ -82,7 +82,7 @@ abstract class AbstractApi extends \Magento\Framework\Object
     protected $_customerAddress;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -97,7 +97,7 @@ abstract class AbstractApi extends \Magento\Framework\Object
     protected $_regionFactory;
 
     /**
-     * @var \Magento\Framework\Logger\AdapterFactory
+     * @var \Psr\Log\LoggerInterface\AdapterFactory
      */
     protected $_logAdapterFactory;
 
@@ -108,18 +108,18 @@ abstract class AbstractApi extends \Magento\Framework\Object
      * attributes This behavior may change in child classes
      *
      * @param \Magento\Customer\Helper\Address $customerAddress
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
      * @param \Magento\Directory\Model\RegionFactory $regionFactory
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param array $data
      */
     public function __construct(
         \Magento\Customer\Helper\Address $customerAddress,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Locale\ResolverInterface $localeResolver,
         \Magento\Directory\Model\RegionFactory $regionFactory,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         array $data = []
     ) {
         $this->_customerAddress = $customerAddress;
diff --git a/app/code/Magento/Paypal/Model/Api/Nvp.php b/app/code/Magento/Paypal/Model/Api/Nvp.php
index 05517f84e7a..82dd7ada7c2 100644
--- a/app/code/Magento/Paypal/Model/Api/Nvp.php
+++ b/app/code/Magento/Paypal/Model/Api/Nvp.php
@@ -741,10 +741,10 @@ class Nvp extends \Magento\Paypal\Model\Api\AbstractApi
 
     /**
      * @param \Magento\Customer\Helper\Address $customerAddress
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
      * @param \Magento\Directory\Model\RegionFactory $regionFactory
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param \Magento\Directory\Model\CountryFactory $countryFactory
      * @param \Magento\Paypal\Model\Api\ProcessableExceptionFactory $processableExceptionFactory
      * @param \Magento\Framework\Model\ExceptionFactory $frameworkExceptionFactory
@@ -753,10 +753,10 @@ class Nvp extends \Magento\Paypal\Model\Api\AbstractApi
      */
     public function __construct(
         \Magento\Customer\Helper\Address $customerAddress,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Locale\ResolverInterface $localeResolver,
         \Magento\Directory\Model\RegionFactory $regionFactory,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         \Magento\Directory\Model\CountryFactory $countryFactory,
         \Magento\Paypal\Model\Api\ProcessableExceptionFactory $processableExceptionFactory,
         \Magento\Framework\Model\ExceptionFactory $frameworkExceptionFactory,
diff --git a/app/code/Magento/Paypal/Model/Api/PayflowNvp.php b/app/code/Magento/Paypal/Model/Api/PayflowNvp.php
index 11145aeafbf..483a3bb3980 100644
--- a/app/code/Magento/Paypal/Model/Api/PayflowNvp.php
+++ b/app/code/Magento/Paypal/Model/Api/PayflowNvp.php
@@ -439,10 +439,10 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp
 
     /**
      * @param \Magento\Customer\Helper\Address $customerAddress
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
      * @param \Magento\Directory\Model\RegionFactory $regionFactory
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param \Magento\Directory\Model\CountryFactory $countryFactory
      * @param \Magento\Paypal\Model\Api\ProcessableExceptionFactory $processableExceptionFactory
      * @param \Magento\Framework\Model\ExceptionFactory $frameworkExceptionFactory
@@ -453,10 +453,10 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp
      */
     public function __construct(
         \Magento\Customer\Helper\Address $customerAddress,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Locale\ResolverInterface $localeResolver,
         \Magento\Directory\Model\RegionFactory $regionFactory,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         \Magento\Directory\Model\CountryFactory $countryFactory,
         \Magento\Paypal\Model\Api\ProcessableExceptionFactory $processableExceptionFactory,
         \Magento\Framework\Model\ExceptionFactory $frameworkExceptionFactory,
diff --git a/app/code/Magento/Paypal/Model/Direct.php b/app/code/Magento/Paypal/Model/Direct.php
index 499839cea42..e9945594532 100644
--- a/app/code/Magento/Paypal/Model/Direct.php
+++ b/app/code/Magento/Paypal/Model/Direct.php
@@ -134,8 +134,8 @@ class Direct extends \Magento\Payment\Model\Method\Cc
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Module\ModuleListInterface $moduleList
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Centinel\Model\Service $centinelService
@@ -152,8 +152,8 @@ class Direct extends \Magento\Payment\Model\Method\Cc
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Module\ModuleListInterface $moduleList,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Centinel\Model\Service $centinelService,
diff --git a/app/code/Magento/Paypal/Model/Express.php b/app/code/Magento/Paypal/Model/Express.php
index 4fab1d56be3..17c0e989059 100644
--- a/app/code/Magento/Paypal/Model/Express.php
+++ b/app/code/Magento/Paypal/Model/Express.php
@@ -165,7 +165,7 @@ class Express extends \Magento\Payment\Model\Method\AbstractMethod
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param ProFactory $proFactory
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\UrlInterface $urlBuilder
@@ -178,7 +178,7 @@ class Express extends \Magento\Payment\Model\Method\AbstractMethod
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         ProFactory $proFactory,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\UrlInterface $urlBuilder,
diff --git a/app/code/Magento/Paypal/Model/Express/Checkout.php b/app/code/Magento/Paypal/Model/Express/Checkout.php
index 06492302db8..3e149d8b1e4 100644
--- a/app/code/Magento/Paypal/Model/Express/Checkout.php
+++ b/app/code/Magento/Paypal/Model/Express/Checkout.php
@@ -169,7 +169,7 @@ class Checkout
     protected $_customerUrl;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -199,7 +199,7 @@ class Checkout
     protected $_cartFactory;
 
     /**
-     * @var \Magento\Framework\Logger\AdapterFactory
+     * @var \Psr\Log\LoggerInterface\AdapterFactory
      */
     protected $_logFactory;
 
@@ -271,7 +271,7 @@ class Checkout
     /**
      * Set config, session and quote instances
      *
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Customer\Model\Url $customerUrl
      * @param \Magento\Tax\Helper\Data $taxData
      * @param \Magento\Checkout\Helper\Data $checkoutData
@@ -282,7 +282,7 @@ class Checkout
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\UrlInterface $coreUrl
      * @param \Magento\Paypal\Model\CartFactory $cartFactory
-     * @param \Magento\Framework\Logger\AdapterFactory $logFactory
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logFactory
      * @param \Magento\Checkout\Model\Type\OnepageFactory $onepageFactory
      * @param \Magento\Sales\Model\Service\QuoteFactory $serviceQuoteFactory
      * @param \Magento\Paypal\Model\Billing\AgreementFactory $agreementFactory
@@ -300,7 +300,7 @@ class Checkout
      * @throws \Exception
      */
     public function __construct(
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Customer\Model\Url $customerUrl,
         \Magento\Tax\Helper\Data $taxData,
         \Magento\Checkout\Helper\Data $checkoutData,
@@ -311,7 +311,7 @@ class Checkout
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\UrlInterface $coreUrl,
         \Magento\Paypal\Model\CartFactory $cartFactory,
-        \Magento\Framework\Logger\AdapterFactory $logFactory,
+        \Psr\Log\LoggerInterface\AdapterFactory $logFactory,
         \Magento\Checkout\Model\Type\OnepageFactory $onepageFactory,
         \Magento\Sales\Model\Service\QuoteFactory $serviceQuoteFactory,
         \Magento\Paypal\Model\Billing\AgreementFactory $agreementFactory,
diff --git a/app/code/Magento/Paypal/Model/Hostedpro.php b/app/code/Magento/Paypal/Model/Hostedpro.php
index 5363c71d8b1..1817268f562 100644
--- a/app/code/Magento/Paypal/Model/Hostedpro.php
+++ b/app/code/Magento/Paypal/Model/Hostedpro.php
@@ -71,8 +71,8 @@ class Hostedpro extends \Magento\Paypal\Model\Direct
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Module\ModuleListInterface $moduleList
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Centinel\Model\Service $centinelService
@@ -90,8 +90,8 @@ class Hostedpro extends \Magento\Paypal\Model\Direct
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Module\ModuleListInterface $moduleList,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Centinel\Model\Service $centinelService,
diff --git a/app/code/Magento/Paypal/Model/Ipn.php b/app/code/Magento/Paypal/Model/Ipn.php
index cf93bcb51fa..177a575d0fd 100644
--- a/app/code/Magento/Paypal/Model/Ipn.php
+++ b/app/code/Magento/Paypal/Model/Ipn.php
@@ -42,7 +42,7 @@ class Ipn extends \Magento\Paypal\Model\AbstractIpn implements IpnInterface
 
     /**
      * @param \Magento\Paypal\Model\ConfigFactory $configFactory
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param \Magento\Framework\HTTP\Adapter\CurlFactory $curlFactory
      * @param \Magento\Sales\Model\OrderFactory $orderFactory
      * @param Info $paypalInfo
@@ -52,7 +52,7 @@ class Ipn extends \Magento\Paypal\Model\AbstractIpn implements IpnInterface
      */
     public function __construct(
         \Magento\Paypal\Model\ConfigFactory $configFactory,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         \Magento\Framework\HTTP\Adapter\CurlFactory $curlFactory,
         \Magento\Sales\Model\OrderFactory $orderFactory,
         Info $paypalInfo,
diff --git a/app/code/Magento/Paypal/Model/Method/Agreement.php b/app/code/Magento/Paypal/Model/Method/Agreement.php
index 824506b4c1b..936b2604146 100644
--- a/app/code/Magento/Paypal/Model/Method/Agreement.php
+++ b/app/code/Magento/Paypal/Model/Method/Agreement.php
@@ -117,7 +117,7 @@ class Agreement extends \Magento\Paypal\Model\Payment\Method\Billing\AbstractAgr
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param \Magento\Paypal\Model\Billing\AgreementFactory $agreementFactory
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Paypal\Model\ProFactory $proFactory
@@ -131,7 +131,7 @@ class Agreement extends \Magento\Paypal\Model\Payment\Method\Billing\AbstractAgr
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         \Magento\Paypal\Model\Billing\AgreementFactory $agreementFactory,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Paypal\Model\ProFactory $proFactory,
diff --git a/app/code/Magento/Paypal/Model/Observer.php b/app/code/Magento/Paypal/Model/Observer.php
index e68422948a5..d2c40e4f47a 100644
--- a/app/code/Magento/Paypal/Model/Observer.php
+++ b/app/code/Magento/Paypal/Model/Observer.php
@@ -33,7 +33,7 @@ class Observer
     protected $_coreData;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -66,7 +66,7 @@ class Observer
      * @param \Magento\Core\Helper\Data $coreData
      * @param \Magento\Paypal\Helper\Hss $paypalHss
      * @param \Magento\Framework\Registry $coreRegistry
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param Report\SettlementFactory $settlementFactory
      * @param \Magento\Framework\App\ViewInterface $view
      * @param \Magento\Paypal\Model\Billing\AgreementFactory $agreementFactory
@@ -77,7 +77,7 @@ class Observer
         \Magento\Core\Helper\Data $coreData,
         \Magento\Paypal\Helper\Hss $paypalHss,
         \Magento\Framework\Registry $coreRegistry,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Paypal\Model\Report\SettlementFactory $settlementFactory,
         \Magento\Framework\App\ViewInterface $view,
         \Magento\Paypal\Model\Billing\AgreementFactory $agreementFactory,
diff --git a/app/code/Magento/Paypal/Model/PayflowExpress.php b/app/code/Magento/Paypal/Model/PayflowExpress.php
index e880fe8edbb..f454a30afc8 100644
--- a/app/code/Magento/Paypal/Model/PayflowExpress.php
+++ b/app/code/Magento/Paypal/Model/PayflowExpress.php
@@ -35,7 +35,7 @@ class PayflowExpress extends \Magento\Paypal\Model\Express
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param ProFactory $proFactory
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\UrlInterface $urlBuilder
@@ -49,7 +49,7 @@ class PayflowExpress extends \Magento\Paypal\Model\Express
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         ProFactory $proFactory,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\UrlInterface $urlBuilder,
diff --git a/app/code/Magento/Paypal/Model/Payflowlink.php b/app/code/Magento/Paypal/Model/Payflowlink.php
index c7a2b082a01..6be0ac49795 100644
--- a/app/code/Magento/Paypal/Model/Payflowlink.php
+++ b/app/code/Magento/Paypal/Model/Payflowlink.php
@@ -136,8 +136,8 @@ class Payflowlink extends \Magento\Paypal\Model\Payflowpro
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Module\ModuleListInterface $moduleList
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Centinel\Model\Service $centinelService
@@ -159,8 +159,8 @@ class Payflowlink extends \Magento\Paypal\Model\Payflowpro
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Module\ModuleListInterface $moduleList,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Centinel\Model\Service $centinelService,
diff --git a/app/code/Magento/Paypal/Model/Payflowpro.php b/app/code/Magento/Paypal/Model/Payflowpro.php
index 8709324a2cd..0d3afe955d1 100644
--- a/app/code/Magento/Paypal/Model/Payflowpro.php
+++ b/app/code/Magento/Paypal/Model/Payflowpro.php
@@ -216,8 +216,8 @@ class Payflowpro extends \Magento\Payment\Model\Method\Cc
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Module\ModuleListInterface $moduleList
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Centinel\Model\Service $centinelService
@@ -233,8 +233,8 @@ class Payflowpro extends \Magento\Payment\Model\Method\Cc
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Module\ModuleListInterface $moduleList,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Centinel\Model\Service $centinelService,
diff --git a/app/code/Magento/Paypal/Model/Payment/Method/Billing/AbstractAgreement.php b/app/code/Magento/Paypal/Model/Payment/Method/Billing/AbstractAgreement.php
index 6c549f7ea37..008234ace93 100644
--- a/app/code/Magento/Paypal/Model/Payment/Method/Billing/AbstractAgreement.php
+++ b/app/code/Magento/Paypal/Model/Payment/Method/Billing/AbstractAgreement.php
@@ -42,7 +42,7 @@ abstract class AbstractAgreement extends \Magento\Payment\Model\Method\AbstractM
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param \Magento\Paypal\Model\Billing\AgreementFactory $agreementFactory
      * @param array $data
      */
@@ -50,7 +50,7 @@ abstract class AbstractAgreement extends \Magento\Payment\Model\Method\AbstractM
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         \Magento\Paypal\Model\Billing\AgreementFactory $agreementFactory,
         array $data = []
     ) {
diff --git a/app/code/Magento/Paypal/Model/Resource/Billing/Agreement/Collection.php b/app/code/Magento/Paypal/Model/Resource/Billing/Agreement/Collection.php
index d3d2fc6ed58..ca5ff96879a 100644
--- a/app/code/Magento/Paypal/Model/Resource/Billing/Agreement/Collection.php
+++ b/app/code/Magento/Paypal/Model/Resource/Billing/Agreement/Collection.php
@@ -38,7 +38,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Customer\Model\Resource\Customer $customerResource
@@ -48,7 +48,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Customer\Model\Resource\Customer $customerResource,
diff --git a/app/code/Magento/Paypal/Model/Standard.php b/app/code/Magento/Paypal/Model/Standard.php
index 2c914114379..933fa6cd35b 100644
--- a/app/code/Magento/Paypal/Model/Standard.php
+++ b/app/code/Magento/Paypal/Model/Standard.php
@@ -85,7 +85,7 @@ class Standard extends \Magento\Payment\Model\Method\AbstractMethod
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param \Magento\Framework\Session\Generic $paypalSession
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param \Magento\Framework\UrlInterface $urlBuilder
@@ -102,7 +102,7 @@ class Standard extends \Magento\Payment\Model\Method\AbstractMethod
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         \Magento\Framework\Session\Generic $paypalSession,
         \Magento\Checkout\Model\Session $checkoutSession,
         \Magento\Framework\UrlInterface $urlBuilder,
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Viewed.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Viewed.php
index 1f880f78c78..18e7b255e42 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Viewed.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Viewed.php
@@ -49,7 +49,7 @@ class Viewed extends \Magento\Reports\Controller\Adminhtml\Report\Product
             $this->messageManager->addError(
                 __('An error occurred while showing the product views report. Please review the log and try again.')
             );
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->_redirect('reports/*/viewed/');
             return;
         }
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshLifetime.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshLifetime.php
index fb2c8545ecc..956d727041c 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshLifetime.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshLifetime.php
@@ -25,7 +25,7 @@ class RefreshLifetime extends \Magento\Reports\Controller\Adminhtml\Report\Stati
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t refresh lifetime statistics.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
 
         if ($this->_getSession()->isFirstPageAfterLogin()) {
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshRecent.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshRecent.php
index 967006fb2fb..dd6cf080fa7 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshRecent.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshRecent.php
@@ -28,7 +28,7 @@ class RefreshRecent extends \Magento\Reports\Controller\Adminhtml\Report\Statist
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t refresh recent statistics.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
 
         if ($this->_getSession()->isFirstPageAfterLogin()) {
diff --git a/app/code/Magento/Reports/Model/Resource/Customer/Collection.php b/app/code/Magento/Reports/Model/Resource/Customer/Collection.php
index bf5a1d3c700..12bf75598b5 100644
--- a/app/code/Magento/Reports/Model/Resource/Customer/Collection.php
+++ b/app/code/Magento/Reports/Model/Resource/Customer/Collection.php
@@ -67,7 +67,7 @@ class Collection extends \Magento\Customer\Model\Resource\Customer\Collection
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\Config $eavConfig
@@ -85,7 +85,7 @@ class Collection extends \Magento\Customer\Model\Resource\Customer\Collection
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Model\Config $eavConfig,
diff --git a/app/code/Magento/Reports/Model/Resource/Order/Collection.php b/app/code/Magento/Reports/Model/Resource/Order/Collection.php
index d5fbb0d48a2..5e90b28e091 100644
--- a/app/code/Magento/Reports/Model/Resource/Order/Collection.php
+++ b/app/code/Magento/Reports/Model/Resource/Order/Collection.php
@@ -56,7 +56,7 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Collection
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\DB\Helper $coreResourceHelper
@@ -72,7 +72,7 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Collection
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Framework\DB\Helper $coreResourceHelper,
diff --git a/app/code/Magento/Reports/Model/Resource/Product/Collection.php b/app/code/Magento/Reports/Model/Resource/Product/Collection.php
index 04c689b3eb9..28ad32d28ed 100644
--- a/app/code/Magento/Reports/Model/Resource/Product/Collection.php
+++ b/app/code/Magento/Reports/Model/Resource/Product/Collection.php
@@ -54,7 +54,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Product\Collection
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\Config $eavConfig
@@ -81,7 +81,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Product\Collection
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Model\Config $eavConfig,
diff --git a/app/code/Magento/Reports/Model/Resource/Product/Index/Collection/AbstractCollection.php b/app/code/Magento/Reports/Model/Resource/Product/Index/Collection/AbstractCollection.php
index 5e3234b2262..6a980688534 100644
--- a/app/code/Magento/Reports/Model/Resource/Product/Index/Collection/AbstractCollection.php
+++ b/app/code/Magento/Reports/Model/Resource/Product/Index/Collection/AbstractCollection.php
@@ -26,7 +26,7 @@ abstract class AbstractCollection extends \Magento\Catalog\Model\Resource\Produc
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\Config $eavConfig
@@ -51,7 +51,7 @@ abstract class AbstractCollection extends \Magento\Catalog\Model\Resource\Produc
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Model\Config $eavConfig,
diff --git a/app/code/Magento/Reports/Model/Resource/Product/Lowstock/Collection.php b/app/code/Magento/Reports/Model/Resource/Product/Lowstock/Collection.php
index 6e6251cad6c..c6e28286319 100644
--- a/app/code/Magento/Reports/Model/Resource/Product/Lowstock/Collection.php
+++ b/app/code/Magento/Reports/Model/Resource/Product/Lowstock/Collection.php
@@ -43,7 +43,7 @@ class Collection extends \Magento\Reports\Model\Resource\Product\Collection
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\Config $eavConfig
@@ -73,7 +73,7 @@ class Collection extends \Magento\Reports\Model\Resource\Product\Collection
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Model\Config $eavConfig,
diff --git a/app/code/Magento/Reports/Model/Resource/Quote/Collection.php b/app/code/Magento/Reports/Model/Resource/Quote/Collection.php
index 89c1a3ea0d6..50a0031ab5f 100644
--- a/app/code/Magento/Reports/Model/Resource/Quote/Collection.php
+++ b/app/code/Magento/Reports/Model/Resource/Quote/Collection.php
@@ -45,7 +45,7 @@ class Collection extends \Magento\Sales\Model\Resource\Quote\Collection
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Catalog\Model\Resource\Product\Collection $productResource
@@ -55,7 +55,7 @@ class Collection extends \Magento\Sales\Model\Resource\Quote\Collection
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Catalog\Model\Resource\Product\Collection $productResource,
diff --git a/app/code/Magento/Reports/Model/Resource/Report/AbstractReport.php b/app/code/Magento/Reports/Model/Resource/Report/AbstractReport.php
index 1f9723f1107..8fea5b72d7d 100644
--- a/app/code/Magento/Reports/Model/Resource/Report/AbstractReport.php
+++ b/app/code/Magento/Reports/Model/Resource/Report/AbstractReport.php
@@ -18,7 +18,7 @@ abstract class AbstractReport extends \Magento\Framework\Model\Resource\Db\Abstr
     protected $_flag = null;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -34,7 +34,7 @@ abstract class AbstractReport extends \Magento\Framework\Model\Resource\Db\Abstr
 
     /**
      * @param \Magento\Framework\App\Resource $resource
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Reports\Model\FlagFactory $reportsFlagFactory
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
@@ -42,7 +42,7 @@ abstract class AbstractReport extends \Magento\Framework\Model\Resource\Db\Abstr
      */
     public function __construct(
         \Magento\Framework\App\Resource $resource,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Reports\Model\FlagFactory $reportsFlagFactory,
         \Magento\Framework\Stdlib\DateTime $dateTime,
diff --git a/app/code/Magento/Reports/Model/Resource/Report/Product/Viewed.php b/app/code/Magento/Reports/Model/Resource/Report/Product/Viewed.php
index 8224d7952e7..0065c5b791c 100644
--- a/app/code/Magento/Reports/Model/Resource/Report/Product/Viewed.php
+++ b/app/code/Magento/Reports/Model/Resource/Report/Product/Viewed.php
@@ -39,7 +39,7 @@ class Viewed extends \Magento\Sales\Model\Resource\Report\AbstractReport
 
     /**
      * @param \Magento\Framework\App\Resource $resource
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Reports\Model\FlagFactory $reportsFlagFactory
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
@@ -49,7 +49,7 @@ class Viewed extends \Magento\Sales\Model\Resource\Report\AbstractReport
      */
     public function __construct(
         \Magento\Framework\App\Resource $resource,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Reports\Model\FlagFactory $reportsFlagFactory,
         \Magento\Framework\Stdlib\DateTime $dateTime,
diff --git a/app/code/Magento/Reports/Model/Resource/Report/Product/Viewed/Collection.php b/app/code/Magento/Reports/Model/Resource/Report/Product/Viewed/Collection.php
index b23f2bbafb1..7923155007e 100644
--- a/app/code/Magento/Reports/Model/Resource/Report/Product/Viewed/Collection.php
+++ b/app/code/Magento/Reports/Model/Resource/Report/Product/Viewed/Collection.php
@@ -26,7 +26,7 @@ class Collection extends \Magento\Reports\Model\Resource\Report\Collection\Abstr
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Sales\Model\Resource\Report $resource
@@ -34,7 +34,7 @@ class Collection extends \Magento\Reports\Model\Resource\Report\Collection\Abstr
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Sales\Model\Resource\Report $resource,
diff --git a/app/code/Magento/Reports/Model/Resource/Review/Customer/Collection.php b/app/code/Magento/Reports/Model/Resource/Review/Customer/Collection.php
index 4d9785f5462..6c3e9d99b3e 100644
--- a/app/code/Magento/Reports/Model/Resource/Review/Customer/Collection.php
+++ b/app/code/Magento/Reports/Model/Resource/Review/Customer/Collection.php
@@ -19,7 +19,7 @@ class Collection extends \Magento\Review\Model\Resource\Review\Collection
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Review\Helper\Data $reviewData
@@ -31,7 +31,7 @@ class Collection extends \Magento\Review\Model\Resource\Review\Collection
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Review\Helper\Data $reviewData,
diff --git a/app/code/Magento/Reports/Model/Resource/Wishlist/Collection.php b/app/code/Magento/Reports/Model/Resource/Wishlist/Collection.php
index f06e1bcabab..c692dc1c0ac 100644
--- a/app/code/Magento/Reports/Model/Resource/Wishlist/Collection.php
+++ b/app/code/Magento/Reports/Model/Resource/Wishlist/Collection.php
@@ -26,7 +26,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Customer\Model\Resource\Customer\CollectionFactory $customerResFactory
@@ -35,7 +35,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Customer\Model\Resource\Customer\CollectionFactory $customerResFactory,
diff --git a/app/code/Magento/Review/Controller/Product.php b/app/code/Magento/Review/Controller/Product.php
index 333d558e746..1bbc2610ff5 100644
--- a/app/code/Magento/Review/Controller/Product.php
+++ b/app/code/Magento/Review/Controller/Product.php
@@ -47,7 +47,7 @@ class Product extends \Magento\Framework\App\Action\Action
     /**
      * Logger
      *
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -98,7 +98,7 @@ class Product extends \Magento\Framework\App\Action\Action
      * @param \Magento\Framework\Registry $coreRegistry
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
      * @param \Magento\Review\Model\ReviewFactory $reviewFactory
      * @param \Magento\Review\Model\RatingFactory $ratingFactory
@@ -112,7 +112,7 @@ class Product extends \Magento\Framework\App\Action\Action
         \Magento\Framework\Registry $coreRegistry,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
         \Magento\Review\Model\ReviewFactory $reviewFactory,
         \Magento\Review\Model\RatingFactory $ratingFactory,
diff --git a/app/code/Magento/Review/Model/Resource/Rating.php b/app/code/Magento/Review/Model/Resource/Rating.php
index 535e963d972..64ba57293a0 100644
--- a/app/code/Magento/Review/Model/Resource/Rating.php
+++ b/app/code/Magento/Review/Model/Resource/Rating.php
@@ -26,13 +26,13 @@ class Rating extends \Magento\Framework\Model\Resource\Db\AbstractDb
     protected $moduleManager;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
     /**
      * @param \Magento\Framework\App\Resource $resource
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Module\Manager $moduleManager
      * @param \Magento\Review\Helper\Data $ratingData
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
@@ -40,7 +40,7 @@ class Rating extends \Magento\Framework\Model\Resource\Db\AbstractDb
      */
     public function __construct(
         \Magento\Framework\App\Resource $resource,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Module\Manager $moduleManager,
         \Magento\Review\Helper\Data $ratingData,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
diff --git a/app/code/Magento/Review/Model/Resource/Rating/Collection.php b/app/code/Magento/Review/Model/Resource/Rating/Collection.php
index 59a4578e293..290814cf08b 100644
--- a/app/code/Magento/Review/Model/Resource/Rating/Collection.php
+++ b/app/code/Magento/Review/Model/Resource/Rating/Collection.php
@@ -29,7 +29,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
@@ -39,7 +39,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
diff --git a/app/code/Magento/Review/Model/Resource/Rating/Grid/Collection.php b/app/code/Magento/Review/Model/Resource/Rating/Grid/Collection.php
index 69875d13f85..57c530f0a0c 100644
--- a/app/code/Magento/Review/Model/Resource/Rating/Grid/Collection.php
+++ b/app/code/Magento/Review/Model/Resource/Rating/Grid/Collection.php
@@ -20,7 +20,7 @@ class Collection extends \Magento\Review\Model\Resource\Rating\Collection
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
@@ -31,7 +31,7 @@ class Collection extends \Magento\Review\Model\Resource\Rating\Collection
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
diff --git a/app/code/Magento/Review/Model/Resource/Rating/Option/Vote/Collection.php b/app/code/Magento/Review/Model/Resource/Rating/Option/Vote/Collection.php
index 02a3d934520..c106f65892a 100644
--- a/app/code/Magento/Review/Model/Resource/Rating/Option/Vote/Collection.php
+++ b/app/code/Magento/Review/Model/Resource/Rating/Option/Vote/Collection.php
@@ -25,7 +25,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
@@ -35,7 +35,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
diff --git a/app/code/Magento/Review/Model/Resource/Review/Collection.php b/app/code/Magento/Review/Model/Resource/Review/Collection.php
index 2e2694c0f86..7c0e4fb196a 100644
--- a/app/code/Magento/Review/Model/Resource/Review/Collection.php
+++ b/app/code/Magento/Review/Model/Resource/Review/Collection.php
@@ -75,7 +75,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Review\Helper\Data $reviewData
@@ -86,7 +86,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Review\Helper\Data $reviewData,
diff --git a/app/code/Magento/Review/Model/Resource/Review/Product/Collection.php b/app/code/Magento/Review/Model/Resource/Review/Product/Collection.php
index ea67d81c056..e43f85a0fcf 100644
--- a/app/code/Magento/Review/Model/Resource/Review/Product/Collection.php
+++ b/app/code/Magento/Review/Model/Resource/Review/Product/Collection.php
@@ -57,7 +57,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Product\Collection
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\Config $eavConfig
@@ -83,7 +83,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Product\Collection
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Eav\Model\Config $eavConfig,
diff --git a/app/code/Magento/Review/Model/Resource/Review/Summary/Collection.php b/app/code/Magento/Review/Model/Resource/Review/Summary/Collection.php
index b4b00c2d252..db45d49c4ce 100644
--- a/app/code/Magento/Review/Model/Resource/Review/Summary/Collection.php
+++ b/app/code/Magento/Review/Model/Resource/Review/Summary/Collection.php
@@ -20,13 +20,13 @@ class Collection extends \Magento\Framework\Data\Collection\Db
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\App\Resource $resource
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\App\Resource $resource
     ) {
diff --git a/app/code/Magento/Rss/App/Action/Plugin/BackendAuthentication.php b/app/code/Magento/Rss/App/Action/Plugin/BackendAuthentication.php
index a217415827c..4f7e300d2e6 100644
--- a/app/code/Magento/Rss/App/Action/Plugin/BackendAuthentication.php
+++ b/app/code/Magento/Rss/App/Action/Plugin/BackendAuthentication.php
@@ -22,7 +22,7 @@ class BackendAuthentication extends \Magento\Backend\App\Action\Plugin\Authentic
     protected $httpAuthentication;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
@@ -45,7 +45,7 @@ class BackendAuthentication extends \Magento\Backend\App\Action\Plugin\Authentic
      * @param \Magento\Framework\App\ActionFlag $actionFlag
      * @param \Magento\Framework\Message\ManagerInterface $messageManager
      * @param \Magento\Framework\HTTP\Authentication $httpAuthentication
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\AuthorizationInterface $authorization
      */
     public function __construct(
@@ -55,7 +55,7 @@ class BackendAuthentication extends \Magento\Backend\App\Action\Plugin\Authentic
         \Magento\Framework\App\ActionFlag $actionFlag,
         \Magento\Framework\Message\ManagerInterface $messageManager,
         \Magento\Framework\HTTP\Authentication $httpAuthentication,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\AuthorizationInterface $authorization
     ) {
         $this->httpAuthentication = $httpAuthentication;
diff --git a/app/code/Magento/Rss/Controller/Feed.php b/app/code/Magento/Rss/Controller/Feed.php
index 84fd2cd0fd9..06a19e3c9da 100644
--- a/app/code/Magento/Rss/Controller/Feed.php
+++ b/app/code/Magento/Rss/Controller/Feed.php
@@ -25,7 +25,7 @@ class Feed extends \Magento\Framework\App\Action\Action
     protected $httpAuthentication;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
@@ -52,7 +52,7 @@ class Feed extends \Magento\Framework\App\Action\Action
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Customer\Api\AccountManagementInterface $customerAccountManagement
      * @param \Magento\Framework\HTTP\Authentication $httpAuthentication
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      */
     public function __construct(
         \Magento\Framework\App\Action\Context $context,
@@ -62,7 +62,7 @@ class Feed extends \Magento\Framework\App\Action\Action
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Customer\Api\AccountManagementInterface $customerAccountManagement,
         \Magento\Framework\HTTP\Authentication $httpAuthentication,
-        \Magento\Framework\Logger $logger
+        \Psr\Log\LoggerInterface $logger
     ) {
         $this->rssManager = $rssManager;
         $this->scopeConfig = $scopeConfig;
diff --git a/app/code/Magento/Rule/Model/Condition/Combine.php b/app/code/Magento/Rule/Model/Condition/Combine.php
index ec15afef65d..75362ace2c7 100644
--- a/app/code/Magento/Rule/Model/Condition/Combine.php
+++ b/app/code/Magento/Rule/Model/Condition/Combine.php
@@ -12,7 +12,7 @@ class Combine extends AbstractCondition
     protected $_conditionFactory;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
diff --git a/app/code/Magento/Rule/Model/Condition/Context.php b/app/code/Magento/Rule/Model/Condition/Context.php
index 5c7a32fb712..58ef010e230 100644
--- a/app/code/Magento/Rule/Model/Condition/Context.php
+++ b/app/code/Magento/Rule/Model/Condition/Context.php
@@ -32,7 +32,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
     protected $_conditionFactory;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -41,14 +41,14 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Framework\View\LayoutInterface $layout
      * @param \Magento\Rule\Model\ConditionFactory $conditionFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      */
     public function __construct(
         \Magento\Framework\View\Asset\Repository $assetRepo,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Framework\View\LayoutInterface $layout,
         \Magento\Rule\Model\ConditionFactory $conditionFactory,
-        \Magento\Framework\Logger $logger
+        \Psr\Log\LoggerInterface $logger
     ) {
         $this->_assetRepo = $assetRepo;
         $this->_localeDate = $localeDate;
@@ -90,7 +90,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
     }
 
     /**
-     * @return \Magento\Framework\Logger
+     * @return \Psr\Log\LoggerInterface
      */
     public function getLogger()
     {
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Cancel.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Cancel.php
index 489637db0f4..94b9f269119 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Cancel.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Cancel.php
@@ -24,7 +24,7 @@ class Cancel extends \Magento\Sales\Controller\Adminhtml\Order
                 $this->messageManager->addError($e->getMessage());
             } catch (\Exception $e) {
                 $this->messageManager->addError(__('You have not canceled the item.'));
-                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             }
             $this->_redirect('sales/order/view', ['order_id' => $order->getId()]);
         }
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php
index d7325721c57..fd22737d145 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php
@@ -123,7 +123,7 @@ class Save extends \Magento\Backend\App\Action
             $this->messageManager->addError($e->getMessage());
             $this->_getSession()->setFormData($data);
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->messageManager->addError(__('Cannot save the credit memo.'));
         }
         $this->_redirect('sales/*/new', ['_current' => true]);
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Email.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Email.php
index 9d67b4d466e..4db052f51d7 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Email.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Email.php
@@ -29,7 +29,7 @@ class Email extends \Magento\Sales\Controller\Adminhtml\Order
                 $this->messageManager->addError($e->getMessage());
             } catch (\Exception $e) {
                 $this->messageManager->addError(__('We couldn\'t send the email order.'));
-                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             }
             $this->_redirect('sales/order/view', ['order_id' => $order->getId()]);
         }
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php
index 061872f8f9c..24eaeae7280 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php
@@ -188,14 +188,14 @@ class Save extends \Magento\Backend\App\Action
             try {
                 $this->invoiceCommentSender->send($invoice, !empty($data['send_email']), $comment);
             } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                 $this->messageManager->addError(__('We can\'t send the invoice email.'));
             }
             if ($shipment) {
                 try {
                     $this->shipmentSender->send($shipment, !empty($data['send_email']));
                 } catch (\Exception $e) {
-                    $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                    $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                     $this->messageManager->addError(__('We can\'t send the shipment.'));
                 }
             }
@@ -206,7 +206,7 @@ class Save extends \Magento\Backend\App\Action
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t save the invoice.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->_redirect('sales/*/new', ['order_id' => $orderId]);
     }
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/ReviewPayment.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/ReviewPayment.php
index 5fe6d8e37dd..b1507b81be3 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/ReviewPayment.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/ReviewPayment.php
@@ -49,7 +49,7 @@ class ReviewPayment extends \Magento\Sales\Controller\Adminhtml\Order
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We couldn\'t update the payment.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->_redirect('sales/order/view', ['order_id' => $order->getId()]);
     }
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/View.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/View.php
index 6ff2b7c428b..fc4ed63d9b9 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/View.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/View.php
@@ -26,7 +26,7 @@ class View extends \Magento\Sales\Controller\Adminhtml\Order
                 $this->_redirect('sales/order/index');
                 return;
             } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                 $this->messageManager->addError(__('Exception occurred during order load'));
                 $this->_redirect('sales/order/index');
                 return;
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/VoidPayment.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/VoidPayment.php
index ae99743a7e4..1e30725aa5e 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/VoidPayment.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/VoidPayment.php
@@ -26,7 +26,7 @@ class VoidPayment extends \Magento\Sales\Controller\Adminhtml\Order
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We couldn\'t void the payment.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->_redirect('sales/*/view', ['order_id' => $order->getId()]);
     }
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Fetch.php b/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Fetch.php
index 4399974ea79..72bdfbd4073 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Fetch.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Fetch.php
@@ -28,7 +28,7 @@ class Fetch extends \Magento\Sales\Controller\Adminhtml\Transactions
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t update the transaction details.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->_redirect('sales/transactions/view', ['_current' => true]);
     }
diff --git a/app/code/Magento/Sales/Model/AbstractNotifier.php b/app/code/Magento/Sales/Model/AbstractNotifier.php
index d25db83eed0..d9c808ee4e6 100644
--- a/app/code/Magento/Sales/Model/AbstractNotifier.php
+++ b/app/code/Magento/Sales/Model/AbstractNotifier.php
@@ -5,7 +5,7 @@
 
 namespace Magento\Sales\Model;
 
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 use Magento\Framework\Mail\Exception;
 use Magento\Sales\Model\Order\Email\Sender;
 use Magento\Sales\Model\Resource\Order\Status\History\CollectionFactory;
@@ -22,7 +22,7 @@ abstract class AbstractNotifier extends \Magento\Framework\Model\AbstractModel
     protected $historyCollectionFactory;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
diff --git a/app/code/Magento/Sales/Model/AdminOrder/Create.php b/app/code/Magento/Sales/Model/AdminOrder/Create.php
index 761cb20b95b..5d06152dd0b 100644
--- a/app/code/Magento/Sales/Model/AdminOrder/Create.php
+++ b/app/code/Magento/Sales/Model/AdminOrder/Create.php
@@ -86,7 +86,7 @@ class Create extends \Magento\Framework\Object implements \Magento\Checkout\Mode
     protected $_coreRegistry = null;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -200,7 +200,7 @@ class Create extends \Magento\Framework\Object implements \Magento\Checkout\Mode
      * @param \Magento\Framework\Registry $coreRegistry
      * @param \Magento\Sales\Model\Config $salesConfig
      * @param \Magento\Backend\Model\Session\Quote $quoteSession
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Object\Copy $objectCopyService
      * @param \Magento\Framework\Message\ManagerInterface $messageManager
      * @param Product\Quote\Initializer $quoteInitializer
@@ -226,7 +226,7 @@ class Create extends \Magento\Framework\Object implements \Magento\Checkout\Mode
         \Magento\Framework\Registry $coreRegistry,
         \Magento\Sales\Model\Config $salesConfig,
         \Magento\Backend\Model\Session\Quote $quoteSession,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Object\Copy $objectCopyService,
         \Magento\Framework\Message\ManagerInterface $messageManager,
         Product\Quote\Initializer $quoteInitializer,
diff --git a/app/code/Magento/Sales/Model/AdminOrder/EmailSender.php b/app/code/Magento/Sales/Model/AdminOrder/EmailSender.php
index b249f7d7d63..9e283b8d52b 100644
--- a/app/code/Magento/Sales/Model/AdminOrder/EmailSender.php
+++ b/app/code/Magento/Sales/Model/AdminOrder/EmailSender.php
@@ -4,7 +4,7 @@
  */
 namespace Magento\Sales\Model\AdminOrder;
 
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 use Magento\Framework\Message\ManagerInterface;
 use Magento\Sales\Model\Order;
 use Magento\Sales\Model\Order\Email\Sender\OrderSender;
diff --git a/app/code/Magento/Sales/Model/Config/Ordered.php b/app/code/Magento/Sales/Model/Config/Ordered.php
index 0da1fc08f10..06640009284 100644
--- a/app/code/Magento/Sales/Model/Config/Ordered.php
+++ b/app/code/Magento/Sales/Model/Config/Ordered.php
@@ -59,7 +59,7 @@ abstract class Ordered extends \Magento\Framework\App\Config\Base
     protected $_configCacheType;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -70,13 +70,13 @@ abstract class Ordered extends \Magento\Framework\App\Config\Base
 
     /**
      * @param \Magento\Framework\App\Cache\Type\Config $configCacheType
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Sales\Model\Config $salesConfig
      * @param \Magento\Framework\Simplexml\Element $sourceData
      */
     public function __construct(
         \Magento\Framework\App\Cache\Type\Config $configCacheType,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Sales\Model\Config $salesConfig,
         $sourceData = null
     ) {
diff --git a/app/code/Magento/Sales/Model/Order/CreditmemoNotifier.php b/app/code/Magento/Sales/Model/Order/CreditmemoNotifier.php
index 97cd87fc60b..ad1edd48113 100644
--- a/app/code/Magento/Sales/Model/Order/CreditmemoNotifier.php
+++ b/app/code/Magento/Sales/Model/Order/CreditmemoNotifier.php
@@ -5,7 +5,7 @@
 
 namespace Magento\Sales\Model\Order;
 
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 use Magento\Sales\Model\Order\Email\Sender\CreditmemoSender;
 use Magento\Sales\Model\Resource\Order\Status\History\CollectionFactory;
 
@@ -21,7 +21,7 @@ class CreditmemoNotifier extends \Magento\Sales\Model\AbstractNotifier
     protected $historyCollectionFactory;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
diff --git a/app/code/Magento/Sales/Model/Order/InvoiceNotifier.php b/app/code/Magento/Sales/Model/Order/InvoiceNotifier.php
index d8952c48f47..e9c82ce7c72 100644
--- a/app/code/Magento/Sales/Model/Order/InvoiceNotifier.php
+++ b/app/code/Magento/Sales/Model/Order/InvoiceNotifier.php
@@ -5,7 +5,7 @@
 
 namespace Magento\Sales\Model\Order;
 
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 use Magento\Sales\Model\Order\Email\Sender\InvoiceSender;
 use Magento\Sales\Model\Resource\Order\Status\History\CollectionFactory;
 
@@ -21,7 +21,7 @@ class InvoiceNotifier extends \Magento\Sales\Model\AbstractNotifier
     protected $historyCollectionFactory;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
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 f20acae7fc2..00c098f071f 100644
--- a/app/code/Magento/Sales/Model/Order/Total/Config/Base.php
+++ b/app/code/Magento/Sales/Model/Order/Total/Config/Base.php
@@ -37,14 +37,14 @@ class Base extends \Magento\Sales\Model\Config\Ordered
 
     /**
      * @param \Magento\Framework\App\Cache\Type\Config $configCacheType
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Sales\Model\Config $salesConfig
      * @param \Magento\Sales\Model\Order\TotalFactory $orderTotalFactory
      * @param mixed $sourceData
      */
     public function __construct(
         \Magento\Framework\App\Cache\Type\Config $configCacheType,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Sales\Model\Config $salesConfig,
         \Magento\Sales\Model\Order\TotalFactory $orderTotalFactory,
         $sourceData = null
diff --git a/app/code/Magento/Sales/Model/OrderNotifier.php b/app/code/Magento/Sales/Model/OrderNotifier.php
index 2177000ca15..317a49b0c5d 100644
--- a/app/code/Magento/Sales/Model/OrderNotifier.php
+++ b/app/code/Magento/Sales/Model/OrderNotifier.php
@@ -5,7 +5,7 @@
 
 namespace Magento\Sales\Model;
 
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 use Magento\Sales\Model\Order\Email\Sender\OrderSender;
 use Magento\Sales\Model\Resource\Order\Status\History\CollectionFactory;
 
@@ -21,7 +21,7 @@ class OrderNotifier extends \Magento\Sales\Model\AbstractNotifier
     protected $historyCollectionFactory;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
diff --git a/app/code/Magento/Sales/Model/Quote/Address/Total/Collector.php b/app/code/Magento/Sales/Model/Quote/Address/Total/Collector.php
index 7458e105508..9c711850919 100644
--- a/app/code/Magento/Sales/Model/Quote/Address/Total/Collector.php
+++ b/app/code/Magento/Sales/Model/Quote/Address/Total/Collector.php
@@ -61,7 +61,7 @@ class Collector extends \Magento\Sales\Model\Config\Ordered
 
     /**
      * @param \Magento\Framework\App\Cache\Type\Config $configCacheType
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Sales\Model\Config $salesConfig
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
@@ -71,7 +71,7 @@ class Collector extends \Magento\Sales\Model\Config\Ordered
      */
     public function __construct(
         \Magento\Framework\App\Cache\Type\Config $configCacheType,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Sales\Model\Config $salesConfig,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
diff --git a/app/code/Magento/Sales/Model/Resource/Order/Collection.php b/app/code/Magento/Sales/Model/Resource/Order/Collection.php
index 3a2e120ca3b..a27701d5112 100644
--- a/app/code/Magento/Sales/Model/Resource/Order/Collection.php
+++ b/app/code/Magento/Sales/Model/Resource/Order/Collection.php
@@ -35,7 +35,7 @@ class Collection extends AbstractCollection implements OrderSearchResultInterfac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\DB\Helper $coreResourceHelper
@@ -44,7 +44,7 @@ class Collection extends AbstractCollection implements OrderSearchResultInterfac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Framework\DB\Helper $coreResourceHelper,
diff --git a/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Order/Grid/Collection.php b/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Order/Grid/Collection.php
index 21e235b8126..2cade1f151f 100644
--- a/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Order/Grid/Collection.php
+++ b/app/code/Magento/Sales/Model/Resource/Order/Creditmemo/Order/Grid/Collection.php
@@ -18,7 +18,7 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Creditmemo\Grid\Col
 
     /**
      * @param \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\Registry $registryManager
@@ -27,7 +27,7 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Creditmemo\Grid\Col
      */
     public function __construct(
         \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Framework\Registry $registryManager,
diff --git a/app/code/Magento/Sales/Model/Resource/Order/Invoice/Orders/Grid/Collection.php b/app/code/Magento/Sales/Model/Resource/Order/Invoice/Orders/Grid/Collection.php
index b4dc1664e44..8f3b2f01318 100644
--- a/app/code/Magento/Sales/Model/Resource/Order/Invoice/Orders/Grid/Collection.php
+++ b/app/code/Magento/Sales/Model/Resource/Order/Invoice/Orders/Grid/Collection.php
@@ -13,7 +13,7 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Invoice\Grid\Collec
 
     /**
      * @param \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\Registry $registryManager
@@ -22,7 +22,7 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Invoice\Grid\Collec
      */
     public function __construct(
         \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Framework\Registry $registryManager,
diff --git a/app/code/Magento/Sales/Model/Resource/Order/Payment/Collection.php b/app/code/Magento/Sales/Model/Resource/Order/Payment/Collection.php
index 5afc10aacfa..b3036288845 100644
--- a/app/code/Magento/Sales/Model/Resource/Order/Payment/Collection.php
+++ b/app/code/Magento/Sales/Model/Resource/Order/Payment/Collection.php
@@ -28,7 +28,7 @@ class Collection extends AbstractCollection implements OrderPaymentSearchResultI
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Zend_Db_Adapter_Abstract $connection
@@ -36,7 +36,7 @@ class Collection extends AbstractCollection implements OrderPaymentSearchResultI
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         $connection = null,
diff --git a/app/code/Magento/Sales/Model/Resource/Order/Shipment/Order/Grid/Collection.php b/app/code/Magento/Sales/Model/Resource/Order/Shipment/Order/Grid/Collection.php
index 56da2f266f1..e5a1677943e 100644
--- a/app/code/Magento/Sales/Model/Resource/Order/Shipment/Order/Grid/Collection.php
+++ b/app/code/Magento/Sales/Model/Resource/Order/Shipment/Order/Grid/Collection.php
@@ -18,7 +18,7 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Shipment\Grid\Colle
 
     /**
      * @param \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\Registry $registryManager
@@ -27,7 +27,7 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Shipment\Grid\Colle
      */
     public function __construct(
         \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Framework\Registry $registryManager,
diff --git a/app/code/Magento/Sales/Model/Resource/Order/Status.php b/app/code/Magento/Sales/Model/Resource/Order/Status.php
index 34a9b9608b3..df6258b3683 100644
--- a/app/code/Magento/Sales/Model/Resource/Order/Status.php
+++ b/app/code/Magento/Sales/Model/Resource/Order/Status.php
@@ -5,7 +5,7 @@
 namespace Magento\Sales\Model\Resource\Order;
 
 use Magento\Framework\App\Resource;
-use Magento\Framework\Logger as LogWriter;
+use Psr\Log\LoggerInterface as LogWriter;
 use Magento\Framework\Model\Exception;
 
 /**
@@ -30,7 +30,7 @@ class Status extends \Magento\Framework\Model\Resource\Db\AbstractDb
     protected $stateTable;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
diff --git a/app/code/Magento/Sales/Model/Resource/Quote/Address/Rate/Collection.php b/app/code/Magento/Sales/Model/Resource/Quote/Address/Rate/Collection.php
index e88135a1bfa..e726f76e37c 100644
--- a/app/code/Magento/Sales/Model/Resource/Quote/Address/Rate/Collection.php
+++ b/app/code/Magento/Sales/Model/Resource/Quote/Address/Rate/Collection.php
@@ -20,7 +20,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Sales\Model\Quote\Address\CarrierFactoryInterface $carrierFactory
@@ -29,7 +29,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Sales\Model\Quote\Address\CarrierFactoryInterface $carrierFactory,
diff --git a/app/code/Magento/Sales/Model/Resource/Quote/Item/Collection.php b/app/code/Magento/Sales/Model/Resource/Quote/Item/Collection.php
index 1aa6352b223..979e2932865 100644
--- a/app/code/Magento/Sales/Model/Resource/Quote/Item/Collection.php
+++ b/app/code/Magento/Sales/Model/Resource/Quote/Item/Collection.php
@@ -40,7 +40,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Sales\Model\Resource\Quote\Item\Option\CollectionFactory $itemOptionCollectionFactory
@@ -51,7 +51,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Sales\Model\Resource\Quote\Item\Option\CollectionFactory $itemOptionCollectionFactory,
diff --git a/app/code/Magento/Sales/Model/Resource/Quote/Payment/Collection.php b/app/code/Magento/Sales/Model/Resource/Quote/Payment/Collection.php
index 178e03ab5db..1a3a1f07543 100644
--- a/app/code/Magento/Sales/Model/Resource/Quote/Payment/Collection.php
+++ b/app/code/Magento/Sales/Model/Resource/Quote/Payment/Collection.php
@@ -11,7 +11,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 {
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Zend_Db_Adapter_Abstract $connection
@@ -19,7 +19,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         $connection = null,
diff --git a/app/code/Magento/Sales/Model/Resource/Report/Bestsellers.php b/app/code/Magento/Sales/Model/Resource/Report/Bestsellers.php
index 9e9cbc9bb79..49989878dc4 100644
--- a/app/code/Magento/Sales/Model/Resource/Report/Bestsellers.php
+++ b/app/code/Magento/Sales/Model/Resource/Report/Bestsellers.php
@@ -36,7 +36,7 @@ class Bestsellers extends AbstractReport
 
     /**
      * @param \Magento\Framework\App\Resource $resource
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Reports\Model\FlagFactory $reportsFlagFactory
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
@@ -47,7 +47,7 @@ class Bestsellers extends AbstractReport
      */
     public function __construct(
         \Magento\Framework\App\Resource $resource,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Reports\Model\FlagFactory $reportsFlagFactory,
         \Magento\Framework\Stdlib\DateTime $dateTime,
diff --git a/app/code/Magento/Sales/Model/Resource/Report/Bestsellers/Collection.php b/app/code/Magento/Sales/Model/Resource/Report/Bestsellers/Collection.php
index 73525e8f13a..16782bc6898 100644
--- a/app/code/Magento/Sales/Model/Resource/Report/Bestsellers/Collection.php
+++ b/app/code/Magento/Sales/Model/Resource/Report/Bestsellers/Collection.php
@@ -27,7 +27,7 @@ class Collection extends \Magento\Sales\Model\Resource\Report\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Sales\Model\Resource\Report $resource
@@ -35,7 +35,7 @@ class Collection extends \Magento\Sales\Model\Resource\Report\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Sales\Model\Resource\Report $resource,
diff --git a/app/code/Magento/Sales/Model/Resource/Report/Collection/AbstractCollection.php b/app/code/Magento/Sales/Model/Resource/Report/Collection/AbstractCollection.php
index d6142402445..7a8bd502caa 100644
--- a/app/code/Magento/Sales/Model/Resource/Report/Collection/AbstractCollection.php
+++ b/app/code/Magento/Sales/Model/Resource/Report/Collection/AbstractCollection.php
@@ -20,7 +20,7 @@ class AbstractCollection extends \Magento\Reports\Model\Resource\Report\Collecti
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Sales\Model\Resource\Report $resource
@@ -28,7 +28,7 @@ class AbstractCollection extends \Magento\Reports\Model\Resource\Report\Collecti
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Sales\Model\Resource\Report $resource,
diff --git a/app/code/Magento/Sales/Model/Resource/Report/Invoiced/Collection/Invoiced.php b/app/code/Magento/Sales/Model/Resource/Report/Invoiced/Collection/Invoiced.php
index 73be9036f20..1f6c8513556 100644
--- a/app/code/Magento/Sales/Model/Resource/Report/Invoiced/Collection/Invoiced.php
+++ b/app/code/Magento/Sales/Model/Resource/Report/Invoiced/Collection/Invoiced.php
@@ -13,7 +13,7 @@ class Invoiced extends Order
 {
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Sales\Model\Resource\Report $resource
@@ -21,7 +21,7 @@ class Invoiced extends Order
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Sales\Model\Resource\Report $resource,
diff --git a/app/code/Magento/Sales/Model/Resource/Report/Invoiced/Collection/Order.php b/app/code/Magento/Sales/Model/Resource/Report/Invoiced/Collection/Order.php
index 600501645c5..f2a9f172b2f 100644
--- a/app/code/Magento/Sales/Model/Resource/Report/Invoiced/Collection/Order.php
+++ b/app/code/Magento/Sales/Model/Resource/Report/Invoiced/Collection/Order.php
@@ -27,7 +27,7 @@ class Order extends \Magento\Sales\Model\Resource\Report\Collection\AbstractColl
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Sales\Model\Resource\Report $resource
@@ -35,7 +35,7 @@ class Order extends \Magento\Sales\Model\Resource\Report\Collection\AbstractColl
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Sales\Model\Resource\Report $resource,
diff --git a/app/code/Magento/Sales/Model/Resource/Report/Order.php b/app/code/Magento/Sales/Model/Resource/Report/Order.php
index c18cbf90c5e..4e8dea3eb1e 100644
--- a/app/code/Magento/Sales/Model/Resource/Report/Order.php
+++ b/app/code/Magento/Sales/Model/Resource/Report/Order.php
@@ -21,7 +21,7 @@ class Order extends AbstractReport
 
     /**
      * @param \Magento\Framework\App\Resource $resource
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Reports\Model\FlagFactory $reportsFlagFactory
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
@@ -31,7 +31,7 @@ class Order extends AbstractReport
      */
     public function __construct(
         \Magento\Framework\App\Resource $resource,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Reports\Model\FlagFactory $reportsFlagFactory,
         \Magento\Framework\Stdlib\DateTime $dateTime,
diff --git a/app/code/Magento/Sales/Model/Resource/Report/Order/Collection.php b/app/code/Magento/Sales/Model/Resource/Report/Order/Collection.php
index 4c6afaa58c8..61143dda0bd 100644
--- a/app/code/Magento/Sales/Model/Resource/Report/Order/Collection.php
+++ b/app/code/Magento/Sales/Model/Resource/Report/Order/Collection.php
@@ -34,7 +34,7 @@ class Collection extends \Magento\Sales\Model\Resource\Report\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Sales\Model\Resource\Report $resource
@@ -42,7 +42,7 @@ class Collection extends \Magento\Sales\Model\Resource\Report\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Sales\Model\Resource\Report $resource,
diff --git a/app/code/Magento/Sales/Model/Resource/Report/Refunded/Collection/Order.php b/app/code/Magento/Sales/Model/Resource/Report/Refunded/Collection/Order.php
index 4c961548377..ff0eb84377c 100644
--- a/app/code/Magento/Sales/Model/Resource/Report/Refunded/Collection/Order.php
+++ b/app/code/Magento/Sales/Model/Resource/Report/Refunded/Collection/Order.php
@@ -27,7 +27,7 @@ class Order extends \Magento\Sales\Model\Resource\Report\Collection\AbstractColl
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Sales\Model\Resource\Report $resource
@@ -35,7 +35,7 @@ class Order extends \Magento\Sales\Model\Resource\Report\Collection\AbstractColl
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Sales\Model\Resource\Report $resource,
diff --git a/app/code/Magento/Sales/Model/Resource/Report/Refunded/Collection/Refunded.php b/app/code/Magento/Sales/Model/Resource/Report/Refunded/Collection/Refunded.php
index 820e18229b6..d79ab374ac2 100644
--- a/app/code/Magento/Sales/Model/Resource/Report/Refunded/Collection/Refunded.php
+++ b/app/code/Magento/Sales/Model/Resource/Report/Refunded/Collection/Refunded.php
@@ -13,7 +13,7 @@ class Refunded extends Order
 {
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Sales\Model\Resource\Report $resource
@@ -21,7 +21,7 @@ class Refunded extends Order
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Sales\Model\Resource\Report $resource,
diff --git a/app/code/Magento/Sales/Model/Resource/Report/Shipping/Collection/Order.php b/app/code/Magento/Sales/Model/Resource/Report/Shipping/Collection/Order.php
index a9b72b30be0..cedf8781e90 100644
--- a/app/code/Magento/Sales/Model/Resource/Report/Shipping/Collection/Order.php
+++ b/app/code/Magento/Sales/Model/Resource/Report/Shipping/Collection/Order.php
@@ -27,7 +27,7 @@ class Order extends \Magento\Sales\Model\Resource\Report\Collection\AbstractColl
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Sales\Model\Resource\Report $resource
@@ -35,7 +35,7 @@ class Order extends \Magento\Sales\Model\Resource\Report\Collection\AbstractColl
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Sales\Model\Resource\Report $resource,
diff --git a/app/code/Magento/Sales/Model/Resource/Report/Shipping/Collection/Shipment.php b/app/code/Magento/Sales/Model/Resource/Report/Shipping/Collection/Shipment.php
index ceaf16cf728..b2fcd7ac9dc 100644
--- a/app/code/Magento/Sales/Model/Resource/Report/Shipping/Collection/Shipment.php
+++ b/app/code/Magento/Sales/Model/Resource/Report/Shipping/Collection/Shipment.php
@@ -13,7 +13,7 @@ class Shipment extends Order
 {
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Sales\Model\Resource\Report $resource
@@ -21,7 +21,7 @@ class Shipment extends Order
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Sales\Model\Resource\Report $resource,
diff --git a/app/code/Magento/Sales/Model/Resource/Sale/Collection.php b/app/code/Magento/Sales/Model/Resource/Sale/Collection.php
index 99d40d4961d..d0987f3d99d 100644
--- a/app/code/Magento/Sales/Model/Resource/Sale/Collection.php
+++ b/app/code/Magento/Sales/Model/Resource/Sale/Collection.php
@@ -8,7 +8,7 @@ use Magento\Core\Model\EntityFactory;
 use Magento\Store\Model\StoreManagerInterface;
 use Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
 use Magento\Framework\Event\ManagerInterface;
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 use Magento\Sales\Model\Resource\Order;
 
 /**
diff --git a/app/code/Magento/Sales/Model/Resource/Transaction/Grid/Collection.php b/app/code/Magento/Sales/Model/Resource/Transaction/Grid/Collection.php
index 438a0998be9..4f8bb993dbd 100644
--- a/app/code/Magento/Sales/Model/Resource/Transaction/Grid/Collection.php
+++ b/app/code/Magento/Sales/Model/Resource/Transaction/Grid/Collection.php
@@ -16,7 +16,7 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Payment\Transaction
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\Registry $registryManager
@@ -25,7 +25,7 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Payment\Transaction
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Framework\Registry $registryManager,
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Delete.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Delete.php
index 14fbb20f1ff..cd5fe932c1b 100644
--- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Delete.php
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Delete.php
@@ -29,7 +29,7 @@ class Delete extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
                 $this->messageManager->addError(
                     __('An error occurred while deleting the rule. Please review the log and try again.')
                 );
-                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                 $this->_redirect('sales_rule/*/edit', ['id' => $this->getRequest()->getParam('id')]);
                 return;
             }
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php
index 4a1b23890b2..c29d02cc2d3 100644
--- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php
@@ -52,7 +52,7 @@ class Generate extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
                 $result['error'] = __(
                     'Something went wrong while generating coupons. Please review the log and try again.'
                 );
-                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             }
         }
         $this->getResponse()->representJson(
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php
index f0867046d93..1aa9ed6cc53 100644
--- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php
@@ -93,7 +93,7 @@ class Save extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
                 $this->messageManager->addError(
                     __('An error occurred while saving the rule data. Please review the log and try again.')
                 );
-                $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                 $this->_objectManager->get('Magento\Backend\Model\Session')->setPageData($data);
                 $this->_redirect('sales_rule/*/edit', ['id' => $this->getRequest()->getParam('rule_id')]);
                 return;
diff --git a/app/code/Magento/SalesRule/Model/Resource/Report/Collection.php b/app/code/Magento/SalesRule/Model/Resource/Report/Collection.php
index 9e0e726e501..8ef7dfc1de5 100644
--- a/app/code/Magento/SalesRule/Model/Resource/Report/Collection.php
+++ b/app/code/Magento/SalesRule/Model/Resource/Report/Collection.php
@@ -46,7 +46,7 @@ class Collection extends \Magento\Sales\Model\Resource\Report\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Sales\Model\Resource\Report $resource
@@ -55,7 +55,7 @@ class Collection extends \Magento\Sales\Model\Resource\Report\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Sales\Model\Resource\Report $resource,
diff --git a/app/code/Magento/SalesRule/Model/Resource/Report/Rule.php b/app/code/Magento/SalesRule/Model/Resource/Report/Rule.php
index ad81ce6fd40..43ac17f896e 100644
--- a/app/code/Magento/SalesRule/Model/Resource/Report/Rule.php
+++ b/app/code/Magento/SalesRule/Model/Resource/Report/Rule.php
@@ -23,7 +23,7 @@ class Rule extends \Magento\Reports\Model\Resource\Report\AbstractReport
 
     /**
      * @param \Magento\Framework\App\Resource $resource
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Reports\Model\FlagFactory $reportsFlagFactory
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
@@ -33,7 +33,7 @@ class Rule extends \Magento\Reports\Model\Resource\Report\AbstractReport
      */
     public function __construct(
         \Magento\Framework\App\Resource $resource,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Reports\Model\FlagFactory $reportsFlagFactory,
         \Magento\Framework\Stdlib\DateTime $dateTime,
diff --git a/app/code/Magento/SalesRule/Model/Resource/Rule/Collection.php b/app/code/Magento/SalesRule/Model/Resource/Rule/Collection.php
index b8d8057dd82..ba0fb345b26 100644
--- a/app/code/Magento/SalesRule/Model/Resource/Rule/Collection.php
+++ b/app/code/Magento/SalesRule/Model/Resource/Rule/Collection.php
@@ -36,7 +36,7 @@ class Collection extends \Magento\Rule\Model\Resource\Rule\Collection\AbstractCo
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\Stdlib\DateTime\DateTime $date
@@ -45,7 +45,7 @@ class Collection extends \Magento\Rule\Model\Resource\Rule\Collection\AbstractCo
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Framework\Stdlib\DateTime\DateTime $date,
diff --git a/app/code/Magento/Search/Model/Resource/Query/Collection.php b/app/code/Magento/Search/Model/Resource/Query/Collection.php
index 07dc2a4f169..9da9c34b18f 100644
--- a/app/code/Magento/Search/Model/Resource/Query/Collection.php
+++ b/app/code/Magento/Search/Model/Resource/Query/Collection.php
@@ -35,7 +35,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
@@ -45,7 +45,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/CreateLabel.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/CreateLabel.php
index 3ea56bc83ab..5b09369e89f 100644
--- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/CreateLabel.php
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/CreateLabel.php
@@ -64,7 +64,7 @@ class CreateLabel extends \Magento\Backend\App\Action
             $response->setError(true);
             $response->setMessage($e->getMessage());
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $response->setError(true);
             $response->setMessage(__('An error occurred while creating shipping label.'));
         }
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintLabel.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintLabel.php
index 453ebde07a0..4058d5f0632 100644
--- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintLabel.php
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintLabel.php
@@ -95,7 +95,7 @@ class PrintLabel extends \Magento\Backend\App\Action
         } catch (\Magento\Framework\Model\Exception $e) {
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->messageManager->addError(__('An error occurred while creating shipping label.'));
         }
         $this->_redirect(
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php
index 006e63beab5..893cf57a363 100644
--- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php
@@ -143,7 +143,7 @@ class Save extends \Magento\Backend\App\Action
                 $this->_redirect('*/*/new', ['order_id' => $this->getRequest()->getParam('order_id')]);
             }
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             if ($isNeedCreateLabel) {
                 $responseAjax->setError(true);
                 $responseAjax->setMessage(__('An error occurred while creating shipping label.'));
diff --git a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrier.php b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrier.php
index 7efca7af945..cb490cc476c 100644
--- a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrier.php
+++ b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrier.php
@@ -86,20 +86,20 @@ abstract class AbstractCarrier extends \Magento\Framework\Object implements Abst
     protected $_rateErrorFactory;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param array $data
      */
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         array $data = []
     ) {
         parent::__construct($data);
diff --git a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php
index 061e953250e..3a8f97aab63 100644
--- a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php
+++ b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrierOnline.php
@@ -103,7 +103,7 @@ abstract class AbstractCarrierOnline extends AbstractCarrier
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateFactory
      * @param \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
@@ -122,7 +122,7 @@ abstract class AbstractCarrierOnline extends AbstractCarrier
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory,
         \Magento\Shipping\Model\Rate\ResultFactory $rateFactory,
         \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
diff --git a/app/code/Magento/Shipping/Model/ShipmentNotifier.php b/app/code/Magento/Shipping/Model/ShipmentNotifier.php
index 6f868b0627f..38299cb23fc 100644
--- a/app/code/Magento/Shipping/Model/ShipmentNotifier.php
+++ b/app/code/Magento/Shipping/Model/ShipmentNotifier.php
@@ -5,7 +5,7 @@
 
 namespace Magento\Shipping\Model;
 
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 use Magento\Sales\Model\Order\Email\Sender\ShipmentSender;
 use Magento\Sales\Model\Resource\Order\Status\History\CollectionFactory;
 
@@ -21,7 +21,7 @@ class ShipmentNotifier extends \Magento\Sales\Model\AbstractNotifier
     protected $historyCollectionFactory;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
diff --git a/app/code/Magento/Store/Model/Resource/Config/Collection/Scoped.php b/app/code/Magento/Store/Model/Resource/Config/Collection/Scoped.php
index 2e416222c87..411d7aa62ed 100644
--- a/app/code/Magento/Store/Model/Resource/Config/Collection/Scoped.php
+++ b/app/code/Magento/Store/Model/Resource/Config/Collection/Scoped.php
@@ -24,7 +24,7 @@ class Scoped extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCol
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Core\Model\Resource\Config\Data $resource
@@ -34,7 +34,7 @@ class Scoped extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCol
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Core\Model\Resource\Config\Data $resource,
diff --git a/app/code/Magento/Store/Model/StorageFactory.php b/app/code/Magento/Store/Model/StorageFactory.php
index e7473e2ba7c..0ec394d4770 100644
--- a/app/code/Magento/Store/Model/StorageFactory.php
+++ b/app/code/Magento/Store/Model/StorageFactory.php
@@ -31,7 +31,7 @@ class StorageFactory
     protected $_eventManager;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_log;
 
diff --git a/app/code/Magento/Tax/Model/Resource/Calculation/Rate/Collection.php b/app/code/Magento/Tax/Model/Resource/Calculation/Rate/Collection.php
index e9f427e3b0e..f70eb490356 100644
--- a/app/code/Magento/Tax/Model/Resource/Calculation/Rate/Collection.php
+++ b/app/code/Magento/Tax/Model/Resource/Calculation/Rate/Collection.php
@@ -22,7 +22,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
@@ -31,7 +31,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
diff --git a/app/code/Magento/Tax/Model/Resource/Report/Collection.php b/app/code/Magento/Tax/Model/Resource/Report/Collection.php
index 7ae32523bcc..6cdfeb5bf15 100644
--- a/app/code/Magento/Tax/Model/Resource/Report/Collection.php
+++ b/app/code/Magento/Tax/Model/Resource/Report/Collection.php
@@ -31,7 +31,7 @@ class Collection extends \Magento\Sales\Model\Resource\Report\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Sales\Model\Resource\Report $resource
@@ -39,7 +39,7 @@ class Collection extends \Magento\Sales\Model\Resource\Report\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Sales\Model\Resource\Report $resource,
diff --git a/app/code/Magento/Tax/Model/Resource/Report/Tax.php b/app/code/Magento/Tax/Model/Resource/Report/Tax.php
index f85c89784ca..c184dd5bf6e 100644
--- a/app/code/Magento/Tax/Model/Resource/Report/Tax.php
+++ b/app/code/Magento/Tax/Model/Resource/Report/Tax.php
@@ -22,7 +22,7 @@ class Tax extends \Magento\Reports\Model\Resource\Report\AbstractReport
 
     /**
      * @param \Magento\Framework\App\Resource $resource
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Reports\Model\FlagFactory $reportsFlagFactory
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
@@ -32,7 +32,7 @@ class Tax extends \Magento\Reports\Model\Resource\Report\AbstractReport
      */
     public function __construct(
         \Magento\Framework\App\Resource $resource,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Reports\Model\FlagFactory $reportsFlagFactory,
         \Magento\Framework\Stdlib\DateTime $dateTime,
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Delete.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Delete.php
index 84520950e44..70ac5381a35 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Delete.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Delete.php
@@ -35,7 +35,7 @@ class Delete extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addException($e, __('We cannot delete the theme.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         /**
          * @todo Temporary solution. Theme module should not know about the existence of editor module.
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCss.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCss.php
index 909a46b10f3..a36241655f6 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCss.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCss.php
@@ -43,7 +43,7 @@ class DownloadCss extends \Magento\Theme\Controller\Adminhtml\System\Design\Them
         } catch (\Exception $e) {
             $this->messageManager->addException($e, __('File not found: "%1".', $fileId));
             $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
     }
 }
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCustomCss.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCustomCss.php
index 5f2158f8381..38f9b1a5c80 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCustomCss.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCustomCss.php
@@ -41,7 +41,7 @@ class DownloadCustomCss extends \Magento\Theme\Controller\Adminhtml\System\Desig
         } catch (\Exception $e) {
             $this->messageManager->addException($e, __('We cannot find file'));
             $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
     }
 }
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Edit.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Edit.php
index 9305e1eb450..cc443d1d80b 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Edit.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Edit.php
@@ -40,7 +40,7 @@ class Edit extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
             $this->_redirect('adminhtml/*/');
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We cannot find the theme.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->_redirect('adminhtml/*/');
         }
     }
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Save.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Save.php
index 91db9e41116..2c3965ec8cf 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Save.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Save.php
@@ -69,7 +69,7 @@ class Save extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
             $redirectBack = true;
         } catch (\Exception $e) {
             $this->messageManager->addError('The theme was not saved');
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $redirectBack ? $this->_redirect(
             'adminhtml/*/edit',
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadCss.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadCss.php
index 14035e57241..bf7ee434a10 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadCss.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadCss.php
@@ -23,7 +23,7 @@ class UploadCss extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
             $result = ['error' => true, 'message' => $e->getMessage()];
         } catch (\Exception $e) {
             $result = ['error' => true, 'message' => __('We cannot upload the CSS file.')];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadJs.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadJs.php
index 9c40d817334..6722f35aa16 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadJs.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadJs.php
@@ -47,7 +47,7 @@ class UploadJs extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
             $result = ['error' => true, 'message' => $e->getMessage()];
         } catch (\Exception $e) {
             $result = ['error' => true, 'message' => __('We cannot upload the JS file.')];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/NewFolder.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/NewFolder.php
index da8b2b9c47f..cd50539d069 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/NewFolder.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/NewFolder.php
@@ -22,7 +22,7 @@ class NewFolder extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwy
             $result = ['error' => true, 'message' => $e->getMessage()];
         } catch (\Exception $e) {
             $result = ['error' => true, 'message' => __('Sorry, there was an unknown error.')];
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->getResponse()->representJson(
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/PreviewImage.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/PreviewImage.php
index c55290767a4..e1bd7a7bec3 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/PreviewImage.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/PreviewImage.php
@@ -27,7 +27,7 @@ class PreviewImage extends \Magento\Theme\Controller\Adminhtml\System\Design\Wys
                 DirectoryList::MEDIA
             );
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->_redirect('core/index/notFound');
         }
     }
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/TreeJson.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/TreeJson.php
index 55dd0f21069..93187621097 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/TreeJson.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/TreeJson.php
@@ -23,7 +23,7 @@ class TreeJson extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg
                 )
             );
         } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->getResponse()->representJson(
                 $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode([])
             );
diff --git a/app/code/Magento/Theme/Model/Wysiwyg/Storage.php b/app/code/Magento/Theme/Model/Wysiwyg/Storage.php
index 64b796628bb..0dc097aa355 100644
--- a/app/code/Magento/Theme/Model/Wysiwyg/Storage.php
+++ b/app/code/Magento/Theme/Model/Wysiwyg/Storage.php
@@ -159,7 +159,7 @@ class Storage
             $image->resize(self::THUMBNAIL_WIDTH, self::THUMBNAIL_HEIGHT);
             $image->save($this->mediaWriteDirectory->getAbsolutePath($thumbnailPath));
         } catch (\Magento\Framework\Filesystem\FilesystemException $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             return false;
         }
 
diff --git a/app/code/Magento/Ups/Model/Carrier.php b/app/code/Magento/Ups/Model/Carrier.php
index 91cf8654565..2ccb54582ae 100644
--- a/app/code/Magento/Ups/Model/Carrier.php
+++ b/app/code/Magento/Ups/Model/Carrier.php
@@ -105,7 +105,7 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface
     protected $_localeFormat;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -117,7 +117,7 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateFactory
      * @param \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
@@ -138,7 +138,7 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory,
         \Magento\Shipping\Model\Rate\ResultFactory $rateFactory,
         \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
diff --git a/app/code/Magento/UrlRewrite/Model/Resource/UrlRewriteCollection.php b/app/code/Magento/UrlRewrite/Model/Resource/UrlRewriteCollection.php
index 0e50c89bf2d..ad3059c13ee 100644
--- a/app/code/Magento/UrlRewrite/Model/Resource/UrlRewriteCollection.php
+++ b/app/code/Magento/UrlRewrite/Model/Resource/UrlRewriteCollection.php
@@ -17,7 +17,7 @@ class UrlRewriteCollection extends \Magento\Framework\Model\Resource\Db\Collecti
 
     /**
      * @param \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
@@ -26,7 +26,7 @@ class UrlRewriteCollection extends \Magento\Framework\Model\Resource\Db\Collecti
      */
     public function __construct(
         \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
diff --git a/app/code/Magento/Usps/Model/Carrier.php b/app/code/Magento/Usps/Model/Carrier.php
index 11e7aa0a4ef..a4b61c755e6 100644
--- a/app/code/Magento/Usps/Model/Carrier.php
+++ b/app/code/Magento/Usps/Model/Carrier.php
@@ -115,7 +115,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory
      * @param \Magento\Shipping\Model\Rate\ResultFactory $rateFactory
      * @param \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
@@ -137,7 +137,7 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Shipping\Model\Simplexml\ElementFactory $xmlElFactory,
         \Magento\Shipping\Model\Rate\ResultFactory $rateFactory,
         \Magento\Sales\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
diff --git a/app/code/Magento/Webapi/Controller/ErrorProcessor.php b/app/code/Magento/Webapi/Controller/ErrorProcessor.php
index 35d44e282e0..3e951b285ad 100644
--- a/app/code/Magento/Webapi/Controller/ErrorProcessor.php
+++ b/app/code/Magento/Webapi/Controller/ErrorProcessor.php
@@ -48,7 +48,7 @@ class ErrorProcessor
     protected $_appState;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -67,13 +67,13 @@ class ErrorProcessor
     /**
      * @param \Magento\Core\Helper\Data $helper
      * @param \Magento\Framework\App\State $appState
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Filesystem $filesystem
      */
     public function __construct(
         \Magento\Core\Helper\Data $helper,
         \Magento\Framework\App\State $appState,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Filesystem $filesystem
     ) {
         $this->_coreHelper = $helper;
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance.php
index 6c749bd080f..44756854059 100644
--- a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance.php
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance.php
@@ -23,7 +23,7 @@ class Instance extends \Magento\Backend\App\Action
     protected $_widgetFactory;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -41,7 +41,7 @@ class Instance extends \Magento\Backend\App\Action
      * @param \Magento\Backend\App\Action\Context $context
      * @param \Magento\Framework\Registry $coreRegistry
      * @param \Magento\Widget\Model\Widget\InstanceFactory $widgetFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Math\Random $mathRandom
      * @param \Magento\Framework\Translate\InlineInterface $translateInline
      */
@@ -49,7 +49,7 @@ class Instance extends \Magento\Backend\App\Action
         \Magento\Backend\App\Action\Context $context,
         \Magento\Framework\Registry $coreRegistry,
         \Magento\Widget\Model\Widget\InstanceFactory $widgetFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Math\Random $mathRandom,
         \Magento\Framework\Translate\InlineInterface $translateInline
     ) {
diff --git a/app/code/Magento/Widget/Model/Template/Filter.php b/app/code/Magento/Widget/Model/Template/Filter.php
index e5c7aa30374..695345a62c8 100644
--- a/app/code/Magento/Widget/Model/Template/Filter.php
+++ b/app/code/Magento/Widget/Model/Template/Filter.php
@@ -21,7 +21,7 @@ class Filter extends \Magento\Cms\Model\Template\Filter
 
     /**
      * @param \Magento\Framework\Stdlib\String $string
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Escaper $escaper
      * @param \Magento\Framework\View\Asset\Repository $assetRepo
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
@@ -36,7 +36,7 @@ class Filter extends \Magento\Cms\Model\Template\Filter
      */
     public function __construct(
         \Magento\Framework\Stdlib\String $string,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Escaper $escaper,
         \Magento\Framework\View\Asset\Repository $assetRepo,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
diff --git a/app/code/Magento/Wishlist/Controller/Index/Add.php b/app/code/Magento/Wishlist/Controller/Index/Add.php
index 0be01dfee72..7b45de5f6fd 100644
--- a/app/code/Magento/Wishlist/Controller/Index/Add.php
+++ b/app/code/Magento/Wishlist/Controller/Index/Add.php
@@ -127,7 +127,7 @@ class Add extends Action\Action implements IndexInterface
             );
         } catch (\Exception $e) {
             $this->messageManager->addError(__('An error occurred while adding item to wish list.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
 
         $this->_redirect('*', ['wishlist_id' => $wishlist->getId()]);
diff --git a/app/code/Magento/Wishlist/Controller/Index/Configure.php b/app/code/Magento/Wishlist/Controller/Index/Configure.php
index 0ff51f62b57..56e56caff33 100644
--- a/app/code/Magento/Wishlist/Controller/Index/Configure.php
+++ b/app/code/Magento/Wishlist/Controller/Index/Configure.php
@@ -99,7 +99,7 @@ class Configure extends Action\Action implements IndexInterface
             return;
         } catch (\Exception $e) {
             $this->messageManager->addError(__('We can\'t configure the product.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             $this->_redirect('*');
             return;
         }
diff --git a/app/code/Magento/Wishlist/Controller/Index/Update.php b/app/code/Magento/Wishlist/Controller/Index/Update.php
index c64ae78ed22..40c1e7dbee4 100644
--- a/app/code/Magento/Wishlist/Controller/Index/Update.php
+++ b/app/code/Magento/Wishlist/Controller/Index/Update.php
@@ -94,7 +94,7 @@ class Update extends Action\Action implements IndexInterface
                     try {
                         $item->delete();
                     } catch (\Exception $e) {
-                        $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+                        $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
                         $this->messageManager->addError(__('Can\'t delete item from wishlist'));
                     }
                 }
diff --git a/app/code/Magento/Wishlist/Controller/Index/UpdateItemOptions.php b/app/code/Magento/Wishlist/Controller/Index/UpdateItemOptions.php
index 46057776574..8d6046d6e93 100644
--- a/app/code/Magento/Wishlist/Controller/Index/UpdateItemOptions.php
+++ b/app/code/Magento/Wishlist/Controller/Index/UpdateItemOptions.php
@@ -99,7 +99,7 @@ class UpdateItemOptions extends Action\Action implements IndexInterface
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
             $this->messageManager->addError(__('An error occurred while updating wish list.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->critical($e);
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
         }
         $this->_redirect('*/*', ['wishlist_id' => $wishlist->getId()]);
     }
diff --git a/app/code/Magento/Wishlist/Model/ItemCarrier.php b/app/code/Magento/Wishlist/Model/ItemCarrier.php
index 5f843995d11..a492568b03d 100644
--- a/app/code/Magento/Wishlist/Model/ItemCarrier.php
+++ b/app/code/Magento/Wishlist/Model/ItemCarrier.php
@@ -9,7 +9,7 @@ use Magento\Checkout\Helper\Cart as CartHelper;
 use Magento\Checkout\Model\Cart;
 use Magento\Customer\Model\Session;
 use Magento\Framework\App\Response\RedirectInterface;
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 use Magento\Framework\Message\ManagerInterface as MessageManager;
 use Magento\Framework\UrlInterface;
 use Magento\Wishlist\Helper\Data as WishlistHelper;
@@ -32,7 +32,7 @@ class ItemCarrier
     protected $cart;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
diff --git a/app/code/Magento/Wishlist/Model/Resource/Item/Collection.php b/app/code/Magento/Wishlist/Model/Resource/Item/Collection.php
index 73bfe66eedf..8ab2536a38a 100644
--- a/app/code/Magento/Wishlist/Model/Resource/Item/Collection.php
+++ b/app/code/Magento/Wishlist/Model/Resource/Item/Collection.php
@@ -131,7 +131,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration
@@ -153,7 +153,7 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration,
diff --git a/app/code/Magento/Wishlist/Model/Resource/Item/Collection/Grid.php b/app/code/Magento/Wishlist/Model/Resource/Item/Collection/Grid.php
index c785b0fff90..06c7bd3b58e 100644
--- a/app/code/Magento/Wishlist/Model/Resource/Item/Collection/Grid.php
+++ b/app/code/Magento/Wishlist/Model/Resource/Item/Collection/Grid.php
@@ -19,7 +19,7 @@ class Grid extends \Magento\Wishlist\Model\Resource\Item\Collection
 
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration
@@ -42,7 +42,7 @@ class Grid extends \Magento\Wishlist\Model\Resource\Item\Collection
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration,
diff --git a/dev/tests/functional/lib/Mtf/Util/Generate/Repository/TableCollection.php b/dev/tests/functional/lib/Mtf/Util/Generate/Repository/TableCollection.php
index 940de6bd0ff..f5c9bcbe2d5 100644
--- a/dev/tests/functional/lib/Mtf/Util/Generate/Repository/TableCollection.php
+++ b/dev/tests/functional/lib/Mtf/Util/Generate/Repository/TableCollection.php
@@ -21,7 +21,7 @@ class TableCollection extends AbstractCollection
     /**
      * @constructor
      * @param \Magento\Core\Model\EntityFactory $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param null $connection
@@ -30,7 +30,7 @@ class TableCollection extends AbstractCollection
      */
     public function __construct(
         \Magento\Core\Model\EntityFactory $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         $connection = null,
diff --git a/dev/tests/integration/framework/Magento/TestFramework/Application.php b/dev/tests/integration/framework/Magento/TestFramework/Application.php
index 17caa1db0b1..5ecbb875d99 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/Application.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/Application.php
@@ -272,10 +272,10 @@ class Application
         $objectManager->removeSharedInstance('Magento\Framework\Filesystem');
         $objectManager->addSharedInstance($filesystem, 'Magento\Framework\Filesystem');
 
-        /** @var \Magento\Framework\Logger $logger */
+        /** @var \Psr\Log\LoggerInterface $logger */
         $logger = $objectManager->get('Magento\TestFramework\ErrorLog\Logger');
-        $objectManager->removeSharedInstance('Magento\Framework\Logger');
-        $objectManager->addSharedInstance($logger, 'Magento\Framework\Logger');
+        $objectManager->removeSharedInstance('Psr\Log\LoggerInterface');
+        $objectManager->addSharedInstance($logger, 'Psr\Log\LoggerInterface');
 
         Helper\Bootstrap::setObjectManager($objectManager);
 
diff --git a/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Listener.php b/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Listener.php
index a74645c54ae..ce2720accac 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Listener.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Listener.php
@@ -72,7 +72,7 @@ class Listener implements \PHPUnit_Framework_TestListener
      */
     public function startTest(\PHPUnit_Framework_Test $test)
     {
-        $this->logger = Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Logger');
+        $this->logger = Helper\Bootstrap::getObjectManager()->get('Psr\Log\LoggerInterface');
         $this->logger->clearMessages();
     }
 
diff --git a/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Logger.php b/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Logger.php
index 6cef1344d10..1b52381998e 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Logger.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Logger.php
@@ -4,7 +4,7 @@
  */
 namespace Magento\TestFramework\ErrorLog;
 
-class Logger extends \Magento\Framework\Logger
+class Logger extends \Psr\Log\LoggerInterface
 {
     /** @var array */
     protected $messages = [];
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Model/SessionTest.php b/dev/tests/integration/testsuite/Magento/Backend/Model/SessionTest.php
index 1b8db05de46..8c49a3d8589 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Model/SessionTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Model/SessionTest.php
@@ -16,7 +16,7 @@ class SessionTest extends \PHPUnit_Framework_TestCase
         if (array_key_exists('adminhtml', $_SESSION)) {
             unset($_SESSION['adminhtml']);
         }
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface', [], [], '', false);
         \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
             'Magento\Backend\Model\Session',
             [$logger]
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Type/AbstractTypeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Type/AbstractTypeTest.php
index cb7cc49ea3c..47a3fca5749 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Type/AbstractTypeTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/Type/AbstractTypeTest.php
@@ -31,7 +31,7 @@ class AbstractTypeTest extends \PHPUnit_Framework_TestCase
         $fileStorageDb = $this->getMock('Magento\Core\Helper\File\Storage\Database', [], [], '', false);
         $filesystem = $this->getMock('Magento\Framework\Filesystem', [], [], '', false);
         $registry = $this->getMock('Magento\Framework\Registry', [], [], '', false);
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface', [], [], '', false);
         $this->_model = $this->getMockForAbstractClass(
             'Magento\Catalog\Model\Product\Type\AbstractType',
             [
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/AddressTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/AddressTest.php
index 75f463af759..2ff68a63b48 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Controller/AddressTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/AddressTest.php
@@ -14,7 +14,7 @@ class AddressTest extends \Magento\TestFramework\TestCase\AbstractController
     protected function setUp()
     {
         parent::setUp();
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface', [], [], '', false);
         $session = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
             'Magento\Customer\Model\Session',
             [$logger]
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Model/Resource/Db/Collection/AbstractTest.php b/dev/tests/integration/testsuite/Magento/Framework/Model/Resource/Db/Collection/AbstractTest.php
index ecfd7fa158d..cbf2052f709 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Model/Resource/Db/Collection/AbstractTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Model/Resource/Db/Collection/AbstractTest.php
@@ -43,7 +43,7 @@ class AbstractTest extends \PHPUnit_Framework_TestCase
         $entityFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
             'Magento\Core\Model\EntityFactory'
         );
-        $logger = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Logger');
+        $logger = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Psr\Log\LoggerInterface');
 
         $this->_model = $this->getMockForAbstractClass(
             'Magento\Framework\Model\Resource\Db\Collection\AbstractCollection',
diff --git a/dev/tests/integration/testsuite/Magento/Multishipping/Controller/CheckoutTest.php b/dev/tests/integration/testsuite/Magento/Multishipping/Controller/CheckoutTest.php
index 87bf4d582e6..9e25b21ee91 100644
--- a/dev/tests/integration/testsuite/Magento/Multishipping/Controller/CheckoutTest.php
+++ b/dev/tests/integration/testsuite/Magento/Multishipping/Controller/CheckoutTest.php
@@ -31,7 +31,7 @@ class CheckoutTest extends \Magento\TestFramework\TestCase\AbstractController
             ->setQuoteId($quote->getId());
 
         $formKey = $this->_objectManager->get('Magento\Framework\Data\Form\FormKey');
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface', [], [], '', false);
 
         /** @var $session \Magento\Customer\Model\Session */
         $session = Bootstrap::getObjectManager()->create('Magento\Customer\Model\Session', [$logger]);
diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Model/VoidTest.php b/dev/tests/integration/testsuite/Magento/Paypal/Model/VoidTest.php
index ef9a3150b0a..cb860a2a8f2 100644
--- a/dev/tests/integration/testsuite/Magento/Paypal/Model/VoidTest.php
+++ b/dev/tests/integration/testsuite/Magento/Paypal/Model/VoidTest.php
@@ -17,8 +17,8 @@ class VoidTest extends \PHPUnit_Framework_TestCase
         $moduleList = $objectManager->get('Magento\Framework\Module\ModuleListInterface');
         $paymentData = $objectManager->get('Magento\Payment\Helper\Data');
         $scopeConfig = $objectManager->get('Magento\Framework\App\Config\ScopeConfigInterface');
-        $logger = $objectManager->get('Magento\Framework\Logger');
-        $logAdapterFactory = $objectManager->get('Magento\Framework\Logger\AdapterFactory');
+        $logger = $objectManager->get('Psr\Log\LoggerInterface');
+        $logAdapterFactory = $objectManager->get('Psr\Log\LoggerInterface\AdapterFactory');
         $localeDate = $objectManager->get('Magento\Framework\Stdlib\DateTime\TimezoneInterface');
         $centinelService = $objectManager->get('Magento\Centinel\Model\Service');
         $storeManager = $objectManager->get('Magento\Store\Model\StoreManagerInterface');
diff --git a/dev/tests/integration/testsuite/Magento/Sendfriend/Block/SendTest.php b/dev/tests/integration/testsuite/Magento/Sendfriend/Block/SendTest.php
index c0f83653175..2e88e9f1fd6 100644
--- a/dev/tests/integration/testsuite/Magento/Sendfriend/Block/SendTest.php
+++ b/dev/tests/integration/testsuite/Magento/Sendfriend/Block/SendTest.php
@@ -53,7 +53,7 @@ class SendTest extends \PHPUnit_Framework_TestCase
      */
     public function testGetCustomerFieldFromSession($field, $value)
     {
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface', [], [], '', false);
         /** @var $session \Magento\Customer\Model\Session */
         $session = Bootstrap::getObjectManager()->create('Magento\Customer\Model\Session', [$logger]);
         /** @var \Magento\Customer\Api\AccountManagementInterface $service */
diff --git a/dev/tests/integration/testsuite/Magento/Translation/Model/InlineParserTest.php b/dev/tests/integration/testsuite/Magento/Translation/Model/InlineParserTest.php
index 22e3403aa81..21aca63de45 100644
--- a/dev/tests/integration/testsuite/Magento/Translation/Model/InlineParserTest.php
+++ b/dev/tests/integration/testsuite/Magento/Translation/Model/InlineParserTest.php
@@ -62,7 +62,7 @@ class InlineParserTest extends \PHPUnit_Framework_TestCase
         } catch (\Exception $e) {
             $model->delete();
             \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
-                ->get('Magento\Framework\Logger')
+                ->get('Psr\Log\LoggerInterface')
                 ->critical($e);
         }
     }
diff --git a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/IndexTest.php b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/IndexTest.php
index 3fea90233aa..26cb4a3747a 100644
--- a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/IndexTest.php
+++ b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/IndexTest.php
@@ -24,7 +24,7 @@ class IndexTest extends \Magento\TestFramework\TestCase\AbstractController
     protected function setUp()
     {
         parent::setUp();
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface', [], [], '', false);
         $this->_customerSession = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
             'Magento\Customer\Model\Session',
             [$logger]
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
index 68e501b6893..b80740de2d0 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
@@ -1724,7 +1724,7 @@ return [
     ['Magento\Adminhtml\Block\Report\Wishlist', 'Magento\Reports\Block\Adminhtml\Wishlist'],
     ['Magento\Backend\Helper\Addresses'],
     ['Magento\Core\Model\Cookie', 'Magento\Framework\Stdlib\Cookie'],
-    ['Magento\Core\Model\Logger', 'Magento\Framework\Logger'],
+    ['Magento\Core\Model\Logger', 'Psr\Log\LoggerInterface'],
     ['Magento\Core\Block\Template\Context', 'Magento\Framework\View\Element\Template\Context'],
     ['Magento\Page\Block\Template\Container'],
     ['Magento\Page\Block\Redirect', 'Magento\Framework\View\Element\Redirect'],
@@ -1980,7 +1980,7 @@ return [
     ['Magento\Core\Model\Image\Adapter\Config', 'Magento\Framework\Image\Adapter\Config'],
     ['Magento\Core\Model\AbstractShell', 'Magento\Framework\App\AbstractShell'],
     ['Magento\Core\Model\Calculator', 'Magento\Framework\Math\Calculator'],
-    ['Magento\Core\Model\Log\Adapter', 'Magento\Framework\Logger\Adapter'],
+    ['Magento\Core\Model\Log\Adapter', 'Psr\Log\LoggerInterface\Adapter'],
     ['Magento\Core\Model\Input\Filter', 'Magento\Framework\Filter\Input'],
     ['Magento\Core\Model\Input\Filter\MaliciousCode', 'Magento\Framework\Filter\Input\MaliciousCode'],
     ['Magento\Core\Model\Option\ArrayInterface', 'Magento\Framework\Option\ArrayInterface'],
@@ -2330,7 +2330,7 @@ return [
     ['Magento\Locale', 'Magento\Framework\Locale'],
     ['Magento\LocaleFactory', 'Magento\Framework\LocaleFactory'],
     ['Magento\LocaleInterface', 'Magento\Framework\LocaleInterface'],
-    ['Magento\Logger', 'Magento\Framework\Logger'],
+    ['Magento\Logger', 'Psr\Log\LoggerInterface'],
     ['Magento\Phrase', 'Magento\Framework\Phrase'],
     ['Magento\Pear', 'Magento\Framework\Pear'],
     [
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_namespaces.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_namespaces.php
index 6892d99ff7d..469e282ce54 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_namespaces.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_namespaces.php
@@ -28,7 +28,7 @@ return [
     ['Magento\Phrase', 'Magento\Framework\Phrase'],
     ['Magento\Locale', 'Magento\Framework\Locale'],
     ['Magento\Message', 'Magento\Framework\Message'],
-    ['Magento\Logger', 'Magento\Framework\Logger'],
+    ['Magento\Logger', 'Psr\Log\LoggerInterface'],
     ['Magento\Error', 'Magento\Framework\Error'],
     ['Magento\Filter', 'Magento\Framework\Filter'],
     ['Magento\DomDocument', 'Magento\Framework\DomDocument'],
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_properties.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_properties.php
index 06922811fcf..9edcd2c881a 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_properties.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_properties.php
@@ -22,7 +22,7 @@ return [
     ['_childGroups', 'Magento\Core\Block\AbstractBlock'],
     ['_combineHistory'],
     ['_config', 'Magento\Core\Model\Design\Package'],
-    ['_config', 'Magento\Framework\Logger', '_dirs'],
+    ['_config', 'Psr\Log\LoggerInterface', '_dirs'],
     ['_config', 'Magento\Core\Model\Resource\Setup'],
     ['_configModel', 'Magento\Backend\Model\Menu\AbstractDirector'],
     ['_connectionConfig', 'Magento\Core\Model\Resource\Setup'],
diff --git a/dev/tests/unit/framework/Magento/Test/Block/Adminhtml.php b/dev/tests/unit/framework/Magento/Test/Block/Adminhtml.php
index 8080328c0f1..865cc78c1d9 100644
--- a/dev/tests/unit/framework/Magento/Test/Block/Adminhtml.php
+++ b/dev/tests/unit/framework/Magento/Test/Block/Adminhtml.php
@@ -82,7 +82,7 @@ class Adminhtml extends \PHPUnit_Framework_TestCase
         $this->_urlMock             = $this->_makeMock('Magento\Framework\UrlInterface');
         $this->_eventManagerMock    = $this->_makeMock('Magento\Framework\Event\ManagerInterface');
         $this->_controllerMock      = $this->_makeMock('Magento\Framework\App\FrontController');
-        $this->_loggerMock          = $this->_makeMock('Magento\Framework\Logger');
+        $this->_loggerMock          = $this->_makeMock('Psr\Log\LoggerInterface');
         $this->_filesystemMock      = $this->_makeMock('Magento\Framework\Filesystem');
         $this->_cacheMock           = $this->_makeMock('Magento\Framework\App\CacheInterface');
         $this->_scopeConfigMock     = $this->_makeMock('Magento\Framework\App\Config\ScopeConfigInterface');
diff --git a/dev/tests/unit/testsuite/Magento/Authorization/Model/Acl/AclRetrieverTest.php b/dev/tests/unit/testsuite/Magento/Authorization/Model/Acl/AclRetrieverTest.php
index 72906ff1a52..a1e39651e62 100644
--- a/dev/tests/unit/testsuite/Magento/Authorization/Model/Acl/AclRetrieverTest.php
+++ b/dev/tests/unit/testsuite/Magento/Authorization/Model/Acl/AclRetrieverTest.php
@@ -165,7 +165,7 @@ class AclRetrieverTest extends \PHPUnit_Framework_TestCase
             $aclBuilderMock,
             $roleCollectionFactoryMock,
             $rulesCollectionFactoryMock,
-            $this->getMock('Magento\Framework\Logger', [], [], '', false)
+            $this->getMock('Psr\Log\LoggerInterface')
         );
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/Dashboard/TunnelTest.php b/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/Dashboard/TunnelTest.php
index 7c5a367fbfb..58b3541dd4c 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/Dashboard/TunnelTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/Dashboard/TunnelTest.php
@@ -142,11 +142,11 @@ class TunnelTest extends \PHPUnit_Framework_TestCase
             ->method('create')
             ->with('Magento\Framework\HTTP\ZendClient')
             ->will($this->throwException($exceptionMock));
-        $loggerMock = $this->getMock('Magento\Framework\Logger', ['critical'], [], '', false);
+        $loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $loggerMock->expects($this->once())->method('critical')->with($exceptionMock);
         $this->_objectManager->expects($this->at(2))
             ->method('get')
-            ->with('Magento\Framework\Logger')
+            ->with('Psr\Log\LoggerInterface')
             ->will($this->returnValue($loggerMock));
 
         $controller = $this->_factory($this->_request, $this->_response);
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/BaseurlTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/BaseurlTest.php
index 4434ebbb8ee..dc5dd79a794 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/BaseurlTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/BaseurlTest.php
@@ -11,7 +11,7 @@ class BaseurlTest extends \PHPUnit_Framework_TestCase
         $eventDispatcher = $this->getMock('Magento\Framework\Event\ManagerInterface', [], [], '', false);
         $appState = $this->getMock('Magento\Framework\App\State', [], [], '', false);
         $cacheManager = $this->getMock('Magento\Framework\App\CacheInterface');
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface');
         $actionValidatorMock = $this->getMock(
             'Magento\Framework\Model\ActionValidator\RemoveAction',
             [],
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/SecureTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/SecureTest.php
index d1a38f433c5..8d8c30a7dd7 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/SecureTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Backend/SecureTest.php
@@ -11,7 +11,7 @@ class SecureTest extends \PHPUnit_Framework_TestCase
         $eventDispatcher = $this->getMock('Magento\Framework\Event\ManagerInterface', [], [], '', false);
         $appState = $this->getMock('Magento\Framework\App\State', [], [], '', false);
         $cacheManager = $this->getMock('Magento\Framework\App\CacheInterface');
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface');
         $actionValidatorMock = $this->getMock(
             '\Magento\Framework\Model\ActionValidator\RemoveAction',
             [],
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Source/Admin/PageTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Source/Admin/PageTest.php
index 1fff5d361bb..7e7fbee400d 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Source/Admin/PageTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Config/Source/Admin/PageTest.php
@@ -32,7 +32,7 @@ class PageTest extends \PHPUnit_Framework_TestCase
 
     protected function setUp()
     {
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface');
         $this->_menuModel = new \Magento\Backend\Model\Menu($logger);
         $this->_menuSubModel = new \Magento\Backend\Model\Menu($logger);
 
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/BuilderTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/BuilderTest.php
index 25e7413aa29..b4880b7154c 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/BuilderTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/BuilderTest.php
@@ -27,7 +27,7 @@ class BuilderTest extends \PHPUnit_Framework_TestCase
         $this->_menuMock = $this->getMock(
             'Magento\Backend\Model\Menu',
             [],
-            [$this->getMock('Magento\Framework\Logger', [], [], '', false)]
+            [$this->getMock('Psr\Log\LoggerInterface')]
         );
 
         $this->_model = new \Magento\Backend\Model\Menu\Builder($this->_factoryMock, $this->_menuMock);
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/ConfigTest.php
index e3aa7a064ac..bc5f314e061 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/ConfigTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/ConfigTest.php
@@ -94,18 +94,12 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
             false
         );
 
-        $this->_logger = $this->getMock(
-            'Magento\Framework\Logger',
-            ['addStoreLog', 'log', 'critical'],
-            [],
-            '',
-            false
-        );
+        $this->_logger = $this->getMock('Psr\Log\LoggerInterface');
 
         $this->_menuMock = $this->getMock(
             'Magento\Backend\Model\Menu',
             [],
-            [$this->getMock('Magento\Framework\Logger', [], [], '', false)]
+            [$this->getMock('Psr\Log\LoggerInterface')]
         );
 
         $this->_menuBuilderMock = $this->getMock('Magento\Backend\Model\Menu\Builder', [], [], '', false);
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/Director/DirectorTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/Director/DirectorTest.php
index 452d3d5071f..696043006c9 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/Director/DirectorTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/Director/DirectorTest.php
@@ -38,13 +38,7 @@ class DirectorTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $this->_builderMock = $this->getMock('Magento\Backend\Model\Menu\Builder', [], [], '', false);
-        $this->_logger = $this->getMock(
-            'Magento\Framework\Logger',
-            ['debug', 'info', 'critical'],
-            [],
-            '',
-            false
-        );
+        $this->_logger = $this->getMock('Psr\Log\LoggerInterface');
         $this->_commandMock = $this->getMock(
             'Magento\Backend\Model\Menu\Builder\AbstractCommand',
             ['getId', '_execute', 'execute', 'chain'],
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/Filter/IteratorTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/Filter/IteratorTest.php
index a1f3c38ae4a..080cd564b17 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/Filter/IteratorTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/Filter/IteratorTest.php
@@ -38,7 +38,7 @@ class IteratorTest extends \PHPUnit_Framework_TestCase
         $this->_items['item3']->expects($this->any())->method('isDisabled')->will($this->returnValue(false));
         $this->_items['item3']->expects($this->any())->method('isAllowed')->will($this->returnValue(false));
 
-        $loggerMock = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $loggerMock = $this->getMock('Psr\Log\LoggerInterface');
 
         $this->_menuModel = new \Magento\Backend\Model\Menu($loggerMock);
         $this->_filterIteratorModel = new \Magento\Backend\Model\Menu\Filter\Iterator(
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/ItemTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/ItemTest.php
index e7ce46a61dc..30d52ab0419 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/ItemTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/ItemTest.php
@@ -217,7 +217,7 @@ class ItemTest extends \PHPUnit_Framework_TestCase
         $menuMock = $this->getMock(
             'Magento\Backend\Model\Menu',
             [],
-            [$this->getMock('Magento\Framework\Logger', [], [], '', false)]
+            [$this->getMock('Psr\Log\LoggerInterface')]
         );
 
         $this->_menuFactoryMock->expects($this->once())->method('create')->will($this->returnValue($menuMock));
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/MenuTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/MenuTest.php
index 3812e291ded..f788228c365 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/MenuTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/MenuTest.php
@@ -12,7 +12,7 @@ class MenuTest extends \PHPUnit_Framework_TestCase
     protected $_model;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -32,7 +32,7 @@ class MenuTest extends \PHPUnit_Framework_TestCase
         $this->_items['item3'] = $this->getMock('Magento\Backend\Model\Menu\Item', [], [], '', false);
         $this->_items['item3']->expects($this->any())->method('getId')->will($this->returnValue('item3'));
 
-        $this->_logger = $this->getMock('Magento\Framework\Logger', ['info'], [], '', false);
+        $this->_logger = $this->getMock('Psr\Log\LoggerInterface');
 
         $this->_model = new \Magento\Backend\Model\Menu($this->_logger);
     }
@@ -47,14 +47,6 @@ class MenuTest extends \PHPUnit_Framework_TestCase
 
     public function testAddDoLogAddAction()
     {
-        $this->_logger->expects(
-            $this->once()
-        )->method(
-            'info'
-        )->with(
-            $this->equalTo(sprintf('Add of item with id %s was processed', $this->_items['item1']->getId()))
-        );
-
         $this->_model->add($this->_items['item1']);
     }
 
@@ -136,7 +128,7 @@ class MenuTest extends \PHPUnit_Framework_TestCase
         $subMenu = $this->getMock(
             'Magento\Backend\Model\Menu',
             [],
-            [$this->getMock('Magento\Framework\Logger', [], [], '', false)]
+            [$this->getMock('Psr\Log\LoggerInterface')]
         );
         $subMenu->expects($this->once())->method("add")->with($this->_items['item3']);
 
@@ -189,7 +181,7 @@ class MenuTest extends \PHPUnit_Framework_TestCase
         $menuMock = $this->getMock(
             'Magento\Backend\Model\Menu',
             [],
-            [$this->getMock('Magento\Framework\Logger', [], [], '', false)]
+            [$this->getMock('Psr\Log\LoggerInterface')]
         );
         $menuMock->expects($this->once())->method('remove')->with($this->equalTo('item2'));
 
@@ -203,15 +195,6 @@ class MenuTest extends \PHPUnit_Framework_TestCase
     public function testRemoveDoLogRemoveAction()
     {
         $this->_model->add($this->_items['item1']);
-
-        $this->_logger->expects(
-            $this->once()
-        )->method(
-            'info'
-        )->with(
-            $this->equalTo(sprintf('Remove on item with id %s was processed', $this->_items['item1']->getId()))
-        );
-
         $this->_model->remove('item1');
     }
 
@@ -335,7 +318,6 @@ class MenuTest extends \PHPUnit_Framework_TestCase
     public function testSerialize()
     {
         $this->assertNotEmpty($this->_model->serialize());
-        $this->_logger->expects($this->once())->method('info');
         $this->_model->add($this->_items['item1']);
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/UrlTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/UrlTest.php
index a06bdd16060..74d4b10a1eb 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/UrlTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/UrlTest.php
@@ -77,7 +77,7 @@ class UrlTest extends \PHPUnit_Framework_TestCase
         $this->_menuMock = $this->getMock(
             'Magento\Backend\Model\Menu',
             [],
-            [$this->getMock('Magento\Framework\Logger', [], [], '', false)]
+            [$this->getMock('Psr\Log\LoggerInterface')]
         );
 
         $this->_menuConfigMock = $this->getMock('Magento\Backend\Model\Menu\Config', [], [], '', false);
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/BuilderTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/BuilderTest.php
index aea23a0b5ca..cc5bec71073 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/BuilderTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/BuilderTest.php
@@ -43,7 +43,7 @@ class BuilderTest extends \PHPUnit_Framework_TestCase
 
     protected function setUp()
     {
-        $this->loggerMock = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $this->productFactoryMock = $this->getMock('Magento\Catalog\Model\ProductFactory', ['create'], [], '', false);
         $this->registryMock = $this->getMock('Magento\Framework\Registry', [], [], '', false);
         $this->wysiwygConfigMock = $this->getMock(
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Type/SimpleTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Type/SimpleTest.php
index 20896835474..716996ecadc 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Type/SimpleTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Type/SimpleTest.php
@@ -21,7 +21,7 @@ class SimpleTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
         $coreRegistry = $this->getMock('Magento\Framework\Registry', [], [], '', false);
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface');
         $productFactoryMock = $this->getMock('Magento\Catalog\Model\ProductFactory', [], [], '', false);
         $this->_model = $objectHelper->getObject(
             'Magento\Catalog\Model\Product\Type\Simple',
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Type/VirtualTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Type/VirtualTest.php
index b8f01b46c86..3bcc6208d14 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Type/VirtualTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Type/VirtualTest.php
@@ -21,7 +21,7 @@ class VirtualTest extends \PHPUnit_Framework_TestCase
         $filesystem = $this->getMockBuilder('Magento\Framework\Filesystem')
             ->disableOriginalConstructor()
             ->getMock();
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface');
         $productFactoryMock = $this->getMock('Magento\Catalog\Model\ProductFactory', [], [], '', false);
         $this->_model = $objectHelper->getObject(
             'Magento\Catalog\Model\Product\Type\Virtual',
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Product/Link/Product/CollectionTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Product/Link/Product/CollectionTest.php
index b49d56d50d0..f57e9360912 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Product/Link/Product/CollectionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Product/Link/Product/CollectionTest.php
@@ -76,7 +76,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $this->entityFactoryMock = $this->getMock('Magento\Core\Model\EntityFactory', [], [], '', false);
-        $this->loggerMock = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $this->fetchStrategyMock = $this->getMock('Magento\Framework\Data\Collection\Db\FetchStrategyInterface');
         $this->managerInterfaceMock = $this->getMock('Magento\Framework\Event\ManagerInterface');
         $this->configMock = $this->getMock('Magento\Eav\Model\Config', [], [], '', false);
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Product/Option/CollectionTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Product/Option/CollectionTest.php
index 878c7e23d45..cbaa9833206 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Product/Option/CollectionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Product/Option/CollectionTest.php
@@ -12,7 +12,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
     protected $collection;
 
     /**
-     * @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $loggerMock;
 
@@ -61,7 +61,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
         $this->entityFactoryMock = $this->getMock(
             'Magento\Core\Model\EntityFactory', ['create'], [], '', false
         );
-        $this->loggerMock = $this->getMock('Magento\Framework\Logger', ['log'], [], '', false);
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $this->fetchStrategyMock = $this->getMock(
             'Magento\Framework\Data\Collection\Db\FetchStrategy\Query', ['fetchAll'], [], '', false
         );
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Render/FinalPriceBoxTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Render/FinalPriceBoxTest.php
index f7b481eb9fe..930c7fcbd5b 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Render/FinalPriceBoxTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Render/FinalPriceBoxTest.php
@@ -41,7 +41,7 @@ class FinalPriceBoxTest extends \PHPUnit_Framework_TestCase
     protected $product;
 
     /**
-     * @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $logger;
 
@@ -74,7 +74,7 @@ class FinalPriceBoxTest extends \PHPUnit_Framework_TestCase
         $this->layout = $this->getMock('Magento\Framework\View\Layout', [], [], '', false);
 
         $this->priceBox = $this->getMock('Magento\Framework\Pricing\Render\PriceBox', [], [], '', false);
-        $this->logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $this->logger = $this->getMock('Psr\Log\LoggerInterface');
 
         $this->layout->expects($this->any())
             ->method('getBlock')
diff --git a/dev/tests/unit/testsuite/Magento/CatalogImportExport/Model/Import/Product/Type/OptionTest.php b/dev/tests/unit/testsuite/Magento/CatalogImportExport/Model/Import/Product/Type/OptionTest.php
index 00d68c8f780..f43f1498795 100644
--- a/dev/tests/unit/testsuite/Magento/CatalogImportExport/Model/Import/Product/Type/OptionTest.php
+++ b/dev/tests/unit/testsuite/Magento/CatalogImportExport/Model/Import/Product/Type/OptionTest.php
@@ -381,7 +381,7 @@ class OptionTest extends \PHPUnit_Framework_TestCase
             'Magento\Framework\Data\Collection\Db\FetchStrategyInterface',
             ['fetchAll']
         );
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface');
         $entityFactory = $this->getMock('Magento\Core\Model\EntityFactory', [], [], '', false);
 
         $optionCollection = $this->getMock(
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Model/Type/OnepageTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Model/Type/OnepageTest.php
index 7db6a77aa9e..29431583620 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Model/Type/OnepageTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Model/Type/OnepageTest.php
@@ -28,7 +28,7 @@ class OnepageTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Customer\Model\Url|\PHPUnit_Framework_MockObject_MockObject */
     protected $customerUrlMock;
 
-    /** @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject */
+    /** @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject */
     protected $loggerMock;
 
     /** @var \Magento\Checkout\Model\Session|\PHPUnit_Framework_MockObject_MockObject */
@@ -113,7 +113,7 @@ class OnepageTest extends \PHPUnit_Framework_TestCase
         $this->eventManagerMock = $this->getMock('Magento\Framework\Event\ManagerInterface');
         $this->checkoutHelperMock = $this->getMock('Magento\Checkout\Helper\Data', [], [], '', false);
         $this->customerUrlMock = $this->getMock('Magento\Customer\Model\Url', [], [], '', false);
-        $this->loggerMock = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $this->checkoutSessionMock = $this->getMock(
             'Magento\Checkout\Model\Session',
             ['getLastOrderId', 'getQuote', 'setStepData', 'getStepData'],
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Address/Billing/WriteServiceTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Address/Billing/WriteServiceTest.php
index 688ceb111d5..46358567666 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Address/Billing/WriteServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Address/Billing/WriteServiceTest.php
@@ -69,7 +69,7 @@ class WriteServiceTest extends \PHPUnit_Framework_TestCase
             '\Magento\Checkout\Service\V1\Address\Converter', [], [], '', false
         );
 
-        $this->loggerMock = $this->getMock('\Magento\Framework\Logger', [], [], '', false);
+        $this->loggerMock = $this->getMock('\Psr\Log\LoggerInterface', [], [], '', false);
 
         $this->service = new \Magento\Checkout\Service\V1\Address\Billing\WriteService(
             $this->quoteRepositoryMock,
diff --git a/dev/tests/unit/testsuite/Magento/Cms/Model/Resource/PageCriteriaMapperTest.php b/dev/tests/unit/testsuite/Magento/Cms/Model/Resource/PageCriteriaMapperTest.php
index 1affb8ae653..1db747a9106 100644
--- a/dev/tests/unit/testsuite/Magento/Cms/Model/Resource/PageCriteriaMapperTest.php
+++ b/dev/tests/unit/testsuite/Magento/Cms/Model/Resource/PageCriteriaMapperTest.php
@@ -10,7 +10,7 @@ namespace Magento\Cms\Model\Resource;
 class PageCriteriaMapperTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $loggerMock;
 
@@ -46,13 +46,7 @@ class PageCriteriaMapperTest extends \PHPUnit_Framework_TestCase
      */
     protected function setUp()
     {
-        $this->loggerMock = $this->getMock(
-            'Magento\Framework\Logger',
-            [],
-            [],
-            '',
-            false
-        );
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $this->fetchStrategyMock = $this->getMockForAbstractClass(
             'Magento\Framework\Data\Collection\Db\FetchStrategyInterface',
             [],
diff --git a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php
index 2f072bd8810..7f282cceff0 100644
--- a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php
+++ b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php
@@ -51,7 +51,7 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
         $coreRegistry = $this->getMock('Magento\Framework\Registry', [], [], '', false);
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface');
         $productFactoryMock = $this->getMock('Magento\Catalog\Model\ProductFactory', [], [], '', false);
         $this->_typeConfigurableFactory = $this->getMock(
             'Magento\ConfigurableProduct\Model\Resource\Product\Type\ConfigurableFactory',
diff --git a/dev/tests/unit/testsuite/Magento/Core/Model/File/Storage/Directory/DatabaseTest.php b/dev/tests/unit/testsuite/Magento/Core/Model/File/Storage/Directory/DatabaseTest.php
index ee220db6174..24c78c03786 100644
--- a/dev/tests/unit/testsuite/Magento/Core/Model/File/Storage/Directory/DatabaseTest.php
+++ b/dev/tests/unit/testsuite/Magento/Core/Model/File/Storage/Directory/DatabaseTest.php
@@ -55,7 +55,7 @@ class DatabaseTest extends \PHPUnit_Framework_TestCase
     protected $resourceDirectoryDatabaseMock;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $loggerMock;
 
@@ -106,7 +106,7 @@ class DatabaseTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $this->loggerMock = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
 
         $this->directoryFactoryMock->expects(
             $this->any()
diff --git a/dev/tests/unit/testsuite/Magento/Core/Model/File/Storage/MediaTest.php b/dev/tests/unit/testsuite/Magento/Core/Model/File/Storage/MediaTest.php
index 86d283fc25b..ae0ed046c2b 100644
--- a/dev/tests/unit/testsuite/Magento/Core/Model/File/Storage/MediaTest.php
+++ b/dev/tests/unit/testsuite/Magento/Core/Model/File/Storage/MediaTest.php
@@ -36,7 +36,7 @@ class MediaTest extends \PHPUnit_Framework_TestCase
 
     protected function setUp()
     {
-        $this->_loggerMock = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $this->_loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $this->_storageHelperMock = $this->getMock(
             'Magento\Core\Helper\File\Storage\Database',
             [],
diff --git a/dev/tests/unit/testsuite/Magento/Core/Model/Layout/MergeTest.php b/dev/tests/unit/testsuite/Magento/Core/Model/Layout/MergeTest.php
index e64c7edb5c8..028bec513f8 100644
--- a/dev/tests/unit/testsuite/Magento/Core/Model/Layout/MergeTest.php
+++ b/dev/tests/unit/testsuite/Magento/Core/Model/Layout/MergeTest.php
@@ -79,7 +79,7 @@ class MergeTest extends \PHPUnit_Framework_TestCase
 
         $this->_appState = $this->getMock('Magento\Framework\App\State', [], [], '', false);
 
-        $this->_logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $this->_logger = $this->getMock('Psr\Log\LoggerInterface');
 
         $this->_layoutValidator = $this->getMock(
             'Magento\Core\Model\Layout\Update\Validator',
diff --git a/dev/tests/unit/testsuite/Magento/Core/Model/Resource/File/Storage/FileTest.php b/dev/tests/unit/testsuite/Magento/Core/Model/Resource/File/Storage/FileTest.php
index 343573b5df6..5f61a0eddc9 100644
--- a/dev/tests/unit/testsuite/Magento/Core/Model/Resource/File/Storage/FileTest.php
+++ b/dev/tests/unit/testsuite/Magento/Core/Model/Resource/File/Storage/FileTest.php
@@ -36,7 +36,7 @@ class FileTest extends \PHPUnit_Framework_TestCase
      */
     protected function setUp()
     {
-        $this->loggerMock = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $this->filesystemMock = $this->getMock(
             'Magento\Framework\Filesystem',
             ['getDirectoryRead'],
diff --git a/dev/tests/unit/testsuite/Magento/Core/Model/Resource/Layout/Link/CollectionTest.php b/dev/tests/unit/testsuite/Magento/Core/Model/Resource/Layout/Link/CollectionTest.php
index 85a97321f60..d606ae998b9 100644
--- a/dev/tests/unit/testsuite/Magento/Core/Model/Resource/Layout/Link/CollectionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Core/Model/Resource/Layout/Link/CollectionTest.php
@@ -28,7 +28,7 @@ class CollectionTest extends \Magento\Core\Model\Resource\Layout\AbstractTestCas
 
         return new \Magento\Core\Model\Resource\Layout\Link\Collection(
             $this->getMock('Magento\Core\Model\EntityFactory', [], [], '', false),
-            $this->getMock('Magento\Framework\Logger', [], [], '', false),
+            $this->getMock('Psr\Log\LoggerInterface'),
             $this->getMockForAbstractClass('Magento\Framework\Data\Collection\Db\FetchStrategyInterface'),
             $eventManager,
             $this->getMock('Magento\Framework\Stdlib\DateTime', null, [], '', true),
diff --git a/dev/tests/unit/testsuite/Magento/Core/Model/Resource/Layout/Update/CollectionTest.php b/dev/tests/unit/testsuite/Magento/Core/Model/Resource/Layout/Update/CollectionTest.php
index 06ae56f3b04..34d7145aafd 100644
--- a/dev/tests/unit/testsuite/Magento/Core/Model/Resource/Layout/Update/CollectionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Core/Model/Resource/Layout/Update/CollectionTest.php
@@ -18,7 +18,7 @@ class CollectionTest extends \Magento\Core\Model\Resource\Layout\AbstractTestCas
 
         return new \Magento\Core\Model\Resource\Layout\Update\Collection(
             $this->getMock('Magento\Core\Model\EntityFactory', [], [], '', false),
-            $this->getMock('Magento\Framework\Logger', [], [], '', false),
+            $this->getMock('Psr\Log\LoggerInterface'),
             $this->getMockForAbstractClass('Magento\Framework\Data\Collection\Db\FetchStrategyInterface'),
             $eventManager,
             $this->getMock('Magento\Framework\Stdlib\DateTime', null, [], '', true),
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Model/Attribute/Data/PostcodeTest.php b/dev/tests/unit/testsuite/Magento/Customer/Model/Attribute/Data/PostcodeTest.php
index d5b34e20715..fd40eb5504a 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Model/Attribute/Data/PostcodeTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Model/Attribute/Data/PostcodeTest.php
@@ -31,7 +31,7 @@ class PostcodeTest extends \PHPUnit_Framework_TestCase
     private $localeResolverMock;
 
     /**
-     * @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     private $loggerMock;
 
@@ -41,8 +41,7 @@ class PostcodeTest extends \PHPUnit_Framework_TestCase
             ->getMock();
         $this->localeResolverMock = $this->getMockBuilder('Magento\Framework\Locale\ResolverInterface')
             ->getMock();
-        $this->loggerMock = $this->getMockBuilder('Magento\Framework\Logger')
-            ->disableOriginalConstructor()
+        $this->loggerMock = $this->getMockBuilder('Psr\Log\LoggerInterface')
             ->getMock();
         $this->directoryHelperMock = $this->getMockBuilder('Magento\Directory\Helper\Data')
             ->disableOriginalConstructor()
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Model/Customer/Attribute/Backend/BillingTest.php b/dev/tests/unit/testsuite/Magento/Customer/Model/Customer/Attribute/Backend/BillingTest.php
index 21d44a8283e..15a2fb85938 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Model/Customer/Attribute/Backend/BillingTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Model/Customer/Attribute/Backend/BillingTest.php
@@ -13,8 +13,8 @@ class BillingTest extends \PHPUnit_Framework_TestCase
 
     public function setUp()
     {
-        $logger = $this->getMockBuilder('Magento\Framework\Logger')->disableOriginalConstructor()->getMock();
-        /** @var \Magento\Framework\Logger $logger */
+        $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
+        /** @var \Psr\Log\LoggerInterface $logger */
         $this->testable = new Billing($logger);
     }
 
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Model/Customer/Attribute/Backend/ShippingTest.php b/dev/tests/unit/testsuite/Magento/Customer/Model/Customer/Attribute/Backend/ShippingTest.php
index 463632cb97d..c4dcd2f89ae 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Model/Customer/Attribute/Backend/ShippingTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Model/Customer/Attribute/Backend/ShippingTest.php
@@ -14,8 +14,8 @@ class ShippingTest extends \PHPUnit_Framework_TestCase
 
     public function setUp()
     {
-        $logger = $this->getMockBuilder('Magento\Framework\Logger')->disableOriginalConstructor()->getMock();
-        /** @var \Magento\Framework\Logger $logger */
+        $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
+        /** @var \Psr\Log\LoggerInterface $logger */
         $this->testable = new Shipping($logger);
     }
 
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Model/Metadata/Form/AbstractDataTest.php b/dev/tests/unit/testsuite/Magento/Customer/Model/Metadata/Form/AbstractDataTest.php
index 41b751c72a0..937392319dc 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Model/Metadata/Form/AbstractDataTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Model/Metadata/Form/AbstractDataTest.php
@@ -19,7 +19,7 @@ class AbstractDataTest extends \PHPUnit_Framework_TestCase
     /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Locale\ResolverInterface */
     protected $_localeResolverMock;
 
-    /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Logger */
+    /** @var \PHPUnit_Framework_MockObject_MockObject | \Psr\Log\LoggerInterface */
     protected $_loggerMock;
 
     /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Customer\Api\Data\AttributeMetadataInterface */
@@ -42,7 +42,7 @@ class AbstractDataTest extends \PHPUnit_Framework_TestCase
         $this->_localeResolverMock = $this->getMockBuilder(
             'Magento\Framework\Locale\ResolverInterface'
         )->disableOriginalConstructor()->getMock();
-        $this->_loggerMock = $this->getMockBuilder('Magento\Framework\Logger')->disableOriginalConstructor()->getMock();
+        $this->_loggerMock = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
         $this->_attributeMock = $this->getMock('Magento\Customer\Api\Data\AttributeMetadataInterface');
         $this->_value = 'VALUE';
         $this->_entityTypeCode = 'ENTITY_TYPE_CODE';
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Model/Metadata/Form/AbstractFormTestCase.php b/dev/tests/unit/testsuite/Magento/Customer/Model/Metadata/Form/AbstractFormTestCase.php
index 827aa69df61..eea536eb7e0 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Model/Metadata/Form/AbstractFormTestCase.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Model/Metadata/Form/AbstractFormTestCase.php
@@ -13,7 +13,7 @@ abstract class AbstractFormTestCase extends \PHPUnit_Framework_TestCase
     /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Locale\ResolverInterface */
     protected $localeResolverMock;
 
-    /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Logger */
+    /** @var \PHPUnit_Framework_MockObject_MockObject | \Psr\Log\LoggerInterface */
     protected $loggerMock;
 
     /** @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Customer\Api\Data\AttributeMetadataInterface */
@@ -23,7 +23,7 @@ abstract class AbstractFormTestCase extends \PHPUnit_Framework_TestCase
     {
         $this->localeMock = $this->getMockBuilder('Magento\Framework\Stdlib\DateTime\TimezoneInterface')->getMock();
         $this->localeResolverMock = $this->getMockBuilder('Magento\Framework\Locale\ResolverInterface')->getMock();
-        $this->loggerMock = $this->getMockBuilder('Magento\Framework\Logger')->disableOriginalConstructor()->getMock();
+        $this->loggerMock = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
         $this->attributeMetadataMock = $this->getMock('Magento\Customer\Api\Data\AttributeMetadataInterface');
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Directory/Model/PriceCurrencyTest.php b/dev/tests/unit/testsuite/Magento/Directory/Model/PriceCurrencyTest.php
index 6b644e2703f..52490c8b796 100644
--- a/dev/tests/unit/testsuite/Magento/Directory/Model/PriceCurrencyTest.php
+++ b/dev/tests/unit/testsuite/Magento/Directory/Model/PriceCurrencyTest.php
@@ -33,8 +33,7 @@ class PriceCurrencyTest extends \PHPUnit_Framework_TestCase
             ->setMethods(['create'])
             ->getMock();
 
-        $this->logger = $this->getMockBuilder('Magento\Framework\Logger')
-            ->disableOriginalConstructor()
+        $this->logger = $this->getMockBuilder('Psr\Log\LoggerInterface')
             ->getMock();
 
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
diff --git a/dev/tests/unit/testsuite/Magento/Directory/Model/Resource/Country/CollectionTest.php b/dev/tests/unit/testsuite/Magento/Directory/Model/Resource/Country/CollectionTest.php
index 0d46c4bec54..00158413afe 100644
--- a/dev/tests/unit/testsuite/Magento/Directory/Model/Resource/Country/CollectionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Directory/Model/Resource/Country/CollectionTest.php
@@ -35,7 +35,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
         $fetchStrategy = $this->getMockForAbstractClass('Magento\Framework\Data\Collection\Db\FetchStrategyInterface');
         $entityFactory = $this->getMock('Magento\Core\Model\EntityFactory', [], [], '', false);
         $scopeConfigMock = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface');
         $countryFactory = $this->getMock(
             'Magento\Directory\Model\Resource\CountryFactory',
             [],
diff --git a/dev/tests/unit/testsuite/Magento/Downloadable/Model/Product/TypeTest.php b/dev/tests/unit/testsuite/Magento/Downloadable/Model/Product/TypeTest.php
index c5ac347e6e3..2542ded8189 100644
--- a/dev/tests/unit/testsuite/Magento/Downloadable/Model/Product/TypeTest.php
+++ b/dev/tests/unit/testsuite/Magento/Downloadable/Model/Product/TypeTest.php
@@ -26,7 +26,7 @@ class TypeTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
         $coreRegistry = $this->getMock('Magento\Framework\Registry', [], [], '', false);
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface');
         $productFactoryMock = $this->getMock('Magento\Catalog\Model\ProductFactory', [], [], '', false);
         $sampleResFactory = $this->getMock('Magento\Downloadable\Model\Resource\SampleFactory', [], [], '', false);
         $linkResource = $this->getMock('Magento\Downloadable\Model\Resource\Link', [], [], '', false);
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/AbstractDataTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/AbstractDataTest.php
index 01669f34e3d..f1d427f3744 100644
--- a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/AbstractDataTest.php
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/AbstractDataTest.php
@@ -14,7 +14,7 @@ class AbstractDataTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $timezoneMock = $this->getMock('\Magento\Framework\Stdlib\DateTime\TimezoneInterface');
-        $loggerMock = $this->getMock('\Magento\Framework\Logger', [], [], '', false);
+        $loggerMock = $this->getMock('\Psr\Log\LoggerInterface', [], [], '', false);
         $localeResolverMock = $this->getMock('\Magento\Framework\Locale\ResolverInterface');
         $stringMock = $this->getMock('\Magento\Framework\Stdlib\String', [], [], '', false);
 
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/BooleanTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/BooleanTest.php
index 6b5d8843328..0c8ead39311 100644
--- a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/BooleanTest.php
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/BooleanTest.php
@@ -14,7 +14,7 @@ class BooleanTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $timezoneMock = $this->getMock('\Magento\Framework\Stdlib\DateTime\TimezoneInterface');
-        $loggerMock = $this->getMock('\Magento\Framework\Logger', [], [], '', false);
+        $loggerMock = $this->getMock('\Psr\Log\LoggerInterface', [], [], '', false);
         $localeResolverMock = $this->getMock('\Magento\Framework\Locale\ResolverInterface');
 
         $this->model = new Boolean($timezoneMock, $loggerMock, $localeResolverMock);
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/DateTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/DateTest.php
index 4932899f055..6bb94af2800 100644
--- a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/DateTest.php
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/DateTest.php
@@ -19,7 +19,7 @@ class DateTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $this->timezoneMock = $this->getMock('\Magento\Framework\Stdlib\DateTime\TimezoneInterface');
-        $loggerMock = $this->getMock('\Magento\Framework\Logger', [], [], '', false);
+        $loggerMock = $this->getMock('\Psr\Log\LoggerInterface', [], [], '', false);
         $localeResolverMock = $this->getMock('\Magento\Framework\Locale\ResolverInterface');
 
         $this->model = new Date($this->timezoneMock, $loggerMock, $localeResolverMock);
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/FileTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/FileTest.php
index 70370559083..1560e4e3048 100644
--- a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/FileTest.php
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/FileTest.php
@@ -24,7 +24,7 @@ class FileTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $timezoneMock = $this->getMock('\Magento\Framework\Stdlib\DateTime\TimezoneInterface');
-        $loggerMock = $this->getMock('\Magento\Framework\Logger', [], [], '', false);
+        $loggerMock = $this->getMock('\Psr\Log\LoggerInterface', [], [], '', false);
         $localeResolverMock = $this->getMock('\Magento\Framework\Locale\ResolverInterface');
         $this->urlEncoder = $this->getMock('Magento\Framework\Url\EncoderInterface', [], [], '', false);
         $this->fileValidatorMock = $this->getMock(
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/ImageTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/ImageTest.php
index 59cb2a0d147..626e8b99683 100644
--- a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/ImageTest.php
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/ImageTest.php
@@ -14,7 +14,7 @@ class ImageTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $timezoneMock = $this->getMock('\Magento\Framework\Stdlib\DateTime\TimezoneInterface');
-        $loggerMock = $this->getMock('\Magento\Framework\Logger', [], [], '', false);
+        $loggerMock = $this->getMock('\Psr\Log\LoggerInterface', [], [], '', false);
         $localeResolverMock = $this->getMock('\Magento\Framework\Locale\ResolverInterface');
         $urlEncoder = $this->getMock('Magento\Framework\Url\EncoderInterface', [], [], '', false);
         $fileValidatorMock = $this->getMock(
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/MultilineTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/MultilineTest.php
index 0e6e1e1f20f..7871eef64e5 100644
--- a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/MultilineTest.php
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/MultilineTest.php
@@ -19,7 +19,7 @@ class MultilineTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $timezoneMock = $this->getMock('\Magento\Framework\Stdlib\DateTime\TimezoneInterface');
-        $loggerMock = $this->getMock('\Magento\Framework\Logger', [], [], '', false);
+        $loggerMock = $this->getMock('\Psr\Log\LoggerInterface', [], [], '', false);
         $localeResolverMock = $this->getMock('\Magento\Framework\Locale\ResolverInterface');
         $this->stringMock = $this->getMock('\Magento\Framework\Stdlib\String', [], [], '', false);
 
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/MultiselectTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/MultiselectTest.php
index 6304d8fb153..969ebfcfd5d 100644
--- a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/MultiselectTest.php
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/MultiselectTest.php
@@ -14,7 +14,7 @@ class MultiselectTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $timezoneMock = $this->getMock('\Magento\Framework\Stdlib\DateTime\TimezoneInterface');
-        $loggerMock = $this->getMock('\Magento\Framework\Logger', [], [], '', false);
+        $loggerMock = $this->getMock('\Psr\Log\LoggerInterface', [], [], '', false);
         $localeResolverMock = $this->getMock('\Magento\Framework\Locale\ResolverInterface');
 
         $this->model = new Multiselect($timezoneMock, $loggerMock, $localeResolverMock);
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/SelectTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/SelectTest.php
index 5500ddd0bb7..611c5c81d21 100644
--- a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/SelectTest.php
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/SelectTest.php
@@ -14,7 +14,7 @@ class SelectTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $timezoneMock = $this->getMock('\Magento\Framework\Stdlib\DateTime\TimezoneInterface');
-        $loggerMock = $this->getMock('\Magento\Framework\Logger', [], [], '', false);
+        $loggerMock = $this->getMock('\Psr\Log\LoggerInterface', [], [], '', false);
         $localeResolverMock = $this->getMock('\Magento\Framework\Locale\ResolverInterface');
 
         $this->model = new Select($timezoneMock, $loggerMock, $localeResolverMock);
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/TextTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/TextTest.php
index bd6504e7eea..8b02bb74601 100644
--- a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/TextTest.php
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/TextTest.php
@@ -29,7 +29,7 @@ class TextTest extends \PHPUnit_Framework_TestCase
             false,
             false
         );
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false, false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface');
         $helper = $this->getMock('Magento\Framework\Stdlib\String', [], [], '', false, false);
 
         $attributeData = [
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Attribute/Backend/ArrayTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Attribute/Backend/ArrayTest.php
index 00cc2d8ec13..6d83b5cf568 100644
--- a/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Attribute/Backend/ArrayTest.php
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Attribute/Backend/ArrayTest.php
@@ -25,7 +25,7 @@ class ArrayTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface');
         $this->_model = new \Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend($logger);
         $this->_model->setAttribute($this->_attribute);
     }
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Collection/AbstractCollectionTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Collection/AbstractCollectionTest.php
index 643be759694..8c2fbd95ed9 100644
--- a/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Collection/AbstractCollectionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Collection/AbstractCollectionTest.php
@@ -17,7 +17,7 @@ class AbstractCollectionTest extends \PHPUnit_Framework_TestCase
     protected $coreEntityFactoryMock;
 
     /**
-     * @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $loggerMock;
 
@@ -59,7 +59,7 @@ class AbstractCollectionTest extends \PHPUnit_Framework_TestCase
     public function setUp()
     {
         $this->coreEntityFactoryMock = $this->getMock('Magento\Core\Model\EntityFactory', [], [], '', false);
-        $this->loggerMock = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $this->fetchStrategyMock = $this->getMock(
             'Magento\Framework\Data\Collection\Db\FetchStrategyInterface',
             [],
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Resource/Attribute/CollectionTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Resource/Attribute/CollectionTest.php
index 0d712466ff2..f71b2d4fd71 100644
--- a/dev/tests/unit/testsuite/Magento/Eav/Model/Resource/Attribute/CollectionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Resource/Attribute/CollectionTest.php
@@ -17,7 +17,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
     protected $entityFactoryMock;
 
     /**
-     * @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $loggerMock;
 
@@ -64,7 +64,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $this->entityFactoryMock = $this->getMock('Magento\Core\Model\EntityFactory', [], [], '', false);
-        $this->loggerMock = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $this->fetchStrategyMock = $this->getMock('Magento\Framework\Data\Collection\Db\FetchStrategyInterface');
         $this->eventManagerMock = $this->getMock('Magento\Framework\Event\ManagerInterface');
 
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Resource/Entity/Attribute/Option/CollectionTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Resource/Entity/Attribute/Option/CollectionTest.php
index 7d2313e46b0..5e27db60b51 100644
--- a/dev/tests/unit/testsuite/Magento/Eav/Model/Resource/Entity/Attribute/Option/CollectionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Resource/Entity/Attribute/Option/CollectionTest.php
@@ -17,7 +17,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
     protected $entityFactoryMock;
 
     /**
-     * @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $loggerMock;
 
@@ -59,7 +59,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $this->entityFactoryMock = $this->getMock('Magento\Core\Model\EntityFactory', [], [], '', false);
-        $this->loggerMock = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $this->fetchStrategyMock = $this->getMock(
             'Magento\Framework\Data\Collection\Db\FetchStrategyInterface',
             [],
diff --git a/dev/tests/unit/testsuite/Magento/Email/Block/Adminhtml/Template/EditTest.php b/dev/tests/unit/testsuite/Magento/Email/Block/Adminhtml/Template/EditTest.php
index 8b54b0509e5..12105ab2f55 100644
--- a/dev/tests/unit/testsuite/Magento/Email/Block/Adminhtml/Template/EditTest.php
+++ b/dev/tests/unit/testsuite/Magento/Email/Block/Adminhtml/Template/EditTest.php
@@ -52,7 +52,7 @@ class EditTest extends \PHPUnit_Framework_TestCase
         $menuMock = $this->getMock(
             'Magento\Backend\Model\Menu',
             [],
-            [$this->getMock('Magento\Framework\Logger', [], [], '', false)]
+            [$this->getMock('Psr\Log\LoggerInterface')]
         );
         $menuItemMock = $this->getMock('Magento\Backend\Model\Menu\Item', [], [], '', false, false);
         $urlBuilder = $this->getMock('Magento\Backend\Model\Url', [], [], '', false, false);
diff --git a/dev/tests/unit/testsuite/Magento/Fedex/Model/CarrierTest.php b/dev/tests/unit/testsuite/Magento/Fedex/Model/CarrierTest.php
index 4bb9d7ee7e9..9e28c26b13e 100644
--- a/dev/tests/unit/testsuite/Magento/Fedex/Model/CarrierTest.php
+++ b/dev/tests/unit/testsuite/Magento/Fedex/Model/CarrierTest.php
@@ -77,7 +77,7 @@ class CarrierTest extends \PHPUnit_Framework_TestCase
                 'scopeConfig' => $scopeConfig,
                 'rateErrorFactory' =>
                     $this->getMock('Magento\Sales\Model\Quote\Address\RateResult\ErrorFactory', [], [], '', false),
-                'logger' => $this->getMock('Magento\Framework\Logger', [], [], '', false),
+                'logger' => $this->getMock('Psr\Log\LoggerInterface'),
                 'xmlElFactory' => $this->getMock('Magento\Shipping\Model\Simplexml\ElementFactory', [], [], '', false),
                 'rateFactory' => $rateFactory,
                 'rateMethodFactory' => $rateMethodFactory,
diff --git a/dev/tests/unit/testsuite/Magento/Framework/App/BootstrapTest.php b/dev/tests/unit/testsuite/Magento/Framework/App/BootstrapTest.php
index 11b5ff8d5ea..986ad6a02af 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/App/BootstrapTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/App/BootstrapTest.php
@@ -25,7 +25,7 @@ class BootstrapTest extends \PHPUnit_Framework_TestCase
     protected $objectManager;
 
     /**
-     * @var \Magento\Framework\Logger | \PHPUnit_Framework_MockObject_MockObject
+     * @var \Psr\Log\LoggerInterface | \PHPUnit_Framework_MockObject_MockObject
      */
     protected $logger;
 
@@ -62,7 +62,7 @@ class BootstrapTest extends \PHPUnit_Framework_TestCase
         $this->maintenanceMode = $this->getMock('Magento\Framework\App\MaintenanceMode', ['isOn'], [], '', false);
         $filesystem = $this->getMock('Magento\Framework\Filesystem', [], [], '', false);
 
-        $this->logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $this->logger = $this->getMock('Psr\Log\LoggerInterface');
 
         $this->deploymentConfig = $this->getMock('Magento\Framework\App\DeploymentConfig', [], [], '', false);
 
@@ -71,7 +71,7 @@ class BootstrapTest extends \PHPUnit_Framework_TestCase
             ['Magento\Framework\App\MaintenanceMode', $this->maintenanceMode],
             ['Magento\Framework\Filesystem', $filesystem],
             ['Magento\Framework\App\DeploymentConfig', $this->deploymentConfig],
-            ['Magento\Framework\Logger', $this->logger],
+            ['Psr\Log\LoggerInterface', $this->logger],
         ];
 
         $this->objectManager->expects($this->any())->method('get')
diff --git a/dev/tests/unit/testsuite/Magento/Framework/DB/AbstractMapperTest.php b/dev/tests/unit/testsuite/Magento/Framework/DB/AbstractMapperTest.php
index 9a97d863332..7ccd46efefa 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/DB/AbstractMapperTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/DB/AbstractMapperTest.php
@@ -25,7 +25,7 @@ class AbstractMapperTest extends \PHPUnit_Framework_TestCase
     protected $selectMock;
 
     /**
-     * @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $loggerMock;
 
@@ -81,13 +81,7 @@ class AbstractMapperTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $this->loggerMock = $this->getMock(
-            'Magento\Framework\Logger',
-            [],
-            [],
-            '',
-            false
-        );
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $this->fetchStrategyMock = $this->getMockForAbstractClass(
             'Magento\Framework\Data\Collection\Db\FetchStrategyInterface',
             [],
diff --git a/dev/tests/unit/testsuite/Magento/Framework/DB/QueryTest.php b/dev/tests/unit/testsuite/Magento/Framework/DB/QueryTest.php
index 799e194e822..fa8981c85e3 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/DB/QueryTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/DB/QueryTest.php
@@ -30,7 +30,7 @@ class QueryTest extends \PHPUnit_Framework_TestCase
     protected $fetchStmtMock;
 
     /**
-     * @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $loggerMock;
 
@@ -85,13 +85,7 @@ class QueryTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $this->loggerMock = $this->getMock(
-            'Magento\Framework\Logger',
-            [],
-            [],
-            '',
-            false
-        );
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $this->fetchStrategyMock = $this->getMockForAbstractClass(
             'Magento\Framework\Data\Collection\Db\FetchStrategyInterface',
             [],
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Data/Collection/DbTest.php b/dev/tests/unit/testsuite/Magento/Framework/Data/Collection/DbTest.php
index a261fa3694d..34dbe81ac59 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Data/Collection/DbTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Data/Collection/DbTest.php
@@ -12,7 +12,7 @@ class DbTest extends \PHPUnit_Framework_TestCase
     protected $collection;
 
     /**
-     * @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $loggerMock;
 
@@ -34,7 +34,7 @@ class DbTest extends \PHPUnit_Framework_TestCase
         $this->entityFactoryMock = $this->getMock(
             'Magento\Core\Model\EntityFactory', ['create'], [], '', false
         );
-        $this->loggerMock = $this->getMock('Magento\Framework\Logger', ['info'], [], '', false);
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $this->collection = new \Magento\Framework\Data\Collection\Db(
             $this->entityFactoryMock,
             $this->loggerMock,
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Model/AbstractExtensibleModelTest.php b/dev/tests/unit/testsuite/Magento/Framework/Model/AbstractExtensibleModelTest.php
index 98eacb609f3..26c1423a966 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Model/AbstractExtensibleModelTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Model/AbstractExtensibleModelTest.php
@@ -55,7 +55,7 @@ class AbstractExtensibleModelTest extends \PHPUnit_Framework_TestCase
             false
         );
         $this->contextMock = new \Magento\Framework\Model\Context(
-            $this->getMock('Magento\Framework\Logger', [], [], '', false),
+            $this->getMock('Psr\Log\LoggerInterface'),
             $this->getMock('Magento\Framework\Event\ManagerInterface', [], [], '', false),
             $this->getMock('Magento\Framework\App\CacheInterface', [], [], '', false),
             $this->getMock('Magento\Framework\App\State', [], [], '', false),
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Model/AbstractModelTest.php b/dev/tests/unit/testsuite/Magento/Framework/Model/AbstractModelTest.php
index 708eeda02c8..2d2109a4b6e 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Model/AbstractModelTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Model/AbstractModelTest.php
@@ -53,7 +53,7 @@ class AbstractModelTest extends \PHPUnit_Framework_TestCase
             false
         );
         $this->contextMock = new \Magento\Framework\Model\Context(
-            $this->getMock('Magento\Framework\Logger', [], [], '', false),
+            $this->getMock('Psr\Log\LoggerInterface'),
             $this->getMock('Magento\Framework\Event\ManagerInterface', [], [], '', false),
             $this->getMock('Magento\Framework\App\CacheInterface', [], [], '', false),
             $this->getMock('Magento\Framework\App\State', [], [], '', false),
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Model/Resource/Db/Collection/AbstractCollectionTest.php b/dev/tests/unit/testsuite/Magento/Framework/Model/Resource/Db/Collection/AbstractCollectionTest.php
index 3d6b52266b5..8212036d79c 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Model/Resource/Db/Collection/AbstractCollectionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Model/Resource/Db/Collection/AbstractCollectionTest.php
@@ -21,7 +21,7 @@ class AbstractCollectionTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Framework\Data\Collection\EntityFactoryInterface|\PHPUnit_Framework_MockObject_MockObject */
     protected $entityFactoryMock;
 
-    /** @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject */
+    /** @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject */
     protected $loggerMock;
 
     /** @var \Magento\Framework\Data\Collection\Db\FetchStrategyInterface|\PHPUnit_Framework_MockObject_MockObject */
@@ -45,7 +45,7 @@ class AbstractCollectionTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $this->entityFactoryMock = $this->getMock('Magento\Framework\Data\Collection\EntityFactoryInterface');
-        $this->loggerMock = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $this->fetchStrategyMock = $this->getMock('Magento\Framework\Data\Collection\Db\FetchStrategyInterface');
         $this->managerMock = $this->getMock('Magento\Framework\Event\ManagerInterface');
         $this->connectionMock = $this->getMock('Magento\Framework\DB\Adapter\Pdo\Mysql', [], [], '', false);
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Module/Setup/MigrationTest.php b/dev/tests/unit/testsuite/Magento/Framework/Module/Setup/MigrationTest.php
index 29b126f121e..455753f860e 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Module/Setup/MigrationTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Module/Setup/MigrationTest.php
@@ -159,7 +159,7 @@ class MigrationTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue($this->getMock('Magento\Framework\App\Resource', [], [], '', false)));
         $contextMock->expects($this->once())
             ->method('getLogger')
-            ->will($this->returnValue($this->getMock('Magento\Framework\Logger', [], [], '', false)));
+            ->will($this->returnValue($this->getMock('Psr\Log\LoggerInterface')));
         $contextMock->expects($this->once())
             ->method('getModulesReader')
             ->will(
@@ -216,7 +216,7 @@ class MigrationTest extends \PHPUnit_Framework_TestCase
             $this->getMock('Magento\Framework\App\Resource', [], [], '', false, false),
             $this->getMock('Magento\Framework\Filesystem', [], [], '', false),
             $this->getMock('Magento\Core\Helper\Data', [], [], '', false),
-            $this->getMock('Magento\Framework\Logger', [], [], '', false),
+            $this->getMock('Psr\Log\LoggerInterface'),
             $this->getMock('Magento\Framework\Event\ManagerInterface', [], [], '', false),
             $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface'),
             $this->getMock('Magento\Framework\Module\ModuleListInterface'),
diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Asset/MergedTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Asset/MergedTest.php
index f83923b7fe3..0075409fc18 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/View/Asset/MergedTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/Asset/MergedTest.php
@@ -48,7 +48,7 @@ class MergedTest extends \PHPUnit_Framework_TestCase
         $this->_assetJsTwo->expects($this->any())->method('getPath')
             ->will($this->returnValue('script_two.js'));
 
-        $this->_logger = $this->getMock('Magento\Framework\Logger', ['critical'], [], '', false);
+        $this->_logger = $this->getMock('Psr\Log\LoggerInterface');
 
         $this->_mergeStrategy = $this->getMock('Magento\Framework\View\Asset\MergeStrategyInterface');
 
diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Asset/MinifiedTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Asset/MinifiedTest.php
index c9225cec514..953d28830ee 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/View/Asset/MinifiedTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/Asset/MinifiedTest.php
@@ -14,7 +14,7 @@ class MinifiedTest extends \PHPUnit_Framework_TestCase
     protected $_asset;
 
     /**
-     * @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $_logger;
 
@@ -51,7 +51,7 @@ class MinifiedTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $this->_asset = $this->getMockForAbstractClass('\Magento\Framework\View\Asset\LocalInterface');
-        $this->_logger = $this->getMock('\Magento\Framework\Logger', [], [], '', false);
+        $this->_logger = $this->getMock('\Psr\Log\LoggerInterface', [], [], '', false);
         $this->_baseUrl = $this->getMock('\Magento\Framework\Url', [], [], '', false);
         $this->_staticViewDir = $this->getMockForAbstractClass(
             '\Magento\Framework\Filesystem\Directory\WriteInterface'
diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/ContextTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/ContextTest.php
index 79bf24db649..a5e76e1716f 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/View/ContextTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/ContextTest.php
@@ -117,7 +117,7 @@ class ContextTest extends \PHPUnit_Framework_TestCase
 
     public function testGetLogger()
     {
-        $this->assertInstanceOf('\Magento\Framework\Logger', $this->context->getLogger());
+        $this->assertInstanceOf('\Psr\Log\LoggerInterface', $this->context->getLogger());
     }
 
     public function testGetAppState()
diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Design/Theme/ImageTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Design/Theme/ImageTest.php
index e3ab232cf71..406399dfcda 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/View/Design/Theme/ImageTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/Design/Theme/ImageTest.php
@@ -86,7 +86,7 @@ class ImageTest extends \PHPUnit_Framework_TestCase
         $this->_imageMock = $this->getMock('Magento\Framework\Image', [], [], '', false, false);
         $imageFactory->expects($this->any())->method('create')->will($this->returnValue($this->_imageMock));
 
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false, false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface');
         $this->_themeMock = $this->getMock('Magento\Core\Model\Theme', ['__wakeup'], [], '', false, false);
         $this->_uploaderMock = $this->getMock(
             'Magento\Framework\View\Design\Theme\Image\Uploader',
diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/RendererTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/RendererTest.php
index 70bfc7346e0..64e3254b0bc 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/RendererTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/Page/Config/RendererTest.php
@@ -56,7 +56,7 @@ class RendererTest extends \PHPUnit_Framework_TestCase
     protected $stringMock;
 
     /**
-     * @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $loggerMock;
 
@@ -106,8 +106,7 @@ class RendererTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
 
-        $this->loggerMock = $this->getMockBuilder('Magento\Framework\Logger')
-            ->disableOriginalConstructor()
+        $this->loggerMock = $this->getMockBuilder('Psr\Log\LoggerInterface')
             ->getMock();
 
         $this->assetsCollection = $this->getMockBuilder('Magento\Framework\View\Asset\GroupedCollection')
diff --git a/dev/tests/unit/testsuite/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAddTest.php b/dev/tests/unit/testsuite/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAddTest.php
index 4171f4a6f80..f5b3c73d021 100644
--- a/dev/tests/unit/testsuite/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAddTest.php
+++ b/dev/tests/unit/testsuite/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAddTest.php
@@ -73,10 +73,9 @@ class MassAddTest extends \PHPUnit_Framework_TestCase
         $this->flag->expects($this->once())->method('lock')
             ->will($this->throwException(new \Exception('Test exception')));
 
-        $logger = $this->getMockBuilder('Magento\Framework\Logger')->setMethods(['critical'])
-            ->disableOriginalConstructor()->getMock();
+        $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
         $this->controllerArguments['context']->getObjectManager()
-            ->expects($this->at(2))->method('get')->with('Magento\Framework\Logger')
+            ->expects($this->at(2))->method('get')->with('Psr\Log\LoggerInterface')
             ->will($this->returnValue($logger));
 
         $this->controller->execute();
diff --git a/dev/tests/unit/testsuite/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/RefreshTest.php b/dev/tests/unit/testsuite/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/RefreshTest.php
index df7ff93455d..71c385ce8f1 100644
--- a/dev/tests/unit/testsuite/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/RefreshTest.php
+++ b/dev/tests/unit/testsuite/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/RefreshTest.php
@@ -67,10 +67,9 @@ class RefreshTest extends \PHPUnit_Framework_TestCase
         $this->flag->expects($this->once())->method('lock')
             ->will($this->throwException(new \Exception('Test exception')));
 
-        $logger = $this->getMockBuilder('Magento\Framework\Logger')->setMethods(['critical'])
-            ->disableOriginalConstructor()->getMock();
+        $logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
         $this->controllerArguments['context']->getObjectManager()->expects($this->at(1))->method('get')
-            ->with('Magento\Framework\Logger')
+            ->with('Psr\Log\LoggerInterface')
             ->will($this->returnValue($logger));
 
         $this->controller->execute();
diff --git a/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/MassOperationsTest.php b/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/MassOperationsTest.php
index 980020bf9d4..72752d10b79 100644
--- a/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/MassOperationsTest.php
+++ b/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/MassOperationsTest.php
@@ -30,7 +30,7 @@ class MassOperationsTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
     protected $storeManagerInterface;
 
-    /** @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject */
+    /** @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject */
     protected $logger;
 
     /** @var \Magento\GoogleShopping\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */
@@ -49,7 +49,7 @@ class MassOperationsTest extends \PHPUnit_Framework_TestCase
         $this->productFactory = $this->getMock('Magento\Catalog\Model\ProductFactory', [], [], '', false);
         $this->notificationInterface = $this->getMock('Magento\Framework\Notification\NotifierInterface');
         $this->storeManagerInterface = $this->getMock('Magento\Store\Model\StoreManagerInterface');
-        $this->logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $this->logger = $this->getMock('Psr\Log\LoggerInterface');
         $this->googleShoppingHelper = $this->getMock('Magento\GoogleShopping\Helper\Data', [], [], '', false);
         $this->googleShoppingCategoryHelper = $this->getMock('Magento\GoogleShopping\Helper\Category');
 
diff --git a/dev/tests/unit/testsuite/Magento/GroupedProduct/Model/Product/Type/GroupedTest.php b/dev/tests/unit/testsuite/Magento/GroupedProduct/Model/Product/Type/GroupedTest.php
index ad9392e906e..cd98cd9ee70 100644
--- a/dev/tests/unit/testsuite/Magento/GroupedProduct/Model/Product/Type/GroupedTest.php
+++ b/dev/tests/unit/testsuite/Magento/GroupedProduct/Model/Product/Type/GroupedTest.php
@@ -40,7 +40,7 @@ class GroupedTest extends \PHPUnit_Framework_TestCase
         $filesystem = $this->getMock('Magento\Framework\Filesystem', [], [], '', false);
         $coreRegistry = $this->getMock('Magento\Framework\Registry', [], [], '', false);
         $this->product = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false);
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface');
         $productFactoryMock = $this->getMock('Magento\Catalog\Model\ProductFactory', [], [], '', false);
         $this->catalogProductLink = $this->getMock(
             '\Magento\GroupedProduct\Model\Resource\Product\Link',
diff --git a/dev/tests/unit/testsuite/Magento/ImportExport/Model/ExportTest.php b/dev/tests/unit/testsuite/Magento/ImportExport/Model/ExportTest.php
index 8b0f5e49a1f..ce1d09e5366 100644
--- a/dev/tests/unit/testsuite/Magento/ImportExport/Model/ExportTest.php
+++ b/dev/tests/unit/testsuite/Magento/ImportExport/Model/ExportTest.php
@@ -57,7 +57,7 @@ class ExportTest extends \PHPUnit_Framework_TestCase
             $this->returnValue($this->_exportFileExtension)
         );
 
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface');
         $filesystem = $this->getMock('Magento\Framework\Filesystem', [], [], '', false);
         $entityFactory = $this->getMock(
             'Magento\ImportExport\Model\Export\Entity\Factory',
diff --git a/dev/tests/unit/testsuite/Magento/ImportExport/Model/Resource/CollectionByPagesIteratorTest.php b/dev/tests/unit/testsuite/Magento/ImportExport/Model/Resource/CollectionByPagesIteratorTest.php
index 15b1b6c5660..4b3e456e467 100644
--- a/dev/tests/unit/testsuite/Magento/ImportExport/Model/Resource/CollectionByPagesIteratorTest.php
+++ b/dev/tests/unit/testsuite/Magento/ImportExport/Model/Resource/CollectionByPagesIteratorTest.php
@@ -41,7 +41,7 @@ class CollectionByPagesIteratorTest extends \PHPUnit_Framework_TestCase
         $select = $this->getMock('Zend_Db_Select', [], [], '', false);
 
         $entityFactory = $this->getMock('Magento\Core\Model\EntityFactory', [], [], '', false);
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface');
 
         /** @var $collectionMock \Magento\Framework\Data\Collection\Db|PHPUnit_Framework_MockObject_MockObject */
         $collectionMock = $this->getMock(
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/IntegrationTest.php b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/IntegrationTest.php
index 41775ba8193..4e27d2ab84a 100644
--- a/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/IntegrationTest.php
+++ b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/IntegrationTest.php
@@ -190,9 +190,9 @@ abstract class IntegrationTest extends \PHPUnit_Framework_TestCase
         $menuMock = $this->getMock(
             'Magento\Backend\Model\Menu',
             [],
-            [$this->getMock('Magento\Framework\Logger', [], [], '', false)]
+            [$this->getMock('Psr\Log\LoggerInterface')]
         );
-        $loggerMock = $this->getMockBuilder('Magento\Framework\Logger')->disableOriginalConstructor()->getMock();
+        $loggerMock = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
         $loggerMock->expects($this->any())->method('critical')->will($this->returnSelf());
         $menuMock->expects($this->any())->method('getParentItems')->will($this->returnValue([]));
         $blockMock->expects($this->any())->method('getMenuModel')->will($this->returnValue($menuMock));
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Helper/Oauth/ConsumerTest.php b/dev/tests/unit/testsuite/Magento/Integration/Helper/Oauth/ConsumerTest.php
index 45d3773694e..075e79d14d0 100644
--- a/dev/tests/unit/testsuite/Magento/Integration/Helper/Oauth/ConsumerTest.php
+++ b/dev/tests/unit/testsuite/Magento/Integration/Helper/Oauth/ConsumerTest.php
@@ -33,7 +33,7 @@ class ConsumerTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Integration\Service\V1\OauthInterface */
     protected $_oauthService;
 
-    /** @var \Magento\Framework\Logger */
+    /** @var \Psr\Log\LoggerInterface */
     protected $_loggerMock;
 
     protected function setUp()
@@ -90,9 +90,7 @@ class ConsumerTest extends \PHPUnit_Framework_TestCase
             'Magento\Framework\HTTP\ZendClient'
         )->disableOriginalConstructor()->getMock();
         $this->_loggerMock = $this->getMockBuilder(
-            'Magento\Framework\Logger'
-        )->disableOriginalConstructor()->setMethods(
-            ['critical']
+            'Psr\Log\LoggerInterface'
         )->getMock();
 
         $this->_oauthService = new \Magento\Integration\Service\V1\Oauth(
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Service/V1/AuthorizationServiceTest.php b/dev/tests/unit/testsuite/Magento/Integration/Service/V1/AuthorizationServiceTest.php
index 73aeef14728..b0a84bce0c5 100644
--- a/dev/tests/unit/testsuite/Magento/Integration/Service/V1/AuthorizationServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Integration/Service/V1/AuthorizationServiceTest.php
@@ -43,7 +43,7 @@ class AuthorizationServiceTest extends \PHPUnit_Framework_TestCase
             $this->getMock('Magento\Authorization\Model\Resource\Role\CollectionFactory', [], [], '', false),
             $this->getMock('Magento\Authorization\Model\RulesFactory', [], [], '', false),
             $this->getMock('Magento\Authorization\Model\Resource\Rules\CollectionFactory', [], [], '', false),
-            $this->getMock('Magento\Framework\Logger', [], [], '', false),
+            $this->getMock('Psr\Log\LoggerInterface'),
             $this->getMock('Magento\Framework\Acl\RootResource', [], [], '', false)
         );
     }
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Service/V1/OauthTest.php b/dev/tests/unit/testsuite/Magento/Integration/Service/V1/OauthTest.php
index eaeb90e7e17..01ab337946e 100644
--- a/dev/tests/unit/testsuite/Magento/Integration/Service/V1/OauthTest.php
+++ b/dev/tests/unit/testsuite/Magento/Integration/Service/V1/OauthTest.php
@@ -94,7 +94,7 @@ class OauthTest extends \PHPUnit_Framework_TestCase
             $this->_tokenFactoryMock,
             $this->getMock('Magento\Integration\Helper\Oauth\Data', [], [], '', false),
             $this->getMock('Magento\Framework\HTTP\ZendClient', [], [], '', false),
-            $this->getMock('Magento\Framework\Logger', [], [], '', false),
+            $this->getMock('Psr\Log\LoggerInterface'),
             $this->getMock('Magento\Framework\Oauth\Helper\Oauth', [], [], '', false),
             $this->_tokenProviderMock
         );
diff --git a/dev/tests/unit/testsuite/Magento/OfflinePayments/Model/BanktransferTest.php b/dev/tests/unit/testsuite/Magento/OfflinePayments/Model/BanktransferTest.php
index 6c96fbfa426..16d951af2fc 100644
--- a/dev/tests/unit/testsuite/Magento/OfflinePayments/Model/BanktransferTest.php
+++ b/dev/tests/unit/testsuite/Magento/OfflinePayments/Model/BanktransferTest.php
@@ -18,7 +18,7 @@ class BanktransferTest extends \PHPUnit_Framework_TestCase
         $paymentDataMock = $this->getMock('Magento\Payment\Helper\Data', [], [], '', false);
         $scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
         $adapterFactoryMock = $this->getMock(
-            'Magento\Framework\Logger\AdapterFactory',
+            'Psr\Log\LoggerInterface\AdapterFactory',
             ['create'],
             [],
             '',
diff --git a/dev/tests/unit/testsuite/Magento/OfflinePayments/Model/CashondeliveryTest.php b/dev/tests/unit/testsuite/Magento/OfflinePayments/Model/CashondeliveryTest.php
index 651183471b2..7cac02dbe88 100644
--- a/dev/tests/unit/testsuite/Magento/OfflinePayments/Model/CashondeliveryTest.php
+++ b/dev/tests/unit/testsuite/Magento/OfflinePayments/Model/CashondeliveryTest.php
@@ -18,7 +18,7 @@ class CashondeliveryTest extends \PHPUnit_Framework_TestCase
         $eventManager = $this->getMock('Magento\Framework\Event\ManagerInterface', [], [], '', false);
         $paymentDataMock = $this->getMock('Magento\Payment\Helper\Data', [], [], '', false);
         $adapterFactoryMock = $this->getMock(
-            'Magento\Framework\Logger\AdapterFactory',
+            'Psr\Log\LoggerInterface\AdapterFactory',
             ['create'],
             [],
             '',
diff --git a/dev/tests/unit/testsuite/Magento/Ogone/Model/ApiTest.php b/dev/tests/unit/testsuite/Magento/Ogone/Model/ApiTest.php
index a9caa901e08..535adca0f1b 100644
--- a/dev/tests/unit/testsuite/Magento/Ogone/Model/ApiTest.php
+++ b/dev/tests/unit/testsuite/Magento/Ogone/Model/ApiTest.php
@@ -25,7 +25,7 @@ class ApiTest extends \PHPUnit_Framework_TestCase
         $config = $this->getMock('Magento\Ogone\Model\Config', [], [], '', false);
         $paymentDataMock = $this->getMock('Magento\Payment\Helper\Data', [], [], '', false);
         $scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
-        $loggerFactory = $this->getMock('\Magento\Framework\Logger\AdapterFactory', [], [], '', false);
+        $loggerFactory = $this->getMock('\Psr\Log\LoggerInterface\AdapterFactory', [], [], '', false);
         $object = new \Magento\Ogone\Model\Api(
             $eventManager,
             $paymentDataMock,
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Block/Info/ContainerAbstractTest.php b/dev/tests/unit/testsuite/Magento/Payment/Block/Info/ContainerAbstractTest.php
index 0891b30fc93..22fca248a05 100644
--- a/dev/tests/unit/testsuite/Magento/Payment/Block/Info/ContainerAbstractTest.php
+++ b/dev/tests/unit/testsuite/Magento/Payment/Block/Info/ContainerAbstractTest.php
@@ -22,7 +22,7 @@ class ContainerAbstractTest extends \PHPUnit_Framework_TestCase
         $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
         $paymentInfo = $objectManagerHelper->getObject('Magento\Payment\Model\Info');
         $adapterFactoryMock = $this->getMock(
-            'Magento\Framework\Logger\AdapterFactory',
+            'Psr\Log\LoggerInterface\AdapterFactory',
             ['create'],
             [],
             '',
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/Method/FreeTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/Method/FreeTest.php
index e927fe780da..dd3d95bf9d5 100644
--- a/dev/tests/unit/testsuite/Magento/Payment/Model/Method/FreeTest.php
+++ b/dev/tests/unit/testsuite/Magento/Payment/Model/Method/FreeTest.php
@@ -20,7 +20,7 @@ class FreeTest extends \PHPUnit_Framework_TestCase
         $eventManager = $this->getMock('Magento\Framework\Event\ManagerInterface', [], [], '', false);
         $paymentData  = $this->getMock('Magento\Payment\Helper\Data', [], [], '', false);
         $this->scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface', [], [], '', false);
-        $logAdapterFactory = $this->getMock('Magento\Framework\Logger\AdapterFactory', [], [], '', false);
+        $logAdapterFactory = $this->getMock('Psr\Log\LoggerInterface\AdapterFactory', [], [], '', false);
         $this->currencyPrice = $this->getMockBuilder('Magento\Framework\Pricing\PriceCurrencyInterface')->getMock();
 
         $this->methodFree = new \Magento\Payment\Model\Method\Free(
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Controller/Ipn/IndexTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Controller/Ipn/IndexTest.php
index e4234cca300..2af8e61d612 100644
--- a/dev/tests/unit/testsuite/Magento/Paypal/Controller/Ipn/IndexTest.php
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Controller/Ipn/IndexTest.php
@@ -10,7 +10,7 @@ class IndexTest extends \PHPUnit_Framework_TestCase
     /** @var Index */
     protected $model;
 
-    /** @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject */
+    /** @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject */
     protected $logger;
 
     /** @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject */
@@ -21,7 +21,7 @@ class IndexTest extends \PHPUnit_Framework_TestCase
 
     protected function setUp()
     {
-        $this->logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $this->logger = $this->getMock('Psr\Log\LoggerInterface');
         $this->request = $this->getMock('Magento\Framework\App\Request\Http', [], [], '', false);
         $this->response = $this->getMock('Magento\Framework\App\Response\Http', [], [], '', false);
 
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Model/Api/NvpTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Model/Api/NvpTest.php
index 5c9b931611e..2c18495c669 100644
--- a/dev/tests/unit/testsuite/Magento/Paypal/Model/Api/NvpTest.php
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Model/Api/NvpTest.php
@@ -15,7 +15,7 @@ class NvpTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Customer\Helper\Address|\PHPUnit_Framework_MockObject_MockObject */
     protected $customerAddressHelper;
 
-    /** @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject */
+    /** @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject */
     protected $logger;
 
     /** @var \Magento\Framework\Locale\ResolverInterface|\PHPUnit_Framework_MockObject_MockObject */
@@ -45,10 +45,10 @@ class NvpTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $this->customerAddressHelper = $this->getMock('Magento\Customer\Helper\Address', [], [], '', false);
-        $this->logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $this->logger = $this->getMock('Psr\Log\LoggerInterface');
         $this->resolver = $this->getMock('Magento\Framework\Locale\ResolverInterface');
         $this->regionFactory = $this->getMock('Magento\Directory\Model\RegionFactory', [], [], '', false);
-        $this->adapterFactory = $this->getMock('Magento\Framework\Logger\AdapterFactory', [], [], '', false);
+        $this->adapterFactory = $this->getMock('Psr\Log\LoggerInterface\AdapterFactory', [], [], '', false);
         $this->countryFactory = $this->getMock('Magento\Directory\Model\CountryFactory', [], [], '', false);
         $processableExceptionFactory = $this->getMock(
             'Magento\Paypal\Model\Api\ProcessableExceptionFactory',
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Model/IpnTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Model/IpnTest.php
index 1c13879a5a1..6a8c89d3997 100644
--- a/dev/tests/unit/testsuite/Magento/Paypal/Model/IpnTest.php
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Model/IpnTest.php
@@ -101,7 +101,7 @@ class IpnTest extends \PHPUnit_Framework_TestCase
         $this->_ipn = $objectHelper->getObject('Magento\Paypal\Model\Ipn',
             [
                 'configFactory' => $this->configFactory,
-                'logAdapterFactory' => $this->getMock('Magento\Framework\Logger\AdapterFactory', [], [], '', false),
+                'logAdapterFactory' => $this->getMock('Psr\Log\LoggerInterface\AdapterFactory', [], [], '', false),
                 'curlFactory' => $this->curlFactory,
                 'orderFactory' => $this->_orderMock,
                 'paypalInfo' => $this->_paypalInfo,
@@ -180,7 +180,7 @@ class IpnTest extends \PHPUnit_Framework_TestCase
         $this->_ipn = $objectHelper->getObject('Magento\Paypal\Model\Ipn',
             [
                 'configFactory' => $this->configFactory,
-                'logAdapterFactory' => $this->getMock('Magento\Framework\Logger\AdapterFactory', [], [], '', false),
+                'logAdapterFactory' => $this->getMock('Psr\Log\LoggerInterface\AdapterFactory', [], [], '', false),
                 'curlFactory' => $this->curlFactory,
                 'orderFactory' => $this->_orderMock,
                 'paypalInfo' => $this->_paypalInfo,
diff --git a/dev/tests/unit/testsuite/Magento/Reports/Model/Resource/Report/Collection/AbstractCollectionTest.php b/dev/tests/unit/testsuite/Magento/Reports/Model/Resource/Report/Collection/AbstractCollectionTest.php
index f8bfd4a06e5..69d555efe55 100644
--- a/dev/tests/unit/testsuite/Magento/Reports/Model/Resource/Report/Collection/AbstractCollectionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Reports/Model/Resource/Report/Collection/AbstractCollectionTest.php
@@ -14,7 +14,7 @@ class AbstractCollectionTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $entityFactory = $this->getMock('\Magento\Core\Model\EntityFactory', [], [], '', false);
-        $logger = $this->getMock('\Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('\Psr\Log\LoggerInterface', [], [], '', false);
         $fetchStrategy = $this->getMock('\Magento\Framework\Data\Collection\Db\FetchStrategy\Query', [], [], '', false);
         $eventManager = $this->getMock('\Magento\Framework\Event\Manager', [], [], '', false);
         $connection = $this->getMock('\Magento\Framework\DB\Adapter\Pdo\Mysql', [], [], '', false);
diff --git a/dev/tests/unit/testsuite/Magento/Review/Model/Resource/Review/Summary/CollectionTest.php b/dev/tests/unit/testsuite/Magento/Review/Model/Resource/Review/Summary/CollectionTest.php
index 57e071b3ce9..2fc0f29b855 100644
--- a/dev/tests/unit/testsuite/Magento/Review/Model/Resource/Review/Summary/CollectionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Review/Model/Resource/Review/Summary/CollectionTest.php
@@ -23,7 +23,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
     protected $entityFactoryMock;
 
     /**
-     * @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $loggerMock;
 
@@ -58,7 +58,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $this->loggerMock = $this->getMock('Magento\Framework\Logger', ['log'], [], '', false);
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $this->resourceMock = $this->getMock(
             'Magento\Framework\App\Resource',
             [],
diff --git a/dev/tests/unit/testsuite/Magento/Rule/Model/Condition/CombineTest.php b/dev/tests/unit/testsuite/Magento/Rule/Model/Condition/CombineTest.php
index 25921b6990c..109f79c4b22 100644
--- a/dev/tests/unit/testsuite/Magento/Rule/Model/Condition/CombineTest.php
+++ b/dev/tests/unit/testsuite/Magento/Rule/Model/Condition/CombineTest.php
@@ -20,7 +20,7 @@ class CombineTest extends \PHPUnit_Framework_TestCase
     private $conditionFactoryMock;
 
     /**
-     * @var \Magento\Framework\Logger | \PHPUnit_Framework_MockObject_MockObject
+     * @var \Psr\Log\LoggerInterface | \PHPUnit_Framework_MockObject_MockObject
      */
     private $loggerMock;
 
@@ -40,7 +40,7 @@ class CombineTest extends \PHPUnit_Framework_TestCase
             ->setMethods([])
             ->getMock();
 
-        $this->loggerMock = $this->getMockBuilder('\Magento\Framework\Logger')
+        $this->loggerMock = $this->getMockBuilder('\Psr\Log\LoggerInterface')
             ->disableOriginalConstructor()
             ->setMethods([])
             ->getMock();
diff --git a/dev/tests/unit/testsuite/Magento/Rule/Model/Resource/Rule/Collection/AbstractCollectionTest.php b/dev/tests/unit/testsuite/Magento/Rule/Model/Resource/Rule/Collection/AbstractCollectionTest.php
index f6aafa74b4e..5b0448f6cc9 100644
--- a/dev/tests/unit/testsuite/Magento/Rule/Model/Resource/Rule/Collection/AbstractCollectionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Rule/Model/Resource/Rule/Collection/AbstractCollectionTest.php
@@ -25,7 +25,7 @@ class AbstractCollectionTest extends \PHPUnit_Framework_TestCase
     protected $_entityFactoryMock;
 
     /**
-     * @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $_loggerMock;
 
@@ -47,7 +47,7 @@ class AbstractCollectionTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $this->_entityFactoryMock = $this->getMock('Magento\Framework\Data\Collection\EntityFactoryInterface');
-        $this->_loggerMock = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $this->_loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $this->_fetchStrategyMock = $this->getMock('Magento\Framework\Data\Collection\Db\FetchStrategyInterface');
         $this->_managerMock = $this->getMock('Magento\Framework\Event\ManagerInterface');
         $this->_db = $this->getMockForAbstractClass(
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php
index 4594b959c67..80a1d4554f5 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php
@@ -83,7 +83,7 @@ class CreateTest extends \PHPUnit_Framework_TestCase
         $registryMock = $this->getMock('Magento\Framework\Registry');
         $configMock = $this->getMock('Magento\Sales\Model\Config', [], [], '', false);
         $this->sessionQuoteMock = $this->getMock('Magento\Backend\Model\Session\Quote', [], [], '', false);
-        $loggerMock = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $copyMock = $this->getMock('Magento\Framework\Object\Copy', [], [], '', false);
         $messageManagerMock = $this->getMock('Magento\Framework\Message\ManagerInterface');
         $this->formFactoryMock = $this->getMock(
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/EmailSenderTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/EmailSenderTest.php
index 4091a20ee0f..36eb38f6789 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/EmailSenderTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/EmailSenderTest.php
@@ -41,7 +41,7 @@ class EmailSenderTest extends \PHPUnit_Framework_TestCase
             false
         );
         $this->loggerMock = $this->getMock(
-            '\Magento\Framework\Logger',
+            '\Psr\Log\LoggerInterface',
             [],
             [],
             '',
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/Order/CreditmemoNotifierTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/Order/CreditmemoNotifierTest.php
index 5be56a6b12a..02507357841 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Model/Order/CreditmemoNotifierTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/Order/CreditmemoNotifierTest.php
@@ -61,13 +61,7 @@ class CreditmemoNotifierTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $this->loggerMock = $this->getMock(
-            'Magento\Framework\Logger',
-            ['critical'],
-            [],
-            '',
-            false
-        );
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $this->notifier = new CreditmemoNotifier(
             $this->historyCollectionFactory,
             $this->loggerMock,
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/Order/InvoiceNotifierTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/Order/InvoiceNotifierTest.php
index 416f702e22b..0c1e9564625 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Model/Order/InvoiceNotifierTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/Order/InvoiceNotifierTest.php
@@ -61,13 +61,7 @@ class InvoiceNotifierTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $this->loggerMock = $this->getMock(
-            'Magento\Framework\Logger',
-            ['critical'],
-            [],
-            '',
-            false
-        );
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $this->notifier = new InvoiceNotifier(
             $this->historyCollectionFactory,
             $this->loggerMock,
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/Order/Total/Config/BaseTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/Order/Total/Config/BaseTest.php
index 9328efcab2f..2f75543c398 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Model/Order/Total/Config/BaseTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/Order/Total/Config/BaseTest.php
@@ -14,7 +14,7 @@ class BaseTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Framework\App\Cache\Type\Config|\PHPUnit_Framework_MockObject_MockObject */
     protected $configCacheType;
 
-    /** @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject */
+    /** @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject */
     protected $logger;
 
     /** @var \Magento\Sales\Model\Config|\PHPUnit_Framework_MockObject_MockObject */
@@ -26,7 +26,7 @@ class BaseTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $this->configCacheType = $this->getMock('Magento\Framework\App\Cache\Type\Config', [], [], '', false);
-        $this->logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $this->logger = $this->getMock('Psr\Log\LoggerInterface');
         $this->salesConfig = $this->getMock('Magento\Sales\Model\Config', [], [], '', false);
         $this->orderTotalFactory = $this->getMock('Magento\Sales\Model\Order\TotalFactory', [], [], '', false);
 
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/OrderNotifierTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/OrderNotifierTest.php
index 2478cd0a11f..b9e83c91494 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Model/OrderNotifierTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/OrderNotifierTest.php
@@ -61,13 +61,7 @@ class OrderNotifierTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $this->loggerMock = $this->getMock(
-            'Magento\Framework\Logger',
-            ['critical'],
-            [],
-            '',
-            false
-        );
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $this->notifier = new OrderNotifier(
             $this->historyCollectionFactory,
             $this->loggerMock,
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/Resource/Order/Status/History/CollectionTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/Resource/Order/Status/History/CollectionTest.php
index 7d76ae4ca3b..27daafea1a9 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Model/Resource/Order/Status/History/CollectionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/Resource/Order/Status/History/CollectionTest.php
@@ -97,7 +97,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
             ->method('create')
             ->will($this->returnValue($this->historyItemMock));
 
-        $logger = $this->getMock('Magento\Framework\Logger', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface');
         $this->collection = new \Magento\Sales\Model\Resource\Order\Status\History\Collection(
             $this->entityFactoryMock,
             $logger,
diff --git a/dev/tests/unit/testsuite/Magento/SalesRule/Model/Resource/Report/CollectionTest.php b/dev/tests/unit/testsuite/Magento/SalesRule/Model/Resource/Report/CollectionTest.php
index bd0aa76837d..25e0312732b 100644
--- a/dev/tests/unit/testsuite/Magento/SalesRule/Model/Resource/Report/CollectionTest.php
+++ b/dev/tests/unit/testsuite/Magento/SalesRule/Model/Resource/Report/CollectionTest.php
@@ -61,13 +61,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
             false
         );
 
-        $this->loggerMock = $this->getMock(
-            'Magento\Framework\Logger',
-            [],
-            [],
-            '',
-            false
-        );
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
 
         $this->fetchStrategy = $this->getMock(
             'Magento\Framework\Data\Collection\Db\FetchStrategyInterface',
diff --git a/dev/tests/unit/testsuite/Magento/Shipping/Controller/Adminhtml/Order/Shipment/CreateLabelTest.php b/dev/tests/unit/testsuite/Magento/Shipping/Controller/Adminhtml/Order/Shipment/CreateLabelTest.php
index 42b71d2689c..3f95683d565 100644
--- a/dev/tests/unit/testsuite/Magento/Shipping/Controller/Adminhtml/Order/Shipment/CreateLabelTest.php
+++ b/dev/tests/unit/testsuite/Magento/Shipping/Controller/Adminhtml/Order/Shipment/CreateLabelTest.php
@@ -199,13 +199,7 @@ class CreateLabelTest extends \PHPUnit_Framework_TestCase
      */
     public function testExecuteSaveException()
     {
-        $logerMock = $this->getMock(
-            'Magento\Framework\Logger',
-            ['critical', '__wakeup'],
-            [],
-            '',
-            false
-        );
+        $logerMock = $this->getMock('Psr\Log\LoggerInterface');
 
         $this->shipmentLoaderMock->expects($this->once())
             ->method('load')
@@ -218,7 +212,7 @@ class CreateLabelTest extends \PHPUnit_Framework_TestCase
         $logerMock->expects($this->once())->method('critical');
         $this->objectManagerMock->expects($this->once())
             ->method('get')
-            ->with('Magento\Framework\Logger')
+            ->with('Psr\Log\LoggerInterface')
             ->will($this->returnValue($logerMock));
         $this->responseMock->expects($this->once())->method('representJson');
 
diff --git a/dev/tests/unit/testsuite/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintLabelTest.php b/dev/tests/unit/testsuite/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintLabelTest.php
index 866d56eafe8..44174420797 100644
--- a/dev/tests/unit/testsuite/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintLabelTest.php
+++ b/dev/tests/unit/testsuite/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintLabelTest.php
@@ -301,13 +301,7 @@ class PrintLabelTest extends \PHPUnit_Framework_TestCase
         $labelContent = 'Label-content';
         $incrementId = '1000001';
 
-        $loggerMock = $this->getMock(
-            'Magento\Framework\Logger',
-            ['critical'],
-            [],
-            '',
-            false
-        );
+        $loggerMock = $this->getMock('Psr\Log\LoggerInterface');
 
         $this->shipmentLoaderMock->expects($this->once())
             ->method('load')
@@ -332,7 +326,7 @@ class PrintLabelTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnSelf());
         $this->objectManagerMock->expects($this->once())
             ->method('get')
-            ->with('Magento\Framework\Logger')
+            ->with('Psr\Log\LoggerInterface')
             ->will($this->returnValue($loggerMock));
         $loggerMock->expects($this->once())
             ->method('critical');
diff --git a/dev/tests/unit/testsuite/Magento/Shipping/Model/ShipmentNotifierTest.php b/dev/tests/unit/testsuite/Magento/Shipping/Model/ShipmentNotifierTest.php
index 70b25e84321..647d012cb2e 100644
--- a/dev/tests/unit/testsuite/Magento/Shipping/Model/ShipmentNotifierTest.php
+++ b/dev/tests/unit/testsuite/Magento/Shipping/Model/ShipmentNotifierTest.php
@@ -61,13 +61,7 @@ class ShipmentNotifierTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $this->loggerMock = $this->getMock(
-            'Magento\Framework\Logger',
-            ['critical'],
-            [],
-            '',
-            false
-        );
+        $this->loggerMock = $this->getMock('Psr\Log\LoggerInterface');
         $this->notifier = new ShipmentNotifier(
             $this->historyCollectionFactory,
             $this->loggerMock,
diff --git a/dev/tests/unit/testsuite/Magento/Theme/Controller/Adminhtml/System/Design/Theme/IndexTest.php b/dev/tests/unit/testsuite/Magento/Theme/Controller/Adminhtml/System/Design/Theme/IndexTest.php
index 22b22e76054..bc70b77601c 100644
--- a/dev/tests/unit/testsuite/Magento/Theme/Controller/Adminhtml/System/Design/Theme/IndexTest.php
+++ b/dev/tests/unit/testsuite/Magento/Theme/Controller/Adminhtml/System/Design/Theme/IndexTest.php
@@ -17,7 +17,7 @@ class IndexTest extends \Magento\Theme\Controller\Adminhtml\System\Design\ThemeT
         $menuModel = $this->getMock(
             'Magento\Backend\Model\Menu',
             [],
-            [$this->getMock('Magento\Framework\Logger', [], [], '', false)]
+            [$this->getMock('Psr\Log\LoggerInterface')]
         );
         $menuModel->expects($this->once())
             ->method('getParentItems')
diff --git a/dev/tests/unit/testsuite/Magento/Webapi/Controller/ErrorProcessorTest.php b/dev/tests/unit/testsuite/Magento/Webapi/Controller/ErrorProcessorTest.php
index 0fe8d442a1c..58cd77c941e 100644
--- a/dev/tests/unit/testsuite/Magento/Webapi/Controller/ErrorProcessorTest.php
+++ b/dev/tests/unit/testsuite/Magento/Webapi/Controller/ErrorProcessorTest.php
@@ -21,7 +21,7 @@ class ErrorProcessorTest extends \PHPUnit_Framework_TestCase
     /** @var \PHPUnit_Framework_MockObject_MockObject */
     protected $_appStateMock;
 
-    /** @var \Magento\Framework\Logger */
+    /** @var \Psr\Log\LoggerInterface */
     protected $_loggerMock;
 
     protected function setUp()
@@ -35,7 +35,7 @@ class ErrorProcessorTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
 
-        $this->_loggerMock = $this->getMockBuilder('Magento\Framework\Logger')->disableOriginalConstructor()->getMock();
+        $this->_loggerMock = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock();
 
         $filesystemMock = $this->getMockBuilder('\Magento\Framework\Filesystem')
             ->disableOriginalConstructor()
diff --git a/lib/internal/Magento/Framework/App/Area.php b/lib/internal/Magento/Framework/App/Area.php
index 07f24f415f3..0cef58d9159 100644
--- a/lib/internal/Magento/Framework/App/Area.php
+++ b/lib/internal/Magento/Framework/App/Area.php
@@ -62,7 +62,7 @@ class Area implements \Magento\Framework\App\AreaInterface
     protected $_diConfigLoader;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -84,7 +84,7 @@ class Area implements \Magento\Framework\App\AreaInterface
     protected $_designExceptions;
 
     /**
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\TranslateInterface $translator
      * @param \Magento\Framework\ObjectManagerInterface $objectManager
@@ -95,7 +95,7 @@ class Area implements \Magento\Framework\App\AreaInterface
      * @param string $areaCode
      */
     public function __construct(
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Framework\TranslateInterface $translator,
         \Magento\Framework\ObjectManagerInterface $objectManager,
diff --git a/lib/internal/Magento/Framework/App/Bootstrap.php b/lib/internal/Magento/Framework/App/Bootstrap.php
index 07666344ff8..c3808f5764a 100644
--- a/lib/internal/Magento/Framework/App/Bootstrap.php
+++ b/lib/internal/Magento/Framework/App/Bootstrap.php
@@ -410,7 +410,7 @@ class Bootstrap
                 if (!$this->objectManager) {
                     throw new \DomainException();
                 }
-                $this->objectManager->get('Magento\Framework\Logger')->critical($e);
+                $this->objectManager->get('Psr\Log\LoggerInterface')->critical($e);
             } catch (\Exception $e) {
                 $message .= "Could not write error message to log. Please use developer mode to see the message.\n";
             }
diff --git a/lib/internal/Magento/Framework/App/Helper/AbstractHelper.php b/lib/internal/Magento/Framework/App/Helper/AbstractHelper.php
index 9eace9044d1..175cb85b531 100644
--- a/lib/internal/Magento/Framework/App/Helper/AbstractHelper.php
+++ b/lib/internal/Magento/Framework/App/Helper/AbstractHelper.php
@@ -36,7 +36,7 @@ abstract class AbstractHelper
     protected $_moduleManager;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
diff --git a/lib/internal/Magento/Framework/App/Helper/Context.php b/lib/internal/Magento/Framework/App/Helper/Context.php
index 48cebe19896..49ae5dd5be2 100644
--- a/lib/internal/Magento/Framework/App/Helper/Context.php
+++ b/lib/internal/Magento/Framework/App/Helper/Context.php
@@ -24,7 +24,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
     protected $_eventManager;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -66,7 +66,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
     /**
      * @param \Magento\Framework\Url\EncoderInterface $urlEncoder
      * @param \Magento\Framework\Url\DecoderInterface $urlDecoder
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Translate\InlineInterface $translateInline
      * @param \Magento\Framework\Module\Manager $moduleManager
      * @param \Magento\Framework\App\RequestInterface $httpRequest
@@ -81,7 +81,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
     public function __construct(
         \Magento\Framework\Url\EncoderInterface $urlEncoder,
         \Magento\Framework\Url\DecoderInterface $urlDecoder,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Translate\InlineInterface $translateInline,
         \Magento\Framework\Module\Manager $moduleManager,
         \Magento\Framework\App\RequestInterface $httpRequest,
@@ -153,7 +153,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
     }
 
     /**
-     * @return \Magento\Framework\Logger
+     * @return \Psr\Log\LoggerInterface
      */
     public function getLogger()
     {
diff --git a/lib/internal/Magento/Framework/DB/AbstractMapper.php b/lib/internal/Magento/Framework/DB/AbstractMapper.php
index d6cac55a45e..cde379716e2 100644
--- a/lib/internal/Magento/Framework/DB/AbstractMapper.php
+++ b/lib/internal/Magento/Framework/DB/AbstractMapper.php
@@ -8,7 +8,7 @@ use Magento\Framework\Api\CriteriaInterface;
 use Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
 use Magento\Framework\Data\ObjectFactory;
 use Magento\Framework\DB\Adapter\AdapterInterface;
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 use Magento\Framework\Object;
 
 /**
diff --git a/lib/internal/Magento/Framework/DB/Query.php b/lib/internal/Magento/Framework/DB/Query.php
index 39ef80941e1..15e6575326c 100644
--- a/lib/internal/Magento/Framework/DB/Query.php
+++ b/lib/internal/Magento/Framework/DB/Query.php
@@ -4,7 +4,7 @@
  */
 namespace Magento\Framework\DB;
 
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 
 /**
  * Class Query
diff --git a/lib/internal/Magento/Framework/Data/AbstractSearchCriteriaBuilder.php b/lib/internal/Magento/Framework/Data/AbstractSearchCriteriaBuilder.php
index c7571d72e89..6845e5edd8f 100644
--- a/lib/internal/Magento/Framework/Data/AbstractSearchCriteriaBuilder.php
+++ b/lib/internal/Magento/Framework/Data/AbstractSearchCriteriaBuilder.php
@@ -4,7 +4,7 @@
  */
 namespace Magento\Framework\Data;
 
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 
 /**
  * Class AbstractSearchCriteriaBuilder
diff --git a/lib/internal/Magento/Framework/Data/Collection/Db.php b/lib/internal/Magento/Framework/Data/Collection/Db.php
index 5694e470cf0..a3d0b641186 100644
--- a/lib/internal/Magento/Framework/Data/Collection/Db.php
+++ b/lib/internal/Magento/Framework/Data/Collection/Db.php
@@ -7,7 +7,7 @@ namespace Magento\Framework\Data\Collection;
 use Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
 use Magento\Framework\DB\Adapter\AdapterInterface;
 use Magento\Framework\DB\Select;
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 
 /**
  * Base items collection class
diff --git a/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php b/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php
index 29883baa622..c6baaa31867 100644
--- a/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php
+++ b/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php
@@ -153,7 +153,7 @@ abstract class AbstractAdapter implements AdapterInterface
     protected $directoryWrite;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
diff --git a/lib/internal/Magento/Framework/Less/PreProcessor/ErrorHandler.php b/lib/internal/Magento/Framework/Less/PreProcessor/ErrorHandler.php
index 1096ec6a7f7..331ce1d74e1 100644
--- a/lib/internal/Magento/Framework/Less/PreProcessor/ErrorHandler.php
+++ b/lib/internal/Magento/Framework/Less/PreProcessor/ErrorHandler.php
@@ -10,14 +10,14 @@ namespace Magento\Framework\Less\PreProcessor;
 class ErrorHandler implements ErrorHandlerInterface
 {
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
     /**
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      */
-    public function __construct(\Magento\Framework\Logger $logger)
+    public function __construct(\Psr\Log\LoggerInterface $logger)
     {
         $this->logger = $logger;
     }
diff --git a/lib/internal/Magento/Framework/Message/Manager.php b/lib/internal/Magento/Framework/Message/Manager.php
index 4ea6187585b..e1bac02e7f0 100644
--- a/lib/internal/Magento/Framework/Message/Manager.php
+++ b/lib/internal/Magento/Framework/Message/Manager.php
@@ -5,7 +5,7 @@
 namespace Magento\Framework\Message;
 
 use Magento\Framework\Event\ManagerInterface as EventManagerInterface;
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 
 /**
  * Message manager model
diff --git a/lib/internal/Magento/Framework/Model/AbstractModel.php b/lib/internal/Magento/Framework/Model/AbstractModel.php
index 9bf7cd8b941..b223b53f1ce 100644
--- a/lib/internal/Magento/Framework/Model/AbstractModel.php
+++ b/lib/internal/Magento/Framework/Model/AbstractModel.php
@@ -109,7 +109,7 @@ abstract class AbstractModel extends \Magento\Framework\Object
     protected $_registry;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
diff --git a/lib/internal/Magento/Framework/Model/Context.php b/lib/internal/Magento/Framework/Model/Context.php
index 2b2835b5a20..78f7125d254 100644
--- a/lib/internal/Magento/Framework/Model/Context.php
+++ b/lib/internal/Magento/Framework/Model/Context.php
@@ -19,7 +19,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
     protected $_cacheManager;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -34,14 +34,14 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
     protected $_actionValidator;
 
     /**
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Event\ManagerInterface $eventDispatcher
      * @param \Magento\Framework\App\CacheInterface $cacheManager
      * @param \Magento\Framework\App\State $appState
      * @param \Magento\Framework\Model\ActionValidator\RemoveAction $actionValidator
      */
     public function __construct(
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Event\ManagerInterface $eventDispatcher,
         \Magento\Framework\App\CacheInterface $cacheManager,
         \Magento\Framework\App\State $appState,
@@ -71,7 +71,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
     }
 
     /**
-     * @return \Magento\Framework\Logger
+     * @return \Psr\Log\LoggerInterface
      */
     public function getLogger()
     {
diff --git a/lib/internal/Magento/Framework/Model/Resource/Db/Collection/AbstractCollection.php b/lib/internal/Magento/Framework/Model/Resource/Db/Collection/AbstractCollection.php
index aead4c8901f..6e68ed3552d 100644
--- a/lib/internal/Magento/Framework/Model/Resource/Db/Collection/AbstractCollection.php
+++ b/lib/internal/Magento/Framework/Model/Resource/Db/Collection/AbstractCollection.php
@@ -95,7 +95,7 @@ abstract class AbstractCollection extends \Magento\Framework\Data\Collection\Db
 
     /**
      * @param \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Zend_Db_Adapter_Abstract $connection
@@ -103,7 +103,7 @@ abstract class AbstractCollection extends \Magento\Framework\Data\Collection\Db
      */
     public function __construct(
         \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         $connection = null,
diff --git a/lib/internal/Magento/Framework/Module/DataSetup.php b/lib/internal/Magento/Framework/Module/DataSetup.php
index ab81a996487..7612e372fa0 100644
--- a/lib/internal/Magento/Framework/Module/DataSetup.php
+++ b/lib/internal/Magento/Framework/Module/DataSetup.php
@@ -50,7 +50,7 @@ class DataSetup extends \Magento\Framework\Module\Setup implements \Magento\Fram
     protected $_eventManager;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
diff --git a/lib/internal/Magento/Framework/Module/Setup/Context.php b/lib/internal/Magento/Framework/Module/Setup/Context.php
index 5eb9006f363..a2fcecf9f14 100644
--- a/lib/internal/Magento/Framework/Module/Setup/Context.php
+++ b/lib/internal/Magento/Framework/Module/Setup/Context.php
@@ -7,7 +7,7 @@ namespace Magento\Framework\Module\Setup;
 class Context implements \Magento\Framework\ObjectManager\ContextInterface
 {
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -54,7 +54,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
     /**
      * Constructor
      *
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\App\Resource $appResource
      * @param \Magento\Framework\Module\Dir\Reader $modulesReader
@@ -65,7 +65,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
      * @param \Magento\Framework\Filesystem $filesystem
      */
     public function __construct(
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Framework\App\Resource $appResource,
         \Magento\Framework\Module\Dir\Reader $modulesReader,
@@ -95,7 +95,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
     }
 
     /**
-     * @return \Magento\Framework\Logger $logger
+     * @return \Psr\Log\LoggerInterface $logger
      */
     public function getLogger()
     {
diff --git a/lib/internal/Magento/Framework/View/Asset/Merged.php b/lib/internal/Magento/Framework/View/Asset/Merged.php
index 4da09f0e3d2..9bb0d8f4097 100644
--- a/lib/internal/Magento/Framework/View/Asset/Merged.php
+++ b/lib/internal/Magento/Framework/View/Asset/Merged.php
@@ -10,7 +10,7 @@ namespace Magento\Framework\View\Asset;
 class Merged implements \Iterator
 {
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
@@ -40,14 +40,14 @@ class Merged implements \Iterator
     protected $isInitialized = false;
 
     /**
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param MergeStrategyInterface $mergeStrategy
      * @param \Magento\Framework\View\Asset\Repository $assetRepo
      * @param MergeableInterface[] $assets
      * @throws \InvalidArgumentException
      */
     public function __construct(
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         MergeStrategyInterface $mergeStrategy,
         \Magento\Framework\View\Asset\Repository $assetRepo,
         array $assets
diff --git a/lib/internal/Magento/Framework/View/Asset/Minified.php b/lib/internal/Magento/Framework/View/Asset/Minified.php
index 6ad6c6f151d..17e5230e458 100644
--- a/lib/internal/Magento/Framework/View/Asset/Minified.php
+++ b/lib/internal/Magento/Framework/View/Asset/Minified.php
@@ -74,7 +74,7 @@ class Minified implements MergeableInterface
     /**
      * Logger
      *
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
@@ -103,7 +103,7 @@ class Minified implements MergeableInterface
      * Constructor
      *
      * @param LocalInterface $asset
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Filesystem $filesystem
      * @param \Magento\Framework\UrlInterface $baseUrl
      * @param \Magento\Framework\Code\Minifier\AdapterInterface $adapter
@@ -111,7 +111,7 @@ class Minified implements MergeableInterface
      */
     public function __construct(
         LocalInterface $asset,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Filesystem $filesystem,
         \Magento\Framework\UrlInterface $baseUrl,
         \Magento\Framework\Code\Minifier\AdapterInterface $adapter,
diff --git a/lib/internal/Magento/Framework/View/Context.php b/lib/internal/Magento/Framework/View/Context.php
index 2c3f9452554..df294c46907 100644
--- a/lib/internal/Magento/Framework/View/Context.php
+++ b/lib/internal/Magento/Framework/View/Context.php
@@ -11,7 +11,7 @@ use Magento\Framework\App\FrontControllerInterface;
 use Magento\Framework\App\Request\Http as Request;
 use Magento\Framework\App\State as AppState;
 use Magento\Framework\Event\ManagerInterface;
-use Magento\Framework\Logger;
+use Psr\Log\LoggerInterface as Logger;
 use Magento\Framework\Session\SessionManager;
 use Magento\Framework\TranslateInterface;
 use Magento\Framework\UrlInterface;
@@ -114,7 +114,7 @@ class Context
     /**
      * Logger
      *
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
@@ -302,7 +302,7 @@ class Context
     /**
      * Retrieve logger
      *
-     * @return \Magento\Framework\Logger
+     * @return \Psr\Log\LoggerInterface
      */
     public function getLogger()
     {
diff --git a/lib/internal/Magento/Framework/View/Design/Theme/Image.php b/lib/internal/Magento/Framework/View/Design/Theme/Image.php
index 4dcad824f2f..5408f611b83 100644
--- a/lib/internal/Magento/Framework/View/Design/Theme/Image.php
+++ b/lib/internal/Magento/Framework/View/Design/Theme/Image.php
@@ -63,7 +63,7 @@ class Image
     /**
      * Logger
      *
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
@@ -88,7 +88,7 @@ class Image
      * @param \Magento\Framework\Image\Factory $imageFactory
      * @param Image\Uploader $uploader
      * @param Image\PathInterface $themeImagePath
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param array $imageParams
      * @param ThemeInterface $theme
      * @codingStandardsIgnoreStart
@@ -98,7 +98,7 @@ class Image
         \Magento\Framework\Image\Factory $imageFactory,
         Image\Uploader $uploader,
         Image\PathInterface $themeImagePath,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         array $imageParams = [self::PREVIEW_IMAGE_WIDTH, self::PREVIEW_IMAGE_HEIGHT],
         ThemeInterface $theme = null
     ) {
diff --git a/lib/internal/Magento/Framework/View/Element/AbstractBlock.php b/lib/internal/Magento/Framework/View/Element/AbstractBlock.php
index 77eaa40ec95..56689fe7335 100644
--- a/lib/internal/Magento/Framework/View/Element/AbstractBlock.php
+++ b/lib/internal/Magento/Framework/View/Element/AbstractBlock.php
@@ -117,7 +117,7 @@ abstract class AbstractBlock extends \Magento\Framework\Object implements BlockI
     /**
      * Logger
      *
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
diff --git a/lib/internal/Magento/Framework/View/Element/Context.php b/lib/internal/Magento/Framework/View/Element/Context.php
index c908ec9fe32..c51fb19a835 100644
--- a/lib/internal/Magento/Framework/View/Element/Context.php
+++ b/lib/internal/Magento/Framework/View/Element/Context.php
@@ -107,7 +107,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
     /**
      * Logger
      *
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -149,7 +149,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
      * @param \Magento\Framework\View\Asset\Repository $assetRepo
      * @param \Magento\Framework\View\ConfigInterface $viewConfig
      * @param \Magento\Framework\App\Cache\StateInterface $cacheState
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Escaper $escaper
      * @param \Magento\Framework\Filter\FilterManager $filterManager
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
@@ -171,7 +171,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
         \Magento\Framework\View\Asset\Repository $assetRepo,
         \Magento\Framework\View\ConfigInterface $viewConfig,
         \Magento\Framework\App\Cache\StateInterface $cacheState,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Escaper $escaper,
         \Magento\Framework\Filter\FilterManager $filterManager,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
@@ -340,7 +340,7 @@ class Context implements \Magento\Framework\ObjectManager\ContextInterface
     /**
      * Get logger
      *
-     * @return \Magento\Framework\Logger
+     * @return \Psr\Log\LoggerInterface
      */
     public function getLogger()
     {
diff --git a/lib/internal/Magento/Framework/View/Element/Template/Context.php b/lib/internal/Magento/Framework/View/Element/Template/Context.php
index e0578a46ec5..1045d69095f 100644
--- a/lib/internal/Magento/Framework/View/Element/Template/Context.php
+++ b/lib/internal/Magento/Framework/View/Element/Template/Context.php
@@ -16,7 +16,7 @@ class Context extends \Magento\Framework\View\Element\Context
     /**
      * Logger instance
      *
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $_logger;
 
@@ -74,7 +74,7 @@ class Context extends \Magento\Framework\View\Element\Context
      * @param \Magento\Framework\View\Asset\Repository $assetRepo
      * @param \Magento\Framework\View\ConfigInterface $viewConfig
      * @param \Magento\Framework\App\Cache\StateInterface $cacheState
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Escaper $escaper
      * @param \Magento\Framework\Filter\FilterManager $filterManager
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
@@ -102,7 +102,7 @@ class Context extends \Magento\Framework\View\Element\Context
         \Magento\Framework\View\Asset\Repository $assetRepo,
         \Magento\Framework\View\ConfigInterface $viewConfig,
         \Magento\Framework\App\Cache\StateInterface $cacheState,
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Escaper $escaper,
         \Magento\Framework\Filter\FilterManager $filterManager,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
@@ -157,7 +157,7 @@ class Context extends \Magento\Framework\View\Element\Context
     /**
      * Get logger instance
      *
-     * @return \Magento\Framework\Logger
+     * @return \Psr\Log\LoggerInterface
      */
     public function getLogger()
     {
diff --git a/lib/internal/Magento/Framework/View/Layout/Data/Structure.php b/lib/internal/Magento/Framework/View/Layout/Data/Structure.php
index 641c7ea5437..cff15d3f74a 100644
--- a/lib/internal/Magento/Framework/View/Layout/Data/Structure.php
+++ b/lib/internal/Magento/Framework/View/Layout/Data/Structure.php
@@ -19,18 +19,18 @@ class Structure extends DataStructure
     protected $_nameIncrement = [];
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
     /**
      * Constructor
      *
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      * @param array $elements
      */
     public function __construct(
-        \Magento\Framework\Logger $logger,
+        \Psr\Log\LoggerInterface $logger,
         array $elements = null
     ) {
         $this->logger = $logger;
diff --git a/lib/internal/Magento/Framework/View/Layout/Generator/Block.php b/lib/internal/Magento/Framework/View/Layout/Generator/Block.php
index 15e7e4b2603..1fb604e81f1 100644
--- a/lib/internal/Magento/Framework/View/Layout/Generator/Block.php
+++ b/lib/internal/Magento/Framework/View/Layout/Generator/Block.php
@@ -29,7 +29,7 @@ class Block implements Layout\GeneratorInterface
     protected $eventManager;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
@@ -39,13 +39,13 @@ class Block implements Layout\GeneratorInterface
      * @param \Magento\Framework\View\Element\BlockFactory $blockFactory
      * @param \Magento\Framework\Data\Argument\InterpreterInterface $argumentInterpreter
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      */
     public function __construct(
         \Magento\Framework\View\Element\BlockFactory $blockFactory,
         \Magento\Framework\Data\Argument\InterpreterInterface $argumentInterpreter,
         \Magento\Framework\Event\ManagerInterface $eventManager,
-        \Magento\Framework\Logger $logger
+        \Psr\Log\LoggerInterface $logger
     ) {
         $this->blockFactory = $blockFactory;
         $this->argumentInterpreter = $argumentInterpreter;
diff --git a/lib/internal/Magento/Framework/View/Layout/ScheduledStructure/Helper.php b/lib/internal/Magento/Framework/View/Layout/ScheduledStructure/Helper.php
index 0e5a9253b39..0c919eb96ea 100644
--- a/lib/internal/Magento/Framework/View/Layout/ScheduledStructure/Helper.php
+++ b/lib/internal/Magento/Framework/View/Layout/ScheduledStructure/Helper.php
@@ -26,15 +26,15 @@ class Helper
     protected $counter = 0;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
     /**
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      */
     public function __construct(
-        \Magento\Framework\Logger $logger
+        \Psr\Log\LoggerInterface $logger
     ) {
         $this->logger = $logger;
     }
diff --git a/lib/internal/Magento/Framework/View/Page/Config/Renderer.php b/lib/internal/Magento/Framework/View/Page/Config/Renderer.php
index 9bec2a0bd36..5edeba40ea2 100644
--- a/lib/internal/Magento/Framework/View/Page/Config/Renderer.php
+++ b/lib/internal/Magento/Framework/View/Page/Config/Renderer.php
@@ -39,7 +39,7 @@ class Renderer
     protected $string;
 
     /**
-     * @var \Magento\Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
@@ -55,7 +55,7 @@ class Renderer
      * @param \Magento\Framework\UrlInterface $urlBuilder
      * @param \Magento\Framework\Escaper $escaper
      * @param \Magento\Framework\Stdlib\String $string
-     * @param \Magento\Framework\Logger $logger
+     * @param \Psr\Log\LoggerInterface $logger
      */
     public function __construct(
         Config $pageConfig,
@@ -64,7 +64,7 @@ class Renderer
         \Magento\Framework\UrlInterface $urlBuilder,
         \Magento\Framework\Escaper $escaper,
         \Magento\Framework\Stdlib\String $string,
-        \Magento\Framework\Logger $logger
+        \Psr\Log\LoggerInterface $logger
     ) {
         $this->pageConfig = $pageConfig;
         $this->assetMinifyService = $assetMinifyService;
-- 
GitLab


From 737f9c13e19b563724662ab22fd3cee4e13ab607 Mon Sep 17 00:00:00 2001
From: Andriy Nasinnyk <anasinnyk@ebay.com>
Date: Fri, 19 Dec 2014 14:29:41 +0200
Subject: [PATCH 16/71] MAGETWO-13915: PSR-3: common interface for logging
 libraries.

 - configure logger
---
 app/etc/di.xml | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/app/etc/di.xml b/app/etc/di.xml
index 048eea823d7..09307c527d5 100644
--- a/app/etc/di.xml
+++ b/app/etc/di.xml
@@ -5,6 +5,7 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <preference for="Psr\Log\LoggerInterface" type="Monolog\Logger" />
     <preference for="Magento\Framework\ObjectManager\FactoryInterface" type="Magento\Framework\ObjectManager\Factory\Dynamic\Developer" />
     <preference for="Magento\Framework\Search\Adapter\Mysql\Filter\PreprocessorInterface" type="Magento\Framework\Search\Adapter\Mysql\Filter\Preprocessor" />
     <preference for="Magento\Framework\Search\Adapter\Mysql\Field\ResolverInterface" type="Magento\Framework\Search\Adapter\Mysql\Field\Resolver" />
@@ -84,6 +85,32 @@
     <preference for="Magento\Framework\DB\LoggerInterface" type="Magento\Framework\DB\Logger\Null"/>
     <preference for="Magento\Framework\App\Resource\ConnectionAdapterInterface" type="Magento\Framework\Model\Resource\Type\Db\Pdo\Mysql"/>
     <preference for="Magento\Framework\DB\QueryInterface" type="Magento\Framework\DB\Query"/>
+    <virtualType name="Monolog\Heandler\Stream\System" type="Monolog\Handler\StreamHandler">
+        <arguments>
+            <argument name="stream" xsi:type="string">var/log/system.log</argument>
+            <argument name="level" xsi:type="const">Monolog\Logger::DEBUG</argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="Monolog\Heandler\Stream\Exception" type="Monolog\Handler\StreamHandler">
+        <arguments>
+            <argument name="stream" xsi:type="string">var/log/exception.log</argument>
+            <argument name="level" xsi:type="const">Monolog\Logger::CRITICAL</argument>
+        </arguments>
+    </virtualType>
+    <type name="Monolog\Logger">
+        <arguments>
+            <argument name="name" xsi:type="string">main</argument>
+            <argument name="handlers"  xsi:type="array">
+                <item name="exception" xsi:type="object">Monolog\Heandler\Stream\Exception</item>
+                <item name="system" xsi:type="object">Monolog\Heandler\Stream\System</item>
+            </argument>
+        </arguments>
+    </type>
+    <type name="Monolog\Handler\StreamHandler">
+        <arguments>
+            <argument name="stream" xsi:type="string">var/log/system.log</argument>
+        </arguments>
+    </type>
     <type name="Magento\Framework\Model\Context">
         <arguments>
             <argument name="actionValidator" xsi:type="object">Magento\Framework\Model\ActionValidator\RemoveAction\Proxy</argument>
-- 
GitLab


From f0fd0a8399a19fae75d959c5059f5bd0850f8706 Mon Sep 17 00:00:00 2001
From: Andriy Nasinnyk <anasinnyk@ebay.com>
Date: Fri, 19 Dec 2014 14:55:22 +0200
Subject: [PATCH 17/71] MAGETWO-13915: PSR-3: common interface for logging
 libraries.

 - eliminate Magento\Framework\Logger
---
 .../Test/Legacy/_files/obsolete_classes.php   |  1 +
 lib/internal/Magento/Framework/Logger.php     | 54 -------------------
 .../Magento/Framework/View/Result/Page.php    |  2 +-
 3 files changed, 2 insertions(+), 55 deletions(-)
 delete mode 100644 lib/internal/Magento/Framework/Logger.php

diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
index b80740de2d0..764fc631b79 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
@@ -2829,4 +2829,5 @@ return [
     ['Magento\Rule\Model\Rule', 'Magento\Rule\Model\AbstractModel'],
     ['Magento\Framework\App\Cache\State\Options', 'Magento\Framework\App\Cache\State'],
     ['Magento\Framework\App\Cache\State\OptionsInterface', 'Magento\Framework\App\Cache\State'],
+    ['Magento\Framework\Logger', 'Psr\Log\LoggerInterface'],
 ];
diff --git a/lib/internal/Magento/Framework/Logger.php b/lib/internal/Magento/Framework/Logger.php
deleted file mode 100644
index bc9b11ab1a5..00000000000
--- a/lib/internal/Magento/Framework/Logger.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-/**
- * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- */
-namespace Magento\Framework;
-
-/**
- * Logger model
- */
-class Logger
-{
-    /**#@-*/
-
-    /**
-     * @var array
-     */
-    protected $_loggers = [];
-
-    /**
-     * Log a message
-     *
-     * @param string $message
-     * @internal param int $level
-     */
-    public function info($message)
-    {
-        if (is_array($message) || is_object($message)) {
-            $message = print_r($message, true);
-        }
-        //$this->log($message, $level);
-    }
-
-    /**
-     * Log a message with "debug" level
-     *
-     * @param string $message
-     * @return void
-     */
-    public function debug($message)
-    {
-        $this->info($message);
-    }
-
-    /**
-     * Log an exception
-     *
-     * @param \Exception $e
-     * @return void
-     */
-    public function critical(\Exception $e)
-    {
-        $this->info("\n" . $e->__toString());
-    }
-}
diff --git a/lib/internal/Magento/Framework/View/Result/Page.php b/lib/internal/Magento/Framework/View/Result/Page.php
index e45eee4157f..4ddaf6f9144 100644
--- a/lib/internal/Magento/Framework/View/Result/Page.php
+++ b/lib/internal/Magento/Framework/View/Result/Page.php
@@ -78,7 +78,7 @@ class Page extends Layout
     protected $assetRepo;
 
     /**
-     * @var Framework\Logger
+     * @var \Psr\Log\LoggerInterface
      */
     protected $logger;
 
-- 
GitLab


From d5bebc91925b93021103ddef91cc35d1f2f10be3 Mon Sep 17 00:00:00 2001
From: agurzhyi <agurzhyi@ebay.com>
Date: Fri, 19 Dec 2014 15:20:57 +0200
Subject: [PATCH 18/71] MAGETWO-27636: Persistent Shopping Cart: 'Not
 %Username%?' link is displayed during page load for user logged in

---
 .../Magento/Persistent/Model/Observer.php     | 19 ++-----------------
 1 file changed, 2 insertions(+), 17 deletions(-)

diff --git a/app/code/Magento/Persistent/Model/Observer.php b/app/code/Magento/Persistent/Model/Observer.php
index d91abec4545..67d50e90ab4 100644
--- a/app/code/Magento/Persistent/Model/Observer.php
+++ b/app/code/Magento/Persistent/Model/Observer.php
@@ -92,23 +92,9 @@ class Observer
             null
         );
 
-        $this->_applyAccountLinksPersistentData();
-        $welcomeMessage = __('Welcome, %1!', $escapedName)
-            . ' ' . $this->_layout->getBlock('header.additional')->toHtml();
-        $block->setWelcome($welcomeMessage);
-        return $this;
-    }
+        $block->setWelcome(__('Welcome, %1!', $escapedName));
 
-    /**
-     * Emulate 'account links' block with persistent data
-     *
-     * @return void
-     */
-    protected function _applyAccountLinksPersistentData()
-    {
-        if (!$this->_layout->getBlock('header.additional')) {
-            $this->_layout->addBlock('Magento\Persistent\Block\Header\Additional', 'header.additional');
-        }
+        return $this;
     }
 
     /**
@@ -119,7 +105,6 @@ class Observer
      */
     public function emulateTopLinks($block)
     {
-        $this->_applyAccountLinksPersistentData();
         $block->removeLinkByUrl($this->_url->getUrl('customer/account/login'));
     }
 }
-- 
GitLab


From 9448068c244d5fbdde885375ad7bef1ccda265e4 Mon Sep 17 00:00:00 2001
From: Arkadii Chyzhov <achyzhov@ebay.com>
Date: Fri, 19 Dec 2014 15:59:35 +0200
Subject: [PATCH 19/71] MAGETWO-29555: Incorrect path type format in
 ObjectManager calls

- Merge the branch into a new repository magento2ce
---
 .../Adminhtml/Tax/IgnoreTaxNotification.php          |  2 +-
 .../Controller/Adminhtml/User/InvalidateToken.php    |  2 +-
 .../functional/lib/Mtf/App/State/AbstractState.php   |  2 +-
 .../app/Magento/Store/Test/TestCase/StoreTest.php    |  2 +-
 .../AbstractAssertTaxWithCrossBorderApplying.php     |  2 +-
 .../app/Magento/Tax/Test/TestCase/TaxRuleTest.php    |  2 +-
 .../TestFramework/TestCase/AbstractConfigFiles.php   |  2 +-
 .../Magento/Backend/Block/Widget/GridTest.php        |  2 +-
 .../testsuite/Magento/Backend/Model/AuthTest.php     |  2 +-
 .../Magento/Catalog/Block/Product/NewTest.php        |  2 +-
 .../Magento/Catalog/Helper/Product/FlatTest.php      |  2 +-
 .../Model/Indexer/Product/Eav/Action/FullTest.php    |  4 ++--
 .../Model/Indexer/Product/Eav/Action/RowTest.php     |  4 ++--
 .../Model/Indexer/Product/Eav/Action/RowsTest.php    |  4 ++--
 .../Model/Indexer/Product/Price/Action/FullTest.php  |  4 ++--
 .../Model/Indexer/Product/Price/Action/RowTest.php   |  4 ++--
 .../Model/Indexer/Product/Price/Action/RowsTest.php  |  4 ++--
 .../Model/Layer/Filter/DataProvider/PriceTest.php    |  2 +-
 .../Magento/Catalog/Model/Layer/Filter/PriceTest.php |  4 ++--
 .../Resource/Product/Link/Product/CollectionTest.php |  4 ++--
 .../Catalog/Model/Resource/Product/OptionTest.php    |  4 ++--
 .../_files/attribute_set_with_image_attribute.php    |  6 +++---
 .../attribute_set_with_image_attribute_rollback.php  |  4 ++--
 .../Magento/Catalog/_files/empty_attribute_group.php |  2 +-
 .../_files/empty_attribute_group_rollback.php        |  4 ++--
 .../Model/Config/Backend/ManagestockTest.php         |  6 +++---
 .../Model/Indexer/Stock/Action/FullTest.php          |  4 ++--
 .../Model/Indexer/Stock/Action/RowTest.php           |  8 ++++----
 .../Model/Indexer/Stock/Action/RowsTest.php          | 10 +++++-----
 .../CatalogSearch/Block/Advanced/ResultTest.php      |  2 +-
 .../Magento/CatalogSearch/Helper/DataTest.php        |  2 +-
 .../CatalogSearch/Model/Layer/Filter/PriceTest.php   |  2 +-
 .../CatalogSearch/Model/Search/CatalogTest.php       |  2 +-
 .../Magento/Checkout/Block/Onepage/BillingTest.php   |  2 +-
 .../Magento/Checkout/Controller/OnepageTest.php      |  2 +-
 .../_files/quote_with_address_saved_rollback.php     |  2 +-
 .../_files/quote_with_coupon_saved_rollback.php      |  2 +-
 .../_files/quote_with_payment_saved_rollback.php     |  2 +-
 .../quote_with_simple_product_saved_rollback.php     |  2 +-
 ...ote_with_virtual_product_and_address_rollback.php |  2 +-
 .../quote_with_virtual_product_saved_rollback.php    |  2 +-
 .../Magento/Customer/Api/AddressRepositoryTest.php   |  2 +-
 .../Magento/Customer/Block/Address/EditTest.php      |  2 +-
 .../Block/Adminhtml/Edit/Tab/AccountTest.php         |  2 +-
 .../Adminhtml/Edit/Tab/View/PersonalInfoTest.php     |  2 +-
 .../Customer/Block/Adminhtml/Group/EditTest.php      |  2 +-
 .../Adminhtml/Cart/Product/Composite/CartTest.php    |  2 +-
 .../Model/Resource/AddressRepositoryTest.php         |  2 +-
 .../Model/Resource/CustomerRepositoryTest.php        |  6 +++---
 .../testsuite/Magento/Customer/_files/customer.php   |  2 +-
 .../Magento/Framework/Data/Form/Element/DateTest.php |  2 +-
 .../Magento/Framework/Module/DataSetupTest.php       |  2 +-
 .../Module/Plugin/DbStatusValidatorTest.php          |  2 +-
 .../Framework/Search/Adapter/Mysql/AdapterTest.php   |  2 +-
 .../GiftMessage/_files/quote_with_item_message.php   |  2 +-
 .../_files/quote_with_item_message_rollback.php      |  2 +-
 .../GiftMessage/_files/quote_with_message.php        |  2 +-
 .../_files/quote_with_message_rollback.php           |  2 +-
 .../Block/Checkout/Address/SelectTest.php            |  2 +-
 .../Block/Adminhtml/Queue/Edit/FormTest.php          |  2 +-
 .../Sales/Block/Adminhtml/Order/Create/FormTest.php  |  4 ++--
 .../Sales/Controller/Adminhtml/Order/CreateTest.php  |  2 +-
 .../testsuite/Magento/Sales/Model/QuoteTest.php      |  2 +-
 .../Magento/Sales/Model/Resource/OrderTest.php       |  2 +-
 .../Magento/Sales/_files/creditmemo_for_get.php      |  2 +-
 .../Tax/Model/Sales/Total/Quote/SubtotalTest.php     |  8 ++++----
 .../Magento/Tax/Model/TaxRuleRepositoryTest.php      |  2 +-
 .../Magento/Webapi/Model/PathProcessorTest.php       |  2 +-
 .../Backend/Model/Translate/Inline/ConfigTest.php    |  2 +-
 .../Magento/Bundle/Model/Plugin/PriceBackendTest.php |  2 +-
 .../Magento/Bundle/Model/Plugin/ProductTest.php      |  2 +-
 .../Magento/Bundle/Model/Product/OptionListTest.php  |  2 +-
 .../Adminhtml/Product/Helper/Form/CategoryTest.php   |  4 ++--
 .../Adminhtml/Product/Helper/Form/WeightTest.php     |  2 +-
 .../testsuite/Magento/Catalog/Model/ConfigTest.php   | 12 ++++++------
 .../Model/Indexer/Product/Price/ObserverTest.php     |  2 +-
 .../Product/Price/Plugin/CustomerGroupTest.php       |  2 +-
 .../Indexer/Product/Price/Plugin/WebsiteTest.php     |  2 +-
 .../Product/Price/System/Config/PriceScopeTest.php   |  2 +-
 .../testsuite/Magento/Catalog/Model/ObserverTest.php |  2 +-
 .../Magento/Catalog/Model/Product/ActionTest.php     |  2 +-
 .../Magento/Catalog/Model/Product/ConditionTest.php  |  2 +-
 .../Initialization/Helper/ProductLinksTest.php       |  2 +-
 .../Catalog/Model/Product/LinkTypeProviderTest.php   |  2 +-
 .../Magento/Catalog/Model/Product/OptionTest.php     |  2 +-
 .../Model/ProductAttributeGroupRepositoryTest.php    |  2 +-
 .../Catalog/Model/ProductLink/ManagementTest.php     |  2 +-
 .../Catalog/Model/ProductLink/RepositoryTest.php     |  2 +-
 .../Catalog/Model/Resource/Eav/AttributeTest.php     |  2 +-
 .../Magento/Catalog/Model/Resource/ProductTest.php   |  2 +-
 .../Model/System/Config/Source/InputtypeTest.php     |  2 +-
 .../Magento/Catalog/Pricing/Price/BasePriceTest.php  |  2 +-
 .../CatalogImportExport/Model/Import/ProductTest.php |  2 +-
 .../Magento/Checkout/Block/Cart/ShippingTest.php     |  2 +-
 .../Checkout/Block/Cart/Sidebar/TotalsTest.php       |  2 +-
 .../Magento/Checkout/Block/Cart/SidebarTest.php      |  2 +-
 .../Checkout/Block/Onepage/AbstractOnepageTest.php   |  2 +-
 .../Magento/Checkout/Block/Shipping/PriceTest.php    |  2 +-
 .../Checkout/Controller/Onepage/IndexTest.php        |  2 +-
 .../testsuite/Magento/Checkout/Model/SessionTest.php |  6 +++---
 .../Service/V1/Address/Shipping/WriteServiceTest.php |  2 +-
 .../Checkout/Service/V1/Address/ValidatorTest.php    |  4 ++--
 .../Service/V1/Cart/PaymentMethod/BuilderTest.php    |  2 +-
 .../Service/V1/Cart/PaymentMethod/ConverterTest.php  |  2 +-
 .../Checkout/Service/V1/Cart/ReadServiceTest.php     |  2 +-
 .../Checkout/Service/V1/Cart/WriteServiceTest.php    |  2 +-
 .../Checkout/Service/V1/Coupon/ReadServiceTest.php   |  2 +-
 .../Service/V1/Data/PaymentMethod/ConverterTest.php  |  2 +-
 .../Service/V1/PaymentMethod/ReadServiceTest.php     |  2 +-
 .../Service/V1/PaymentMethod/WriteServiceTest.php    |  2 +-
 .../Service/V1/ShippingMethod/ReadServiceTest.php    |  2 +-
 .../CheckoutAgreements/Model/AgreementTest.php       |  2 +-
 .../Block/Adminhtml/Edit/Tab/AccountTest.php         |  2 +-
 .../Magento/Customer/Block/NewsletterTest.php        |  2 +-
 .../Magento/Customer/Block/Widget/DobTest.php        |  4 ++--
 .../Resource/Group/Grid/ServiceCollectionTest.php    |  4 ++--
 .../Eav/Model/Attribute/GroupRepositoryTest.php      |  2 +-
 .../Eav/Model/Resource/Attribute/CollectionTest.php  |  2 +-
 .../Framework/Api/Data/AttributeValueTest.php        |  8 ++++----
 .../Magento/Framework/Data/AbstractCriteriaTest.php  |  2 +-
 .../testsuite/Magento/Framework/HTTP/HeaderTest.php  |  4 ++--
 .../Magento/Framework/Image/Adapter/Gd2Test.php      |  2 +-
 .../Framework/ObjectManager/ObjectManagerTest.php    |  2 +-
 .../Framework/Search/Adapter/Mysql/AdapterTest.php   |  2 +-
 .../Search/Adapter/Mysql/ConditionManagerTest.php    |  2 +-
 .../Search/Adapter/Mysql/DimensionsTest.php          |  2 +-
 .../Search/Adapter/Mysql/ResponseFactoryTest.php     |  2 +-
 .../Magento/Framework/Validator/ConfigTest.php       |  2 +-
 .../Framework/View/Element/Html/Link/CurrentTest.php |  8 ++++----
 .../Magento/GiftMessage/Helper/MessageTest.php       |  2 +-
 .../Model/Attribute/SalePriceEffectiveDateTest.php   |  2 +-
 .../Magento/GoogleShopping/Model/ObserverTest.php    |  2 +-
 .../Magento/GoogleShopping/Model/ServiceTest.php     |  2 +-
 .../Controller/Adminhtml/Edit/PopupTest.php          |  2 +-
 .../LayeredNavigation/Block/NavigationTest.php       |  2 +-
 .../Controller/Checkout/Address/EditAddressTest.php  |  2 +-
 .../Magento/Payment/Model/MethodListTest.php         |  2 +-
 .../testsuite/Magento/Persistent/Helper/DataTest.php |  2 +-
 .../Sales/Model/Quote/Address/ValidatorTest.php      |  2 +-
 .../Magento/Search/Model/DataProviderTest.php        |  4 ++--
 .../Magento/Search/Model/QueryResultTest.php         |  2 +-
 .../Magento/Store/Model/StorageFactoryTest.php       |  2 +-
 .../Tax/Block/Adminhtml/Items/Price/RendererTest.php |  2 +-
 .../Tax/Block/Checkout/Cart/Sidebar/TotalsTest.php   |  2 +-
 .../Tax/Block/Checkout/Shipping/PriceTest.php        |  2 +-
 .../Magento/Tax/Block/Item/Price/RendererTest.php    |  2 +-
 .../Tax/Model/Sales/Total/Quote/SubtotalTest.php     |  2 +-
 .../Magento/Tax/Model/Sales/Total/Quote/TaxTest.php  |  8 ++++----
 .../Magento/Tax/Model/TaxCalculationTest.php         |  2 +-
 .../Magento/Tax/Model/TaxClass/Type/CustomerTest.php |  4 ++--
 .../Magento/Translation/Model/Inline/ConfigTest.php  |  2 +-
 .../Magento/Webapi/Controller/RequestTest.php        |  4 ++--
 .../Magento/Weee/Block/Item/Price/RendererTest.php   |  2 +-
 .../Wishlist/Controller/WishlistProviderTest.php     |  2 +-
 .../Migration/aliases_map/composite_modules_ce.php   |  2 +-
 .../fixtures/cart_price_rules.php                    |  2 +-
 .../fixtures/catalog_price_rules.php                 |  2 +-
 .../performance-toolkit/fixtures/categories.php      |  2 +-
 .../fixtures/configurable_products.php               |  2 +-
 dev/tools/performance-toolkit/fixtures/customers.php |  2 +-
 .../performance-toolkit/fixtures/eav_variations.php  |  2 +-
 .../performance-toolkit/fixtures/simple_products.php |  2 +-
 dev/tools/performance-toolkit/fixtures/stores.php    |  2 +-
 .../Search/Adapter/Mysql/AggregationFactory.php      |  2 +-
 .../Search/Adapter/Mysql/DocumentFactory.php         |  4 ++--
 .../Search/Adapter/Mysql/ResponseFactory.php         |  2 +-
 pub/errors/processorFactory.php                      |  2 +-
 167 files changed, 221 insertions(+), 221 deletions(-)

diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Tax/IgnoreTaxNotification.php b/app/code/Magento/Tax/Controller/Adminhtml/Tax/IgnoreTaxNotification.php
index 41a4916f592..20d37aecdcc 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Tax/IgnoreTaxNotification.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Tax/IgnoreTaxNotification.php
@@ -39,7 +39,7 @@ class IgnoreTaxNotification extends \Magento\Tax\Controller\Adminhtml\Tax
         if ($section) {
             try {
                 $path = 'tax/notification/ignore_' . $section;
-                $this->_objectManager->get('\Magento\Core\Model\Resource\Config')
+                $this->_objectManager->get('Magento\Core\Model\Resource\Config')
                     ->saveConfig($path, 1, \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT, 0);
             } catch (\Exception $e) {
                 $this->messageManager->addError($e->getMessage());
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/InvalidateToken.php b/app/code/Magento/User/Controller/Adminhtml/User/InvalidateToken.php
index 2fd4c02fffb..392d87a98f0 100644
--- a/app/code/Magento/User/Controller/Adminhtml/User/InvalidateToken.php
+++ b/app/code/Magento/User/Controller/Adminhtml/User/InvalidateToken.php
@@ -18,7 +18,7 @@ class InvalidateToken extends \Magento\User\Controller\Adminhtml\User
     {
         if ($userId = $this->getRequest()->getParam('user_id')) {
             /** @var \Magento\Integration\Service\V1\AdminTokenService $tokenService */
-            $tokenService = $this->_objectManager->get('\Magento\Integration\Service\V1\AdminTokenService');
+            $tokenService = $this->_objectManager->get('Magento\Integration\Service\V1\AdminTokenService');
             try {
                 $tokenService->revokeAdminAccessToken($userId);
                 $this->messageManager->addSuccess(__('You have revoked the user\'s tokens.'));
diff --git a/dev/tests/functional/lib/Mtf/App/State/AbstractState.php b/dev/tests/functional/lib/Mtf/App/State/AbstractState.php
index f83a0102f95..dacaadb5724 100644
--- a/dev/tests/functional/lib/Mtf/App/State/AbstractState.php
+++ b/dev/tests/functional/lib/Mtf/App/State/AbstractState.php
@@ -38,7 +38,7 @@ abstract class AbstractState implements StateInterface
      */
     public function clearInstance()
     {
-        $dirList = \Mtf\ObjectManagerFactory::getObjectManager()->get('\Magento\Framework\Filesystem\DirectoryList');
+        $dirList = \Mtf\ObjectManagerFactory::getObjectManager()->get('Magento\Framework\Filesystem\DirectoryList');
         $deploymentConfig = new \Magento\Framework\App\DeploymentConfig(
             new \Magento\Framework\App\DeploymentConfig\Reader($dirList),
             []
diff --git a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/StoreTest.php b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/StoreTest.php
index 6effc32b6bf..17773f76ef7 100644
--- a/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/StoreTest.php
+++ b/dev/tests/functional/tests/app/Magento/Store/Test/TestCase/StoreTest.php
@@ -26,7 +26,7 @@ class StoreTest extends Functional
     public function testCreateNewLocalizedStoreView()
     {
         $objectManager = Factory::getObjectManager();
-        $storeFixture = $objectManager->create('\Magento\Store\Test\Fixture\Store', ['dataSet' => 'german']);
+        $storeFixture = $objectManager->create('Magento\Store\Test\Fixture\Store', ['dataSet' => 'german']);
 
         $storeListPage = Factory::getPageFactory()->getAdminSystemStore();
         $storeListPage->open();
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AbstractAssertTaxWithCrossBorderApplying.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AbstractAssertTaxWithCrossBorderApplying.php
index 0dc49a4adda..8bb7c9f9fdf 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AbstractAssertTaxWithCrossBorderApplying.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AbstractAssertTaxWithCrossBorderApplying.php
@@ -179,7 +179,7 @@ abstract class AbstractAssertTaxWithCrossBorderApplying extends AbstractConstrai
     protected function loginCustomer($customer)
     {
         $this->objectManager->create(
-            '\Magento\Customer\Test\TestStep\LoginCustomerOnFrontendStep',
+            'Magento\Customer\Test\TestStep\LoginCustomerOnFrontendStep',
             ['customer' => $customer]
         )->run();
     }
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxRuleTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxRuleTest.php
index a3673f47e29..8f6c77c43c6 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxRuleTest.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxRuleTest.php
@@ -27,7 +27,7 @@ class TaxRuleTest extends Functional
     {
         //Data
         $objectManager = Factory::getObjectManager();
-        $fixture = $objectManager->create('\Magento\Tax\Test\Fixture\TaxRule', ['dataSet' => 'us_ca_ny_rule']);
+        $fixture = $objectManager->create('Magento\Tax\Test\Fixture\TaxRule', ['dataSet' => 'us_ca_ny_rule']);
         //Pages
         $taxGridPage = Factory::getPageFactory()->getTaxRuleIndex();
         $newTaxRulePage = Factory::getPageFactory()->getTaxRuleNew();
diff --git a/dev/tests/integration/framework/Magento/TestFramework/TestCase/AbstractConfigFiles.php b/dev/tests/integration/framework/Magento/TestFramework/TestCase/AbstractConfigFiles.php
index 9a51c6c64c0..9706eb58e33 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/TestCase/AbstractConfigFiles.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/TestCase/AbstractConfigFiles.php
@@ -133,7 +133,7 @@ abstract class AbstractConfigFiles extends \PHPUnit_Framework_TestCase
         $directory = $objectManager->get('Magento\Framework\Filesystem')
             ->getDirectoryRead(DirectoryList::MODULES);
 
-        return $objectManager->get('\Magento\Framework\Config\FileIteratorFactory')
+        return $objectManager->get('Magento\Framework\Config\FileIteratorFactory')
             ->create($directory, $directory->search($this->_getConfigFilePathGlob()));
     }
 
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/Widget/GridTest.php b/dev/tests/integration/testsuite/Magento/Backend/Block/Widget/GridTest.php
index 2accd8b009e..76152ca7b91 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Block/Widget/GridTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Block/Widget/GridTest.php
@@ -106,7 +106,7 @@ class GridTest extends \PHPUnit_Framework_TestCase
                     'Magento\Framework\View\Element\Template\Context',
                     [
                         'filesystem' => $objectManager->create(
-                            '\Magento\Framework\Filesystem',
+                            'Magento\Framework\Filesystem',
                             ['directoryList' => $directoryList]
                         )
                     ]
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Model/AuthTest.php b/dev/tests/integration/testsuite/Magento/Backend/Model/AuthTest.php
index c0d6f56d0a9..9583306450b 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Model/AuthTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Model/AuthTest.php
@@ -80,7 +80,7 @@ class AuthTest extends \PHPUnit_Framework_TestCase
             \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD
         );
         $this->assertNotEmpty($this->_model->getAuthStorage()->getData());
-        $cookie = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('\Magento\Framework\Stdlib\Cookie');
+        $cookie = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Stdlib\Cookie');
         $cookie->set($this->_model->getAuthStorage()->getName(), 'session_id');
         $this->_model->logout();
         $this->assertEmpty($this->_model->getAuthStorage()->getData());
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/NewTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/NewTest.php
index c12895d67ec..9cc35b8ea03 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/NewTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Block/Product/NewTest.php
@@ -22,7 +22,7 @@ class NewTest extends \PHPUnit_Framework_TestCase
          * @var \Magento\Customer\Api\GroupManagementInterface $groupManagement
          */
         $groupManagement = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
-            ->get('\Magento\Customer\Api\GroupManagementInterface');
+            ->get('Magento\Customer\Api\GroupManagementInterface');
         $notLoggedInId = $groupManagement->getNotLoggedInGroup()->getId();
 
         \Magento\TestFramework\Helper\Bootstrap::getInstance()->loadArea(\Magento\Framework\App\Area::AREA_FRONTEND);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Helper/Product/FlatTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Helper/Product/FlatTest.php
index 410c81020ce..948a96da436 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Helper/Product/FlatTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Helper/Product/FlatTest.php
@@ -22,7 +22,7 @@ class FlatTest extends \PHPUnit_Framework_TestCase
             'Magento\Catalog\Helper\Product\Flat\Indexer'
         );
         $this->_state = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            '\Magento\Catalog\Model\Indexer\Product\Flat\State'
+            'Magento\Catalog\Model\Indexer\Product\Flat\State'
         );
     }
 
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/FullTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/FullTest.php
index c0e46ec17ba..73e8cfc2460 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/FullTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/FullTest.php
@@ -38,11 +38,11 @@ class FullTest extends \PHPUnit_Framework_TestCase
         $this->_processor->reindexAll();
 
         $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            '\Magento\Catalog\Model\CategoryFactory'
+            'Magento\Catalog\Model\CategoryFactory'
         );
         /** @var \Magento\Catalog\Block\Product\ListProduct $listProduct */
         $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            '\Magento\Catalog\Block\Product\ListProduct'
+            'Magento\Catalog\Block\Product\ListProduct'
         );
 
         $category = $categoryFactory->create()->load(2);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/RowTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/RowTest.php
index cf8a2af24f0..9b2f7a5ff76 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/RowTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/RowTest.php
@@ -33,11 +33,11 @@ class RowTest extends \PHPUnit_Framework_TestCase
         $product->save();
 
         $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            '\Magento\Catalog\Model\CategoryFactory'
+            'Magento\Catalog\Model\CategoryFactory'
         );
         /** @var \Magento\Catalog\Block\Product\ListProduct $listProduct */
         $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            '\Magento\Catalog\Block\Product\ListProduct'
+            'Magento\Catalog\Block\Product\ListProduct'
         );
 
         $category = $categoryFactory->create()->load(2);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/RowsTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/RowsTest.php
index ebddf818523..d6e7a0c6e24 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/RowsTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/RowsTest.php
@@ -42,11 +42,11 @@ class RowsTest extends \PHPUnit_Framework_TestCase
         );
 
         $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            '\Magento\Catalog\Model\CategoryFactory'
+            'Magento\Catalog\Model\CategoryFactory'
         );
         /** @var \Magento\Catalog\Block\Product\ListProduct $listProduct */
         $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            '\Magento\Catalog\Block\Product\ListProduct'
+            'Magento\Catalog\Block\Product\ListProduct'
         );
 
         $category = $categoryFactory->create()->load(2);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Action/FullTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Action/FullTest.php
index 91b50ef4850..679611aa5ec 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Action/FullTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Action/FullTest.php
@@ -31,10 +31,10 @@ class FullTest extends \PHPUnit_Framework_TestCase
         $this->_processor->reindexAll();
 
         $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            '\Magento\Catalog\Model\CategoryFactory'
+            'Magento\Catalog\Model\CategoryFactory'
         );
         $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            '\Magento\Catalog\Block\Product\ListProduct'
+            'Magento\Catalog\Block\Product\ListProduct'
         );
 
         $category = $categoryFactory->create()->load(2);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Action/RowTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Action/RowTest.php
index 6fc0d65ccb0..05e8cc116fb 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Action/RowTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Action/RowTest.php
@@ -37,10 +37,10 @@ class RowTest extends \PHPUnit_Framework_TestCase
     public function testProductUpdate()
     {
         $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            '\Magento\Catalog\Model\CategoryFactory'
+            'Magento\Catalog\Model\CategoryFactory'
         );
         $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            '\Magento\Catalog\Block\Product\ListProduct'
+            'Magento\Catalog\Block\Product\ListProduct'
         );
 
         $this->_processor->getIndexer()->setScheduled(false);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Action/RowsTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Action/RowsTest.php
index 85a40e054b2..949334c2aab 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Action/RowsTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Action/RowsTest.php
@@ -41,10 +41,10 @@ class RowsTest extends \PHPUnit_Framework_TestCase
         $this->_processor->reindexList([$this->_product->getId()]);
 
         $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            '\Magento\Catalog\Model\CategoryFactory'
+            'Magento\Catalog\Model\CategoryFactory'
         );
         $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            '\Magento\Catalog\Block\Product\ListProduct'
+            'Magento\Catalog\Block\Product\ListProduct'
         );
 
         $category = $categoryFactory->create()->load(9);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/DataProvider/PriceTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/DataProvider/PriceTest.php
index c98c982ae7d..4d0272067cc 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/DataProvider/PriceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/DataProvider/PriceTest.php
@@ -24,7 +24,7 @@ class PriceTest extends \PHPUnit_Framework_TestCase
         );
         $category->load(4);
         $layer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
-            ->get('\Magento\Catalog\Model\Layer\Category');
+            ->get('Magento\Catalog\Model\Layer\Category');
         $layer->setCurrentCategory($category);
         $this->_model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
             ->create('Magento\Catalog\Model\Layer\Filter\DataProvider\Price', ['layer' => $layer]);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/PriceTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/PriceTest.php
index e1ff64c14b7..51618660439 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/PriceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/PriceTest.php
@@ -28,12 +28,12 @@ class PriceTest extends \PHPUnit_Framework_TestCase
         );
         $category->load(4);
         $layer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
-            ->get('\Magento\Catalog\Model\Layer\Category');
+            ->get('Magento\Catalog\Model\Layer\Category');
         $layer->setCurrentCategory($category);
         $this->_model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
             ->create('Magento\Catalog\Model\Layer\Filter\Price', ['layer' => $layer]);
         $this->groupManagement = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
-            ->get('\Magento\Customer\Api\GroupManagementInterface');
+            ->get('Magento\Customer\Api\GroupManagementInterface');
     }
 
     public function testApplyNothing()
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/Product/Link/Product/CollectionTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/Product/Link/Product/CollectionTest.php
index f95746c869f..06ee8df098b 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/Product/Link/Product/CollectionTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/Product/Link/Product/CollectionTest.php
@@ -28,7 +28,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
     public function testAddLinkAttributeToFilterWithResults()
     {
         $om = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-        $link = $om->get('\Magento\Catalog\Model\Product\Link')->useCrossSellLinks();
+        $link = $om->get('Magento\Catalog\Model\Product\Link')->useCrossSellLinks();
         $this->collection->setLinkModel($link);
         $this->collection->addLinkAttributeToFilter('position', ['from' => 0, 'to' => 2]);
         $product = $om->get('Magento\Catalog\Model\Product')->load(2);
@@ -47,7 +47,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
     public function testAddLinkAttributeToFilterNoResults()
     {
         $om = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-        $link = $om->get('\Magento\Catalog\Model\Product\Link')->useCrossSellLinks();
+        $link = $om->get('Magento\Catalog\Model\Product\Link')->useCrossSellLinks();
         $this->collection->setLinkModel($link);
         $this->collection->addLinkAttributeToFilter('position', ['from' => 2, 'to' => 3]);
         $product = $om->get('Magento\Catalog\Model\Product')->load(2);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/Product/OptionTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/Product/OptionTest.php
index 38116e3a2ab..c0b5b823179 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/Product/OptionTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/Product/OptionTest.php
@@ -101,7 +101,7 @@ class OptionTest extends \PHPUnit_Framework_TestCase
 
         $title = $options[0]['values'][0]['title'];
         $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            '\Magento\Catalog\Model\Product'
+            'Magento\Catalog\Model\Product'
         );
         $product->load($productId);
         $product->setStoreIds([$storeId]);
@@ -152,7 +152,7 @@ class OptionTest extends \PHPUnit_Framework_TestCase
         $price = $options[0]['values'][0]['price'];
         $priceType = $options[0]['values'][0]['price_type'];
         $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            '\Magento\Catalog\Model\Product'
+            'Magento\Catalog\Model\Product'
         );
         $product->load($productId);
         $product->setStoreIds([$storeId]);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_with_image_attribute.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_with_image_attribute.php
index 7b1ac48421d..bdd5d6924e9 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_with_image_attribute.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_with_image_attribute.php
@@ -7,10 +7,10 @@
 $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
 
 /** @var \Magento\Eav\Model\Entity\Attribute\Set $attributeSet */
-$attributeSet = $objectManager->create('\Magento\Eav\Model\Entity\Attribute\Set');
+$attributeSet = $objectManager->create('Magento\Eav\Model\Entity\Attribute\Set');
 
 $entityType = $objectManager->create('Magento\Eav\Model\Entity\Type')->loadByCode('catalog_product');
-$defaultSetId = $objectManager->create('\Magento\Catalog\Model\Product')->getDefaultAttributeSetid();
+$defaultSetId = $objectManager->create('Magento\Catalog\Model\Product')->getDefaultAttributeSetid();
 
 $data = [
     'attribute_set_name' => 'attribute_set_with_media_attribute',
@@ -37,6 +37,6 @@ $attributeData = [
 ];
 
 /** @var \Magento\Catalog\Model\Entity\Attribute $attribute */
-$attribute = $objectManager->create('\Magento\Catalog\Model\Entity\Attribute');
+$attribute = $objectManager->create('Magento\Catalog\Model\Entity\Attribute');
 $attribute->setData($attributeData);
 $attribute->save();
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_with_image_attribute_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_with_image_attribute_rollback.php
index 645c7805786..117e9c4d0da 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_with_image_attribute_rollback.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/attribute_set_with_image_attribute_rollback.php
@@ -11,7 +11,7 @@ $entityType = $objectManager->create('Magento\Eav\Model\Entity\Type')->loadByCod
 // remove attribute
 
 /** @var \Magento\Catalog\Model\Resource\Product\Attribute\Collection $attributeCollection */
-$attributeCollection = $objectManager->create('\Magento\Catalog\Model\Resource\Product\Attribute\Collection');
+$attributeCollection = $objectManager->create('Magento\Catalog\Model\Resource\Product\Attribute\Collection');
 $attributeCollection->setFrontendInputTypeFilter('media_image');
 $attributeCollection->setCodeFilter('funny_image');
 $attributeCollection->setEntityTypeFilter($entityType->getId());
@@ -23,7 +23,7 @@ $attribute->delete();
 // remove attribute set
 
 /** @var \Magento\Eav\Model\Resource\Entity\Attribute\Set\Collection $attributeSetCollection */
-$attributeSetCollection = $objectManager->create('\Magento\Eav\Model\Resource\Entity\Attribute\Set\Collection');
+$attributeSetCollection = $objectManager->create('Magento\Eav\Model\Resource\Entity\Attribute\Set\Collection');
 $attributeSetCollection->addFilter('attribute_set_name', 'attribute_set_with_media_attribute');
 $attributeSetCollection->addFilter('entity_type_id', $entityType->getId());
 $attributeSetCollection->setOrder('attribute_set_id'); // descending is default value
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/empty_attribute_group.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/empty_attribute_group.php
index 28966589455..7a94a52af2d 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/_files/empty_attribute_group.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/empty_attribute_group.php
@@ -4,7 +4,7 @@
  */
 $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
 /** @var \Magento\Eav\Model\Entity\Attribute\Set $attributeSet */
-$attributeGroup = $objectManager->create('\Magento\Eav\Model\Entity\Attribute\Group');
+$attributeGroup = $objectManager->create('Magento\Eav\Model\Entity\Attribute\Group');
 $entityTypeId = $objectManager->create('Magento\Eav\Model\Entity\Type')->loadByCode('catalog_product')->getId();
 $attributeGroup->setData([
     'attribute_group_name' => 'empty_attribute_group',
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/empty_attribute_group_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/empty_attribute_group_rollback.php
index 2fd90f66832..64a41828d2d 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/_files/empty_attribute_group_rollback.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/empty_attribute_group_rollback.php
@@ -4,13 +4,13 @@
  */
 $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
 /** @var \Magento\Eav\Model\Entity\Attribute\Group $attributeSet */
-$attributeGroup = $objectManager->create('\Magento\Eav\Model\Entity\Attribute\Group')
+$attributeGroup = $objectManager->create('Magento\Eav\Model\Entity\Attribute\Group')
     ->load('empty_attribute_group', 'attribute_group_name');
 if ($attributeGroup->getId()) {
     $attributeGroup->delete();
 }
 
-$attributeGroupUpdated = $objectManager->create('\Magento\Eav\Model\Entity\Attribute\Group')
+$attributeGroupUpdated = $objectManager->create('Magento\Eav\Model\Entity\Attribute\Group')
     ->load('empty_attribute_group_updated', 'attribute_group_name');
 if ($attributeGroupUpdated->getId()) {
     $attributeGroupUpdated->delete();
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Config/Backend/ManagestockTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Config/Backend/ManagestockTest.php
index f4143ddb9cd..2c475a9f3e5 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Config/Backend/ManagestockTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Config/Backend/ManagestockTest.php
@@ -50,9 +50,9 @@ class ManagestockTest extends \PHPUnit_Framework_TestCase
             ->method('rebuild');
 
         $manageStock = new Managestock(
-            Bootstrap::getObjectManager()->get('\Magento\Framework\Model\Context'),
-            Bootstrap::getObjectManager()->get('\Magento\Framework\Registry'),
-            Bootstrap::getObjectManager()->get('\Magento\Framework\App\Config\ScopeConfigInterface'),
+            Bootstrap::getObjectManager()->get('Magento\Framework\Model\Context'),
+            Bootstrap::getObjectManager()->get('Magento\Framework\Registry'),
+            Bootstrap::getObjectManager()->get('Magento\Framework\App\Config\ScopeConfigInterface'),
             $stockManagement,
             Bootstrap::getObjectManager()->get('Magento\CatalogInventory\Model\Indexer\Stock\Processor'),
             Bootstrap::getObjectManager()->get('Magento\Core\Model\Resource\Config')
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/FullTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/FullTest.php
index d4fd95a0453..89cf2b837cf 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/FullTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/FullTest.php
@@ -31,11 +31,11 @@ class FullTest extends \PHPUnit_Framework_TestCase
         $this->_processor->reindexAll();
 
         $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            '\Magento\Catalog\Model\CategoryFactory'
+            'Magento\Catalog\Model\CategoryFactory'
         );
         /** @var \Magento\Catalog\Block\Product\ListProduct $listProduct */
         $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            '\Magento\Catalog\Block\Product\ListProduct'
+            'Magento\Catalog\Block\Product\ListProduct'
         );
 
         $category = $categoryFactory->create()->load(2);
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/RowTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/RowTest.php
index 026b38f8910..473cc73fee4 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/RowTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/RowTest.php
@@ -27,16 +27,16 @@ class RowTest extends \PHPUnit_Framework_TestCase
     public function testProductUpdate()
     {
         $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            '\Magento\Catalog\Model\CategoryFactory'
+            'Magento\Catalog\Model\CategoryFactory'
         );
         /** @var \Magento\Catalog\Block\Product\ListProduct $listProduct */
         $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            '\Magento\Catalog\Block\Product\ListProduct'
+            'Magento\Catalog\Block\Product\ListProduct'
         );
 
         /** @var \Magento\CatalogInventory\Api\Data\StockItemInterfaceBuilder $stockItemBuilder */
         $stockItemBuilder = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            '\Magento\CatalogInventory\Api\Data\StockItemInterfaceBuilder'
+            'Magento\CatalogInventory\Api\Data\StockItemInterfaceBuilder'
         );
 
         /** @var \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry */
@@ -45,7 +45,7 @@ class RowTest extends \PHPUnit_Framework_TestCase
         );
         /** @var \Magento\CatalogInventory\Api\StockItemRepositoryInterface $stockItemRepository */
         $stockItemRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            '\Magento\CatalogInventory\Api\StockItemRepositoryInterface'
+            'Magento\CatalogInventory\Api\StockItemRepositoryInterface'
         );
 
         $this->_processor->getIndexer()->setScheduled(false);
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/RowsTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/RowsTest.php
index 2d018b6e00c..402488cac91 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/RowsTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/RowsTest.php
@@ -27,16 +27,16 @@ class RowsTest extends \PHPUnit_Framework_TestCase
     public function testProductUpdate()
     {
         $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            '\Magento\Catalog\Model\CategoryFactory'
+            'Magento\Catalog\Model\CategoryFactory'
         );
         /** @var \Magento\Catalog\Block\Product\ListProduct $listProduct */
         $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            '\Magento\Catalog\Block\Product\ListProduct'
+            'Magento\Catalog\Block\Product\ListProduct'
         );
 
         /** @var \Magento\CatalogInventory\Api\Data\StockItemInterfaceBuilder $stockRegistry */
         $stockItemBuilder = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            '\Magento\CatalogInventory\Api\Data\StockItemInterfaceBuilder'
+            'Magento\CatalogInventory\Api\Data\StockItemInterfaceBuilder'
         );
 
         /** @var \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry */
@@ -45,12 +45,12 @@ class RowsTest extends \PHPUnit_Framework_TestCase
         );
         /** @var \Magento\CatalogInventory\Api\StockItemRepositoryInterface $stockItemRepository */
         $stockItemRepository = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            '\Magento\CatalogInventory\Api\StockItemRepositoryInterface'
+            'Magento\CatalogInventory\Api\StockItemRepositoryInterface'
         );
 
         /** @var \Magento\CatalogInventory\Model\Resource\Stock\Item $stockItemResource */
         $stockItemResource = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            '\Magento\CatalogInventory\Model\Resource\Stock\Item'
+            'Magento\CatalogInventory\Model\Resource\Stock\Item'
         );
 
         $stockItem = $stockRegistry->getStockItem(1, 1);
diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/Block/Advanced/ResultTest.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/Block/Advanced/ResultTest.php
index 7148428c9ac..f0e200b6362 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogSearch/Block/Advanced/ResultTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/Block/Advanced/ResultTest.php
@@ -48,7 +48,7 @@ class ResultTest extends \PHPUnit_Framework_TestCase
         $category->setId(100500); // Any id - just for layer navigation
         /** @var \Magento\Catalog\Model\Layer\Resolver $resolver */
         $resolver = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
-            ->get('\Magento\Catalog\Model\Layer\Resolver');
+            ->get('Magento\Catalog\Model\Layer\Resolver');
         $resolver->get()->setCurrentCategory($category);
 
         $childBlock = $this->_layout->addBlock('Magento\Framework\View\Element\Text', 'search_result_list', 'block');
diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/Helper/DataTest.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/Helper/DataTest.php
index ae968cbb819..00ab87d8936 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogSearch/Helper/DataTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/Helper/DataTest.php
@@ -16,7 +16,7 @@ class DataTest extends \PHPUnit_Framework_TestCase
         /** @var \Magento\TestFramework\ObjectManager  $objectManager */
         $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
         /** @var \Magento\Framework\App\Request\Http $request */
-        $request = $objectManager->get('\Magento\Framework\App\RequestInterface');
+        $request = $objectManager->get('Magento\Framework\App\RequestInterface');
         $request->setParam('q', 'five <words> here <being> tested');
         $this->_helper = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
             'Magento\CatalogSearch\Helper\Data'
diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php
index 2537014e94b..4fbd3a84f09 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php
@@ -23,7 +23,7 @@ class PriceTest extends \PHPUnit_Framework_TestCase
         );
         $category->load(4);
         $layer = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
-            ->get('\Magento\Catalog\Model\Layer\Category');
+            ->get('Magento\Catalog\Model\Layer\Category');
         $layer->setCurrentCategory($category);
         $this->_model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
             ->create('Magento\CatalogSearch\Model\Layer\Filter\Price', ['layer' => $layer]);
diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Search/CatalogTest.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Search/CatalogTest.php
index b55a860c1f7..0f0b6b748cc 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Search/CatalogTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Search/CatalogTest.php
@@ -16,7 +16,7 @@ class CatalogTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $this->catalogSearch = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
-            ->create('\Magento\CatalogSearch\Model\Search\Catalog');
+            ->create('Magento\CatalogSearch\Model\Search\Catalog');
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/Block/Onepage/BillingTest.php b/dev/tests/integration/testsuite/Magento/Checkout/Block/Onepage/BillingTest.php
index b97f1d0667c..ec857c1bde0 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/Block/Onepage/BillingTest.php
+++ b/dev/tests/integration/testsuite/Magento/Checkout/Block/Onepage/BillingTest.php
@@ -43,7 +43,7 @@ class BillingTest extends \PHPUnit_Framework_TestCase
         $this->_customerRepository = $objectManager->create('Magento\Customer\Api\CustomerRepositoryInterface');
         $customer = $this->_customerRepository->getById(self::FIXTURE_CUSTOMER_ID);
 
-        $customerSession = $objectManager->get('\Magento\Customer\Model\Session');
+        $customerSession = $objectManager->get('Magento\Customer\Model\Session');
         $customerSession->setCustomerData($customer);
 
         $this->_addressRepository = $objectManager->get('Magento\Customer\Api\AddressRepositoryInterface');
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/Controller/OnepageTest.php b/dev/tests/integration/testsuite/Magento/Checkout/Controller/OnepageTest.php
index cde2a86b105..228ed3b174f 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/Controller/OnepageTest.php
+++ b/dev/tests/integration/testsuite/Magento/Checkout/Controller/OnepageTest.php
@@ -56,7 +56,7 @@ class OnepageTest extends \Magento\TestFramework\TestCase\AbstractController
 
     public function testSaveOrderActionWithFormKey()
     {
-        $formKey = $this->_objectManager->get('\Magento\Framework\Data\Form\FormKey');
+        $formKey = $this->_objectManager->get('Magento\Framework\Data\Form\FormKey');
         $this->getRequest()->setParam('form_key', $formKey->getFormKey());
         $this->dispatch('checkout/onepage/saveOrder');
         $html = $this->getResponse()->getBody();
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_address_saved_rollback.php b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_address_saved_rollback.php
index 72299fe0f47..de7d649c73c 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_address_saved_rollback.php
+++ b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_address_saved_rollback.php
@@ -7,5 +7,5 @@
 
 /** @var $objectManager \Magento\TestFramework\ObjectManager */
 $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-$quote = $objectManager->create('\Magento\Sales\Model\Quote');
+$quote = $objectManager->create('Magento\Sales\Model\Quote');
 $quote->load('test_order_1', 'reserved_order_id')->delete();
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_coupon_saved_rollback.php b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_coupon_saved_rollback.php
index 3ab5c1e99b4..1cd90ff860e 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_coupon_saved_rollback.php
+++ b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_coupon_saved_rollback.php
@@ -7,5 +7,5 @@
 
 /** @var $objectManager \Magento\TestFramework\ObjectManager */
 $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-$quote = $objectManager->create('\Magento\Sales\Model\Quote');
+$quote = $objectManager->create('Magento\Sales\Model\Quote');
 $quote->load('test_order_1', 'reserved_order_id')->delete();
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_payment_saved_rollback.php b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_payment_saved_rollback.php
index 86ddf3132a3..9e17789926a 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_payment_saved_rollback.php
+++ b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_payment_saved_rollback.php
@@ -7,5 +7,5 @@
 
 /** @var $objectManager \Magento\TestFramework\ObjectManager */
 $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-$quote = $objectManager->create('\Magento\Sales\Model\Quote');
+$quote = $objectManager->create('Magento\Sales\Model\Quote');
 $quote->load('test_order_1_with_payment', 'reserved_order_id')->delete();
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_simple_product_saved_rollback.php b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_simple_product_saved_rollback.php
index 89f9c1904bc..b10d221b9c7 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_simple_product_saved_rollback.php
+++ b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_simple_product_saved_rollback.php
@@ -7,5 +7,5 @@
 
 /** @var $objectManager \Magento\TestFramework\ObjectManager */
 $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-$quote = $objectManager->create('\Magento\Sales\Model\Quote');
+$quote = $objectManager->create('Magento\Sales\Model\Quote');
 $quote->load('test_order_with_simple_product_without_address', 'reserved_order_id')->delete();
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_virtual_product_and_address_rollback.php b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_virtual_product_and_address_rollback.php
index 23b3ce94d60..4a8529c87fb 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_virtual_product_and_address_rollback.php
+++ b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_virtual_product_and_address_rollback.php
@@ -6,5 +6,5 @@
  */
 /** @var $objectManager \Magento\TestFramework\ObjectManager */
 $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-$quote = $objectManager->create('\Magento\Sales\Model\Quote');
+$quote = $objectManager->create('Magento\Sales\Model\Quote');
 $quote->load('test_order_with_virtual_product', 'reserved_order_id')->delete();
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_virtual_product_saved_rollback.php b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_virtual_product_saved_rollback.php
index 4b569f04613..95e6b8af75f 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_virtual_product_saved_rollback.php
+++ b/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_virtual_product_saved_rollback.php
@@ -7,5 +7,5 @@
 
 /** @var $objectManager \Magento\TestFramework\ObjectManager */
 $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-$quote = $objectManager->create('\Magento\Sales\Model\Quote');
+$quote = $objectManager->create('Magento\Sales\Model\Quote');
 $quote->load('test_order_with_virtual_product_without_address', 'reserved_order_id')->delete();
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Api/AddressRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Customer/Api/AddressRepositoryTest.php
index 4f7d447b7b0..ec1aeb73a48 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Api/AddressRepositoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Api/AddressRepositoryTest.php
@@ -34,7 +34,7 @@ class AddressRepositoryTest extends \PHPUnit_Framework_TestCase
         $this->repository = $this->_objectManager->create('Magento\Customer\Api\AddressRepositoryInterface');
         $this->_addressBuilder = $this->_objectManager->create('Magento\Customer\Api\Data\AddressDataBuilder');
 
-        $builder = $this->_objectManager->create('\Magento\Customer\Api\Data\RegionDataBuilder');
+        $builder = $this->_objectManager->create('Magento\Customer\Api\Data\RegionDataBuilder');
         $region = $builder
             ->setRegionCode('AL')
             ->setRegion('Alabama')
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Address/EditTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Address/EditTest.php
index 9ce8d04c04a..5f75bfa8f19 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Block/Address/EditTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Address/EditTest.php
@@ -25,7 +25,7 @@ class EditTest extends \PHPUnit_Framework_TestCase
     {
         $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
 
-        $this->_customerSession = $objectManager->get('\Magento\Customer\Model\Session');
+        $this->_customerSession = $objectManager->get('Magento\Customer\Model\Session');
         $this->_customerSession->setCustomerId(1);
 
         $this->_context = $objectManager->get('Magento\Backend\Block\Template\Context');
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/AccountTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/AccountTest.php
index 910039c9d8b..c66adba030c 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/AccountTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/AccountTest.php
@@ -167,7 +167,7 @@ class AccountTest extends \PHPUnit_Framework_TestCase
     public function testNewCustomer()
     {
         /** @var \Magento\Customer\Api\Data\CustomerDataBuilder $customerBuilder */
-        $customerBuilder = $this->objectManager->get('\Magento\Customer\Api\Data\CustomerDataBuilder');
+        $customerBuilder = $this->objectManager->get('Magento\Customer\Api\Data\CustomerDataBuilder');
         $customerData = $this->dataObjectProcessor
             ->buildOutputDataArray($customerBuilder->create(), '\Magento\Customer\Api\Data\CustomerInterface');
         $this->backendSession->setCustomerData(
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfoTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfoTest.php
index 8f771f5dfd6..e67b270c569 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfoTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/View/PersonalInfoTest.php
@@ -65,7 +65,7 @@ class PersonalInfoTest extends \PHPUnit_Framework_TestCase
         $this->_dataObjectProcessor = $this->_objectManager->get('Magento\Framework\Reflection\DataObjectProcessor');
 
         $this->_groupRepository = $this->_objectManager->get('Magento\Customer\Api\GroupRepositoryInterface');
-        $this->dateTime = $this->_objectManager->get('\Magento\Framework\Stdlib\DateTime');
+        $this->dateTime = $this->_objectManager->get('Magento\Framework\Stdlib\DateTime');
 
         $this->_block = $this->_objectManager->get(
             'Magento\Framework\View\LayoutInterface'
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Group/EditTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Group/EditTest.php
index f0ab8217eb8..9fe6f349d50 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Group/EditTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Group/EditTest.php
@@ -80,7 +80,7 @@ class EditTest extends AbstractController
      */
     public function testDeleteButtonExistInCustomGroup()
     {
-        $builder = Bootstrap::getObjectManager()->create('\Magento\Framework\Api\FilterBuilder');
+        $builder = Bootstrap::getObjectManager()->create('Magento\Framework\Api\FilterBuilder');
         /** @var \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteria */
         $searchCriteria = Bootstrap::getObjectManager()
             ->create('Magento\Framework\Api\SearchCriteriaBuilder')
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Cart/Product/Composite/CartTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Cart/Product/Composite/CartTest.php
index 4bf13eed6fc..426b24433e2 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Cart/Product/Composite/CartTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/Adminhtml/Cart/Product/Composite/CartTest.php
@@ -18,7 +18,7 @@ class CartTest extends \Magento\Backend\Utility\Controller
     {
         parent::setUp();
         $this->quoteItemCollectionFactory = $this->_objectManager->get(
-            '\Magento\Sales\Model\Resource\Quote\Item\CollectionFactory'
+            'Magento\Sales\Model\Resource\Quote\Item\CollectionFactory'
         );
     }
 
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/AddressRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/AddressRepositoryTest.php
index ebdd0e35727..113c9eb6d69 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/AddressRepositoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/AddressRepositoryTest.php
@@ -35,7 +35,7 @@ class AddressRepositoryTest extends \PHPUnit_Framework_TestCase
         $this->repository = $this->_objectManager->create('Magento\Customer\Api\AddressRepositoryInterface');
         $this->_addressBuilder = $this->_objectManager->create('Magento\Customer\Api\Data\AddressDataBuilder');
 
-        $builder = $this->_objectManager->create('\Magento\Customer\Api\Data\RegionDataBuilder');
+        $builder = $this->_objectManager->create('Magento\Customer\Api\Data\RegionDataBuilder');
         $region = $builder
             ->setRegionCode('AL')
             ->setRegion('Alabama')
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/CustomerRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/CustomerRepositoryTest.php
index 103fe685bde..24210493d4d 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/CustomerRepositoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/CustomerRepositoryTest.php
@@ -271,7 +271,7 @@ class CustomerRepositoryTest extends \PHPUnit_Framework_TestCase
 
     public function searchCustomersDataProvider()
     {
-        $builder = Bootstrap::getObjectManager()->create('\Magento\Framework\Api\FilterBuilder');
+        $builder = Bootstrap::getObjectManager()->create('Magento\Framework\Api\FilterBuilder');
         return [
             'Customer with specific email' => [
                 [$builder->setField('email')->setValue('customer@search.example.com')->create()],
@@ -321,14 +321,14 @@ class CustomerRepositoryTest extends \PHPUnit_Framework_TestCase
         $searchBuilder = $objectManager->create('Magento\Framework\Api\SearchCriteriaDataBuilder');
 
         // Filter for 'firstname' like 'First'
-        $filterBuilder = $objectManager->create('\Magento\Framework\Api\FilterBuilder');
+        $filterBuilder = $objectManager->create('Magento\Framework\Api\FilterBuilder');
         $firstnameFilter = $filterBuilder->setField('firstname')
             ->setConditionType('like')
             ->setValue('First%')
             ->create();
         $searchBuilder->addFilter([$firstnameFilter]);
         // Search ascending order
-        $sortOrderBuilder = $objectManager->create('\Magento\Framework\Api\SortOrderBuilder');
+        $sortOrderBuilder = $objectManager->create('Magento\Framework\Api\SortOrderBuilder');
         $sortOrder = $sortOrderBuilder
             ->setField('lastname')
             ->setDirection(SearchCriteriaInterface::SORT_ASC)
diff --git a/dev/tests/integration/testsuite/Magento/Customer/_files/customer.php b/dev/tests/integration/testsuite/Magento/Customer/_files/customer.php
index 5d196d0bb08..aa4af34c98f 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/_files/customer.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/_files/customer.php
@@ -5,7 +5,7 @@
 
 $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
 /** @var $repository \Magento\Customer\Api\CustomerRepositoryInterface */
-$repository = $objectManager->create('\Magento\Customer\Api\CustomerRepositoryInterface');
+$repository = $objectManager->create('Magento\Customer\Api\CustomerRepositoryInterface');
 $customer = $objectManager->create('Magento\Customer\Model\Customer');
 
 /** @var Magento\Customer\Model\Customer $customer */
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Data/Form/Element/DateTest.php b/dev/tests/integration/testsuite/Magento/Framework/Data/Form/Element/DateTest.php
index 65ed2f489ee..0628f7d67ef 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Data/Form/Element/DateTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Data/Form/Element/DateTest.php
@@ -24,7 +24,7 @@ class DateTest extends \PHPUnit_Framework_TestCase
     {
         $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
         $this->_elementFactory = $objectManager->create('Magento\Framework\Data\Form\ElementFactory');
-        $this->_localeDate = $objectManager->get('\Magento\Framework\Stdlib\DateTime\Timezone');
+        $this->_localeDate = $objectManager->get('Magento\Framework\Stdlib\DateTime\Timezone');
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Module/DataSetupTest.php b/dev/tests/integration/testsuite/Magento/Framework/Module/DataSetupTest.php
index 1186ce0262e..23adfd02785 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Module/DataSetupTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Module/DataSetupTest.php
@@ -23,7 +23,7 @@ class DataSetupTest extends \PHPUnit_Framework_TestCase
     {
         /* reset data version */
         \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            '\Magento\Framework\Module\ResourceInterface'
+            'Magento\Framework\Module\ResourceInterface'
         )->setDataVersion(
             'adminnotification_setup',
             false
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Module/Plugin/DbStatusValidatorTest.php b/dev/tests/integration/testsuite/Magento/Framework/Module/Plugin/DbStatusValidatorTest.php
index c4fad76c42d..fa8fe5f9b6d 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Module/Plugin/DbStatusValidatorTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Module/Plugin/DbStatusValidatorTest.php
@@ -24,7 +24,7 @@ class DbStatusValidatorTest extends \Magento\TestFramework\TestCase\AbstractCont
         $moduleList = $objectManager->get('Magento\Framework\Module\ModuleListInterface');
 
         /** @var \Magento\Framework\Module\ResourceResolverInterface $resourceResolver */
-        $resourceResolver = $objectManager->get('\Magento\Framework\Module\ResourceResolverInterface');
+        $resourceResolver = $objectManager->get('Magento\Framework\Module\ResourceResolverInterface');
 
         // get first resource, we don't care which one it is.
         foreach ($moduleList->getNames() as $moduleName) {
diff --git a/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php b/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php
index 394581ba4bd..0a3f75362d9 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php
@@ -83,7 +83,7 @@ class AdapterTest extends \PHPUnit_Framework_TestCase
     private function reindexAll()
     {
         /** @var \Magento\Indexer\Model\Indexer[] $indexerList */
-        $indexerList = $this->objectManager->get('\Magento\Indexer\Model\Indexer\CollectionFactory')
+        $indexerList = $this->objectManager->get('Magento\Indexer\Model\Indexer\CollectionFactory')
             ->create()
             ->getItems();
 
diff --git a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_item_message.php b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_item_message.php
index 02c9732fd2d..7327f57113a 100644
--- a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_item_message.php
+++ b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_item_message.php
@@ -37,7 +37,7 @@ $quote->setReservedOrderId('test_order_item_with_message')
 $quote->collectTotals()->save();
 
 /** @var \Magento\GiftMessage\Model\Message $message */
-$message = $objectManager->create('\Magento\GiftMessage\Model\Message');
+$message = $objectManager->create('Magento\GiftMessage\Model\Message');
 $message->setSender('John Doe');
 $message->setRecipient('Jane Roe');
 $message->setMessage('Gift Message Text');
diff --git a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_item_message_rollback.php b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_item_message_rollback.php
index c71266ff03a..3e591550b0f 100644
--- a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_item_message_rollback.php
+++ b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_item_message_rollback.php
@@ -9,7 +9,7 @@ $registry->register('isSecureArea', true);
 $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
 $quote = $objectManager->create('Magento\Sales\Model\Quote');
 $quote->load('test_order_item_with_message', 'reserved_order_id');
-$message = $objectManager->create('\Magento\GiftMessage\Model\Message');
+$message = $objectManager->create('Magento\GiftMessage\Model\Message');
 $product = $objectManager->create('Magento\Catalog\Model\Product');
 foreach ($quote->getAllItems() as $item) {
     $message->load($item->getGiftMessageId());
diff --git a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_message.php b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_message.php
index ac79d7407e5..3cdc3632d35 100644
--- a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_message.php
+++ b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_message.php
@@ -6,7 +6,7 @@
 $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
 
 /** @var \Magento\GiftMessage\Model\Message $message */
-$message = $objectManager->create('\Magento\GiftMessage\Model\Message');
+$message = $objectManager->create('Magento\GiftMessage\Model\Message');
 $message->setSender('Romeo');
 $message->setRecipient('Mercutio');
 $message->setMessage('I thought all for the best.');
diff --git a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_message_rollback.php b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_message_rollback.php
index 020bd49302f..d812b302dd6 100644
--- a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_message_rollback.php
+++ b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/quote_with_message_rollback.php
@@ -10,7 +10,7 @@ $quote = $objectManager->create('Magento\Sales\Model\Quote');
 $quote->load('message_order_21', 'reserved_order_id');
 
 /** @var \Magento\GiftMessage\Model\Message $message */
-$message = $objectManager->create('\Magento\GiftMessage\Model\Message');
+$message = $objectManager->create('Magento\GiftMessage\Model\Message');
 $message->load($quote->getGiftMessageId());
 $message->delete();
 
diff --git a/dev/tests/integration/testsuite/Magento/Multishipping/Block/Checkout/Address/SelectTest.php b/dev/tests/integration/testsuite/Magento/Multishipping/Block/Checkout/Address/SelectTest.php
index 9f4f37ead61..ba1ea5ac55f 100644
--- a/dev/tests/integration/testsuite/Magento/Multishipping/Block/Checkout/Address/SelectTest.php
+++ b/dev/tests/integration/testsuite/Magento/Multishipping/Block/Checkout/Address/SelectTest.php
@@ -31,7 +31,7 @@ class SelectTest extends \PHPUnit_Framework_TestCase
     {
         /** @var \Magento\Customer\Api\AddressRepositoryInterface $addressRepository */
         $addressRepository = Bootstrap::getObjectManager()->create(
-            '\Magento\Customer\Api\AddressRepositoryInterface'
+            'Magento\Customer\Api\AddressRepositoryInterface'
         );
         $fixtureAddressId = 1;
         $address = $addressRepository->getById($fixtureAddressId);
diff --git a/dev/tests/integration/testsuite/Magento/Newsletter/Block/Adminhtml/Queue/Edit/FormTest.php b/dev/tests/integration/testsuite/Magento/Newsletter/Block/Adminhtml/Queue/Edit/FormTest.php
index 6849d9ffd89..aeee37329df 100644
--- a/dev/tests/integration/testsuite/Magento/Newsletter/Block/Adminhtml/Queue/Edit/FormTest.php
+++ b/dev/tests/integration/testsuite/Magento/Newsletter/Block/Adminhtml/Queue/Edit/FormTest.php
@@ -18,7 +18,7 @@ class FormTest extends \PHPUnit_Framework_TestCase
         $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
         $queue = $objectManager->get('Magento\Newsletter\Model\Queue');
         /** @var \Magento\Framework\Registry $registry */
-        $registry = $objectManager->get('\Magento\Framework\Registry');
+        $registry = $objectManager->get('Magento\Framework\Registry');
         $registry->register('current_queue', $queue);
 
         $objectManager->get(
diff --git a/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/FormTest.php b/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/FormTest.php
index b442c566996..8c81582f654 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/FormTest.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/FormTest.php
@@ -86,8 +86,8 @@ ORDER_DATA_JSON;
 
     private function setUpMockAddress()
     {
-        $regionBuilder1 = $this->_objectManager->create('\Magento\Customer\Api\Data\RegionDataBuilder');
-        $regionBuilder2 = $this->_objectManager->create('\Magento\Customer\Api\Data\RegionDataBuilder');
+        $regionBuilder1 = $this->_objectManager->create('Magento\Customer\Api\Data\RegionDataBuilder');
+        $regionBuilder2 = $this->_objectManager->create('Magento\Customer\Api\Data\RegionDataBuilder');
 
         /** @var \Magento\Customer\Api\Data\AddressDataBuilder $addressBuilder */
         $addressBuilder = $this->_objectManager->create('Magento\Customer\Api\Data\AddressDataBuilder');
diff --git a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php
index 5c50ad08fc1..9750f9707be 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php
@@ -108,7 +108,7 @@ class CreateTest extends \Magento\Backend\Utility\Controller
     public function testGetAclResource($actionName, $reordered, $expectedResult)
     {
         $this->_objectManager->get('Magento\Backend\Model\Session\Quote')->setReordered($reordered);
-        $orderController = $this->_objectManager->get('\Magento\Sales\Controller\Adminhtml\Order\Create');
+        $orderController = $this->_objectManager->get('Magento\Sales\Controller\Adminhtml\Order\Create');
 
         $this->getRequest()->setActionName($actionName);
 
diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/QuoteTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/QuoteTest.php
index 2bfff2ec255..356f1b8d016 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/Model/QuoteTest.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/Model/QuoteTest.php
@@ -68,7 +68,7 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
          * @var \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository
          */
         $customerRepository = Bootstrap::getObjectManager()
-            ->create('\Magento\Customer\Api\CustomerRepositoryInterface');
+            ->create('Magento\Customer\Api\CustomerRepositoryInterface');
         $customerRepository->save($customerDataSet);
         $quote->setCustomer($customerDataSet);
         $expected = $this->_getCustomerDataArray();
diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/Resource/OrderTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/Resource/OrderTest.php
index f9da905c795..9d10fd0bb27 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/Model/Resource/OrderTest.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/Model/Resource/OrderTest.php
@@ -24,7 +24,7 @@ class OrderTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-        $this->resourceModel = $this->objectManager->create('\Magento\Sales\Model\Resource\Order');
+        $this->resourceModel = $this->objectManager->create('Magento\Sales\Model\Resource\Order');
         $this->orderIncrementId = '100000001';
     }
 
diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_for_get.php b/dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_for_get.php
index 53494019e75..e61b8202340 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_for_get.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/_files/creditmemo_for_get.php
@@ -20,7 +20,7 @@ $creditmemo->setIncrementId('100000001');
 $creditmemo->save();
 
 /** @var \Magento\Sales\Model\Order\Item $orderItem */
-$orderItem = $objectManager->get('\Magento\Sales\Model\Order\Item');
+$orderItem = $objectManager->get('Magento\Sales\Model\Order\Item');
 $orderItem->setName('Test item')
     ->setQtyRefunded(1)
     ->setQtyInvoiced(10)
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SubtotalTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SubtotalTest.php
index fbe32032429..6f24cee6597 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SubtotalTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SubtotalTest.php
@@ -106,11 +106,11 @@ class SubtotalTest extends \PHPUnit_Framework_TestCase
         $address = $quote->getShippingAddress();
 
         /** @var \Magento\Sales\Model\Quote\Address\Total\Subtotal $addressSubtotalCollector */
-        $addressSubtotalCollector = $this->objectManager->create('\Magento\Sales\Model\Quote\Address\Total\Subtotal');
+        $addressSubtotalCollector = $this->objectManager->create('Magento\Sales\Model\Quote\Address\Total\Subtotal');
         $addressSubtotalCollector->collect($address);
 
         /** @var \Magento\Tax\Model\Sales\Total\Quote\Subtotal $subtotalCollector */
-        $subtotalCollector = $this->objectManager->create('\Magento\Tax\Model\Sales\Total\Quote\Subtotal');
+        $subtotalCollector = $this->objectManager->create('Magento\Tax\Model\Sales\Total\Quote\Subtotal');
         $subtotalCollector->collect($address);
 
         $this->assertEquals($expected['subtotal'], $address->getSubtotal());
@@ -221,11 +221,11 @@ class SubtotalTest extends \PHPUnit_Framework_TestCase
         $address = $quote->getShippingAddress();
 
         /** @var \Magento\Sales\Model\Quote\Address\Total\Subtotal $addressSubtotalCollector */
-        $addressSubtotalCollector = $this->objectManager->create('\Magento\Sales\Model\Quote\Address\Total\Subtotal');
+        $addressSubtotalCollector = $this->objectManager->create('Magento\Sales\Model\Quote\Address\Total\Subtotal');
         $addressSubtotalCollector->collect($address);
 
         /** @var \Magento\Tax\Model\Sales\Total\Quote\Subtotal $subtotalCollector */
-        $subtotalCollector = $this->objectManager->create('\Magento\Tax\Model\Sales\Total\Quote\Subtotal');
+        $subtotalCollector = $this->objectManager->create('Magento\Tax\Model\Sales\Total\Quote\Subtotal');
         $subtotalCollector->collect($address);
 
         $this->assertEquals($expected['subtotal'], $address->getSubtotal());
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxRuleRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxRuleRepositoryTest.php
index 9d67c1a1ba1..57d6eec4bbc 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxRuleRepositoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxRuleRepositoryTest.php
@@ -310,7 +310,7 @@ class TaxRuleRepositoryTest extends \PHPUnit_Framework_TestCase
 
     public function searchTaxRulesDataProvider()
     {
-        $filterBuilder = Bootstrap::getObjectManager()->create('\Magento\Framework\Api\FilterBuilder');
+        $filterBuilder = Bootstrap::getObjectManager()->create('Magento\Framework\Api\FilterBuilder');
 
         return [
             'code eq "Default Rule"' => [
diff --git a/dev/tests/integration/testsuite/Magento/Webapi/Model/PathProcessorTest.php b/dev/tests/integration/testsuite/Magento/Webapi/Model/PathProcessorTest.php
index 0f881df4bc9..3b159bc71b4 100644
--- a/dev/tests/integration/testsuite/Magento/Webapi/Model/PathProcessorTest.php
+++ b/dev/tests/integration/testsuite/Magento/Webapi/Model/PathProcessorTest.php
@@ -21,7 +21,7 @@ class PathProcessorTest extends \PHPUnit_Framework_TestCase
     {
         $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
         $this->storeManager = $objectManager->get('Magento\Store\Model\StoreManagerInterface');
-        $this->pathProcessor = $objectManager->get('\Magento\Webapi\Model\PathProcessor');
+        $this->pathProcessor = $objectManager->get('Magento\Webapi\Model\PathProcessor');
     }
 
     /**
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/Translate/Inline/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/Translate/Inline/ConfigTest.php
index 8178a8f98b8..6796ff7b20e 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/Translate/Inline/ConfigTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Translate/Inline/ConfigTest.php
@@ -21,7 +21,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
         );
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $config = $objectManager->getObject(
-            '\Magento\Backend\Model\Translate\Inline\Config',
+            'Magento\Backend\Model\Translate\Inline\Config',
             ['config' => $backendConfig]
         );
         $this->assertEquals($result, $config->isActive('any'));
diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Model/Plugin/PriceBackendTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Model/Plugin/PriceBackendTest.php
index 169b42dce90..531e403b2b1 100644
--- a/dev/tests/unit/testsuite/Magento/Bundle/Model/Plugin/PriceBackendTest.php
+++ b/dev/tests/unit/testsuite/Magento/Bundle/Model/Plugin/PriceBackendTest.php
@@ -24,7 +24,7 @@ class PriceBackendTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $objectManager = new ObjectManager($this);
-        $this->priceBackendPlugin = $objectManager->getObject('\Magento\Bundle\Model\Plugin\PriceBackend');
+        $this->priceBackendPlugin = $objectManager->getObject('Magento\Bundle\Model\Plugin\PriceBackend');
 
         $this->closure = function () {
             return static::CLOSURE_VALUE;
diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Model/Plugin/ProductTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Model/Plugin/ProductTest.php
index aacd23afdc7..5751d3ce996 100644
--- a/dev/tests/unit/testsuite/Magento/Bundle/Model/Plugin/ProductTest.php
+++ b/dev/tests/unit/testsuite/Magento/Bundle/Model/Plugin/ProductTest.php
@@ -34,7 +34,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
             ->getMock();
 
         $this->plugin = $objectManager->getObject(
-            '\Magento\Bundle\Model\Plugin\Product',
+            'Magento\Bundle\Model\Plugin\Product',
             [
                 'type' => $this->type,
             ]
diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Model/Product/OptionListTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Model/Product/OptionListTest.php
index 4a6e8fdea8d..e8cdedd266e 100644
--- a/dev/tests/unit/testsuite/Magento/Bundle/Model/Product/OptionListTest.php
+++ b/dev/tests/unit/testsuite/Magento/Bundle/Model/Product/OptionListTest.php
@@ -63,7 +63,7 @@ class OptionListTest extends \PHPUnit_Framework_TestCase
         );
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $optionsCollMock = $objectManager->getCollectionMock(
-            '\Magento\Bundle\Model\Resource\Option\Collection',
+            'Magento\Bundle\Model\Resource\Option\Collection',
             [$optionMock]
         );
         $this->typeMock->expects($this->once())
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/CategoryTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/CategoryTest.php
index 416050c0d71..9c433061847 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/CategoryTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/CategoryTest.php
@@ -34,7 +34,7 @@ class CategoryTest extends \PHPUnit_Framework_TestCase
             ->method('isAllowed')
             ->will($this->returnValue($isAllowed));
         $model = $this->objectManager->getObject(
-            '\Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Category',
+            'Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Category',
             ['authorization' => $this->authorization]
         );
         switch ($isAllowed) {
@@ -60,7 +60,7 @@ class CategoryTest extends \PHPUnit_Framework_TestCase
     public function testGetAfterElementHtml()
     {
         $model = $this->objectManager->getObject(
-            '\Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Category',
+            'Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Category',
             ['authorization' => $this->authorization]
         );
         $this->authorization->expects($this->any())
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/WeightTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/WeightTest.php
index e4c9298ab93..02d63ad6b97 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/WeightTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/WeightTest.php
@@ -84,7 +84,7 @@ class WeightTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->_model = $objectManager->getObject(
-            '\Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Weight',
+            'Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Weight',
             ['factoryElement' => $factory, 'factoryCollection' => $collectionFactory, 'helper' => $helper]
         );
 
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/ConfigTest.php
index 4760cbfea68..06236231c14 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/ConfigTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/ConfigTest.php
@@ -22,7 +22,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
         );
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $model = $objectManager->getObject(
-            '\Magento\Catalog\Model\Config',
+            'Magento\Catalog\Model\Config',
             ['setCollectionFactory' => $setCollectionFactory]
         );
         $setItem = $this->getMock(
@@ -81,7 +81,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
         );
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $model = $objectManager->getObject(
-            '\Magento\Catalog\Model\Config',
+            'Magento\Catalog\Model\Config',
             ['groupCollectionFactory' => $groupCollectionFactory]
         );
         $setItem = $this->getMock(
@@ -137,7 +137,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
         $productTypeFactory = $this->getMock('\Magento\Catalog\Model\Product\TypeFactory', ['create'], [], '', false);
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $model = $objectManager->getObject(
-            '\Magento\Catalog\Model\Config',
+            'Magento\Catalog\Model\Config',
             ['productTypeFactory' => $productTypeFactory]
         );
         $typeCollection = $this->getMock('\Magento\Catalog\Model\Product\Type', ['getOptionArray'], [], '', false);
@@ -183,7 +183,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
         $object = $this->getMock('\Magento\Framework\Object', ['getAllOptions'], [], '', false);
         $object->expects($this->once())->method('getAllOptions')->will($this->returnValue($data));
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $model = $objectManager->getObject('\Magento\Catalog\Model\Config');
+        $model = $objectManager->getObject('Magento\Catalog\Model\Config');
         $this->assertEquals($expected, $model->getSourceOptionId($object, $search));
     }
 
@@ -254,7 +254,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
 
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $model = $objectManager->getObject(
-            '\Magento\Catalog\Model\Config',
+            'Magento\Catalog\Model\Config',
             ['configFactory' => $configFactory, 'storeManager' => $storeManager, 'eavConfig' => $eavConfig]
         );
 
@@ -314,7 +314,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
         $scopeConfig->expects($this->once())->method('getValue')
             ->with('catalog/frontend/default_sort_by', 'store', null)->will($this->returnValue(1));
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $model = $objectManager->getObject('\Magento\Catalog\Model\Config', ['scopeConfig' => $scopeConfig]);
+        $model = $objectManager->getObject('Magento\Catalog\Model\Config', ['scopeConfig' => $scopeConfig]);
         $this->assertEquals(1, $model->getProductListDefaultSortBy());
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Price/ObserverTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Price/ObserverTest.php
index cd70ab51464..7fe4c17e397 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Price/ObserverTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Price/ObserverTest.php
@@ -70,7 +70,7 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->_model = $this->_objectManager->getObject(
-            '\Magento\Catalog\Model\Indexer\Product\Price\Observer',
+            'Magento\Catalog\Model\Indexer\Product\Price\Observer',
             [
                 'storeManager' => $this->_storeManagerMock,
                 'resource' => $this->_resourceMock,
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Plugin/CustomerGroupTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Plugin/CustomerGroupTest.php
index d2d7da59dd8..52b3b6a1fc8 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Plugin/CustomerGroupTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Plugin/CustomerGroupTest.php
@@ -49,7 +49,7 @@ class CustomerGroupTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue($indexerMock));
 
         $this->_model = $this->_objectManager->getObject(
-            '\Magento\Catalog\Model\Indexer\Product\Price\Plugin\CustomerGroup',
+            'Magento\Catalog\Model\Indexer\Product\Price\Plugin\CustomerGroup',
             ['indexerRegistry' => $this->indexerRegistryMock]
         );
     }
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Plugin/WebsiteTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Plugin/WebsiteTest.php
index 182203e835e..3dcc701027f 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Plugin/WebsiteTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Price/Plugin/WebsiteTest.php
@@ -34,7 +34,7 @@ class WebsiteTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->_model = $this->_objectManager->getObject(
-            '\Magento\Catalog\Model\Indexer\Product\Price\Plugin\Website',
+            'Magento\Catalog\Model\Indexer\Product\Price\Plugin\Website',
             ['processor' => $this->_priceProcessorMock]
         );
     }
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Price/System/Config/PriceScopeTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Price/System/Config/PriceScopeTest.php
index cf4d702fa65..f3125755230 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Price/System/Config/PriceScopeTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Price/System/Config/PriceScopeTest.php
@@ -46,7 +46,7 @@ class PriceScopeTest extends \PHPUnit_Framework_TestCase
 
 
         $this->_model = $this->_objectManager->getObject(
-            '\Magento\Catalog\Model\Indexer\Product\Price\System\Config\PriceScope',
+            'Magento\Catalog\Model\Indexer\Product\Price\System\Config\PriceScope',
             [
                 'context' => $contextMock,
                 'registry' => $registryMock,
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/ObserverTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/ObserverTest.php
index 8000b58eaa2..dbb81426dd2 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/ObserverTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/ObserverTest.php
@@ -61,7 +61,7 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
 
-        $this->_observer = (new ObjectManager($this))->getObject('\Magento\Catalog\Model\Observer', [
+        $this->_observer = (new ObjectManager($this))->getObject('Magento\Catalog\Model\Observer', [
             'urlFactory' => $this->_getCleanMock('\Magento\Catalog\Model\UrlFactory'),
             'categoryResource' => $this->_getCleanMock('\Magento\Catalog\Model\Resource\Category'),
             'catalogProduct' => $this->_getCleanMock('\Magento\Catalog\Model\Resource\Product'),
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/ActionTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/ActionTest.php
index 2f1cb376bc7..731eef5fb6c 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/ActionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/ActionTest.php
@@ -99,7 +99,7 @@ class ActionTest extends \PHPUnit_Framework_TestCase
 
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $this->model = $objectManager->getObject(
-            '\Magento\Catalog\Model\Product\Action',
+            'Magento\Catalog\Model\Product\Action',
             [
                 'eventDispatcher' => $eventManagerMock,
                 'resource' => $this->resource,
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/ConditionTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/ConditionTest.php
index 217ab2d9ea2..963ae068f26 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/ConditionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/ConditionTest.php
@@ -36,7 +36,7 @@ class ConditionTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $helper = new ObjectManager($this);
-        $this->model = $helper->getObject('\Magento\Catalog\Model\Product\Condition');
+        $this->model = $helper->getObject('Magento\Catalog\Model\Product\Condition');
         $this->model->setTable('testTable')
             ->setPkFieldName('testFieldName');
     }
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Initialization/Helper/ProductLinksTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Initialization/Helper/ProductLinksTest.php
index a4f97b33b60..17c4d474b1d 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Initialization/Helper/ProductLinksTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Initialization/Helper/ProductLinksTest.php
@@ -26,7 +26,7 @@ class ProductLinksTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $helper = new ObjectManager($this);
-        $this->model = $helper->getObject('\Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks');
+        $this->model = $helper->getObject('Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks');
     }
 
     /**
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/LinkTypeProviderTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/LinkTypeProviderTest.php
index 0062cfe3a6f..0638418b149 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/LinkTypeProviderTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/LinkTypeProviderTest.php
@@ -52,7 +52,7 @@ class LinkTypeProviderTest extends \PHPUnit_Framework_TestCase
         ];
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $this->model = $objectManager->getObject(
-            '\Magento\Catalog\Model\Product\LinkTypeProvider',
+            'Magento\Catalog\Model\Product\LinkTypeProvider',
             [
                 'linkTypeBuilder' => $this->linkTypeBuilderMock,
                 'linkAttributeBuilder' => $this->linkAttributeBuilderMock,
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/OptionTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/OptionTest.php
index 5e91220127e..3be3f6ab782 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/OptionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/OptionTest.php
@@ -22,7 +22,7 @@ class OptionTest extends \PHPUnit_Framework_TestCase
     {
         $this->productMock = $this->getMock('\Magento\Catalog\Model\Product', [], [], '', false);
         $objectManager = new ObjectManager($this);
-        $this->model = $objectManager->getObject('\Magento\Catalog\Model\Product\Option');
+        $this->model = $objectManager->getObject('Magento\Catalog\Model\Product\Option');
         $this->model->setProduct($this->productMock);
     }
 
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/ProductAttributeGroupRepositoryTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/ProductAttributeGroupRepositoryTest.php
index fa30c85ad16..db5ed390cdf 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/ProductAttributeGroupRepositoryTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/ProductAttributeGroupRepositoryTest.php
@@ -46,7 +46,7 @@ class ProductAttributeGroupRepositoryTest extends \PHPUnit_Framework_TestCase
 
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $this->model = $objectManager->getObject(
-            '\Magento\Catalog\Model\ProductAttributeGroupRepository',
+            'Magento\Catalog\Model\ProductAttributeGroupRepository',
             [
                 'groupRepository' => $this->groupRepositoryMock,
                 'groupResource' => $this->groupResourceMock,
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/ProductLink/ManagementTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/ProductLink/ManagementTest.php
index eb38e54cfb9..ec0193d5c18 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/ProductLink/ManagementTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/ProductLink/ManagementTest.php
@@ -86,7 +86,7 @@ class ManagementTest extends \PHPUnit_Framework_TestCase
 
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $this->model = $objectManager->getObject(
-            '\Magento\Catalog\Model\ProductLink\Management',
+            'Magento\Catalog\Model\ProductLink\Management',
             [
                 'productRepository' => $this->productRepositoryMock,
                 'collectionProvider' => $this->collectionProviderMock,
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/ProductLink/RepositoryTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/ProductLink/RepositoryTest.php
index fd9267a2d71..6635666e29c 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/ProductLink/RepositoryTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/ProductLink/RepositoryTest.php
@@ -47,7 +47,7 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
         );
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $this->model = $objectManager->getObject(
-            '\Magento\Catalog\Model\ProductLink\Repository',
+            'Magento\Catalog\Model\ProductLink\Repository',
             [
                 'productRepository' => $this->productRepositoryMock,
                 'entityCollectionProvider' => $this->entityCollectionProviderMock,
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Eav/AttributeTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Eav/AttributeTest.php
index 3b1c80d319f..363a4056506 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Eav/AttributeTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Eav/AttributeTest.php
@@ -91,7 +91,7 @@ class AttributeTest extends \PHPUnit_Framework_TestCase
 
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $this->_model = $objectManager->getObject(
-                '\Magento\Catalog\Model\Resource\Eav\Attribute',
+                'Magento\Catalog\Model\Resource\Eav\Attribute',
                 [
                     'context' => $this->contextMock,
                     'productFlatIndexerProcessor' => $this->_processor,
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/ProductTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/ProductTest.php
index 1410fc93c6a..2ad45ca8b2a 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/ProductTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/ProductTest.php
@@ -44,7 +44,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->model = $objectManager->getObject(
-            '\Magento\Catalog\Model\Resource\Product',
+            'Magento\Catalog\Model\Resource\Product',
             [
                 'setFactory' => $this->setFactoryMock,
                 'typeFactory' => $this->typeFactoryMock,
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/System/Config/Source/InputtypeTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/System/Config/Source/InputtypeTest.php
index 4e0eb00d8c2..40e37f28a1b 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/System/Config/Source/InputtypeTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/System/Config/Source/InputtypeTest.php
@@ -19,7 +19,7 @@ class InputtypeTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $this->_helper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->_model = $this->_helper->getObject('\Magento\Catalog\Model\System\Config\Source\Inputtype');
+        $this->_model = $this->_helper->getObject('Magento\Catalog\Model\System\Config\Source\Inputtype');
     }
 
     public function testToOptionArrayIsArray()
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/BasePriceTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/BasePriceTest.php
index f76f8f8f590..577b8abf638 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/BasePriceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/BasePriceTest.php
@@ -72,7 +72,7 @@ class BasePriceTest extends \PHPUnit_Framework_TestCase
         ];
 
         $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->basePrice = $helper->getObject('\Magento\Catalog\Pricing\Price\BasePrice',
+        $this->basePrice = $helper->getObject('Magento\Catalog\Pricing\Price\BasePrice',
             [
                 'saleableItem' => $this->saleableItemMock,
                 'quantity' => $qty,
diff --git a/dev/tests/unit/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/unit/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
index a425a07ea61..5914ed6ce02 100644
--- a/dev/tests/unit/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
+++ b/dev/tests/unit/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php
@@ -267,7 +267,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
 
         $this->_model = $objectManager->getObject(
-            '\Magento\CatalogImportExport\Model\Import\Product',
+            'Magento\CatalogImportExport\Model\Import\Product',
             [
                 'config' => $this->_eavConfig,
                 'optionFactory' => $this->_optionFactory,
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Block/Cart/ShippingTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Block/Cart/ShippingTest.php
index 2bb94676cfc..0d4c5653a30 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Block/Cart/ShippingTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Block/Cart/ShippingTest.php
@@ -57,7 +57,7 @@ class ShippingTest extends \PHPUnit_Framework_TestCase
 
         /** @var \Magento\Checkout\Block\Cart\Shipping $shippingBlock */
         $shippingBlock = $this->objectManager->getObject(
-            '\Magento\Checkout\Block\Cart\Shipping',
+            'Magento\Checkout\Block\Cart\Shipping',
             ['context' => $contextMock]
         );
 
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Block/Cart/Sidebar/TotalsTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Block/Cart/Sidebar/TotalsTest.php
index d9afed82a88..555b4b496cd 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Block/Cart/Sidebar/TotalsTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Block/Cart/Sidebar/TotalsTest.php
@@ -40,7 +40,7 @@ class TotalsTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue($this->quote));
 
         $this->totalsObj = $objectManager->getObject(
-            '\Magento\Checkout\Block\Cart\Sidebar\Totals',
+            'Magento\Checkout\Block\Cart\Sidebar\Totals',
             ['checkoutSession' => $checkoutSession]
         );
     }
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Block/Cart/SidebarTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Block/Cart/SidebarTest.php
index 0c7f3897adf..7bd683816b7 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Block/Cart/SidebarTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Block/Cart/SidebarTest.php
@@ -143,7 +143,7 @@ class SidebarTest extends \PHPUnit_Framework_TestCase
 
         /** @var \Magento\Checkout\Block\Cart\SideBar $sidebarBlock */
         $sidebarBlock = $this->_objectManager->getObject(
-            '\Magento\Checkout\Block\Cart\SideBar',
+            'Magento\Checkout\Block\Cart\SideBar',
             ['context' => $contextMock]
         );
 
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Block/Onepage/AbstractOnepageTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Block/Onepage/AbstractOnepageTest.php
index 04fa9ed5146..e0eed207ba0 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Block/Onepage/AbstractOnepageTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Block/Onepage/AbstractOnepageTest.php
@@ -57,7 +57,7 @@ class AbstractOnepageTest extends \PHPUnit_Framework_TestCase
 
         /** @var \Magento\Checkout\Block\Onepage\AbstractOnepage $onepage */
         $onepage = $this->objectManager->getObject(
-            '\Magento\Checkout\Block\Cart\Shipping',
+            'Magento\Checkout\Block\Cart\Shipping',
             ['context' => $contextMock]
         );
 
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Block/Shipping/PriceTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Block/Shipping/PriceTest.php
index 3aecb126e51..9194999d94b 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Block/Shipping/PriceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Block/Shipping/PriceTest.php
@@ -36,7 +36,7 @@ class PriceTest extends \PHPUnit_Framework_TestCase
         $this->priceCurrency = $this->getMockBuilder('Magento\Framework\Pricing\PriceCurrencyInterface')->getMock();
 
         $this->priceObj = $objectManager->getObject(
-            '\Magento\Checkout\Block\Shipping\Price',
+            'Magento\Checkout\Block\Shipping\Price',
             ['priceCurrency'   => $this->priceCurrency]
         );
     }
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Controller/Onepage/IndexTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Controller/Onepage/IndexTest.php
index 6a015a401c4..662d082c6fb 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Controller/Onepage/IndexTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Controller/Onepage/IndexTest.php
@@ -144,7 +144,7 @@ class IndexTest extends \PHPUnit_Framework_TestCase
 
         // SUT
         $this->model = $this->objectManager->getObject(
-            '\Magento\Checkout\Controller\Onepage\Index',
+            'Magento\Checkout\Controller\Onepage\Index',
             [
                 'context' => $this->contextMock,
                 'customerSession' => $this->sessionMock,
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Model/SessionTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Model/SessionTest.php
index 54ee170aa57..d5bb6fe1b0f 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Model/SessionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Model/SessionTest.php
@@ -344,7 +344,7 @@ class SessionTest extends \PHPUnit_Framework_TestCase
     public function testResetCheckout()
     {
         /** @var $session \Magento\Checkout\Model\Session */
-        $session = $this->_helper->getObject('\Magento\Checkout\Model\Session', [
+        $session = $this->_helper->getObject('Magento\Checkout\Model\Session', [
             'storage' => new \Magento\Framework\Session\Storage()
         ]);
         $session->resetCheckout();
@@ -360,7 +360,7 @@ class SessionTest extends \PHPUnit_Framework_TestCase
             ],
         ];
         /** @var $session \Magento\Checkout\Model\Session */
-        $session = $this->_helper->getObject('\Magento\Checkout\Model\Session', [
+        $session = $this->_helper->getObject('Magento\Checkout\Model\Session', [
             'storage' => new \Magento\Framework\Session\Storage()
         ]);
         $session->setSteps($stepData);
@@ -379,7 +379,7 @@ class SessionTest extends \PHPUnit_Framework_TestCase
             ],
         ];
         /** @var $session \Magento\Checkout\Model\Session */
-        $session = $this->_helper->getObject('\Magento\Checkout\Model\Session', [
+        $session = $this->_helper->getObject('Magento\Checkout\Model\Session', [
             'storage' => new \Magento\Framework\Session\Storage()
         ]);
         $session->setSteps($stepData);
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Address/Shipping/WriteServiceTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Address/Shipping/WriteServiceTest.php
index 282fb0ba66e..d8ba19ff325 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Address/Shipping/WriteServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Address/Shipping/WriteServiceTest.php
@@ -71,7 +71,7 @@ class WriteServiceTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->service = $this->objectManager->getObject(
-            '\Magento\Checkout\Service\V1\Address\Shipping\WriteService',
+            'Magento\Checkout\Service\V1\Address\Shipping\WriteService',
             [
                 'quoteRepository' => $this->quoteRepositoryMock,
                 'quoteAddressFactory' => $this->addressFactoryMock,
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Address/ValidatorTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Address/ValidatorTest.php
index 5c3a5952ef2..52fe4ee0589 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Address/ValidatorTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Address/ValidatorTest.php
@@ -68,12 +68,12 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->addressDataBuilder = $this->objectManager->getObject(
-            '\Magento\Checkout\Service\V1\Data\Cart\AddressBuilder',
+            'Magento\Checkout\Service\V1\Data\Cart\AddressBuilder',
             ['regionBuilder' => $builder]
         );
 
         $this->model = $this->objectManager->getObject(
-            '\Magento\Checkout\Service\V1\Address\Validator',
+            'Magento\Checkout\Service\V1\Address\Validator',
             [
                 'quoteAddressFactory' => $this->addressFactoryMock,
                 'customerFactory' => $this->customerFactoryMock,
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Cart/PaymentMethod/BuilderTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Cart/PaymentMethod/BuilderTest.php
index daccd8b4144..04324909f39 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Cart/PaymentMethod/BuilderTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Cart/PaymentMethod/BuilderTest.php
@@ -21,7 +21,7 @@ class BuilderTest extends \PHPUnit_Framework_TestCase
     {
         $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $this->builder = $this->objectManager->getObject(
-            '\Magento\Checkout\Service\V1\Data\Cart\PaymentMethod\Builder'
+            'Magento\Checkout\Service\V1\Data\Cart\PaymentMethod\Builder'
         );
     }
 
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Cart/PaymentMethod/ConverterTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Cart/PaymentMethod/ConverterTest.php
index 296b8aaf8a0..9e2c0ea62ad 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Cart/PaymentMethod/ConverterTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Cart/PaymentMethod/ConverterTest.php
@@ -36,7 +36,7 @@ class ConverterTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->converter = $this->objectManager->getObject(
-            '\Magento\Checkout\Service\V1\Data\Cart\PaymentMethod\Converter',
+            'Magento\Checkout\Service\V1\Data\Cart\PaymentMethod\Converter',
             [
                 'builder' => $this->paymentMethodBuilderMock,
             ]
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Cart/ReadServiceTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Cart/ReadServiceTest.php
index 190ed00f085..da0cdc677b3 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Cart/ReadServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Cart/ReadServiceTest.php
@@ -60,7 +60,7 @@ class ReadServiceTest extends \PHPUnit_Framework_TestCase
         ];
         $this->quoteMock = $this->getMock('\Magento\Sales\Model\Quote', $methods, [], '', false);
         $this->quoteCollectionMock = $objectManager->getCollectionMock(
-            '\Magento\Sales\Model\Resource\Quote\Collection', [$this->quoteMock]);
+            'Magento\Sales\Model\Resource\Quote\Collection', [$this->quoteMock]);
         $this->searchResultsBuilderMock =
             $this->getMock('\Magento\Checkout\Service\V1\Data\CartSearchResultsBuilder', [], [], '', false);
         $this->cartMapperMock = $this->getMock('\Magento\Checkout\Service\V1\Data\CartMapper', ['map'], [], '', false);
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Cart/WriteServiceTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Cart/WriteServiceTest.php
index edee9277ac4..5e683c74434 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Cart/WriteServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Cart/WriteServiceTest.php
@@ -104,7 +104,7 @@ class WriteServiceTest extends \PHPUnit_Framework_TestCase
             false
         );
         $this->service = $this->objectManager->getObject(
-            '\Magento\Checkout\Service\V1\Cart\WriteService',
+            'Magento\Checkout\Service\V1\Cart\WriteService',
             [
                 'storeManager' => $this->storeManagerMock,
                 'customerRepository' => $this->customerRepositoryMock,
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Coupon/ReadServiceTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Coupon/ReadServiceTest.php
index 86ea3f35499..18f1afad761 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Coupon/ReadServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Coupon/ReadServiceTest.php
@@ -33,7 +33,7 @@ class ReadServiceTest extends \PHPUnit_Framework_TestCase
             '\Magento\Checkout\Service\V1\Data\Cart\CouponBuilder', [], [], '', false
         );
         $this->service = $objectManager->getObject(
-            '\Magento\Checkout\Service\V1\Coupon\ReadService',
+            'Magento\Checkout\Service\V1\Coupon\ReadService',
             [
                 'quoteRepository' => $this->quoteRepositoryMock,
                 'couponBuilder' => $this->couponBuilderMock,
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Data/PaymentMethod/ConverterTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Data/PaymentMethod/ConverterTest.php
index 7069ba299ea..58f49fce129 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Data/PaymentMethod/ConverterTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/Data/PaymentMethod/ConverterTest.php
@@ -32,7 +32,7 @@ class ConverterTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->converter = $this->objectManager->getObject(
-            '\Magento\Checkout\Service\V1\Data\PaymentMethod\Converter',
+            'Magento\Checkout\Service\V1\Data\PaymentMethod\Converter',
             [
                 'builder' => $this->paymentMethodBuilderMock,
             ]
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/PaymentMethod/ReadServiceTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/PaymentMethod/ReadServiceTest.php
index 7fb960654ef..7bfdd2524ba 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/PaymentMethod/ReadServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/PaymentMethod/ReadServiceTest.php
@@ -50,7 +50,7 @@ class ReadServiceTest extends \PHPUnit_Framework_TestCase
         $this->methodListMock = $this->getMock('\Magento\Payment\Model\MethodList', [], [], '', false);
 
         $this->service = $this->objectManager->getObject(
-            '\Magento\Checkout\Service\V1\PaymentMethod\ReadService',
+            'Magento\Checkout\Service\V1\PaymentMethod\ReadService',
             [
                 'quoteRepository' => $this->quoteRepositoryMock,
                 'quoteMethodConverter' => $this->quoteMethodConverterMock,
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/PaymentMethod/WriteServiceTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/PaymentMethod/WriteServiceTest.php
index 7a07b8c8aad..918124800a2 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/PaymentMethod/WriteServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/PaymentMethod/WriteServiceTest.php
@@ -49,7 +49,7 @@ class WriteServiceTest extends \PHPUnit_Framework_TestCase
         $this->validatorMock = $this->getMock('\Magento\Payment\Model\Checks\ZeroTotal', [], [], '', false);
 
         $this->service = $this->objectManager->getObject(
-            '\Magento\Checkout\Service\V1\PaymentMethod\WriteService',
+            'Magento\Checkout\Service\V1\PaymentMethod\WriteService',
             [
                 'quoteRepository' => $this->quoteRepositoryMock,
                 'paymentMethodBuilder' => $this->paymentMethodBuilderMock,
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/ShippingMethod/ReadServiceTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/ShippingMethod/ReadServiceTest.php
index cfae35ef94a..d48c14f27b7 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/ShippingMethod/ReadServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Service/V1/ShippingMethod/ReadServiceTest.php
@@ -96,7 +96,7 @@ class ReadServiceTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->service = $this->objectManager->getObject(
-            '\Magento\Checkout\Service\V1\ShippingMethod\ReadService',
+            'Magento\Checkout\Service\V1\ShippingMethod\ReadService',
             [
                 'quoteRepository' => $this->quoteRepositoryMock,
                 'methodBuilder' => $this->methodBuilderMock,
diff --git a/dev/tests/unit/testsuite/Magento/CheckoutAgreements/Model/AgreementTest.php b/dev/tests/unit/testsuite/Magento/CheckoutAgreements/Model/AgreementTest.php
index a775fd23cf4..c7b36ca7eda 100644
--- a/dev/tests/unit/testsuite/Magento/CheckoutAgreements/Model/AgreementTest.php
+++ b/dev/tests/unit/testsuite/Magento/CheckoutAgreements/Model/AgreementTest.php
@@ -14,7 +14,7 @@ class AgreementTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->model = $this->objectManager->getObject('\Magento\CheckoutAgreements\Model\Agreement');
+        $this->model = $this->objectManager->getObject('Magento\CheckoutAgreements\Model\Agreement');
     }
 
     /**
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/AccountTest.php b/dev/tests/unit/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/AccountTest.php
index 3ff772d19f7..0cce2cb3e3f 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/AccountTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/AccountTest.php
@@ -100,7 +100,7 @@ class AccountTest extends \PHPUnit_Framework_TestCase
         $layoutMock->expects($this->at(0))->method('createBlock')
             ->with('Magento\Customer\Block\Adminhtml\Edit\Renderer\Attribute\Group')
             ->will($this->returnValue(
-                $this->objectManagerHelper->getObject('\Magento\Customer\Block\Adminhtml\Edit\Renderer\Attribute\Group')
+                $this->objectManagerHelper->getObject('Magento\Customer\Block\Adminhtml\Edit\Renderer\Attribute\Group')
             ));
         $layoutMock->expects($this->at(1))->method('createBlock')
             ->with('Magento\Backend\Block\Store\Switcher\Form\Renderer\Fieldset\Element')
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Block/NewsletterTest.php b/dev/tests/unit/testsuite/Magento/Customer/Block/NewsletterTest.php
index 4ddb6f8c5c7..728853623ad 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Block/NewsletterTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Block/NewsletterTest.php
@@ -20,7 +20,7 @@ class NewsletterTest extends \PHPUnit_Framework_TestCase
     {
         $this->urlBuilder = $this->getMock('\Magento\Framework\UrlInterface');
         $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->block = $helper->getObject('\Magento\Customer\Block\Newsletter', ['urlBuilder' => $this->urlBuilder]);
+        $this->block = $helper->getObject('Magento\Customer\Block\Newsletter', ['urlBuilder' => $this->urlBuilder]);
     }
 
     public function testGetAction()
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Block/Widget/DobTest.php b/dev/tests/unit/testsuite/Magento/Customer/Block/Widget/DobTest.php
index 5e1faeb65fc..63e82abc9ee 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Block/Widget/DobTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Block/Widget/DobTest.php
@@ -62,13 +62,13 @@ class DobTest extends \PHPUnit_Framework_TestCase
 
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $locale = $objectManager->getObject(
-            '\Magento\Framework\Locale',
+            'Magento\Framework\Locale',
             ['locale' => \Magento\Framework\Locale\ResolverInterface::DEFAULT_LOCALE]
         );
         $localeResolver = $this->getMock('\Magento\Framework\Locale\ResolverInterface');
         $localeResolver->expects($this->any())->method('getLocale')->will($this->returnValue($locale));
         $timezone = $objectManager->getObject(
-            '\Magento\Framework\Stdlib\DateTime\Timezone',
+            'Magento\Framework\Stdlib\DateTime\Timezone',
             ['localeResolver' => $localeResolver]
         );
 
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Model/Resource/Group/Grid/ServiceCollectionTest.php b/dev/tests/unit/testsuite/Magento/Customer/Model/Resource/Group/Grid/ServiceCollectionTest.php
index 71e1db6d481..f3ed61dc74a 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Model/Resource/Group/Grid/ServiceCollectionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Model/Resource/Group/Grid/ServiceCollectionTest.php
@@ -36,7 +36,7 @@ class ServiceCollectionTest extends \PHPUnit_Framework_TestCase
     public function setUp()
     {
         $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->filterBuilder = $this->objectManager->getObject('\Magento\Framework\Api\FilterBuilder');
+        $this->filterBuilder = $this->objectManager->getObject('Magento\Framework\Api\FilterBuilder');
         $filterGroupBuilder = $this->objectManager
             ->getObject('Magento\Framework\Api\Search\FilterGroupBuilder');
         /** @var \Magento\Framework\Api\SearchCriteriaBuilder $searchBuilder */
@@ -45,7 +45,7 @@ class ServiceCollectionTest extends \PHPUnit_Framework_TestCase
             ['filterGroupBuilder' => $filterGroupBuilder]
         );
         $this->sortOrderBuilder = $this->objectManager->getObject(
-            '\Magento\Framework\Api\SortOrderBuilder'
+            'Magento\Framework\Api\SortOrderBuilder'
         );
         $this->groupRepositoryMock = $this->getMockBuilder('\Magento\Customer\Api\GroupRepositoryInterface')
             ->getMock();
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/GroupRepositoryTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/GroupRepositoryTest.php
index 49c27d38b75..b177b478a5f 100644
--- a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/GroupRepositoryTest.php
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/GroupRepositoryTest.php
@@ -70,7 +70,7 @@ class GroupRepositoryTest extends \PHPUnit_Framework_TestCase
 
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $this->model = $objectManager->getObject(
-            '\Magento\Eav\Model\Attribute\GroupRepository',
+            'Magento\Eav\Model\Attribute\GroupRepository',
             [
                 'groupResource' => $this->groupResourceMock,
                 'groupListFactory' => $this->groupListFactoryMock,
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Resource/Attribute/CollectionTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Resource/Attribute/CollectionTest.php
index 0d712466ff2..5a090489fc8 100644
--- a/dev/tests/unit/testsuite/Magento/Eav/Model/Resource/Attribute/CollectionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Resource/Attribute/CollectionTest.php
@@ -164,7 +164,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
     public function testInitSelect($column, $value, $expected)
     {
         $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->model = $helper->getObject('\Magento\Customer\Model\Resource\Attribute\Collection',
+        $this->model = $helper->getObject('Magento\Customer\Model\Resource\Attribute\Collection',
             [
                 'entityFactory' => $this->entityFactoryMock,
                 'logger' => $this->loggerMock,
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Api/Data/AttributeValueTest.php b/dev/tests/unit/testsuite/Magento/Framework/Api/Data/AttributeValueTest.php
index f9639ea5425..fd20df2184f 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Api/Data/AttributeValueTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Api/Data/AttributeValueTest.php
@@ -21,7 +21,7 @@ class AttributeValueTest extends \PHPUnit_Framework_TestCase
     public function testConstructorAndGettersWithString()
     {
         $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $attributeBuilder = $helper->getObject('\Magento\Framework\Api\AttributeDataBuilder')
+        $attributeBuilder = $helper->getObject('Magento\Framework\Api\AttributeDataBuilder')
             ->setAttributeCode(self::ATTRIBUTE_CODE)
             ->setValue(self::STRING_VALUE);
         $attribute = new AttributeValue($attributeBuilder);
@@ -33,7 +33,7 @@ class AttributeValueTest extends \PHPUnit_Framework_TestCase
     public function testConstructorAndGettersWithInteger()
     {
         $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $attributeBuilder = $helper->getObject('\Magento\Framework\Api\AttributeDataBuilder')
+        $attributeBuilder = $helper->getObject('Magento\Framework\Api\AttributeDataBuilder')
             ->setAttributeCode(self::ATTRIBUTE_CODE)
             ->setValue(self::INTEGER_VALUE);
         $attribute = new AttributeValue($attributeBuilder);
@@ -45,7 +45,7 @@ class AttributeValueTest extends \PHPUnit_Framework_TestCase
     public function testConstructorAndGettersWithFloat()
     {
         $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $attributeBuilder = $helper->getObject('\Magento\Framework\Api\AttributeDataBuilder')
+        $attributeBuilder = $helper->getObject('Magento\Framework\Api\AttributeDataBuilder')
             ->setAttributeCode(self::ATTRIBUTE_CODE)
             ->setValue(self::FLOAT_VALUE);
         $attribute = new AttributeValue($attributeBuilder);
@@ -57,7 +57,7 @@ class AttributeValueTest extends \PHPUnit_Framework_TestCase
     public function testConstructorAndGettersWithBoolean()
     {
         $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $attributeBuilder = $helper->getObject('\Magento\Framework\Api\AttributeDataBuilder')
+        $attributeBuilder = $helper->getObject('Magento\Framework\Api\AttributeDataBuilder')
             ->setAttributeCode(self::ATTRIBUTE_CODE)
             ->setValue(self::BOOLEAN_VALUE);
         $attribute = new AttributeValue($attributeBuilder);
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Data/AbstractCriteriaTest.php b/dev/tests/unit/testsuite/Magento/Framework/Data/AbstractCriteriaTest.php
index 4751c65c29d..55b3d94536d 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Data/AbstractCriteriaTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Data/AbstractCriteriaTest.php
@@ -24,7 +24,7 @@ class AbstractCriteriaTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->criteria = $objectManager->getObject('\Magento\Framework\Data\Criteria\Sample');
+        $this->criteria = $objectManager->getObject('Magento\Framework\Data\Criteria\Sample');
     }
 
     /**
diff --git a/dev/tests/unit/testsuite/Magento/Framework/HTTP/HeaderTest.php b/dev/tests/unit/testsuite/Magento/Framework/HTTP/HeaderTest.php
index 21079262a0f..05efc158f0a 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/HTTP/HeaderTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/HTTP/HeaderTest.php
@@ -56,7 +56,7 @@ class HeaderTest extends \PHPUnit_Framework_TestCase
         $this->_prepareCleanString($clean);
 
         $headerObject = $this->_objectManager->getObject(
-            '\Magento\Framework\HTTP\Header',
+            'Magento\Framework\HTTP\Header',
             ['httpRequest' => $this->_request, 'converter' => $this->_converter]
         );
 
@@ -138,7 +138,7 @@ class HeaderTest extends \PHPUnit_Framework_TestCase
         $this->_prepareCleanString($clean);
 
         $headerObject = $this->_objectManager->getObject(
-            '\Magento\Framework\HTTP\Header',
+            'Magento\Framework\HTTP\Header',
             ['httpRequest' => $this->_request, 'converter' => $this->_converter]
         );
 
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Image/Adapter/Gd2Test.php b/dev/tests/unit/testsuite/Magento/Framework/Image/Adapter/Gd2Test.php
index 4ac70fbf71d..9136cc70df5 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Image/Adapter/Gd2Test.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Image/Adapter/Gd2Test.php
@@ -89,7 +89,7 @@ class Gd2Test extends \PHPUnit_Framework_TestCase
     public function setUp()
     {
         $this->objectManager = new ObjectManager($this);
-        $this->adapter = $this->objectManager->getObject('\Magento\Framework\Image\Adapter\Gd2');
+        $this->adapter = $this->objectManager->getObject('Magento\Framework\Image\Adapter\Gd2');
     }
 
     /**
diff --git a/dev/tests/unit/testsuite/Magento/Framework/ObjectManager/ObjectManagerTest.php b/dev/tests/unit/testsuite/Magento/Framework/ObjectManager/ObjectManagerTest.php
index 9c1416a06c7..5a1eb47f3ec 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/ObjectManager/ObjectManagerTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/ObjectManager/ObjectManagerTest.php
@@ -394,6 +394,6 @@ class ObjectManagerTest extends \PHPUnit_Framework_TestCase
 
     public function testGetIgnoresFirstSlash()
     {
-        $this->assertSame($this->_object->get('Magento\Test\Di\Child'), $this->_object->get('\Magento\Test\Di\Child'));
+        $this->assertSame($this->_object->get('Magento\Test\Di\Child'), $this->_object->get('Magento\Test\Di\Child'));
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php
index cfd0209b33a..fea8b17efa8 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/AdapterTest.php
@@ -107,7 +107,7 @@ class AdapterTest extends \PHPUnit_Framework_TestCase
             ->getMockForAbstractClass();
 
         $this->adapter = $this->objectManager->getObject(
-            '\Magento\Framework\Search\Adapter\Mysql\Adapter',
+            'Magento\Framework\Search\Adapter\Mysql\Adapter',
             [
                 'mapper' => $this->mapper,
                 'responseFactory' => $this->responseFactory,
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/ConditionManagerTest.php b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/ConditionManagerTest.php
index 29a3e1c7760..f340d258baa 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/ConditionManagerTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/ConditionManagerTest.php
@@ -57,7 +57,7 @@ class ConditionManagerTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue($this->adapter));
 
         $this->conditionManager = $objectManager->getObject(
-            '\Magento\Framework\Search\Adapter\Mysql\ConditionManager',
+            'Magento\Framework\Search\Adapter\Mysql\ConditionManager',
             [
                 'resource' => $this->resource
             ]
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/DimensionsTest.php b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/DimensionsTest.php
index 729aa46274a..72ebd5c70b1 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/DimensionsTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/DimensionsTest.php
@@ -62,7 +62,7 @@ class DimensionsTest extends \PHPUnit_Framework_TestCase
             );
 
         $this->builder = $this->objectManager->getObject(
-            '\Magento\Framework\Search\Adapter\Mysql\Dimensions',
+            'Magento\Framework\Search\Adapter\Mysql\Dimensions',
             [
                 'conditionManager' => $this->conditionManager,
                 'scopeResolver' => $this->scopeResolver
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/ResponseFactoryTest.php b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/ResponseFactoryTest.php
index cc410bea0bf..fbf01248758 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/ResponseFactoryTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Search/Adapter/Mysql/ResponseFactoryTest.php
@@ -72,7 +72,7 @@ class ResponseFactoryTest extends \PHPUnit_Framework_TestCase
 
         $this->objectManager->expects($this->once())->method('create')
             ->with(
-                $this->equalTo('\Magento\Framework\Search\Response\QueryResponse'),
+                $this->equalTo('Magento\Framework\Search\Response\QueryResponse'),
                 $this->equalTo(['documents' => ['document1', 'document2'], 'aggregations' => null])
             )
             ->will($this->returnValue('QueryResponseObject'));
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Validator/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Framework/Validator/ConfigTest.php
index 3ee92e5be90..5e223a9015f 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Validator/ConfigTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Validator/ConfigTest.php
@@ -52,7 +52,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
         $factory = new \Magento\Framework\ObjectManager\Factory\Dynamic\Developer($config);
         $realObjectManager = new \Magento\Framework\ObjectManager\ObjectManager($factory, $config);
         $factory->setObjectManager($realObjectManager);
-        $universalFactory = $realObjectManager->get('\Magento\Framework\Validator\UniversalFactory');
+        $universalFactory = $realObjectManager->get('Magento\Framework\Validator\UniversalFactory');
         $this->_config = $this->_objectManager->getObject(
             'Magento\Framework\Validator\Config',
             ['configFiles' => $configFiles, 'builderFactory' => $universalFactory]
diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Element/Html/Link/CurrentTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Element/Html/Link/CurrentTest.php
index d914dc86f1f..accdfcbff9a 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/View/Element/Html/Link/CurrentTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/Element/Html/Link/CurrentTest.php
@@ -43,7 +43,7 @@ class CurrentTest extends \PHPUnit_Framework_TestCase
 
         /** @var \Magento\Framework\View\Element\Html\Link\Current $link */
         $link = $this->_objectManager->getObject(
-            '\Magento\Framework\View\Element\Html\Link\Current',
+            'Magento\Framework\View\Element\Html\Link\Current',
             ['urlBuilder' => $this->_urlBuilderMock]
         );
 
@@ -54,7 +54,7 @@ class CurrentTest extends \PHPUnit_Framework_TestCase
     public function testIsCurrentIfIsset()
     {
         /** @var \Magento\Framework\View\Element\Html\Link\Current $link */
-        $link = $this->_objectManager->getObject('\Magento\Framework\View\Element\Html\Link\Current');
+        $link = $this->_objectManager->getObject('Magento\Framework\View\Element\Html\Link\Current');
         $link->setCurrent(true);
         $this->assertTrue($link->IsCurrent());
     }
@@ -75,7 +75,7 @@ class CurrentTest extends \PHPUnit_Framework_TestCase
         $this->_requestMock->expects($this->once())->method('getControllerName')->will($this->returnValue('b'));
         /** @var \Magento\Framework\View\Element\Html\Link\Current $link */
         $link = $this->_objectManager->getObject(
-            '\Magento\Framework\View\Element\Html\Link\Current',
+            'Magento\Framework\View\Element\Html\Link\Current',
             [
                 'urlBuilder' => $this->_urlBuilderMock,
                 'request' => $this->_requestMock,
@@ -93,7 +93,7 @@ class CurrentTest extends \PHPUnit_Framework_TestCase
 
         /** @var \Magento\Framework\View\Element\Html\Link\Current $link */
         $link = $this->_objectManager->getObject(
-            '\Magento\Framework\View\Element\Html\Link\Current',
+            'Magento\Framework\View\Element\Html\Link\Current',
             ['urlBuilder' => $this->_urlBuilderMock, 'request' => $this->_requestMock]
         );
         $this->assertFalse($link->isCurrent());
diff --git a/dev/tests/unit/testsuite/Magento/GiftMessage/Helper/MessageTest.php b/dev/tests/unit/testsuite/Magento/GiftMessage/Helper/MessageTest.php
index e6058c1fe9e..2ade264a0dc 100644
--- a/dev/tests/unit/testsuite/Magento/GiftMessage/Helper/MessageTest.php
+++ b/dev/tests/unit/testsuite/Magento/GiftMessage/Helper/MessageTest.php
@@ -21,7 +21,7 @@ class MessageTest extends \PHPUnit_Framework_TestCase
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $this->layoutFactoryMock = $this->getMock('\Magento\Framework\View\LayoutFactory', [], [], '', false);
 
-        $this->helper = $objectManager->getObject('\Magento\GiftMessage\Helper\Message', [
+        $this->helper = $objectManager->getObject('Magento\GiftMessage\Helper\Message', [
             'layoutFactory' => $this->layoutFactoryMock,
             'skipMessageCheck' => ['onepage_checkout'],
         ]);
diff --git a/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/Attribute/SalePriceEffectiveDateTest.php b/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/Attribute/SalePriceEffectiveDateTest.php
index d7b77c400c1..bce6d2cca4a 100644
--- a/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/Attribute/SalePriceEffectiveDateTest.php
+++ b/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/Attribute/SalePriceEffectiveDateTest.php
@@ -15,7 +15,7 @@ class SalePriceEffectiveDateTest extends \PHPUnit_Framework_TestCase
     {
         /** @var \Magento\GoogleShopping\Model\Attribute\SalePriceEffectiveDate $model */
         $model = (new \Magento\TestFramework\Helper\ObjectManager($this))
-            ->getObject('\Magento\GoogleShopping\Model\Attribute\SalePriceEffectiveDate');
+            ->getObject('Magento\GoogleShopping\Model\Attribute\SalePriceEffectiveDate');
         $product = $this->getMock('\Magento\Catalog\Model\Product', ['__wakeup'], [], '', false);
         $effectiveDateFrom = $this->getMock(
             '\Magento\GoogleShopping\Model\Attribute\DefaultAttribute',
diff --git a/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/ObserverTest.php b/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/ObserverTest.php
index 1aef8d8808a..d0bf24668cb 100644
--- a/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/ObserverTest.php
+++ b/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/ObserverTest.php
@@ -62,7 +62,7 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
     {
         $this->flag->expects($this->once())->method('loadSelf')->will($this->returnSelf());
         $this->flag->expects($this->once())->method('isExpired')->will($this->returnValue(true));
-        $observer = $this->objectManagerHelper->getObject('\Magento\Framework\Event\Observer');
+        $observer = $this->objectManagerHelper->getObject('Magento\Framework\Event\Observer');
         $this->notificationInterface->expects($this->once())->method('addMajor')
             ->with(
                 'Google Shopping operation has expired.',
diff --git a/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/ServiceTest.php b/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/ServiceTest.php
index 42971cf8a13..b4097daf20a 100644
--- a/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/ServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/GoogleShopping/Model/ServiceTest.php
@@ -43,7 +43,7 @@ class ServiceTest extends \PHPUnit_Framework_TestCase
         $coreRegistryMock->expects($this->any())->method('registry')->will($this->returnValue(1));
 
         $arguments = ['contentFactory' => $contentFactoryMock, 'coreRegistry' => $coreRegistryMock];
-        $this->_model = $this->_helper->getObject('\Magento\GoogleShopping\Model\Service', $arguments);
+        $this->_model = $this->_helper->getObject('Magento\GoogleShopping\Model\Service', $arguments);
     }
 
     public function testGetService()
diff --git a/dev/tests/unit/testsuite/Magento/GroupedProduct/Controller/Adminhtml/Edit/PopupTest.php b/dev/tests/unit/testsuite/Magento/GroupedProduct/Controller/Adminhtml/Edit/PopupTest.php
index 9473104ee5d..cc11f721b5d 100644
--- a/dev/tests/unit/testsuite/Magento/GroupedProduct/Controller/Adminhtml/Edit/PopupTest.php
+++ b/dev/tests/unit/testsuite/Magento/GroupedProduct/Controller/Adminhtml/Edit/PopupTest.php
@@ -45,7 +45,7 @@ class PopupTest extends \PHPUnit_Framework_TestCase
 
         $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $this->action = $this->objectManager->getObject(
-            '\Magento\GroupedProduct\Controller\Adminhtml\Edit\Popup',
+            'Magento\GroupedProduct\Controller\Adminhtml\Edit\Popup',
             [
                 'request' => $this->request,
                 'factory' => $this->factory,
diff --git a/dev/tests/unit/testsuite/Magento/LayeredNavigation/Block/NavigationTest.php b/dev/tests/unit/testsuite/Magento/LayeredNavigation/Block/NavigationTest.php
index 20cc60ccd34..4acd06a43f9 100644
--- a/dev/tests/unit/testsuite/Magento/LayeredNavigation/Block/NavigationTest.php
+++ b/dev/tests/unit/testsuite/Magento/LayeredNavigation/Block/NavigationTest.php
@@ -55,7 +55,7 @@ class NavigationTest extends \PHPUnit_Framework_TestCase
 
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $this->model = $objectManager->getObject(
-            '\Magento\LayeredNavigation\Block\Navigation',
+            'Magento\LayeredNavigation\Block\Navigation',
             [
                 'layerResolver' => $layerResolver,
                 'filterList' => $this->filterListMock,
diff --git a/dev/tests/unit/testsuite/Magento/Multishipping/Controller/Checkout/Address/EditAddressTest.php b/dev/tests/unit/testsuite/Magento/Multishipping/Controller/Checkout/Address/EditAddressTest.php
index a16266fae67..458b6a186d1 100644
--- a/dev/tests/unit/testsuite/Magento/Multishipping/Controller/Checkout/Address/EditAddressTest.php
+++ b/dev/tests/unit/testsuite/Magento/Multishipping/Controller/Checkout/Address/EditAddressTest.php
@@ -88,7 +88,7 @@ class EditAddressTest extends \PHPUnit_Framework_TestCase
         $this->pageMock->expects($this->any())->method('getConfig')->willReturn($this->configMock);
         $this->configMock->expects($this->any())->method('getTitle')->willReturn($this->titleMock);
         $this->viewMock->expects($this->any())->method('getPage')->willReturn($this->pageMock);
-        $this->controller = $objectManager->getObject('\Magento\Multishipping\Controller\Checkout\Address\EditAddress',
+        $this->controller = $objectManager->getObject('Magento\Multishipping\Controller\Checkout\Address\EditAddress',
             ['context' => $contextMock]);
     }
 
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/MethodListTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/MethodListTest.php
index a6f181262c9..c4dc8081188 100644
--- a/dev/tests/unit/testsuite/Magento/Payment/Model/MethodListTest.php
+++ b/dev/tests/unit/testsuite/Magento/Payment/Model/MethodListTest.php
@@ -35,7 +35,7 @@ class MethodListTest extends \PHPUnit_Framework_TestCase
             '\Magento\Payment\Model\Checks\SpecificationFactory', [], [], '', false
         );
         $this->methodList = $this->objectManager->getObject(
-            '\Magento\Payment\Model\MethodList',
+            'Magento\Payment\Model\MethodList',
             [
                 'paymentHelper' => $this->paymentHelperMock,
                 'specificationFactory' => $this->specificationFactoryMock
diff --git a/dev/tests/unit/testsuite/Magento/Persistent/Helper/DataTest.php b/dev/tests/unit/testsuite/Magento/Persistent/Helper/DataTest.php
index 0dee70ce932..313b4830bb0 100644
--- a/dev/tests/unit/testsuite/Magento/Persistent/Helper/DataTest.php
+++ b/dev/tests/unit/testsuite/Magento/Persistent/Helper/DataTest.php
@@ -21,7 +21,7 @@ class DataTest extends \PHPUnit_Framework_TestCase
         $this->_modulesReader = $this->getMock('\Magento\Framework\Module\Dir\Reader', [], [], '', false);
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $this->_helper = $objectManager->getObject(
-            '\Magento\Persistent\Helper\Data',
+            'Magento\Persistent\Helper\Data',
             ['modulesReader' => $this->_modulesReader]
         );
     }
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/Address/ValidatorTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/Address/ValidatorTest.php
index d73cf5246be..5f65333e646 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/Address/ValidatorTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/Address/ValidatorTest.php
@@ -46,7 +46,7 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase
             ->method('create')
             ->will($this->returnValue($this->countryMock));
         $this->model = $objectManager->getObject(
-            '\Magento\Sales\Model\Quote\Address\Validator',
+            'Magento\Sales\Model\Quote\Address\Validator',
             [
                 'countryFactory' => $this->countryFactoryMock,
             ]
diff --git a/dev/tests/unit/testsuite/Magento/Search/Model/DataProviderTest.php b/dev/tests/unit/testsuite/Magento/Search/Model/DataProviderTest.php
index 402783398b2..e5293d8bc01 100644
--- a/dev/tests/unit/testsuite/Magento/Search/Model/DataProviderTest.php
+++ b/dev/tests/unit/testsuite/Magento/Search/Model/DataProviderTest.php
@@ -24,14 +24,14 @@ class DataProviderTest extends \PHPUnit_Framework_TestCase
         /** @var \Magento\Search\Model\QueryInterface|\PHPUnit_Framework_MockObject_MockObject $searchQuery */
         $searchQuery = $this->getMockBuilder('\Magento\Search\Model\QueryInterface')->getMockForAbstractClass();
         /** @var \Magento\Search\Model\SearchDataProvider $dataProvider */
-        $dataProvider = $this->objectManager->getObject('\Magento\Search\Model\SearchDataProvider');
+        $dataProvider = $this->objectManager->getObject('Magento\Search\Model\SearchDataProvider');
         $this->assertEquals([], $dataProvider->getSearchData($searchQuery));
     }
 
     public function testIsCountResultsEnabled()
     {
         /** @var \Magento\Search\Model\SearchDataProvider $dataProvider */
-        $dataProvider = $this->objectManager->getObject('\Magento\Search\Model\SearchDataProvider');
+        $dataProvider = $this->objectManager->getObject('Magento\Search\Model\SearchDataProvider');
         $this->assertFalse($dataProvider->isCountResultsEnabled());
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Search/Model/QueryResultTest.php b/dev/tests/unit/testsuite/Magento/Search/Model/QueryResultTest.php
index d9f3f429ca5..16c75ce01c8 100644
--- a/dev/tests/unit/testsuite/Magento/Search/Model/QueryResultTest.php
+++ b/dev/tests/unit/testsuite/Magento/Search/Model/QueryResultTest.php
@@ -26,7 +26,7 @@ class QueryResultTest extends \PHPUnit_Framework_TestCase
     {
         /** @var \Magento\Search\Model\QueryResult $queryResult */
         $queryResult = $this->objectManager->getObject(
-            '\Magento\Search\Model\QueryResult',
+            'Magento\Search\Model\QueryResult',
             [
                 'queryText' => $queryText,
                 'resultsCount' => $resultsCount,
diff --git a/dev/tests/unit/testsuite/Magento/Store/Model/StorageFactoryTest.php b/dev/tests/unit/testsuite/Magento/Store/Model/StorageFactoryTest.php
index 40baf58ed1c..da97a4e28cb 100644
--- a/dev/tests/unit/testsuite/Magento/Store/Model/StorageFactoryTest.php
+++ b/dev/tests/unit/testsuite/Magento/Store/Model/StorageFactoryTest.php
@@ -135,7 +135,7 @@ class StorageFactoryTest extends \PHPUnit_Framework_TestCase
         $this->_scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
         $this->request = $this->getMock('Magento\Framework\App\RequestInterface', [], [], '', false);
 
-        $this->_model = $this->helper->getObject('\Magento\Store\Model\StorageFactory', [
+        $this->_model = $this->helper->getObject('Magento\Store\Model\StorageFactory', [
             'objectManager' => $this->_objectManagerMock,
             'eventManager' => $this->_eventManagerMock,
             'logger' => $this->_logMock,
diff --git a/dev/tests/unit/testsuite/Magento/Tax/Block/Adminhtml/Items/Price/RendererTest.php b/dev/tests/unit/testsuite/Magento/Tax/Block/Adminhtml/Items/Price/RendererTest.php
index 18c10bb1d60..5b3d9405bab 100644
--- a/dev/tests/unit/testsuite/Magento/Tax/Block/Adminhtml/Items/Price/RendererTest.php
+++ b/dev/tests/unit/testsuite/Magento/Tax/Block/Adminhtml/Items/Price/RendererTest.php
@@ -46,7 +46,7 @@ class RendererTest extends \PHPUnit_Framework_TestCase
             ->getMock();
 
         $this->renderer = $objectManager->getObject(
-            '\Magento\Tax\Block\Adminhtml\Items\Price\Renderer',
+            'Magento\Tax\Block\Adminhtml\Items\Price\Renderer',
             [
                 'itemPriceRenderer' => $this->itemPriceRenderer,
                 'defaultColumnRenderer' => $this->defaultColumnRenderer,
diff --git a/dev/tests/unit/testsuite/Magento/Tax/Block/Checkout/Cart/Sidebar/TotalsTest.php b/dev/tests/unit/testsuite/Magento/Tax/Block/Checkout/Cart/Sidebar/TotalsTest.php
index 6ffa098284d..ae4eb2b7d0e 100644
--- a/dev/tests/unit/testsuite/Magento/Tax/Block/Checkout/Cart/Sidebar/TotalsTest.php
+++ b/dev/tests/unit/testsuite/Magento/Tax/Block/Checkout/Cart/Sidebar/TotalsTest.php
@@ -62,7 +62,7 @@ class TotalsTest extends \PHPUnit_Framework_TestCase
             ->getMock();
 
         $this->totalsObj = $objectManager->getObject(
-            '\Magento\Tax\Block\Checkout\Cart\Sidebar\Totals',
+            'Magento\Tax\Block\Checkout\Cart\Sidebar\Totals',
             [
                 'checkoutSession' => $checkoutSession,
                 'taxHelper' => $this->taxHelper,
diff --git a/dev/tests/unit/testsuite/Magento/Tax/Block/Checkout/Shipping/PriceTest.php b/dev/tests/unit/testsuite/Magento/Tax/Block/Checkout/Shipping/PriceTest.php
index 7015ba9a35e..c40596a3f04 100644
--- a/dev/tests/unit/testsuite/Magento/Tax/Block/Checkout/Shipping/PriceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Tax/Block/Checkout/Shipping/PriceTest.php
@@ -68,7 +68,7 @@ class PriceTest extends \PHPUnit_Framework_TestCase
             ->getMock();
 
         $this->priceObj = $objectManager->getObject(
-            '\Magento\Tax\Block\Checkout\Shipping\Price',
+            'Magento\Tax\Block\Checkout\Shipping\Price',
             [
                 'checkoutSession' => $checkoutSession,
                 'taxHelper' => $this->taxHelper,
diff --git a/dev/tests/unit/testsuite/Magento/Tax/Block/Item/Price/RendererTest.php b/dev/tests/unit/testsuite/Magento/Tax/Block/Item/Price/RendererTest.php
index 71da9164776..c209104ed09 100644
--- a/dev/tests/unit/testsuite/Magento/Tax/Block/Item/Price/RendererTest.php
+++ b/dev/tests/unit/testsuite/Magento/Tax/Block/Item/Price/RendererTest.php
@@ -41,7 +41,7 @@ class RendererTest extends \PHPUnit_Framework_TestCase
             ->getMock();
 
         $this->renderer = $objectManager->getObject(
-            '\Magento\Tax\Block\Item\Price\Renderer',
+            'Magento\Tax\Block\Item\Price\Renderer',
             [
                 'taxHelper' => $this->taxHelper,
                 'priceCurrency' => $this->priceCurrency,
diff --git a/dev/tests/unit/testsuite/Magento/Tax/Model/Sales/Total/Quote/SubtotalTest.php b/dev/tests/unit/testsuite/Magento/Tax/Model/Sales/Total/Quote/SubtotalTest.php
index 90f95e6e632..4e6228baccc 100644
--- a/dev/tests/unit/testsuite/Magento/Tax/Model/Sales/Total/Quote/SubtotalTest.php
+++ b/dev/tests/unit/testsuite/Magento/Tax/Model/Sales/Total/Quote/SubtotalTest.php
@@ -97,7 +97,7 @@ class SubtotalTest extends \PHPUnit_Framework_TestCase
         $customerAddressRegionBuilderMock->expects($this->any())->method('setRegionId')->willReturnSelf();
 
         $this->model = $this->objectManager->getObject(
-            '\Magento\Tax\Model\Sales\Total\Quote\Subtotal',
+            'Magento\Tax\Model\Sales\Total\Quote\Subtotal',
             [
                 'taxConfig' => $this->taxConfigMock,
                 'taxCalculationService' => $this->taxCalculationMock,
diff --git a/dev/tests/unit/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php b/dev/tests/unit/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php
index ae53fc86aff..cc67af4a7cf 100644
--- a/dev/tests/unit/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php
+++ b/dev/tests/unit/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php
@@ -415,7 +415,7 @@ class TaxTest extends \PHPUnit_Framework_TestCase
 
         $objectManager = new ObjectManager($this);
         $taxTotalsCalcModel = $objectManager->getObject(
-            '\Magento\Tax\Model\Sales\Total\Quote\Tax',
+            'Magento\Tax\Model\Sales\Total\Quote\Tax',
             ['taxData' => $taxData]
         );
         $array = $taxTotalsCalcModel->processConfigArray([], null);
@@ -448,7 +448,7 @@ class TaxTest extends \PHPUnit_Framework_TestCase
     public function testMapQuoteExtraTaxables($itemData, $addressData)
     {
         $objectManager = new ObjectManager($this);
-        $taxTotalsCalcModel = $objectManager->getObject('\Magento\Tax\Model\Sales\Total\Quote\Tax');
+        $taxTotalsCalcModel = $objectManager->getObject('Magento\Tax\Model\Sales\Total\Quote\Tax');
 
         $taxClassKeyBuilder = $this->getMockBuilder('\Magento\Tax\Api\Data\TaxClassKeyDataBuilder')
             ->disableOriginalConstructor()
@@ -606,7 +606,7 @@ class TaxTest extends \PHPUnit_Framework_TestCase
 
         $objectManager = new ObjectManager($this);
         $taxTotalsCalcModel = $objectManager->getObject(
-            '\Magento\Tax\Model\Sales\Total\Quote\Tax',
+            'Magento\Tax\Model\Sales\Total\Quote\Tax',
             ['taxConfig' => $taxConfig]
         );
 
@@ -695,7 +695,7 @@ class TaxTest extends \PHPUnit_Framework_TestCase
     public function testGetLabel()
     {
         $objectManager = new ObjectManager($this);
-        $taxTotalsCalcModel = $objectManager->getObject('\Magento\Tax\Model\Sales\Total\Quote\Tax');
+        $taxTotalsCalcModel = $objectManager->getObject('Magento\Tax\Model\Sales\Total\Quote\Tax');
         $this->assertSame($taxTotalsCalcModel->getLabel(), __('Tax'));
     }
 
diff --git a/dev/tests/unit/testsuite/Magento/Tax/Model/TaxCalculationTest.php b/dev/tests/unit/testsuite/Magento/Tax/Model/TaxCalculationTest.php
index 50084d96e69..3c1574c4186 100644
--- a/dev/tests/unit/testsuite/Magento/Tax/Model/TaxCalculationTest.php
+++ b/dev/tests/unit/testsuite/Magento/Tax/Model/TaxCalculationTest.php
@@ -79,7 +79,7 @@ class TaxCalculationTest extends \PHPUnit_Framework_TestCase
 
         $objectManager = new ObjectManager($this);
         $this->taxCalculationService = $objectManager->getObject(
-            '\Magento\Tax\Model\TaxCalculation',
+            'Magento\Tax\Model\TaxCalculation',
             [
                 'calculation' => $this->calculationTool,
                 'calculatorFactory' => $this->calculatorFactory,
diff --git a/dev/tests/unit/testsuite/Magento/Tax/Model/TaxClass/Type/CustomerTest.php b/dev/tests/unit/testsuite/Magento/Tax/Model/TaxClass/Type/CustomerTest.php
index ca34e808ece..bf76b0be065 100644
--- a/dev/tests/unit/testsuite/Magento/Tax/Model/TaxClass/Type/CustomerTest.php
+++ b/dev/tests/unit/testsuite/Magento/Tax/Model/TaxClass/Type/CustomerTest.php
@@ -19,9 +19,9 @@ class CustomerTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue(['randomValue']));
 
         $filterBuilder = $objectManagerHelper
-            ->getObject('\Magento\Framework\Api\FilterBuilder');
+            ->getObject('Magento\Framework\Api\FilterBuilder');
         $filterGroupBuilder = $objectManagerHelper
-            ->getObject('\Magento\Framework\Api\Search\FilterGroupBuilder');
+            ->getObject('Magento\Framework\Api\Search\FilterGroupBuilder');
         $searchCriteriaBuilder = $objectManagerHelper->getObject(
             'Magento\Framework\Api\SearchCriteriaBuilder',
             [
diff --git a/dev/tests/unit/testsuite/Magento/Translation/Model/Inline/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Translation/Model/Inline/ConfigTest.php
index b4d125da73b..1dc15a6e778 100644
--- a/dev/tests/unit/testsuite/Magento/Translation/Model/Inline/ConfigTest.php
+++ b/dev/tests/unit/testsuite/Magento/Translation/Model/Inline/ConfigTest.php
@@ -49,7 +49,7 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
         );
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $config = $objectManager->getObject(
-            '\Magento\Translation\Model\Inline\Config',
+            'Magento\Translation\Model\Inline\Config',
             ['scopeConfig' => $scopeConfig]
         );
         $this->assertEquals($result, $config->isActive($store));
diff --git a/dev/tests/unit/testsuite/Magento/Webapi/Controller/RequestTest.php b/dev/tests/unit/testsuite/Magento/Webapi/Controller/RequestTest.php
index 6d370056469..493a58994d7 100644
--- a/dev/tests/unit/testsuite/Magento/Webapi/Controller/RequestTest.php
+++ b/dev/tests/unit/testsuite/Magento/Webapi/Controller/RequestTest.php
@@ -29,7 +29,7 @@ class RequestTest extends \PHPUnit_Framework_TestCase
         $this->cookieReader = $this->getMock('Magento\Framework\Stdlib\Cookie\CookieReaderInterface');
 
         $this->request = $objectManager->getObject(
-            '\Magento\Webapi\Controller\Request',
+            'Magento\Webapi\Controller\Request',
             ['cookieReader' => $this->cookieReader]
         );
     }
@@ -46,4 +46,4 @@ class RequestTest extends \PHPUnit_Framework_TestCase
 
         $this->request->getCookie($key, $default);
     }
-} 
+}
diff --git a/dev/tests/unit/testsuite/Magento/Weee/Block/Item/Price/RendererTest.php b/dev/tests/unit/testsuite/Magento/Weee/Block/Item/Price/RendererTest.php
index af86ba43823..b8facece366 100644
--- a/dev/tests/unit/testsuite/Magento/Weee/Block/Item/Price/RendererTest.php
+++ b/dev/tests/unit/testsuite/Magento/Weee/Block/Item/Price/RendererTest.php
@@ -78,7 +78,7 @@ class RendererTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue(self::STORE_ID));
 
         $this->renderer = $objectManager->getObject(
-            '\Magento\Weee\Block\Item\Price\Renderer',
+            'Magento\Weee\Block\Item\Price\Renderer',
             [
                 'weeeHelper' => $this->weeeHelper,
                 'priceCurrency' => $this->priceCurrency,
diff --git a/dev/tests/unit/testsuite/Magento/Wishlist/Controller/WishlistProviderTest.php b/dev/tests/unit/testsuite/Magento/Wishlist/Controller/WishlistProviderTest.php
index c90f955d1c4..5899fd32805 100644
--- a/dev/tests/unit/testsuite/Magento/Wishlist/Controller/WishlistProviderTest.php
+++ b/dev/tests/unit/testsuite/Magento/Wishlist/Controller/WishlistProviderTest.php
@@ -73,7 +73,7 @@ class WishlistProviderTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->wishlistProvider = $objectManager->getObject(
-            '\Magento\Wishlist\Controller\WishlistProvider',
+            'Magento\Wishlist\Controller\WishlistProvider',
             [
                 'request' => $this->request,
                 'wishlistFactory' => $this->wishlistFactory,
diff --git a/dev/tools/Magento/Tools/Migration/aliases_map/composite_modules_ce.php b/dev/tools/Magento/Tools/Migration/aliases_map/composite_modules_ce.php
index 4ca5ea24754..87a7483bde9 100644
--- a/dev/tools/Magento/Tools/Migration/aliases_map/composite_modules_ce.php
+++ b/dev/tools/Magento/Tools/Migration/aliases_map/composite_modules_ce.php
@@ -18,4 +18,4 @@ require_once realpath(
 ) . '/app/code/Magento/Core/Model/Resource/Setup/Migration.php';
 
 $objectManager = new \Magento\Framework\App\ObjectManager();
-return $objectManager->create('\Magento\Framework\Module\Setup\Migration')->getCompositeModules();
+return $objectManager->create('Magento\Framework\Module\Setup\Migration')->getCompositeModules();
diff --git a/dev/tools/performance-toolkit/fixtures/cart_price_rules.php b/dev/tools/performance-toolkit/fixtures/cart_price_rules.php
index 66cd24c33ad..64fe5341887 100644
--- a/dev/tools/performance-toolkit/fixtures/cart_price_rules.php
+++ b/dev/tools/performance-toolkit/fixtures/cart_price_rules.php
@@ -8,7 +8,7 @@ $cartPriceRulesProductsFloor = \Magento\ToolkitFramework\Config::getInstance()->
 $this->resetObjectManager();
 
 /** @var \Magento\Store\Model\StoreManager $storeManager */
-$storeManager = $this->getObjectManager()->create('\Magento\Store\Model\StoreManager');
+$storeManager = $this->getObjectManager()->create('Magento\Store\Model\StoreManager');
 /** @var $category \Magento\Catalog\Model\Category */
 $category = $this->getObjectManager()->get('Magento\Catalog\Model\Category');
 /** @var $model  \Magento\SalesRule\Model\Rule*/
diff --git a/dev/tools/performance-toolkit/fixtures/catalog_price_rules.php b/dev/tools/performance-toolkit/fixtures/catalog_price_rules.php
index 626946cef99..ab5c33e6a07 100644
--- a/dev/tools/performance-toolkit/fixtures/catalog_price_rules.php
+++ b/dev/tools/performance-toolkit/fixtures/catalog_price_rules.php
@@ -7,7 +7,7 @@ $catalogPriceRulesCount = \Magento\ToolkitFramework\Config::getInstance()->getVa
 $this->resetObjectManager();
 
 /** @var \Magento\Store\Model\StoreManager $storeManager */
-$storeManager = $this->getObjectManager()->create('\Magento\Store\Model\StoreManager');
+$storeManager = $this->getObjectManager()->create('Magento\Store\Model\StoreManager');
 /** @var $category \Magento\Catalog\Model\Category */
 $category = $this->getObjectManager()->get('Magento\Catalog\Model\Category');
 /** @var $model  \Magento\CatalogRule\Model\Rule*/
diff --git a/dev/tools/performance-toolkit/fixtures/categories.php b/dev/tools/performance-toolkit/fixtures/categories.php
index f25a56829e4..c01e7090464 100644
--- a/dev/tools/performance-toolkit/fixtures/categories.php
+++ b/dev/tools/performance-toolkit/fixtures/categories.php
@@ -8,7 +8,7 @@ $maxNestingLevel = \Magento\ToolkitFramework\Config::getInstance()->getValue('ca
 $this->resetObjectManager();
 
 /** @var \Magento\Store\Model\StoreManager $storeManager */
-$storeManager = $this->getObjectManager()->create('\Magento\Store\Model\StoreManager');
+$storeManager = $this->getObjectManager()->create('Magento\Store\Model\StoreManager');
 /** @var $category \Magento\Catalog\Model\Category */
 $category = $this->getObjectManager()->create('Magento\Catalog\Model\Category');
 
diff --git a/dev/tools/performance-toolkit/fixtures/configurable_products.php b/dev/tools/performance-toolkit/fixtures/configurable_products.php
index 657a94b5869..49a2f6574bd 100644
--- a/dev/tools/performance-toolkit/fixtures/configurable_products.php
+++ b/dev/tools/performance-toolkit/fixtures/configurable_products.php
@@ -7,7 +7,7 @@ $configurablesCount = \Magento\ToolkitFramework\Config::getInstance()->getValue(
 $this->resetObjectManager();
 
 /** @var \Magento\Store\Model\StoreManager $storeManager */
-$storeManager = $this->getObjectManager()->create('\Magento\Store\Model\StoreManager');
+$storeManager = $this->getObjectManager()->create('Magento\Store\Model\StoreManager');
 /** @var $category \Magento\Catalog\Model\Category */
 $category = $this->getObjectManager()->get('Magento\Catalog\Model\Category');
 
diff --git a/dev/tools/performance-toolkit/fixtures/customers.php b/dev/tools/performance-toolkit/fixtures/customers.php
index 195e7ff6b00..0932c543886 100644
--- a/dev/tools/performance-toolkit/fixtures/customers.php
+++ b/dev/tools/performance-toolkit/fixtures/customers.php
@@ -7,7 +7,7 @@ $customersNumber = \Magento\ToolkitFramework\Config::getInstance()->getValue('cu
 $this->resetObjectManager();
 
 /** @var \Magento\Store\Model\StoreManager $storeManager */
-$storeManager = $this->getObjectManager()->create('\Magento\Store\Model\StoreManager');
+$storeManager = $this->getObjectManager()->create('Magento\Store\Model\StoreManager');
 /** @var $category \Magento\Catalog\Model\Category */
 $category = $this->getObjectManager()->get('Magento\Catalog\Model\Category');
 /** @var $defaultStoreView \Magento\Store\Model\Store */
diff --git a/dev/tools/performance-toolkit/fixtures/eav_variations.php b/dev/tools/performance-toolkit/fixtures/eav_variations.php
index e3f307a2ec6..76e30a453a8 100644
--- a/dev/tools/performance-toolkit/fixtures/eav_variations.php
+++ b/dev/tools/performance-toolkit/fixtures/eav_variations.php
@@ -11,7 +11,7 @@ $model = $this->getObjectManager()->create('Magento\Catalog\Model\Resource\Eav\A
 /* @var $helper \Magento\Catalog\Helper\Product */
 $helper = $this->getObjectManager()->get('Magento\Catalog\Helper\Product');
 /** @var \Magento\Store\Model\StoreManager $storeManager */
-$storeManager = $this->getObjectManager()->create('\Magento\Store\Model\StoreManager');
+$storeManager = $this->getObjectManager()->create('Magento\Store\Model\StoreManager');
 $stores = $storeManager->getStores();
 $storeViewsCount = count($stores);
 
diff --git a/dev/tools/performance-toolkit/fixtures/simple_products.php b/dev/tools/performance-toolkit/fixtures/simple_products.php
index 755623b780c..ea54c518c1c 100644
--- a/dev/tools/performance-toolkit/fixtures/simple_products.php
+++ b/dev/tools/performance-toolkit/fixtures/simple_products.php
@@ -7,7 +7,7 @@ $simpleProductsCount = \Magento\ToolkitFramework\Config::getInstance()->getValue
 $this->resetObjectManager();
 
 /** @var \Magento\Store\Model\StoreManager $storeManager */
-$storeManager = $this->getObjectManager()->create('\Magento\Store\Model\StoreManager');
+$storeManager = $this->getObjectManager()->create('Magento\Store\Model\StoreManager');
 /** @var $category \Magento\Catalog\Model\Category */
 $category = $this->getObjectManager()->get('Magento\Catalog\Model\Category');
 
diff --git a/dev/tools/performance-toolkit/fixtures/stores.php b/dev/tools/performance-toolkit/fixtures/stores.php
index c2b932c846b..d58463ac2d9 100644
--- a/dev/tools/performance-toolkit/fixtures/stores.php
+++ b/dev/tools/performance-toolkit/fixtures/stores.php
@@ -9,7 +9,7 @@ $storesCount = \Magento\ToolkitFramework\Config::getInstance()->getValue('store_
 $this->resetObjectManager();
 
 /** @var \Magento\Store\Model\StoreManager $storeManager */
-$storeManager = $this->getObjectManager()->create('\Magento\Store\Model\StoreManager');
+$storeManager = $this->getObjectManager()->create('Magento\Store\Model\StoreManager');
 /** @var $category \Magento\Catalog\Model\Category */
 $category = $this->getObjectManager()->create('Magento\Catalog\Model\Category');
 
diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/AggregationFactory.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/AggregationFactory.php
index be11aaf87c0..67737e0c191 100644
--- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/AggregationFactory.php
+++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/AggregationFactory.php
@@ -43,7 +43,7 @@ class AggregationFactory
                 ]
             );
         }
-        return $this->objectManager->create('\Magento\Framework\Search\Response\Aggregation', ['buckets' => $buckets]);
+        return $this->objectManager->create('Magento\Framework\Search\Response\Aggregation', ['buckets' => $buckets]);
     }
 
     /**
diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/DocumentFactory.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/DocumentFactory.php
index 5088c01d6e5..0f96fb6a5aa 100644
--- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/DocumentFactory.php
+++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/DocumentFactory.php
@@ -49,11 +49,11 @@ class DocumentFactory
             if ($rawField['name'] == $entityId) {
                 $documentId = $rawField['value'];
             } else {
-                $fields[] = $this->objectManager->create('\Magento\Framework\Search\DocumentField', $rawField);
+                $fields[] = $this->objectManager->create('Magento\Framework\Search\DocumentField', $rawField);
             }
         }
         return $this->objectManager->create(
-            '\Magento\Framework\Search\Document',
+            'Magento\Framework\Search\Document',
             ['documentFields' => $fields, 'documentId' => $documentId]
         );
     }
diff --git a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ResponseFactory.php b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ResponseFactory.php
index dcc8e1b08f4..7a79ca11e61 100644
--- a/lib/internal/Magento/Framework/Search/Adapter/Mysql/ResponseFactory.php
+++ b/lib/internal/Magento/Framework/Search/Adapter/Mysql/ResponseFactory.php
@@ -62,7 +62,7 @@ class ResponseFactory
         /** @var \Magento\Framework\Search\Response\Aggregation $aggregations */
         $aggregations = $this->aggregationFactory->create($rawResponse['aggregations']);
         return $this->objectManager->create(
-            '\Magento\Framework\Search\Response\QueryResponse',
+            'Magento\Framework\Search\Response\QueryResponse',
             [
                 'documents' => $documents,
                 'aggregations' => $aggregations
diff --git a/pub/errors/processorFactory.php b/pub/errors/processorFactory.php
index ba61ce6a9fa..62b5330f805 100644
--- a/pub/errors/processorFactory.php
+++ b/pub/errors/processorFactory.php
@@ -21,7 +21,7 @@ class ProcessorFactory
     {
         $objectManagerFactory = \Magento\Framework\App\Bootstrap::createObjectManagerFactory(BP, $_SERVER);
         $objectManager = $objectManagerFactory->create($_SERVER);
-        $response = $objectManager->create('\Magento\Framework\App\Response\Http');
+        $response = $objectManager->create('Magento\Framework\App\Response\Http');
         return new Processor($response);
     }
 }
-- 
GitLab


From bfa23651061ea6e11935bbae99ebb3a136fce3c2 Mon Sep 17 00:00:00 2001
From: Sviatoslav Mankivskyi <smankivskyi@ebay.com>
Date: Fri, 19 Dec 2014 16:15:55 +0200
Subject: [PATCH 20/71] MAGETWO-31961: Exception when add configurable product
 from wishlist into cart(problem with product id and item_id)

---
 .../Wishlist/Controller/Index/Cart.php        | 113 ++-
 .../Wishlist/Controller/Index/CartTest.php    | 797 ++++++++++++++++++
 2 files changed, 867 insertions(+), 43 deletions(-)
 create mode 100644 dev/tests/unit/testsuite/Magento/Wishlist/Controller/Index/CartTest.php

diff --git a/app/code/Magento/Wishlist/Controller/Index/Cart.php b/app/code/Magento/Wishlist/Controller/Index/Cart.php
index 27e2885c753..edb018b57b8 100644
--- a/app/code/Magento/Wishlist/Controller/Index/Cart.php
+++ b/app/code/Magento/Wishlist/Controller/Index/Cart.php
@@ -21,18 +21,66 @@ class Cart extends Action\Action implements IndexInterface
      */
     protected $quantityProcessor;
 
+    /**
+     * @var \Magento\Wishlist\Model\ItemFactory
+     */
+    protected $itemFactory;
+
+    /**
+     * @var \Magento\Checkout\Model\Cart
+     */
+    protected $cart;
+
+    /**
+     * @var \Magento\Wishlist\Model\Item\OptionFactory
+     */
+    private $optionFactory;
+
+    /**
+     * @var \Magento\Catalog\Helper\Product
+     */
+    protected $productHelper;
+
+    /**
+     * @var \Magento\Framework\Escaper
+     */
+    protected $escaper;
+
+    /**
+     * @var \Magento\Wishlist\Helper\Data
+     */
+    protected $helper;
+
     /**
      * @param Action\Context $context
      * @param \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider
      * @param \Magento\Wishlist\Model\LocaleQuantityProcessor $quantityProcessor
+     * @param \Magento\Wishlist\Model\ItemFactory $itemFactory
+     * @param \Magento\Checkout\Model\Cart $cart
+     * @param \Magento\Wishlist\Model\Item\OptionFactory $
+     * @param \Magento\Catalog\Helper\Product $productHelper
+     * @param \Magento\Framework\Escaper $escaper
+     * @param \Magento\Wishlist\Helper\Data $helper
      */
     public function __construct(
         Action\Context $context,
         \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider,
-        \Magento\Wishlist\Model\LocaleQuantityProcessor $quantityProcessor
+        \Magento\Wishlist\Model\LocaleQuantityProcessor $quantityProcessor,
+        \Magento\Wishlist\Model\ItemFactory $itemFactory,
+        \Magento\Checkout\Model\Cart $cart,
+        \Magento\Wishlist\Model\Item\OptionFactory $optionFactory,
+        \Magento\Catalog\Helper\Product $productHelper,
+        \Magento\Framework\Escaper $escaper,
+        \Magento\Wishlist\Helper\Data $helper
     ) {
         $this->wishlistProvider = $wishlistProvider;
         $this->quantityProcessor = $quantityProcessor;
+        $this->itemFactory = $itemFactory;
+        $this->cart = $cart;
+        $this->optionFactory = $optionFactory;
+        $this->productHelper = $productHelper;
+        $this->escaper = $escaper;
+        $this->helper = $helper;
         parent::__construct($context);
     }
 
@@ -49,7 +97,7 @@ class Cart extends Action\Action implements IndexInterface
         $itemId = (int)$this->getRequest()->getParam('item');
 
         /* @var $item \Magento\Wishlist\Model\Item */
-        $item = $this->_objectManager->create('Magento\Wishlist\Model\Item')->load($itemId);
+        $item = $this->itemFactory->create()->load($itemId);
         if (!$item->getId()) {
             return $this->_redirect('*/*');
         }
@@ -72,82 +120,61 @@ class Cart extends Action\Action implements IndexInterface
             $item->setQty($qty);
         }
 
-        /* @var $session \Magento\Framework\Session\Generic */
-        $session = $this->_objectManager->get('Magento\Wishlist\Model\Session');
-        $cart = $this->_objectManager->get('Magento\Checkout\Model\Cart');
-
         $redirectUrl = $this->_url->getUrl('*/*');
+        $configureUrl = $this->_url->getUrl(
+            '*/*/configure/',
+            [
+                'id' => $item->getId(),
+                'product_id' => $item->getProductId(),
+            ]
+        );
 
         try {
-            $options = $this->_objectManager->create(
-                'Magento\Wishlist\Model\Item\Option'
-            )->getCollection()->addItemFilter(
-                [$itemId]
-            );
+            /** @var \Magento\Wishlist\Model\Resource\Item\Option\Collection $options */
+            $options = $this->optionFactory->create()->getCollection()->addItemFilter([$itemId]);
             $item->setOptions($options->getOptionsByItem($itemId));
 
-            $buyRequest = $this->_objectManager->get(
-                'Magento\Catalog\Helper\Product'
-            )->addParamsToBuyRequest(
+            $buyRequest = $this->productHelper->addParamsToBuyRequest(
                 $this->getRequest()->getParams(),
                 ['current_config' => $item->getBuyRequest()]
             );
 
             $item->mergeBuyRequest($buyRequest);
-            $item->addToCart($cart, true);
-            $cart->save()->getQuote()->collectTotals();
+            $item->addToCart($this->cart, true);
+            $this->cart->save()->getQuote()->collectTotals();
             $wishlist->save();
 
-            if (!$cart->getQuote()->getHasError()) {
+            if (!$this->cart->getQuote()->getHasError()) {
                 $message = __(
                     'You added %1 to your shopping cart.',
-                    $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($item->getProduct()->getName())
+                    $this->escaper->escapeHtml($item->getProduct()->getName())
                 );
                 $this->messageManager->addSuccess($message);
             }
 
-            $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
-
-            if ($this->_objectManager->get('Magento\Checkout\Helper\Cart')->getShouldRedirectToCart()) {
-                $redirectUrl = $this->_objectManager->get('Magento\Checkout\Helper\Cart')->getCartUrl();
+            if ($this->cart->getShouldRedirectToCart()) {
+                $redirectUrl = $this->cart->getCartUrl();
             } else {
                 $refererUrl = $this->_redirect->getRefererUrl();
-                if ($refererUrl &&
-                    ($refererUrl != $this->_objectManager->get('Magento\Framework\UrlInterface')
-                            ->getUrl('*/*/configure/', ['id' => $item->getId(), 'product_id' => $item->getProductId()])
-                    )
-                ) {
+                if ($refererUrl && $refererUrl != $configureUrl) {
                     $redirectUrl = $refererUrl;
                 }
             }
-            $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
         } catch (\Magento\Framework\Model\Exception $e) {
             if ($e->getCode() == \Magento\Wishlist\Model\Item::EXCEPTION_CODE_NOT_SALABLE) {
                 $this->messageManager->addError(__('This product(s) is out of stock.'));
             } elseif ($e->getCode() == \Magento\Wishlist\Model\Item::EXCEPTION_CODE_HAS_REQUIRED_OPTIONS) {
                 $this->messageManager->addNotice($e->getMessage());
-                $redirectUrl = $this->_url->getUrl(
-                    '*/*/configure/',
-                    [
-                        'id' => $item->getId(),
-                        'product_id' => $item->getProductId(),
-                    ]
-                );
+                $redirectUrl = $configureUrl;
             } else {
                 $this->messageManager->addNotice($e->getMessage());
-                $redirectUrl = $this->_url->getUrl(
-                    '*/*/configure/',
-                    [
-                        'id' => $item->getId(),
-                        'product_id' => $item->getProductId(),
-                    ]
-                );
+                $redirectUrl = $configureUrl;
             }
         } catch (\Exception $e) {
             $this->messageManager->addException($e, __('Cannot add item to shopping cart'));
         }
 
-        $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
+        $this->helper->calculate();
 
         return $this->getResponse()->setRedirect($redirectUrl);
     }
diff --git a/dev/tests/unit/testsuite/Magento/Wishlist/Controller/Index/CartTest.php b/dev/tests/unit/testsuite/Magento/Wishlist/Controller/Index/CartTest.php
new file mode 100644
index 00000000000..9fdcf260c80
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Wishlist/Controller/Index/CartTest.php
@@ -0,0 +1,797 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Wishlist\Controller\Index;
+
+class CartTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Cart
+     */
+    protected $model;
+
+    /**
+     * @var \Magento\Framework\App\Action\Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $contextMock;
+
+    /**
+     * @var \Magento\Wishlist\Controller\WishlistProviderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $wishlistProviderMock;
+
+    /**
+     * @var \Magento\Wishlist\Model\LocaleQuantityProcessor|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $quantityProcessorMock;
+
+    /**
+     * @var \Magento\Wishlist\Model\ItemFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $itemFactoryMock;
+
+    /**
+     * @var \Magento\Checkout\Model\Cart|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $checkoutCartMock;
+
+    /**
+     * @var \Magento\Wishlist\Model\Item\OptionFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $optionFactoryMock;
+
+    /**
+     * @var \Magento\Catalog\Helper\Product|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productHelperMock;
+
+    /**
+     * @var \Magento\Framework\Escaper|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $escaperMock;
+
+    /**
+     * @var \Magento\Wishlist\Helper\Data|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $helperMock;
+
+    /**
+     * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $requestMock;
+
+    /**
+     * @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $responseMock;
+
+    /**
+     * @var \Magento\Framework\App\Response\RedirectInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $redirectMock;
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $objectManagerMock;
+
+    /**
+     * @var \Magento\Framework\Message\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $messageManagerMock;
+
+    /**
+     * @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlMock;
+
+    protected function setUp()
+    {
+        $this->wishlistProviderMock = $this->getMockBuilder('Magento\Wishlist\Controller\WishlistProviderInterface')
+            ->disableOriginalConstructor()
+            ->setMethods(['getWishlist'])
+            ->getMockForAbstractClass();
+
+        $this->quantityProcessorMock = $this->getMockBuilder('Magento\Wishlist\Model\LocaleQuantityProcessor')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->itemFactoryMock = $this->getMockBuilder('Magento\Wishlist\Model\ItemFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+
+        $this->checkoutCartMock = $this->getMockBuilder('Magento\Checkout\Model\Cart')
+            ->disableOriginalConstructor()
+            ->setMethods(['save', 'getQuote', 'getShouldRedirectToCart', 'getCartUrl'])
+            ->getMock();
+
+        $this->optionFactoryMock = $this->getMockBuilder('Magento\Wishlist\Model\Item\OptionFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+
+        $this->productHelperMock = $this->getMockBuilder('Magento\Catalog\Helper\Product')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->escaperMock = $this->getMockBuilder('Magento\Framework\Escaper')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->helperMock = $this->getMockBuilder('Magento\Wishlist\Helper\Data')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->requestMock = $this->getMockBuilder('Magento\Framework\App\RequestInterface')
+            ->disableOriginalConstructor()
+            ->setMethods(['getParams', 'getParam'])
+            ->getMockForAbstractClass();
+
+        $this->responseMock = $this->getMockBuilder('Magento\Framework\App\ResponseInterface')
+            ->disableOriginalConstructor()
+            ->setMethods(['setRedirect'])
+            ->getMockForAbstractClass();
+
+        $this->redirectMock = $this->getMockBuilder('Magento\Framework\App\Response\RedirectInterface')
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+
+        $this->objectManagerMock = $this->getMockBuilder('Magento\Framework\ObjectManagerInterface')
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+
+        $this->messageManagerMock = $this->getMockBuilder('Magento\Framework\Message\ManagerInterface')
+            ->disableOriginalConstructor()
+            ->setMethods(['addSuccess'])
+            ->getMockForAbstractClass();
+
+        $this->urlMock = $this->getMockBuilder('Magento\Framework\UrlInterface')
+            ->disableOriginalConstructor()
+            ->setMethods(['getUrl'])
+            ->getMockForAbstractClass();
+
+        $this->contextMock = $this->getMockBuilder('Magento\Framework\App\Action\Context')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->contextMock->expects($this->any())
+            ->method('getRequest')
+            ->will($this->returnValue($this->requestMock));
+        $this->contextMock->expects($this->any())
+            ->method('getResponse')
+            ->will($this->returnValue($this->responseMock));
+        $this->contextMock->expects($this->any())
+            ->method('getRedirect')
+            ->will($this->returnValue($this->redirectMock));
+        $this->contextMock->expects($this->any())
+            ->method('getObjectManager')
+            ->will($this->returnValue($this->objectManagerMock));
+        $this->contextMock->expects($this->any())
+            ->method('getMessageManager')
+            ->will($this->returnValue($this->messageManagerMock));
+        $this->contextMock->expects($this->any())
+            ->method('getUrl')
+            ->will($this->returnValue($this->urlMock));
+
+        $this->model = new Cart(
+            $this->contextMock,
+            $this->wishlistProviderMock,
+            $this->quantityProcessorMock,
+            $this->itemFactoryMock,
+            $this->checkoutCartMock,
+            $this->optionFactoryMock,
+            $this->productHelperMock,
+            $this->escaperMock,
+            $this->helperMock
+        );
+    }
+
+    public function testExecuteWithNoItem()
+    {
+        $itemId = false;
+
+        $itemMock = $this->getMockBuilder('Magento\Wishlist\Model\Item')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->requestMock->expects($this->once())
+            ->method('getParam')
+            ->with('item', null)
+            ->willReturn($itemId);
+        $this->itemFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($itemMock);
+
+        $itemMock->expects($this->once())
+            ->method('load')
+            ->with($itemId, null)
+            ->willReturnSelf();
+        $itemMock->expects($this->once())
+            ->method('getId')
+            ->willReturn(null);
+
+        $this->redirectMock->expects($this->once())
+            ->method('redirect')
+            ->with($this->responseMock, '*/*', [])
+            ->willReturn($this->responseMock);
+
+        $this->assertEquals($this->responseMock, $this->model->execute());
+    }
+
+    public function testExecuteWithNoWishlist()
+    {
+        $itemId = 2;
+        $wishlistId = 1;
+
+        $itemMock = $this->getMockBuilder('Magento\Wishlist\Model\Item')
+            ->disableOriginalConstructor()
+            ->setMethods(['load', 'getId', 'getWishlistId'])
+            ->getMock();
+
+        $this->requestMock->expects($this->once())
+            ->method('getParam')
+            ->with('item', null)
+            ->willReturn($itemId);
+        $this->itemFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($itemMock);
+
+        $itemMock->expects($this->once())
+            ->method('load')
+            ->with($itemId, null)
+            ->willReturnSelf();
+        $itemMock->expects($this->once())
+            ->method('getId')
+            ->willReturn($itemId);
+        $itemMock->expects($this->once())
+            ->method('getWishlistId')
+            ->willReturn($wishlistId);
+
+        $this->wishlistProviderMock->expects($this->once())
+            ->method('getWishlist')
+            ->with($wishlistId)
+            ->willReturn(null);
+
+        $this->redirectMock->expects($this->once())
+            ->method('redirect')
+            ->with($this->responseMock, '*/*', [])
+            ->willReturn($this->responseMock);
+
+        $this->assertEquals($this->responseMock, $this->model->execute());
+    }
+
+    public function testExecuteWithQuantityArray()
+    {
+        $itemId = 2;
+        $wishlistId = 1;
+        $qty = [$itemId => 3];
+        $productId = 4;
+        $productName = 'product_name';
+        $indexUrl = 'index_url';
+        $configureUrl = 'configure_url';
+        $options = [5 => 'option'];
+        $params = ['item' => $itemId, 'qty' => $qty];
+        $refererUrl = 'referer_url';
+
+        $itemMock = $this->getMockBuilder('Magento\Wishlist\Model\Item')
+            ->disableOriginalConstructor()
+            ->setMethods(
+                [
+                    'load',
+                    'getId',
+                    'getWishlistId',
+                    'setQty',
+                    'setOptions',
+                    'getBuyRequest',
+                    'mergeBuyRequest',
+                    'addToCart',
+                    'getProduct',
+                    'getProductId',
+                ]
+            )
+            ->getMock();
+
+        $this->requestMock->expects($this->at(0))
+            ->method('getParam')
+            ->with('item', null)
+            ->willReturn($itemId);
+        $this->itemFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($itemMock);
+
+        $itemMock->expects($this->once())
+            ->method('load')
+            ->with($itemId, null)
+            ->willReturnSelf();
+        $itemMock->expects($this->exactly(2))
+            ->method('getId')
+            ->willReturn($itemId);
+        $itemMock->expects($this->once())
+            ->method('getWishlistId')
+            ->willReturn($wishlistId);
+
+        $wishlistMock = $this->getMockBuilder('Magento\Wishlist\Model\Wishlist')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->wishlistProviderMock->expects($this->once())
+            ->method('getWishlist')
+            ->with($wishlistId)
+            ->willReturn($wishlistMock);
+
+        $this->requestMock->expects($this->at(1))
+            ->method('getParam')
+            ->with('qty', null)
+            ->willReturn($qty);
+
+        $this->quantityProcessorMock->expects($this->once())
+            ->method('process')
+            ->with($qty[$itemId])
+            ->willReturnArgument(0);
+
+        $itemMock->expects($this->once())
+            ->method('setQty')
+            ->with($qty[$itemId])
+            ->willReturnSelf();
+
+        $this->urlMock->expects($this->at(0))
+            ->method('getUrl')
+            ->with('*/*', null)
+            ->willReturn($indexUrl);
+
+        $itemMock->expects($this->once())
+            ->method('getProductId')
+            ->willReturn($productId);
+
+        $this->urlMock->expects($this->at(1))
+            ->method('getUrl')
+            ->with('*/*/configure/', ['id' => $itemId, 'product_id' => $productId])
+            ->willReturn($configureUrl);
+
+        $optionMock = $this->getMockBuilder('Magento\Wishlist\Model\Item\Option')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->optionFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($optionMock);
+
+        $optionsMock = $this->getMockBuilder('Magento\Wishlist\Model\Resource\Item\Option\Collection')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $optionMock->expects($this->once())
+            ->method('getCollection')
+            ->willReturn($optionsMock);
+
+        $optionsMock->expects($this->once())
+            ->method('addItemFilter')
+            ->with([$itemId])
+            ->willReturnSelf();
+        $optionsMock->expects($this->once())
+            ->method('getOptionsByItem')
+            ->with($itemId)
+            ->willReturn($options);
+
+        $itemMock->expects($this->once())
+            ->method('setOptions')
+            ->with($options)
+            ->willReturnSelf();
+
+        $this->requestMock->expects($this->once())
+            ->method('getParams')
+            ->willReturn($params);
+
+        $buyRequestMock = $this->getMockBuilder('Magento\Framework\Object')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $itemMock->expects($this->once())
+            ->method('getBuyRequest')
+            ->willReturn($buyRequestMock);
+
+        $this->productHelperMock->expects($this->once())
+            ->method('addParamsToBuyRequest')
+            ->with($params, ['current_config' => $buyRequestMock])
+            ->willReturn($buyRequestMock);
+
+        $itemMock->expects($this->once())
+            ->method('mergeBuyRequest')
+            ->with($buyRequestMock)
+            ->willReturnSelf();
+        $itemMock->expects($this->once())
+            ->method('addToCart')
+            ->with($this->checkoutCartMock, true)
+            ->willReturn(true);
+
+        $this->checkoutCartMock->expects($this->once())
+            ->method('save')
+            ->willReturnSelf();
+
+        $quoteMock = $this->getMockBuilder('Magento\Sales\Model\Quote')
+            ->disableOriginalConstructor()
+            ->setMethods(['getHasError', 'collectTotals'])
+            ->getMock();
+
+        $this->checkoutCartMock->expects($this->exactly(2))
+            ->method('getQuote')
+            ->willReturn($quoteMock);
+
+        $quoteMock->expects($this->once())
+            ->method('collectTotals')
+            ->willReturnSelf();
+
+        $wishlistMock->expects($this->once())
+            ->method('save')
+            ->willReturnSelf();
+
+        $quoteMock->expects($this->once())
+            ->method('getHasError')
+            ->willReturn(false);
+
+        $productMock = $this->getMockBuilder('Magento\Catalog\Model\Product')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $itemMock->expects($this->once())
+            ->method('getProduct')
+            ->willReturn($productMock);
+
+        $productMock->expects($this->once())
+            ->method('getName')
+            ->willReturn($productName);
+
+        $this->escaperMock->expects($this->once())
+            ->method('escapeHtml')
+            ->with($productName, null)
+            ->willReturn($productName);
+
+        $this->messageManagerMock->expects($this->once())
+            ->method('addSuccess')
+            ->with('You added '  . $productName . ' to your shopping cart.', null)
+            ->willReturnSelf();
+
+        $this->checkoutCartMock->expects($this->once())
+            ->method('getShouldRedirectToCart')
+            ->willReturn(false);
+
+        $this->redirectMock->expects($this->once())
+            ->method('getRefererUrl')
+            ->willReturn($refererUrl);
+
+        $this->helperMock->expects($this->once())
+            ->method('calculate')
+            ->willReturnSelf();
+
+        $this->responseMock->expects($this->once())
+            ->method('setRedirect')
+            ->with($refererUrl)
+            ->willReturn($this->responseMock);
+
+        $this->assertEquals($this->responseMock, $this->model->execute());
+    }
+
+    public function testExecuteWithoutQuantityArrayAndOutOfStock()
+    {
+        $itemId = 2;
+        $wishlistId = 1;
+        $qty = [];
+        $productId = 4;
+        $indexUrl = 'index_url';
+        $configureUrl = 'configure_url';
+        $options = [5 => 'option'];
+        $params = ['item' => $itemId, 'qty' => $qty];
+
+        $itemMock = $this->getMockBuilder('Magento\Wishlist\Model\Item')
+            ->disableOriginalConstructor()
+            ->setMethods(
+                [
+                    'load',
+                    'getId',
+                    'getWishlistId',
+                    'setQty',
+                    'setOptions',
+                    'getBuyRequest',
+                    'mergeBuyRequest',
+                    'addToCart',
+                    'getProduct',
+                    'getProductId',
+                ]
+            )
+            ->getMock();
+
+        $this->requestMock->expects($this->at(0))
+            ->method('getParam')
+            ->with('item', null)
+            ->willReturn($itemId);
+        $this->itemFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($itemMock);
+
+        $itemMock->expects($this->once())
+            ->method('load')
+            ->with($itemId, null)
+            ->willReturnSelf();
+        $itemMock->expects($this->exactly(2))
+            ->method('getId')
+            ->willReturn($itemId);
+        $itemMock->expects($this->once())
+            ->method('getWishlistId')
+            ->willReturn($wishlistId);
+
+        $wishlistMock = $this->getMockBuilder('Magento\Wishlist\Model\Wishlist')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->wishlistProviderMock->expects($this->once())
+            ->method('getWishlist')
+            ->with($wishlistId)
+            ->willReturn($wishlistMock);
+
+        $this->requestMock->expects($this->at(1))
+            ->method('getParam')
+            ->with('qty', null)
+            ->willReturn($qty);
+
+        $this->quantityProcessorMock->expects($this->once())
+            ->method('process')
+            ->with(1)
+            ->willReturnArgument(0);
+
+        $itemMock->expects($this->once())
+            ->method('setQty')
+            ->with(1)
+            ->willReturnSelf();
+
+        $this->urlMock->expects($this->at(0))
+            ->method('getUrl')
+            ->with('*/*', null)
+            ->willReturn($indexUrl);
+
+        $itemMock->expects($this->once())
+            ->method('getProductId')
+            ->willReturn($productId);
+
+        $this->urlMock->expects($this->at(1))
+            ->method('getUrl')
+            ->with('*/*/configure/', ['id' => $itemId, 'product_id' => $productId])
+            ->willReturn($configureUrl);
+
+        $optionMock = $this->getMockBuilder('Magento\Wishlist\Model\Item\Option')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->optionFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($optionMock);
+
+        $optionsMock = $this->getMockBuilder('Magento\Wishlist\Model\Resource\Item\Option\Collection')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $optionMock->expects($this->once())
+            ->method('getCollection')
+            ->willReturn($optionsMock);
+
+        $optionsMock->expects($this->once())
+            ->method('addItemFilter')
+            ->with([$itemId])
+            ->willReturnSelf();
+        $optionsMock->expects($this->once())
+            ->method('getOptionsByItem')
+            ->with($itemId)
+            ->willReturn($options);
+
+        $itemMock->expects($this->once())
+            ->method('setOptions')
+            ->with($options)
+            ->willReturnSelf();
+
+        $this->requestMock->expects($this->once())
+            ->method('getParams')
+            ->willReturn($params);
+
+        $buyRequestMock = $this->getMockBuilder('Magento\Framework\Object')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $itemMock->expects($this->once())
+            ->method('getBuyRequest')
+            ->willReturn($buyRequestMock);
+
+        $this->productHelperMock->expects($this->once())
+            ->method('addParamsToBuyRequest')
+            ->with($params, ['current_config' => $buyRequestMock])
+            ->willReturn($buyRequestMock);
+
+        $itemMock->expects($this->once())
+            ->method('mergeBuyRequest')
+            ->with($buyRequestMock)
+            ->willReturnSelf();
+        $itemMock->expects($this->once())
+            ->method('addToCart')
+            ->with($this->checkoutCartMock, true)
+            ->willThrowException(
+                new \Magento\Framework\Model\Exception(null, \Magento\Wishlist\Model\Item::EXCEPTION_CODE_NOT_SALABLE)
+            );
+
+        $this->messageManagerMock->expects($this->once())
+            ->method('addError')
+            ->with('This product(s) is out of stock.', null)
+            ->willReturnSelf();
+
+        $this->helperMock->expects($this->once())
+            ->method('calculate')
+            ->willReturnSelf();
+
+        $this->responseMock->expects($this->once())
+            ->method('setRedirect')
+            ->with($indexUrl)
+            ->willReturn($this->responseMock);
+
+        $this->assertEquals($this->responseMock, $this->model->execute());
+    }
+
+    public function testExecuteWithoutQuantityArrayAndConfigurable()
+    {
+        $itemId = 2;
+        $wishlistId = 1;
+        $qty = [];
+        $productId = 4;
+        $indexUrl = 'index_url';
+        $configureUrl = 'configure_url';
+        $options = [5 => 'option'];
+        $params = ['item' => $itemId, 'qty' => $qty];
+
+        $itemMock = $this->getMockBuilder('Magento\Wishlist\Model\Item')
+            ->disableOriginalConstructor()
+            ->setMethods(
+                [
+                    'load',
+                    'getId',
+                    'getWishlistId',
+                    'setQty',
+                    'setOptions',
+                    'getBuyRequest',
+                    'mergeBuyRequest',
+                    'addToCart',
+                    'getProduct',
+                    'getProductId',
+                ]
+            )
+            ->getMock();
+
+        $this->requestMock->expects($this->at(0))
+            ->method('getParam')
+            ->with('item', null)
+            ->willReturn($itemId);
+        $this->itemFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($itemMock);
+
+        $itemMock->expects($this->once())
+            ->method('load')
+            ->with($itemId, null)
+            ->willReturnSelf();
+        $itemMock->expects($this->exactly(2))
+            ->method('getId')
+            ->willReturn($itemId);
+        $itemMock->expects($this->once())
+            ->method('getWishlistId')
+            ->willReturn($wishlistId);
+
+        $wishlistMock = $this->getMockBuilder('Magento\Wishlist\Model\Wishlist')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->wishlistProviderMock->expects($this->once())
+            ->method('getWishlist')
+            ->with($wishlistId)
+            ->willReturn($wishlistMock);
+
+        $this->requestMock->expects($this->at(1))
+            ->method('getParam')
+            ->with('qty', null)
+            ->willReturn($qty);
+
+        $this->quantityProcessorMock->expects($this->once())
+            ->method('process')
+            ->with(1)
+            ->willReturnArgument(0);
+
+        $itemMock->expects($this->once())
+            ->method('setQty')
+            ->with(1)
+            ->willReturnSelf();
+
+        $this->urlMock->expects($this->at(0))
+            ->method('getUrl')
+            ->with('*/*', null)
+            ->willReturn($indexUrl);
+
+        $itemMock->expects($this->once())
+            ->method('getProductId')
+            ->willReturn($productId);
+
+        $this->urlMock->expects($this->at(1))
+            ->method('getUrl')
+            ->with('*/*/configure/', ['id' => $itemId, 'product_id' => $productId])
+            ->willReturn($configureUrl);
+
+        $optionMock = $this->getMockBuilder('Magento\Wishlist\Model\Item\Option')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->optionFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($optionMock);
+
+        $optionsMock = $this->getMockBuilder('Magento\Wishlist\Model\Resource\Item\Option\Collection')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $optionMock->expects($this->once())
+            ->method('getCollection')
+            ->willReturn($optionsMock);
+
+        $optionsMock->expects($this->once())
+            ->method('addItemFilter')
+            ->with([$itemId])
+            ->willReturnSelf();
+        $optionsMock->expects($this->once())
+            ->method('getOptionsByItem')
+            ->with($itemId)
+            ->willReturn($options);
+
+        $itemMock->expects($this->once())
+            ->method('setOptions')
+            ->with($options)
+            ->willReturnSelf();
+
+        $this->requestMock->expects($this->once())
+            ->method('getParams')
+            ->willReturn($params);
+
+        $buyRequestMock = $this->getMockBuilder('Magento\Framework\Object')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $itemMock->expects($this->once())
+            ->method('getBuyRequest')
+            ->willReturn($buyRequestMock);
+
+        $this->productHelperMock->expects($this->once())
+            ->method('addParamsToBuyRequest')
+            ->with($params, ['current_config' => $buyRequestMock])
+            ->willReturn($buyRequestMock);
+
+        $itemMock->expects($this->once())
+            ->method('mergeBuyRequest')
+            ->with($buyRequestMock)
+            ->willReturnSelf();
+        $itemMock->expects($this->once())
+            ->method('addToCart')
+            ->with($this->checkoutCartMock, true)
+            ->willThrowException(
+                new \Magento\Framework\Model\Exception(
+                    'message',
+                    \Magento\Wishlist\Model\Item::EXCEPTION_CODE_HAS_REQUIRED_OPTIONS
+                )
+            );
+
+        $this->messageManagerMock->expects($this->once())
+            ->method('addNotice')
+            ->with('message', null)
+            ->willReturnSelf();
+
+        $this->helperMock->expects($this->once())
+            ->method('calculate')
+            ->willReturnSelf();
+
+        $this->responseMock->expects($this->once())
+            ->method('setRedirect')
+            ->with($configureUrl)
+            ->willReturn($this->responseMock);
+
+        $this->assertEquals($this->responseMock, $this->model->execute());
+    }
+}
-- 
GitLab


From 68ef14c5556e3ece0cc590428029354d5e3f8249 Mon Sep 17 00:00:00 2001
From: Dmytro Voskoboinikov <dvoskoboinikov@ebay.com>
Date: Fri, 19 Dec 2014 16:22:58 +0200
Subject: [PATCH 21/71] MAGETWO-30854: Unexpected <br> html element is present
 on 'View Return' Customer account frontend page

---
 app/code/Magento/Customer/etc/config.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/code/Magento/Customer/etc/config.xml b/app/code/Magento/Customer/etc/config.xml
index 10a4fcbd2f6..521a80d8c30 100644
--- a/app/code/Magento/Customer/etc/config.xml
+++ b/app/code/Magento/Customer/etc/config.xml
@@ -58,7 +58,7 @@ T: {{var telephone}}
 {{depend fax}}F: {{var fax}}{{/depend}}
 {{depend vat_id}}VAT: {{var vat_id}}{{/depend}}</text>
                 <oneline>{{depend prefix}}{{var prefix}} {{/depend}}{{var firstname}} {{depend middlename}}{{var middlename}} {{/depend}}{{var lastname}}{{depend suffix}} {{var suffix}}{{/depend}}, {{var street}}, {{var city}}, {{var region}} {{var postcode}}, {{var country}}</oneline>
-                <html><![CDATA[{{depend prefix}}{{var prefix}} {{/depend}}{{var firstname}} {{depend middlename}}{{var middlename}} {{/depend}}{{var lastname}}{{depend suffix}} {{var suffix}}{{/depend}}<br/>
+                <html><![CDATA[{{depend prefix}}{{var prefix}} {{/depend}}{{var firstname}} {{depend middlename}}{{var middlename}} {{/depend}}{{var lastname}}{{depend suffix}} {{var suffix}}{{/depend}}{{depend firstname}}<br/>{{/depend}}
 {{depend company}}{{var company}}<br />{{/depend}}
 {{if street1}}{{var street1}}<br />{{/if}}
 {{depend street2}}{{var street2}}<br />{{/depend}}
-- 
GitLab


From 912b4a8136ee5d744e842444a40c84eaa5429688 Mon Sep 17 00:00:00 2001
From: Dmytro Aponasenko <daponasenko@ebay.com>
Date: Fri, 19 Dec 2014 16:35:08 +0200
Subject: [PATCH 22/71] MTA-589: Re-factor Test for Quick Search

---
 .../CatalogSearch/Test/Fixture/CatalogSearchQuery/QueryText.php  | 1 +
 1 file changed, 1 insertion(+)

diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery/QueryText.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery/QueryText.php
index 5018a19a16d..e570c33fa10 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery/QueryText.php
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery/QueryText.php
@@ -33,6 +33,7 @@ class QueryText implements FixtureInterface
     protected $data;
 
     /**
+     * @constructor
      * @param FixtureFactory $fixtureFactory
      * @param array $params
      * @param array $data
-- 
GitLab


From 642dcde1ef1ac1495c853c13cf019420ee0a1507 Mon Sep 17 00:00:00 2001
From: Andriy Nasinnyk <anasinnyk@ebay.com>
Date: Fri, 19 Dec 2014 16:45:04 +0200
Subject: [PATCH 23/71] MAGETWO-13915: PSR-3: common interface for logging
 libraries.

 - eliminate Magento\Framework\Logger\Adapter
---
 .../Authorizenet/Model/Authorizenet.php       |  3 --
 .../Magento/Authorizenet/Model/Directpost.php |  7 ++--
 app/code/Magento/Centinel/Model/Api.php       | 20 ++++--------
 app/code/Magento/Fedex/Model/Carrier.php      |  5 ---
 .../Magento/GoogleShopping/Model/Service.php  | 32 ++++++-------------
 .../GoogleShopping/Model/Service/Item.php     |  6 ++--
 app/code/Magento/Ogone/Model/Api.php          |  6 ++--
 .../Payment/Model/Method/AbstractMethod.php   | 23 +++----------
 app/code/Magento/Payment/Model/Method/Cc.php  | 12 +------
 .../Magento/Payment/Model/Method/Free.php     |  6 ++--
 app/code/Magento/Paypal/Model/AbstractIpn.php | 19 +++--------
 .../Magento/Paypal/Model/Api/AbstractApi.php  | 16 +---------
 app/code/Magento/Paypal/Model/Api/Nvp.php     |  4 +--
 .../Magento/Paypal/Model/Api/PayflowNvp.php   |  3 --
 app/code/Magento/Paypal/Model/Direct.php      |  3 --
 app/code/Magento/Paypal/Model/Express.php     |  6 ++--
 .../Magento/Paypal/Model/Express/Checkout.php | 14 ++------
 app/code/Magento/Paypal/Model/Hostedpro.php   |  3 --
 app/code/Magento/Paypal/Model/Ipn.php         |  6 ++--
 .../Magento/Paypal/Model/Method/Agreement.php |  6 ++--
 .../Magento/Paypal/Model/PayflowExpress.php   |  6 ++--
 app/code/Magento/Paypal/Model/Payflowlink.php |  3 --
 app/code/Magento/Paypal/Model/Payflowpro.php  |  3 --
 .../Method/Billing/AbstractAgreement.php      |  6 ++--
 app/code/Magento/Paypal/Model/Standard.php    |  6 ++--
 .../Magento/Paypal/Model/VoidTest.php         |  2 --
 .../Test/Legacy/_files/obsolete_classes.php   |  2 +-
 .../Model/BanktransferTest.php                |  8 -----
 .../Model/CashondeliveryTest.php              |  8 -----
 .../testsuite/Magento/Ogone/Model/ApiTest.php |  4 +--
 .../Block/Info/ContainerAbstractTest.php      | 12 +------
 .../Magento/Payment/Model/Method/FreeTest.php |  4 +--
 .../Magento/Paypal/Model/Api/NvpTest.php      |  5 ---
 .../Magento/Paypal/Model/IpnTest.php          |  4 +--
 34 files changed, 68 insertions(+), 205 deletions(-)

diff --git a/app/code/Magento/Authorizenet/Model/Authorizenet.php b/app/code/Magento/Authorizenet/Model/Authorizenet.php
index db9df42b623..adb6bd704f2 100644
--- a/app/code/Magento/Authorizenet/Model/Authorizenet.php
+++ b/app/code/Magento/Authorizenet/Model/Authorizenet.php
@@ -296,7 +296,6 @@ class Authorizenet extends \Magento\Payment\Model\Method\Cc
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Module\ModuleListInterface $moduleList
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
@@ -315,7 +314,6 @@ class Authorizenet extends \Magento\Payment\Model\Method\Cc
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Module\ModuleListInterface $moduleList,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
@@ -338,7 +336,6 @@ class Authorizenet extends \Magento\Payment\Model\Method\Cc
             $eventManager,
             $paymentData,
             $scopeConfig,
-            $logAdapterFactory,
             $logger,
             $moduleList,
             $localeDate,
diff --git a/app/code/Magento/Authorizenet/Model/Directpost.php b/app/code/Magento/Authorizenet/Model/Directpost.php
index 71b481ba5f1..ec9ef1711ce 100644
--- a/app/code/Magento/Authorizenet/Model/Directpost.php
+++ b/app/code/Magento/Authorizenet/Model/Directpost.php
@@ -82,7 +82,6 @@ class Directpost extends \Magento\Authorizenet\Model\Authorizenet
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Module\ModuleListInterface $moduleList
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
@@ -107,7 +106,6 @@ class Directpost extends \Magento\Authorizenet\Model\Authorizenet
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Module\ModuleListInterface $moduleList,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
@@ -130,7 +128,6 @@ class Directpost extends \Magento\Authorizenet\Model\Authorizenet
             $eventManager,
             $paymentData,
             $scopeConfig,
-            $logAdapterFactory,
             $logger,
             $moduleList,
             $localeDate,
@@ -727,7 +724,7 @@ class Directpost extends \Magento\Authorizenet\Model\Authorizenet
             $order->registerCancellation($message)->save();
         } catch (\Exception $e) {
             //quiet decline
-            $this->_logger->critical($e);
+            $this->logger->critical($e);
         }
     }
 
@@ -766,7 +763,7 @@ class Directpost extends \Magento\Authorizenet\Model\Authorizenet
                 $order->save();
             } catch (\Exception $e) {
                 //if we couldn't capture order, just leave it as NEW order.
-                $this->_logger->critical($e);
+                $this->logger->critical($e);
             }
         }
     }
diff --git a/app/code/Magento/Centinel/Model/Api.php b/app/code/Magento/Centinel/Model/Api.php
index 223b299e43d..ccfe486b544 100644
--- a/app/code/Magento/Centinel/Model/Api.php
+++ b/app/code/Magento/Centinel/Model/Api.php
@@ -213,19 +213,17 @@ class Api extends \Magento\Framework\Object
     protected $_clientInstance = null;
 
     /**
-     * Log adapter factory
-     *
-     * @var \Psr\Log\LoggerInterface\AdapterFactory
+     * @var \Psr\Log\LoggerInterface
      */
-    protected $_logFactory;
+    protected $logger;
 
     /**
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logFactory
+     * @param \Psr\Log\LoggerInterface $logger
      * @param array $data
      */
-    public function __construct(\Psr\Log\LoggerInterface\AdapterFactory $logFactory, array $data = [])
+    public function __construct(\Psr\Log\LoggerInterface $logger, array $data = [])
     {
-        $this->_logFactory = $logFactory;
+        $this->logger = $logger;
         parent::__construct($data);
     }
 
@@ -419,13 +417,7 @@ class Api extends \Magento\Framework\Object
     protected function _debug($debugData)
     {
         if ($this->getDebugFlag()) {
-            $this->_logFactory->create(
-                ['fileName' => 'card_validation_3d_secure.log']
-            )->setFilterDataKeys(
-                $this->_debugReplacePrivateDataKeys
-            )->log(
-                $debugData
-            );
+            $this->logger->debug($debugData);
         }
     }
 }
diff --git a/app/code/Magento/Fedex/Model/Carrier.php b/app/code/Magento/Fedex/Model/Carrier.php
index 7b94207a152..dbd542535c5 100644
--- a/app/code/Magento/Fedex/Model/Carrier.php
+++ b/app/code/Magento/Fedex/Model/Carrier.php
@@ -106,11 +106,6 @@ class Carrier extends AbstractCarrierOnline implements \Magento\Shipping\Model\C
      */
     protected $_storeManager;
 
-    /**
-     * @var \Psr\Log\LoggerInterface
-     */
-    protected $_logger;
-
     /**
      * @var \Magento\Catalog\Model\Resource\Product\CollectionFactory
      */
diff --git a/app/code/Magento/GoogleShopping/Model/Service.php b/app/code/Magento/GoogleShopping/Model/Service.php
index e421d731a06..f1a9814e9c2 100644
--- a/app/code/Magento/GoogleShopping/Model/Service.php
+++ b/app/code/Magento/GoogleShopping/Model/Service.php
@@ -32,13 +32,6 @@ class Service extends \Magento\Framework\Object
      */
     protected $_config;
 
-    /**
-     * Log adapter factory
-     *
-     * @var \Psr\Log\LoggerInterface\AdapterFactory
-     */
-    protected $_logAdapterFactory;
-
     /**
      * Service
      * @var \Magento\Framework\Gdata\Gshopping\Content
@@ -52,25 +45,25 @@ class Service extends \Magento\Framework\Object
     protected $_contentFactory;
 
     /**
-     * Constructor
-     *
-     * By default is looking for first argument as array and assigns it as object
-     * attributes This behavior may change in child classes
-     *
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
+     * @var \Psr\Log\LoggerInterface
+     */
+    protected $logger;
+
+    /**
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Registry $coreRegistry
-     * @param \Magento\GoogleShopping\Model\Config $config
+     * @param Config $config
      * @param \Magento\Framework\Gdata\Gshopping\ContentFactory $contentFactory
      * @param array $data
      */
     public function __construct(
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Registry $coreRegistry,
         \Magento\GoogleShopping\Model\Config $config,
         \Magento\Framework\Gdata\Gshopping\ContentFactory $contentFactory,
         array $data = []
     ) {
-        $this->_logAdapterFactory = $logAdapterFactory;
+        $this->logger = $logger;
         $this->_coreRegistry = $coreRegistry;
         $this->_config = $config;
         $this->_contentFactory = $contentFactory;
@@ -149,12 +142,7 @@ class Service extends \Magento\Framework\Object
             $this->_service = $this->_connect($storeId);
 
             if ($this->getConfig()->getIsDebug($storeId)) {
-                $this->_service->setLogAdapter(
-                    $this->_logAdapterFactory->create(['fileName' => 'googleshopping.log']),
-                    'log'
-                )->setDebug(
-                    true
-                );
+                $this->_service->setLogAdapter($this->logger, 'debug')->setDebug(true);
             }
         }
         return $this->_service;
diff --git a/app/code/Magento/GoogleShopping/Model/Service/Item.php b/app/code/Magento/GoogleShopping/Model/Service/Item.php
index 3ee511cb4f3..857945556fc 100644
--- a/app/code/Magento/GoogleShopping/Model/Service/Item.php
+++ b/app/code/Magento/GoogleShopping/Model/Service/Item.php
@@ -24,7 +24,7 @@ class Item extends \Magento\GoogleShopping\Model\Service
     protected $_date;
 
     /**
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Registry $coreRegistry
      * @param \Magento\GoogleShopping\Model\Config $config
      * @param \Magento\Framework\Gdata\Gshopping\ContentFactory $contentFactory
@@ -33,7 +33,7 @@ class Item extends \Magento\GoogleShopping\Model\Service
      * @param array $data
      */
     public function __construct(
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Registry $coreRegistry,
         \Magento\GoogleShopping\Model\Config $config,
         \Magento\Framework\Gdata\Gshopping\ContentFactory $contentFactory,
@@ -43,7 +43,7 @@ class Item extends \Magento\GoogleShopping\Model\Service
     ) {
         $this->_date = $date;
         $this->_googleShoppingHelper = $googleShoppingHelper;
-        parent::__construct($logAdapterFactory, $coreRegistry, $config, $contentFactory, $data);
+        parent::__construct($logger, $coreRegistry, $config, $contentFactory, $data);
     }
 
     /**
diff --git a/app/code/Magento/Ogone/Model/Api.php b/app/code/Magento/Ogone/Model/Api.php
index 4943812f894..801bdfd2504 100644
--- a/app/code/Magento/Ogone/Model/Api.php
+++ b/app/code/Magento/Ogone/Model/Api.php
@@ -456,7 +456,7 @@ class Api extends \Magento\Payment\Model\Method\AbstractMethod
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
      * @param \Magento\Framework\UrlInterface $urlBuilder
@@ -468,7 +468,7 @@ class Api extends \Magento\Payment\Model\Method\AbstractMethod
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\Locale\ResolverInterface $localeResolver,
         \Magento\Framework\UrlInterface $urlBuilder,
@@ -481,7 +481,7 @@ class Api extends \Magento\Payment\Model\Method\AbstractMethod
         $this->_urlBuilder = $urlBuilder;
         $this->string = $string;
         $this->_config = $config;
-        parent::__construct($eventManager, $paymentData, $scopeConfig, $logAdapterFactory, $data);
+        parent::__construct($eventManager, $paymentData, $scopeConfig, $logger, $data);
     }
 
     /**
diff --git a/app/code/Magento/Payment/Model/Method/AbstractMethod.php b/app/code/Magento/Payment/Model/Method/AbstractMethod.php
index c50920b5d3d..ba16262cbb2 100644
--- a/app/code/Magento/Payment/Model/Method/AbstractMethod.php
+++ b/app/code/Magento/Payment/Model/Method/AbstractMethod.php
@@ -196,34 +196,27 @@ abstract class AbstractMethod extends \Magento\Framework\Object implements Metho
      */
     protected $_eventManager;
 
-    /**
-     * Log adapter factory
-     *
-     * @var \Psr\Log\LoggerInterface\AdapterFactory
-     */
-    protected $_logAdapterFactory;
+    protected $logger;
 
     /**
-     * Construct
-     *
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface $logger
      * @param array $data
      */
     public function __construct(
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface $logger,
         array $data = []
     ) {
         parent::__construct($data);
+        $this->logger = $logger;
         $this->_eventManager = $eventManager;
         $this->_paymentData = $paymentData;
         $this->_scopeConfig = $scopeConfig;
-        $this->_logAdapterFactory = $logAdapterFactory;
     }
 
     /**
@@ -773,13 +766,7 @@ abstract class AbstractMethod extends \Magento\Framework\Object implements Metho
     protected function _debug($debugData)
     {
         if ($this->getDebugFlag()) {
-            $this->_logAdapterFactory->create(
-                ['fileName' => 'payment_' . $this->getCode() . '.log']
-            )->setFilterDataKeys(
-                $this->_debugReplacePrivateDataKeys
-            )->log(
-                $debugData
-            );
+            $this->logger->debug($debugData);
         }
     }
 
diff --git a/app/code/Magento/Payment/Model/Method/Cc.php b/app/code/Magento/Payment/Model/Method/Cc.php
index 8cb5cbc0089..d7383e31db1 100644
--- a/app/code/Magento/Payment/Model/Method/Cc.php
+++ b/app/code/Magento/Payment/Model/Method/Cc.php
@@ -38,18 +38,10 @@ class Cc extends \Magento\Payment\Model\Method\AbstractMethod
      */
     protected $_centinelService;
 
-    /**
-     * Construct
-     *
-     * @var \Psr\Log\LoggerInterface
-     */
-    protected $_logger;
-
     /**
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Module\ModuleListInterface $moduleList
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
@@ -60,16 +52,14 @@ class Cc extends \Magento\Payment\Model\Method\AbstractMethod
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Module\ModuleListInterface $moduleList,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Centinel\Model\Service $centinelService,
         array $data = []
     ) {
-        parent::__construct($eventManager, $paymentData, $scopeConfig, $logAdapterFactory, $data);
+        parent::__construct($eventManager, $paymentData, $scopeConfig, $logger, $data);
         $this->_moduleList = $moduleList;
-        $this->_logger = $logger;
         $this->_localeDate = $localeDate;
         $this->_centinelService = $centinelService;
     }
diff --git a/app/code/Magento/Payment/Model/Method/Free.php b/app/code/Magento/Payment/Model/Method/Free.php
index 3a3bde6cd32..7463a08bcd5 100644
--- a/app/code/Magento/Payment/Model/Method/Free.php
+++ b/app/code/Magento/Payment/Model/Method/Free.php
@@ -43,7 +43,7 @@ class Free extends \Magento\Payment\Model\Method\AbstractMethod
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface $logger
      * @param PriceCurrencyInterface $priceCurrency
      * @param array $data
      */
@@ -51,11 +51,11 @@ class Free extends \Magento\Payment\Model\Method\AbstractMethod
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface $logger,
         PriceCurrencyInterface $priceCurrency,
         array $data = []
     ) {
-        parent::__construct($eventManager, $paymentData, $scopeConfig, $logAdapterFactory, $data);
+        parent::__construct($eventManager, $paymentData, $scopeConfig, $logger, $data);
         $this->priceCurrency = $priceCurrency;
     }
 
diff --git a/app/code/Magento/Paypal/Model/AbstractIpn.php b/app/code/Magento/Paypal/Model/AbstractIpn.php
index 583227b62bc..d073f605ecf 100644
--- a/app/code/Magento/Paypal/Model/AbstractIpn.php
+++ b/app/code/Magento/Paypal/Model/AbstractIpn.php
@@ -9,11 +9,6 @@ use Magento\Paypal\UnavailableException;
 
 class AbstractIpn
 {
-    /**
-     * Default log filename
-     */
-    const DEFAULT_LOG_FILE = 'paypal_unknown_ipn.log';
-
     /**
      * @var Config
      */
@@ -45,18 +40,18 @@ class AbstractIpn
 
     /**
      * @param \Magento\Paypal\Model\ConfigFactory $configFactory
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\HTTP\Adapter\CurlFactory $curlFactory
      * @param array $data
      */
     public function __construct(
         \Magento\Paypal\Model\ConfigFactory $configFactory,
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\HTTP\Adapter\CurlFactory $curlFactory,
         array $data = []
     ) {
         $this->_configFactory = $configFactory;
-        $this->_logAdapterFactory = $logAdapterFactory;
+        $this->logger = $logger;
         $this->_curlFactory = $curlFactory;
         $this->_ipnRequest = $data;
     }
@@ -116,7 +111,7 @@ class AbstractIpn
         if ($response != 'VERIFIED') {
             $this->_addDebugData('postback', $postbackQuery);
             $this->_addDebugData('postback_result', $postbackResult);
-            throw new \Exception('PayPal IPN postback failure. See ' . self::DEFAULT_LOG_FILE . ' for details.');
+            throw new \Exception('PayPal IPN postback failure. See system.log for details.');
         }
     }
 
@@ -168,11 +163,7 @@ class AbstractIpn
     protected function _debug()
     {
         if ($this->_config && $this->_config->getConfigValue('debug')) {
-            $file = $this->_config
-                ->getMethodCode() ? "payment_{$this
-                ->_config
-                ->getMethodCode()}.log" : self::DEFAULT_LOG_FILE;
-            $this->_logAdapterFactory->create(['fileName' => $file])->log($this->_debugData);
+            $this->logger->debug($this->_debugData);
         }
     }
 
diff --git a/app/code/Magento/Paypal/Model/Api/AbstractApi.php b/app/code/Magento/Paypal/Model/Api/AbstractApi.php
index aa974746bb7..c312381e5ed 100644
--- a/app/code/Magento/Paypal/Model/Api/AbstractApi.php
+++ b/app/code/Magento/Paypal/Model/Api/AbstractApi.php
@@ -96,11 +96,6 @@ abstract class AbstractApi extends \Magento\Framework\Object
      */
     protected $_regionFactory;
 
-    /**
-     * @var \Psr\Log\LoggerInterface\AdapterFactory
-     */
-    protected $_logAdapterFactory;
-
     /**
      * Constructor
      *
@@ -111,7 +106,6 @@ abstract class AbstractApi extends \Magento\Framework\Object
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
      * @param \Magento\Directory\Model\RegionFactory $regionFactory
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param array $data
      */
     public function __construct(
@@ -119,14 +113,12 @@ abstract class AbstractApi extends \Magento\Framework\Object
         \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Locale\ResolverInterface $localeResolver,
         \Magento\Directory\Model\RegionFactory $regionFactory,
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         array $data = []
     ) {
         $this->_customerAddress = $customerAddress;
         $this->_logger = $logger;
         $this->_localeResolver = $localeResolver;
         $this->_regionFactory = $regionFactory;
-        $this->_logAdapterFactory = $logAdapterFactory;
         parent::__construct($data);
     }
 
@@ -603,13 +595,7 @@ abstract class AbstractApi extends \Magento\Framework\Object
     protected function _debug($debugData)
     {
         if ($this->getDebugFlag()) {
-            $this->_logAdapterFactory->create(
-                ['fileName' => 'payment_' . $this->_config->getMethodCode() . '.log']
-            )->setFilterDataKeys(
-                $this->_debugReplacePrivateDataKeys
-            )->log(
-                $debugData
-            );
+            $this->_logger->debug($debugData);
         }
     }
 
diff --git a/app/code/Magento/Paypal/Model/Api/Nvp.php b/app/code/Magento/Paypal/Model/Api/Nvp.php
index 82dd7ada7c2..6e1677fe98e 100644
--- a/app/code/Magento/Paypal/Model/Api/Nvp.php
+++ b/app/code/Magento/Paypal/Model/Api/Nvp.php
@@ -744,7 +744,6 @@ class Nvp extends \Magento\Paypal\Model\Api\AbstractApi
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
      * @param \Magento\Directory\Model\RegionFactory $regionFactory
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param \Magento\Directory\Model\CountryFactory $countryFactory
      * @param \Magento\Paypal\Model\Api\ProcessableExceptionFactory $processableExceptionFactory
      * @param \Magento\Framework\Model\ExceptionFactory $frameworkExceptionFactory
@@ -756,14 +755,13 @@ class Nvp extends \Magento\Paypal\Model\Api\AbstractApi
         \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Locale\ResolverInterface $localeResolver,
         \Magento\Directory\Model\RegionFactory $regionFactory,
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         \Magento\Directory\Model\CountryFactory $countryFactory,
         \Magento\Paypal\Model\Api\ProcessableExceptionFactory $processableExceptionFactory,
         \Magento\Framework\Model\ExceptionFactory $frameworkExceptionFactory,
         \Magento\Framework\HTTP\Adapter\CurlFactory $curlFactory,
         array $data = []
     ) {
-        parent::__construct($customerAddress, $logger, $localeResolver, $regionFactory, $logAdapterFactory, $data);
+        parent::__construct($customerAddress, $logger, $localeResolver, $regionFactory, $data);
         $this->_countryFactory = $countryFactory;
         $this->_processableExceptionFactory = $processableExceptionFactory;
         $this->_frameworkExceptionFactory = $frameworkExceptionFactory;
diff --git a/app/code/Magento/Paypal/Model/Api/PayflowNvp.php b/app/code/Magento/Paypal/Model/Api/PayflowNvp.php
index 483a3bb3980..7022af73abc 100644
--- a/app/code/Magento/Paypal/Model/Api/PayflowNvp.php
+++ b/app/code/Magento/Paypal/Model/Api/PayflowNvp.php
@@ -442,7 +442,6 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
      * @param \Magento\Directory\Model\RegionFactory $regionFactory
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param \Magento\Directory\Model\CountryFactory $countryFactory
      * @param \Magento\Paypal\Model\Api\ProcessableExceptionFactory $processableExceptionFactory
      * @param \Magento\Framework\Model\ExceptionFactory $frameworkExceptionFactory
@@ -456,7 +455,6 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp
         \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Locale\ResolverInterface $localeResolver,
         \Magento\Directory\Model\RegionFactory $regionFactory,
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         \Magento\Directory\Model\CountryFactory $countryFactory,
         \Magento\Paypal\Model\Api\ProcessableExceptionFactory $processableExceptionFactory,
         \Magento\Framework\Model\ExceptionFactory $frameworkExceptionFactory,
@@ -470,7 +468,6 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp
             $logger,
             $localeResolver,
             $regionFactory,
-            $logAdapterFactory,
             $countryFactory,
             $processableExceptionFactory,
             $frameworkExceptionFactory,
diff --git a/app/code/Magento/Paypal/Model/Direct.php b/app/code/Magento/Paypal/Model/Direct.php
index e9945594532..aa6583b8087 100644
--- a/app/code/Magento/Paypal/Model/Direct.php
+++ b/app/code/Magento/Paypal/Model/Direct.php
@@ -134,7 +134,6 @@ class Direct extends \Magento\Payment\Model\Method\Cc
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Module\ModuleListInterface $moduleList
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
@@ -152,7 +151,6 @@ class Direct extends \Magento\Payment\Model\Method\Cc
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Module\ModuleListInterface $moduleList,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
@@ -168,7 +166,6 @@ class Direct extends \Magento\Payment\Model\Method\Cc
             $eventManager,
             $paymentData,
             $scopeConfig,
-            $logAdapterFactory,
             $logger,
             $moduleList,
             $localeDate,
diff --git a/app/code/Magento/Paypal/Model/Express.php b/app/code/Magento/Paypal/Model/Express.php
index 17c0e989059..126f85aaef7 100644
--- a/app/code/Magento/Paypal/Model/Express.php
+++ b/app/code/Magento/Paypal/Model/Express.php
@@ -165,7 +165,7 @@ class Express extends \Magento\Payment\Model\Method\AbstractMethod
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface $logger
      * @param ProFactory $proFactory
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\UrlInterface $urlBuilder
@@ -178,7 +178,7 @@ class Express extends \Magento\Payment\Model\Method\AbstractMethod
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface $logger,
         ProFactory $proFactory,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\UrlInterface $urlBuilder,
@@ -187,7 +187,7 @@ class Express extends \Magento\Payment\Model\Method\AbstractMethod
         \Magento\Framework\Model\ExceptionFactory $exception,
         array $data = []
     ) {
-        parent::__construct($eventManager, $paymentData, $scopeConfig, $logAdapterFactory, $data);
+        parent::__construct($eventManager, $paymentData, $scopeConfig, $logger, $data);
         $this->_storeManager = $storeManager;
         $this->_urlBuilder = $urlBuilder;
         $this->_cartFactory = $cartFactory;
diff --git a/app/code/Magento/Paypal/Model/Express/Checkout.php b/app/code/Magento/Paypal/Model/Express/Checkout.php
index 3e149d8b1e4..6f0cc27445b 100644
--- a/app/code/Magento/Paypal/Model/Express/Checkout.php
+++ b/app/code/Magento/Paypal/Model/Express/Checkout.php
@@ -198,11 +198,6 @@ class Checkout
      */
     protected $_cartFactory;
 
-    /**
-     * @var \Psr\Log\LoggerInterface\AdapterFactory
-     */
-    protected $_logFactory;
-
     /**
      * @var \Magento\Checkout\Model\Type\OnepageFactory
      */
@@ -282,7 +277,6 @@ class Checkout
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\UrlInterface $coreUrl
      * @param \Magento\Paypal\Model\CartFactory $cartFactory
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logFactory
      * @param \Magento\Checkout\Model\Type\OnepageFactory $onepageFactory
      * @param \Magento\Sales\Model\Service\QuoteFactory $serviceQuoteFactory
      * @param \Magento\Paypal\Model\Billing\AgreementFactory $agreementFactory
@@ -311,7 +305,6 @@ class Checkout
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\UrlInterface $coreUrl,
         \Magento\Paypal\Model\CartFactory $cartFactory,
-        \Psr\Log\LoggerInterface\AdapterFactory $logFactory,
         \Magento\Checkout\Model\Type\OnepageFactory $onepageFactory,
         \Magento\Sales\Model\Service\QuoteFactory $serviceQuoteFactory,
         \Magento\Paypal\Model\Billing\AgreementFactory $agreementFactory,
@@ -337,7 +330,6 @@ class Checkout
         $this->_storeManager = $storeManager;
         $this->_coreUrl = $coreUrl;
         $this->_cartFactory = $cartFactory;
-        $this->_logFactory = $logFactory;
         $this->_checkoutOnepageFactory = $onepageFactory;
         $this->_serviceQuoteFactory = $serviceQuoteFactory;
         $this->_agreementFactory = $agreementFactory;
@@ -727,8 +719,6 @@ class Checkout
      */
     public function getShippingOptionsCallbackResponse(array $request)
     {
-        // prepare debug data
-        $logger = $this->_logFactory->create(['fileName' => 'payment_' . $this->_methodType . '.log']);
         $debugData = ['request' => $request, 'response' => []];
 
         try {
@@ -750,10 +740,10 @@ class Checkout
 
             // log request and response
             $debugData['response'] = $response;
-            $logger->log($debugData);
+            $this->_logger->debug($debugData);
             return $response;
         } catch (\Exception $e) {
-            $logger->log($debugData);
+            $this->_logger->critical($debugData);
             throw $e;
         }
     }
diff --git a/app/code/Magento/Paypal/Model/Hostedpro.php b/app/code/Magento/Paypal/Model/Hostedpro.php
index 1817268f562..b3b741bffba 100644
--- a/app/code/Magento/Paypal/Model/Hostedpro.php
+++ b/app/code/Magento/Paypal/Model/Hostedpro.php
@@ -71,7 +71,6 @@ class Hostedpro extends \Magento\Paypal\Model\Direct
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Module\ModuleListInterface $moduleList
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
@@ -90,7 +89,6 @@ class Hostedpro extends \Magento\Paypal\Model\Direct
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Module\ModuleListInterface $moduleList,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
@@ -108,7 +106,6 @@ class Hostedpro extends \Magento\Paypal\Model\Direct
             $eventManager,
             $paymentData,
             $scopeConfig,
-            $logAdapterFactory,
             $logger,
             $moduleList,
             $localeDate,
diff --git a/app/code/Magento/Paypal/Model/Ipn.php b/app/code/Magento/Paypal/Model/Ipn.php
index 177a575d0fd..14329722805 100644
--- a/app/code/Magento/Paypal/Model/Ipn.php
+++ b/app/code/Magento/Paypal/Model/Ipn.php
@@ -42,7 +42,7 @@ class Ipn extends \Magento\Paypal\Model\AbstractIpn implements IpnInterface
 
     /**
      * @param \Magento\Paypal\Model\ConfigFactory $configFactory
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\HTTP\Adapter\CurlFactory $curlFactory
      * @param \Magento\Sales\Model\OrderFactory $orderFactory
      * @param Info $paypalInfo
@@ -52,7 +52,7 @@ class Ipn extends \Magento\Paypal\Model\AbstractIpn implements IpnInterface
      */
     public function __construct(
         \Magento\Paypal\Model\ConfigFactory $configFactory,
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\HTTP\Adapter\CurlFactory $curlFactory,
         \Magento\Sales\Model\OrderFactory $orderFactory,
         Info $paypalInfo,
@@ -60,7 +60,7 @@ class Ipn extends \Magento\Paypal\Model\AbstractIpn implements IpnInterface
         CreditmemoSender $creditmemoSender,
         array $data = []
     ) {
-        parent::__construct($configFactory, $logAdapterFactory, $curlFactory, $data);
+        parent::__construct($configFactory, $logger, $curlFactory, $data);
         $this->_orderFactory = $orderFactory;
         $this->_paypalInfo = $paypalInfo;
         $this->orderSender = $orderSender;
diff --git a/app/code/Magento/Paypal/Model/Method/Agreement.php b/app/code/Magento/Paypal/Model/Method/Agreement.php
index 936b2604146..e7aa4f053d3 100644
--- a/app/code/Magento/Paypal/Model/Method/Agreement.php
+++ b/app/code/Magento/Paypal/Model/Method/Agreement.php
@@ -117,7 +117,7 @@ class Agreement extends \Magento\Paypal\Model\Payment\Method\Billing\AbstractAgr
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Paypal\Model\Billing\AgreementFactory $agreementFactory
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Paypal\Model\ProFactory $proFactory
@@ -131,7 +131,7 @@ class Agreement extends \Magento\Paypal\Model\Payment\Method\Billing\AbstractAgr
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Paypal\Model\Billing\AgreementFactory $agreementFactory,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Paypal\Model\ProFactory $proFactory,
@@ -146,7 +146,7 @@ class Agreement extends \Magento\Paypal\Model\Payment\Method\Billing\AbstractAgr
             $eventManager,
             $paymentData,
             $scopeConfig,
-            $logAdapterFactory,
+            $logger,
             $agreementFactory,
             $data
         );
diff --git a/app/code/Magento/Paypal/Model/PayflowExpress.php b/app/code/Magento/Paypal/Model/PayflowExpress.php
index f454a30afc8..9091042b93c 100644
--- a/app/code/Magento/Paypal/Model/PayflowExpress.php
+++ b/app/code/Magento/Paypal/Model/PayflowExpress.php
@@ -35,7 +35,7 @@ class PayflowExpress extends \Magento\Paypal\Model\Express
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface $logger
      * @param ProFactory $proFactory
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\UrlInterface $urlBuilder
@@ -49,7 +49,7 @@ class PayflowExpress extends \Magento\Paypal\Model\Express
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface $logger,
         ProFactory $proFactory,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\UrlInterface $urlBuilder,
@@ -63,7 +63,7 @@ class PayflowExpress extends \Magento\Paypal\Model\Express
             $eventManager,
             $paymentData,
             $scopeConfig,
-            $logAdapterFactory,
+            $logger,
             $proFactory,
             $storeManager,
             $urlBuilder,
diff --git a/app/code/Magento/Paypal/Model/Payflowlink.php b/app/code/Magento/Paypal/Model/Payflowlink.php
index 6be0ac49795..1b0c7858402 100644
--- a/app/code/Magento/Paypal/Model/Payflowlink.php
+++ b/app/code/Magento/Paypal/Model/Payflowlink.php
@@ -136,7 +136,6 @@ class Payflowlink extends \Magento\Paypal\Model\Payflowpro
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Module\ModuleListInterface $moduleList
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
@@ -159,7 +158,6 @@ class Payflowlink extends \Magento\Paypal\Model\Payflowpro
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Module\ModuleListInterface $moduleList,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
@@ -186,7 +184,6 @@ class Payflowlink extends \Magento\Paypal\Model\Payflowpro
             $eventManager,
             $paymentData,
             $scopeConfig,
-            $logAdapterFactory,
             $logger,
             $moduleList,
             $localeDate,
diff --git a/app/code/Magento/Paypal/Model/Payflowpro.php b/app/code/Magento/Paypal/Model/Payflowpro.php
index 0d3afe955d1..79b10e9805f 100644
--- a/app/code/Magento/Paypal/Model/Payflowpro.php
+++ b/app/code/Magento/Paypal/Model/Payflowpro.php
@@ -216,7 +216,6 @@ class Payflowpro extends \Magento\Payment\Model\Method\Cc
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
      * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Module\ModuleListInterface $moduleList
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
@@ -233,7 +232,6 @@ class Payflowpro extends \Magento\Payment\Model\Method\Cc
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
         \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Module\ModuleListInterface $moduleList,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
@@ -252,7 +250,6 @@ class Payflowpro extends \Magento\Payment\Model\Method\Cc
             $eventManager,
             $paymentData,
             $scopeConfig,
-            $logAdapterFactory,
             $logger,
             $moduleList,
             $localeDate,
diff --git a/app/code/Magento/Paypal/Model/Payment/Method/Billing/AbstractAgreement.php b/app/code/Magento/Paypal/Model/Payment/Method/Billing/AbstractAgreement.php
index 008234ace93..24f59cf4826 100644
--- a/app/code/Magento/Paypal/Model/Payment/Method/Billing/AbstractAgreement.php
+++ b/app/code/Magento/Paypal/Model/Payment/Method/Billing/AbstractAgreement.php
@@ -42,7 +42,7 @@ abstract class AbstractAgreement extends \Magento\Payment\Model\Method\AbstractM
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Paypal\Model\Billing\AgreementFactory $agreementFactory
      * @param array $data
      */
@@ -50,12 +50,12 @@ abstract class AbstractAgreement extends \Magento\Payment\Model\Method\AbstractM
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Paypal\Model\Billing\AgreementFactory $agreementFactory,
         array $data = []
     ) {
         $this->_agreementFactory = $agreementFactory;
-        parent::__construct($eventManager, $paymentData, $scopeConfig, $logAdapterFactory, $data);
+        parent::__construct($eventManager, $paymentData, $scopeConfig, $logger, $data);
     }
 
     /**
diff --git a/app/code/Magento/Paypal/Model/Standard.php b/app/code/Magento/Paypal/Model/Standard.php
index 933fa6cd35b..8728dcb0ee7 100644
--- a/app/code/Magento/Paypal/Model/Standard.php
+++ b/app/code/Magento/Paypal/Model/Standard.php
@@ -85,7 +85,7 @@ class Standard extends \Magento\Payment\Model\Method\AbstractMethod
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory
+     * @param \Psr\Log\LoggerInterface $logger
      * @param \Magento\Framework\Session\Generic $paypalSession
      * @param \Magento\Checkout\Model\Session $checkoutSession
      * @param \Magento\Framework\UrlInterface $urlBuilder
@@ -102,7 +102,7 @@ class Standard extends \Magento\Payment\Model\Method\AbstractMethod
         \Magento\Framework\Event\ManagerInterface $eventManager,
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Psr\Log\LoggerInterface\AdapterFactory $logAdapterFactory,
+        \Psr\Log\LoggerInterface $logger,
         \Magento\Framework\Session\Generic $paypalSession,
         \Magento\Checkout\Model\Session $checkoutSession,
         \Magento\Framework\UrlInterface $urlBuilder,
@@ -121,7 +121,7 @@ class Standard extends \Magento\Payment\Model\Method\AbstractMethod
         $this->_apiStandardFactory = $apiStandardFactory;
         $this->_cartFactory = $cartFactory;
         $this->_configFactory = $configFactory;
-        parent::__construct($eventManager, $paymentData, $scopeConfig, $logAdapterFactory, $data);
+        parent::__construct($eventManager, $paymentData, $scopeConfig, $logger, $data);
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Model/VoidTest.php b/dev/tests/integration/testsuite/Magento/Paypal/Model/VoidTest.php
index cb860a2a8f2..4d7cc4a155a 100644
--- a/dev/tests/integration/testsuite/Magento/Paypal/Model/VoidTest.php
+++ b/dev/tests/integration/testsuite/Magento/Paypal/Model/VoidTest.php
@@ -18,7 +18,6 @@ class VoidTest extends \PHPUnit_Framework_TestCase
         $paymentData = $objectManager->get('Magento\Payment\Helper\Data');
         $scopeConfig = $objectManager->get('Magento\Framework\App\Config\ScopeConfigInterface');
         $logger = $objectManager->get('Psr\Log\LoggerInterface');
-        $logAdapterFactory = $objectManager->get('Psr\Log\LoggerInterface\AdapterFactory');
         $localeDate = $objectManager->get('Magento\Framework\Stdlib\DateTime\TimezoneInterface');
         $centinelService = $objectManager->get('Magento\Centinel\Model\Service');
         $storeManager = $objectManager->get('Magento\Store\Model\StoreManagerInterface');
@@ -42,7 +41,6 @@ class VoidTest extends \PHPUnit_Framework_TestCase
                 $eventManager,
                 $paymentData,
                 $scopeConfig,
-                $logAdapterFactory,
                 $logger,
                 $moduleList,
                 $localeDate,
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
index 764fc631b79..40e446b4654 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
@@ -1980,7 +1980,7 @@ return [
     ['Magento\Core\Model\Image\Adapter\Config', 'Magento\Framework\Image\Adapter\Config'],
     ['Magento\Core\Model\AbstractShell', 'Magento\Framework\App\AbstractShell'],
     ['Magento\Core\Model\Calculator', 'Magento\Framework\Math\Calculator'],
-    ['Magento\Core\Model\Log\Adapter', 'Psr\Log\LoggerInterface\Adapter'],
+    ['Magento\Core\Model\Log\Adapter', 'Magento\Framework\Logger\Adapter'],
     ['Magento\Core\Model\Input\Filter', 'Magento\Framework\Filter\Input'],
     ['Magento\Core\Model\Input\Filter\MaliciousCode', 'Magento\Framework\Filter\Input\MaliciousCode'],
     ['Magento\Core\Model\Option\ArrayInterface', 'Magento\Framework\Option\ArrayInterface'],
diff --git a/dev/tests/unit/testsuite/Magento/OfflinePayments/Model/BanktransferTest.php b/dev/tests/unit/testsuite/Magento/OfflinePayments/Model/BanktransferTest.php
index 16d951af2fc..03f21339f63 100644
--- a/dev/tests/unit/testsuite/Magento/OfflinePayments/Model/BanktransferTest.php
+++ b/dev/tests/unit/testsuite/Magento/OfflinePayments/Model/BanktransferTest.php
@@ -17,20 +17,12 @@ class BanktransferTest extends \PHPUnit_Framework_TestCase
         $eventManager = $this->getMock('Magento\Framework\Event\ManagerInterface', [], [], '', false);
         $paymentDataMock = $this->getMock('Magento\Payment\Helper\Data', [], [], '', false);
         $scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
-        $adapterFactoryMock = $this->getMock(
-            'Psr\Log\LoggerInterface\AdapterFactory',
-            ['create'],
-            [],
-            '',
-            false
-        );
         $this->_object = $objectManagerHelper->getObject(
             'Magento\OfflinePayments\Model\Banktransfer',
             [
                 'eventManager' => $eventManager,
                 'paymentData' => $paymentDataMock,
                 'scopeConfig' => $scopeConfig,
-                'logAdapterFactory' => $adapterFactoryMock
             ]
         );
     }
diff --git a/dev/tests/unit/testsuite/Magento/OfflinePayments/Model/CashondeliveryTest.php b/dev/tests/unit/testsuite/Magento/OfflinePayments/Model/CashondeliveryTest.php
index 7cac02dbe88..2f3cb65cfc3 100644
--- a/dev/tests/unit/testsuite/Magento/OfflinePayments/Model/CashondeliveryTest.php
+++ b/dev/tests/unit/testsuite/Magento/OfflinePayments/Model/CashondeliveryTest.php
@@ -17,13 +17,6 @@ class CashondeliveryTest extends \PHPUnit_Framework_TestCase
 
         $eventManager = $this->getMock('Magento\Framework\Event\ManagerInterface', [], [], '', false);
         $paymentDataMock = $this->getMock('Magento\Payment\Helper\Data', [], [], '', false);
-        $adapterFactoryMock = $this->getMock(
-            'Psr\Log\LoggerInterface\AdapterFactory',
-            ['create'],
-            [],
-            '',
-            false
-        );
 
         $scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
         $this->_object = $helper->getObject(
@@ -32,7 +25,6 @@ class CashondeliveryTest extends \PHPUnit_Framework_TestCase
                 'eventManager' => $eventManager,
                 'paymentData' => $paymentDataMock,
                 'scopeConfig' => $scopeConfig,
-                'logAdapterFactory' => $adapterFactoryMock
             ]
         );
     }
diff --git a/dev/tests/unit/testsuite/Magento/Ogone/Model/ApiTest.php b/dev/tests/unit/testsuite/Magento/Ogone/Model/ApiTest.php
index 535adca0f1b..ba85434f7d1 100644
--- a/dev/tests/unit/testsuite/Magento/Ogone/Model/ApiTest.php
+++ b/dev/tests/unit/testsuite/Magento/Ogone/Model/ApiTest.php
@@ -25,12 +25,12 @@ class ApiTest extends \PHPUnit_Framework_TestCase
         $config = $this->getMock('Magento\Ogone\Model\Config', [], [], '', false);
         $paymentDataMock = $this->getMock('Magento\Payment\Helper\Data', [], [], '', false);
         $scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
-        $loggerFactory = $this->getMock('\Psr\Log\LoggerInterface\AdapterFactory', [], [], '', false);
+        $logger = $this->getMock('\Psr\Log\LoggerInterface');
         $object = new \Magento\Ogone\Model\Api(
             $eventManager,
             $paymentDataMock,
             $scopeConfig,
-            $loggerFactory,
+            $logger,
             $storeManager,
             $localeResolver,
             $urlBuilder,
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Block/Info/ContainerAbstractTest.php b/dev/tests/unit/testsuite/Magento/Payment/Block/Info/ContainerAbstractTest.php
index 22fca248a05..a2974944cb1 100644
--- a/dev/tests/unit/testsuite/Magento/Payment/Block/Info/ContainerAbstractTest.php
+++ b/dev/tests/unit/testsuite/Magento/Payment/Block/Info/ContainerAbstractTest.php
@@ -21,17 +21,7 @@ class ContainerAbstractTest extends \PHPUnit_Framework_TestCase
         );
         $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
         $paymentInfo = $objectManagerHelper->getObject('Magento\Payment\Model\Info');
-        $adapterFactoryMock = $this->getMock(
-            'Psr\Log\LoggerInterface\AdapterFactory',
-            ['create'],
-            [],
-            '',
-            false
-        );
-        $methodInstance = $objectManagerHelper->getObject(
-            'Magento\OfflinePayments\Model\Checkmo',
-            ['logAdapterFactory' => $adapterFactoryMock]
-        );
+        $methodInstance = $objectManagerHelper->getObject('Magento\OfflinePayments\Model\Checkmo');
         $paymentInfo->setMethodInstance($methodInstance);
         $block->expects($this->atLeastOnce())->method('getPaymentInfo')->will($this->returnValue($paymentInfo));
 
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/Method/FreeTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/Method/FreeTest.php
index dd3d95bf9d5..11571cbb2f9 100644
--- a/dev/tests/unit/testsuite/Magento/Payment/Model/Method/FreeTest.php
+++ b/dev/tests/unit/testsuite/Magento/Payment/Model/Method/FreeTest.php
@@ -20,14 +20,14 @@ class FreeTest extends \PHPUnit_Framework_TestCase
         $eventManager = $this->getMock('Magento\Framework\Event\ManagerInterface', [], [], '', false);
         $paymentData  = $this->getMock('Magento\Payment\Helper\Data', [], [], '', false);
         $this->scopeConfig = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface', [], [], '', false);
-        $logAdapterFactory = $this->getMock('Psr\Log\LoggerInterface\AdapterFactory', [], [], '', false);
+        $logger = $this->getMock('Psr\Log\LoggerInterface');
         $this->currencyPrice = $this->getMockBuilder('Magento\Framework\Pricing\PriceCurrencyInterface')->getMock();
 
         $this->methodFree = new \Magento\Payment\Model\Method\Free(
             $eventManager,
             $paymentData,
             $this->scopeConfig,
-            $logAdapterFactory,
+            $logger,
             $this->currencyPrice
         );
     }
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Model/Api/NvpTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Model/Api/NvpTest.php
index 2c18495c669..1c9c5f7f644 100644
--- a/dev/tests/unit/testsuite/Magento/Paypal/Model/Api/NvpTest.php
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Model/Api/NvpTest.php
@@ -24,9 +24,6 @@ class NvpTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Directory\Model\RegionFactory|\PHPUnit_Framework_MockObject_MockObject */
     protected $regionFactory;
 
-    /** @var \PHPUnit_Framework_MockObject_MockObject */
-    protected $adapterFactory;
-
     /** @var \Magento\Directory\Model\CountryFactory|\PHPUnit_Framework_MockObject_MockObject */
     protected $countryFactory;
 
@@ -48,7 +45,6 @@ class NvpTest extends \PHPUnit_Framework_TestCase
         $this->logger = $this->getMock('Psr\Log\LoggerInterface');
         $this->resolver = $this->getMock('Magento\Framework\Locale\ResolverInterface');
         $this->regionFactory = $this->getMock('Magento\Directory\Model\RegionFactory', [], [], '', false);
-        $this->adapterFactory = $this->getMock('Psr\Log\LoggerInterface\AdapterFactory', [], [], '', false);
         $this->countryFactory = $this->getMock('Magento\Directory\Model\CountryFactory', [], [], '', false);
         $processableExceptionFactory = $this->getMock(
             'Magento\Paypal\Model\Api\ProcessableExceptionFactory',
@@ -88,7 +84,6 @@ class NvpTest extends \PHPUnit_Framework_TestCase
                 'logger' => $this->logger,
                 'localeResolver' => $this->resolver,
                 'regionFactory' => $this->regionFactory,
-                'logAdapterFactory' => $this->adapterFactory,
                 'countryFactory' => $this->countryFactory,
                 'processableExceptionFactory' => $processableExceptionFactory,
                 'frameworkExceptionFactory' => $exceptionFactory,
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Model/IpnTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Model/IpnTest.php
index 6a8c89d3997..4eb7539b36b 100644
--- a/dev/tests/unit/testsuite/Magento/Paypal/Model/IpnTest.php
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Model/IpnTest.php
@@ -101,7 +101,7 @@ class IpnTest extends \PHPUnit_Framework_TestCase
         $this->_ipn = $objectHelper->getObject('Magento\Paypal\Model\Ipn',
             [
                 'configFactory' => $this->configFactory,
-                'logAdapterFactory' => $this->getMock('Psr\Log\LoggerInterface\AdapterFactory', [], [], '', false),
+                'logger' => $this->getMock('Psr\Log\LoggerInterface'),
                 'curlFactory' => $this->curlFactory,
                 'orderFactory' => $this->_orderMock,
                 'paypalInfo' => $this->_paypalInfo,
@@ -180,7 +180,7 @@ class IpnTest extends \PHPUnit_Framework_TestCase
         $this->_ipn = $objectHelper->getObject('Magento\Paypal\Model\Ipn',
             [
                 'configFactory' => $this->configFactory,
-                'logAdapterFactory' => $this->getMock('Psr\Log\LoggerInterface\AdapterFactory', [], [], '', false),
+                'logger' => $this->getMock('Psr\Log\LoggerInterface'),
                 'curlFactory' => $this->curlFactory,
                 'orderFactory' => $this->_orderMock,
                 'paypalInfo' => $this->_paypalInfo,
-- 
GitLab


From 887e6bc9e79ed0d98eaa49c943912eb8d54963e8 Mon Sep 17 00:00:00 2001
From: Andriy Nasinnyk <anasinnyk@ebay.com>
Date: Fri, 19 Dec 2014 16:51:52 +0200
Subject: [PATCH 24/71] MAGETWO-13915: PSR-3: common interface for logging
 libraries.

 - eliminate Magento\Framework\Logger\Adapter
---
 app/code/Magento/Store/Model/StorageFactory.php | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/app/code/Magento/Store/Model/StorageFactory.php b/app/code/Magento/Store/Model/StorageFactory.php
index 0ec394d4770..edcf2110824 100644
--- a/app/code/Magento/Store/Model/StorageFactory.php
+++ b/app/code/Magento/Store/Model/StorageFactory.php
@@ -30,11 +30,6 @@ class StorageFactory
      */
     protected $_eventManager;
 
-    /**
-     * @var \Psr\Log\LoggerInterface
-     */
-    protected $_log;
-
     /**
      * @var \Magento\Framework\Session\SidResolverInterface
      */
-- 
GitLab


From d4d6361c2e0974a7fe7355c564c7585cec495fc6 Mon Sep 17 00:00:00 2001
From: Andriy Nasinnyk <anasinnyk@ebay.com>
Date: Fri, 19 Dec 2014 16:57:21 +0200
Subject: [PATCH 25/71] MAGETWO-13915: PSR-3: common interface for logging
 libraries.

 - fixed grammatical error
---
 app/etc/di.xml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/app/etc/di.xml b/app/etc/di.xml
index 09307c527d5..60364ef243e 100644
--- a/app/etc/di.xml
+++ b/app/etc/di.xml
@@ -85,13 +85,13 @@
     <preference for="Magento\Framework\DB\LoggerInterface" type="Magento\Framework\DB\Logger\Null"/>
     <preference for="Magento\Framework\App\Resource\ConnectionAdapterInterface" type="Magento\Framework\Model\Resource\Type\Db\Pdo\Mysql"/>
     <preference for="Magento\Framework\DB\QueryInterface" type="Magento\Framework\DB\Query"/>
-    <virtualType name="Monolog\Heandler\Stream\System" type="Monolog\Handler\StreamHandler">
+    <virtualType name="Monolog\Handler\Stream\System" type="Monolog\Handler\StreamHandler">
         <arguments>
             <argument name="stream" xsi:type="string">var/log/system.log</argument>
             <argument name="level" xsi:type="const">Monolog\Logger::DEBUG</argument>
         </arguments>
     </virtualType>
-    <virtualType name="Monolog\Heandler\Stream\Exception" type="Monolog\Handler\StreamHandler">
+    <virtualType name="Monolog\Handler\Stream\Exception" type="Monolog\Handler\StreamHandler">
         <arguments>
             <argument name="stream" xsi:type="string">var/log/exception.log</argument>
             <argument name="level" xsi:type="const">Monolog\Logger::CRITICAL</argument>
@@ -101,8 +101,8 @@
         <arguments>
             <argument name="name" xsi:type="string">main</argument>
             <argument name="handlers"  xsi:type="array">
-                <item name="exception" xsi:type="object">Monolog\Heandler\Stream\Exception</item>
-                <item name="system" xsi:type="object">Monolog\Heandler\Stream\System</item>
+                <item name="exception" xsi:type="object">Monolog\Handler\Stream\Exception</item>
+                <item name="system" xsi:type="object">Monolog\Handler\Stream\System</item>
             </argument>
         </arguments>
     </type>
-- 
GitLab


From f0b25b7a526269bdf772b3a2d2c10ec55bad6976 Mon Sep 17 00:00:00 2001
From: Cari Spruiell <cspruiell@ebay.com>
Date: Fri, 19 Dec 2014 11:37:42 -0600
Subject: [PATCH 26/71] MAGETWO-9680: [Security] XSS in Admin Save Role

 - injected FilterManager to strip any tags from the submitted role name
---
 .../Magento/User/Controller/Adminhtml/User/Role.php    | 10 +++++++++-
 .../User/Controller/Adminhtml/User/Role/SaveRole.php   |  2 +-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Role.php b/app/code/Magento/User/Controller/Adminhtml/User/Role.php
index dcd17cc7111..0cf36ec618e 100644
--- a/app/code/Magento/User/Controller/Adminhtml/User/Role.php
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Role.php
@@ -43,6 +43,11 @@ class Role extends \Magento\Backend\App\AbstractAction
      */
     protected $_authSession;
 
+    /**
+     * @var \Magento\Framework\Filter\FilterManager
+     */
+    protected $_filterManager;
+
     /**
      * @param \Magento\Backend\App\Action\Context $context
      * @param \Magento\Framework\Registry $coreRegistry
@@ -50,6 +55,7 @@ class Role extends \Magento\Backend\App\AbstractAction
      * @param \Magento\User\Model\UserFactory $userFactory
      * @param \Magento\Authorization\Model\RulesFactory $rulesFactory
      * @param \Magento\Backend\Model\Auth\Session $authSession
+     * @param \Magento\Framework\Filter\FilterManager $filterManager
      */
     public function __construct(
         \Magento\Backend\App\Action\Context $context,
@@ -57,7 +63,8 @@ class Role extends \Magento\Backend\App\AbstractAction
         \Magento\Authorization\Model\RoleFactory $roleFactory,
         \Magento\User\Model\UserFactory $userFactory,
         \Magento\Authorization\Model\RulesFactory $rulesFactory,
-        \Magento\Backend\Model\Auth\Session $authSession
+        \Magento\Backend\Model\Auth\Session $authSession,
+        \Magento\Framework\Filter\FilterManager $filterManager
     ) {
         parent::__construct($context);
         $this->_coreRegistry = $coreRegistry;
@@ -65,6 +72,7 @@ class Role extends \Magento\Backend\App\AbstractAction
         $this->_userFactory = $userFactory;
         $this->_rulesFactory = $rulesFactory;
         $this->_authSession = $authSession;
+        $this->_filterManager = $filterManager;
     }
 
     /**
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php b/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php
index 773e39cebef..7041aab2fa6 100644
--- a/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php
@@ -78,7 +78,7 @@ class SaveRole extends \Magento\User\Controller\Adminhtml\User\Role
         }
 
         try {
-            $roleName = $this->getRequest()->getParam('rolename', false);
+            $roleName = $this->_filterManager->removeTags($this->getRequest()->getParam('rolename', false));
 
             $role->setName($roleName)
                 ->setPid($this->getRequest()->getParam('parent_id', false))
-- 
GitLab


From 2892b221de0d5aebd0872498b96123e3a2a86806 Mon Sep 17 00:00:00 2001
From: Arkadii Chyzhov <achyzhov@ebay.com>
Date: Mon, 22 Dec 2014 10:53:47 +0200
Subject: [PATCH 27/71] MAGETWO-31388: WebAPI Application Uses Reflection
 Inconsistently

- Migrate from old branch to magento2ce
---
 .../Webapi/Model/Config/ClassReflector.php    | 21 ++++++++++++++++++-
 .../Model/Config/ClassReflectorTest.php       |  4 +++-
 .../Config/TestServiceForClassReflector.php   |  5 ++++-
 .../Framework/Reflection/TypeProcessor.php    |  4 ++--
 4 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/app/code/Magento/Webapi/Model/Config/ClassReflector.php b/app/code/Magento/Webapi/Model/Config/ClassReflector.php
index 51878ad2d09..e734ff1ef40 100644
--- a/app/code/Magento/Webapi/Model/Config/ClassReflector.php
+++ b/app/code/Magento/Webapi/Model/Config/ClassReflector.php
@@ -6,6 +6,7 @@ namespace Magento\Webapi\Model\Config;
 
 use Zend\Server\Reflection;
 use Zend\Server\Reflection\ReflectionMethod;
+use Zend\Code\Reflection\MethodReflection;
 
 /**
  * Class reflector.
@@ -84,7 +85,7 @@ class ClassReflector
      */
     public function extractMethodData(ReflectionMethod $method)
     {
-        $methodData = ['documentation' => $method->getDescription(), 'interface' => []];
+        $methodData = ['documentation' => $this->extractMethodDescription($method), 'interface' => []];
         $prototypes = $method->getPrototypes();
         /** Take the fullest interface that also includes optional parameters. */
         /** @var \Zend\Server\Reflection\Prototype $prototype */
@@ -111,4 +112,22 @@ class ClassReflector
 
         return $methodData;
     }
+
+    /**
+     * Retrieve method full documentation description.
+     *
+     * @param ReflectionMethod $method
+     * @return string
+     */
+    protected function extractMethodDescription(ReflectionMethod $method)
+    {
+        $methodReflection = new MethodReflection(
+            $method->getDeclaringClass()->getName(),
+            $method->getName()
+        );
+
+        $docBlock = $methodReflection->getDocBlock();
+
+        return $this->_typeProcessor->getDescription($docBlock);
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Webapi/Model/Config/ClassReflectorTest.php b/dev/tests/unit/testsuite/Magento/Webapi/Model/Config/ClassReflectorTest.php
index 30fdab7a8cc..498df37e372 100644
--- a/dev/tests/unit/testsuite/Magento/Webapi/Model/Config/ClassReflectorTest.php
+++ b/dev/tests/unit/testsuite/Magento/Webapi/Model/Config/ClassReflectorTest.php
@@ -66,7 +66,9 @@ class ClassReflectorTest extends \PHPUnit_Framework_TestCase
     protected function _getSampleReflectionData()
     {
         return [
-            'documentation' => 'Basic random string generator',
+            'documentation' =>
+                'Basic random string generator. This line is short description '.
+                'This line is long description. This is still the long description.',
             'interface' => [
                 'in' => [
                     'parameters' => [
diff --git a/dev/tests/unit/testsuite/Magento/Webapi/Model/Config/TestServiceForClassReflector.php b/dev/tests/unit/testsuite/Magento/Webapi/Model/Config/TestServiceForClassReflector.php
index f3f25ccb5f4..cce8322bdaf 100644
--- a/dev/tests/unit/testsuite/Magento/Webapi/Model/Config/TestServiceForClassReflector.php
+++ b/dev/tests/unit/testsuite/Magento/Webapi/Model/Config/TestServiceForClassReflector.php
@@ -7,7 +7,10 @@ namespace Magento\Webapi\Model\Config;
 class TestServiceForClassReflector
 {
     /**
-     * Basic random string generator
+     * Basic random string generator. This line is short description
+     * This line is long description.
+     *
+     * This is still the long description.
      *
      * @param int $length length of the random string
      * @return string random string
diff --git a/lib/internal/Magento/Framework/Reflection/TypeProcessor.php b/lib/internal/Magento/Framework/Reflection/TypeProcessor.php
index 901eded854d..8756180f16b 100644
--- a/lib/internal/Magento/Framework/Reflection/TypeProcessor.php
+++ b/lib/internal/Magento/Framework/Reflection/TypeProcessor.php
@@ -157,7 +157,7 @@ class TypeProcessor
             }
             $reflection = new ClassReflection($class);
             $docBlock = $reflection->getDocBlock();
-            $this->_types[$typeName]['documentation'] = $docBlock ? $this->_getDescription($docBlock) : '';
+            $this->_types[$typeName]['documentation'] = $docBlock ? $this->getDescription($docBlock) : '';
             /** @var \Zend\Code\Reflection\MethodReflection $methodReflection */
             foreach ($reflection->getMethods(\ReflectionMethod::IS_PUBLIC) as $methodReflection) {
                 if ($methodReflection->class === "Magento\Framework\Model\AbstractModel") {
@@ -200,7 +200,7 @@ class TypeProcessor
      * @param \Zend\Code\Reflection\DocBlockReflection $doc
      * @return string
      */
-    protected function _getDescription(\Zend\Code\Reflection\DocBlockReflection $doc)
+    public function getDescription(\Zend\Code\Reflection\DocBlockReflection $doc)
     {
         $shortDescription = $doc->getShortDescription();
         $longDescription = $doc->getLongDescription();
-- 
GitLab


From 26ff26a6f1c6324d2ad7975440f9b618e46beca2 Mon Sep 17 00:00:00 2001
From: Arkadii Chyzhov <achyzhov@ebay.com>
Date: Mon, 22 Dec 2014 11:03:43 +0200
Subject: [PATCH 28/71] MAGETWO-24806: Fix Output Format of
 CustomerMetadataService getAllAttributeSetMetadata()

- Migrate from old branch to magento2ce
---
 .../Customer/Model/Customer/Attribute/Source/Website.php        | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/code/Magento/Customer/Model/Customer/Attribute/Source/Website.php b/app/code/Magento/Customer/Model/Customer/Attribute/Source/Website.php
index d22315515a4..22c524c3ff7 100644
--- a/app/code/Magento/Customer/Model/Customer/Attribute/Source/Website.php
+++ b/app/code/Magento/Customer/Model/Customer/Attribute/Source/Website.php
@@ -38,7 +38,7 @@ class Website extends \Magento\Eav\Model\Entity\Attribute\Source\Table
     public function getAllOptions()
     {
         if (!$this->_options) {
-            $this->_options = $this->_store->getWebsiteValuesForForm(true, true);
+            $this->_options = $this->_store->getWebsiteValuesForForm(false, true);
         }
 
         return $this->_options;
-- 
GitLab


From 7009abff583f7e7a807a1e7e798424e54f82492a Mon Sep 17 00:00:00 2001
From: Vladyslav Shcherbyna <vshcherbyna@ebay.com>
Date: Mon, 22 Dec 2014 12:22:52 +0200
Subject: [PATCH 29/71] MAGETWO-7359: Incorrect totals shown on coupon usage
 report

---
 .../Model/Resource/Report/Rule/Createdat.php  |  12 ++-
 .../Resource/Report/Rule/CreatedatTest.php    | 102 ++++++++++++++++++
 2 files changed, 111 insertions(+), 3 deletions(-)
 create mode 100644 dev/tests/integration/testsuite/Magento/SalesRule/Model/Resource/Report/Rule/CreatedatTest.php

diff --git a/app/code/Magento/SalesRule/Model/Resource/Report/Rule/Createdat.php b/app/code/Magento/SalesRule/Model/Resource/Report/Rule/Createdat.php
index 9e3ec5c0403..63bd5a0554e 100644
--- a/app/code/Magento/SalesRule/Model/Resource/Report/Rule/Createdat.php
+++ b/app/code/Magento/SalesRule/Model/Resource/Report/Rule/Createdat.php
@@ -94,7 +94,10 @@ class Createdat extends \Magento\Reports\Model\Resource\Report\AbstractReport
                         'base_subtotal_canceled',
                         0
                     ) . ' - ' . $adapter->getIfNullSql(
-                        'ABS(base_discount_amount) - ' . $adapter->getIfNullSql('base_discount_canceled', 0),
+                        'ABS(base_discount_amount) - ABS(' . $adapter->getIfNullSql('base_discount_canceled', 0) . ')',
+                        0
+                    ) . ' + ' . $adapter->getIfNullSql(
+                        'base_tax_amount - ' . $adapter->getIfNullSql('base_tax_canceled', 0),
                         0
                     ) . ')
                         * base_to_global_rate)',
@@ -120,9 +123,12 @@ class Createdat extends \Magento\Reports\Model\Resource\Report\AbstractReport
                         'base_subtotal_refunded',
                         0
                     ) . ' - ' . $adapter->getIfNullSql(
-                        'base_discount_invoiced - ' . $adapter->getIfNullSql('base_discount_refunded', 0),
+                        'ABS(base_discount_invoiced) - ABS(' . $adapter->getIfNullSql('base_discount_refunded', 0) . ')',
                         0
-                    ) . ') * base_to_global_rate)',
+                    ) . ' + ' . $adapter->getIfNullSql(
+                        'base_tax_invoiced - ' . $adapter->getIfNullSql('base_tax_refunded', 0),
+                        0
+                    )   . ') * base_to_global_rate)',
                     0
                 ),
             ];
diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/Model/Resource/Report/Rule/CreatedatTest.php b/dev/tests/integration/testsuite/Magento/SalesRule/Model/Resource/Report/Rule/CreatedatTest.php
new file mode 100644
index 00000000000..aabe4d1790b
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/SalesRule/Model/Resource/Report/Rule/CreatedatTest.php
@@ -0,0 +1,102 @@
+<?php
+/**
+ * {license_notice}
+ *
+ * @copyright   {copyright}
+ * @license     {license_link}
+ */
+namespace Magento\SalesRule\Model\Resource\Report\Rule;
+
+/**
+ * Createdat test for check report totals calculate
+ *
+ * @magentoDataFixture Magento/SalesRule/_files/order_with_coupon.php
+ */
+class CreatedatTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider orderParamsDataProvider()
+     * @param $orderParams
+     */
+    public function testTotals($orderParams)
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Sales\Model\Order');
+        $order->loadByIncrementId('100000001')
+            ->setBaseGrandTotal($orderParams['base_subtotal'])
+            ->setSubtotal($orderParams['base_subtotal'])
+            ->setBaseSubtotal($orderParams['base_subtotal'])
+            ->setBaseDiscountAmount($orderParams['base_discount_amount'])
+            ->setBaseTaxAmount($orderParams['base_tax_amount'])
+            ->setBaseSubtotalInvoiced($orderParams['base_subtotal_invoiced'])
+            ->setBaseDiscountInvoiced($orderParams['base_discount_invoiced'])
+            ->setBaseTaxInvoiced($orderParams['base_tax_invoiced'])
+            ->setBaseShippingAmount(0)
+            ->setBaseToGlobalRate(1)
+            ->setCouponCode('1234567890')
+            ->setCreatedAt('2014-10-25 10:10:10')
+            ->save();
+        // refresh report statistics
+        /** @var \Magento\SalesRule\Model\Resource\Report\Rule $reportResource */
+        $reportResource = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            'Magento\SalesRule\Model\Resource\Report\Rule'
+        );
+        $reportResource->aggregate();
+        /** @var \Magento\SalesRule\Model\Resource\Report\Collection $reportCollection */
+        $reportCollection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            'Magento\SalesRule\Model\Resource\Report\Collection'
+        );
+        $salesRuleReportItem = $reportCollection->getFirstItem();
+        $this->assertEquals($this->getTotalAmount($order), $salesRuleReportItem['total_amount']);
+        $this->assertEquals($this->getTotalAmountActual($order), $salesRuleReportItem['total_amount_actual']);
+    }
+
+    /**
+     * Repeat sql formula from \Magento\SalesRule\Model\Resource\Report\Rule\Createdat::_aggregateByOrder
+     *
+     * @param \Magento\Sales\Model\Order $order
+     * @return float
+     */
+    private function getTotalAmount(\Magento\Sales\Model\Order $order)
+    {
+        return (
+            $order->getBaseSubtotal() - $order->getBaseSubtotalCanceled()
+            - (abs($order->getBaseDiscountAmount()) - abs($order->getBaseDiscountCanceled()))
+            + ($order->getBaseTaxAmount() - $order->getBaseTaxCanceled())
+        ) * $order->getBaseToGlobalRate();
+    }
+
+    /**
+     * Repeat sql formula from \Magento\SalesRule\Model\Resource\Report\Rule\Createdat::_aggregateByOrder
+     *
+     * @param \Magento\Sales\Model\Order $order
+     * @return float
+     */
+    private function getTotalAmountActual(\Magento\Sales\Model\Order $order)
+    {
+        return (
+            $order->getBaseSubtotalInvoiced() - $order->getSubtotalRefunded()
+            - abs($order->getBaseDiscountInvoiced()) - abs($order->getBaseDiscountRefunded())
+            + $order->getBaseTaxInvoiced() - $order->getBaseTaxRefunded()
+        ) * $order->getBaseToGlobalRate();
+    }
+
+    /**
+     * @return array
+     */
+    public function orderParamsDataProvider()
+    {
+        return [
+            [
+                [
+                    'base_discount_amount' => 98.80,
+                    'base_subtotal' => 494,
+                    'base_tax_amount' => 8.8,
+                    'base_subtotal_invoiced' => 494,
+                    'base_discount_invoiced' => 98.80,
+                    'base_tax_invoiced' => 8.8
+                ]
+            ]
+        ];
+    }
+}
-- 
GitLab


From d6e9146361ed1527461bf2eff4dea5ec6c6460a0 Mon Sep 17 00:00:00 2001
From: Andriy Nasinnyk <anasinnyk@ebay.com>
Date: Mon, 22 Dec 2014 18:48:11 +0200
Subject: [PATCH 30/71] MAGETWO-13915: PSR-3: common interface for logging
 libraries.

 - replace log and logException calls
 - fixed bug with unexisting log directory
---
 .../Controller/Adminhtml/Index/Create.php     |  4 +-
 .../Controller/Adminhtml/Index/Rollback.php   |  4 +-
 .../Model/Carrier/AbstractCarrier.php         |  2 +-
 app/etc/di.xml                                | 16 +-----
 .../Magento/TestFramework/ErrorLog/Logger.php | 12 +----
 .../Framework/Logger/Handler/Critical.php     | 21 ++++++++
 .../Framework/Logger/Handler/System.php       | 51 +++++++++++++++++++
 7 files changed, 81 insertions(+), 29 deletions(-)
 create mode 100644 lib/internal/Magento/Framework/Logger/Handler/Critical.php
 create mode 100644 lib/internal/Magento/Framework/Logger/Handler/System.php

diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index/Create.php b/app/code/Magento/Backup/Controller/Adminhtml/Index/Create.php
index 654697d038d..d594ed09070 100644
--- a/app/code/Magento/Backup/Controller/Adminhtml/Index/Create.php
+++ b/app/code/Magento/Backup/Controller/Adminhtml/Index/Create.php
@@ -86,10 +86,10 @@ class Create extends \Magento\Backup\Controller\Adminhtml\Index
         } catch (\Magento\Framework\Backup\Exception\NotEnoughFreeSpace $e) {
             $errorMessage = __('You need more free space to create a backup.');
         } catch (\Magento\Framework\Backup\Exception\NotEnoughPermissions $e) {
-            $this->_objectManager->get('Psr\Log\LoggerInterface')->log($e->getMessage());
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->info($e->getMessage());
             $errorMessage = __('You need more permissions to create a backup.');
         } catch (\Exception $e) {
-            $this->_objectManager->get('Psr\Log\LoggerInterface')->log($e->getMessage());
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->info($e->getMessage());
             $errorMessage = __('Something went wrong creating the backup.');
         }
 
diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index/Rollback.php b/app/code/Magento/Backup/Controller/Adminhtml/Index/Rollback.php
index c10b5b37c5b..20723783b18 100644
--- a/app/code/Magento/Backup/Controller/Adminhtml/Index/Rollback.php
+++ b/app/code/Magento/Backup/Controller/Adminhtml/Index/Rollback.php
@@ -122,10 +122,10 @@ class Rollback extends \Magento\Backup\Controller\Adminhtml\Index
         } catch (\Magento\Framework\Backup\Exception\FtpValidationFailed $e) {
             $errorMsg = __('Failed to validate FTP');
         } catch (\Magento\Framework\Backup\Exception\NotEnoughPermissions $e) {
-            $this->_objectManager->get('Psr\Log\LoggerInterface')->log($e->getMessage());
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->info($e->getMessage());
             $errorMsg = __('Not enough permissions to perform rollback.');
         } catch (\Exception $e) {
-            $this->_objectManager->get('Psr\Log\LoggerInterface')->log($e->getMessage());
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->info($e->getMessage());
             $errorMsg = __('Failed to rollback');
         }
 
diff --git a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrier.php b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrier.php
index cb490cc476c..1f695dcf1e6 100644
--- a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrier.php
+++ b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrier.php
@@ -568,7 +568,7 @@ abstract class AbstractCarrier extends \Magento\Framework\Object implements Abst
     protected function _debug($debugData)
     {
         if ($this->getDebugFlag()) {
-            $this->_logger->log($debugData);
+            $this->_logger->info($debugData);
         }
     }
 
diff --git a/app/etc/di.xml b/app/etc/di.xml
index 60364ef243e..f048c38392d 100644
--- a/app/etc/di.xml
+++ b/app/etc/di.xml
@@ -85,24 +85,12 @@
     <preference for="Magento\Framework\DB\LoggerInterface" type="Magento\Framework\DB\Logger\Null"/>
     <preference for="Magento\Framework\App\Resource\ConnectionAdapterInterface" type="Magento\Framework\Model\Resource\Type\Db\Pdo\Mysql"/>
     <preference for="Magento\Framework\DB\QueryInterface" type="Magento\Framework\DB\Query"/>
-    <virtualType name="Monolog\Handler\Stream\System" type="Monolog\Handler\StreamHandler">
-        <arguments>
-            <argument name="stream" xsi:type="string">var/log/system.log</argument>
-            <argument name="level" xsi:type="const">Monolog\Logger::DEBUG</argument>
-        </arguments>
-    </virtualType>
-    <virtualType name="Monolog\Handler\Stream\Exception" type="Monolog\Handler\StreamHandler">
-        <arguments>
-            <argument name="stream" xsi:type="string">var/log/exception.log</argument>
-            <argument name="level" xsi:type="const">Monolog\Logger::CRITICAL</argument>
-        </arguments>
-    </virtualType>
     <type name="Monolog\Logger">
         <arguments>
             <argument name="name" xsi:type="string">main</argument>
             <argument name="handlers"  xsi:type="array">
-                <item name="exception" xsi:type="object">Monolog\Handler\Stream\Exception</item>
-                <item name="system" xsi:type="object">Monolog\Handler\Stream\System</item>
+                <item name="exception" xsi:type="object">Magento\Framework\Logger\Handler\Critical</item>
+                <item name="system" xsi:type="object">Magento\Framework\Logger\Handler\System</item>
             </argument>
         </arguments>
     </type>
diff --git a/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Logger.php b/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Logger.php
index 1b52381998e..842d3ffe563 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Logger.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Logger.php
@@ -4,7 +4,7 @@
  */
 namespace Magento\TestFramework\ErrorLog;
 
-class Logger extends \Psr\Log\LoggerInterface
+class Logger extends \Monolog\Logger
 {
     /** @var array */
     protected $messages = [];
@@ -21,6 +21,7 @@ class Logger extends \Psr\Log\LoggerInterface
     public function __construct()
     {
         $this->minimumErrorLevel = defined('TESTS_ERROR_LOG_LISTENER_LEVEL') ? TESTS_ERROR_LOG_LISTENER_LEVEL : -1;
+        parent::__construct('integration-test');
     }
 
     /**
@@ -38,13 +39,4 @@ class Logger extends \Psr\Log\LoggerInterface
     {
         return $this->messages;
     }
-
-    /**
-     * @param string $message
-     * @internal param int $level
-     */
-    public function info($message)
-    {
-        parent::info($message);
-    }
 }
diff --git a/lib/internal/Magento/Framework/Logger/Handler/Critical.php b/lib/internal/Magento/Framework/Logger/Handler/Critical.php
new file mode 100644
index 00000000000..1f2a1950179
--- /dev/null
+++ b/lib/internal/Magento/Framework/Logger/Handler/Critical.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Framework\Logger\Handler;
+
+use Monolog\Logger;
+
+class Critical extends System
+{
+    /**
+     * @var string
+     */
+    protected $fileName = '/var/log/exception.log';
+
+    /**
+     * @var int
+     */
+    protected $loggerType = Logger::CRITICAL;
+}
diff --git a/lib/internal/Magento/Framework/Logger/Handler/System.php b/lib/internal/Magento/Framework/Logger/Handler/System.php
new file mode 100644
index 00000000000..b3f799e56cc
--- /dev/null
+++ b/lib/internal/Magento/Framework/Logger/Handler/System.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Framework\Logger\Handler;
+
+use Magento\Framework\Filesystem\Driver\File;
+use Monolog\Handler\StreamHandler;
+use Monolog\Logger;
+
+class System extends StreamHandler
+{
+    /**
+     * @var string
+     */
+    protected $fileName = '/var/log/system.log';
+
+    /**
+     * @var int
+     */
+    protected $loggerType = Logger::DEBUG;
+
+    /**
+     * @var File
+     */
+    protected $filesystem;
+
+    /**
+     * @param File $filesystem
+     */
+    public function __construct(File $filesystem)
+    {
+        $this->filesystem = $filesystem;
+        parent::__construct(BP . $this->fileName, $this->loggerType);
+    }
+
+    /**
+     * @{inerhitDoc}
+     *
+     * @param $record array
+     */
+    public function write(array $record)
+    {
+        $logDir = $this->filesystem->getParentDirectory($this->url);
+        if (!$this->filesystem->isDirectory($logDir)) {
+            $this->filesystem->createDirectory($logDir, 0777);
+        }
+        parent::write($record);
+    }
+}
-- 
GitLab


From 92683ac9ce47ca93349d508ed686bf9601a77be3 Mon Sep 17 00:00:00 2001
From: Rob Mangiafico <robfico@users.noreply.github.com>
Date: Mon, 22 Dec 2014 11:49:58 -0500
Subject: [PATCH 31/71] Update Actions.php

Changing URL_PATH to work for page edits in backend
---
 app/code/Magento/Cms/Ui/DataProvider/Page/Row/Actions.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/code/Magento/Cms/Ui/DataProvider/Page/Row/Actions.php b/app/code/Magento/Cms/Ui/DataProvider/Page/Row/Actions.php
index 8c10225dd3e..85ef7f19c4c 100644
--- a/app/code/Magento/Cms/Ui/DataProvider/Page/Row/Actions.php
+++ b/app/code/Magento/Cms/Ui/DataProvider/Page/Row/Actions.php
@@ -16,7 +16,7 @@ class Actions implements RowInterface
     /**
      * Url path
      */
-    const URL_PATH = 'adminhtml/cms_page/edit';
+    const URL_PATH = 'cms/page/edit';
 
     /**
      * @var UrlBuilder
-- 
GitLab


From 271fd759630c50cdbec4362a2c65a00fd567e8b5 Mon Sep 17 00:00:00 2001
From: Andriy Nasinnyk <anasinnyk@ebay.com>
Date: Mon, 22 Dec 2014 18:59:01 +0200
Subject: [PATCH 32/71] MAGETWO-13915: PSR-3: common interface for logging
 libraries.

---
 .../framework/Magento/TestFramework/ErrorLog/Listener.php | 2 +-
 lib/internal/Magento/Framework/Logger/Handler/System.php  | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Listener.php b/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Listener.php
index ce2720accac..e86373e49f1 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Listener.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Listener.php
@@ -72,7 +72,7 @@ class Listener implements \PHPUnit_Framework_TestListener
      */
     public function startTest(\PHPUnit_Framework_Test $test)
     {
-        $this->logger = Helper\Bootstrap::getObjectManager()->get('Psr\Log\LoggerInterface');
+        $this->logger = Helper\Bootstrap::getObjectManager()->get('Magento\TestFramework\ErrorLog\Logger');
         $this->logger->clearMessages();
     }
 
diff --git a/lib/internal/Magento/Framework/Logger/Handler/System.php b/lib/internal/Magento/Framework/Logger/Handler/System.php
index b3f799e56cc..d836d7df376 100644
--- a/lib/internal/Magento/Framework/Logger/Handler/System.php
+++ b/lib/internal/Magento/Framework/Logger/Handler/System.php
@@ -5,7 +5,7 @@
 
 namespace Magento\Framework\Logger\Handler;
 
-use Magento\Framework\Filesystem\Driver\File;
+use Magento\Framework\Filesystem\DriverInterface;
 use Monolog\Handler\StreamHandler;
 use Monolog\Logger;
 
@@ -22,14 +22,14 @@ class System extends StreamHandler
     protected $loggerType = Logger::DEBUG;
 
     /**
-     * @var File
+     * @var DriverInterface
      */
     protected $filesystem;
 
     /**
-     * @param File $filesystem
+     * @param DriverInterface $filesystem
      */
-    public function __construct(File $filesystem)
+    public function __construct(DriverInterface $filesystem)
     {
         $this->filesystem = $filesystem;
         parent::__construct(BP . $this->fileName, $this->loggerType);
-- 
GitLab


From c62be57a024c6214ed0e0b5656ce4ca378d5e55b Mon Sep 17 00:00:00 2001
From: Andriy Nasinnyk <anasinnyk@ebay.com>
Date: Mon, 22 Dec 2014 19:04:49 +0200
Subject: [PATCH 33/71] MAGETWO-13915: PSR-3: common interface for logging
 libraries.

---
 app/etc/di.xml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/app/etc/di.xml b/app/etc/di.xml
index f048c38392d..e0be4971c62 100644
--- a/app/etc/di.xml
+++ b/app/etc/di.xml
@@ -85,6 +85,11 @@
     <preference for="Magento\Framework\DB\LoggerInterface" type="Magento\Framework\DB\Logger\Null"/>
     <preference for="Magento\Framework\App\Resource\ConnectionAdapterInterface" type="Magento\Framework\Model\Resource\Type\Db\Pdo\Mysql"/>
     <preference for="Magento\Framework\DB\QueryInterface" type="Magento\Framework\DB\Query"/>
+    <type name="Magento\Framework\Logger\Handler\System">
+        <arguments>
+            <argument name="filesystem" xsi:type="object">Magento\Framework\Filesystem\Driver\File</argument>
+        </arguments>
+    </type>
     <type name="Monolog\Logger">
         <arguments>
             <argument name="name" xsi:type="string">main</argument>
-- 
GitLab


From 0fac107d31f7a59c8aa90872e52e17de08e4db74 Mon Sep 17 00:00:00 2001
From: Kevin Abel <kabel@users.noreply.github.com>
Date: Mon, 22 Dec 2014 13:18:16 -0600
Subject: [PATCH 34/71] Fix email template creation date not being persisted

The database schema from https://github.com/magento/magento2/blob/develop/app/code/Magento/Email/sql/email_setup/install-2.0.0.php#L62-L67 uses the column `added_at` for storing the date the email template creation date. When `setCreatedAt` is used, that date is not persisted to the database, leaving the column `NULL` in the database.
---
 app/code/Magento/Email/Model/Resource/Template.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/code/Magento/Email/Model/Resource/Template.php b/app/code/Magento/Email/Model/Resource/Template.php
index f4cf0242b54..6c6fe926b97 100644
--- a/app/code/Magento/Email/Model/Resource/Template.php
+++ b/app/code/Magento/Email/Model/Resource/Template.php
@@ -99,7 +99,7 @@ class Template extends \Magento\Framework\Model\Resource\Db\AbstractDb
     protected function _beforeSave(AbstractModel $object)
     {
         if ($object->isObjectNew()) {
-            $object->setCreatedAt($this->dateTime->formatDate(true));
+            $object->setAddedAt($this->dateTime->formatDate(true));
         }
         $object->setModifiedAt($this->dateTime->formatDate(true));
         $object->setTemplateType((int)$object->getTemplateType());
-- 
GitLab


From bc445afbcae98d1f59f2a22b63386c99cab49402 Mon Sep 17 00:00:00 2001
From: agurzhyi <agurzhyi@ebay.com>
Date: Mon, 22 Dec 2014 21:23:17 +0200
Subject: [PATCH 35/71] MAGETWO-27636: Persistent Shopping Cart: 'Not
 %Username%?' link is displayed during page load for user logged in

---
 .../Persistent/Block/Header/Additional.php    |  19 +-
 .../Model/Layout/DepersonalizePlugin.php      |  73 ++++
 .../Magento/Persistent/Model/Observer.php     |  19 +-
 .../Magento/Persistent/etc/frontend/di.xml    |   6 +
 .../Block/Header/AdditionalTest.php           | 356 ++++++++++++++++++
 .../Model/Layout/DepersonalizePluginTest.php  | 163 ++++++++
 6 files changed, 627 insertions(+), 9 deletions(-)
 create mode 100644 app/code/Magento/Persistent/Model/Layout/DepersonalizePlugin.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Persistent/Block/Header/AdditionalTest.php
 create mode 100644 dev/tests/unit/testsuite/Magento/Persistent/Model/Layout/DepersonalizePluginTest.php

diff --git a/app/code/Magento/Persistent/Block/Header/Additional.php b/app/code/Magento/Persistent/Block/Header/Additional.php
index 298052731e3..4b7f83d2e23 100644
--- a/app/code/Magento/Persistent/Block/Header/Additional.php
+++ b/app/code/Magento/Persistent/Block/Header/Additional.php
@@ -44,6 +44,7 @@ class Additional extends \Magento\Framework\View\Element\Html\Link
         \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
         array $data = []
     ) {
+        $this->isScopePrivate = true;
         $this->_customerViewHelper = $customerViewHelper;
         $this->_persistentSessionHelper = $persistentSessionHelper;
         $this->customerRepository = $customerRepository;
@@ -68,12 +69,16 @@ class Additional extends \Magento\Framework\View\Element\Html\Link
      */
     protected function _toHtml()
     {
-        $persistentName = $this->_escaper->escapeHtml(
-            $this->_customerViewHelper->getCustomerName(
-                $this->customerRepository->getById($this->_persistentSessionHelper->getSession()->getCustomerId())
-            )
-        );
-        return '<span><a ' . $this->getLinkAttributes() . ' >' . $this->escapeHtml(__('(Not %1?)', $persistentName))
-        . '</a></span>';
+        if ($this->_persistentSessionHelper->getSession()->getCustomerId()) {
+            $persistentName = $this->escapeHtml(
+                $this->_customerViewHelper->getCustomerName(
+                    $this->customerRepository->getById($this->_persistentSessionHelper->getSession()->getCustomerId())
+                )
+            );
+            return '<span><a ' . $this->getLinkAttributes() . ' >' . __('(Not %1?)', $persistentName)
+            . '</a></span>';
+        }
+
+        return '';
     }
 }
diff --git a/app/code/Magento/Persistent/Model/Layout/DepersonalizePlugin.php b/app/code/Magento/Persistent/Model/Layout/DepersonalizePlugin.php
new file mode 100644
index 00000000000..46bf6df5212
--- /dev/null
+++ b/app/code/Magento/Persistent/Model/Layout/DepersonalizePlugin.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Persistent\Model\Layout;
+
+/**
+ * Class DepersonalizePlugin
+ */
+class DepersonalizePlugin
+{
+    /**
+     * @var \Magento\Persistent\Model\Session
+     */
+    protected $persistentSession;
+
+    /**
+     * @var \Magento\Framework\App\RequestInterface
+     */
+    protected $request;
+
+    /**
+     * @var \Magento\Framework\Module\Manager
+     */
+    protected $moduleManager;
+
+    /**
+     * @var \Magento\PageCache\Model\Config
+     */
+    protected $cacheConfig;
+
+    /**
+     * Constructor
+     *
+     * @param \Magento\Persistent\Model\Session $persistentSession
+     * @param \Magento\Framework\App\RequestInterface $request
+     * @param \Magento\Framework\Module\Manager $moduleManager
+     * @param \Magento\PageCache\Model\Config $cacheConfig
+     */
+    public function __construct(
+        \Magento\Persistent\Model\Session $persistentSession,
+        \Magento\Framework\App\RequestInterface $request,
+        \Magento\Framework\Module\Manager $moduleManager,
+        \Magento\PageCache\Model\Config $cacheConfig
+    ) {
+        $this->persistentSession = $persistentSession;
+        $this->request = $request;
+        $this->moduleManager = $moduleManager;
+        $this->cacheConfig = $cacheConfig;
+    }
+
+    /**
+     * After generate Xml
+     *
+     * @param \Magento\Framework\View\LayoutInterface $subject
+     * @param \Magento\Framework\View\LayoutInterface $result
+     * @return \Magento\Framework\View\LayoutInterface
+     */
+    public function afterGenerateXml(
+        \Magento\Framework\View\LayoutInterface $subject,
+        \Magento\Framework\View\LayoutInterface $result
+    ) {
+        if ($this->moduleManager->isEnabled('Magento_PageCache')
+            && $this->cacheConfig->isEnabled()
+            && !$this->request->isAjax()
+            && $subject->isCacheable()
+        ) {
+            $this->persistentSession->setCustomerId(null);
+        }
+
+        return $result;
+    }
+}
diff --git a/app/code/Magento/Persistent/Model/Observer.php b/app/code/Magento/Persistent/Model/Observer.php
index 67d50e90ab4..d91abec4545 100644
--- a/app/code/Magento/Persistent/Model/Observer.php
+++ b/app/code/Magento/Persistent/Model/Observer.php
@@ -92,11 +92,25 @@ class Observer
             null
         );
 
-        $block->setWelcome(__('Welcome, %1!', $escapedName));
-
+        $this->_applyAccountLinksPersistentData();
+        $welcomeMessage = __('Welcome, %1!', $escapedName)
+            . ' ' . $this->_layout->getBlock('header.additional')->toHtml();
+        $block->setWelcome($welcomeMessage);
         return $this;
     }
 
+    /**
+     * Emulate 'account links' block with persistent data
+     *
+     * @return void
+     */
+    protected function _applyAccountLinksPersistentData()
+    {
+        if (!$this->_layout->getBlock('header.additional')) {
+            $this->_layout->addBlock('Magento\Persistent\Block\Header\Additional', 'header.additional');
+        }
+    }
+
     /**
      * Emulate 'top links' block with persistent data
      *
@@ -105,6 +119,7 @@ class Observer
      */
     public function emulateTopLinks($block)
     {
+        $this->_applyAccountLinksPersistentData();
         $block->removeLinkByUrl($this->_url->getUrl('customer/account/login'));
     }
 }
diff --git a/app/code/Magento/Persistent/etc/frontend/di.xml b/app/code/Magento/Persistent/etc/frontend/di.xml
index 08f489c2469..a3d5a161a17 100644
--- a/app/code/Magento/Persistent/etc/frontend/di.xml
+++ b/app/code/Magento/Persistent/etc/frontend/di.xml
@@ -12,4 +12,10 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Framework\View\Layout">
+        <plugin name="customer-session-depersonalize"
+                type="Magento\Persistent\Model\Layout\DepersonalizePlugin"
+                sortOrder="10"
+        />
+    </type>
 </config>
diff --git a/dev/tests/unit/testsuite/Magento/Persistent/Block/Header/AdditionalTest.php b/dev/tests/unit/testsuite/Magento/Persistent/Block/Header/AdditionalTest.php
new file mode 100644
index 00000000000..9237b9f7ff8
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Persistent/Block/Header/AdditionalTest.php
@@ -0,0 +1,356 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Persistent\Block\Header;
+
+/**
+ * Class AdditionalTest
+ */
+class AdditionalTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Customer\Helper\View|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $customerViewHelperMock;
+
+    /**
+     * @var \Magento\Persistent\Helper\Session|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $persistentSessionHelperMock;
+
+    /**
+     * Customer repository
+     *
+     * @var \Magento\Customer\Api\CustomerRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $customerRepositoryMock;
+
+    /**
+     * @var \Magento\Framework\View\Element\Template\Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $contextMock;
+
+    /**
+     * @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $eventManagerMock;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $scopeConfigMock;
+
+    /**
+     * @var \Magento\Framework\App\Cache\StateInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $cacheStateMock;
+
+    /**
+     * @var \Magento\Framework\App\CacheInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $cacheMock;
+
+    /**
+     * @var \Magento\Framework\Session\SidResolverInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $sidResolverMock;
+
+    /**
+     * @var \Magento\Framework\Session\SessionManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $sessionMock;
+
+    /**
+     * @var \Magento\Framework\Escaper|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $escaperMock;
+
+    /**
+     * @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlBuilderMock;
+
+    /**
+     * @var \Magento\Persistent\Block\Header\Additional
+     */
+    protected $additional;
+
+    /**
+     * @var \Magento\TestFramework\Helper\ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * Set up
+     *
+     * @return void
+     */
+    protected function setUp()
+    {
+        $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
+
+        $this->contextMock = $this->getMock(
+            'Magento\Framework\View\Element\Template\Context',
+            [
+                'getEventManager',
+                'getScopeConfig',
+                'getCacheState',
+                'getCache',
+                'getInlineTranslation',
+                'getSidResolver',
+                'getSession',
+                'getEscaper',
+                'getUrlBuilder'
+            ],
+            [],
+            '',
+            false
+        );
+        $this->customerViewHelperMock = $this->getMock(
+            'Magento\Customer\Helper\View',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->persistentSessionHelperMock = $this->getMock(
+            'Magento\Persistent\Helper\Session',
+            ['getSession'],
+            [],
+            '',
+            false
+        );
+        $this->customerRepositoryMock = $this->getMockForAbstractClass(
+            'Magento\Customer\Api\CustomerRepositoryInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['getById']
+        );
+
+        $this->eventManagerMock = $this->getMockForAbstractClass(
+            'Magento\Framework\Event\ManagerInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['dispatch']
+        );
+        $this->scopeConfigMock = $this->getMockForAbstractClass(
+            'Magento\Framework\App\Config\ScopeConfigInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['getValue']
+        );
+        $this->cacheStateMock = $this->getMockForAbstractClass(
+            'Magento\Framework\App\Cache\StateInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['isEnabled']
+        );
+        $this->cacheMock = $this->getMockForAbstractClass(
+            'Magento\Framework\App\CacheInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['load']
+        );
+        $this->sidResolverMock = $this->getMockForAbstractClass(
+            'Magento\Framework\Session\SidResolverInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['getSessionIdQueryParam']
+        );
+        $this->sessionMock = $this->getMockForAbstractClass(
+            'Magento\Framework\Session\SessionManagerInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['getSessionId']
+        );
+        $this->escaperMock = $this->getMockForAbstractClass(
+            'Magento\Framework\Escaper',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['escapeHtml']
+        );
+        $this->urlBuilderMock = $this->getMockForAbstractClass(
+            'Magento\Framework\UrlInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['getUrl']
+        );
+
+        $this->contextMock->expects($this->once())
+            ->method('getEventManager')
+            ->willReturn($this->eventManagerMock);
+        $this->contextMock->expects($this->once())
+            ->method('getScopeConfig')
+            ->willReturn($this->scopeConfigMock);
+        $this->contextMock->expects($this->once())
+            ->method('getCacheState')
+            ->willReturn($this->cacheStateMock);
+        $this->contextMock->expects($this->once())
+            ->method('getCache')
+            ->willReturn($this->cacheMock);
+        $this->contextMock->expects($this->once())
+            ->method('getSidResolver')
+            ->willReturn($this->sidResolverMock);
+        $this->contextMock->expects($this->once())
+            ->method('getSession')
+            ->willReturn($this->sessionMock);
+        $this->contextMock->expects($this->once())
+            ->method('getEscaper')
+            ->willReturn($this->escaperMock);
+        $this->contextMock->expects($this->once())
+            ->method('getUrlBuilder')
+            ->willReturn($this->urlBuilderMock);
+
+        $this->additional = $this->objectManager->getObject(
+            'Magento\Persistent\Block\Header\Additional',
+            [
+                'context' => $this->contextMock,
+                'customerViewHelper' => $this->customerViewHelperMock,
+                'persistentSessionHelper' => $this->persistentSessionHelperMock,
+                'customerRepository' => $this->customerRepositoryMock,
+                'data' => []
+            ]
+        );
+    }
+
+    /**
+     * Run test toHtml method
+     *
+     * @param bool $customerId
+     * @return void
+     *
+     * @dataProvider dataProviderToHtml
+     */
+    public function testToHtml($customerId)
+    {
+        $cacheData = false;
+        $idQueryParam = 'id-query-param';
+        $sessionId = 'session-id';
+        $customerName = 'customer-name';
+
+        $this->additional->setData('cache_lifetime', 789);
+        $this->additional->setData('cache_key', 'cache-key');
+
+        $this->eventManagerMock->expects($this->once())
+            ->method('dispatch')
+            ->with('view_block_abstract_to_html_before', ['block' => $this->additional]);
+        $this->scopeConfigMock->expects($this->once())
+            ->method('getValue')
+            ->with(
+                'advanced/modules_disable_output/Magento_Persistent',
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+            )->willReturn(false);
+
+        // get cache
+        $this->cacheStateMock->expects($this->at(0))
+            ->method('isEnabled')
+            ->with(\Magento\Persistent\Block\Header\Additional::CACHE_GROUP)
+            ->willReturn(true);
+        // save cache
+        $this->cacheStateMock->expects($this->at(1))
+            ->method('isEnabled')
+            ->with(\Magento\Persistent\Block\Header\Additional::CACHE_GROUP)
+            ->willReturn(false);
+
+        $this->cacheMock->expects($this->once())
+            ->method('load')
+            ->willReturn($cacheData);
+        $this->sidResolverMock->expects($this->never())
+            ->method('getSessionIdQueryParam')
+            ->with($this->sessionMock)
+            ->willReturn($idQueryParam);
+        $this->sessionMock->expects($this->never())
+            ->method('getSessionId')
+            ->willReturn($sessionId);
+
+        // call protected _toHtml method
+        $sessionMock = $this->getMock(
+            'Magento\Persistent\Model\Session',
+            ['getCustomerId'],
+            [],
+            '',
+            false
+        );
+
+        $this->persistentSessionHelperMock->expects($this->atLeastOnce())
+            ->method('getSession')
+            ->willReturn($sessionMock);
+
+        $sessionMock->expects($this->atLeastOnce())
+            ->method('getCustomerId')
+            ->willReturn($customerId);
+
+        if ($customerId) {
+
+            $customerMock = $this->getMockForAbstractClass(
+                'Magento\Customer\Api\Data\CustomerInterface',
+                [],
+                '',
+                false,
+                true,
+                true,
+                []
+            );
+
+            $this->customerRepositoryMock->expects($this->once())
+                ->method('getById')
+                ->with($customerId)
+                ->willReturn($customerMock);
+
+            $this->customerViewHelperMock->expects($this->once())
+                ->method('getCustomerName')
+                ->with($customerMock)
+                ->willReturn($customerName);
+
+            $this->escaperMock->expects($this->at(0))
+                ->method('escapeHtml')
+                ->with($customerName)
+                ->willReturn($customerName);
+
+            $this->assertEquals('<span><a  >(Not customer-name?)</a></span>', $this->additional->toHtml());
+        } else {
+            $this->assertEquals('', $this->additional->toHtml());
+        }
+    }
+
+    /**
+     * Data provider for dataProviderToHtml method
+     *
+     * @return array
+     */
+    public function dataProviderToHtml()
+    {
+        return [
+            ['customerId' => 2],
+            ['customerId' => null],
+        ];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Persistent/Model/Layout/DepersonalizePluginTest.php b/dev/tests/unit/testsuite/Magento/Persistent/Model/Layout/DepersonalizePluginTest.php
new file mode 100644
index 00000000000..4e92b86b297
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Persistent/Model/Layout/DepersonalizePluginTest.php
@@ -0,0 +1,163 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Persistent\Model\Layout;
+
+/**
+ * Class DepersonalizePluginTest
+ */
+class DepersonalizePluginTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Persistent\Model\Session|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $persistentSessionMock;
+
+    /**
+     * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $requestMock;
+
+    /**
+     * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $moduleManagerMock;
+
+    /**
+     * @var \Magento\PageCache\Model\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $cacheConfigMock;
+
+    /**
+     * @var \Magento\TestFramework\Helper\ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * @var \Magento\Persistent\Model\Layout\DepersonalizePlugin
+     */
+    protected $plugin;
+
+    /**
+     * Set up
+     *
+     * @return void
+     */
+    protected function setUp()
+    {
+        $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
+
+        $this->persistentSessionMock = $this->getMock(
+            'Magento\Persistent\Model\Session',
+            ['setCustomerId'],
+            [],
+            '',
+            false
+        );
+
+        $this->requestMock = $this->getMockForAbstractClass(
+            'Magento\Framework\App\RequestInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['isAjax']
+        );
+        $this->moduleManagerMock = $this->getMock(
+            'Magento\Framework\Module\Manager',
+            ['isEnabled'],
+            [],
+            '',
+            false
+        );
+        $this->cacheConfigMock = $this->getMock(
+            'Magento\PageCache\Model\Config',
+            ['isEnabled'],
+            [],
+            '',
+            false
+        );
+
+        $this->plugin = $this->objectManager->getObject(
+            'Magento\Persistent\Model\Layout\DepersonalizePlugin',
+            [
+                'persistentSession' => $this->persistentSessionMock,
+                'request' => $this->requestMock,
+                'moduleManager' => $this->moduleManagerMock,
+                'cacheConfig' => $this->cacheConfigMock
+            ]
+        );
+    }
+
+    /**
+     * Run test afterGenerateXml method
+     *
+     * @param bool $result
+     *
+     * @dataProvider dataProviderAfterGenerateXml
+     */
+    public function testAfterGenerateXml($result)
+    {
+        /** @var \Magento\Framework\View\LayoutInterface|\PHPUnit_Framework_MockObject_MockObject $subjectMock */
+        $subjectMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\LayoutInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['isCacheable']
+        );
+        /** @var \Magento\Framework\View\LayoutInterface|\PHPUnit_Framework_MockObject_MockObject $resultMock */
+        $resultMock = $this->getMockForAbstractClass(
+            'Magento\Framework\View\LayoutInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            []
+        );
+
+        $this->moduleManagerMock->expects($this->once())
+            ->method('isEnabled')
+            ->with('Magento_PageCache')
+            ->willReturn($result);
+        $this->cacheConfigMock->expects($this->any())
+            ->method('isEnabled')
+            ->willReturn($result);
+        $this->requestMock->expects($this->any())
+            ->method('isAjax')
+            ->willReturn(!$result);
+        $subjectMock->expects($this->any())
+            ->method('isCacheable')
+            ->willReturn($result);
+
+        if ($result) {
+            $this->persistentSessionMock->expects($this->once())
+                ->method('setCustomerId')
+                ->with(null);
+        } else {
+            $this->persistentSessionMock->expects($this->never())
+                ->method('setCustomerId')
+                ->with(null);
+        }
+
+        $this->assertEquals($resultMock, $this->plugin->afterGenerateXml($subjectMock, $resultMock));
+    }
+
+    /**
+     * Data provider for testAfterGenerateXml
+     *
+     * @return array
+     */
+    public function dataProviderAfterGenerateXml()
+    {
+        return [
+            ['result' => true],
+            ['result' => false]
+        ];
+    }
+}
-- 
GitLab


From 97b29e18061fba172ca38c2b7aedb4384abb4b39 Mon Sep 17 00:00:00 2001
From: Cyrill Schumacher <cyrill@schumacher.fm>
Date: Tue, 23 Dec 2014 10:15:11 +1100
Subject: [PATCH 36/71] Feature:
 Magento\Backend\Block\Widget\Grid\Column\Renderer Currency and Price
 Renderer: use _getValue() to be able to also retrieve a calculated value
 instead of a fixed one via getData().

---
 .../Backend/Block/Widget/Grid/Column/Renderer/Currency.php      | 2 +-
 .../Magento/Backend/Block/Widget/Grid/Column/Renderer/Price.php | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Currency.php b/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Currency.php
index c20d77945b3..076ff34ceda 100644
--- a/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Currency.php
+++ b/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Currency.php
@@ -80,7 +80,7 @@ class Currency extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\Abstra
      */
     public function render(\Magento\Framework\Object $row)
     {
-        if ($data = (string)$row->getData($this->getColumn()->getIndex())) {
+        if ($data = (string)$this->_getValue($row)) {
             $currency_code = $this->_getCurrencyCode($row);
             $data = floatval($data) * $this->_getRate($row);
             $sign = (bool)(int)$this->getColumn()->getShowNumberSign() && $data > 0 ? '+' : '';
diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Price.php b/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Price.php
index e140c795860..8dc712981ef 100644
--- a/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Price.php
+++ b/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Price.php
@@ -48,7 +48,7 @@ class Price extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractR
      */
     public function render(\Magento\Framework\Object $row)
     {
-        if ($data = $row->getData($this->getColumn()->getIndex())) {
+        if ($data = $this->_getValue($row)) {
             $currencyCode = $this->_getCurrencyCode($row);
 
             if (!$currencyCode) {
-- 
GitLab


From 697c2b89dbc4a7396d53d65b3809b7192ebf2f6a Mon Sep 17 00:00:00 2001
From: Oleksandr Manchenko <omanchenko@ebay.com>
Date: Tue, 23 Dec 2014 09:56:16 +0200
Subject: [PATCH 37/71] MTA-1272: Update file iterators to work with symlinks

---
 .../Mtf/Util/Generate/Factory/AbstractFactory.php    | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/dev/tests/functional/lib/Mtf/Util/Generate/Factory/AbstractFactory.php b/dev/tests/functional/lib/Mtf/Util/Generate/Factory/AbstractFactory.php
index 9ff3fa47857..dae63661d8e 100644
--- a/dev/tests/functional/lib/Mtf/Util/Generate/Factory/AbstractFactory.php
+++ b/dev/tests/functional/lib/Mtf/Util/Generate/Factory/AbstractFactory.php
@@ -161,7 +161,10 @@ abstract class AbstractFactory
                 } else {
                     $dirIterator = new \RegexIterator(
                         new \RecursiveIteratorIterator(
-                            new \RecursiveDirectoryIterator($filePath, \FilesystemIterator::SKIP_DOTS)
+                            new \RecursiveDirectoryIterator(
+                                $filePath,
+                                \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS
+                            )
                         ),
                         '/.php$/i'
                     );
@@ -190,9 +193,10 @@ abstract class AbstractFactory
     {
         $filename = str_replace('\\', '/', $filename);
 
-        $classPath = str_replace(MTF_BP . '/' . $path . '/', '', $filename);
-        $classPath = str_replace('.php', '', $classPath);
-        $className = str_replace('/', '\\', $classPath);
+        $posTestsPath = strpos($filename, $path);
+        $posClassName = $posTestsPath + strlen($path);
+        $classPath = str_replace('.php', '', $filename);
+        $className = str_replace('/', '\\', substr($classPath, $posClassName));
 
         $reflectionClass = new \ReflectionClass($className);
         if ($reflectionClass->isAbstract()) {
-- 
GitLab


From 2150d5f5850ee0de711962bbd60b6f9b161b5591 Mon Sep 17 00:00:00 2001
From: agurzhyi <agurzhyi@ebay.com>
Date: Tue, 23 Dec 2014 10:33:18 +0200
Subject: [PATCH 38/71] MAGETWO-31784: Tax class drop-down on New Customer
 Group page should not contain value 'none'

---
 app/code/Magento/Tax/Model/TaxClass/Source/Customer.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php b/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php
index 3fd2d7ae699..e01a192bb2a 100644
--- a/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php
+++ b/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php
@@ -68,7 +68,7 @@ class Customer extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
                 ];
             }
             if (empty($options)) {
-                throw new StateException('Customer tax class cannot does not exist.');
+                throw new StateException('At least one customer tax class should be present.');
             }
             $this->_options = $options;
         }
-- 
GitLab


From 4463990fb7d55020e82c1b62e0325f7306af62dd Mon Sep 17 00:00:00 2001
From: agurzhyi <agurzhyi@ebay.com>
Date: Tue, 23 Dec 2014 11:09:51 +0200
Subject: [PATCH 39/71] MAGETWO-5713: Shopping Cart Price Rules not applying to
 configurable products based on product attributes

---
 .../Model/Rule/Condition/Product.php          | 56 +++++++-------
 .../Model/Condition/AbstractCondition.php     | 11 ++-
 .../Magento/Rule/Model/Condition/Combine.php  | 10 +--
 .../Condition/Product/AbstractProduct.php     | 32 ++++----
 .../Model/Rule/Condition/Address.php          | 14 ++--
 .../Model/Rule/Condition/Product.php          | 14 ++--
 .../Model/Rule/Condition/Product/Found.php    |  6 +-
 .../Rule/Condition/Product/Subselect.php      |  6 +-
 .../Magento/SalesRule/Model/RulesApplier.php  | 13 +++-
 .../Model/Condition/AbstractConditionTest.php | 42 +++++++++++
 .../Condition/Product/AbstractProductTest.php | 49 ++++++++++--
 .../SalesRule/Model/RulesApplierTest.php      | 75 +++++++++++++++----
 12 files changed, 236 insertions(+), 92 deletions(-)

diff --git a/app/code/Magento/CatalogRule/Model/Rule/Condition/Product.php b/app/code/Magento/CatalogRule/Model/Rule/Condition/Product.php
index 7511d2f5c0b..cb8b7786232 100644
--- a/app/code/Magento/CatalogRule/Model/Rule/Condition/Product.php
+++ b/app/code/Magento/CatalogRule/Model/Rule/Condition/Product.php
@@ -8,26 +8,29 @@
  */
 namespace Magento\CatalogRule\Model\Rule\Condition;
 
+/**
+ * Class Product
+ */
 class Product extends \Magento\Rule\Model\Condition\Product\AbstractProduct
 {
     /**
      * Validate product attribute value for condition
      *
-     * @param \Magento\Framework\Object $object
+     * @param \Magento\Framework\Model\AbstractModel $model
      * @return bool
      */
-    public function validate(\Magento\Framework\Object $object)
+    public function validate(\Magento\Framework\Model\AbstractModel $model)
     {
         $attrCode = $this->getAttribute();
         if ('category_ids' == $attrCode) {
-            return $this->validateAttribute($object->getAvailableInCategories());
+            return $this->validateAttribute($model->getAvailableInCategories());
         }
 
-        $oldAttrValue = $object->hasData($attrCode) ? $object->getData($attrCode) : null;
-        $this->_setAttributeValue($object);
+        $oldAttrValue = $model->hasData($attrCode) ? $model->getData($attrCode) : null;
+        $this->_setAttributeValue($model);
 
-        $result = $this->validateAttribute($object->getData($this->getAttribute()));
-        $this->_restoreOldAttrValue($object, $oldAttrValue);
+        $result = $this->validateAttribute($model->getData($this->getAttribute()));
+        $this->_restoreOldAttrValue($model, $oldAttrValue);
 
         return (bool)$result;
     }
@@ -35,36 +38,36 @@ class Product extends \Magento\Rule\Model\Condition\Product\AbstractProduct
     /**
      * Restore old attribute value
      *
-     * @param \Magento\Framework\Object $object
+     * @param \Magento\Framework\Model\AbstractModel $model
      * @param mixed $oldAttrValue
      * @return void
      */
-    protected function _restoreOldAttrValue($object, $oldAttrValue)
+    protected function _restoreOldAttrValue(\Magento\Framework\Model\AbstractModel $model, $oldAttrValue)
     {
         $attrCode = $this->getAttribute();
         if (is_null($oldAttrValue)) {
-            $object->unsetData($attrCode);
+            $model->unsetData($attrCode);
         } else {
-            $object->setData($attrCode, $oldAttrValue);
+            $model->setData($attrCode, $oldAttrValue);
         }
     }
 
     /**
      * Set attribute value
      *
-     * @param \Magento\Framework\Object $object
+     * @param \Magento\Framework\Model\AbstractModel $model
      * @return $this
      */
-    protected function _setAttributeValue($object)
+    protected function _setAttributeValue(\Magento\Framework\Model\AbstractModel $model)
     {
-        $storeId = $object->getStoreId();
+        $storeId = $model->getStoreId();
         $defaultStoreId = \Magento\Store\Model\Store::DEFAULT_STORE_ID;
 
-        if (!isset($this->_entityAttributeValues[$object->getId()])) {
+        if (!isset($this->_entityAttributeValues[$model->getId()])) {
             return $this;
         }
 
-        $productValues  = $this->_entityAttributeValues[$object->getId()];
+        $productValues  = $this->_entityAttributeValues[$model->getId()];
 
         if (!isset($productValues[$storeId]) && !isset($productValues[$defaultStoreId])) {
             return $this;
@@ -72,10 +75,11 @@ class Product extends \Magento\Rule\Model\Condition\Product\AbstractProduct
 
         $value = isset($productValues[$storeId]) ? $productValues[$storeId] : $productValues[$defaultStoreId];
 
-        $value = $this->_prepareDatetimeValue($value, $object);
-        $value = $this->_prepareMultiselectValue($value, $object);
+        $value = $this->_prepareDatetimeValue($value, $model);
+        $value = $this->_prepareMultiselectValue($value, $model);
+
+        $model->setData($this->getAttribute(), $value);
 
-        $object->setData($this->getAttribute(), $value);
         return $this;
     }
 
@@ -83,15 +87,16 @@ class Product extends \Magento\Rule\Model\Condition\Product\AbstractProduct
      * Prepare datetime attribute value
      *
      * @param mixed $value
-     * @param \Magento\Framework\Object $object
+     * @param \Magento\Framework\Model\AbstractModel $model
      * @return mixed
      */
-    protected function _prepareDatetimeValue($value, $object)
+    protected function _prepareDatetimeValue($value, \Magento\Framework\Model\AbstractModel $model)
     {
-        $attribute = $object->getResource()->getAttribute($this->getAttribute());
+        $attribute = $model->getResource()->getAttribute($this->getAttribute());
         if ($attribute && $attribute->getBackendType() == 'datetime') {
             $value = strtotime($value);
         }
+
         return $value;
     }
 
@@ -99,15 +104,16 @@ class Product extends \Magento\Rule\Model\Condition\Product\AbstractProduct
      * Prepare multiselect attribute value
      *
      * @param mixed $value
-     * @param \Magento\Framework\Object $object
+     * @param \Magento\Framework\Model\AbstractModel $model
      * @return mixed
      */
-    protected function _prepareMultiselectValue($value, $object)
+    protected function _prepareMultiselectValue($value, \Magento\Framework\Model\AbstractModel $model)
     {
-        $attribute = $object->getResource()->getAttribute($this->getAttribute());
+        $attribute = $model->getResource()->getAttribute($this->getAttribute());
         if ($attribute && $attribute->getFrontendInput() == 'multiselect') {
             $value = strlen($value) ? explode(',', $value) : [];
         }
+
         return $value;
     }
 }
diff --git a/app/code/Magento/Rule/Model/Condition/AbstractCondition.php b/app/code/Magento/Rule/Model/Condition/AbstractCondition.php
index 9c2987de3a3..916a1404540 100644
--- a/app/code/Magento/Rule/Model/Condition/AbstractCondition.php
+++ b/app/code/Magento/Rule/Model/Condition/AbstractCondition.php
@@ -832,12 +832,17 @@ abstract class AbstractCondition extends \Magento\Framework\Object implements Co
     }
 
     /**
-     * @param \Magento\Framework\Object $object
+     * @param \Magento\Framework\Model\AbstractModel $model
      * @return bool
      */
-    public function validate(\Magento\Framework\Object $object)
+    public function validate(\Magento\Framework\Model\AbstractModel $model)
     {
-        return $this->validateAttribute($object->getData($this->getAttribute()));
+        if (!$model->hasData($this->getAttribute())) {
+            $model->load($model->getId());
+        }
+        $attributeValue = $model->getData($this->getAttribute());
+
+        return $this->validateAttribute($attributeValue);
     }
 
     /**
diff --git a/app/code/Magento/Rule/Model/Condition/Combine.php b/app/code/Magento/Rule/Model/Condition/Combine.php
index 8e9355a4957..f565e98b548 100644
--- a/app/code/Magento/Rule/Model/Condition/Combine.php
+++ b/app/code/Magento/Rule/Model/Condition/Combine.php
@@ -316,12 +316,12 @@ class Combine extends AbstractCondition
     }
 
     /**
-     * @param \Magento\Framework\Object $object
+     * @param \Magento\Framework\Model\AbstractModel $model
      * @return bool
      */
-    public function validate(\Magento\Framework\Object $object)
+    public function validate(\Magento\Framework\Model\AbstractModel $model)
     {
-        return $this->_isValid($object);
+        return $this->_isValid($model);
     }
 
     /**
@@ -338,7 +338,7 @@ class Combine extends AbstractCondition
     /**
      * Is entity valid
      *
-     * @param int|\Magento\Framework\Object $entity
+     * @param int|\Magento\Framework\Model\AbstractModel $entity
      * @return bool
      */
     protected function _isValid($entity)
@@ -351,7 +351,7 @@ class Combine extends AbstractCondition
         $true = (bool)$this->getValue();
 
         foreach ($this->getConditions() as $cond) {
-            if ($entity instanceof \Magento\Framework\Object) {
+            if ($entity instanceof \Magento\Framework\Model\AbstractModel) {
                 $validated = $cond->validate($entity);
             } else {
                 $validated = $cond->validateByEntityId($entity);
diff --git a/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php b/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php
index 00034cf90ae..f0d4de7d40f 100644
--- a/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php
+++ b/app/code/Magento/Rule/Model/Condition/Product/AbstractProduct.php
@@ -523,50 +523,50 @@ abstract class AbstractProduct extends \Magento\Rule\Model\Condition\AbstractCon
     /**
      * Validate product attribute value for condition
      *
-     * @param \Magento\Framework\Object $object
+     * @param \Magento\Framework\Model\AbstractModel $model
      * @return bool
      */
-    public function validate(\Magento\Framework\Object $object)
+    public function validate(\Magento\Framework\Model\AbstractModel $model)
     {
         $attrCode = $this->getAttribute();
 
         if ('category_ids' == $attrCode) {
-            return $this->validateAttribute($object->getAvailableInCategories());
-        } elseif (!isset($this->_entityAttributeValues[$object->getId()])) {
-            if (!$object->getResource()) {
+            return $this->validateAttribute($model->getAvailableInCategories());
+        } elseif (!isset($this->_entityAttributeValues[$model->getId()])) {
+            if (!$model->getResource()) {
                 return false;
             }
-            $attr = $object->getResource()->getAttribute($attrCode);
+            $attr = $model->getResource()->getAttribute($attrCode);
 
             if ($attr && $attr->getBackendType() == 'datetime' && !is_int($this->getValue())) {
                 $this->setValue(strtotime($this->getValue()));
-                $value = strtotime($object->getData($attrCode));
+                $value = strtotime($model->getData($attrCode));
                 return $this->validateAttribute($value);
             }
 
             if ($attr && $attr->getFrontendInput() == 'multiselect') {
-                $value = $object->getData($attrCode);
+                $value = $model->getData($attrCode);
                 $value = strlen($value) ? explode(',', $value) : [];
                 return $this->validateAttribute($value);
             }
 
-            return parent::validate($object);
+            return parent::validate($model);
         } else {
             $result = false;
             // any valid value will set it to TRUE
             // remember old attribute state
-            $oldAttrValue = $object->hasData($attrCode) ? $object->getData($attrCode) : null;
+            $oldAttrValue = $model->hasData($attrCode) ? $model->getData($attrCode) : null;
 
-            foreach ($this->_entityAttributeValues[$object->getId()] as $value) {
-                $attr = $object->getResource()->getAttribute($attrCode);
+            foreach ($this->_entityAttributeValues[$model->getId()] as $value) {
+                $attr = $model->getResource()->getAttribute($attrCode);
                 if ($attr && $attr->getBackendType() == 'datetime') {
                     $value = strtotime($value);
                 } elseif ($attr && $attr->getFrontendInput() == 'multiselect') {
                     $value = strlen($value) ? explode(',', $value) : [];
                 }
 
-                $object->setData($attrCode, $value);
-                $result |= parent::validate($object);
+                $model->setData($attrCode, $value);
+                $result |= parent::validate($model);
 
                 if ($result) {
                     break;
@@ -574,9 +574,9 @@ abstract class AbstractProduct extends \Magento\Rule\Model\Condition\AbstractCon
             }
 
             if (is_null($oldAttrValue)) {
-                $object->unsetData($attrCode);
+                $model->unsetData($attrCode);
             } else {
-                $object->setData($attrCode, $oldAttrValue);
+                $model->setData($attrCode, $oldAttrValue);
             }
 
             return (bool)$result;
diff --git a/app/code/Magento/SalesRule/Model/Rule/Condition/Address.php b/app/code/Magento/SalesRule/Model/Rule/Condition/Address.php
index 49983011229..5589be55402 100644
--- a/app/code/Magento/SalesRule/Model/Rule/Condition/Address.php
+++ b/app/code/Magento/SalesRule/Model/Rule/Condition/Address.php
@@ -160,22 +160,22 @@ class Address extends \Magento\Rule\Model\Condition\AbstractCondition
     /**
      * Validate Address Rule Condition
      *
-     * @param \Magento\Framework\Object $object
+     * @param \Magento\Framework\Model\AbstractModel $model
      * @return bool
      */
-    public function validate(\Magento\Framework\Object $object)
+    public function validate(\Magento\Framework\Model\AbstractModel $model)
     {
-        $address = $object;
+        $address = $model;
         if (!$address instanceof \Magento\Sales\Model\Quote\Address) {
-            if ($object->getQuote()->isVirtual()) {
-                $address = $object->getQuote()->getBillingAddress();
+            if ($model->getQuote()->isVirtual()) {
+                $address = $model->getQuote()->getBillingAddress();
             } else {
-                $address = $object->getQuote()->getShippingAddress();
+                $address = $model->getQuote()->getShippingAddress();
             }
         }
 
         if ('payment_method' == $this->getAttribute() && !$address->hasPaymentMethod()) {
-            $address->setPaymentMethod($object->getQuote()->getPayment()->getMethod());
+            $address->setPaymentMethod($model->getQuote()->getPayment()->getMethod());
         }
 
         return parent::validate($address);
diff --git a/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php b/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php
index 9b614b59ae3..2f4fcbf7c0a 100644
--- a/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php
+++ b/app/code/Magento/SalesRule/Model/Rule/Condition/Product.php
@@ -28,24 +28,24 @@ class Product extends \Magento\Rule\Model\Condition\Product\AbstractProduct
     /**
      * Validate Product Rule Condition
      *
-     * @param \Magento\Framework\Object $object
+     * @param \Magento\Framework\Model\AbstractModel $model
      * @return bool
      */
-    public function validate(\Magento\Framework\Object $object)
+    public function validate(\Magento\Framework\Model\AbstractModel $model)
     {
         //@todo reimplement this method when is fixed MAGETWO-5713
         /** @var \Magento\Catalog\Model\Product $product */
-        $product = $object->getProduct();
+        $product = $model->getProduct();
         if (!$product instanceof \Magento\Catalog\Model\Product) {
-            $product = $this->productRepository->getById($object->getProductId());
+            $product = $this->productRepository->getById($model->getProductId());
         }
 
         $product->setQuoteItemQty(
-            $object->getQty()
+            $model->getQty()
         )->setQuoteItemPrice(
-            $object->getPrice() // possible bug: need to use $object->getBasePrice()
+            $model->getPrice() // possible bug: need to use $model->getBasePrice()
         )->setQuoteItemRowTotal(
-            $object->getBaseRowTotal()
+            $model->getBaseRowTotal()
         );
 
         return parent::validate($product);
diff --git a/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Found.php b/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Found.php
index c36ee4671e1..bea0defa401 100644
--- a/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Found.php
+++ b/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Found.php
@@ -52,15 +52,15 @@ class Found extends \Magento\SalesRule\Model\Rule\Condition\Product\Combine
     /**
      * Validate
      *
-     * @param \Magento\Framework\Object $object Quote
+     * @param \Magento\Framework\Model\AbstractModel $model
      * @return bool
      */
-    public function validate(\Magento\Framework\Object $object)
+    public function validate(\Magento\Framework\Model\AbstractModel $model)
     {
         $all = $this->getAggregator() === 'all';
         $true = (bool)$this->getValue();
         $found = false;
-        foreach ($object->getAllItems() as $item) {
+        foreach ($model->getAllItems() as $item) {
             $found = $all;
             foreach ($this->getConditions() as $cond) {
                 $validated = $cond->validate($item);
diff --git a/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Subselect.php b/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Subselect.php
index 59a5455e96b..08f75032598 100644
--- a/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Subselect.php
+++ b/app/code/Magento/SalesRule/Model/Rule/Condition/Product/Subselect.php
@@ -133,17 +133,17 @@ class Subselect extends \Magento\SalesRule\Model\Rule\Condition\Product\Combine
     /**
      * Validate
      *
-     * @param \Magento\Framework\Object $object Quote
+     * @param \Magento\Framework\Model\AbstractModel $model
      * @return bool
      */
-    public function validate(\Magento\Framework\Object $object)
+    public function validate(\Magento\Framework\Model\AbstractModel $model)
     {
         if (!$this->getConditions()) {
             return false;
         }
         $attr = $this->getAttribute();
         $total = 0;
-        foreach ($object->getQuote()->getAllVisibleItems() as $item) {
+        foreach ($model->getQuote()->getAllVisibleItems() as $item) {
             if (parent::validate($item)) {
                 $total += $item->getData($attr);
             }
diff --git a/app/code/Magento/SalesRule/Model/RulesApplier.php b/app/code/Magento/SalesRule/Model/RulesApplier.php
index f7bde08d44e..4dace1d8f8d 100644
--- a/app/code/Magento/SalesRule/Model/RulesApplier.php
+++ b/app/code/Magento/SalesRule/Model/RulesApplier.php
@@ -59,7 +59,18 @@ class RulesApplier
             }
 
             if (!$skipValidation && !$rule->getActions()->validate($item)) {
-                continue;
+                $childItems = $item->getChildren();
+                $isContinue = true;
+                if (!empty($childItems)) {
+                    foreach ($childItems as $childItem) {
+                        if ($rule->getActions()->validate($childItem)) {
+                            $isContinue = false;
+                        }
+                    }
+                }
+                if ($isContinue) {
+                    continue;
+                }
             }
 
             $this->applyRule($item, $rule, $address, $couponCode);
diff --git a/dev/tests/unit/testsuite/Magento/Rule/Model/Condition/AbstractConditionTest.php b/dev/tests/unit/testsuite/Magento/Rule/Model/Condition/AbstractConditionTest.php
index ba41ccae4d4..9d1f9f3ac6f 100644
--- a/dev/tests/unit/testsuite/Magento/Rule/Model/Condition/AbstractConditionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Rule/Model/Condition/AbstractConditionTest.php
@@ -106,6 +106,48 @@ class AbstractConditionTest extends \PHPUnit_Framework_TestCase
         );
     }
 
+    /**
+     * @param $existingValue
+     * @param $operator
+     * @param $valueForValidate
+     * @param $expectedResult
+     *
+     * @dataProvider validateAttributeDataProvider
+     */
+    public function testValidate($existingValue, $operator, $valueForValidate, $expectedResult)
+    {
+        $objectMock = $this->getMock(
+            'Magento\Framework\Model\AbstractModel',
+            ['hasData', 'load', 'getId', 'getData'],
+            [],
+            '',
+            false
+        );
+        $objectMock->expects($this->once())
+            ->method('hasData')
+            ->willReturn(false);
+        $objectMock->expects($this->once())
+            ->method('getId')
+            ->willReturn(7);
+        $objectMock->expects($this->once())
+            ->method('load')
+            ->with(7);
+        $objectMock->expects($this->once())
+            ->method('getData')
+            ->willReturn($valueForValidate);
+
+        $this->_condition->setOperator($operator);
+        $this->_condition->setData('value_parsed', $existingValue);
+        $this->assertEquals(
+            $expectedResult,
+            $this->_condition->validate($objectMock),
+            "Failed asserting that "
+            . var_export($existingValue, true)
+            . $operator
+            . var_export($valueForValidate, true)
+        );
+    }
+
     public function validateAttributeArrayInputTypeDataProvider()
     {
         return [
diff --git a/dev/tests/unit/testsuite/Magento/Rule/Model/Condition/Product/AbstractProductTest.php b/dev/tests/unit/testsuite/Magento/Rule/Model/Condition/Product/AbstractProductTest.php
index 97289d77f05..93ad5f6f97d 100644
--- a/dev/tests/unit/testsuite/Magento/Rule/Model/Condition/Product/AbstractProductTest.php
+++ b/dev/tests/unit/testsuite/Magento/Rule/Model/Condition/Product/AbstractProductTest.php
@@ -55,7 +55,7 @@ class AbstractProductTest extends \PHPUnit_Framework_TestCase
 
     public function testValidateAttributeEqualCategoryId()
     {
-        $product = $this->getMock('\Magento\Framework\Object', ["getAttribute"], [], '', false);
+        $product = $this->getMock('Magento\Framework\Model\AbstractModel', ["getAttribute"], [], '', false);
         $this->_condition->setAttribute('category_ids');
         $product->setAvailableInCategories(new \Magento\Framework\Object());
         $this->assertFalse($this->_condition->validate($product));
@@ -63,7 +63,16 @@ class AbstractProductTest extends \PHPUnit_Framework_TestCase
 
     public function testValidateEmptyEntityAttributeValues()
     {
-        $product = $this->getMock('\Magento\Framework\Object', ["getAttribute"], [], '', false);
+        $product = $this->getMock(
+            'Magento\Framework\Model\AbstractModel',
+            ["getAttribute", 'getResource'],
+            [],
+            '',
+            false
+        );
+        $product->expects($this->once())
+            ->method('getResource')
+            ->willReturn(null);
         $product->setId(1);
         $configProperty = new \ReflectionProperty(
             'Magento\Rule\Model\Condition\Product\AbstractProduct',
@@ -76,7 +85,13 @@ class AbstractProductTest extends \PHPUnit_Framework_TestCase
 
     public function testValidateEmptyEntityAttributeValuesWithResource()
     {
-        $product = $this->getMock('\Magento\Framework\Object', ["getAttribute"], [], '', false);
+        $product = $this->getMock(
+            'Magento\Framework\Model\AbstractModel',
+            ["getAttribute", 'getResource'],
+            [],
+            '',
+            false
+        );
         $product->setId(1);
         $time = '04/19/2012 11:59 am';
         $product->setData('someAttribute', $time);
@@ -103,8 +118,10 @@ class AbstractProductTest extends \PHPUnit_Framework_TestCase
             ->with('someAttribute')
             ->will($this->returnValue($attribute));
         $newResource->_config = $this->getMock('Magento\Eav\Model\Config', [], [], '', false);
+        $product->expects($this->atLeastOnce())
+            ->method('getResource')
+            ->willReturn($newResource);
 
-        $product->setResource($newResource);
         $this->assertFalse($this->_condition->validate($product));
 
         $product->setData('someAttribute', 'option1,option2,option3');
@@ -125,7 +142,13 @@ class AbstractProductTest extends \PHPUnit_Framework_TestCase
     public function testValidateSetEntityAttributeValuesWithResource()
     {
         $this->_condition->setAttribute('someAttribute');
-        $product = $this->getMock('\Magento\Framework\Object', ['getAttribute'], [], '', false);
+        $product = $this->getMock(
+            'Magento\Framework\Model\AbstractModel',
+            ['getAttribute', 'getResource'],
+            [],
+            '',
+            false
+        );
         $product->setAtribute('attribute');
         $product->setId(12);
 
@@ -146,7 +169,9 @@ class AbstractProductTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue($attribute));
         $newResource->_config = $this->getMock('Magento\Eav\Model\Config', [], [], '', false);
 
-        $product->setResource($newResource);
+        $product->expects($this->atLeastOnce())
+            ->method('getResource')
+            ->willReturn($newResource);
 
         $this->_entityAttributeValuesProperty->setValue(
             $this->_condition,
@@ -161,7 +186,13 @@ class AbstractProductTest extends \PHPUnit_Framework_TestCase
 
     public function testValidateSetEntityAttributeValuesWithoutResource()
     {
-        $product = $this->getMock('\Magento\Framework\Object', ['someMethod'], [], '', false);
+        $product = $this->getMock(
+            'Magento\Framework\Model\AbstractModel',
+            ['someMethod', 'getResource', 'load'],
+            [],
+            '',
+            false
+        );
         $this->_condition->setAttribute('someAttribute');
         $product->setAtribute('attribute');
         $product->setId(12);
@@ -198,7 +229,9 @@ class AbstractProductTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue($attribute));
         $newResource->_config = $this->getMock('Magento\Eav\Model\Config', [], [], '', false);
 
-        $product->setResource($newResource);
+        $product->expects($this->atLeastOnce())
+            ->method('getResource')
+            ->willReturn($newResource);
 
         $this->_entityAttributeValuesProperty->setValue(
             $this->_condition,
diff --git a/dev/tests/unit/testsuite/Magento/SalesRule/Model/RulesApplierTest.php b/dev/tests/unit/testsuite/Magento/SalesRule/Model/RulesApplierTest.php
index bc875f4835b..200e619dbfc 100644
--- a/dev/tests/unit/testsuite/Magento/SalesRule/Model/RulesApplierTest.php
+++ b/dev/tests/unit/testsuite/Magento/SalesRule/Model/RulesApplierTest.php
@@ -58,10 +58,16 @@ class RulesApplierTest extends \PHPUnit_Framework_TestCase
         );
     }
 
-    public function testApplyRulesWhenRuleWithStopRulesProcessingIsUsed()
+    /**
+     * @param bool $isChildren
+     * @param bool $isContinue
+     *
+     * @dataProvider dataProviderChildren
+     */
+    public function testApplyRulesWhenRuleWithStopRulesProcessingIsUsed($isChildren, $isContinue)
     {
         $positivePrice = 1;
-        $skipValidation = true;
+        $skipValidation = false;
         $item = $this->getPreparedItem();
         $couponCode = 111;
 
@@ -73,7 +79,7 @@ class RulesApplierTest extends \PHPUnit_Framework_TestCase
          */
         $ruleWithStopFurtherProcessing = $this->getMock(
             'Magento\SalesRule\Model\Rule',
-            ['getStoreLabel', 'getCouponType', 'getRuleId', '__wakeup'],
+            ['getStoreLabel', 'getCouponType', 'getRuleId', '__wakeup', 'getActions'],
             [],
             '',
             false
@@ -87,6 +93,14 @@ class RulesApplierTest extends \PHPUnit_Framework_TestCase
             false
         );
 
+        $actionMock = $this->getMock(
+            'Magento\Rule\Model\Action\Collection',
+            ['validate'],
+            [],
+            '',
+            false
+        );
+
         $ruleWithStopFurtherProcessing->setName('ruleWithStopFurtherProcessing');
         $ruleThatShouldNotBeRun->setName('ruleThatShouldNotBeRun');
         $rules = [$ruleWithStopFurtherProcessing, $ruleThatShouldNotBeRun];
@@ -96,20 +110,52 @@ class RulesApplierTest extends \PHPUnit_Framework_TestCase
 
         $this->validatorUtility->expects($this->atLeastOnce())
             ->method('canProcessRule')
-            ->will(
-                $this->returnValue(true)
-            );
-        $ruleWithStopFurtherProcessing->expects($this->any())
-            ->method('getRuleId')
-            ->will($this->returnValue($ruleId));
-        $this->applyRule($item, $ruleWithStopFurtherProcessing);
-        $ruleWithStopFurtherProcessing->setStopRulesProcessing(true);
-        $ruleThatShouldNotBeRun->expects($this->never())
-            ->method('getStopRulesProcessing');
+            ->will($this->returnValue(true));
+
+        $ruleWithStopFurtherProcessing->expects($this->atLeastOnce())
+            ->method('getActions')
+            ->willReturn($actionMock);
+        $actionMock->expects($this->at(0))
+            ->method('validate')
+            ->with($item)
+            ->willReturn(!$isChildren);
+
+        // if there are child elements, check them
+        if ($isChildren) {
+            $item->expects($this->atLeastOnce())
+                ->method('getChildren')
+                ->willReturn([$item]);
+            $actionMock->expects($this->at(1))
+                ->method('validate')
+                ->with($item)
+                ->willReturn(!$isContinue);
+        }
+
+        //
+        if (!$isContinue || !$isChildren) {
+            $ruleWithStopFurtherProcessing->expects($this->any())
+                ->method('getRuleId')
+                ->will($this->returnValue($ruleId));
+
+            $this->applyRule($item, $ruleWithStopFurtherProcessing);
+
+            $ruleWithStopFurtherProcessing->setStopRulesProcessing(true);
+            $ruleThatShouldNotBeRun->expects($this->never())
+                ->method('getStopRulesProcessing');
+        }
+
         $result = $this->rulesApplier->applyRules($item, $rules, $skipValidation, $couponCode);
         $this->assertEquals($appliedRuleIds, $result);
     }
 
+    public function dataProviderChildren()
+    {
+        return [
+            ['isChildren' => true, 'isContinue' => false],
+            ['isChildren' => false, 'isContinue' => true],
+        ];
+    }
+
     /**
      * @return \Magento\Sales\Model\Quote\Item\AbstractItem|\PHPUnit_Framework_MockObject_MockObject
      */
@@ -137,7 +183,8 @@ class RulesApplierTest extends \PHPUnit_Framework_TestCase
                 'setDiscountPercent',
                 'getAddress',
                 'setAppliedRuleIds',
-                '__wakeup'
+                '__wakeup',
+                'getChildren'
             ],
             [],
             '',
-- 
GitLab


From 588314dba8708f24f31feb265df494f0c1c3dff3 Mon Sep 17 00:00:00 2001
From: Andriy Nasinnyk <anasinnyk@ebay.com>
Date: Tue, 23 Dec 2014 12:00:43 +0200
Subject: [PATCH 40/71] MAGETWO-13915: PSR-3: common interface for logging
 libraries.

---
 app/code/Magento/Payment/Model/Method/AbstractMethod.php       | 3 +++
 .../Integration/Service/V1/AuthorizationServiceTest.php        | 2 +-
 lib/internal/Magento/Framework/Logger/Handler/System.php       | 1 +
 lib/internal/Magento/Framework/Logger/README.md                | 3 +++
 4 files changed, 8 insertions(+), 1 deletion(-)
 create mode 100644 lib/internal/Magento/Framework/Logger/README.md

diff --git a/app/code/Magento/Payment/Model/Method/AbstractMethod.php b/app/code/Magento/Payment/Model/Method/AbstractMethod.php
index ba16262cbb2..70ef8ea29f3 100644
--- a/app/code/Magento/Payment/Model/Method/AbstractMethod.php
+++ b/app/code/Magento/Payment/Model/Method/AbstractMethod.php
@@ -196,6 +196,9 @@ abstract class AbstractMethod extends \Magento\Framework\Object implements Metho
      */
     protected $_eventManager;
 
+    /**
+     * @var \Psr\Log\LoggerInterface
+     */
     protected $logger;
 
     /**
diff --git a/dev/tests/integration/testsuite/Magento/Integration/Service/V1/AuthorizationServiceTest.php b/dev/tests/integration/testsuite/Magento/Integration/Service/V1/AuthorizationServiceTest.php
index 11217c53e37..7192622e0c5 100644
--- a/dev/tests/integration/testsuite/Magento/Integration/Service/V1/AuthorizationServiceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Integration/Service/V1/AuthorizationServiceTest.php
@@ -25,7 +25,7 @@ class AuthorizationServiceTest extends \PHPUnit_Framework_TestCase
     {
         parent::setUp();
         $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-        $loggerMock = $this->getMockBuilder('Magento\\Framework\\Logger')->disableOriginalConstructor()->getMock();
+        $loggerMock = $this->getMockBuilder('Psr\\Log\\LoggerInterface')->disableOriginalConstructor()->getMock();
         $loggerMock->expects($this->any())->method('critical')->will($this->returnSelf());
         $this->_service = $objectManager->create(
             'Magento\Integration\Service\V1\AuthorizationService',
diff --git a/lib/internal/Magento/Framework/Logger/Handler/System.php b/lib/internal/Magento/Framework/Logger/Handler/System.php
index d836d7df376..6bc2157a558 100644
--- a/lib/internal/Magento/Framework/Logger/Handler/System.php
+++ b/lib/internal/Magento/Framework/Logger/Handler/System.php
@@ -39,6 +39,7 @@ class System extends StreamHandler
      * @{inerhitDoc}
      *
      * @param $record array
+     * @return void
      */
     public function write(array $record)
     {
diff --git a/lib/internal/Magento/Framework/Logger/README.md b/lib/internal/Magento/Framework/Logger/README.md
new file mode 100644
index 00000000000..2d2b0410de1
--- /dev/null
+++ b/lib/internal/Magento/Framework/Logger/README.md
@@ -0,0 +1,3 @@
+# Logger
+
+**Logger** provides a standard mechanism to log to system and error logs.
-- 
GitLab


From 738d3755edf9064cc4eed43defb866a89b4e4346 Mon Sep 17 00:00:00 2001
From: Maxim Medinskiy <mmedinskiy@ebay.com>
Date: Tue, 23 Dec 2014 12:17:54 +0200
Subject: [PATCH 41/71] MAGETWO-32095: Modify .gitignore CE according to new
 repos structure

---
 dev/tests/functional/.gitignore | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/dev/tests/functional/.gitignore b/dev/tests/functional/.gitignore
index f12c1a57910..d3b32c5f1d4 100755
--- a/dev/tests/functional/.gitignore
+++ b/dev/tests/functional/.gitignore
@@ -3,6 +3,9 @@
 /generated
 /var
 /config/*
-!/config/*.dist
+!/config/application.yml.dist
+!/config/handler.yml.dist
+!/config/isolation.yml.dist
+!/config/server.yml.dist
 phpunit.xml
 /lib/Mtf/Util/Generate/testcase.xml
-- 
GitLab


From b3ac09acbc2f5e125566d43c4b6311a16a79e8b6 Mon Sep 17 00:00:00 2001
From: Andriy Nasinnyk <anasinnyk@ebay.com>
Date: Tue, 23 Dec 2014 12:38:52 +0200
Subject: [PATCH 42/71] MAGETWO-13915: PSR-3: common interface for logging
 libraries.

---
 composer.lock | 112 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 111 insertions(+), 1 deletion(-)

diff --git a/composer.lock b/composer.lock
index 7cb7c6f857a..3aa9ff55893 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "cf88c5db8e11255eb97498f788609028",
+    "hash": "25a2a2ff9de53c394a797011b0f84855",
     "packages": [
         {
             "name": "composer/composer",
@@ -178,6 +178,116 @@
             ],
             "time": "2014-12-12 15:28:16"
         },
+        {
+            "name": "monolog/monolog",
+            "version": "1.11.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Seldaek/monolog.git",
+                "reference": "ec3961874c43840e96da3a8a1ed20d8c73d7e5aa"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/ec3961874c43840e96da3a8a1ed20d8c73d7e5aa",
+                "reference": "ec3961874c43840e96da3a8a1ed20d8c73d7e5aa",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0",
+                "psr/log": "~1.0"
+            },
+            "provide": {
+                "psr/log-implementation": "1.0.0"
+            },
+            "require-dev": {
+                "aws/aws-sdk-php": "~2.4, >2.4.8",
+                "doctrine/couchdb": "~1.0@dev",
+                "graylog2/gelf-php": "~1.0",
+                "phpunit/phpunit": "~3.7.0",
+                "raven/raven": "~0.5",
+                "ruflin/elastica": "0.90.*",
+                "videlalvaro/php-amqplib": "~2.4"
+            },
+            "suggest": {
+                "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
+                "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
+                "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
+                "ext-mongo": "Allow sending log messages to a MongoDB server",
+                "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
+                "raven/raven": "Allow sending log messages to a Sentry server",
+                "rollbar/rollbar": "Allow sending log messages to Rollbar",
+                "ruflin/elastica": "Allow sending log messages to an Elastic Search server",
+                "videlalvaro/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.11.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Monolog\\": "src/Monolog"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be",
+                    "homepage": "http://seld.be"
+                }
+            ],
+            "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
+            "homepage": "http://github.com/Seldaek/monolog",
+            "keywords": [
+                "log",
+                "logging",
+                "psr-3"
+            ],
+            "time": "2014-09-30 13:30:58"
+        },
+        {
+            "name": "psr/log",
+            "version": "1.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/log.git",
+                "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
+                "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
+                "shasum": ""
+            },
+            "type": "library",
+            "autoload": {
+                "psr-0": {
+                    "Psr\\Log\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for logging libraries",
+            "keywords": [
+                "log",
+                "psr",
+                "psr-3"
+            ],
+            "time": "2012-12-21 11:40:51"
+        },
         {
             "name": "seld/jsonlint",
             "version": "1.3.0",
-- 
GitLab


From 6fabce0c69fb9fc87d99f65e377324a984b436ab Mon Sep 17 00:00:00 2001
From: Andriy Nasinnyk <anasinnyk@ebay.com>
Date: Tue, 23 Dec 2014 14:35:42 +0200
Subject: [PATCH 43/71] MAGETWO-13915: PSR-3: common interface for logging
 libraries.

---
 app/etc/di.xml                                       |  4 ++--
 .../Magento/TestFramework/ErrorLog/Logger.php        |  2 +-
 lib/internal/Magento/Framework/Logger/Monolog.php    | 12 ++++++++++++
 3 files changed, 15 insertions(+), 3 deletions(-)
 create mode 100644 lib/internal/Magento/Framework/Logger/Monolog.php

diff --git a/app/etc/di.xml b/app/etc/di.xml
index 6d5a7d369ec..c5259bd3c87 100644
--- a/app/etc/di.xml
+++ b/app/etc/di.xml
@@ -5,7 +5,7 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
-    <preference for="Psr\Log\LoggerInterface" type="Monolog\Logger" />
+    <preference for="Psr\Log\LoggerInterface" type="Magento\Framework\Logger\Monolog" />
     <preference for="Magento\Framework\ObjectManager\FactoryInterface" type="Magento\Framework\ObjectManager\Factory\Dynamic\Developer" />
     <preference for="Magento\Framework\Search\Adapter\Mysql\Filter\PreprocessorInterface" type="Magento\Framework\Search\Adapter\Mysql\Filter\Preprocessor" />
     <preference for="Magento\Framework\Search\Adapter\Mysql\Field\ResolverInterface" type="Magento\Framework\Search\Adapter\Mysql\Field\Resolver" />
@@ -91,7 +91,7 @@
             <argument name="filesystem" xsi:type="object">Magento\Framework\Filesystem\Driver\File</argument>
         </arguments>
     </type>
-    <type name="Monolog\Logger">
+    <type name="Magento\Framework\Logger\Monolog">
         <arguments>
             <argument name="name" xsi:type="string">main</argument>
             <argument name="handlers"  xsi:type="array">
diff --git a/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Logger.php b/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Logger.php
index 842d3ffe563..d548626cee8 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Logger.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/ErrorLog/Logger.php
@@ -4,7 +4,7 @@
  */
 namespace Magento\TestFramework\ErrorLog;
 
-class Logger extends \Monolog\Logger
+class Logger extends \Magento\Framework\Logger\Monolog
 {
     /** @var array */
     protected $messages = [];
diff --git a/lib/internal/Magento/Framework/Logger/Monolog.php b/lib/internal/Magento/Framework/Logger/Monolog.php
new file mode 100644
index 00000000000..304528bf4c9
--- /dev/null
+++ b/lib/internal/Magento/Framework/Logger/Monolog.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Framework\Logger;
+
+use Monolog\Logger;
+
+class Monolog extends Logger
+{
+}
-- 
GitLab


From 3fd6206fb144b9e314660f7a9f7c0878cb86731b Mon Sep 17 00:00:00 2001
From: Oleksandr Rykh <orykh@ebay.com>
Date: Tue, 23 Dec 2014 15:41:13 +0200
Subject: [PATCH 44/71] MTA-743: Test names of MTF Corpuscular tests are
 displayed not correctly in parallel mode on bamboo

---
 dev/tests/functional/phpunit.xml.dist | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/dev/tests/functional/phpunit.xml.dist b/dev/tests/functional/phpunit.xml.dist
index 3cfdfc5ccbd..e480294de2a 100755
--- a/dev/tests/functional/phpunit.xml.dist
+++ b/dev/tests/functional/phpunit.xml.dist
@@ -25,6 +25,7 @@
             </arguments>
         </listener>
         <listener class="Mtf\System\Event\StateListener" />
+        <listener class="Mtf\System\JUnit"/>
     </listeners>
 
     <php>
@@ -38,6 +39,7 @@
         <env name="log_directory" value="var/log" />
         <env name="events_preset" value="base" />
         <env name="module_whitelist" value="Magento_Install" />
+        <env name="report_file_name" value="test-cases-report.xml"/>
     </php>
 
 </phpunit>
-- 
GitLab


From a32b444c9d02ab8f3985ff266ccfe9432756a848 Mon Sep 17 00:00:00 2001
From: agurzhyi <agurzhyi@ebay.com>
Date: Tue, 23 Dec 2014 15:59:47 +0200
Subject: [PATCH 45/71] MAGETWO-27636: Persistent Shopping Cart: 'Not
 %Username%?' link is displayed during page load for user logged in

---
 app/code/Magento/Persistent/etc/module.xml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/app/code/Magento/Persistent/etc/module.xml b/app/code/Magento/Persistent/etc/module.xml
index 0a201d7d4ef..bc37874917d 100644
--- a/app/code/Magento/Persistent/etc/module.xml
+++ b/app/code/Magento/Persistent/etc/module.xml
@@ -7,6 +7,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
     <module name="Magento_Persistent" schema_version="2.0.0">
         <sequence>
+            <module name="Magento_PageCache"/>
             <module name="Magento_Checkout"/>
         </sequence>
     </module>
-- 
GitLab


From a6a3417a85b831e5db1d6c8316202541f3c951ee Mon Sep 17 00:00:00 2001
From: agurzhyi <agurzhyi@ebay.com>
Date: Tue, 23 Dec 2014 16:36:16 +0200
Subject: [PATCH 46/71] MAGETWO-31784: Tax class drop-down on New Customer
 Group page should not contain value 'none'

---
 app/code/Magento/Tax/Model/TaxClass/Source/Customer.php   | 3 ---
 .../Magento/Tax/Model/TaxClass/Source/CustomerTest.php    | 8 ++------
 2 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php b/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php
index e01a192bb2a..7033763324e 100644
--- a/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php
+++ b/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php
@@ -67,9 +67,6 @@ class Customer extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
                     'label' => $taxClass->getClassName(),
                 ];
             }
-            if (empty($options)) {
-                throw new StateException('At least one customer tax class should be present.');
-            }
             $this->_options = $options;
         }
 
diff --git a/dev/tests/unit/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php b/dev/tests/unit/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php
index 4ccee7bf5b7..2787e1c44c5 100644
--- a/dev/tests/unit/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php
+++ b/dev/tests/unit/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php
@@ -164,11 +164,7 @@ class CustomerTest extends \PHPUnit_Framework_TestCase
                 ->method('getItems')
                 ->willReturn($items);
             // checking exception
-            try {
-                $this->customer->getAllOptions();
-            } catch (\Exception $e) {
-                $this->assertInstanceOf('Magento\Framework\Exception\StateException', $e);
-            }
+            $this->assertEmpty($this->customer->getAllOptions());
         }
     }
 
@@ -181,7 +177,7 @@ class CustomerTest extends \PHPUnit_Framework_TestCase
     {
         return [
             ['isEmpty' => false, 'expected' => [['value' => 10, 'label' => 'class-name']]],
-            ['isEmpty' => true, 'expected' => [['value' => '0', 'label' => __('None')]]]
+            ['isEmpty' => true, 'expected' => []]
         ];
     }
 }
-- 
GitLab


From 0ecb9168718fd74db5e6dcdff5e4e8cb54ef4988 Mon Sep 17 00:00:00 2001
From: agurzhyi <agurzhyi@ebay.com>
Date: Tue, 23 Dec 2014 16:39:36 +0200
Subject: [PATCH 47/71] MAGETWO-27636: Persistent Shopping Cart: 'Not
 %Username%?' link is displayed during page load for user logged in

---
 app/code/Magento/Persistent/etc/module.xml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/app/code/Magento/Persistent/etc/module.xml b/app/code/Magento/Persistent/etc/module.xml
index bc37874917d..0a201d7d4ef 100644
--- a/app/code/Magento/Persistent/etc/module.xml
+++ b/app/code/Magento/Persistent/etc/module.xml
@@ -7,7 +7,6 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
     <module name="Magento_Persistent" schema_version="2.0.0">
         <sequence>
-            <module name="Magento_PageCache"/>
             <module name="Magento_Checkout"/>
         </sequence>
     </module>
-- 
GitLab


From c9a320b9e938a8ffe7419a7eaa111953d81284ad Mon Sep 17 00:00:00 2001
From: agurzhyi <agurzhyi@ebay.com>
Date: Tue, 23 Dec 2014 16:58:51 +0200
Subject: [PATCH 48/71] MAGETWO-31634: 'Credit Memo' button is absent on
 Invoice page for Authorize.net

---
 app/code/Magento/Sales/Model/Order.php        |  2 +-
 .../Magento/Sales/Model/OrderTest.php         | 83 ++++++++++++++++++-
 2 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php
index 540409a35ba..89e8ca8befb 100644
--- a/app/code/Magento/Sales/Model/Order.php
+++ b/app/code/Magento/Sales/Model/Order.php
@@ -3389,7 +3389,7 @@ class Order extends AbstractModel implements EntityInterface, ApiOrderInterface
         if ($this->getData(ApiOrderInterface::STATUS_HISTORIES) == null) {
             $this->setData(
                 ApiOrderInterface::STATUS_HISTORIES,
-                $this->getPaymentsCollection()->getItems()
+                $this->getStatusHistoryCollection()->getItems()
             );
         }
         return $this->getData(ApiOrderInterface::STATUS_HISTORIES);
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/OrderTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/OrderTest.php
index 17e91454fa8..6af26f5a816 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Model/OrderTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/OrderTest.php
@@ -4,6 +4,8 @@
  */
 namespace Magento\Sales\Model;
 
+use Magento\Sales\Model\Resource\Order\Status\History\CollectionFactory as HistoryCollectionFactory;
+
 /**
  * Test class for \Magento\Sales\Model\Order
  */
@@ -39,6 +41,11 @@ class OrderTest extends \PHPUnit_Framework_TestCase
      */
     protected $item;
 
+    /**
+     * @var HistoryCollectionFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $historyCollectionFactoryMock;
+
     protected function setUp()
     {
         $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
@@ -56,6 +63,13 @@ class OrderTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
+        $this->historyCollectionFactoryMock = $this->getMock(
+            'Magento\Sales\Model\Resource\Order\Status\History\CollectionFactory',
+            ['create'],
+            [],
+            '',
+            false
+        );
         $this->item = $this->getMock(
             'Magento\Sales\Model\Resource\Order\Item',
             ['isDeleted', 'getQtyToInvoice', 'getParentItemId', 'getQuoteItemId'],
@@ -87,7 +101,8 @@ class OrderTest extends \PHPUnit_Framework_TestCase
                 'paymentCollectionFactory' => $this->paymentCollectionFactoryMock,
                 'orderItemCollectionFactory' => $this->orderItemCollectionFactoryMock,
                 'data' => ['increment_id' => $this->incrementId],
-                'context' => $context
+                'context' => $context,
+                'historyCollectionFactory' => $this->historyCollectionFactoryMock
             ]
         );
     }
@@ -484,4 +499,70 @@ class OrderTest extends \PHPUnit_Framework_TestCase
     {
         $this->assertEquals('order', $this->order->getEntityType());
     }
+
+    /**
+     * Run test getStatusHistories method
+     *
+     * @return void
+     */
+    public function testGetStatusHistories()
+    {
+        $itemMock = $this->getMockForAbstractClass(
+            'Magento\Sales\Api\Data\OrderStatusHistoryInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['setOrder']
+        );
+        $dbMock = $this->getMock(
+            'Magento\Framework\Data\Collection\Db',
+            ['setOrder'],
+            [],
+            '',
+            false
+        );
+        $collectionMock = $this->getMock(
+            'Magento\Sales\Model\Resource\Order\Status\History\Collection',
+            [
+                'setOrderFilter',
+                'setOrder',
+                'getItems',
+                'getIterator',
+                'toOptionArray',
+                'count',
+                'load'
+            ],
+            [],
+            '',
+            false
+        );
+
+        $collectionItems = [$itemMock];
+
+        $collectionMock->expects($this->once())
+            ->method('setOrderFilter')
+            ->with($this->order)
+            ->willReturnSelf();
+        $collectionMock->expects($this->once())
+            ->method('setOrder')
+            ->with('created_at', 'desc')
+            ->willReturn($dbMock);
+        $dbMock->expects($this->once())
+            ->method('setOrder')
+            ->with('entity_id', 'desc')
+            ->willReturn($collectionMock);
+        $collectionMock->expects($this->once())
+            ->method('getItems')
+            ->willReturn($collectionItems);
+
+        $this->historyCollectionFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($collectionMock);
+
+        for ($i = 10; --$i;) {
+            $this->assertEquals($collectionItems, $this->order->getStatusHistories());
+        }
+    }
 }
-- 
GitLab


From d3d2de734ca92818f831d2206ef68349137b89c0 Mon Sep 17 00:00:00 2001
From: Dmytro Voskoboinikov <dvoskoboinikov@ebay.com>
Date: Mon, 15 Dec 2014 17:40:24 +0200
Subject: [PATCH 49/71] MAGETWO-3404: Transactions Tab on Order page in Admin

Signed-off-by: Dmytro Voskoboinikov <dvoskoboinikov@ebay.com>
---
 .../OfflinePayments/Model/Banktransfer.php    |   7 +
 .../OfflinePayments/Model/Cashondelivery.php  |   7 +
 .../Magento/OfflinePayments/Model/Checkmo.php |   7 +
 .../OfflinePayments/Model/Purchaseorder.php   |   7 +
 .../Payment/Model/Method/AbstractMethod.php   |  17 +++
 .../Adminhtml/Order/View/Tab/Transactions.php |  24 +++-
 .../Order/View/Tab/TransactionsTest.php       | 128 ++++++++++++++++++
 7 files changed, 195 insertions(+), 2 deletions(-)
 create mode 100644 dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/View/Tab/TransactionsTest.php

diff --git a/app/code/Magento/OfflinePayments/Model/Banktransfer.php b/app/code/Magento/OfflinePayments/Model/Banktransfer.php
index fb8d31b9c90..858f68ddc21 100644
--- a/app/code/Magento/OfflinePayments/Model/Banktransfer.php
+++ b/app/code/Magento/OfflinePayments/Model/Banktransfer.php
@@ -32,6 +32,13 @@ class Banktransfer extends \Magento\Payment\Model\Method\AbstractMethod
      */
     protected $_infoBlockType = 'Magento\Payment\Block\Info\Instructions';
 
+    /**
+     * Availability option
+     *
+     * @var bool
+     */
+    protected $_isOffline = true;
+
     /**
      * Get instructions text from config
      *
diff --git a/app/code/Magento/OfflinePayments/Model/Cashondelivery.php b/app/code/Magento/OfflinePayments/Model/Cashondelivery.php
index 74097a82728..07ca59f6ac7 100644
--- a/app/code/Magento/OfflinePayments/Model/Cashondelivery.php
+++ b/app/code/Magento/OfflinePayments/Model/Cashondelivery.php
@@ -30,6 +30,13 @@ class Cashondelivery extends \Magento\Payment\Model\Method\AbstractMethod
      */
     protected $_infoBlockType = 'Magento\Payment\Block\Info\Instructions';
 
+    /**
+     * Availability option
+     *
+     * @var bool
+     */
+    protected $_isOffline = true;
+
     /**
      * Get instructions text from config
      *
diff --git a/app/code/Magento/OfflinePayments/Model/Checkmo.php b/app/code/Magento/OfflinePayments/Model/Checkmo.php
index 4b1bc2b0558..37a8e7a3e20 100644
--- a/app/code/Magento/OfflinePayments/Model/Checkmo.php
+++ b/app/code/Magento/OfflinePayments/Model/Checkmo.php
@@ -21,6 +21,13 @@ class Checkmo extends \Magento\Payment\Model\Method\AbstractMethod
      */
     protected $_infoBlockType = 'Magento\OfflinePayments\Block\Info\Checkmo';
 
+    /**
+     * Availability option
+     *
+     * @var bool
+     */
+    protected $_isOffline = true;
+
     /**
      * Assign data to info model instance
      *
diff --git a/app/code/Magento/OfflinePayments/Model/Purchaseorder.php b/app/code/Magento/OfflinePayments/Model/Purchaseorder.php
index d41a3cdbf77..0c82a6352f4 100644
--- a/app/code/Magento/OfflinePayments/Model/Purchaseorder.php
+++ b/app/code/Magento/OfflinePayments/Model/Purchaseorder.php
@@ -21,6 +21,13 @@ class Purchaseorder extends \Magento\Payment\Model\Method\AbstractMethod
      */
     protected $_infoBlockType = 'Magento\OfflinePayments\Block\Info\Purchaseorder';
 
+    /**
+     * Availability option
+     *
+     * @var bool
+     */
+    protected $_isOffline = true;
+
     /**
      * Assign data to info model instance
      *
diff --git a/app/code/Magento/Payment/Model/Method/AbstractMethod.php b/app/code/Magento/Payment/Model/Method/AbstractMethod.php
index 993666627b4..cbeea1302ec 100644
--- a/app/code/Magento/Payment/Model/Method/AbstractMethod.php
+++ b/app/code/Magento/Payment/Model/Method/AbstractMethod.php
@@ -70,6 +70,13 @@ abstract class AbstractMethod extends \Magento\Framework\Object implements Metho
      */
     protected $_isGateway = false;
 
+    /**
+     * Payment Method feature
+     *
+     * @var bool
+     */
+    protected $_isOffline = false;
+
     /**
      * Payment Method feature
      *
@@ -370,6 +377,16 @@ abstract class AbstractMethod extends \Magento\Framework\Object implements Metho
         return $this->_isGateway;
     }
 
+    /**
+     * Retrieve payment method online/offline flag
+     *
+     * @return bool
+     */
+    public function isOffline()
+    {
+        return $this->_isOffline;
+    }
+
     /**
      * Flag if we need to run payment initialize while order place
      *
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/Transactions.php b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/Transactions.php
index c807707f19d..cdddae0d54f 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/Transactions.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/Transactions.php
@@ -17,20 +17,40 @@ class Transactions extends \Magento\Framework\View\Element\Text\ListText impleme
      */
     protected $_authorization;
 
+    /**
+     * Core registry
+     *
+     * @var \Magento\Framework\Registry
+     */
+    protected $_coreRegistry = null;
+
     /**
      * @param \Magento\Framework\View\Element\Context $context
      * @param \Magento\Framework\AuthorizationInterface $authorization
+     * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
         \Magento\Framework\View\Element\Context $context,
         \Magento\Framework\AuthorizationInterface $authorization,
-        array $data = []
+        \Magento\Framework\Registry $registry,
+        array $data = array()
     ) {
         $this->_authorization = $authorization;
+        $this->_coreRegistry = $registry;
         parent::__construct($context, $data);
     }
 
+    /**
+     * Retrieve order model instance
+     *
+     * @return \Magento\Sales\Model\Order
+     */
+    public function getOrder()
+    {
+        return $this->_coreRegistry->registry('current_order');
+    }
+
     /**
      * {@inheritdoc}
      */
@@ -52,7 +72,7 @@ class Transactions extends \Magento\Framework\View\Element\Text\ListText impleme
      */
     public function canShowTab()
     {
-        return true;
+        return !$this->getOrder()->getPayment()->getMethodInstance()->isOffline();
     }
 
     /**
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/View/Tab/TransactionsTest.php b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/View/Tab/TransactionsTest.php
new file mode 100644
index 00000000000..c006dbd646e
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/View/Tab/TransactionsTest.php
@@ -0,0 +1,128 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Block\Adminhtml\Order\View\Tab;
+
+/**
+ * Order transactions tab test
+ */
+class TransactionsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\TestFramework\Helper\ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * @var \Magento\Sales\Block\Adminhtml\Order\View\Tab\Transactions
+     */
+    protected $transactionsTab;
+
+    /**
+     * @var \Magento\Framework\Authorization|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $authorizationMock;
+
+    /**
+     * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $coreRegistryMock;
+
+    /**
+     * @var \Magento\Sales\Model\Order|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $orderMock;
+
+    /**
+     * @var \Magento\Sales\Model\Order\Payment|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $paymentMock;
+
+    protected function setUp()
+    {
+        $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
+
+        $this->authorizationMock = $this->getMock('\Magento\Framework\Authorization', [], [], '', false);
+        $this->coreRegistryMock = $this->getMock('Magento\Framework\Registry', [], [], '', false);
+        $this->orderMock = $this->getMock('\Magento\Sales\Model\Order', [], [], '', false);
+        $this->paymentMock = $this->getMock('\Magento\Sales\Model\Order\Payment', [], [], '', false);
+
+        $this->coreRegistryMock->expects($this->any())
+            ->method('registry')
+            ->with('current_order')
+            ->willReturn($this->orderMock);
+
+        $this->orderMock->expects($this->any())
+            ->method('getPayment')
+            ->willReturn($this->paymentMock);
+
+        $this->transactionsTab = $this->objectManager->getObject(
+            'Magento\Sales\Block\Adminhtml\Order\View\Tab\Transactions',
+            [
+                'authorization' => $this->authorizationMock,
+                'registry' => $this->coreRegistryMock
+            ]
+        );
+    }
+
+    public function testGetOrder()
+    {
+        $this->assertInstanceOf('\Magento\Sales\Model\Order', $this->transactionsTab->getOrder());
+    }
+
+    /**
+     * @param string $methodClass
+     * @param bool $expectedResult
+     * @depends testGetOrder
+     * @dataProvider canShowTabDataProvider
+     */
+    public function testCanShowTab($methodClass, $expectedResult)
+    {
+        $methodInstance = $this->objectManager->getObject($methodClass);
+        $this->paymentMock->expects($this->any())
+            ->method('getMethodInstance')
+            ->willReturn($methodInstance);
+
+        $this->assertEquals($expectedResult, $this->transactionsTab->canShowTab());
+    }
+
+    /**
+     * @return array
+     */
+    public function canShowTabDataProvider()
+    {
+        return [
+            ['\Magento\Pbridge\Model\Payment\Method\Authorizenet', true],
+            ['\Magento\Authorizenet\Model\Authorizenet', true],
+            ['\Magento\OfflinePayments\Model\Cashondelivery', false],
+            ['\Magento\OfflinePayments\Model\Checkmo', false]
+        ];
+    }
+
+    /**
+     * @param bool $isAllowed
+     * @param bool $expectedResult
+     * @dataProvider isHiddenDataProvider
+     */
+    public function testIsHidden($isAllowed, $expectedResult)
+    {
+        $this->authorizationMock->expects($this->any())
+            ->method('isAllowed')
+            ->with('Magento_Sales::transactions_fetch')
+            ->willReturn($isAllowed);
+
+        $this->assertEquals($expectedResult, $this->transactionsTab->isHidden());
+    }
+
+    /**
+     * @return array
+     */
+    public function isHiddenDataProvider()
+    {
+        return [
+            [true, false],
+            [false, true]
+        ];
+    }
+}
-- 
GitLab


From 2f99c7cb26f33f2e1a0c577360b91865605b5c5e Mon Sep 17 00:00:00 2001
From: Dmytro Voskoboinikov <dvoskoboinikov@ebay.com>
Date: Tue, 16 Dec 2014 11:27:00 +0200
Subject: [PATCH 50/71] MAGETWO-3404: Transactions Tab on Order page in Admin

 - Unit tests were updated.

Signed-off-by: Dmytro Voskoboinikov <dvoskoboinikov@ebay.com>
---
 .../Order/View/Tab/Stub/OnlineMethod.php       | 18 ++++++++++++++++++
 .../Order/View/Tab/TransactionsTest.php        |  7 ++++---
 2 files changed, 22 insertions(+), 3 deletions(-)
 create mode 100644 dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/View/Tab/Stub/OnlineMethod.php

diff --git a/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/View/Tab/Stub/OnlineMethod.php b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/View/Tab/Stub/OnlineMethod.php
new file mode 100644
index 00000000000..28818895ef3
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/View/Tab/Stub/OnlineMethod.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Block\Adminhtml\Order\View\Tab\Stub;
+
+/**
+ * Stub for an online payment method
+ */
+class OnlineMethod extends \Magento\Payment\Model\Method\AbstractMethod
+{
+    /**
+     * Availability option
+     *
+     * @var bool
+     */
+    protected $_isOffline = false;
+}
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/View/Tab/TransactionsTest.php b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/View/Tab/TransactionsTest.php
index c006dbd646e..f82ea8b4220 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/View/Tab/TransactionsTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/View/Tab/TransactionsTest.php
@@ -93,10 +93,11 @@ class TransactionsTest extends \PHPUnit_Framework_TestCase
     public function canShowTabDataProvider()
     {
         return [
-            ['\Magento\Pbridge\Model\Payment\Method\Authorizenet', true],
-            ['\Magento\Authorizenet\Model\Authorizenet', true],
+            ['\Magento\Sales\Block\Adminhtml\Order\View\Tab\Stub\OnlineMethod', true],
             ['\Magento\OfflinePayments\Model\Cashondelivery', false],
-            ['\Magento\OfflinePayments\Model\Checkmo', false]
+            ['\Magento\OfflinePayments\Model\Checkmo', false],
+            ['\Magento\OfflinePayments\Model\Banktransfer', false],
+            ['\Magento\OfflinePayments\Model\Purchaseorder', false]
         ];
     }
 
-- 
GitLab


From 14aade103aa921aed3a2652b1a63220eba4a5ddc Mon Sep 17 00:00:00 2001
From: Dmytro Voskoboinikov <dvoskoboinikov@ebay.com>
Date: Tue, 16 Dec 2014 13:32:00 +0200
Subject: [PATCH 51/71] MAGETWO-3404: Transactions Tab on Order page in Admin

 - Changes according to Bamboo tests results.

Signed-off-by: Dmytro Voskoboinikov <dvoskoboinikov@ebay.com>
---
 .../Sales/Block/Adminhtml/Order/View/Tab/Transactions.php       | 2 +-
 .../Magento/Test/Php/_files/phpcpd/blacklist/common.txt         | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/Transactions.php b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/Transactions.php
index cdddae0d54f..a39f367057d 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/Transactions.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Tab/Transactions.php
@@ -34,7 +34,7 @@ class Transactions extends \Magento\Framework\View\Element\Text\ListText impleme
         \Magento\Framework\View\Element\Context $context,
         \Magento\Framework\AuthorizationInterface $authorization,
         \Magento\Framework\Registry $registry,
-        array $data = array()
+        array $data = []
     ) {
         $this->_authorization = $authorization;
         $this->_coreRegistry = $registry;
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 89690a5dd63..083fbe5c84c 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
@@ -144,3 +144,4 @@ app/code/Magento/Sales/Model/Spi
 Magento/Catalog/Model/ProductLink
 Magento/GroupedProduct/Model/Resource/Product/Type/Grouped
 lib/internal/Magento/Framework/Interception/ObjectManager/Config
+app/code/Magento/OfflinePayments/Model
\ No newline at end of file
-- 
GitLab


From a9dd67dab487b04d68543ebaee2308b2f215a045 Mon Sep 17 00:00:00 2001
From: Dmytro Aponasenko <daponasenko@ebay.com>
Date: Mon, 22 Dec 2014 12:29:26 +0200
Subject: [PATCH 52/71] MTA-1249: Update Bamboo Installation Plan

---
 .../TestCase/SearchEntityResultsTest/test.csv |   2 +-
 .../CatalogSearch/Test/etc/constraint.xml     |   2 +-
 .../Install/Test/Block/CreateAdmin.php        |  32 +++
 .../Install/Test/Block/CreateAdmin.xml        |  22 ++
 .../Install/Test/Block/CustomizeStore.php     |  32 +++
 .../Install/Test/Block/CustomizeStore.xml     |  18 ++
 .../Magento/Install/Test/Block/Database.php   |  49 ++++
 .../Magento/Install/Test/Block/Database.xml   |  17 ++
 .../Magento/Install/Test/Block/Install.php    | 100 ++++++++
 .../Magento/Install/Test/Block/Landing.php    |  49 ++++
 .../Magento/Install/Test/Block/License.php    |  49 ++++
 .../Magento/Install/Test/Block/Readiness.php  | 108 +++++++++
 .../Install/Test/Block/WebConfiguration.php   |  48 ++++
 .../Install/Test/Block/WebConfiguration.xml   |  32 +++
 .../Constraint/AssertAgreementTextPresent.php |  49 ++++
 .../Constraint/AssertCurrencySelected.php     |  44 ++++
 .../Test/Constraint/AssertKeyCreated.php      |  46 ++++
 .../Constraint/AssertLanguageSelected.php     |  45 ++++
 .../Test/Constraint/AssertRewritesEnabled.php |  50 ++++
 .../Constraint/AssertSecureUrlEnabled.php     |  57 +++++
 .../Test/Constraint/AssertSuccessInstall.php  |  85 +++++++
 .../AssertSuccessfulReadinessCheck.php        |  69 ++++++
 .../Magento/Install/Test/Fixture/Install.php  | 219 ++++++++++++++++++
 .../Magento/Install/Test/Fixture/Install.xml  |  79 +++++++
 .../app/Magento/Install/Test/Page/Install.xml |  50 ++++
 .../Install/Test/TestCase/InstallTest.php     | 148 ++++++++++++
 .../Test/TestCase/InstallTest/test.csv        |   7 +
 .../Magento/Install/Test/etc/constraint.xml   |  35 +++
 .../app/Magento/Install/Test/etc/fixture.xml  |  35 +++
 .../app/Magento/Install/Test/etc/page.xml     |  12 +
 30 files changed, 1588 insertions(+), 2 deletions(-)
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Block/CreateAdmin.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Block/CreateAdmin.xml
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Block/CustomizeStore.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Block/CustomizeStore.xml
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Block/Database.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Block/Database.xml
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Block/Install.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Block/Landing.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Block/License.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Block/Readiness.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Block/WebConfiguration.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Block/WebConfiguration.xml
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertAgreementTextPresent.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertCurrencySelected.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertKeyCreated.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertLanguageSelected.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertRewritesEnabled.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertSecureUrlEnabled.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertSuccessInstall.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertSuccessfulReadinessCheck.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Fixture/Install.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Fixture/Install.xml
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/Page/Install.xml
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest/test.csv
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/etc/constraint.xml
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/etc/fixture.xml
 create mode 100644 dev/tests/functional/tests/app/Magento/Install/Test/etc/page.xml

diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SearchEntityResultsTest/test.csv b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SearchEntityResultsTest/test.csv
index cf840f41556..f6082080c2e 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SearchEntityResultsTest/test.csv
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SearchEntityResultsTest/test.csv
@@ -1,5 +1,5 @@
 "description";"catalogSearch/data/query_text/value";"constraint";"tag"
-"MAGETWO-12420: Use Quick Search to Find the Product";"catalogProductSimple::default::sku";"","bamboo_plan:BAT"
+"MAGETWO-12420: Use Quick Search to Find the Product";"catalogProductSimple::default::sku";"assertProductCanBeOpenedFromSearchResult";"bamboo_plan:BAT"
 "Search simple product";"catalogProductSimple::default::simple";"assertCatalogSearchResult";""
 "Search virtual product";"catalogProductVirtual::default::virtual";"assertCatalogSearchResult";""
 "Search configurable product";"configurableProductInjectable::default::configurable";"assertCatalogSearchResult";""
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/constraint.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/constraint.xml
index f4d04cfadc0..f55277251d8 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/constraint.xml
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/constraint.xml
@@ -119,7 +119,7 @@
             <browser class="Mtf\Client\Browser" />
         </require>
     </assertSearchSynonymMassActionNotOnFrontend>
-    <assertProductCanBeOpenedFromSearchResult>
+    <assertProductCanBeOpenedFromSearchResult module="Magento_CatalogSearch">
         <severity>high</severity>
         <require>
             <catalogSearch class="Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery" />
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Block/CreateAdmin.php b/dev/tests/functional/tests/app/Magento/Install/Test/Block/CreateAdmin.php
new file mode 100644
index 00000000000..cd025b734f7
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Block/CreateAdmin.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Install\Test\Block;
+
+use Mtf\Block\Form;
+use Mtf\Client\Element\Locator;
+
+/**
+ * Create Admin Account block.
+ */
+class CreateAdmin extends Form
+{
+    /**
+     * 'Next' button.
+     *
+     * @var string
+     */
+    protected $next = "[ng-click*='next']";
+
+    /**
+     * Click on 'Next' button.
+     *
+     * @return void
+     */
+    public function clickNext()
+    {
+        $this->_rootElement->find($this->next, Locator::SELECTOR_CSS)->click();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Block/CreateAdmin.xml b/dev/tests/functional/tests/app/Magento/Install/Test/Block/CreateAdmin.xml
new file mode 100644
index 00000000000..87f9389c514
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Block/CreateAdmin.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<mapping strict="0">
+    <fields>
+        <username>
+            <selector>[name='adminUsername']</selector>
+        </username>
+        <email>
+            <selector>[name='adminEmail']</selector>
+        </email>
+        <password>
+            <selector>[name='adminPassword']</selector>
+        </password>
+        <password_confirmation>
+            <selector>[name='adminConfirm']</selector>
+        </password_confirmation>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Block/CustomizeStore.php b/dev/tests/functional/tests/app/Magento/Install/Test/Block/CustomizeStore.php
new file mode 100644
index 00000000000..af5707450b5
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Block/CustomizeStore.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Install\Test\Block;
+
+use Mtf\Block\Form;
+use Mtf\Client\Element\Locator;
+
+/**
+ * Customize Your Store block.
+ */
+class CustomizeStore extends Form
+{
+    /**
+     * 'Next' button.
+     *
+     * @var string
+     */
+    protected $next = "[ng-click*='next']";
+
+    /**
+     * Click on 'Next' button.
+     *
+     * @return void
+     */
+    public function clickNext()
+    {
+        $this->_rootElement->find($this->next, Locator::SELECTOR_CSS)->click();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Block/CustomizeStore.xml b/dev/tests/functional/tests/app/Magento/Install/Test/Block/CustomizeStore.xml
new file mode 100644
index 00000000000..afca361627a
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Block/CustomizeStore.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<mapping strict="0">
+    <fields>
+        <currency>
+            <selector>[ng-model*='currency']</selector>
+            <input>select</input>
+        </currency>
+        <language>
+            <selector>[ng-model*='language']</selector>
+            <input>select</input>
+        </language>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Block/Database.php b/dev/tests/functional/tests/app/Magento/Install/Test/Block/Database.php
new file mode 100644
index 00000000000..8d5919a7ec9
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Block/Database.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Install\Test\Block;
+
+use Mtf\Block\Form;
+use Mtf\Client\Element\Locator;
+
+/**
+ * Database form.
+ */
+class Database extends Form
+{
+    /**
+     * 'Test connection successful.' message.
+     *
+     * @var string
+     */
+    protected $successConnectionMessage = ".text-success";
+
+    /**
+     * 'Next' button.
+     *
+     * @var string
+     */
+    protected $next = "[ng-click*='testConnection']";
+
+    /**
+     * Get 'Test connection successful.' message.
+     *
+     * @return string
+     */
+    public function getSuccessConnectionMessage()
+    {
+        return $this->_rootElement->find($this->successConnectionMessage, Locator::SELECTOR_CSS)->getText();
+    }
+
+    /**
+     * Click on 'Next' button.
+     *
+     * @return void
+     */
+    public function clickNext()
+    {
+        $this->_rootElement->find($this->next, Locator::SELECTOR_CSS)->click();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Block/Database.xml b/dev/tests/functional/tests/app/Magento/Install/Test/Block/Database.xml
new file mode 100644
index 00000000000..c09b95b5d28
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Block/Database.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<mapping strict="0">
+    <fields>
+        <dbHost />
+        <dbUser />
+        <dbPassword />
+        <dbName>
+            <selector>[name="dbname"]</selector>
+        </dbName>
+        <dbTablePrefix />
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Block/Install.php b/dev/tests/functional/tests/app/Magento/Install/Test/Block/Install.php
new file mode 100644
index 00000000000..8df7ca8d6c0
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Block/Install.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Install\Test\Block;
+
+use Mtf\Block\Block;
+use Mtf\Client\Element\Locator;
+
+/**
+ * Install block.
+ */
+class Install extends Block
+{
+    /**
+     * 'Install Now' button.
+     *
+     * @var string
+     */
+    protected $installNow = "//*[@ng-show='!isStarted']/button";
+
+    /**
+     * Admin info block.
+     *
+     * @var string
+     */
+    protected $adminInfo = "//*[@id='admin-info']";
+
+    /**
+     * Database info block.
+     *
+     * @var string
+     */
+    protected $dbInfo = "//*[@id='db-info']";
+
+    /**
+     * 'Launch Magento Admin' button.
+     *
+     * @var string
+     */
+    protected $launchAdmin = "//*[@type='button']";
+
+    /**
+     * Click on 'Install Now' button.
+     *
+     * @return void
+     */
+    public function clickInstallNow()
+    {
+        $this->_rootElement->find($this->installNow, Locator::SELECTOR_XPATH)->click();
+        $this->waitForElementVisible($this->launchAdmin, Locator::SELECTOR_XPATH);
+    }
+
+    /**
+     * Get admin info.
+     *
+     * @return string
+     */
+    public function getAdminInfo()
+    {
+        $adminData = [];
+        $rows = $this->_rootElement->find('#admin-info .row')->getElements();
+        foreach ($rows as $row) {
+            $dataRow = $row->find('div')->getElements();
+            $key = strtolower(str_replace(' ', '_', str_replace(':', '', $dataRow[0]->getText())));
+            $adminData[$key] = $dataRow[1]->getText();
+        }
+
+        return $adminData;
+    }
+
+    /**
+     * Get database info.
+     *
+     * @return string
+     */
+    public function getDbInfo()
+    {
+        $dbData = [];
+        $rows = $this->_rootElement->find('#db-info .row')->getElements();
+        foreach ($rows as $row) {
+            $dataRow = $row->find('div')->getElements();
+            $key = strtolower(str_replace(' ', '_', str_replace(':', '', $dataRow[0]->getText())));
+            $dbData[$key] = $dataRow[1]->getText();
+        }
+
+        return $dbData;
+    }
+
+    /**
+     * Click on 'Launch Magento Admin' button.
+     *
+     * @return void
+     */
+    public function clickLaunchAdmin()
+    {
+        $this->_rootElement->find($this->launchAdmin, Locator::SELECTOR_XPATH)->click();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Block/Landing.php b/dev/tests/functional/tests/app/Magento/Install/Test/Block/Landing.php
new file mode 100644
index 00000000000..75085d53c75
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Block/Landing.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Install\Test\Block;
+
+use Mtf\Block\Block;
+use Mtf\Client\Element\Locator;
+
+/**
+ * Landing block.
+ */
+class Landing extends Block
+{
+    /**
+     * 'Agree and Set up Magento' button.
+     *
+     * @var string
+     */
+    protected $agreeAndSetup = '.btn-lg.btn-primary';
+
+    /**
+     * 'Terms & Agreement' link.
+     *
+     * @var string
+     */
+    protected $termsAndAgreement = "[ng-click*='previous']";
+
+    /**
+     * Click on 'Agree and Set up Magento' button.
+     *
+     * @return void
+     */
+    public function clickAgreeAndSetup()
+    {
+        $this->_rootElement->find($this->agreeAndSetup, Locator::SELECTOR_CSS)->click();
+    }
+
+    /**
+     * Click on 'Terms & Agreement' link.
+     *
+     * @return void
+     */
+    public function clickTermsAndAgreement()
+    {
+        $this->_rootElement->find($this->termsAndAgreement, Locator::SELECTOR_CSS)->click();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Block/License.php b/dev/tests/functional/tests/app/Magento/Install/Test/Block/License.php
new file mode 100644
index 00000000000..83f59f7159d
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Block/License.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Install\Test\Block;
+
+use Mtf\Block\Block;
+use Mtf\Client\Element\Locator;
+
+/**
+ * License block.
+ */
+class License extends Block
+{
+    /**
+     * 'Back' button.
+     *
+     * @var string
+     */
+    protected $back = '.btn.btn-primary';
+
+    /**
+     * License text.
+     *
+     * @var string
+     */
+    protected $license = '.container.ng-scope';
+
+    /**
+     * Click on 'Back' button.
+     *
+     * @return void
+     */
+    public function clickBack()
+    {
+        $this->_rootElement->find($this->back, Locator::SELECTOR_CSS)->click();
+    }
+
+    /**
+     * Get license text.
+     *
+     * @return string
+     */
+    public function getLicense()
+    {
+        return $this->_rootElement->find($this->license, Locator::SELECTOR_CSS)->getText();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Block/Readiness.php b/dev/tests/functional/tests/app/Magento/Install/Test/Block/Readiness.php
new file mode 100644
index 00000000000..72fcfcb1aa2
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Block/Readiness.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Install\Test\Block;
+
+use Mtf\Block\Block;
+use Mtf\Client\Element\Locator;
+
+/**
+ * Readiness block.
+ */
+class Readiness extends Block
+{
+    /**
+     * 'Start Readiness Check' button.
+     *
+     * @var string
+     */
+    protected $readinessCheck = "[ng-click*='state.go']";
+
+    /**
+     * 'Next' button.
+     *
+     * @var string
+     */
+    protected $next = "[ng-click*='next']";
+
+    /**
+     * 'Completed!' message.
+     * [ng-switch-when="true"]
+     * @var string
+     */
+    protected $completedMessage = '[ng-switch-when="true"]';
+
+    /**
+     * PHP Version successful check.
+     *
+     * @var string
+     */
+    protected $phpVersionCheck = '#php-version';
+
+    /**
+     * PHP Extensions successful check.
+     *
+     * @var string
+     */
+    protected $phpExtensionCheck = '#php-extensions';
+
+    /**
+     * File Permission check.
+     *
+     * @var string
+     */
+    protected $filePermissionCheck = '#php-permissions';
+
+    /**
+     * Click on 'Start Readiness Check' button.
+     *
+     * @return void
+     */
+    public function clickReadinessCheck()
+    {
+        $this->_rootElement->find($this->readinessCheck, Locator::SELECTOR_CSS)->click();
+        $this->waitForElementVisible($this->completedMessage, Locator::SELECTOR_CSS);
+    }
+
+    /**
+     * Click on 'Next' button.
+     *
+     * @return void
+     */
+    public function clickNext()
+    {
+        $this->_rootElement->find($this->next, Locator::SELECTOR_CSS)->click();
+    }
+
+    /**
+     * Get File Permissions check result.
+     *
+     * @return string
+     */
+    public function getFilePermissionCheck()
+    {
+        return $this->_rootElement->find($this->filePermissionCheck, Locator::SELECTOR_CSS)->getText();
+    }
+
+    /**
+     * Get PHP Version check result.
+     *
+     * @return string
+     */
+    public function getPhpVersionCheck()
+    {
+        return $this->_rootElement->find($this->phpVersionCheck, Locator::SELECTOR_CSS)->getText();
+    }
+
+    /**
+     * Get PHP Extensions check result.
+     *
+     * @return string
+     */
+    public function getPhpExtensionsCheck()
+    {
+        return $this->_rootElement->find($this->phpExtensionCheck, Locator::SELECTOR_CSS)->getText();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Block/WebConfiguration.php b/dev/tests/functional/tests/app/Magento/Install/Test/Block/WebConfiguration.php
new file mode 100644
index 00000000000..08ca27d4d6f
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Block/WebConfiguration.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Install\Test\Block;
+
+use Mtf\Block\Form;
+
+/**
+ * Web configuration block.
+ */
+class WebConfiguration extends Form
+{
+    /**
+     * 'Next' button.
+     *
+     * @var string
+     */
+    protected $next = "[ng-click*='next']";
+
+    /**
+     * 'Advanced Options' locator.
+     *
+     * @var string
+     */
+    protected $advancedOptions = "[ng-click*='advanced']";
+
+    /**
+     * Click on 'Next' button.
+     *
+     * @return void
+     */
+    public function clickNext()
+    {
+        $this->_rootElement->find($this->next)->click();
+    }
+
+    /**
+     * Click on 'Advanced Options' button.
+     *
+     * @return void
+     */
+    public function clickAdvancedOptions()
+    {
+        $this->_rootElement->find($this->advancedOptions)->click();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Block/WebConfiguration.xml b/dev/tests/functional/tests/app/Magento/Install/Test/Block/WebConfiguration.xml
new file mode 100644
index 00000000000..06cdb68f1bc
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Block/WebConfiguration.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<mapping strict="0">
+    <fields>
+        <web />
+        <admin />
+        <keyOwn>
+            <selector>[value="user"]</selector>
+            <input>checkbox</input>
+        </keyOwn>
+        <keyValue>
+            <selector>[name="key"]</selector>
+        </keyValue>
+        <apacheRewrites>
+            <selector>[ng-model*="rewrites"]</selector>
+            <input>checkbox</input>
+        </apacheRewrites>
+        <httpsFront>
+            <selector>[ng-model*="front"]</selector>
+            <input>checkbox</input>
+        </httpsFront>
+        <https />
+        <httpsAdmin>
+            <selector>[type="checkbox"][ng-model*="admin"]</selector>
+            <input>checkbox</input>
+        </httpsAdmin>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertAgreementTextPresent.php b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertAgreementTextPresent.php
new file mode 100644
index 00000000000..673956def75
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertAgreementTextPresent.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Install\Test\Constraint;
+
+use Magento\Install\Test\Page\Install;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Check that agreement text present on Terms & Agreement page during install.
+ */
+class AssertAgreementTextPresent extends AbstractConstraint
+{
+    /* tags */
+    const SEVERITY = 'low';
+    /* end tags */
+
+    /**
+     * Part of license agreement text.
+     */
+    const LICENSE_AGREEMENT_TEXT = 'Open Software License ("OSL") v. 3.0';
+
+    /**
+     * Assert that part of license agreement text is present on Terms & Agreement page.
+     *
+     * @param Install $installPage
+     * @return void
+     */
+    public function processAssert(Install $installPage)
+    {
+        \PHPUnit_Framework_Assert::assertContains(
+            self::LICENSE_AGREEMENT_TEXT,
+            $installPage->getLicenseBlock()->getLicense(),
+            'License agreement text is absent.'
+        );
+    }
+
+    /**
+     * Returns a string representation of successful assertion.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return "License agreement text is present on Terms & Agreement page.";
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertCurrencySelected.php b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertCurrencySelected.php
new file mode 100644
index 00000000000..b2da3668ba2
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertCurrencySelected.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Install\Test\Constraint;
+
+use Magento\Backend\Test\Page\Adminhtml\Dashboard;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Assert that selected currency symbol displays in admin.
+ */
+class AssertCurrencySelected extends AbstractConstraint
+{
+    /* tags */
+    const SEVERITY = 'low';
+    /* end tags */
+
+    /**
+     * Assert that selected currency symbol displays on dashboard.
+     *
+     * @param string $currencySymbol
+     * @param Dashboard $dashboardPage
+     * @return void
+     */
+    public function processAssert($currencySymbol, Dashboard $dashboardPage)
+    {
+        \PHPUnit_Framework_Assert::assertTrue(
+            strpos($dashboardPage->getMainBlock()->getRevenuePrice(), $currencySymbol) !== false,
+            'Selected currency symbol not displays on dashboard.'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Selected currency displays in admin.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertKeyCreated.php b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertKeyCreated.php
new file mode 100644
index 00000000000..13cd5642be4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertKeyCreated.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Install\Test\Constraint;
+
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Install\Test\Page\Install;
+use Magento\Install\Test\Fixture\Install as InstallConfig;
+
+/**
+ * Assert that selected encryption key displays on success full install page.
+ */
+class AssertKeyCreated extends AbstractConstraint
+{
+    /* tags */
+    const SEVERITY = 'low';
+    /* end tags */
+
+    /**
+     * Assert that selected encryption key displays on success full install page.
+     *
+     * @param Install $installPage
+     * @param InstallConfig $installConfig
+     * @return void
+     */
+    public function processAssert(Install $installPage, InstallConfig $installConfig)
+    {
+        \PHPUnit_Framework_Assert::assertEquals(
+            $installConfig->getKeyValue(),
+            $installPage->getInstallBlock()->getAdminInfo()['encryption_key'],
+            'Selected encryption key on install page not equals to data from fixture.'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Selected encryption key displays on success full install page.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertLanguageSelected.php b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertLanguageSelected.php
new file mode 100644
index 00000000000..177673c0adb
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertLanguageSelected.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Install\Test\Constraint;
+
+use Magento\Cms\Test\Page\CmsIndex;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Assert that selected language currently displays on frontend.
+ */
+class AssertLanguageSelected extends AbstractConstraint
+{
+    /* tags */
+    const SEVERITY = 'low';
+    /* end tags */
+
+    /**
+     * Assert that selected language currently displays on frontend.
+     *
+     * @param string $languageTemplate
+     * @param CmsIndex $indexPage
+     * @return void
+     */
+    public function processAssert($languageTemplate, CmsIndex $indexPage)
+    {
+        $indexPage->open();
+        \PHPUnit_Framework_Assert::assertTrue(
+            $indexPage->getLinksBlock()->isLinkVisible($languageTemplate),
+            'Selected language not displays on frontend.'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Selected language currently displays on frontend.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertRewritesEnabled.php b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertRewritesEnabled.php
new file mode 100644
index 00000000000..c9db0e7d4a2
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertRewritesEnabled.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Install\Test\Constraint;
+
+use Magento\Cms\Test\Page\CmsIndex;
+use Mtf\Constraint\AbstractConstraint;
+use Mtf\Client\Driver\Selenium\Browser;
+use Magento\Catalog\Test\Fixture\CatalogCategory;
+
+/**
+ * Assert that apache redirect correct works.
+ */
+class AssertRewritesEnabled extends AbstractConstraint
+{
+    /* tags */
+    const SEVERITY = 'low';
+    /* end tags */
+
+    /**
+     * Assert that apache redirect works by opening category page and asserting index.php in its url
+     *
+     * @param CatalogCategory $category
+     * @param CmsIndex $homePage
+     * @param Browser $browser
+     */
+    public function processAssert(CatalogCategory $category, CmsIndex $homePage, Browser $browser)
+    {
+        $category->persist();
+        $homePage->open();
+        $homePage->getTopmenu()->selectCategoryByName($category->getName());
+
+        \PHPUnit_Framework_Assert::assertTrue(
+            strpos($browser->getUrl(), 'index.php') === false,
+            'Apache redirect for category does not work.'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Apache redirect works correct.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertSecureUrlEnabled.php b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertSecureUrlEnabled.php
new file mode 100644
index 00000000000..2397ad0103e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertSecureUrlEnabled.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Install\Test\Constraint;
+
+use Mtf\Client\Browser;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Backend\Test\Page\Adminhtml\Dashboard;
+use Magento\Customer\Test\Page\CustomerAccountLogin;
+
+/**
+ * Assert that Secure Urls Enabled.
+ */
+class AssertSecureUrlEnabled extends AbstractConstraint
+{
+    /* tags */
+    const SEVERITY = 'low';
+    /* end tags */
+
+    /**
+     * Assert that Secure Urls Enabled.
+     *
+     * @param Browser $browser
+     * @param Dashboard $dashboard
+     * @param CustomerAccountLogin $customerAccountLogin
+     * @return void
+     */
+    public function processAssert(
+        Browser $browser,
+        Dashboard $dashboard,
+        CustomerAccountLogin $customerAccountLogin
+    ) {
+        $dashboard->open();
+        \PHPUnit_Framework_Assert::assertTrue(
+            strpos($browser->getUrl(), 'https://') !== false,
+            'Secure Url is not displayed on backend.'
+        );
+
+        $customerAccountLogin->open();
+        \PHPUnit_Framework_Assert::assertTrue(
+            strpos($browser->getUrl(), 'https://') !== false,
+            'Secure Url is not displayed on frontend.'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Secure Urls are displayed successful.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertSuccessInstall.php b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertSuccessInstall.php
new file mode 100644
index 00000000000..47df11f0aac
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertSuccessInstall.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Install\Test\Constraint;
+
+use Magento\User\Test\Fixture\User;
+use Magento\Install\Test\Page\Install;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Install\Test\Fixture\Install as InstallConfig;
+
+/**
+ * Check that Magento successfully installed.
+ */
+class AssertSuccessInstall extends AbstractConstraint
+{
+    /* tags */
+    const SEVERITY = 'high';
+    /* end tags */
+
+    /**
+     * Admin info fields mapping.
+     *
+     * @var array
+     */
+    protected $adminFieldsList = [
+        ['pageData' => 'username', 'fixture' => 'username'],
+        ['pageData' => 'e-mail', 'fixture' => 'email'],
+        ['pageData' => 'your_store_address', 'fixture' => 'web'],
+        ['pageData' => 'magento_admin_address', 'fixture' => 'admin']
+    ];
+
+    /**
+     * Database info fields mapping.
+     *
+     * @var array
+     */
+    protected $dbFieldsList = [
+        ['pageData' => 'database_name', 'fixture' => 'dbName'],
+        ['pageData' => 'username', 'fixture' => 'dbUser']
+    ];
+
+    /**
+     * Assert that Magento successfully installed.
+     *
+     * @param InstallConfig $installConfig
+     * @param User $user
+     * @param Install $installPage
+     * @return void
+     */
+    public function processAssert(Install $installPage, InstallConfig $installConfig, User $user)
+    {
+        $adminData = $installPage->getInstallBlock()->getAdminInfo();
+        $dbData = $installPage->getInstallBlock()->getDbInfo();
+
+        $allData = array_merge($user->getData(), $installConfig->getData());
+        $allData['admin'] = $allData['web'] . $allData['admin'] . '/';
+
+        foreach ($this->adminFieldsList as $field) {
+            \PHPUnit_Framework_Assert::assertEquals(
+                $allData[$field['fixture']],
+                $adminData[$field['pageData']],
+                'Wrong admin information is displayed.'
+            );
+        }
+        foreach ($this->dbFieldsList as $field) {
+            \PHPUnit_Framework_Assert::assertEquals(
+                $allData[$field['fixture']],
+                $dbData[$field['pageData']],
+                'Wrong database information is displayed.'
+            );
+        }
+    }
+
+    /**
+     * Returns a string representation of successful assertion.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return "Install successfully finished.";
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertSuccessfulReadinessCheck.php b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertSuccessfulReadinessCheck.php
new file mode 100644
index 00000000000..de613def6e2
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Constraint/AssertSuccessfulReadinessCheck.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Install\Test\Constraint;
+
+use Magento\Install\Test\Page\Install;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Check that PHP Version, PHP Extensions and File Permission are ok.
+ */
+class AssertSuccessfulReadinessCheck extends AbstractConstraint
+{
+    /* tags */
+    const SEVERITY = 'high';
+    /* end tags */
+
+    /**
+     * PHP version message.
+     */
+    const PHP_VERSION_MESSAGE = 'Your PHP version is correct';
+
+    /**
+     * PHP extensions message.
+     */
+    const PHP_EXTENSIONS_MESSAGE = 'You meet 9 out of 9 PHP extensions requirements.';
+
+    /**
+     * File permission message.
+     */
+    const FILE_PERMISSION_MESSAGE = 'You meet 4 out of 4 writable file permission requirements.';
+
+    /**
+     * Assert that PHP Version, PHP Extensions and File Permission are ok.
+     *
+     * @param Install $installPage
+     * @return void
+     */
+    public function processAssert(Install $installPage)
+    {
+        \PHPUnit_Framework_Assert::assertContains(
+            self::PHP_VERSION_MESSAGE,
+            $installPage->getReadinessBlock()->getPhpVersionCheck(),
+            'PHP version is incorrect.'
+        );
+        \PHPUnit_Framework_Assert::assertContains(
+            self::PHP_EXTENSIONS_MESSAGE,
+            $installPage->getReadinessBlock()->getPhpExtensionsCheck(),
+            'PHP extensions missed.'
+        );
+        \PHPUnit_Framework_Assert::assertContains(
+            self::FILE_PERMISSION_MESSAGE,
+            $installPage->getReadinessBlock()->getFilePermissionCheck(),
+            'File permissions does not meet requirements.'
+        );
+    }
+
+    /**
+     * Returns a string representation of successful assertion.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return "PHP Version, PHP Extensions and File Permission are ok.";
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Fixture/Install.php b/dev/tests/functional/tests/app/Magento/Install/Test/Fixture/Install.php
new file mode 100644
index 00000000000..deec331975f
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Fixture/Install.php
@@ -0,0 +1,219 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Install\Test\Fixture;
+
+use Mtf\Fixture\InjectableFixture;
+
+/**
+ * Class Install
+ *
+ * @SuppressWarnings(PHPMD.TooManyFields)
+ */
+class Install extends InjectableFixture
+{
+    /**
+     * @var string
+     */
+    protected $repositoryClass = 'Magento\Install\Test\Repository\Install';
+
+    /**
+     * @var string
+     */
+    protected $handlerInterface = 'Magento\Install\Test\Handler\Install\InstallInterface';
+
+    protected $defaultDataSet = [
+    ];
+
+    protected $dbHost = [
+        'attribute_code' => 'dbHost',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $dbUser = [
+        'attribute_code' => 'dbUser',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $dbPassword = [
+        'attribute_code' => 'dbPassword',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $dbName = [
+        'attribute_code' => 'dbName',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $web = [
+        'attribute_code' => 'web',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $admin = [
+        'attribute_code' => 'admin',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $adminUsername = [
+        'attribute_code' => 'adminUsername',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $adminEmail = [
+        'attribute_code' => 'adminEmail',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $adminPassword = [
+        'attribute_code' => 'adminPassword',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $adminConfirm = [
+        'attribute_code' => 'adminConfirm',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $apacheRewrites = [
+        'attribute_code' => 'apacheRewrites',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $dbTablePrefix = [
+        'attribute_code' => 'dbTablePrefix',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $keyOwn = [
+        'attribute_code' => 'keyOwn',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $httpsAdmin = [
+        'attribute_code' => 'httpsAdmin',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $https = [
+        'attribute_code' => 'https',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $httpsFront = [
+        'attribute_code' => 'httpsFront',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $keyValue = [
+        'attribute_code' => 'keyValue',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $language = [
+        'attribute_code' => 'language',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $currency = [
+        'attribute_code' => 'language',
+        'backend_type' => 'virtual',
+    ];
+
+    public function getDbHost()
+    {
+        return $this->getData('dbHost');
+    }
+
+    public function getDbUser()
+    {
+        return $this->getData('dbUser');
+    }
+
+    public function getDbPassword()
+    {
+        return $this->getData('dbPassword');
+    }
+
+    public function getDbName()
+    {
+        return $this->getData('dbName');
+    }
+
+    public function getWeb()
+    {
+        return $this->getData('web');
+    }
+
+    public function getAdmin()
+    {
+        return $this->getData('admin');
+    }
+
+    public function getAdminUsername()
+    {
+        return $this->getData('adminUsername');
+    }
+
+    public function getAdminEmail()
+    {
+        return $this->getData('adminEmail');
+    }
+
+    public function getAdminPassword()
+    {
+        return $this->getData('adminPassword');
+    }
+
+    public function getAdminConfirm()
+    {
+        return $this->getData('adminConfirm');
+    }
+
+    public function getCurrency()
+    {
+        return $this->getData('currency');
+    }
+
+    public function getApacheRewrites()
+    {
+        return $this->getData('apacheRewrites');
+    }
+
+    public function getKeyOwn()
+    {
+        return $this->getData('keyOwn');
+    }
+
+    public function getKeyValue()
+    {
+        return $this->getData('keyValue');
+    }
+
+    public function getLanguage()
+    {
+        return $this->getData('language');
+    }
+
+    public function getHttpsAdmin()
+    {
+        return $this->getData('httpsAdmin');
+    }
+
+    public function getHttps()
+    {
+        return $this->getData('https');
+    }
+
+    public function getHttpsFront()
+    {
+        return $this->getData('httpsFront');
+    }
+
+    public function getDbTablePrefix()
+    {
+        return $this->getData('dbTablePrefix');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Fixture/Install.xml b/dev/tests/functional/tests/app/Magento/Install/Test/Fixture/Install.xml
new file mode 100644
index 00000000000..fffac95c703
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Fixture/Install.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<fixture class="Magento\Install\Test\Fixture\Install">
+    <module>Magento_Install</module>
+    <type>virtual</type>
+    <entity_type>install</entity_type>
+    <fields>
+        <dbHost>
+            <attribute_code>dbHost</attribute_code>
+            <backend_type>virtual</backend_type>
+        </dbHost>
+        <dbUser>
+            <attribute_code>dbUser</attribute_code>
+            <backend_type>virtual</backend_type>
+        </dbUser>
+        <dbTablePrefix>
+            <attribute_code>dbTablePrefix</attribute_code>
+            <backend_type>virtual</backend_type>
+        </dbTablePrefix>
+        <dbPassword>
+            <attribute_code>dbPassword</attribute_code>
+            <backend_type>virtual</backend_type>
+        </dbPassword>
+        <dbName>
+            <attribute_code>dbname</attribute_code>
+            <backend_type>virtual</backend_type>
+        </dbName>
+        <web>
+            <attribute_code>web</attribute_code>
+            <backend_type>virtual</backend_type>
+        </web>
+        <dbTablePrefix>
+            <attribute_code>dbTablePrefix</attribute_code>
+            <backend_type>virtual</backend_type>
+        </dbTablePrefix>
+        <admin>
+            <attribute_code>admin</attribute_code>
+            <backend_type>virtual</backend_type>
+        </admin>
+        <httpsFront>
+            <attribute_code>httpsFront</attribute_code>
+            <backend_type>virtual</backend_type>
+        </httpsFront>
+        <https>
+            <attribute_code>https</attribute_code>
+            <backend_type>virtual</backend_type>
+        </https>
+        <httpsAdmin>
+            <attribute_code>httpsAdmin</attribute_code>
+            <backend_type>virtual</backend_type>
+        </httpsAdmin>
+        <apacheRewrites>
+            <attribute_code>apacheRewrites</attribute_code>
+            <backend_type>virtual</backend_type>
+        </apacheRewrites>
+        <keyOwn>
+            <attribute_code>keyOwn</attribute_code>
+            <backend_type>virtual</backend_type>
+        </keyOwn>
+        <keyValue>
+            <attribute_code>keyValue</attribute_code>
+            <backend_type>virtual</backend_type>
+        </keyValue>
+        <language>
+            <attribute_code>language</attribute_code>
+            <backend_type>virtual</backend_type>
+        </language>
+        <currency>
+            <attribute_code>currency</attribute_code>
+            <backend_type>virtual</backend_type>
+        </currency>
+    </fields>
+    <repository_class>Magento\Install\Test\Repository\Install</repository_class>
+    <handler_interface>Magento\Install\Test\Handler\Install\InstallInterface</handler_interface>
+</fixture>
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/Page/Install.xml b/dev/tests/functional/tests/app/Magento/Install/Test/Page/Install.xml
new file mode 100644
index 00000000000..06f3b3a33b4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/Page/Install.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<page mca="setup/" module="Magento_Install">
+    <blocks>
+        <landingBlock>
+            <class>Magento\Install\Test\Block\Landing</class>
+            <locator>body</locator>
+            <strategy>css selector</strategy>
+        </landingBlock>
+        <licenseBlock>
+            <class>Magento\Install\Test\Block\License</class>
+            <locator>body</locator>
+            <strategy>css selector</strategy>
+        </licenseBlock>
+        <readinessBlock>
+            <class>Magento\Install\Test\Block\Readiness</class>
+            <locator>body</locator>
+            <strategy>css selector</strategy>
+        </readinessBlock>
+        <databaseBlock>
+            <class>Magento\Install\Test\Block\Database</class>
+            <locator>body</locator>
+            <strategy>css selector</strategy>
+        </databaseBlock>
+        <webConfigBlock>
+            <class>Magento\Install\Test\Block\WebConfiguration</class>
+            <locator>body</locator>
+            <strategy>css selector</strategy>
+        </webConfigBlock>
+        <customizeStoreBlock>
+            <class>Magento\Install\Test\Block\CustomizeStore</class>
+            <locator>body</locator>
+            <strategy>css selector</strategy>
+        </customizeStoreBlock>
+        <createAdminBlock>
+            <class>Magento\Install\Test\Block\CreateAdmin</class>
+            <locator>body</locator>
+            <strategy>css selector</strategy>
+        </createAdminBlock>
+        <installBlock>
+            <class>Magento\Install\Test\Block\Install</class>
+            <locator>body</locator>
+            <strategy>css selector</strategy>
+        </installBlock>
+    </blocks>
+</page>
\ No newline at end of file
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php
new file mode 100644
index 00000000000..2aa869b7750
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest.php
@@ -0,0 +1,148 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Install\Test\TestCase;
+
+use Magento\Cms\Test\Page\CmsIndex;
+use Magento\Install\Test\Page\Install;
+use Magento\Install\Test\Fixture\Install as InstallConfig;
+use Magento\User\Test\Fixture\User;
+use Mtf\Fixture\FixtureFactory;
+use Mtf\TestCase\Injectable;
+use Mtf\System\Config;
+use Magento\Install\Test\Constraint\AssertAgreementTextPresent;
+use Magento\Install\Test\Constraint\AssertSuccessfulReadinessCheck;
+
+/**
+ * PLEASE ADD NECESSARY INFO BEFORE RUNNING TEST TO
+ * ../dev/tests/functional/config/install_data.yml.dist
+ *
+ * Test Flow:
+ *
+ * Preconditions:
+ * 1. Uninstall Magento.
+ *
+ * Steps:
+ * 1. Go setup landing page.
+ * 2. Click on "Terms and agreements" button.
+ * 3. Check license agreement text.
+ * 4. Return back to landing page and click "Agree and Setup" button.
+ * 5. Click "Start Readiness Check" button.
+ * 6. Make sure PHP Version, PHP Extensions and File Permission are ok.
+ * 7. Click "Next" and fill DB credentials.
+ * 8. Click "Test Connection and Authentication" and make sure connection successful.
+ * 9. Click "Next" and fill store address and admin path.
+ * 10. Click "Next" and leave all default values.
+ * 11. Click "Next" and fill admin user info.
+ * 12. Click "Next" and on the "Step 6: Install" page click "Install Now" button.
+ * 13. Perform assertions.
+ *
+ * @group Installer_and_Upgrade/Downgrade_(PS)
+ * @ZephyrId MAGETWO-31431
+ */
+class InstallTest extends Injectable
+{
+    /**
+     * Install page.
+     *
+     * @var Install
+     */
+    protected $installPage;
+
+    /**
+     * Cms index page.
+     *
+     * @var CmsIndex
+     */
+    protected $homePage;
+
+    /**
+     * Uninstall Magento before test.
+     *
+     * @param Config $systemConfig
+     * @return array
+     */
+    public function __prepare(Config $systemConfig)
+    {
+        // Prepare config data
+        $configData = $systemConfig->getConfigParam('install_data/db_credentials');
+        $urlConfig = $systemConfig->getConfigParam('install_data/url');
+        $configData['web'] = $urlConfig['base_url'];
+        $configData['admin'] = $urlConfig['backend_frontname'];
+
+        return ['configData' => $configData];
+    }
+
+    /**
+     * Injection data.
+     *
+     * @param CmsIndex $homePage
+     * @param Install $installPage
+     * @return void
+     */
+    public function __inject(Install $installPage, CmsIndex $homePage)
+    {
+        $magentoBaseDir = dirname(dirname(dirname(MTF_BP)));
+        // Uninstall Magento.
+        shell_exec("php -f $magentoBaseDir/setup/index.php uninstall");
+        $this->installPage = $installPage;
+        $this->homePage = $homePage;
+    }
+
+    /**
+     * Install Magento via web interface.
+     *
+     * @param User $user
+     * @param array $install
+     * @param array $configData
+     * @param FixtureFactory $fixtureFactory
+     * @param AssertAgreementTextPresent $assertLicense
+     * @param AssertSuccessfulReadinessCheck $assertReadiness
+     * @return array
+     */
+    public function test(
+        User $user,
+        array $install,
+        array $configData,
+        FixtureFactory $fixtureFactory,
+        AssertAgreementTextPresent $assertLicense,
+        AssertSuccessfulReadinessCheck $assertReadiness
+    ) {
+        $dataConfig = array_merge($install, $configData);
+        if ($dataConfig['httpsFront'] != "-") {
+            $dataConfig['https'] = str_replace('http', 'https', $dataConfig['web']);
+        }
+        /** @var InstallConfig $installConfig */
+        $installConfig = $fixtureFactory->create('Magento\Install\Test\Fixture\Install', ['data' => $dataConfig]);
+        // Steps
+        $this->homePage->open();
+        // Verify license agreement.
+        $this->installPage->getLandingBlock()->clickTermsAndAgreement();
+        $assertLicense->processAssert($this->installPage);
+        $this->installPage->getLicenseBlock()->clickBack();
+        $this->installPage->getLandingBlock()->clickAgreeAndSetup();
+        // Step 1: Readiness Check.
+        $this->installPage->getReadinessBlock()->clickReadinessCheck();
+        $assertReadiness->processAssert($this->installPage);
+        $this->installPage->getReadinessBlock()->clickNext();
+        // Step 2: Add a Database.
+        $this->installPage->getDatabaseBlock()->fill($installConfig);
+        $this->installPage->getDatabaseBlock()->clickNext();
+        // Step 3: Web Configuration.
+        $this->installPage->getWebConfigBlock()->clickAdvancedOptions();
+        $this->installPage->getWebConfigBlock()->fill($installConfig);
+        $this->installPage->getWebConfigBlock()->clickNext();
+        // Step 4: Customize Your Store
+        $this->installPage->getCustomizeStoreBlock()->fill($installConfig);
+        $this->installPage->getCustomizeStoreBlock()->clickNext();
+        // Step 5: Create Admin Account.
+        $this->installPage->getCreateAdminBlock()->fill($user);
+        $this->installPage->getCreateAdminBlock()->clickNext();
+        // Step 6: Install.
+        $this->installPage->getInstallBlock()->clickInstallNow();
+
+        return ['installConfig' => $installConfig];
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest/test.csv b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest/test.csv
new file mode 100644
index 00000000000..63ad72c17f7
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/TestCase/InstallTest/test.csv
@@ -0,0 +1,7 @@
+"user/dataSet";"install/dbTablePrefix";"install/admin";"install/httpsFront";"install/httpsAdmin";"install/apacheRewrites";"install/keyOwn";"install/keyValue";"install/language";"install/currency";"currencySymbol";"languageTemplate";"constraint";"description"
+"default";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"assertSuccessInstall, assertUserSuccessLogin";"install with default values"
+"default";"-";"custom";"-";"-";"-";"-";"-";"-";"-";"-";"-";"assertSuccessInstall, assertUserSuccessLogin";"install with custom admin path"
+"default";"-";"-";"-";"-";"-";"Yes";"123123qa";"German (Germany)";"Euro (EUR)";"€";"Suchbegriffe";"assertSuccessInstall, assertKeyCreated, assertUserSuccessLogin, assertCurrencySelected, assertLanguageSelected";"install with custom encryption key and changed currency and locale"
+"default";"prefix1_";"-";"-";"-";"-";"-";"-";"Chinese (China)";"-";"-";"-";"assertSuccessInstall, assertUserSuccessLogin";"install with table prefix"
+"default";"-";"-";"-";"-";"Yes";"-";"-";"-";"-";"-";"-";"assertSuccessInstall, assertUserSuccessLogin, assertRewritesEnabled";"install with enabled url rewrites"
+"default";"-";"-";"Yes";"Yes";"-";"-";"-";"-";"-";"-";"-";"assertSuccessInstall, assertUserSuccessLogin, assertSecureUrlEnabled";"install with enabled secure urls"
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/etc/constraint.xml b/dev/tests/functional/tests/app/Magento/Install/Test/etc/constraint.xml
new file mode 100644
index 00000000000..921f167e824
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/etc/constraint.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<constraint>
+    <assertAgreementTextPresent module="Magento_Install">
+        <severity>low</severity>
+    </assertAgreementTextPresent>
+    <assertSuccessDbConnection module="Magento_Install">
+        <severity>low</severity>
+    </assertSuccessDbConnection>
+    <assertSuccessfulReadinessCheck module="Magento_Install">
+        <severity>low</severity>
+    </assertSuccessfulReadinessCheck>
+    <assertSuccessInstall module="Magento_Install">
+        <severity>low</severity>
+    </assertSuccessInstall>
+    <assertKeyCreated module="Magento_Install">
+        <severity>low</severity>
+    </assertKeyCreated>
+    <assertLanguageSelected module="Magento_Install">
+        <severity>low</severity>
+    </assertLanguageSelected>
+    <assertCurrencySelected module="Magento_Install">
+        <severity>low</severity>
+    </assertCurrencySelected>
+    <assertRewritesEnabled module="Magento_Install">
+        <severity>low</severity>
+    </assertRewritesEnabled>
+    <assertSecureUrlEnabled module="Magento_Install">
+        <severity>low</severity>
+    </assertSecureUrlEnabled>
+</constraint>
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/etc/fixture.xml b/dev/tests/functional/tests/app/Magento/Install/Test/etc/fixture.xml
new file mode 100644
index 00000000000..c5c091aad3d
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/etc/fixture.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+
+<fixture>
+    <install module="Magento_Install">
+        <type>virtual</type>
+        <entity_type>install</entity_type>
+        <fields>
+            <dbHost>
+                <attribute_code>dbHost</attribute_code>
+                <backend_type>virtual</backend_type>
+            </dbHost>
+            <dbUser>
+                <attribute_code>dbUser</attribute_code>
+                <backend_type>virtual</backend_type>
+            </dbUser>
+            <dbPassword>
+                <attribute_code>dbPassword</attribute_code>
+                <backend_type>virtual</backend_type>
+            </dbPassword>
+            <dbname>
+                <attribute_code>dbname</attribute_code>
+                <backend_type>virtual</backend_type>
+            </dbname>
+            <web>
+                <attribute_code>web</attribute_code>
+                <backend_type>virtual</backend_type>
+            </web>
+        </fields>
+    </install>
+</fixture>
diff --git a/dev/tests/functional/tests/app/Magento/Install/Test/etc/page.xml b/dev/tests/functional/tests/app/Magento/Install/Test/etc/page.xml
new file mode 100644
index 00000000000..523ecd7d067
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Install/Test/etc/page.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<page module="Magento_Install">
+    <install>
+        <mca>setup/</mca>
+        <class>Magento\Install\Test\Page\Install</class>
+    </install>
+</page>
-- 
GitLab


From f1b21e05c9fcaaafd5753098ed0570979b8331b1 Mon Sep 17 00:00:00 2001
From: Sergey Ivashchenko <sivashchenko@ebay.com>
Date: Wed, 24 Dec 2014 14:29:15 +0200
Subject: [PATCH 53/71] MAGETWO-7359: Incorrect totals shown on coupon usage
 report

---
 .../SalesRule/Model/Resource/Report/Rule/CreatedatTest.php   | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/dev/tests/integration/testsuite/Magento/SalesRule/Model/Resource/Report/Rule/CreatedatTest.php b/dev/tests/integration/testsuite/Magento/SalesRule/Model/Resource/Report/Rule/CreatedatTest.php
index aabe4d1790b..2d14ae963ce 100644
--- a/dev/tests/integration/testsuite/Magento/SalesRule/Model/Resource/Report/Rule/CreatedatTest.php
+++ b/dev/tests/integration/testsuite/Magento/SalesRule/Model/Resource/Report/Rule/CreatedatTest.php
@@ -1,9 +1,6 @@
 <?php
 /**
- * {license_notice}
- *
- * @copyright   {copyright}
- * @license     {license_link}
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  */
 namespace Magento\SalesRule\Model\Resource\Report\Rule;
 
-- 
GitLab


From e1cb023df09814f502b652b9732c9e39549f757f Mon Sep 17 00:00:00 2001
From: Sergey Ivashchenko <sivashchenko@ebay.com>
Date: Wed, 24 Dec 2014 14:29:50 +0200
Subject: [PATCH 54/71] MAGETWO-31784: Tax class drop-down on New Customer
 Group page should not contain None value

---
 .../testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php | 1 -
 1 file changed, 1 deletion(-)

diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php
index aca4b4b4c59..f6ef2eced2d 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php
@@ -46,7 +46,6 @@ class CustomerTest extends \PHPUnit_Framework_TestCase
         if (empty($expectedResult)) {
             $this->fail('Preconditions failed: At least one tax class should be available.');
         }
-        $expectedResult = array_merge([['value' => '0', 'label' => __('None')]], $expectedResult);
         /** @var \Magento\Tax\Model\TaxClass\Source\Product $source */
         $source = Bootstrap::getObjectManager()->get('Magento\Tax\Model\TaxClass\Source\Customer');
         $this->assertEquals(
-- 
GitLab


From 3ea0eabd7a622d47910d2ee12b012b2954d01ded Mon Sep 17 00:00:00 2001
From: Sviatoslav Mankivskyi <smankivskyi@ebay.com>
Date: Wed, 24 Dec 2014 15:20:46 +0200
Subject: [PATCH 55/71] MAGETWO-31961: Exception when add configurable product
 from wishlist into cart(problem with product id and item_id)

---
 app/code/Magento/Core/Model/Layout/Merge.php  | 40 ++++++++++++++++---
 .../layout/checkout_cart_configure.xml        |  1 +
 .../layout/wishlist_index_configure.xml       |  1 +
 3 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/app/code/Magento/Core/Model/Layout/Merge.php b/app/code/Magento/Core/Model/Layout/Merge.php
index d12c1a07b96..4ada2648411 100644
--- a/app/code/Magento/Core/Model/Layout/Merge.php
+++ b/app/code/Magento/Core/Model/Layout/Merge.php
@@ -132,6 +132,27 @@ class Merge implements \Magento\Framework\View\Layout\ProcessorInterface
      */
     protected $cacheSuffix;
 
+    /**
+     * Status for new added handle
+     *
+     * @var int
+     */
+    protected $handleAdded = 1;
+
+    /**
+     * Status for handle being processed
+     *
+     * @var int
+     */
+    protected $handleProcessing = 2;
+
+    /**
+     * Status for processed handle
+     *
+     * @var int
+     */
+    protected $handleProcessed = 3;
+
     /**
      * Init merge model
      *
@@ -217,10 +238,10 @@ class Merge implements \Magento\Framework\View\Layout\ProcessorInterface
     {
         if (is_array($handleName)) {
             foreach ($handleName as $name) {
-                $this->_handles[$name] = 1;
+                $this->_handles[$name] = $this->handleAdded;
             }
         } else {
-            $this->_handles[$handleName] = 1;
+            $this->_handles[$handleName] = $this->handleAdded;
         }
         return $this;
     }
@@ -477,8 +498,17 @@ class Merge implements \Magento\Framework\View\Layout\ProcessorInterface
      */
     protected function _merge($handle)
     {
-        $this->_fetchPackageLayoutUpdates($handle);
-        $this->_fetchDbLayoutUpdates($handle);
+        if (!isset($this->_handles[$handle]) || $this->_handles[$handle] == $this->handleAdded) {
+            $this->_handles[$handle] = $this->handleProcessing;
+            $this->_fetchPackageLayoutUpdates($handle);
+            $this->_fetchDbLayoutUpdates($handle);
+            $this->_handles[$handle] = $this->handleProcessed;
+        } elseif ($this->_handles[$handle] == $this->handleProcessing
+            && $this->_appState->getMode() === \Magento\Framework\App\State::MODE_DEVELOPER
+        ) {
+            $this->_logger->addStreamLog(\Magento\Framework\Logger::LOGGER_SYSTEM);
+            $this->_logger->log('Cyclic dependency in merged layout for handle: ' . $handle, \Zend_Log::ERR);
+        }
         return $this;
     }
 
@@ -573,8 +603,6 @@ class Merge implements \Magento\Framework\View\Layout\ProcessorInterface
         foreach ($updateXml->children() as $child) {
             if (strtolower($child->getName()) == 'update' && isset($child['handle'])) {
                 $this->_merge((string)$child['handle']);
-                // Adding merged layout handle to the list of applied handles
-                $this->addHandle((string)$child['handle']);
             }
         }
         if (isset($updateXml['layout'])) {
diff --git a/app/code/Magento/Review/view/frontend/layout/checkout_cart_configure.xml b/app/code/Magento/Review/view/frontend/layout/checkout_cart_configure.xml
index 94b9ab84772..046550a20b8 100644
--- a/app/code/Magento/Review/view/frontend/layout/checkout_cart_configure.xml
+++ b/app/code/Magento/Review/view/frontend/layout/checkout_cart_configure.xml
@@ -5,6 +5,7 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+    <update handle="catalog_product_view"/>
     <body>
         <referenceBlock name="reviews.tab">
             <block class="Magento\Review\Block\Form\Configure" name="product.review.form" as="review_form">
diff --git a/app/code/Magento/Review/view/frontend/layout/wishlist_index_configure.xml b/app/code/Magento/Review/view/frontend/layout/wishlist_index_configure.xml
index 94b9ab84772..046550a20b8 100644
--- a/app/code/Magento/Review/view/frontend/layout/wishlist_index_configure.xml
+++ b/app/code/Magento/Review/view/frontend/layout/wishlist_index_configure.xml
@@ -5,6 +5,7 @@
  */
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+    <update handle="catalog_product_view"/>
     <body>
         <referenceBlock name="reviews.tab">
             <block class="Magento\Review\Block\Form\Configure" name="product.review.form" as="review_form">
-- 
GitLab


From f2c827ddeab2f1377ba832aa4a4581afeecb077e Mon Sep 17 00:00:00 2001
From: Sergey Ivashchenko <sivashchenko@ebay.com>
Date: Wed, 24 Dec 2014 15:36:13 +0200
Subject: [PATCH 56/71] MAGETWO-27636: Persistent Shopping Cart: Not Username?
 link is displayed during page load for user logged in

---
 app/code/Magento/Persistent/etc/frontend/di.xml | 2 +-
 app/code/Magento/Persistent/etc/module.xml      | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/app/code/Magento/Persistent/etc/frontend/di.xml b/app/code/Magento/Persistent/etc/frontend/di.xml
index a3d5a161a17..d35e4c3dc20 100644
--- a/app/code/Magento/Persistent/etc/frontend/di.xml
+++ b/app/code/Magento/Persistent/etc/frontend/di.xml
@@ -13,7 +13,7 @@
         </arguments>
     </type>
     <type name="Magento\Framework\View\Layout">
-        <plugin name="customer-session-depersonalize"
+        <plugin name="persistent-session-depersonalize"
                 type="Magento\Persistent\Model\Layout\DepersonalizePlugin"
                 sortOrder="10"
         />
diff --git a/app/code/Magento/Persistent/etc/module.xml b/app/code/Magento/Persistent/etc/module.xml
index 0a201d7d4ef..c71ae0efdf4 100644
--- a/app/code/Magento/Persistent/etc/module.xml
+++ b/app/code/Magento/Persistent/etc/module.xml
@@ -8,6 +8,7 @@
     <module name="Magento_Persistent" schema_version="2.0.0">
         <sequence>
             <module name="Magento_Checkout"/>
+            <module name="Magento_PageCache"/>
         </sequence>
     </module>
 </config>
-- 
GitLab


From 33dc4a840ea7b586d6569f392dba36589e62eb2b Mon Sep 17 00:00:00 2001
From: Sergey Ivashchenko <sivashchenko@ebay.com>
Date: Wed, 24 Dec 2014 15:52:02 +0200
Subject: [PATCH 57/71] MAGETWO-32110: Create pull request for all bugfixes
 made while code freeze

---
 .../functional/testsuites/Mtf/TestSuite/EndToEndCETests.php   | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/dev/tests/functional/testsuites/Mtf/TestSuite/EndToEndCETests.php b/dev/tests/functional/testsuites/Mtf/TestSuite/EndToEndCETests.php
index a02b42d41ea..42243f0d1d7 100755
--- a/dev/tests/functional/testsuites/Mtf/TestSuite/EndToEndCETests.php
+++ b/dev/tests/functional/testsuites/Mtf/TestSuite/EndToEndCETests.php
@@ -39,8 +39,8 @@ class EndToEndCETests
         $suite->addTestSuite('Magento\CatalogSearch\Test\TestCase\AdvancedSearchTest');
 
         // Url rewrites
-        $suite->addTestSuite('Magento\Urlrewrite\Test\TestCase\ProductTest');
-        $suite->addTestSuite('Magento\Urlrewrite\Test\TestCase\CategoryTest');
+        $suite->addTestSuite('Magento\UrlRewrite\Test\TestCase\ProductTest');
+        $suite->addTestSuite('Magento\UrlRewrite\Test\TestCase\CategoryTest');
 
         // Customer
         $suite->addTestSuite('Magento\Customer\Test\TestCase\BackendCustomerCreateTest');
-- 
GitLab


From 5e4be3b532b7027fbe8bab04034859057cfd9550 Mon Sep 17 00:00:00 2001
From: Sergey Ivashchenko <sivashchenko@ebay.com>
Date: Wed, 24 Dec 2014 16:57:39 +0200
Subject: [PATCH 58/71] MAGETWO-32110: Create pull request for all bugfixes
 made while code freeze

---
 app/code/Magento/Persistent/composer.json | 1 +
 1 file changed, 1 insertion(+)

diff --git a/app/code/Magento/Persistent/composer.json b/app/code/Magento/Persistent/composer.json
index f875228c958..b09817d8ff1 100644
--- a/app/code/Magento/Persistent/composer.json
+++ b/app/code/Magento/Persistent/composer.json
@@ -9,6 +9,7 @@
         "magento/module-customer": "0.42.0-beta1",
         "magento/module-sales": "0.42.0-beta1",
         "magento/module-cron": "0.42.0-beta1",
+        "magento/module-page-cache": "0.42.0-beta1",
         "magento/framework": "0.42.0-beta1",
         "magento/magento-composer-installer": "*"
     },
-- 
GitLab


From f5c8db9d850c05df9b2e026331fec5cc6b324cd4 Mon Sep 17 00:00:00 2001
From: Andriy Nasinnyk <anasinnyk@ebay.com>
Date: Wed, 24 Dec 2014 18:38:32 +0200
Subject: [PATCH 59/71] MAGETWO-13915: PSR-3: common interface for logging
 libraries.

 - remove unusable values from config
---
 app/code/Magento/Core/etc/config.xml | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/app/code/Magento/Core/etc/config.xml b/app/code/Magento/Core/etc/config.xml
index 77708c97520..dda5079bb16 100644
--- a/app/code/Magento/Core/etc/config.xml
+++ b/app/code/Magento/Core/etc/config.xml
@@ -19,11 +19,6 @@
             <debug>
                 <profiler>0</profiler>
             </debug>
-            <log>
-                <active>0</active>
-                <file>system.log</file>
-                <exception_file>exception.log</exception_file>
-            </log>
             <js>
                 <merge_files>0</merge_files>
                 <minify_files>0</minify_files>
-- 
GitLab


From 7d85edf41541a6342dcfdf2c3814032fe95cbb6c Mon Sep 17 00:00:00 2001
From: Andriy Nasinnyk <anasinnyk@ebay.com>
Date: Wed, 24 Dec 2014 18:42:07 +0200
Subject: [PATCH 60/71] MAGETWO-13915: PSR-3: common interface for logging
 libraries.

 - fix after merge
---
 app/code/Magento/Core/Model/Layout/Merge.php | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/app/code/Magento/Core/Model/Layout/Merge.php b/app/code/Magento/Core/Model/Layout/Merge.php
index fd0fb54b23f..a1533f98efb 100644
--- a/app/code/Magento/Core/Model/Layout/Merge.php
+++ b/app/code/Magento/Core/Model/Layout/Merge.php
@@ -505,8 +505,7 @@ class Merge implements \Magento\Framework\View\Layout\ProcessorInterface
         } elseif ($this->_handles[$handle] == $this->handleProcessing
             && $this->_appState->getMode() === \Magento\Framework\App\State::MODE_DEVELOPER
         ) {
-            $this->_logger->addStreamLog(\Magento\Framework\Logger::LOGGER_SYSTEM);
-            $this->_logger->log('Cyclic dependency in merged layout for handle: ' . $handle, \Zend_Log::ERR);
+            $this->_logger->info('Cyclic dependency in merged layout for handle: ' . $handle);
         }
         return $this;
     }
-- 
GitLab


From 6c71ee9673238bd9dd7e1ecd5d9aa91b7242ba6a Mon Sep 17 00:00:00 2001
From: Andriy Nasinnyk <anasinnyk@ebay.com>
Date: Wed, 24 Dec 2014 19:16:38 +0200
Subject: [PATCH 61/71] MAGETWO-13915: PSR-3: common interface for logging
 libraries.

 - remove backend configuration for log
---
 .../Magento/Backend/etc/adminhtml/system.xml    | 17 -----------------
 1 file changed, 17 deletions(-)

diff --git a/app/code/Magento/Backend/etc/adminhtml/system.xml b/app/code/Magento/Backend/etc/adminhtml/system.xml
index fb99df20fc9..888b0855bb9 100644
--- a/app/code/Magento/Backend/etc/adminhtml/system.xml
+++ b/app/code/Magento/Backend/etc/adminhtml/system.xml
@@ -193,23 +193,6 @@
                     <comment>Translate, blocks and other output caches should be disabled for both frontend and admin inline translations.</comment>
                 </field>
             </group>
-            <group id="log" translate="label" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
-                <label>Log Settings</label>
-                <field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Enabled</label>
-                    <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                </field>
-                <field id="file" translate="label comment" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>System Log File Name</label>
-                    <backend_model>Magento\Backend\Model\Config\Backend\Filename</backend_model>
-                    <comment>Logging from \Psr\Log\LoggerInterface. File is located in {{base_dir}}/var/log</comment>
-                </field>
-                <field id="exception_file" translate="label comment" type="text" sortOrder="3" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Exceptions Log File Name</label>
-                    <backend_model>Magento\Backend\Model\Config\Backend\Filename</backend_model>
-                    <comment>Logging from \Psr\Log\LoggerInterface. File is located in {{base_dir}}/var/log</comment>
-                </field>
-            </group>
             <group id="js" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1">
                 <label>JavaScript Settings</label>
                 <field id="merge_files" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
-- 
GitLab


From 0f9cd5e6a607bde09d1c30cb201b6de32c7c0943 Mon Sep 17 00:00:00 2001
From: Dmytro Aponasenko <daponasenko@ebay.com>
Date: Wed, 24 Dec 2014 15:01:28 +0200
Subject: [PATCH 62/71] MTA-1247: Sync qmt repository with mainline - Sprint 2

---
 dev/tests/functional/composer.json                          | 2 +-
 .../Magento/Catalog/Test/Block/Adminhtml/Category/Tree.php  | 6 ++++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/dev/tests/functional/composer.json b/dev/tests/functional/composer.json
index ab4bd87728a..e2e3d4ad289 100644
--- a/dev/tests/functional/composer.json
+++ b/dev/tests/functional/composer.json
@@ -1,6 +1,6 @@
 {
     "require": {
-        "magento/mtf": "1.0.0-rc10",
+        "magento/mtf": "1.0.0-rc11",
         "php": ">=5.4.0",
         "phpunit/phpunit": "4.1.0",
         "phpunit/phpunit-selenium": ">=1.2",
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Tree.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Tree.php
index 6402bd1873a..851892347af 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Tree.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Tree.php
@@ -121,9 +121,11 @@ class Tree extends Block
     protected function prepareFullCategoryPath(CatalogCategory $category)
     {
         $path = [];
-        $parentCategory = $category->getDataFieldConfig('parent_id')['source']->getParentCategory();
+        $parentCategory = $category->hasData('parent_id')
+            ? $category->getDataFieldConfig('parent_id')['source']->getParentCategory()
+            : null;
 
-        if ($parentCategory != null) {
+        if ($parentCategory !== null) {
             $path = $this->prepareFullCategoryPath($parentCategory);
         }
         return array_filter(array_merge($path, [$category->getPath(), $category->getName()]));
-- 
GitLab


From db238eedaeccf507d6127f35f5b25e2ab9639393 Mon Sep 17 00:00:00 2001
From: Andriy Nasinnyk <anasinnyk@ebay.com>
Date: Thu, 25 Dec 2014 14:48:39 +0200
Subject: [PATCH 63/71] MAGETWO-13915: PSR-3: common interface for logging
 libraries.

 - split debug and info log type to separate files
---
 app/code/Magento/Backend/Model/Menu.php       |  4 ++--
 .../Backend/Model/Menu/Director/Director.php  |  2 +-
 .../Model/Carrier/AbstractCarrier.php         |  2 +-
 app/code/Magento/Ups/Model/Carrier.php        |  2 +-
 app/etc/di.xml                                |  1 +
 .../Image/Adapter/AbstractAdapter.php         |  2 +-
 .../Framework/Logger/Handler/Debug.php        | 21 +++++++++++++++++++
 .../Framework/Logger/Handler/System.php       |  2 +-
 .../Magento/Framework/Message/Manager.php     |  2 +-
 .../Framework/View/Layout/Generator/Block.php |  2 +-
 .../View/Layout/ScheduledStructure/Helper.php |  2 +-
 11 files changed, 32 insertions(+), 10 deletions(-)
 create mode 100644 lib/internal/Magento/Framework/Logger/Handler/Debug.php

diff --git a/app/code/Magento/Backend/Model/Menu.php b/app/code/Magento/Backend/Model/Menu.php
index 582ab34871e..79fd68d8edb 100644
--- a/app/code/Magento/Backend/Model/Menu.php
+++ b/app/code/Magento/Backend/Model/Menu.php
@@ -55,7 +55,7 @@ class Menu extends \ArrayObject
             $index = intval($index);
             if (!isset($this[$index])) {
                 $this->offsetSet($index, $item);
-                $this->_logger->debug(
+                $this->_logger->info(
                     sprintf('Add of item with id %s was processed', $item->getId())
                 );
             } else {
@@ -120,7 +120,7 @@ class Menu extends \ArrayObject
             if ($item->getId() == $itemId) {
                 unset($this[$key]);
                 $result = true;
-                $this->_logger->debug(
+                $this->_logger->info(
                     sprintf('Remove on item with id %s was processed', $item->getId())
                 );
                 break;
diff --git a/app/code/Magento/Backend/Model/Menu/Director/Director.php b/app/code/Magento/Backend/Model/Menu/Director/Director.php
index ccd4f69f11e..0d77330ecb0 100644
--- a/app/code/Magento/Backend/Model/Menu/Director/Director.php
+++ b/app/code/Magento/Backend/Model/Menu/Director/Director.php
@@ -24,7 +24,7 @@ class Director extends \Magento\Backend\Model\Menu\AbstractDirector
     {
         $command = $this->_commandFactory->create($data['type'], ['data' => $data]);
         if (isset($this->_messagePatterns[$data['type']])) {
-            $logger->debug(
+            $logger->info(
                 sprintf($this->_messagePatterns[$data['type']], $command->getId())
             );
         }
diff --git a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrier.php b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrier.php
index 1f695dcf1e6..21a384ed884 100644
--- a/app/code/Magento/Shipping/Model/Carrier/AbstractCarrier.php
+++ b/app/code/Magento/Shipping/Model/Carrier/AbstractCarrier.php
@@ -568,7 +568,7 @@ abstract class AbstractCarrier extends \Magento\Framework\Object implements Abst
     protected function _debug($debugData)
     {
         if ($this->getDebugFlag()) {
-            $this->_logger->info($debugData);
+            $this->_logger->debug($debugData);
         }
     }
 
diff --git a/app/code/Magento/Ups/Model/Carrier.php b/app/code/Magento/Ups/Model/Carrier.php
index fca08cfbd1e..8a5ea44b6ef 100644
--- a/app/code/Magento/Ups/Model/Carrier.php
+++ b/app/code/Magento/Ups/Model/Carrier.php
@@ -515,7 +515,7 @@ class Carrier extends AbstractCarrierOnline implements CarrierInterface
                         $message = __(
                             'Sorry, something went wrong. Please try again or contact us and we\'ll try to help.'
                         );
-                        $this->_logger->info($message . ': ' . $errorTitle);
+                        $this->_logger->debug($message . ': ' . $errorTitle);
                         break;
                     case 6:
                         if (in_array($row[3], $allowedMethods)) {
diff --git a/app/etc/di.xml b/app/etc/di.xml
index c5259bd3c87..5fa642e9363 100644
--- a/app/etc/di.xml
+++ b/app/etc/di.xml
@@ -97,6 +97,7 @@
             <argument name="handlers"  xsi:type="array">
                 <item name="exception" xsi:type="object">Magento\Framework\Logger\Handler\Critical</item>
                 <item name="system" xsi:type="object">Magento\Framework\Logger\Handler\System</item>
+                <item name="debug" xsi:type="object">Magento\Framework\Logger\Handler\Debug</item>
             </argument>
         </arguments>
     </type>
diff --git a/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php b/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php
index c6baaa31867..bd5b3a6cf23 100644
--- a/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php
+++ b/lib/internal/Magento/Framework/Image/Adapter/AbstractAdapter.php
@@ -675,7 +675,7 @@ abstract class AbstractAdapter implements AdapterInterface
             try {
                 $this->directoryWrite->create($this->directoryWrite->getRelativePath($destination));
             } catch (\Magento\Framework\Filesystem\FilesystemException $e) {
-                $this->logger->info($e->getMessage());
+                $this->logger->critical($e);
                 throw new \Exception('Unable to write file into directory ' . $destination . '. Access forbidden.');
             }
         }
diff --git a/lib/internal/Magento/Framework/Logger/Handler/Debug.php b/lib/internal/Magento/Framework/Logger/Handler/Debug.php
new file mode 100644
index 00000000000..ed360efb95d
--- /dev/null
+++ b/lib/internal/Magento/Framework/Logger/Handler/Debug.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Framework\Logger\Handler;
+
+use Monolog\Logger;
+
+class Debug extends System
+{
+    /**
+     * @var string
+     */
+    protected $fileName = '/var/log/debug.log';
+
+    /**
+     * @var int
+     */
+    protected $loggerType = Logger::DEBUG;
+}
diff --git a/lib/internal/Magento/Framework/Logger/Handler/System.php b/lib/internal/Magento/Framework/Logger/Handler/System.php
index 6bc2157a558..39f50b524d9 100644
--- a/lib/internal/Magento/Framework/Logger/Handler/System.php
+++ b/lib/internal/Magento/Framework/Logger/Handler/System.php
@@ -19,7 +19,7 @@ class System extends StreamHandler
     /**
      * @var int
      */
-    protected $loggerType = Logger::DEBUG;
+    protected $loggerType = Logger::INFO;
 
     /**
      * @var DriverInterface
diff --git a/lib/internal/Magento/Framework/Message/Manager.php b/lib/internal/Magento/Framework/Message/Manager.php
index e1bac02e7f0..739cdb0dbf5 100644
--- a/lib/internal/Magento/Framework/Message/Manager.php
+++ b/lib/internal/Magento/Framework/Message/Manager.php
@@ -258,7 +258,7 @@ class Manager implements ManagerInterface
             $exception->getTraceAsString()
         );
 
-        $this->logger->debug($message);
+        $this->logger->critical($message);
         $this->addMessage($this->messageFactory->create(MessageInterface::TYPE_ERROR, $alternativeText), $group);
         return $this;
     }
diff --git a/lib/internal/Magento/Framework/View/Layout/Generator/Block.php b/lib/internal/Magento/Framework/View/Layout/Generator/Block.php
index 1fb604e81f1..1b192f422b0 100644
--- a/lib/internal/Magento/Framework/View/Layout/Generator/Block.php
+++ b/lib/internal/Magento/Framework/View/Layout/Generator/Block.php
@@ -172,7 +172,7 @@ class Block implements Layout\GeneratorInterface
             try {
                 $block = $this->blockFactory->createBlock($block, $arguments);
             } catch (\ReflectionException $e) {
-                $this->logger->info($e->getMessage());
+                $this->logger->critical($e->getMessage());
             }
         }
         if (!$block instanceof \Magento\Framework\View\Element\AbstractBlock) {
diff --git a/lib/internal/Magento/Framework/View/Layout/ScheduledStructure/Helper.php b/lib/internal/Magento/Framework/View/Layout/ScheduledStructure/Helper.php
index 0c919eb96ea..e0258bdcff7 100644
--- a/lib/internal/Magento/Framework/View/Layout/ScheduledStructure/Helper.php
+++ b/lib/internal/Magento/Framework/View/Layout/ScheduledStructure/Helper.php
@@ -185,7 +185,7 @@ class Helper
                 try {
                     $structure->setAsChild($name, $parentName, $alias);
                 } catch (\Exception $e) {
-                    $this->logger->info($e->getMessage());
+                    $this->logger->critical($e);
                 }
             } else {
                 $this->logger->info(
-- 
GitLab


From e4b6347694c595733b9caf0ace8d62582c5f915e Mon Sep 17 00:00:00 2001
From: Max Y <max@magento.com>
Date: Fri, 26 Dec 2014 17:24:01 +0200
Subject: [PATCH 64/71] MAGETWO-31051: M2 GitHub Update (version 0.42.0-beta2)

---
 CHANGELOG.md                                  | 27 +++++++++++
 .../Magento/AdminNotification/composer.json   | 10 ++--
 app/code/Magento/Authorization/composer.json  |  6 +--
 app/code/Magento/Backend/composer.json        | 34 ++++++-------
 app/code/Magento/Backup/composer.json         | 12 ++---
 app/code/Magento/Bundle/composer.json         | 30 ++++++------
 app/code/Magento/Captcha/composer.json        | 14 +++---
 app/code/Magento/Catalog/composer.json        | 48 +++++++++----------
 .../Magento/CatalogImportExport/composer.json | 20 ++++----
 .../Magento/CatalogInventory/composer.json    | 18 +++----
 app/code/Magento/CatalogRule/composer.json    | 20 ++++----
 app/code/Magento/CatalogSearch/composer.json  | 24 +++++-----
 .../Magento/CatalogUrlRewrite/composer.json   | 18 +++----
 app/code/Magento/CatalogWidget/composer.json  | 22 ++++-----
 app/code/Magento/Centinel/composer.json       | 14 +++---
 app/code/Magento/Checkout/composer.json       | 38 +++++++--------
 .../Magento/CheckoutAgreements/composer.json  | 10 ++--
 app/code/Magento/Cms/composer.json            | 20 ++++----
 app/code/Magento/CmsUrlRewrite/composer.json  | 10 ++--
 .../ConfigurableImportExport/composer.json    | 14 +++---
 .../Magento/ConfigurableProduct/composer.json | 28 +++++------
 app/code/Magento/Contact/composer.json        | 12 ++---
 app/code/Magento/Core/composer.json           | 16 +++----
 app/code/Magento/Cron/composer.json           |  8 ++--
 app/code/Magento/CurrencySymbol/composer.json | 14 +++---
 app/code/Magento/Customer/composer.json       | 38 +++++++--------
 .../CustomerImportExport/composer.json        | 18 +++----
 app/code/Magento/DesignEditor/composer.json   | 14 +++---
 app/code/Magento/Dhl/composer.json            | 22 ++++-----
 app/code/Magento/Directory/composer.json      | 10 ++--
 app/code/Magento/Downloadable/composer.json   | 34 ++++++-------
 app/code/Magento/Eav/composer.json            | 12 ++---
 app/code/Magento/Email/composer.json          | 12 ++---
 app/code/Magento/Fedex/composer.json          | 18 +++----
 app/code/Magento/GiftMessage/composer.json    | 22 ++++-----
 app/code/Magento/GoogleAdwords/composer.json  |  8 ++--
 .../Magento/GoogleAnalytics/composer.json     |  8 ++--
 .../Magento/GoogleOptimizer/composer.json     | 14 +++---
 app/code/Magento/GoogleShopping/composer.json | 20 ++++----
 .../Magento/GroupedImportExport/composer.json | 14 +++---
 app/code/Magento/GroupedProduct/composer.json | 24 +++++-----
 app/code/Magento/ImportExport/composer.json   | 14 +++---
 app/code/Magento/Indexer/composer.json        |  8 ++--
 app/code/Magento/Integration/composer.json    | 16 +++----
 .../Magento/LayeredNavigation/composer.json   |  8 ++--
 app/code/Magento/Log/composer.json            | 14 +++---
 app/code/Magento/Msrp/composer.json           | 22 ++++-----
 app/code/Magento/Multishipping/composer.json  | 20 ++++----
 app/code/Magento/Newsletter/composer.json     | 22 ++++-----
 .../Magento/OfflinePayments/composer.json     |  6 +--
 .../Magento/OfflineShipping/composer.json     | 20 ++++----
 app/code/Magento/PageCache/composer.json      |  8 ++--
 app/code/Magento/Payment/composer.json        | 14 +++---
 app/code/Magento/Persistent/composer.json     | 18 +++----
 app/code/Magento/ProductAlert/composer.json   | 12 ++---
 app/code/Magento/Reports/composer.json        | 36 +++++++-------
 app/code/Magento/RequireJs/composer.json      |  4 +-
 app/code/Magento/Review/composer.json         | 22 ++++-----
 app/code/Magento/Rss/composer.json            | 10 ++--
 app/code/Magento/Rule/composer.json           | 12 ++---
 app/code/Magento/Sales/composer.json          | 46 +++++++++---------
 app/code/Magento/SalesRule/composer.json      | 32 ++++++-------
 app/code/Magento/Search/composer.json         | 10 ++--
 app/code/Magento/Sendfriend/composer.json     | 14 +++---
 app/code/Magento/Shipping/composer.json       | 30 ++++++------
 app/code/Magento/Sitemap/composer.json        | 18 +++----
 app/code/Magento/Store/composer.json          | 10 ++--
 app/code/Magento/Tax/composer.json            | 26 +++++-----
 .../Magento/TaxImportExport/composer.json     | 12 ++---
 app/code/Magento/Theme/composer.json          | 18 +++----
 app/code/Magento/Translation/composer.json    | 10 ++--
 app/code/Magento/Ui/composer.json             | 10 ++--
 app/code/Magento/Ups/composer.json            | 18 +++----
 app/code/Magento/UrlRewrite/composer.json     | 18 +++----
 app/code/Magento/User/composer.json           | 18 +++----
 app/code/Magento/Usps/composer.json           | 18 +++----
 app/code/Magento/Webapi/composer.json         | 16 +++----
 app/code/Magento/Weee/composer.json           | 22 ++++-----
 app/code/Magento/Widget/composer.json         | 14 +++---
 app/code/Magento/Wishlist/composer.json       | 34 ++++++-------
 .../adminhtml/Magento/backend/composer.json   |  4 +-
 .../frontend/Magento/blank/composer.json      |  4 +-
 .../frontend/Magento/luma/composer.json       |  6 +--
 app/i18n/magento/de_de/composer.json          |  4 +-
 app/i18n/magento/en_us/composer.json          |  4 +-
 app/i18n/magento/es_es/composer.json          |  4 +-
 app/i18n/magento/fr_fr/composer.json          |  4 +-
 app/i18n/magento/nl_nl/composer.json          |  4 +-
 app/i18n/magento/pt_br/composer.json          |  4 +-
 app/i18n/magento/zh_cn/composer.json          |  4 +-
 composer.json                                 |  2 +-
 .../Magento/Framework/AppInterface.php        |  2 +-
 lib/internal/Magento/Framework/composer.json  |  2 +-
 93 files changed, 765 insertions(+), 738 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index cfa1a4ac96c..b24b1360750 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,30 @@
+0.42.0-beta2
+=============
+* Framework improvements:
+    * Added composer.lock to the repository
+* Various improvements:
+    * Magento PSR-3 compliance
+    * Updated file iterators to work with symlinks
+    * Replaced end-to-end test for advanced search with injectable test
+    * Replaced end-to-end test for quick search with injectable test
+* Fixed bugs:
+    * Fixed an issue where an exception occurred when adding configurable products to cart from the wishlist
+    * Modify .gitignore CE according to new repos structure (MAGETWO-32095)
+    * Fixed an issue where the 'Not %Username%?' link was displayed for a logged in user while pages were loaded
+    * Fixed an issue where Shopping Cart Price Rules based on product attributes were not applied to configurable products
+    * Fixed an issue where the Tax Class drop-down field on New Customer Group page contained the 'none' value when a tax class already existed
+    * Fixed an issue where the 'Credit Memo' button was absent on the Invoice page for payments
+    * Fixed an issue where incorrect totals were shown in the Coupon Usage report
+    * Fixed an issue where an error occurred and the "Append Comments" checkbox was cleared when submitting an order in the backend
+    * Fixed an issue where the Transactions tab appeared in the backend for orders where offline payment methods were used
+    * Fixed an issue with the extra empty line appearing in the Customer Address template
+* Github requests:
+    * [#853](https://github.com/magento/magento2/pull/853) -- Fix spelling error in Customer module xml
+    * [#858](https://github.com/magento/magento2/pull/858) -- Clicking CMS page in backend takes you to the dashboard
+    * [#858](https://github.com/magento/magento2/issues/816) -- Clicking CMS page takes you to the dashboard
+    * [#859](https://github.com/magento/magento2/pull/859) -- Fix email template creation date not being persisted
+    * [#860](https://github.com/magento/magento2/pull/860) -- Fix currency and price renderer
+
 0.42.0-beta1
 =============
 * Fixed bugs:
diff --git a/app/code/Magento/AdminNotification/composer.json b/app/code/Magento/AdminNotification/composer.json
index 88889376147..c535ad1fe78 100644
--- a/app/code/Magento/AdminNotification/composer.json
+++ b/app/code/Magento/AdminNotification/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Authorization/composer.json b/app/code/Magento/Authorization/composer.json
index 38c4e3fbde9..531bda8586e 100644
--- a/app/code/Magento/Authorization/composer.json
+++ b/app/code/Magento/Authorization/composer.json
@@ -3,12 +3,12 @@
     "description": "Authorization module provides access to Magento ACL functionality.",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Backend/composer.json b/app/code/Magento/Backend/composer.json
index 53c2f7f2821..aeec76291c9 100644
--- a/app/code/Magento/Backend/composer.json
+++ b/app/code/Magento/Backend/composer.json
@@ -3,26 +3,26 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-cron": "0.42.0-beta1",
-        "magento/module-theme": "0.42.0-beta1",
-        "magento/module-reports": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-user": "0.42.0-beta1",
-        "magento/module-backup": "0.42.0-beta1",
-        "magento/module-email": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-translation": "0.42.0-beta1",
-        "magento/module-require-js": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-cron": "0.42.0-beta2",
+        "magento/module-theme": "0.42.0-beta2",
+        "magento/module-reports": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-user": "0.42.0-beta2",
+        "magento/module-backup": "0.42.0-beta2",
+        "magento/module-email": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-translation": "0.42.0-beta2",
+        "magento/module-require-js": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Backup/composer.json b/app/code/Magento/Backup/composer.json
index e942ee4651a..607d773f948 100644
--- a/app/code/Magento/Backup/composer.json
+++ b/app/code/Magento/Backup/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-cron": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-cron": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Bundle/composer.json b/app/code/Magento/Bundle/composer.json
index 775e22220ac..361d5902c7b 100644
--- a/app/code/Magento/Bundle/composer.json
+++ b/app/code/Magento/Bundle/composer.json
@@ -3,24 +3,24 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-tax": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-checkout": "0.42.0-beta1",
-        "magento/module-catalog-inventory": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-catalog-rule": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-gift-message": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
-        "magento/module-webapi": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-tax": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-checkout": "0.42.0-beta2",
+        "magento/module-catalog-inventory": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-catalog-rule": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-gift-message": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
+        "magento/module-webapi": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Captcha/composer.json b/app/code/Magento/Captcha/composer.json
index 280c374d313..a8d6ee4d23b 100644
--- a/app/code/Magento/Captcha/composer.json
+++ b/app/code/Magento/Captcha/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-checkout": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-checkout": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Catalog/composer.json b/app/code/Magento/Catalog/composer.json
index 2fd878e1530..fe448355f37 100644
--- a/app/code/Magento/Catalog/composer.json
+++ b/app/code/Magento/Catalog/composer.json
@@ -3,33 +3,33 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-cms": "0.42.0-beta1",
-        "magento/module-indexer": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-theme": "0.42.0-beta1",
-        "magento/module-checkout": "0.42.0-beta1",
-        "magento/module-log": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-widget": "0.42.0-beta1",
-        "magento/module-wishlist": "0.42.0-beta1",
-        "magento/module-tax": "0.42.0-beta1",
-        "magento/module-msrp": "0.42.0-beta1",
-        "magento/module-catalog-inventory": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/module-catalog-rule": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-product-alert": "0.42.0-beta1",
-        "magento/module-url-rewrite": "0.42.0-beta1",
-        "magento/module-catalog-url-rewrite": "0.42.0-beta1",
-        "magento/module-page-cache": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-cms": "0.42.0-beta2",
+        "magento/module-indexer": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-theme": "0.42.0-beta2",
+        "magento/module-checkout": "0.42.0-beta2",
+        "magento/module-log": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-widget": "0.42.0-beta2",
+        "magento/module-wishlist": "0.42.0-beta2",
+        "magento/module-tax": "0.42.0-beta2",
+        "magento/module-msrp": "0.42.0-beta2",
+        "magento/module-catalog-inventory": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/module-catalog-rule": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-product-alert": "0.42.0-beta2",
+        "magento/module-url-rewrite": "0.42.0-beta2",
+        "magento/module-catalog-url-rewrite": "0.42.0-beta2",
+        "magento/module-page-cache": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CatalogImportExport/composer.json b/app/code/Magento/CatalogImportExport/composer.json
index 597c28e83ed..0c8868a542c 100644
--- a/app/code/Magento/CatalogImportExport/composer.json
+++ b/app/code/Magento/CatalogImportExport/composer.json
@@ -3,20 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-import-export": "0.42.0-beta1",
-        "magento/module-indexer": "0.42.0-beta1",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-catalog-inventory": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-import-export": "0.42.0-beta2",
+        "magento/module-indexer": "0.42.0-beta2",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-catalog-inventory": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "ext-ctype": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CatalogInventory/composer.json b/app/code/Magento/CatalogInventory/composer.json
index 43819e95002..adcd06788b1 100644
--- a/app/code/Magento/CatalogInventory/composer.json
+++ b/app/code/Magento/CatalogInventory/composer.json
@@ -3,18 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-indexer": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-indexer": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CatalogRule/composer.json b/app/code/Magento/CatalogRule/composer.json
index 9716d337d02..8f0d6f3203c 100644
--- a/app/code/Magento/CatalogRule/composer.json
+++ b/app/code/Magento/CatalogRule/composer.json
@@ -3,19 +3,19 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-rule": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-indexer": "0.42.0-beta1",
-        "magento/module-import-export": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-rule": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-indexer": "0.42.0-beta2",
+        "magento/module-import-export": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CatalogSearch/composer.json b/app/code/Magento/CatalogSearch/composer.json
index 367e3b7be75..cfc250a47f0 100644
--- a/app/code/Magento/CatalogSearch/composer.json
+++ b/app/code/Magento/CatalogSearch/composer.json
@@ -3,21 +3,21 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-search": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/module-indexer": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-theme": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-search": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/module-indexer": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-theme": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CatalogUrlRewrite/composer.json b/app/code/Magento/CatalogUrlRewrite/composer.json
index 7ea6b9012c9..14b53cbabdb 100644
--- a/app/code/Magento/CatalogUrlRewrite/composer.json
+++ b/app/code/Magento/CatalogUrlRewrite/composer.json
@@ -3,18 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-catalog-import-export": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-import-export": "0.42.0-beta1",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-url-rewrite": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-catalog-import-export": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-import-export": "0.42.0-beta2",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-url-rewrite": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CatalogWidget/composer.json b/app/code/Magento/CatalogWidget/composer.json
index 9fd0e887d4f..9d078bb6a55 100644
--- a/app/code/Magento/CatalogWidget/composer.json
+++ b/app/code/Magento/CatalogWidget/composer.json
@@ -3,20 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-widget": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-rule": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-wishlist": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-widget": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-rule": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-wishlist": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Centinel/composer.json b/app/code/Magento/Centinel/composer.json
index 171bd6c6ccf..88add92445e 100644
--- a/app/code/Magento/Centinel/composer.json
+++ b/app/code/Magento/Centinel/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-checkout": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-checkout": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Checkout/composer.json b/app/code/Magento/Checkout/composer.json
index c9f6e783f68..bfb7b17b422 100644
--- a/app/code/Magento/Checkout/composer.json
+++ b/app/code/Magento/Checkout/composer.json
@@ -3,28 +3,28 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-authorization": "0.42.0-beta1",
-        "magento/module-catalog-inventory": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-payment": "0.42.0-beta1",
-        "magento/module-tax": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-gift-message": "0.42.0-beta1",
-        "magento/module-wishlist": "0.42.0-beta1",
-        "magento/module-page-cache": "0.42.0-beta1",
-        "magento/module-theme": "0.42.0-beta1",
-        "magento/module-msrp": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
-        "magento/module-ui": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-authorization": "0.42.0-beta2",
+        "magento/module-catalog-inventory": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-payment": "0.42.0-beta2",
+        "magento/module-tax": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-gift-message": "0.42.0-beta2",
+        "magento/module-wishlist": "0.42.0-beta2",
+        "magento/module-page-cache": "0.42.0-beta2",
+        "magento/module-theme": "0.42.0-beta2",
+        "magento/module-msrp": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
+        "magento/module-ui": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CheckoutAgreements/composer.json b/app/code/Magento/CheckoutAgreements/composer.json
index ea79b7e58e0..8463f4a91f4 100644
--- a/app/code/Magento/CheckoutAgreements/composer.json
+++ b/app/code/Magento/CheckoutAgreements/composer.json
@@ -3,14 +3,14 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-checkout": "0.42.0-beta1",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-checkout": "0.42.0-beta2",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Cms/composer.json b/app/code/Magento/Cms/composer.json
index 6ab46844c97..a21c486469f 100644
--- a/app/code/Magento/Cms/composer.json
+++ b/app/code/Magento/Cms/composer.json
@@ -3,19 +3,19 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-theme": "0.42.0-beta1",
-        "magento/module-widget": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-email": "0.42.0-beta1",
-        "magento/module-ui": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-theme": "0.42.0-beta2",
+        "magento/module-widget": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-email": "0.42.0-beta2",
+        "magento/module-ui": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CmsUrlRewrite/composer.json b/app/code/Magento/CmsUrlRewrite/composer.json
index 934d840a004..32a478b3fba 100644
--- a/app/code/Magento/CmsUrlRewrite/composer.json
+++ b/app/code/Magento/CmsUrlRewrite/composer.json
@@ -3,14 +3,14 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-cms": "0.42.0-beta1",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-url-rewrite": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-cms": "0.42.0-beta2",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-url-rewrite": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/ConfigurableImportExport/composer.json b/app/code/Magento/ConfigurableImportExport/composer.json
index fac1ee9342d..de3e60c4f3c 100644
--- a/app/code/Magento/ConfigurableImportExport/composer.json
+++ b/app/code/Magento/ConfigurableImportExport/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-catalog-import-export": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-import-export": "0.42.0-beta1",
-        "magento/module-configurable-product": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-catalog-import-export": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-import-export": "0.42.0-beta2",
+        "magento/module-configurable-product": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/ConfigurableProduct/composer.json b/app/code/Magento/ConfigurableProduct/composer.json
index 8b2ef524551..faa5a31fdf9 100644
--- a/app/code/Magento/ConfigurableProduct/composer.json
+++ b/app/code/Magento/ConfigurableProduct/composer.json
@@ -3,23 +3,23 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-catalog-inventory": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-checkout": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-catalog-rule": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
-        "magento/module-webapi": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-catalog-inventory": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-checkout": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-catalog-rule": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
+        "magento/module-webapi": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Contact/composer.json b/app/code/Magento/Contact/composer.json
index 988d8a4014e..21e57df75eb 100644
--- a/app/code/Magento/Contact/composer.json
+++ b/app/code/Magento/Contact/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-cms": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-cms": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Core/composer.json b/app/code/Magento/Core/composer.json
index 4f30dd91346..d0f462f935c 100644
--- a/app/code/Magento/Core/composer.json
+++ b/app/code/Magento/Core/composer.json
@@ -3,18 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-cron": "0.42.0-beta1",
-        "magento/module-theme": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-page-cache": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-cron": "0.42.0-beta2",
+        "magento/module-theme": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-page-cache": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Cron/composer.json b/app/code/Magento/Cron/composer.json
index 99f4759d0ab..26a0c49e2bc 100644
--- a/app/code/Magento/Cron/composer.json
+++ b/app/code/Magento/Cron/composer.json
@@ -3,13 +3,13 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CurrencySymbol/composer.json b/app/code/Magento/CurrencySymbol/composer.json
index b3cf1637ddd..e81038fe6a9 100644
--- a/app/code/Magento/CurrencySymbol/composer.json
+++ b/app/code/Magento/CurrencySymbol/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-page-cache": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-page-cache": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Customer/composer.json b/app/code/Magento/Customer/composer.json
index 48282323309..b43bee3bd52 100644
--- a/app/code/Magento/Customer/composer.json
+++ b/app/code/Magento/Customer/composer.json
@@ -3,28 +3,28 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-newsletter": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-checkout": "0.42.0-beta1",
-        "magento/module-wishlist": "0.42.0-beta1",
-        "magento/module-theme": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-review": "0.42.0-beta1",
-        "magento/module-tax": "0.42.0-beta1",
-        "magento/module-page-cache": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
-        "magento/module-authorization": "0.42.0-beta1",
-        "magento/module-integration": "0.42.0-beta1",
-        "magento/module-ui": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-newsletter": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-checkout": "0.42.0-beta2",
+        "magento/module-wishlist": "0.42.0-beta2",
+        "magento/module-theme": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-review": "0.42.0-beta2",
+        "magento/module-tax": "0.42.0-beta2",
+        "magento/module-page-cache": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
+        "magento/module-authorization": "0.42.0-beta2",
+        "magento/module-integration": "0.42.0-beta2",
+        "magento/module-ui": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/CustomerImportExport/composer.json b/app/code/Magento/CustomerImportExport/composer.json
index d87b7f176a3..eb6cfecd3b8 100644
--- a/app/code/Magento/CustomerImportExport/composer.json
+++ b/app/code/Magento/CustomerImportExport/composer.json
@@ -3,18 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-import-export": "0.42.0-beta1",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-import-export": "0.42.0-beta2",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/DesignEditor/composer.json b/app/code/Magento/DesignEditor/composer.json
index f5ae9e6fba7..badd482f1f9 100644
--- a/app/code/Magento/DesignEditor/composer.json
+++ b/app/code/Magento/DesignEditor/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-theme": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-theme": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Dhl/composer.json b/app/code/Magento/Dhl/composer.json
index 81853cf0440..6a5e7b77d13 100644
--- a/app/code/Magento/Dhl/composer.json
+++ b/app/code/Magento/Dhl/composer.json
@@ -3,21 +3,21 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-shipping": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-checkout": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-catalog-inventory": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-shipping": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-checkout": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-catalog-inventory": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Directory/composer.json b/app/code/Magento/Directory/composer.json
index 551abbb1217..ffabf1f65c0 100644
--- a/app/code/Magento/Directory/composer.json
+++ b/app/code/Magento/Directory/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Downloadable/composer.json b/app/code/Magento/Downloadable/composer.json
index ad7fd26302c..099aada6176 100644
--- a/app/code/Magento/Downloadable/composer.json
+++ b/app/code/Magento/Downloadable/composer.json
@@ -3,26 +3,26 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-tax": "0.42.0-beta1",
-        "magento/module-theme": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-checkout": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/module-wishlist": "0.42.0-beta1",
-        "magento/module-gift-message": "0.42.0-beta1",
-        "magento/module-catalog-inventory": "0.42.0-beta1",
-        "magento/module-msrp": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-tax": "0.42.0-beta2",
+        "magento/module-theme": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-checkout": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/module-wishlist": "0.42.0-beta2",
+        "magento/module-gift-message": "0.42.0-beta2",
+        "magento/module-catalog-inventory": "0.42.0-beta2",
+        "magento/module-msrp": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Eav/composer.json b/app/code/Magento/Eav/composer.json
index 61dd1d12013..401bb5a2f2a 100644
--- a/app/code/Magento/Eav/composer.json
+++ b/app/code/Magento/Eav/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Email/composer.json b/app/code/Magento/Email/composer.json
index bd8e34bf0d2..5cfba4a520a 100644
--- a/app/code/Magento/Email/composer.json
+++ b/app/code/Magento/Email/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-cms": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-cms": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Fedex/composer.json b/app/code/Magento/Fedex/composer.json
index 1dfde1038b9..c986bb2eaa5 100644
--- a/app/code/Magento/Fedex/composer.json
+++ b/app/code/Magento/Fedex/composer.json
@@ -3,19 +3,19 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-shipping": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-catalog-inventory": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-shipping": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-catalog-inventory": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GiftMessage/composer.json b/app/code/Magento/GiftMessage/composer.json
index f3b13f068ee..49c57a5c0af 100644
--- a/app/code/Magento/GiftMessage/composer.json
+++ b/app/code/Magento/GiftMessage/composer.json
@@ -3,20 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-checkout": "0.42.0-beta1",
-        "magento/module-multishipping": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-checkout": "0.42.0-beta2",
+        "magento/module-multishipping": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GoogleAdwords/composer.json b/app/code/Magento/GoogleAdwords/composer.json
index eb6306f9fc8..788dcfae1dd 100644
--- a/app/code/Magento/GoogleAdwords/composer.json
+++ b/app/code/Magento/GoogleAdwords/composer.json
@@ -3,13 +3,13 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GoogleAnalytics/composer.json b/app/code/Magento/GoogleAnalytics/composer.json
index 49221bfc798..6970e094a64 100644
--- a/app/code/Magento/GoogleAnalytics/composer.json
+++ b/app/code/Magento/GoogleAnalytics/composer.json
@@ -3,13 +3,13 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GoogleOptimizer/composer.json b/app/code/Magento/GoogleOptimizer/composer.json
index ebcb1ea65d3..bf78f67b553 100644
--- a/app/code/Magento/GoogleOptimizer/composer.json
+++ b/app/code/Magento/GoogleOptimizer/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-google-analytics": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-cms": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-google-analytics": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-cms": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GoogleShopping/composer.json b/app/code/Magento/GoogleShopping/composer.json
index f7a4d09d570..e495e5483c9 100644
--- a/app/code/Magento/GoogleShopping/composer.json
+++ b/app/code/Magento/GoogleShopping/composer.json
@@ -3,19 +3,19 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-tax": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-tax": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GroupedImportExport/composer.json b/app/code/Magento/GroupedImportExport/composer.json
index 283e65ae98a..aaecfb8a7ef 100644
--- a/app/code/Magento/GroupedImportExport/composer.json
+++ b/app/code/Magento/GroupedImportExport/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-import-export": "0.42.0-beta1",
-        "magento/module-catalog-import-export": "0.42.0-beta1",
-        "magento/module-grouped-product": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-import-export": "0.42.0-beta2",
+        "magento/module-catalog-import-export": "0.42.0-beta2",
+        "magento/module-grouped-product": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/GroupedProduct/composer.json b/app/code/Magento/GroupedProduct/composer.json
index 78119291313..ed6dc4ddd57 100644
--- a/app/code/Magento/GroupedProduct/composer.json
+++ b/app/code/Magento/GroupedProduct/composer.json
@@ -3,21 +3,21 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-catalog-inventory": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-checkout": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-msrp": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-catalog-inventory": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-checkout": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-msrp": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/ImportExport/composer.json b/app/code/Magento/ImportExport/composer.json
index 51959b20870..0333fadc33c 100644
--- a/app/code/Magento/ImportExport/composer.json
+++ b/app/code/Magento/ImportExport/composer.json
@@ -3,17 +3,17 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-indexer": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-indexer": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "ext-ctype": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Indexer/composer.json b/app/code/Magento/Indexer/composer.json
index 16531f08623..1a2e3bcba07 100644
--- a/app/code/Magento/Indexer/composer.json
+++ b/app/code/Magento/Indexer/composer.json
@@ -3,13 +3,13 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-page-cache": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-page-cache": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Integration/composer.json b/app/code/Magento/Integration/composer.json
index a519797a8ea..d30a365c4c9 100644
--- a/app/code/Magento/Integration/composer.json
+++ b/app/code/Magento/Integration/composer.json
@@ -3,17 +3,17 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-user": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
-        "magento/module-authorization": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-user": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
+        "magento/module-authorization": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/LayeredNavigation/composer.json b/app/code/Magento/LayeredNavigation/composer.json
index de31b81e34d..aadf43d71c1 100644
--- a/app/code/Magento/LayeredNavigation/composer.json
+++ b/app/code/Magento/LayeredNavigation/composer.json
@@ -3,13 +3,13 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Log/composer.json b/app/code/Magento/Log/composer.json
index baa3748cbdd..9f97050e77e 100644
--- a/app/code/Magento/Log/composer.json
+++ b/app/code/Magento/Log/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Msrp/composer.json b/app/code/Magento/Msrp/composer.json
index 7203cd93a37..4644a21f2c4 100644
--- a/app/code/Magento/Msrp/composer.json
+++ b/app/code/Magento/Msrp/composer.json
@@ -3,20 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-bundle": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-downloadable": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-grouped-product": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-tax": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-bundle": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-downloadable": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-grouped-product": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-tax": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Multishipping/composer.json b/app/code/Magento/Multishipping/composer.json
index 5ac026eaacb..4b6f7bd24ac 100644
--- a/app/code/Magento/Multishipping/composer.json
+++ b/app/code/Magento/Multishipping/composer.json
@@ -3,19 +3,19 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-checkout": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-payment": "0.42.0-beta1",
-        "magento/module-tax": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-theme": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-checkout": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-payment": "0.42.0-beta2",
+        "magento/module-tax": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-theme": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Newsletter/composer.json b/app/code/Magento/Newsletter/composer.json
index 06d75d0352e..8e8c5ea8d79 100644
--- a/app/code/Magento/Newsletter/composer.json
+++ b/app/code/Magento/Newsletter/composer.json
@@ -3,20 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-widget": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-cms": "0.42.0-beta1",
-        "magento/module-email": "0.42.0-beta1",
-        "magento/module-cron": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-widget": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-cms": "0.42.0-beta2",
+        "magento/module-email": "0.42.0-beta2",
+        "magento/module-cron": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/OfflinePayments/composer.json b/app/code/Magento/OfflinePayments/composer.json
index 42c64fde731..3e14de61e13 100644
--- a/app/code/Magento/OfflinePayments/composer.json
+++ b/app/code/Magento/OfflinePayments/composer.json
@@ -3,12 +3,12 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-payment": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-payment": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/OfflineShipping/composer.json b/app/code/Magento/OfflineShipping/composer.json
index b48ea50cc45..013eee21a91 100644
--- a/app/code/Magento/OfflineShipping/composer.json
+++ b/app/code/Magento/OfflineShipping/composer.json
@@ -3,19 +3,19 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-shipping": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-sales-rule": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/module-checkout": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-shipping": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-sales-rule": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/module-checkout": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/PageCache/composer.json b/app/code/Magento/PageCache/composer.json
index d52cd8ccee9..1fa0f7dbb24 100644
--- a/app/code/Magento/PageCache/composer.json
+++ b/app/code/Magento/PageCache/composer.json
@@ -3,13 +3,13 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Payment/composer.json b/app/code/Magento/Payment/composer.json
index 65ad4e7e09d..bda90a3cbc1 100644
--- a/app/code/Magento/Payment/composer.json
+++ b/app/code/Magento/Payment/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-centinel": "0.42.0-beta1",
-        "magento/module-checkout": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-centinel": "0.42.0-beta2",
+        "magento/module-checkout": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Persistent/composer.json b/app/code/Magento/Persistent/composer.json
index b09817d8ff1..e9dfbcdca9f 100644
--- a/app/code/Magento/Persistent/composer.json
+++ b/app/code/Magento/Persistent/composer.json
@@ -3,18 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-checkout": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-cron": "0.42.0-beta1",
-        "magento/module-page-cache": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-checkout": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-cron": "0.42.0-beta2",
+        "magento/module-page-cache": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/ProductAlert/composer.json b/app/code/Magento/ProductAlert/composer.json
index 5779c042646..ce27de2532c 100644
--- a/app/code/Magento/ProductAlert/composer.json
+++ b/app/code/Magento/ProductAlert/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Reports/composer.json b/app/code/Magento/Reports/composer.json
index 72161143732..1784a532b0e 100644
--- a/app/code/Magento/Reports/composer.json
+++ b/app/code/Magento/Reports/composer.json
@@ -3,27 +3,27 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-cms": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-widget": "0.42.0-beta1",
-        "magento/module-log": "0.42.0-beta1",
-        "magento/module-wishlist": "0.42.0-beta1",
-        "magento/module-review": "0.42.0-beta1",
-        "magento/module-catalog-inventory": "0.42.0-beta1",
-        "magento/module-tax": "0.42.0-beta1",
-        "magento/module-downloadable": "0.42.0-beta1",
-        "magento/module-sales-rule": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-cms": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-widget": "0.42.0-beta2",
+        "magento/module-log": "0.42.0-beta2",
+        "magento/module-wishlist": "0.42.0-beta2",
+        "magento/module-review": "0.42.0-beta2",
+        "magento/module-catalog-inventory": "0.42.0-beta2",
+        "magento/module-tax": "0.42.0-beta2",
+        "magento/module-downloadable": "0.42.0-beta2",
+        "magento/module-sales-rule": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/RequireJs/composer.json b/app/code/Magento/RequireJs/composer.json
index e212cc993b3..7b1ca1f8af0 100644
--- a/app/code/Magento/RequireJs/composer.json
+++ b/app/code/Magento/RequireJs/composer.json
@@ -3,11 +3,11 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/framework": "0.42.0-beta1",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Review/composer.json b/app/code/Magento/Review/composer.json
index 3a4cc6f7ba6..c0aba7261db 100644
--- a/app/code/Magento/Review/composer.json
+++ b/app/code/Magento/Review/composer.json
@@ -3,20 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-theme": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-newsletter": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
-        "magento/module-ui": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-theme": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-newsletter": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
+        "magento/module-ui": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Rss/composer.json b/app/code/Magento/Rss/composer.json
index d3731ff12a1..55830ff619d 100644
--- a/app/code/Magento/Rss/composer.json
+++ b/app/code/Magento/Rss/composer.json
@@ -3,14 +3,14 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Rule/composer.json b/app/code/Magento/Rule/composer.json
index 523a353b858..cabe83db1fe 100644
--- a/app/code/Magento/Rule/composer.json
+++ b/app/code/Magento/Rule/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Sales/composer.json b/app/code/Magento/Sales/composer.json
index a1b36f44f89..5220cd715a0 100644
--- a/app/code/Magento/Sales/composer.json
+++ b/app/code/Magento/Sales/composer.json
@@ -3,32 +3,32 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-authorization": "0.42.0-beta1",
-        "magento/module-payment": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-checkout": "0.42.0-beta1",
-        "magento/module-theme": "0.42.0-beta1",
-        "magento/module-sales-rule": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-widget": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-tax": "0.42.0-beta1",
-        "magento/module-gift-message": "0.42.0-beta1",
-        "magento/module-reports": "0.42.0-beta1",
-        "magento/module-catalog-inventory": "0.42.0-beta1",
-        "magento/module-wishlist": "0.42.0-beta1",
-        "magento/module-email": "0.42.0-beta1",
-        "magento/module-shipping": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
-        "magento/module-ui": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-authorization": "0.42.0-beta2",
+        "magento/module-payment": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-checkout": "0.42.0-beta2",
+        "magento/module-theme": "0.42.0-beta2",
+        "magento/module-sales-rule": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-widget": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-tax": "0.42.0-beta2",
+        "magento/module-gift-message": "0.42.0-beta2",
+        "magento/module-reports": "0.42.0-beta2",
+        "magento/module-catalog-inventory": "0.42.0-beta2",
+        "magento/module-wishlist": "0.42.0-beta2",
+        "magento/module-email": "0.42.0-beta2",
+        "magento/module-shipping": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
+        "magento/module-ui": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/SalesRule/composer.json b/app/code/Magento/SalesRule/composer.json
index b6346dfd07b..5017f8928d7 100644
--- a/app/code/Magento/SalesRule/composer.json
+++ b/app/code/Magento/SalesRule/composer.json
@@ -3,25 +3,25 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-rule": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/module-shipping": "0.42.0-beta1",
-        "magento/module-payment": "0.42.0-beta1",
-        "magento/module-reports": "0.42.0-beta1",
-        "magento/module-catalog-rule": "0.42.0-beta1",
-        "magento/module-widget": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-rule": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/module-shipping": "0.42.0-beta2",
+        "magento/module-payment": "0.42.0-beta2",
+        "magento/module-reports": "0.42.0-beta2",
+        "magento/module-catalog-rule": "0.42.0-beta2",
+        "magento/module-widget": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Search/composer.json b/app/code/Magento/Search/composer.json
index b629eee559f..5043405ad17 100644
--- a/app/code/Magento/Search/composer.json
+++ b/app/code/Magento/Search/composer.json
@@ -3,14 +3,14 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/framework": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-reports": "0.42.0-beta1",
+        "magento/framework": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-reports": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Sendfriend/composer.json b/app/code/Magento/Sendfriend/composer.json
index 1024ff1f331..b9fc79a750c 100644
--- a/app/code/Magento/Sendfriend/composer.json
+++ b/app/code/Magento/Sendfriend/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-theme": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-theme": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Shipping/composer.json b/app/code/Magento/Shipping/composer.json
index 7eaa767a4de..36a2294310b 100644
--- a/app/code/Magento/Shipping/composer.json
+++ b/app/code/Magento/Shipping/composer.json
@@ -3,27 +3,27 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/module-contact": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-payment": "0.42.0-beta1",
-        "magento/module-tax": "0.42.0-beta1",
-        "magento/module-catalog-inventory": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/module-contact": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-payment": "0.42.0-beta2",
+        "magento/module-tax": "0.42.0-beta2",
+        "magento/module-catalog-inventory": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "ext-gd": "*",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-fedex": "0.42.0-beta1",
-        "magento/module-ups": "0.42.0-beta1"
+        "magento/module-fedex": "0.42.0-beta2",
+        "magento/module-ups": "0.42.0-beta2"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Sitemap/composer.json b/app/code/Magento/Sitemap/composer.json
index e8b37f4c468..6394181c86c 100644
--- a/app/code/Magento/Sitemap/composer.json
+++ b/app/code/Magento/Sitemap/composer.json
@@ -3,18 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-cms": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-catalog-url-rewrite": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-cms": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-catalog-url-rewrite": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Store/composer.json b/app/code/Magento/Store/composer.json
index 80bd98f67ee..4ea7b85cd29 100644
--- a/app/code/Magento/Store/composer.json
+++ b/app/code/Magento/Store/composer.json
@@ -3,14 +3,14 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/module-ui": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/module-ui": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Tax/composer.json b/app/code/Magento/Tax/composer.json
index f064cd1b5ad..47a035e7a77 100644
--- a/app/code/Magento/Tax/composer.json
+++ b/app/code/Magento/Tax/composer.json
@@ -3,22 +3,22 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/module-checkout": "0.42.0-beta1",
-        "magento/module-shipping": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-reports": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/module-checkout": "0.42.0-beta2",
+        "magento/module-shipping": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-reports": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/TaxImportExport/composer.json b/app/code/Magento/TaxImportExport/composer.json
index 6e3cb2bb7fb..e3af939b3c2 100644
--- a/app/code/Magento/TaxImportExport/composer.json
+++ b/app/code/Magento/TaxImportExport/composer.json
@@ -3,15 +3,15 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-tax": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-tax": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Theme/composer.json b/app/code/Magento/Theme/composer.json
index 7037f3dd26c..1f40aae7fd2 100644
--- a/app/code/Magento/Theme/composer.json
+++ b/app/code/Magento/Theme/composer.json
@@ -3,20 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-cms": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
-        "magento/module-require-js": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-cms": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
+        "magento/module-require-js": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-translation": "0.42.0-beta1"
+        "magento/module-translation": "0.42.0-beta2"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Translation/composer.json b/app/code/Magento/Translation/composer.json
index f2615a6f2fb..58011a9b5fc 100644
--- a/app/code/Magento/Translation/composer.json
+++ b/app/code/Magento/Translation/composer.json
@@ -3,14 +3,14 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Ui/composer.json b/app/code/Magento/Ui/composer.json
index f6334f24f4e..a718cf1994a 100644
--- a/app/code/Magento/Ui/composer.json
+++ b/app/code/Magento/Ui/composer.json
@@ -3,14 +3,14 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Ups/composer.json b/app/code/Magento/Ups/composer.json
index 1a719011382..70e71fd6080 100644
--- a/app/code/Magento/Ups/composer.json
+++ b/app/code/Magento/Ups/composer.json
@@ -3,18 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-shipping": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/module-catalog-inventory": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-shipping": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/module-catalog-inventory": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/UrlRewrite/composer.json b/app/code/Magento/UrlRewrite/composer.json
index 308cde149bc..9944ab44a73 100644
--- a/app/code/Magento/UrlRewrite/composer.json
+++ b/app/code/Magento/UrlRewrite/composer.json
@@ -3,18 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-catalog-url-rewrite": "0.42.0-beta1",
-        "magento/module-cms": "0.42.0-beta1",
-        "magento/module-cms-url-rewrite": "0.42.0-beta1",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-catalog-url-rewrite": "0.42.0-beta2",
+        "magento/module-cms": "0.42.0-beta2",
+        "magento/module-cms-url-rewrite": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/User/composer.json b/app/code/Magento/User/composer.json
index 551e1a3c969..aecb0497348 100644
--- a/app/code/Magento/User/composer.json
+++ b/app/code/Magento/User/composer.json
@@ -3,18 +3,18 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-authorization": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-integration": "0.42.0-beta1",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-theme": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
-        "magento/module-require-js": "0.42.0-beta1",
+        "magento/module-authorization": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-integration": "0.42.0-beta2",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-theme": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
+        "magento/module-require-js": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Usps/composer.json b/app/code/Magento/Usps/composer.json
index ced6462e5f0..14d57714237 100644
--- a/app/code/Magento/Usps/composer.json
+++ b/app/code/Magento/Usps/composer.json
@@ -3,19 +3,19 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-shipping": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-catalog-inventory": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-shipping": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-catalog-inventory": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "lib-libxml": "*",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Webapi/composer.json b/app/code/Magento/Webapi/composer.json
index 78b24f45b4b..3d520c28732 100644
--- a/app/code/Magento/Webapi/composer.json
+++ b/app/code/Magento/Webapi/composer.json
@@ -3,19 +3,19 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-authorization": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-integration": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-authorization": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-integration": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-user": "0.42.0-beta1"
+        "magento/module-user": "0.42.0-beta2"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Weee/composer.json b/app/code/Magento/Weee/composer.json
index adf13a5fe3f..acee54fa4cc 100644
--- a/app/code/Magento/Weee/composer.json
+++ b/app/code/Magento/Weee/composer.json
@@ -3,20 +3,20 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-tax": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-directory": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-eav": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-tax": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-directory": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-eav": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Widget/composer.json b/app/code/Magento/Widget/composer.json
index 6edce51d361..29a3df73413 100644
--- a/app/code/Magento/Widget/composer.json
+++ b/app/code/Magento/Widget/composer.json
@@ -3,16 +3,16 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-cms": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-cms": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/code/Magento/Wishlist/composer.json b/app/code/Magento/Wishlist/composer.json
index 263a9b27f3f..d72686c8a1e 100644
--- a/app/code/Magento/Wishlist/composer.json
+++ b/app/code/Magento/Wishlist/composer.json
@@ -3,28 +3,28 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/module-store": "0.42.0-beta1",
-        "magento/module-customer": "0.42.0-beta1",
-        "magento/module-catalog": "0.42.0-beta1",
-        "magento/module-core": "0.42.0-beta1",
-        "magento/module-checkout": "0.42.0-beta1",
-        "magento/module-theme": "0.42.0-beta1",
-        "magento/module-catalog-inventory": "0.42.0-beta1",
-        "magento/module-rss": "0.42.0-beta1",
-        "magento/module-backend": "0.42.0-beta1",
-        "magento/module-sales": "0.42.0-beta1",
-        "magento/module-grouped-product": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
-        "magento/module-ui": "0.42.0-beta1",
+        "magento/module-store": "0.42.0-beta2",
+        "magento/module-customer": "0.42.0-beta2",
+        "magento/module-catalog": "0.42.0-beta2",
+        "magento/module-core": "0.42.0-beta2",
+        "magento/module-checkout": "0.42.0-beta2",
+        "magento/module-theme": "0.42.0-beta2",
+        "magento/module-catalog-inventory": "0.42.0-beta2",
+        "magento/module-rss": "0.42.0-beta2",
+        "magento/module-backend": "0.42.0-beta2",
+        "magento/module-sales": "0.42.0-beta2",
+        "magento/module-grouped-product": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
+        "magento/module-ui": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "suggest": {
-        "magento/module-configurable-product": "0.42.0-beta1",
-        "magento/module-downloadable": "0.42.0-beta1",
-        "magento/module-bundle": "0.42.0-beta1"
+        "magento/module-configurable-product": "0.42.0-beta2",
+        "magento/module-downloadable": "0.42.0-beta2",
+        "magento/module-bundle": "0.42.0-beta2"
     },
     "type": "magento2-module",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/design/adminhtml/Magento/backend/composer.json b/app/design/adminhtml/Magento/backend/composer.json
index c1176fc6fb4..25b1fd38c70 100644
--- a/app/design/adminhtml/Magento/backend/composer.json
+++ b/app/design/adminhtml/Magento/backend/composer.json
@@ -3,11 +3,11 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/framework": "0.42.0-beta1",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-theme",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/design/frontend/Magento/blank/composer.json b/app/design/frontend/Magento/blank/composer.json
index 313d99a4265..ddfe84f6f98 100644
--- a/app/design/frontend/Magento/blank/composer.json
+++ b/app/design/frontend/Magento/blank/composer.json
@@ -3,11 +3,11 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/framework": "0.42.0-beta1",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-theme",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/design/frontend/Magento/luma/composer.json b/app/design/frontend/Magento/luma/composer.json
index 706b3039345..f4ae793c221 100644
--- a/app/design/frontend/Magento/luma/composer.json
+++ b/app/design/frontend/Magento/luma/composer.json
@@ -3,12 +3,12 @@
     "description": "N/A",
     "require": {
         "php": "~5.4.11|~5.5.0",
-        "magento/theme-frontend-blank": "0.42.0-beta1",
-        "magento/framework": "0.42.0-beta1",
+        "magento/theme-frontend-blank": "0.42.0-beta2",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-theme",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/app/i18n/magento/de_de/composer.json b/app/i18n/magento/de_de/composer.json
index 6c7118d8998..a7bdff2a6f0 100644
--- a/app/i18n/magento/de_de/composer.json
+++ b/app/i18n/magento/de_de/composer.json
@@ -1,13 +1,13 @@
 {
     "name": "magento/language-de_de",
     "description": "German (Germany) language",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.42.0-beta1",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/app/i18n/magento/en_us/composer.json b/app/i18n/magento/en_us/composer.json
index 7ffb52d829f..19d2f4bffa4 100644
--- a/app/i18n/magento/en_us/composer.json
+++ b/app/i18n/magento/en_us/composer.json
@@ -1,13 +1,13 @@
 {
     "name": "magento/language-en_us",
     "description": "English (United States) language",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.42.0-beta1",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/app/i18n/magento/es_es/composer.json b/app/i18n/magento/es_es/composer.json
index f99489d5167..ff330bcfc2e 100644
--- a/app/i18n/magento/es_es/composer.json
+++ b/app/i18n/magento/es_es/composer.json
@@ -1,13 +1,13 @@
 {
     "name": "magento/language-es_es",
     "description": "Spanish (Spain) language",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.42.0-beta1",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/app/i18n/magento/fr_fr/composer.json b/app/i18n/magento/fr_fr/composer.json
index bda3533f639..97e699096cf 100644
--- a/app/i18n/magento/fr_fr/composer.json
+++ b/app/i18n/magento/fr_fr/composer.json
@@ -1,13 +1,13 @@
 {
     "name": "magento/language-fr_fr",
     "description": "French (France) language",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.42.0-beta1",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/app/i18n/magento/nl_nl/composer.json b/app/i18n/magento/nl_nl/composer.json
index 357991fb1e4..7aac45fbaed 100644
--- a/app/i18n/magento/nl_nl/composer.json
+++ b/app/i18n/magento/nl_nl/composer.json
@@ -1,13 +1,13 @@
 {
     "name": "magento/language-nl_nl",
     "description": "Dutch (Netherlands) language",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.42.0-beta1",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/app/i18n/magento/pt_br/composer.json b/app/i18n/magento/pt_br/composer.json
index 1ce0e7526d9..7cd46208ae6 100644
--- a/app/i18n/magento/pt_br/composer.json
+++ b/app/i18n/magento/pt_br/composer.json
@@ -1,13 +1,13 @@
 {
     "name": "magento/language-pt_br",
     "description": "Portuguese (Brazil) language",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.42.0-beta1",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/app/i18n/magento/zh_cn/composer.json b/app/i18n/magento/zh_cn/composer.json
index 06cb1f677bd..d04f7afd3dd 100644
--- a/app/i18n/magento/zh_cn/composer.json
+++ b/app/i18n/magento/zh_cn/composer.json
@@ -1,13 +1,13 @@
 {
     "name": "magento/language-zh_cn",
     "description": "Chinese (China) language",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
     ],
     "require": {
-        "magento/framework": "0.42.0-beta1",
+        "magento/framework": "0.42.0-beta2",
         "magento/magento-composer-installer": "*"
     },
     "type": "magento2-language",
diff --git a/composer.json b/composer.json
index 78915324de0..b30cc8775b2 100644
--- a/composer.json
+++ b/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/project-community-edition",
     "description": "Magento project (Community Edition)",
     "type": "project",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
diff --git a/lib/internal/Magento/Framework/AppInterface.php b/lib/internal/Magento/Framework/AppInterface.php
index 2e3f2de0cc7..d5128f358d6 100644
--- a/lib/internal/Magento/Framework/AppInterface.php
+++ b/lib/internal/Magento/Framework/AppInterface.php
@@ -16,7 +16,7 @@ interface AppInterface
     /**
      * Magento version
      */
-    const VERSION = '0.42.0-beta1';
+    const VERSION = '0.42.0-beta2';
 
     /**
      * Launch application
diff --git a/lib/internal/Magento/Framework/composer.json b/lib/internal/Magento/Framework/composer.json
index e118f4730d5..2d0570bae3b 100644
--- a/lib/internal/Magento/Framework/composer.json
+++ b/lib/internal/Magento/Framework/composer.json
@@ -2,7 +2,7 @@
     "name": "magento/framework",
     "description": "N/A",
     "type": "magento2-library",
-    "version": "0.42.0-beta1",
+    "version": "0.42.0-beta2",
     "license": [
         "OSL-3.0",
         "AFL-3.0"
-- 
GitLab


From b02792d8990ba4e7f7460bcff7ba125b847272f7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20M=C3=BCnch?= <c.muench@netz98.de>
Date: Fri, 26 Dec 2014 18:09:30 +0100
Subject: [PATCH 65/71] [BUGFIX] Fixed german translation "Warenkorbrn"

Warenkorbrn" is not really a german word. I corrected the translation. This phrase is also wrong in all Magento 1.x versions.
---
 app/code/Magento/Catalog/i18n/de_DE.csv  | 2 +-
 app/code/Magento/Reports/i18n/de_DE.csv  | 2 +-
 app/code/Magento/Sales/i18n/de_DE.csv    | 2 +-
 app/code/Magento/Wishlist/i18n/de_DE.csv | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/app/code/Magento/Catalog/i18n/de_DE.csv b/app/code/Magento/Catalog/i18n/de_DE.csv
index 8b0df7438ce..ecbd2cb0211 100644
--- a/app/code/Magento/Catalog/i18n/de_DE.csv
+++ b/app/code/Magento/Catalog/i18n/de_DE.csv
@@ -14,7 +14,7 @@ Qty,Qty
 Action,Aktion
 Reset,Zurücksetzen
 Edit,Bearbeiten
-"Add to Cart","Zum Warenkobrn hinzufügen"
+"Add to Cart","Zum Warenkorb hinzufügen"
 "Images (.gif, .jpg, .png)","Images (.gif, .jpg, .png)"
 "First Name",Vorname
 "Last Name","Letzter Name"
diff --git a/app/code/Magento/Reports/i18n/de_DE.csv b/app/code/Magento/Reports/i18n/de_DE.csv
index 2afa2d4426d..b2bd8ea9e79 100644
--- a/app/code/Magento/Reports/i18n/de_DE.csv
+++ b/app/code/Magento/Reports/i18n/de_DE.csv
@@ -11,7 +11,7 @@ Subtotal,Zwischensumme
 Discount,Discount
 Action,Aktion
 Total,Gesamtbetrag
-"Add to Cart","Zum Warenkobrn hinzufügen"
+"Add to Cart","Zum Warenkorb hinzufügen"
 Orders,Aufträge
 Bestsellers,Bestseller
 Customer,Kundenname
diff --git a/app/code/Magento/Sales/i18n/de_DE.csv b/app/code/Magento/Sales/i18n/de_DE.csv
index 6cec0c16a19..38a17ecbf53 100644
--- a/app/code/Magento/Sales/i18n/de_DE.csv
+++ b/app/code/Magento/Sales/i18n/de_DE.csv
@@ -33,7 +33,7 @@ Total,Gesamt
 "Move to Wishlist","Auf Wunschzettel schreiben"
 Edit,Bearbeiten
 Item,Objekt
-"Add to Cart","Zum Warenkobrn hinzufügen"
+"Add to Cart","Zum Warenkorb hinzufügen"
 Sku,SKU
 "Order saving error: %1","Order saving error: %1"
 "You created the order.","You created the order."
diff --git a/app/code/Magento/Wishlist/i18n/de_DE.csv b/app/code/Magento/Wishlist/i18n/de_DE.csv
index 43fc5de10f5..364939cebbb 100644
--- a/app/code/Magento/Wishlist/i18n/de_DE.csv
+++ b/app/code/Magento/Wishlist/i18n/de_DE.csv
@@ -7,7 +7,7 @@ Action,Action
 "Are you sure that you want to remove this item?","Are you sure that you want to remove this item?"
 Edit,Bearbeiten
 "Remove item","Artikel löschen"
-"Add to Cart","Zum Warenkobrn hinzufügen"
+"Add to Cart","Zum Warenkorb hinzufügen"
 Delete,Delete
 Enabled,Enabled
 "We cannot add this item to your shopping cart.","We cannot add this item to your shopping cart."
-- 
GitLab


From 38f56d43fde5a5050b254f3d9bc882931f1b1f88 Mon Sep 17 00:00:00 2001
From: Vladimir Pelipenko <vpelipenko@ebay.com>
Date: Mon, 29 Dec 2014 15:15:13 +0200
Subject: [PATCH 66/71] MAGETWO-31051: M2 GitHub Update (version 0.42.0-beta2)

---
 composer.lock | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/composer.lock b/composer.lock
index 3aa9ff55893..d2fc6da7fe7 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "25a2a2ff9de53c394a797011b0f84855",
+    "hash": "d3a510fb8a6b17c084148509d02478d4",
     "packages": [
         {
             "name": "composer/composer",
-- 
GitLab


From d793849bdf74917b1d1db1c85ed32c5265f44b87 Mon Sep 17 00:00:00 2001
From: Cyrill Schumacher <cyrill@schumacher.fm>
Date: Tue, 30 Dec 2014 08:35:19 +1100
Subject: [PATCH 67/71] Naming Fix: DI compiler.php rename binary to igbinary
 to stay consistent with app/etc/config.php entry and naming in
 https://github.com/magento/magento2/blob/develop/lib%2Finternal%2FMagento%2FFramework%2FObjectManager%2FDefinitionFactory.php#L59

---
 dev/tools/Magento/Tools/Di/compiler.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/dev/tools/Magento/Tools/Di/compiler.php b/dev/tools/Magento/Tools/Di/compiler.php
index f838a21987b..6f185bc3587 100644
--- a/dev/tools/Magento/Tools/Di/compiler.php
+++ b/dev/tools/Magento/Tools/Di/compiler.php
@@ -27,7 +27,7 @@ $codeScanDir = realpath($rootDir . '/app');
 try {
     $opt = new Zend_Console_Getopt(
         [
-            'serializer=w'         => 'serializer function that should be used (serialize|binary) default = serialize',
+            'serializer=w'         => 'serializer function that should be used (serialize|igbinary) default: serialize',
             'verbose|v'            => 'output report after tool run',
             'extra-classes-file=s' => 'path to file with extra proxies and factories to generate',
             'generation=s'         => 'absolute path to generated classes, <magento_root>/var/generation by default',
@@ -55,7 +55,7 @@ try {
     $errorWriter = new Writer\Console();
 
     $log = new Log($logWriter, $errorWriter);
-    $serializer = $opt->getOption('serializer') == 'binary' ? new Serializer\Igbinary() : new Serializer\Standard();
+    $serializer = $opt->getOption('serializer') == 'igbinary' ? new Serializer\Igbinary() : new Serializer\Standard();
 
     $validator = new \Magento\Framework\Code\Validator();
     $validator->add(new \Magento\Framework\Code\Validator\ConstructorIntegrity());
-- 
GitLab


From ee894bc6f68084854aff15598f8b0c9f5e268cfe Mon Sep 17 00:00:00 2001
From: Joan He <joan@x.com>
Date: Fri, 2 Jan 2015 15:39:44 -0600
Subject: [PATCH 68/71] MAGETWO-32328: fixed DateTest

---
 .../Magento/Framework/Data/Form/Element/DateTest.php          | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/dev/tests/integration/testsuite/Magento/Framework/Data/Form/Element/DateTest.php b/dev/tests/integration/testsuite/Magento/Framework/Data/Form/Element/DateTest.php
index 0628f7d67ef..bc6695ea6cd 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Data/Form/Element/DateTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Data/Form/Element/DateTest.php
@@ -56,7 +56,7 @@ class DateTest extends \PHPUnit_Framework_TestCase
                     'time_format' => \Magento\Framework\Stdlib\DateTime\TimezoneInterface::FORMAT_TYPE_SHORT,
                     'value' => $currentTime,
                 ],
-                date('m/j/y g:i A', $currentTime),
+                date('n/j/y g:i A', $currentTime),
             ],
             [
                 [
@@ -70,7 +70,7 @@ class DateTest extends \PHPUnit_Framework_TestCase
                     'date_format' => \Magento\Framework\Stdlib\DateTime\TimezoneInterface::FORMAT_TYPE_SHORT,
                     'value' => $currentTime,
                 ],
-                date('m/j/y', $currentTime)
+                date('n/j/y', $currentTime)
             ]
         ];
     }
-- 
GitLab


From c05f3469e8aa0a9167be58b78694d866f169f0a9 Mon Sep 17 00:00:00 2001
From: Yuxing Zheng <yuxzheng@ebay.com>
Date: Mon, 5 Jan 2015 11:04:10 -0600
Subject: [PATCH 69/71] MAGETWO-32105: Add api-functional tests

---
 composer.json                                 |    3 +-
 composer.lock                                 |   74 +-
 dev/tests/api-functional/.gitignore           |    3 +
 .../TestModule1/Controller/CookieTester.php   |   69 ++
 .../Controller/CookieTester/DeleteCookie.php  |   21 +
 .../CookieTester/SetPublicCookie.php          |   49 +
 .../CookieTester/SetSensitiveCookie.php       |   33 +
 .../TestModule1/Service/V1/AllSoapAndRest.php |  108 ++
 .../Service/V1/AllSoapAndRestInterface.php    |   50 +
 .../V1/Entity/CustomAttributeDataObject.php   |   16 +
 .../CustomAttributeDataObjectBuilder.php      |   20 +
 .../CustomAttributeNestedDataObject.php       |   16 +
 ...CustomAttributeNestedDataObjectBuilder.php |   20 +
 .../V1/Entity/Eav/AttributeMetadata.php       |   42 +
 .../Entity/Eav/AttributeMetadataBuilder.php   |   36 +
 .../TestModule1/Service/V1/Entity/Item.php    |   24 +
 .../Service/V1/Entity/ItemBuilder.php         |   51 +
 .../TestModule1/Service/V2/AllSoapAndRest.php |   85 ++
 .../Service/V2/AllSoapAndRestInterface.php    |   51 +
 .../TestModule1/Service/V2/Entity/Item.php    |   32 +
 .../Service/V2/Entity/ItemBuilder.php         |   41 +
 .../_files/Magento/TestModule1/etc/acl.xml    |   19 +
 .../Magento/TestModule1/etc/data_object.xml   |   16 +
 .../_files/Magento/TestModule1/etc/di.xml     |   22 +
 .../TestModule1/etc/frontend/routes.xml       |   13 +
 .../_files/Magento/TestModule1/etc/module.xml |    9 +
 .../_files/Magento/TestModule1/etc/webapi.xml |   99 ++
 .../TestModule2/Service/V1/Entity/Item.php    |   24 +
 .../Service/V1/Entity/ItemBuilder.php         |   28 +
 .../TestModule2/Service/V1/NoWebApiXml.php    |   60 +
 .../Service/V1/NoWebApiXmlInterface.php       |   41 +
 .../TestModule2/Service/V1/SubsetRest.php     |   68 ++
 .../Service/V1/SubsetRestInterface.php        |   49 +
 .../_files/Magento/TestModule2/etc/acl.xml    |   19 +
 .../_files/Magento/TestModule2/etc/di.xml     |   10 +
 .../_files/Magento/TestModule2/etc/module.xml |    9 +
 .../etc/schema/AllSoapNoRestV1.xsd            |  239 ++++
 .../TestModule2/etc/schema/NoWebApiXmlV1.xsd  |  239 ++++
 .../TestModule2/etc/schema/SubsetRestV1.xsd   |  239 ++++
 .../_files/Magento/TestModule2/etc/webapi.xml |   21 +
 .../Service/V1/Entity/Parameter.php           |   28 +
 .../Service/V1/Entity/ParameterBuilder.php    |   32 +
 .../V1/Entity/WrappedErrorParameter.php       |   29 +
 .../Entity/WrappedErrorParameterBuilder.php   |   33 +
 .../Magento/TestModule3/Service/V1/Error.php  |  117 ++
 .../TestModule3/Service/V1/ErrorInterface.php |   59 +
 .../_files/Magento/TestModule3/etc/acl.xml    |   17 +
 .../_files/Magento/TestModule3/etc/di.xml     |    9 +
 .../_files/Magento/TestModule3/etc/module.xml |    9 +
 .../_files/Magento/TestModule3/etc/webapi.xml |   63 ++
 .../TestModule4/Model/Resource/Item.php       |   22 +
 .../Service/V1/DataObjectService.php          |   69 ++
 .../Service/V1/DataObjectServiceInterface.php |   46 +
 .../Service/V1/Entity/DataObjectRequest.php   |   24 +
 .../V1/Entity/DataObjectRequestBuilder.php    |   26 +
 .../Service/V1/Entity/DataObjectResponse.php  |   24 +
 .../V1/Entity/DataObjectResponseBuilder.php   |   26 +
 .../Service/V1/Entity/ExtensibleRequest.php   |   14 +
 .../V1/Entity/ExtensibleRequestInterface.php  |   18 +
 .../V1/Entity/NestedDataObjectRequest.php     |   16 +
 .../Entity/NestedDataObjectRequestBuilder.php |   17 +
 .../_files/Magento/TestModule4/etc/acl.xml    |   19 +
 .../_files/Magento/TestModule4/etc/di.xml     |   15 +
 .../_files/Magento/TestModule4/etc/module.xml |    9 +
 .../_files/Magento/TestModule4/etc/webapi.xml |   38 +
 .../TestModule5/Service/V1/AllSoapAndRest.php |   73 ++
 .../Service/V1/AllSoapAndRestInterface.php    |   54 +
 .../Service/V1/Entity/AllSoapAndRest.php      |   70 ++
 .../V1/Entity/AllSoapAndRestBuilder.php       |   56 +
 .../Service/V1/OverrideService.php            |   35 +
 .../Service/V1/OverrideServiceInterface.php   |   19 +
 .../TestModule5/Service/V2/AllSoapAndRest.php |   69 ++
 .../Service/V2/AllSoapAndRestInterface.php    |   48 +
 .../Service/V2/Entity/AllSoapAndRest.php      |   18 +
 .../V2/Entity/AllSoapAndRestBuilder.php       |   21 +
 .../_files/Magento/TestModule5/etc/acl.xml    |   19 +
 .../_files/Magento/TestModule5/etc/di.xml     |   11 +
 .../_files/Magento/TestModule5/etc/module.xml |    9 +
 .../_files/Magento/TestModule5/etc/webapi.xml |   78 ++
 .../Api/AllSoapAndRestInterface.php           |   48 +
 .../CustomAttributeDataObjectInterface.php    |   15 +
 ...stomAttributeNestedDataObjectInterface.php |   13 +
 .../TestModuleMSC/Api/Data/ItemInterface.php  |   18 +
 .../TestModuleMSC/Model/AllSoapAndRest.php    |  107 ++
 .../Model/Data/CustomAttributeDataObject.php  |   19 +
 .../Data/CustomAttributeNestedDataObject.php  |   19 +
 .../Model/Data/Eav/AttributeMetadata.php      |   42 +
 .../Data/Eav/AttributeMetadataBuilder.php     |   36 +
 .../Magento/TestModuleMSC/Model/Data/Item.php |   27 +
 .../TestModuleMSC/Model/Resource/Item.php     |   22 +
 .../_files/Magento/TestModuleMSC/etc/acl.xml  |   19 +
 .../Magento/TestModuleMSC/etc/data_object.xml |   16 +
 .../_files/Magento/TestModuleMSC/etc/di.xml   |   38 +
 .../Magento/TestModuleMSC/etc/module.xml      |    9 +
 .../Magento/TestModuleMSC/etc/webapi.xml      |   68 ++
 .../config/install-config-mysql.php.dist      |   29 +
 .../Annotation/ApiDataFixture.php             |  152 +++
 .../Authentication/OauthHelper.php            |  200 ++++
 .../Authentication/Rest/OauthClient.php       |  271 +++++
 .../Rest/OauthClient/Signature.php            |   53 +
 .../Bootstrap/WebapiDocBlock.php              |   23 +
 .../Magento/TestFramework/Helper/Customer.php |  170 +++
 .../TestCase/Webapi/Adapter/Rest.php          |  145 +++
 .../Webapi/Adapter/Rest/CurlClient.php        |  308 +++++
 .../Adapter/Rest/DocumentationGenerator.php   |  238 ++++
 .../TestCase/Webapi/Adapter/Soap.php          |  238 ++++
 .../TestCase/Webapi/AdapterInterface.php      |   37 +
 .../TestFramework/TestCase/Webapi/Curl.php    |   93 ++
 .../TestFramework/TestCase/WebapiAbstract.php |  665 +++++++++++
 .../TestFramework/WebApiApplication.php       |   62 +
 .../api-functional/framework/autoload.php     |   14 +
 .../api-functional/framework/bootstrap.php    |   77 ++
 dev/tests/api-functional/phpunit.xml.dist     |   71 ++
 .../Bundle/Api/ProductLinkManagementTest.php  |  163 +++
 .../Api/ProductOptionRepositoryTest.php       |  267 +++++
 .../Bundle/Api/ProductOptionTypeListTest.php  |   47 +
 .../Magento/Bundle/Api/ProductServiceTest.php |  170 +++
 .../Api/AttributeSetManagementTest.php        |  221 ++++
 .../Api/AttributeSetRepositoryTest.php        |  228 ++++
 ...AttributeOptionManagementInterfaceTest.php |   47 +
 .../Api/CategoryAttributeRepositoryTest.php   |   96 ++
 .../Api/CategoryLinkManagementTest.php        |   65 ++
 .../Api/CategoryLinkRepositoryTest.php        |  149 +++
 .../Catalog/Api/CategoryManagementTest.php    |   94 ++
 .../Catalog/Api/CategoryRepositoryTest.php    |  253 +++++
 .../ProductAttributeGroupRepositoryTest.php   |  191 ++++
 .../Api/ProductAttributeManagementTest.php    |  184 +++
 ...uteMediaGalleryManagementInterfaceTest.php |  647 +++++++++++
 ...AttributeOptionManagementInterfaceTest.php |  152 +++
 .../Api/ProductAttributeRepositoryTest.php    |  266 +++++
 .../Api/ProductAttributeTypesListTest.php     |   37 +
 .../Api/ProductCustomOptionRepositoryTest.php |  367 ++++++
 .../Api/ProductCustomOptionTypeListTest.php   |   42 +
 .../Api/ProductGroupPriceManagementTest.php   |  118 ++
 .../ProductLinkManagementInterfaceTest.php    |  143 +++
 .../ProductLinkRepositoryInterfaceTest.php    |  103 ++
 .../Catalog/Api/ProductLinkTypeListTest.php   |   53 +
 .../ProductMediaAttributeManagementTest.php   |   60 +
 .../Api/ProductRepositoryInterfaceTest.php    |  279 +++++
 .../Api/ProductTierPriceManagementTest.php    |  205 ++++
 .../Catalog/Api/ProductTypeListTest.php       |   59 +
 .../Catalog/Api/_files/product_options.php    |  162 +++
 .../Api/_files/product_options_negative.php   |   91 ++
 .../Magento/Catalog/Api/_files/test_image.jpg |  Bin 0 -> 2004 bytes
 .../Api/LowStockItemsTest.php                 |   79 ++
 .../CatalogInventory/Api/StockItemTest.php    |  222 ++++
 .../CatalogInventory/Api/StockStatusTest.php  |   48 +
 .../V1/Address/Billing/ReadServiceTest.php    |   85 ++
 .../V1/Address/Billing/WriteServiceTest.php   |   97 ++
 .../V1/Address/Shipping/ReadServiceTest.php   |  111 ++
 .../V1/Address/Shipping/WriteServiceTest.php  |  147 +++
 .../Service/V1/Cart/ReadServiceTest.php       |  297 +++++
 .../Service/V1/Cart/TotalsServiceTest.php     |  174 +++
 .../Service/V1/Cart/WriteServiceTest.php      |  299 +++++
 .../Service/V1/Coupon/ReadServiceTest.php     |   55 +
 .../Service/V1/Coupon/WriteServiceTest.php    |  129 +++
 .../Service/V1/Item/ReadServiceTest.php       |   65 ++
 .../Service/V1/Item/WriteServiceTest.php      |  136 +++
 .../V1/PaymentMethod/ReadServiceTest.php      |   89 ++
 .../V1/PaymentMethod/WriteServiceTest.php     |  211 ++++
 .../V1/ShippingMethod/ReadServiceTest.php     |  174 +++
 .../V1/ShippingMethod/WriteServiceTest.php    |  106 ++
 .../Service/V1/Agreement/ReadServiceTest.php  |   84 ++
 .../Api/ConfigurableProductManagementTest.php |   79 ++
 .../Api/LinkManagementTest.php                |  116 ++
 .../Api/OptionRepositoryTest.php              |  289 +++++
 .../Api/OptionTypesListTest.php               |   41 +
 .../Customer/Api/AccountManagementMeTest.php  |  335 ++++++
 .../Customer/Api/AccountManagementTest.php    |  778 +++++++++++++
 .../Customer/Api/AddressMetadataTest.php      |  274 +++++
 .../Customer/Api/AddressRepositoryTest.php    |  166 +++
 .../Customer/Api/CustomerMetadataTest.php     |  321 ++++++
 .../Customer/Api/CustomerRepositoryTest.php   |  659 +++++++++++
 .../Customer/Api/GroupManagementTest.php      |  228 ++++
 .../Customer/Api/GroupRepositoryTest.php      | 1007 +++++++++++++++++
 .../V1/DownloadableLink/ReadServiceTest.php   |  155 +++
 .../V1/DownloadableLink/WriteServiceTest.php  |  796 +++++++++++++
 .../V1/DownloadableLink/_files/test_image.jpg |  Bin 0 -> 2004 bytes
 .../DownloadableSample/WriteServiceTest.php   |  509 +++++++++
 .../Eav/Api/AttributeSetManagementTest.php    |  235 ++++
 .../Eav/Api/AttributeSetRepositoryTest.php    |  260 +++++
 .../Framework/Stdlib/CookieManagerTest.php    |  164 +++
 .../Service/V1/ReadServiceTest.php            |  101 ++
 .../Service/V1/WriteServiceTest.php           |  115 ++
 .../Api/ProductLinkManagementTest.php         |   72 ++
 .../Api/ProductLinkRepositoryTest.php         |   66 ++
 .../Api/ProductLinkTypeListTest.php           |   64 ++
 .../Service/V1/AdminTokenServiceTest.php      |  159 +++
 .../Service/V1/CustomerTokenServiceTest.php   |  164 +++
 .../Service/V1/CreditmemoAddCommentTest.php   |   82 ++
 .../Sales/Service/V1/CreditmemoCancelTest.php |   47 +
 .../Service/V1/CreditmemoCommentsListTest.php |   62 +
 .../Sales/Service/V1/CreditmemoCreateTest.php |  111 ++
 .../Sales/Service/V1/CreditmemoEmailTest.php  |   45 +
 .../Sales/Service/V1/CreditmemoGetTest.php    |  108 ++
 .../Sales/Service/V1/CreditmemoListTest.php   |   89 ++
 .../Service/V1/InvoiceAddCommentTest.php      |   63 ++
 .../Sales/Service/V1/InvoiceCaptureTest.php   |   43 +
 .../Service/V1/InvoiceCommentsListTest.php    |   56 +
 .../Sales/Service/V1/InvoiceCreateTest.php    |  127 +++
 .../Sales/Service/V1/InvoiceEmailTest.php     |   42 +
 .../Sales/Service/V1/InvoiceGetTest.php       |   52 +
 .../Sales/Service/V1/InvoiceListTest.php      |   74 ++
 .../Sales/Service/V1/InvoiceVoidTest.php      |   43 +
 .../Service/V1/OrderAddressUpdateTest.php     |   96 ++
 .../Sales/Service/V1/OrderCancelTest.php      |   39 +
 .../Service/V1/OrderCommentsListTest.php      |   49 +
 .../Sales/Service/V1/OrderCreateTest.php      |  128 +++
 .../Sales/Service/V1/OrderEmailTest.php       |   39 +
 .../Sales/Service/V1/OrderGetStatusTest.php   |   57 +
 .../Magento/Sales/Service/V1/OrderGetTest.php |   89 ++
 .../Sales/Service/V1/OrderHoldTest.php        |   39 +
 .../Sales/Service/V1/OrderListTest.php        |   74 ++
 .../Service/V1/OrderStatusHistoryAddTest.php  |   83 ++
 .../Sales/Service/V1/OrderUnHoldTest.php      |   43 +
 .../Service/V1/ShipmentAddCommentTest.php     |   77 ++
 .../Sales/Service/V1/ShipmentAddTrackTest.php |   83 ++
 .../Service/V1/ShipmentCommentsListTest.php   |   56 +
 .../Sales/Service/V1/ShipmentCreateTest.php   |   88 ++
 .../Sales/Service/V1/ShipmentEmailTest.php    |   43 +
 .../Sales/Service/V1/ShipmentGetTest.php      |   76 ++
 .../Sales/Service/V1/ShipmentLabelGetTest.php |   53 +
 .../Sales/Service/V1/ShipmentListTest.php     |   67 ++
 .../Service/V1/ShipmentRemoveTrackTest.php    |   87 ++
 .../Sales/Service/V1/TransactionTest.php      |  190 ++++
 .../Tax/Api/TaxClassRepositoryTest.php        |  309 +++++
 .../Magento/Tax/Api/TaxRateRepositoryTest.php |  660 +++++++++++
 .../Api/TaxRuleRepositoryInterfaceTest.php    |  606 ++++++++++
 .../Webapi/Authentication/RestTest.php        |  203 ++++
 .../CustomAttributeSerializationMSCTest.php   |  244 ++++
 .../CustomAttributeSerializationTest.php      |  228 ++++
 .../ServiceSerializationTest.php              |  110 ++
 .../Magento/Webapi/DeserializationTest.php    |   79 ++
 .../Magento/Webapi/PartialResponseTest.php    |   99 ++
 .../Magento/Webapi/Routing/BaseService.php    |  113 ++
 .../Webapi/Routing/CoreRoutingTest.php        |   75 ++
 .../Magento/Webapi/Routing/GettersTest.php    |   55 +
 .../Webapi/Routing/NoWebApiXmlTest.php        |  106 ++
 .../Webapi/Routing/RequestIdOverrideTest.php  |  160 +++
 .../Webapi/Routing/RestErrorHandlingTest.php  |  160 +++
 .../Webapi/Routing/ServiceVersionV1Test.php   |  267 +++++
 .../Webapi/Routing/ServiceVersionV2Test.php   |  142 +++
 .../Webapi/Routing/SoapErrorHandlingTest.php  |  163 +++
 .../Magento/Webapi/Routing/SubsetTest.php     |   75 ++
 .../WsdlGenerationFromDataObjectTest.php      |  735 ++++++++++++
 .../Integrity/_files/blacklist/reference.txt  |   14 +
 246 files changed, 28705 insertions(+), 7 deletions(-)
 create mode 100644 dev/tests/api-functional/.gitignore
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/Controller/CookieTester.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/Controller/CookieTester/DeleteCookie.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/Controller/CookieTester/SetPublicCookie.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/Controller/CookieTester/SetSensitiveCookie.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/AllSoapAndRest.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/AllSoapAndRestInterface.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeDataObject.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeDataObjectBuilder.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeNestedDataObject.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeNestedDataObjectBuilder.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/Eav/AttributeMetadata.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/Eav/AttributeMetadataBuilder.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/Item.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/ItemBuilder.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/Service/V2/AllSoapAndRest.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/Service/V2/AllSoapAndRestInterface.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/Service/V2/Entity/Item.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/Service/V2/Entity/ItemBuilder.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/etc/acl.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/etc/data_object.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/etc/di.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/etc/frontend/routes.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/etc/module.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule1/etc/webapi.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/Entity/Item.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/Entity/ItemBuilder.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/NoWebApiXml.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/NoWebApiXmlInterface.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/SubsetRest.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/SubsetRestInterface.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule2/etc/acl.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule2/etc/di.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule2/etc/module.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule2/etc/schema/AllSoapNoRestV1.xsd
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule2/etc/schema/NoWebApiXmlV1.xsd
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule2/etc/schema/SubsetRestV1.xsd
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule2/etc/webapi.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Entity/Parameter.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Entity/ParameterBuilder.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Entity/WrappedErrorParameter.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Entity/WrappedErrorParameterBuilder.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Error.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/ErrorInterface.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule3/etc/acl.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule3/etc/di.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule3/etc/module.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule3/etc/webapi.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule4/Model/Resource/Item.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/DataObjectService.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/DataObjectServiceInterface.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/DataObjectRequest.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/DataObjectRequestBuilder.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/DataObjectResponse.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/DataObjectResponseBuilder.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/ExtensibleRequest.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/ExtensibleRequestInterface.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/NestedDataObjectRequest.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/NestedDataObjectRequestBuilder.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule4/etc/acl.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule4/etc/di.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule4/etc/module.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule4/etc/webapi.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/AllSoapAndRest.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/AllSoapAndRestInterface.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/Entity/AllSoapAndRest.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/Entity/AllSoapAndRestBuilder.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/OverrideService.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/OverrideServiceInterface.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule5/Service/V2/AllSoapAndRest.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule5/Service/V2/AllSoapAndRestInterface.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule5/Service/V2/Entity/AllSoapAndRest.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule5/Service/V2/Entity/AllSoapAndRestBuilder.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule5/etc/acl.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule5/etc/di.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule5/etc/module.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModule5/etc/webapi.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModuleMSC/Api/AllSoapAndRestInterface.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModuleMSC/Api/Data/CustomAttributeDataObjectInterface.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModuleMSC/Api/Data/CustomAttributeNestedDataObjectInterface.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModuleMSC/Api/Data/ItemInterface.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/AllSoapAndRest.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/CustomAttributeDataObject.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/CustomAttributeNestedDataObject.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/Eav/AttributeMetadata.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/Eav/AttributeMetadataBuilder.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/Item.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Resource/Item.php
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/acl.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/data_object.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/di.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/module.xml
 create mode 100644 dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/webapi.xml
 create mode 100644 dev/tests/api-functional/config/install-config-mysql.php.dist
 create mode 100644 dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiDataFixture.php
 create mode 100644 dev/tests/api-functional/framework/Magento/TestFramework/Authentication/OauthHelper.php
 create mode 100644 dev/tests/api-functional/framework/Magento/TestFramework/Authentication/Rest/OauthClient.php
 create mode 100644 dev/tests/api-functional/framework/Magento/TestFramework/Authentication/Rest/OauthClient/Signature.php
 create mode 100644 dev/tests/api-functional/framework/Magento/TestFramework/Bootstrap/WebapiDocBlock.php
 create mode 100644 dev/tests/api-functional/framework/Magento/TestFramework/Helper/Customer.php
 create mode 100644 dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/Adapter/Rest.php
 create mode 100644 dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/Adapter/Rest/CurlClient.php
 create mode 100644 dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/Adapter/Rest/DocumentationGenerator.php
 create mode 100644 dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/Adapter/Soap.php
 create mode 100644 dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/AdapterInterface.php
 create mode 100644 dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/Curl.php
 create mode 100644 dev/tests/api-functional/framework/Magento/TestFramework/TestCase/WebapiAbstract.php
 create mode 100644 dev/tests/api-functional/framework/Magento/TestFramework/WebApiApplication.php
 create mode 100644 dev/tests/api-functional/framework/autoload.php
 create mode 100644 dev/tests/api-functional/framework/bootstrap.php
 create mode 100644 dev/tests/api-functional/phpunit.xml.dist
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductLinkManagementTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductOptionRepositoryTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductOptionTypeListTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/AttributeSetManagementTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/AttributeSetRepositoryTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryAttributeOptionManagementInterfaceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryAttributeRepositoryTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryLinkManagementTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryLinkRepositoryTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryManagementTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeGroupRepositoryTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeManagementTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeMediaGalleryManagementInterfaceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionManagementInterfaceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeTypesListTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionTypeListTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductGroupPriceManagementTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductLinkManagementInterfaceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductLinkRepositoryInterfaceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductLinkTypeListTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductMediaAttributeManagementTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductTierPriceManagementTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductTypeListTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/_files/product_options.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/_files/product_options_negative.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Catalog/Api/_files/test_image.jpg
 create mode 100644 dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/LowStockItemsTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/StockItemTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/StockStatusTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Address/Billing/ReadServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Address/Billing/WriteServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Address/Shipping/ReadServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Address/Shipping/WriteServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Cart/ReadServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Cart/TotalsServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Cart/WriteServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Coupon/ReadServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Coupon/WriteServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Item/ReadServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Item/WriteServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/PaymentMethod/ReadServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/PaymentMethod/WriteServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/ShippingMethod/ReadServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/ShippingMethod/WriteServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/CheckoutAgreements/Service/V1/Agreement/ReadServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/ConfigurableProductManagementTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/LinkManagementTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/OptionRepositoryTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/OptionTypesListTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Customer/Api/AddressMetadataTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Customer/Api/AddressRepositoryTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerMetadataTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerRepositoryTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Customer/Api/GroupManagementTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Customer/Api/GroupRepositoryTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/ReadServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/WriteServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/_files/test_image.jpg
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Downloadable/Service/V1/DownloadableSample/WriteServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Eav/Api/AttributeSetManagementTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Eav/Api/AttributeSetRepositoryTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Framework/Stdlib/CookieManagerTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/GiftMessage/Service/V1/ReadServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/GiftMessage/Service/V1/WriteServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkManagementTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkRepositoryTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkTypeListTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Integration/Service/V1/AdminTokenServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Integration/Service/V1/CustomerTokenServiceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoAddCommentTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoCancelTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoCommentsListTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoCreateTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoEmailTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoGetTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoListTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceAddCommentTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceCaptureTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceCommentsListTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceCreateTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceEmailTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceGetTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceListTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceVoidTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderAddressUpdateTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderCancelTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderCommentsListTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderCreateTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderEmailTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderGetStatusTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderGetTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderHoldTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderListTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderStatusHistoryAddTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderUnHoldTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentAddCommentTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentAddTrackTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentCommentsListTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentCreateTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentEmailTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentGetTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentLabelGetTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentListTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentRemoveTrackTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/TransactionTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxClassRepositoryTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRateRepositoryTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRuleRepositoryInterfaceTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Webapi/Authentication/RestTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Webapi/DataObjectSerialization/CustomAttributeSerializationMSCTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Webapi/DataObjectSerialization/CustomAttributeSerializationTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Webapi/DataObjectSerialization/ServiceSerializationTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Webapi/DeserializationTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Webapi/PartialResponseTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Webapi/Routing/BaseService.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Webapi/Routing/CoreRoutingTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Webapi/Routing/GettersTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Webapi/Routing/NoWebApiXmlTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Webapi/Routing/RequestIdOverrideTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Webapi/Routing/RestErrorHandlingTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Webapi/Routing/ServiceVersionV1Test.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Webapi/Routing/ServiceVersionV2Test.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Webapi/Routing/SoapErrorHandlingTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Webapi/Routing/SubsetTest.php
 create mode 100644 dev/tests/api-functional/testsuite/Magento/Webapi/WsdlGenerationFromDataObjectTest.php

diff --git a/composer.json b/composer.json
index b30cc8775b2..e1e90a8395b 100644
--- a/composer.json
+++ b/composer.json
@@ -48,7 +48,8 @@
         "ext-curl": "*",
         "ext-iconv": "*",
         "sjparkinson/static-review": "~4.1",
-        "fabpot/php-cs-fixer": "~1.2"
+        "fabpot/php-cs-fixer": "~1.2",
+        "lusitanian/oauth": "~0.3"
     },
     "replace": {
         "magento/module-admin-notification": "self.version",
diff --git a/composer.lock b/composer.lock
index d2fc6da7fe7..990692a84d2 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "d3a510fb8a6b17c084148509d02478d4",
+    "hash": "0c7573953aece5e5227468ebff4539da",
     "packages": [
         {
             "name": "composer/composer",
@@ -1923,6 +1923,68 @@
             ],
             "time": "2014-11-08 02:33:31"
         },
+        {
+            "name": "lusitanian/oauth",
+            "version": "v0.3.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Lusitanian/PHPoAuthLib.git",
+                "reference": "ac5a1cd5a4519143728dce2213936eea302edf8a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Lusitanian/PHPoAuthLib/zipball/ac5a1cd5a4519143728dce2213936eea302edf8a",
+                "reference": "ac5a1cd5a4519143728dce2213936eea302edf8a",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "3.7.*",
+                "predis/predis": "0.8.*@dev",
+                "symfony/http-foundation": "~2.1"
+            },
+            "suggest": {
+                "ext-openssl": "Allows for usage of secure connections with the stream-based HTTP client.",
+                "predis/predis": "Allows using the Redis storage backend.",
+                "symfony/http-foundation": "Allows using the Symfony Session storage backend."
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "0.1-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "OAuth": "src",
+                    "OAuth\\Unit": "tests"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "David Desberg",
+                    "email": "david@daviddesberg.com"
+                },
+                {
+                    "name": "Pieter Hordijk",
+                    "email": "info@pieterhordijk.com"
+                }
+            ],
+            "description": "PHP 5.3+ oAuth 1/2 Library",
+            "keywords": [
+                "Authentication",
+                "authorization",
+                "oauth",
+                "security"
+            ],
+            "time": "2014-09-05 15:19:58"
+        },
         {
             "name": "pdepend/pdepend",
             "version": "2.0.4",
@@ -2001,16 +2063,16 @@
         },
         {
             "name": "phpunit/php-code-coverage",
-            "version": "2.0.13",
+            "version": "2.0.14",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
-                "reference": "0e7d2eec5554f869fa7a4ec2d21e4b37af943ea5"
+                "reference": "ca158276c1200cc27f5409a5e338486bc0b4fc94"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/0e7d2eec5554f869fa7a4ec2d21e4b37af943ea5",
-                "reference": "0e7d2eec5554f869fa7a4ec2d21e4b37af943ea5",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca158276c1200cc27f5409a5e338486bc0b4fc94",
+                "reference": "ca158276c1200cc27f5409a5e338486bc0b4fc94",
                 "shasum": ""
             },
             "require": {
@@ -2062,7 +2124,7 @@
                 "testing",
                 "xunit"
             ],
-            "time": "2014-12-03 06:41:44"
+            "time": "2014-12-26 13:28:33"
         },
         {
             "name": "phpunit/php-file-iterator",
diff --git a/dev/tests/api-functional/.gitignore b/dev/tests/api-functional/.gitignore
new file mode 100644
index 00000000000..77d5f53390c
--- /dev/null
+++ b/dev/tests/api-functional/.gitignore
@@ -0,0 +1,3 @@
+/*.xml
+/var/
+/config/*.php
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Controller/CookieTester.php b/dev/tests/api-functional/_files/Magento/TestModule1/Controller/CookieTester.php
new file mode 100644
index 00000000000..e6bc716ff55
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/Controller/CookieTester.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule1\Controller;
+
+use Magento\Framework\App\RequestInterface;
+use Magento\Framework\Stdlib\Cookie\CookieMetadataFactory;
+use Magento\Framework\Stdlib\Cookie\PhpCookieManager;
+
+/**
+ * Controller for testing the CookieManager.
+ *
+ */
+class CookieTester extends \Magento\Framework\App\Action\Action
+{
+    /** @var PhpCookieManager */
+    protected $cookieManager;
+
+    /** @var  CookieMetadataFactory */
+    protected $cookieMetadataFactory;
+
+    /**
+     * @param \Magento\Framework\App\Action\Context $context
+     * @param PhpCookieManager $cookieManager
+     * @param CookieMetadataFactory $cookieMetadataFactory
+     */
+    public function __construct(
+        \Magento\Framework\App\Action\Context $context,
+        PhpCookieManager $cookieManager,
+        CookieMetadataFactory $cookieMetadataFactory
+    ) {
+        $this->cookieManager = $cookieManager;
+        $this->cookieMetadataFacory = $cookieMetadataFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * Retrieve cookie metadata factory
+     */
+    protected function getCookieMetadataFactory()
+    {
+        return $this->cookieMetadataFacory;
+    }
+
+    /**
+     * Retrieve cookie metadata factory
+     */
+    protected function getCookieManager()
+    {
+        return $this->cookieManager;
+    }
+
+    /**
+     * Dispatch request
+     *
+     * @param RequestInterface $request
+     * @return \Magento\Framework\App\ResponseInterface
+     */
+    public function dispatch(RequestInterface $request)
+    {
+        if (!$this->getRequest()->isDispatched()) {
+            parent::dispatch($request);
+        }
+
+        $result = parent::dispatch($request);
+        return $result;
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Controller/CookieTester/DeleteCookie.php b/dev/tests/api-functional/_files/Magento/TestModule1/Controller/CookieTester/DeleteCookie.php
new file mode 100644
index 00000000000..f7ef99d6b52
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/Controller/CookieTester/DeleteCookie.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule1\Controller\CookieTester;
+
+/**
+ * Controller to test deletion of a cookie
+ */
+class DeleteCookie extends \Magento\TestModule1\Controller\CookieTester
+{
+    /**
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $cookieName = $this->getRequest()->getParam('cookie_name');
+        $this->getCookieManager()->deleteCookie($cookieName);
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Controller/CookieTester/SetPublicCookie.php b/dev/tests/api-functional/_files/Magento/TestModule1/Controller/CookieTester/SetPublicCookie.php
new file mode 100644
index 00000000000..c72395edf16
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/Controller/CookieTester/SetPublicCookie.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule1\Controller\CookieTester;
+
+/**
+ */
+class SetPublicCookie extends \Magento\TestModule1\Controller\CookieTester
+{
+    /**
+     * Sets a public cookie with data from url parameters
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $publicCookieMetadata = $this->getCookieMetadataFactory()->createPublicCookieMetadata();
+
+        $cookieDomain = $this->getRequest()->getParam('cookie_domain');
+        if ($cookieDomain !== null) {
+            $publicCookieMetadata->setDomain($cookieDomain);
+        }
+
+        $cookiePath = $this->getRequest()->getParam('cookie_path');
+        if ($cookiePath !== null) {
+            $publicCookieMetadata->setPath($cookiePath);
+        }
+
+        $cookieDuration = $this->getRequest()->getParam('cookie_duration');
+        if ($cookieDuration !== null) {
+            $publicCookieMetadata->setDuration($cookieDuration);
+        }
+
+        $httpOnly = $this->getRequest()->getParam('cookie_httponly');
+        if ($httpOnly !== null) {
+            $publicCookieMetadata->setHttpOnly($httpOnly);
+        }
+
+        $secure = $this->getRequest()->getParam('cookie_secure');
+        if ($secure !== null) {
+            $publicCookieMetadata->setSecure($secure);
+        }
+
+        $cookieName = $this->getRequest()->getParam('cookie_name');
+        $cookieValue = $this->getRequest()->getParam('cookie_value');
+        $this->getCookieManager()->setPublicCookie($cookieName, $cookieValue, $publicCookieMetadata);
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Controller/CookieTester/SetSensitiveCookie.php b/dev/tests/api-functional/_files/Magento/TestModule1/Controller/CookieTester/SetSensitiveCookie.php
new file mode 100644
index 00000000000..3cb0d47fae4
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/Controller/CookieTester/SetSensitiveCookie.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule1\Controller\CookieTester;
+
+/**
+ */
+class SetSensitiveCookie extends \Magento\TestModule1\Controller\CookieTester
+{
+    /**
+     * Sets a sensitive cookie with data from url parameters
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $sensitiveCookieMetadata = $this->getCookieMetadataFactory()->createSensitiveCookieMetadata();
+
+        $cookieDomain = $this->getRequest()->getParam('cookie_domain');
+        if ($cookieDomain !== null) {
+            $sensitiveCookieMetadata->setDomain($cookieDomain);
+        }
+        $cookiePath = $this->getRequest()->getParam('cookie_domain');
+        if ($cookiePath !== null) {
+            $sensitiveCookieMetadata->setPath($cookiePath);
+        }
+
+        $cookieName = $this->getRequest()->getParam('cookie_name');
+        $cookieValue = $this->getRequest()->getParam('cookie_value');
+        $this->getCookieManager()->setSensitiveCookie($cookieName, $cookieValue, $sensitiveCookieMetadata);
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/AllSoapAndRest.php b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/AllSoapAndRest.php
new file mode 100644
index 00000000000..025d819004d
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/AllSoapAndRest.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule1\Service\V1;
+
+use Magento\TestModule1\Service\V1\Entity\CustomAttributeDataObjectBuilder;
+use Magento\TestModule1\Service\V1\Entity\Item;
+use Magento\TestModule1\Service\V1\Entity\ItemBuilder;
+
+class AllSoapAndRest implements \Magento\TestModule1\Service\V1\AllSoapAndRestInterface
+{
+    /**
+     * @var ItemBuilder
+     */
+    protected $itemBuilder;
+
+    /**
+     * @var CustomAttributeDataObjectBuilder
+     */
+    protected $customAttributeDataObjectBuilder;
+
+    /**
+     * @param ItemBuilder $itemBuilder
+     * @param CustomAttributeDataObjectBuilder $customAttributeNestedDataObjectBuilder
+     */
+    public function __construct(
+        ItemBuilder $itemBuilder,
+        CustomAttributeDataObjectBuilder $customAttributeNestedDataObjectBuilder
+    ) {
+        $this->itemBuilder = $itemBuilder;
+        $this->customAttributeDataObjectBuilder = $customAttributeNestedDataObjectBuilder;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function item($itemId)
+    {
+        return $this->itemBuilder->setItemId($itemId)->setName('testProduct1')->create();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function items()
+    {
+        $result1 = $this->itemBuilder->setItemId(1)->setName('testProduct1')->create();
+        $result2 = $this->itemBuilder->setItemId(2)->setName('testProduct2')->create();
+
+        return [$result1, $result2];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function create($name)
+    {
+        return $this->itemBuilder->setItemId(rand())->setName($name)->create();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function update(Item $entityItem)
+    {
+        return $this->itemBuilder->setItemId($entityItem->getItemId())
+            ->setName('Updated' . $entityItem->getName())
+            ->create();
+    }
+
+    public function testOptionalParam($name = null)
+    {
+        if (is_null($name)) {
+            return $this->itemBuilder->setItemId(3)->setName('No Name')->create();
+        } else {
+            return $this->itemBuilder->setItemId(3)->setName($name)->create();
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function itemAnyType(Item $item)
+    {
+        return $item;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPreconfiguredItem()
+    {
+        $customAttributeDataObject = $this->customAttributeDataObjectBuilder
+            ->setName('nameValue')
+            ->setCustomAttribute('custom_attribute_int', 1)
+            ->create();
+
+        $item = $this->itemBuilder
+            ->setItemId(1)
+            ->setName('testProductAnyType')
+            ->setCustomAttribute('custom_attribute_data_object', $customAttributeDataObject)
+            ->setCustomAttribute('custom_attribute_string', 'someStringValue')
+            ->create();
+
+        return $item;
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/AllSoapAndRestInterface.php b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/AllSoapAndRestInterface.php
new file mode 100644
index 00000000000..d43d1553561
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/AllSoapAndRestInterface.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule1\Service\V1;
+
+use Magento\TestModule1\Service\V1\Entity\Item;
+
+interface AllSoapAndRestInterface
+{
+    /**
+     * @param int $itemId
+     * @return \Magento\TestModule1\Service\V1\Entity\Item
+     */
+    public function item($itemId);
+
+    /**
+     * @param string $name
+     * @return \Magento\TestModule1\Service\V1\Entity\Item
+     */
+    public function create($name);
+
+    /**
+     * @param \Magento\TestModule1\Service\V1\Entity\Item $entityItem
+     * @return \Magento\TestModule1\Service\V1\Entity\Item
+     */
+    public function update(Item $entityItem);
+
+    /**
+     * @return \Magento\TestModule1\Service\V1\Entity\Item[]
+     */
+    public function items();
+
+    /**
+     * @param string $name
+     * @return \Magento\TestModule1\Service\V1\Entity\Item
+     */
+    public function testOptionalParam($name = null);
+
+    /**
+     * @param \Magento\TestModule1\Service\V1\Entity\Item $entityItem
+     * @return \Magento\TestModule1\Service\V1\Entity\Item
+     */
+    public function itemAnyType(Item $entityItem);
+
+    /**
+     * @return \Magento\TestModule1\Service\V1\Entity\Item
+     */
+    public function getPreconfiguredItem();
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeDataObject.php b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeDataObject.php
new file mode 100644
index 00000000000..b3cf77d4493
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeDataObject.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule1\Service\V1\Entity;
+
+class CustomAttributeDataObject extends \Magento\Framework\Api\AbstractExtensibleObject
+{
+    /**
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->_data['name'];
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeDataObjectBuilder.php b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeDataObjectBuilder.php
new file mode 100644
index 00000000000..e128de99359
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeDataObjectBuilder.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\TestModule1\Service\V1\Entity;
+
+class CustomAttributeDataObjectBuilder extends \Magento\Framework\Api\ExtensibleObjectBuilder
+{
+    /**
+     * @param string $name
+     *
+     * @return $this
+     */
+    public function setName($name)
+    {
+        $this->data['name'] = $name;
+        return $this;
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeNestedDataObject.php b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeNestedDataObject.php
new file mode 100644
index 00000000000..6b439713faf
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeNestedDataObject.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule1\Service\V1\Entity;
+
+class CustomAttributeNestedDataObject extends \Magento\Framework\Api\AbstractExtensibleObject
+{
+    /**
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->_data['name'];
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeNestedDataObjectBuilder.php b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeNestedDataObjectBuilder.php
new file mode 100644
index 00000000000..4bf501ac727
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/CustomAttributeNestedDataObjectBuilder.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\TestModule1\Service\V1\Entity;
+
+class CustomAttributeNestedDataObjectBuilder extends \Magento\Framework\Api\ExtensibleObjectBuilder
+{
+    /**
+     * @param string $name
+     *
+     * @return $this
+     */
+    public function setName($name)
+    {
+        $this->data['name'] = $name;
+        return $this;
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/Eav/AttributeMetadata.php b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/Eav/AttributeMetadata.php
new file mode 100644
index 00000000000..134623a864f
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/Eav/AttributeMetadata.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule1\Service\V1\Entity\Eav;
+
+use Magento\Framework\Api\AbstractExtensibleObject;
+use Magento\Framework\Api\MetadataObjectInterface;
+
+/**
+ * Class AttributeMetadata
+ */
+class AttributeMetadata extends AbstractExtensibleObject implements MetadataObjectInterface
+{
+    /**#@+
+     * Constants used as keys into $_data
+     */
+    const ATTRIBUTE_ID = 'attribute_id';
+
+    const ATTRIBUTE_CODE = 'attribute_code';
+    /**#@-*/
+
+    /**
+     * Retrieve id of the attribute.
+     *
+     * @return string|null
+     */
+    public function getAttributeId()
+    {
+        return $this->_get(self::ATTRIBUTE_ID);
+    }
+
+    /**
+     * Retrieve code of the attribute.
+     *
+     * @return string|null
+     */
+    public function getAttributeCode()
+    {
+        return $this->_get(self::ATTRIBUTE_CODE);
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/Eav/AttributeMetadataBuilder.php b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/Eav/AttributeMetadataBuilder.php
new file mode 100644
index 00000000000..b96ef2b4f5d
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/Eav/AttributeMetadataBuilder.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule1\Service\V1\Entity\Eav;
+
+use Magento\Framework\Api\AttributeMetadataBuilderInterface;
+use Magento\Framework\Api\ExtensibleObjectBuilder;
+
+/**
+ * Class AttributeMetadataBuilder
+ */
+class AttributeMetadataBuilder extends ExtensibleObjectBuilder implements AttributeMetadataBuilderInterface
+{
+    /**
+     * Set attribute id
+     *
+     * @param  int $attributeId
+     * @return $this
+     */
+    public function setAttributeId($attributeId)
+    {
+        return $this->_set(AttributeMetadata::ATTRIBUTE_ID, $attributeId);
+    }
+
+    /**
+     * Set attribute code
+     *
+     * @param  string $attributeCode
+     * @return $this
+     */
+    public function setAttributeCode($attributeCode)
+    {
+        return $this->_set(AttributeMetadata::ATTRIBUTE_CODE, $attributeCode);
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/Item.php b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/Item.php
new file mode 100644
index 00000000000..d307ac8f6a8
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/Item.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule1\Service\V1\Entity;
+
+class Item extends \Magento\Framework\Api\AbstractExtensibleObject
+{
+    /**
+     * @return int
+     */
+    public function getItemId()
+    {
+        return $this->_data['item_id'];
+    }
+
+    /**
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->_data['name'];
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/ItemBuilder.php b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/ItemBuilder.php
new file mode 100644
index 00000000000..c13fd4b8e89
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V1/Entity/ItemBuilder.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule1\Service\V1\Entity;
+
+class ItemBuilder extends \Magento\Framework\Api\ExtensibleObjectBuilder
+{
+    /**#@+
+     * Custom attribute code constants
+     */
+    const CUSTOM_ATTRIBUTE_1 = 'custom_attribute1';
+    const CUSTOM_ATTRIBUTE_2 = 'custom_attribute2';
+    const CUSTOM_ATTRIBUTE_3 = 'custom_attribute3';
+    /**#@-*/
+
+    /**
+     * @param int $itemId
+     *
+     * @return \Magento\TestModule1\Service\V1\Entity\ItemBuilder
+     */
+    public function setItemId($itemId)
+    {
+        $this->data['item_id'] = $itemId;
+        return $this;
+    }
+
+    /**
+     * @param string $name
+     *
+     * @return \Magento\TestModule1\Service\V1\Entity\ItemBuilder
+     */
+    public function setName($name)
+    {
+        $this->data['name'] = $name;
+        return $this;
+    }
+
+    /**
+     * Template method used to configure the attribute codes for the custom attributes
+     *
+     * @return string[]
+     */
+    public function getCustomAttributesCodes()
+    {
+        return array_merge(
+            parent::getCustomAttributesCodes(),
+            [self::CUSTOM_ATTRIBUTE_1, self::CUSTOM_ATTRIBUTE_2, self::CUSTOM_ATTRIBUTE_3]
+        );
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V2/AllSoapAndRest.php b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V2/AllSoapAndRest.php
new file mode 100644
index 00000000000..ef17f0c5749
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V2/AllSoapAndRest.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule1\Service\V2;
+
+use Magento\TestModule1\Service\V2\Entity\Item;
+use Magento\TestModule1\Service\V2\Entity\ItemBuilder;
+
+class AllSoapAndRest implements \Magento\TestModule1\Service\V2\AllSoapAndRestInterface
+{
+    /**
+     * @var ItemBuilder
+     */
+    protected $itemBuilder;
+
+    /**
+     * @param ItemBuilder $itemBuilder
+     */
+    public function __construct(ItemBuilder $itemBuilder)
+    {
+        $this->itemBuilder = $itemBuilder;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function item($id)
+    {
+        return $this->itemBuilder->setId($id)->setName('testProduct1')->setPrice('1')->create();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function items($filters = [], $sortOrder = 'ASC')
+    {
+        $result = [];
+        $firstItem = $this->itemBuilder->setId(1)->setName('testProduct1')->setPrice('1')->create();
+        $secondItem = $this->itemBuilder->setId(2)->setName('testProduct2')->setPrice('2')->create();
+
+        /** Simple filtration implementation */
+        if (!empty($filters)) {
+            /** @var \Magento\Framework\Api\Filter $filter */
+            foreach ($filters as $filter) {
+                if ('id' == $filter->getField() && $filter->getValue() == 1) {
+                    $result[] = $firstItem;
+                } elseif ('id' == $filter->getField() && $filter->getValue() == 2) {
+                    $result[] = $secondItem;
+                }
+            }
+        } else {
+            /** No filter is specified. */
+            $result = [$firstItem, $secondItem];
+        }
+        return $result;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function create($name)
+    {
+        return $this->itemBuilder->setId(rand())->setName($name)->setPrice('10')->create();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function update(Item $entityItem)
+    {
+        return $this->itemBuilder
+            ->setId($entityItem->getId())
+            ->setName('Updated' . $entityItem->getName())
+            ->setPrice('5')->create();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function delete($id)
+    {
+        return $this->itemBuilder->setId($id)->setName('testProduct1')->setPrice('1')->create();
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V2/AllSoapAndRestInterface.php b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V2/AllSoapAndRestInterface.php
new file mode 100644
index 00000000000..0507a01422b
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V2/AllSoapAndRestInterface.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule1\Service\V2;
+
+use Magento\TestModule1\Service\V2\Entity\Item;
+
+interface AllSoapAndRestInterface
+{
+    /**
+     * Get item.
+     *
+     * @param int $id
+     * @return \Magento\TestModule1\Service\V2\Entity\Item
+     */
+    public function item($id);
+
+    /**
+     * Create item.
+     *
+     * @param string $name
+     * @return \Magento\TestModule1\Service\V2\Entity\Item
+     */
+    public function create($name);
+
+    /**
+     * Update item.
+     *
+     * @param \Magento\TestModule1\Service\V2\Entity\Item $entityItem
+     * @return \Magento\TestModule1\Service\V2\Entity\Item
+     */
+    public function update(Item $entityItem);
+
+    /**
+     * Retrieve a list of items.
+     *
+     * @param \Magento\Framework\Api\Filter[] $filters
+     * @param string $sortOrder
+     * @return \Magento\TestModule1\Service\V2\Entity\Item[]
+     */
+    public function items($filters = [], $sortOrder = 'ASC');
+
+    /**
+     * Delete an item.
+     *
+     * @param int $id
+     * @return \Magento\TestModule1\Service\V2\Entity\Item
+     */
+    public function delete($id);
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V2/Entity/Item.php b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V2/Entity/Item.php
new file mode 100644
index 00000000000..79438931a5d
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V2/Entity/Item.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule1\Service\V2\Entity;
+
+class Item extends \Magento\Framework\Api\AbstractExtensibleObject
+{
+    /**
+     * @return int
+     */
+    public function getId()
+    {
+        return $this->_data['id'];
+    }
+
+    /**
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->_data['name'];
+    }
+
+    /**
+     * @return string
+     */
+    public function getPrice()
+    {
+        return $this->_data['price'];
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/Service/V2/Entity/ItemBuilder.php b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V2/Entity/ItemBuilder.php
new file mode 100644
index 00000000000..d28d791b6b8
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/Service/V2/Entity/ItemBuilder.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule1\Service\V2\Entity;
+
+class ItemBuilder extends \Magento\Framework\Api\ExtensibleObjectBuilder
+{
+    /**
+     * @param int $id
+     *
+     * @return \Magento\TestModule1\Service\V2\Entity\ItemBuilder
+     */
+    public function setId($id)
+    {
+        $this->data['id'] = $id;
+        return $this;
+    }
+
+    /**
+     * @param string $name
+     *
+     * @return \Magento\TestModule1\Service\V2\Entity\ItemBuilder
+     */
+    public function setName($name)
+    {
+        $this->data['name'] = $name;
+        return $this;
+    }
+
+    /**
+     * @param string $price
+     *
+     * @return \Magento\TestModule1\Service\V2\Entity\ItemBuilder
+     */
+    public function setPrice($price)
+    {
+        $this->data['price'] = $price;
+        return $this;
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/etc/acl.xml b/dev/tests/api-functional/_files/Magento/TestModule1/etc/acl.xml
new file mode 100644
index 00000000000..e6fcca6add8
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/etc/acl.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/Acl/etc/acl.xsd">
+    <acl>
+        <resources>
+            <resource id="Magento_Adminhtml::admin">
+                <resource id="Magento_TestModule1::all" title="TestModule1" sortOrder="1">
+                    <resource id="Magento_TestModule1::resource1" title="Resource1" sortOrder="20"/>
+                    <resource id="Magento_TestModule1::resource2" title="Resource2" sortOrder="10"/>
+                    <resource id="Magento_TestModule1::resource3" title="Resource3" sortOrder="30"/>
+                </resource>
+            </resource>
+        </resources>
+    </acl>
+</config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/etc/data_object.xml b/dev/tests/api-functional/_files/Magento/TestModule1/etc/data_object.xml
new file mode 100644
index 00000000000..f30038e83f4
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/etc/data_object.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/Api/etc/data_object.xsd">
+    <custom_attributes for="Magento\TestModule1\Service\V1\Entity\Item">
+        <attribute code="custom_attribute_data_object" type="Magento\TestModule1\Service\V1\Entity\CustomAttributeDataObject" />
+        <attribute code="custom_attribute_string" type="string" />
+    </custom_attributes>
+    <custom_attributes for="Magento\TestModule1\Service\V1\Entity\CustomAttributeDataObject">
+        <attribute code="custom_attribute_nested" type="Magento\TestModule1\Service\V1\Entity\CustomAttributeNestedDataObject" />
+        <attribute code="custom_attribute_int" type="int" />
+    </custom_attributes>
+</config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/etc/di.xml b/dev/tests/api-functional/_files/Magento/TestModule1/etc/di.xml
new file mode 100644
index 00000000000..977ca625f28
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/etc/di.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <preference for="Magento\TestModule1\Service\V1\AllSoapAndRestInterface" type="Magento\TestModule1\Service\V1\AllSoapAndRest" />
+    <preference for="Magento\TestModule1\Service\V2\AllSoapAndRestInterface" type="Magento\TestModule1\Service\V2\AllSoapAndRest" />
+
+    <virtualType name="Magento\TestModule1\Service\Config\TestModule1MetadataConfig" type="Magento\Framework\Api\Config\MetadataConfig">
+        <arguments>
+            <argument name="attributeMetadataBuilder" xsi:type="object">Magento\TestModule1\Service\V1\Entity\Eav\AttributeMetadataBuilder</argument>
+            <argument name="dataObjectClassName" xsi:type="string">Magento\TestModule1\Service\V1\Entity\Item</argument>
+        </arguments>
+    </virtualType>
+    <type name="Magento\TestModule1\Service\V1\Entity\ItemBuilder">
+        <arguments>
+            <argument name="metadataService" xsi:type="object">Magento\TestModule1\Service\Config\TestModule1MetadataConfig</argument>
+        </arguments>
+    </type>
+</config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/etc/frontend/routes.xml b/dev/tests/api-functional/_files/Magento/TestModule1/etc/frontend/routes.xml
new file mode 100644
index 00000000000..f6984e2d6d7
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/etc/frontend/routes.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
+    <router id="standard">
+        <route id="testmoduleone" frontName="testmoduleone">
+            <module name="Magento_TestModule1" />
+        </route>
+    </router>
+</config>
\ No newline at end of file
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/etc/module.xml b/dev/tests/api-functional/_files/Magento/TestModule1/etc/module.xml
new file mode 100644
index 00000000000..ba0d4419588
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/etc/module.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
+    <module name="Magento_TestModule1" schema_version="1.0"/>
+</config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule1/etc/webapi.xml b/dev/tests/api-functional/_files/Magento/TestModule1/etc/webapi.xml
new file mode 100644
index 00000000000..874afa77138
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule1/etc/webapi.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../app/code/Magento/Webapi/etc/webapi.xsd">
+
+    <route method="GET" url="/V1/testmodule1/overwritten">
+        <service class="Magento\TestModule1\Service\V1\AllSoapAndRestInterface" method="item" />
+        <resources>
+            <resource ref="Magento_TestModule1::resource1" />
+        </resources>
+        <data>
+            <parameter name="itemId" force="true">-55</parameter>
+        </data>
+    </route>
+
+    <route method="POST" url="/V1/testmodule1/testOptionalParam">
+        <service class="Magento\TestModule1\Service\V1\AllSoapAndRestInterface" method="testOptionalParam" />
+        <resources>
+            <resource ref="Magento_TestModule1::resource1" />
+        </resources>
+        <data>
+            <parameter name="name">Default Name</parameter>
+        </data>
+    </route>
+
+    <route method="GET" url="/V1/testmodule1/:itemId">
+        <service class="Magento\TestModule1\Service\V1\AllSoapAndRestInterface" method="item" />
+        <resources>
+            <resource ref="Magento_TestModule1::resource1" />
+        </resources>
+    </route>
+    <route method="GET" url="/V1/testmodule1">
+        <service class="Magento\TestModule1\Service\V1\AllSoapAndRestInterface" method="items" />
+        <resources>
+            <resource ref="Magento_TestModule1::resource2" />
+        </resources>
+    </route>
+    <route method="POST" url="/V1/testmodule1">
+        <service class="Magento\TestModule1\Service\V1\AllSoapAndRestInterface" method="create" />
+        <resources>
+            <resource ref="Magento_TestModule1::resource3" />
+        </resources>
+    </route>
+    <route method="PUT" url="/V1/testmodule1/:itemId">
+        <service class="Magento\TestModule1\Service\V1\AllSoapAndRestInterface" method="update" />
+        <resources>
+            <resource ref="Magento_TestModule1::resource1" />
+            <resource ref="Magento_TestModule1::resource2" />
+        </resources>
+    </route>
+    <route method="POST" url="/V1/testmodule1/itemAnyType">
+        <service class="Magento\TestModule1\Service\V1\AllSoapAndRestInterface" method="itemAnyType" />
+        <resources>
+            <resource ref="Magento_TestModule1::resource1" />
+            <resource ref="Magento_TestModule1::resource2" />
+        </resources>
+    </route>
+    <route method="GET" url="/V1/testmodule1/itemPreconfigured">
+        <service class="Magento\TestModule1\Service\V1\AllSoapAndRestInterface" method="getPreconfiguredItem" />
+        <resources>
+            <resource ref="Magento_TestModule1::resource1" />
+            <resource ref="Magento_TestModule1::resource2" />
+        </resources>
+    </route>
+    <route method="GET" url="/V2/testmodule1/:id">
+        <service class="Magento\TestModule1\Service\V2\AllSoapAndRestInterface" method="item" />
+        <resources>
+            <resource ref="Magento_TestModule1::resource1" />
+        </resources>
+    </route>
+    <route method="GET" url="/V2/testmodule1">
+        <service class="Magento\TestModule1\Service\V2\AllSoapAndRestInterface" method="items" />
+        <resources>
+            <resource ref="Magento_TestModule1::resource2" />
+        </resources>
+    </route>
+    <route method="POST" url="/V2/testmodule1">
+        <service class="Magento\TestModule1\Service\V2\AllSoapAndRestInterface" method="create" />
+        <resources>
+            <resource ref="Magento_TestModule1::resource3" />
+        </resources>
+    </route>
+    <route method="PUT" url="/V2/testmodule1/:id">
+        <service class="Magento\TestModule1\Service\V2\AllSoapAndRestInterface" method="update" />
+        <resources>
+            <resource ref="Magento_TestModule1::resource1" />
+            <resource ref="Magento_TestModule1::resource2" />
+        </resources>
+    </route>
+    <route method="DELETE" url="/V2/testmodule1/:id">
+        <service class="Magento\TestModule1\Service\V2\AllSoapAndRestInterface" method="delete" />
+        <resources>
+            <resource ref="Magento_TestModule1::resource1" />
+        </resources>
+    </route>
+</routes>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/Entity/Item.php b/dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/Entity/Item.php
new file mode 100644
index 00000000000..ac51c4663a5
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/Entity/Item.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule2\Service\V1\Entity;
+
+class Item extends \Magento\Framework\Api\AbstractExtensibleObject
+{
+    /**
+     * @return int
+     */
+    public function getId()
+    {
+        return $this->_data['id'];
+    }
+
+    /**
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->_data['name'];
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/Entity/ItemBuilder.php b/dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/Entity/ItemBuilder.php
new file mode 100644
index 00000000000..79b57a34aec
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/Entity/ItemBuilder.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule2\Service\V1\Entity;
+
+class ItemBuilder extends \Magento\Framework\Api\ExtensibleObjectBuilder
+{
+    /**
+     * @param int $id
+     * @return \Magento\TestModule2\Service\V1\Entity\ItemBuilder
+     */
+    public function setId($id)
+    {
+        $this->data['id'] = $id;
+        return $this;
+    }
+
+    /**
+     * @param string $name
+     * @return \Magento\TestModule2\Service\V1\Entity\ItemBuilder
+     */
+    public function setName($name)
+    {
+        $this->data['name'] = $name;
+        return $this;
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/NoWebApiXml.php b/dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/NoWebApiXml.php
new file mode 100644
index 00000000000..9a1128502b8
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/NoWebApiXml.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule2\Service\V1;
+
+use Magento\TestModule2\Service\V1\Entity\Item;
+use Magento\TestModule2\Service\V1\Entity\ItemBuilder;
+
+class NoWebApiXml implements \Magento\TestModule2\Service\V1\NoWebApiXmlInterface
+{
+    /**
+     * @var ItemBuilder
+     */
+    protected $itemBuilder;
+
+    /**
+     * @param ItemBuilder $itemBuilder
+     */
+    public function __construct(ItemBuilder $itemBuilder)
+    {
+        $this->itemBuilder = $itemBuilder;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function item($id)
+    {
+        return $this->itemBuilder->setId($id)->setName('testProduct1')->create();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function items()
+    {
+        $result1 = $this->itemBuilder->setId(1)->setName('testProduct1')->create();
+
+        $result2 = $this->itemBuilder->setId(2)->setName('testProduct2')->create();
+
+        return [$result1, $result2];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function create($name)
+    {
+        return $this->itemBuilder->setId(rand())->setName($name)->create();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function update(Item $item)
+    {
+        return $this->itemBuilder->setId($item->getId())->setName('Updated' . $item->getName())->create();
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/NoWebApiXmlInterface.php b/dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/NoWebApiXmlInterface.php
new file mode 100644
index 00000000000..474ef888d51
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/NoWebApiXmlInterface.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule2\Service\V1;
+
+use Magento\TestModule2\Service\V1\Entity\Item;
+
+interface NoWebApiXmlInterface
+{
+    /**
+     * Get an item.
+     *
+     * @param int $id
+     * @return \Magento\TestModule2\Service\V1\Entity\Item
+     */
+    public function item($id);
+
+    /**
+     * Create an item.
+     *
+     * @param string $name
+     * @return \Magento\TestModule2\Service\V1\Entity\Item
+     */
+    public function create($name);
+
+    /**
+     * Update an item.
+     *
+     * @param \Magento\TestModule2\Service\V1\Entity\Item $item
+     * @return \Magento\TestModule2\Service\V1\Entity\Item
+     */
+    public function update(Item $item);
+
+    /**
+     * Retrieve a list of items.
+     *
+     * @return \Magento\TestModule2\Service\V1\Entity\Item[]
+     */
+    public function items();
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/SubsetRest.php b/dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/SubsetRest.php
new file mode 100644
index 00000000000..0f6d5e9670a
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/SubsetRest.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule2\Service\V1;
+
+use Magento\TestModule2\Service\V1\Entity\Item;
+use Magento\TestModule2\Service\V1\Entity\ItemBuilder;
+
+class SubsetRest implements \Magento\TestModule2\Service\V1\SubsetRestInterface
+{
+    /**
+     * @var ItemBuilder
+     */
+    protected $itemBuilder;
+
+    /**
+     * @param ItemBuilder $itemBuilder
+     */
+    public function __construct(ItemBuilder $itemBuilder)
+    {
+        $this->itemBuilder = $itemBuilder;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function item($id)
+    {
+        return $this->itemBuilder->setId($id)->setName('testItem' . $id)->create();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function items()
+    {
+        $result1 = $this->itemBuilder->setId(1)->setName('testItem1')->create();
+
+        $result2 = $this->itemBuilder->setId(2)->setName('testItem2')->create();
+
+        return [$result1, $result2];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function create($name)
+    {
+        return $this->itemBuilder->setId(rand())->setName($name)->create();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function update(Item $item)
+    {
+        return $this->itemBuilder->setId($item->getId())->setName('Updated' . $item->getName())->create();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function remove($id)
+    {
+        return $this->itemBuilder->setId(1)->create();
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/SubsetRestInterface.php b/dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/SubsetRestInterface.php
new file mode 100644
index 00000000000..c52fd18fb55
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule2/Service/V1/SubsetRestInterface.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule2\Service\V1;
+
+use Magento\TestModule2\Service\V1\Entity\Item;
+
+interface SubsetRestInterface
+{
+    /**
+     * Return a single item.
+     *
+     * @param int $id
+     * @return \Magento\TestModule2\Service\V1\Entity\Item
+     */
+    public function item($id);
+
+    /**
+     * Return multiple items.
+     *
+     * @return \Magento\TestModule2\Service\V1\Entity\Item[]
+     */
+    public function items();
+
+    /**
+     * Create an item.
+     *
+     * @param string $name
+     * @return \Magento\TestModule2\Service\V1\Entity\Item
+     */
+    public function create($name);
+
+    /**
+     * Update an item.
+     *
+     * @param \Magento\TestModule2\Service\V1\Entity\Item $item
+     * @return \Magento\TestModule2\Service\V1\Entity\Item
+     */
+    public function update(Item $item);
+
+    /**
+     * Delete an item.
+     *
+     * @param int $id
+     * @return \Magento\TestModule2\Service\V1\Entity\Item
+     */
+    public function remove($id);
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule2/etc/acl.xml b/dev/tests/api-functional/_files/Magento/TestModule2/etc/acl.xml
new file mode 100644
index 00000000000..d6b32a5bf83
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule2/etc/acl.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/Acl/etc/acl.xsd">
+    <acl>
+        <resources>
+            <resource id="Magento_Adminhtml::admin">
+                <resource id="Magento_TestModule2::all" title="TestModule2" sortOrder="1">
+                    <resource id="Magento_TestModule2::resource1" title="Resource1" sortOrder="20"/>
+                    <resource id="Magento_TestModule2::resource2" title="Resource2" sortOrder="10"/>
+                    <resource id="Magento_TestModule2::resource3" title="Resource3" sortOrder="30"/>
+                </resource>
+            </resource>
+        </resources>
+    </acl>
+</config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule2/etc/di.xml b/dev/tests/api-functional/_files/Magento/TestModule2/etc/di.xml
new file mode 100644
index 00000000000..ffb7f082e52
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule2/etc/di.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <preference for="Magento\TestModule2\Service\V1\SubsetRestInterface" type="Magento\TestModule2\Service\V1\SubsetRest" />
+    <preference for="Magento\TestModule2\Service\V1\NoWebApiXmlInterface" type="Magento\TestModule2\Service\V1\NoWebApiXml" />
+</config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule2/etc/module.xml b/dev/tests/api-functional/_files/Magento/TestModule2/etc/module.xml
new file mode 100644
index 00000000000..6f6c90cfd91
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule2/etc/module.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
+    <module name="Magento_TestModule2" schema_version="1.0"/>
+</config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule2/etc/schema/AllSoapNoRestV1.xsd b/dev/tests/api-functional/_files/Magento/TestModule2/etc/schema/AllSoapNoRestV1.xsd
new file mode 100644
index 00000000000..3e7caaa8d48
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule2/etc/schema/AllSoapNoRestV1.xsd
@@ -0,0 +1,239 @@
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+    <xsd:complexType name="ItemRequest">
+        <xsd:annotation>
+            <xsd:documentation/>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:int">
+                <xsd:annotation>
+                    <xsd:documentation>Entity ID</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:min/>
+                        <inf:max/>
+                        <inf:callInfo>
+                            <inf:callName>Item</inf:callName>
+                            <inf:requiredInput>Yes</inf:requiredInput>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    <xsd:complexType name="ItemResponse">
+        <xsd:annotation>
+            <xsd:documentation>Response container for the Item call.</xsd:documentation>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Item</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+
+    <xsd:complexType name="ItemsResponse">
+        <xsd:annotation>
+            <xsd:documentation>Response container for the Items call.</xsd:documentation>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray"
+                         type="ItemsArray">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Items</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+
+
+    <xsd:complexType name="ItemsArray">
+        <xsd:annotation>
+            <xsd:documentation>Response container for the Items call.</xsd:documentation>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Items</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+            <xsd:element name="name"  type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Item</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+
+    <xsd:complexType name="CreateRequest">
+        <xsd:annotation>
+            <xsd:documentation/>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="name"  type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Create</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    <xsd:complexType name="CreateResponse">
+        <xsd:annotation>
+            <xsd:documentation>Response container for the Create call.</xsd:documentation>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Create</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+            <xsd:element name="name"  type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Create</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    <xsd:complexType name="UpdateRequest">
+        <xsd:annotation>
+            <xsd:documentation/>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:int">
+                <xsd:annotation>
+                    <xsd:documentation>Entity ID</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:min/>
+                        <inf:max/>
+                        <inf:callInfo>
+                            <inf:callName>Update</inf:callName>
+                            <inf:requiredInput>Yes</inf:requiredInput>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    <xsd:complexType name="UpdateResponse">
+        <xsd:annotation>
+            <xsd:documentation>Response container for the Update call.</xsd:documentation>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Update</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    <xsd:complexType name="RemoveRequest">
+        <xsd:annotation>
+            <xsd:documentation/>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:int">
+                <xsd:annotation>
+                    <xsd:documentation>Entity ID</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:min/>
+                        <inf:max/>
+                        <inf:callInfo>
+                            <inf:callName>Remove</inf:callName>
+                            <inf:requiredInput>Yes</inf:requiredInput>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    <xsd:complexType name="RemoveResponse">
+        <xsd:annotation>
+            <xsd:documentation>Response container for the Remove call.</xsd:documentation>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Remove</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+</xsd:schema>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule2/etc/schema/NoWebApiXmlV1.xsd b/dev/tests/api-functional/_files/Magento/TestModule2/etc/schema/NoWebApiXmlV1.xsd
new file mode 100644
index 00000000000..3e7caaa8d48
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule2/etc/schema/NoWebApiXmlV1.xsd
@@ -0,0 +1,239 @@
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+    <xsd:complexType name="ItemRequest">
+        <xsd:annotation>
+            <xsd:documentation/>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:int">
+                <xsd:annotation>
+                    <xsd:documentation>Entity ID</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:min/>
+                        <inf:max/>
+                        <inf:callInfo>
+                            <inf:callName>Item</inf:callName>
+                            <inf:requiredInput>Yes</inf:requiredInput>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    <xsd:complexType name="ItemResponse">
+        <xsd:annotation>
+            <xsd:documentation>Response container for the Item call.</xsd:documentation>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Item</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+
+    <xsd:complexType name="ItemsResponse">
+        <xsd:annotation>
+            <xsd:documentation>Response container for the Items call.</xsd:documentation>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray"
+                         type="ItemsArray">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Items</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+
+
+    <xsd:complexType name="ItemsArray">
+        <xsd:annotation>
+            <xsd:documentation>Response container for the Items call.</xsd:documentation>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Items</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+            <xsd:element name="name"  type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Item</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+
+    <xsd:complexType name="CreateRequest">
+        <xsd:annotation>
+            <xsd:documentation/>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="name"  type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Create</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    <xsd:complexType name="CreateResponse">
+        <xsd:annotation>
+            <xsd:documentation>Response container for the Create call.</xsd:documentation>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Create</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+            <xsd:element name="name"  type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Create</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    <xsd:complexType name="UpdateRequest">
+        <xsd:annotation>
+            <xsd:documentation/>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:int">
+                <xsd:annotation>
+                    <xsd:documentation>Entity ID</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:min/>
+                        <inf:max/>
+                        <inf:callInfo>
+                            <inf:callName>Update</inf:callName>
+                            <inf:requiredInput>Yes</inf:requiredInput>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    <xsd:complexType name="UpdateResponse">
+        <xsd:annotation>
+            <xsd:documentation>Response container for the Update call.</xsd:documentation>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Update</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    <xsd:complexType name="RemoveRequest">
+        <xsd:annotation>
+            <xsd:documentation/>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:int">
+                <xsd:annotation>
+                    <xsd:documentation>Entity ID</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:min/>
+                        <inf:max/>
+                        <inf:callInfo>
+                            <inf:callName>Remove</inf:callName>
+                            <inf:requiredInput>Yes</inf:requiredInput>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    <xsd:complexType name="RemoveResponse">
+        <xsd:annotation>
+            <xsd:documentation>Response container for the Remove call.</xsd:documentation>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Remove</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+</xsd:schema>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule2/etc/schema/SubsetRestV1.xsd b/dev/tests/api-functional/_files/Magento/TestModule2/etc/schema/SubsetRestV1.xsd
new file mode 100644
index 00000000000..3e7caaa8d48
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule2/etc/schema/SubsetRestV1.xsd
@@ -0,0 +1,239 @@
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+    <xsd:complexType name="ItemRequest">
+        <xsd:annotation>
+            <xsd:documentation/>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:int">
+                <xsd:annotation>
+                    <xsd:documentation>Entity ID</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:min/>
+                        <inf:max/>
+                        <inf:callInfo>
+                            <inf:callName>Item</inf:callName>
+                            <inf:requiredInput>Yes</inf:requiredInput>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    <xsd:complexType name="ItemResponse">
+        <xsd:annotation>
+            <xsd:documentation>Response container for the Item call.</xsd:documentation>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Item</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+
+    <xsd:complexType name="ItemsResponse">
+        <xsd:annotation>
+            <xsd:documentation>Response container for the Items call.</xsd:documentation>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray"
+                         type="ItemsArray">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Items</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+
+
+    <xsd:complexType name="ItemsArray">
+        <xsd:annotation>
+            <xsd:documentation>Response container for the Items call.</xsd:documentation>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Items</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+            <xsd:element name="name"  type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Item</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+
+    <xsd:complexType name="CreateRequest">
+        <xsd:annotation>
+            <xsd:documentation/>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="name"  type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Create</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    <xsd:complexType name="CreateResponse">
+        <xsd:annotation>
+            <xsd:documentation>Response container for the Create call.</xsd:documentation>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Create</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+            <xsd:element name="name"  type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Create</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    <xsd:complexType name="UpdateRequest">
+        <xsd:annotation>
+            <xsd:documentation/>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:int">
+                <xsd:annotation>
+                    <xsd:documentation>Entity ID</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:min/>
+                        <inf:max/>
+                        <inf:callInfo>
+                            <inf:callName>Update</inf:callName>
+                            <inf:requiredInput>Yes</inf:requiredInput>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    <xsd:complexType name="UpdateResponse">
+        <xsd:annotation>
+            <xsd:documentation>Response container for the Update call.</xsd:documentation>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Update</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    <xsd:complexType name="RemoveRequest">
+        <xsd:annotation>
+            <xsd:documentation/>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:int">
+                <xsd:annotation>
+                    <xsd:documentation>Entity ID</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:min/>
+                        <inf:max/>
+                        <inf:callInfo>
+                            <inf:callName>Remove</inf:callName>
+                            <inf:requiredInput>Yes</inf:requiredInput>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    <xsd:complexType name="RemoveResponse">
+        <xsd:annotation>
+            <xsd:documentation>Response container for the Remove call.</xsd:documentation>
+            <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap"/>
+        </xsd:annotation>
+        <xsd:sequence>
+            <xsd:element name="id" type="xsd:string">
+                <xsd:annotation>
+                    <xsd:documentation>Default label</xsd:documentation>
+                    <xsd:appinfo xmlns:inf="http://magento.ll/webapi/soap">
+                        <inf:maxLength/>
+                        <inf:callInfo>
+                            <inf:callName>Remove</inf:callName>
+                            <inf:returned>Always</inf:returned>
+                        </inf:callInfo>
+                    </xsd:appinfo>
+                </xsd:annotation>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+</xsd:schema>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule2/etc/webapi.xml b/dev/tests/api-functional/_files/Magento/TestModule2/etc/webapi.xml
new file mode 100644
index 00000000000..fb4339826d5
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule2/etc/webapi.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../app/code/Magento/Webapi/etc/webapi.xsd">
+    <route method="GET" url="/V1/testModule2SubsetRest/:id">
+        <service class="Magento\TestModule2\Service\V1\SubsetRestInterface" method="item" />
+        <resources>
+            <resource ref="Magento_TestModule2::resource1" />
+        </resources>
+    </route>
+    <route method="GET" url="/V1/testModule2SubsetRest">
+        <service class="Magento\TestModule2\Service\V1\SubsetRestInterface" method="items" />
+        <resources>
+            <resource ref="Magento_TestModule2::resource2" />
+            <resource ref="Magento_TestModule2::resource3" />
+        </resources>
+    </route>
+</routes>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Entity/Parameter.php b/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Entity/Parameter.php
new file mode 100644
index 00000000000..a6f58178d04
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Entity/Parameter.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule3\Service\V1\Entity;
+
+class Parameter extends \Magento\Framework\Api\AbstractExtensibleObject
+{
+    /**
+     * Get Name.
+     *
+     * @return string $name
+     */
+    public function getName()
+    {
+        return $this->_data['name'];
+    }
+
+    /**
+     * Get value.
+     *
+     * @return string $value
+     */
+    public function getValue()
+    {
+        return $this->_data['value'];
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Entity/ParameterBuilder.php b/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Entity/ParameterBuilder.php
new file mode 100644
index 00000000000..31ec2076df4
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Entity/ParameterBuilder.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule3\Service\V1\Entity;
+
+class ParameterBuilder extends \Magento\Framework\Api\ExtensibleObjectBuilder
+{
+    /**
+     * Set Name.
+     *
+     * @param string $name
+     * @return \Magento\TestModule3\Service\V1\Entity\ParameterBuilder
+     */
+    public function setName($name)
+    {
+        $this->data['name'] = $name;
+        return $this;
+    }
+
+    /**
+     * Set value.
+     *
+     * @param string $value
+     * @return \Magento\TestModule3\Service\V1\Entity\ParameterBuilder
+     */
+    public function setValue($value)
+    {
+        $this->data['value'] = $value;
+        return $this;
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Entity/WrappedErrorParameter.php b/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Entity/WrappedErrorParameter.php
new file mode 100644
index 00000000000..775e04a2ce5
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Entity/WrappedErrorParameter.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\TestModule3\Service\V1\Entity;
+
+class WrappedErrorParameter extends \Magento\Framework\Api\AbstractExtensibleObject
+{
+    /**
+     * Get field name.
+     *
+     * @return string $name
+     */
+    public function getFieldName()
+    {
+        return $this->_data['field_name'];
+    }
+
+    /**
+     * Get value.
+     *
+     * @return string $value
+     */
+    public function getValue()
+    {
+        return $this->_data['value'];
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Entity/WrappedErrorParameterBuilder.php b/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Entity/WrappedErrorParameterBuilder.php
new file mode 100644
index 00000000000..d6b3f9de2ae
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Entity/WrappedErrorParameterBuilder.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\TestModule3\Service\V1\Entity;
+
+class WrappedErrorParameterBuilder extends \Magento\Framework\Api\ExtensibleObjectBuilder
+{
+    /**
+     * Set field name.
+     *
+     * @param string $fieldName
+     * @return $this
+     */
+    public function setFieldName($fieldName)
+    {
+        $this->data['field_name'] = $fieldName;
+        return $this;
+    }
+
+    /**
+     * Set value.
+     *
+     * @param string $value
+     * @return $this
+     */
+    public function setValue($value)
+    {
+        $this->data['value'] = $value;
+        return $this;
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Error.php b/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Error.php
new file mode 100644
index 00000000000..6410845b051
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/Error.php
@@ -0,0 +1,117 @@
+<?php
+/**
+ * Implementation of a test service for error handling testing
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule3\Service\V1;
+
+use Magento\Framework\Exception\AuthorizationException;
+use Magento\Framework\Exception\InputException;
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\TestModule3\Service\V1\Entity\Parameter;
+use Magento\TestModule3\Service\V1\Entity\ParameterBuilder;
+
+class Error implements \Magento\TestModule3\Service\V1\ErrorInterface
+{
+    /**
+     * @var ParameterBuilder
+     */
+    protected $parameterBuilder;
+
+    /**
+     * @param ParameterBuilder $parameterBuilder
+     */
+    public function __construct(ParameterBuilder $parameterBuilder)
+    {
+        $this->parameterBuilder = $parameterBuilder;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function success()
+    {
+        return $this->parameterBuilder->setName('id')->setValue('a good id')->create();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function resourceNotFoundException()
+    {
+        throw new NoSuchEntityException('Resource with ID "%resource_id" not found.', ['resource_id' => 'resourceY']);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function serviceException()
+    {
+        throw new LocalizedException('Generic service exception %param', ['param' => 3456]);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function parameterizedServiceException($parameters)
+    {
+        $details = [];
+        foreach ($parameters as $parameter) {
+            $details[$parameter->getName()] = $parameter->getValue();
+        }
+        throw new LocalizedException('Parameterized service exception', $details);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function authorizationException()
+    {
+        throw new AuthorizationException('Consumer is not authorized to access %resources', [
+            'resources'   => 'resourceN'
+        ]);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function webapiException()
+    {
+        throw new \Magento\Webapi\Exception('Service not found', 5555, \Magento\Webapi\Exception::HTTP_NOT_FOUND);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function otherException()
+    {
+        throw new \Exception('Non service exception', 5678);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function returnIncompatibleDataType()
+    {
+        return "incompatibleDataType";
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function inputException($wrappedErrorParameters)
+    {
+        $exception = new InputException();
+        if ($wrappedErrorParameters) {
+            foreach ($wrappedErrorParameters as $error) {
+                $exception->addError(
+                    InputException::INVALID_FIELD_VALUE,
+                    ['fieldName' => $error->getFieldName(), 'value' => $error->getValue()]
+                );
+            }
+        }
+        throw $exception;
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/ErrorInterface.php b/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/ErrorInterface.php
new file mode 100644
index 00000000000..59612a9755b
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule3/Service/V1/ErrorInterface.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Interface for a test service for error handling testing
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule3\Service\V1;
+
+use Magento\TestModule3\Service\V1\Entity\Parameter;
+
+interface ErrorInterface
+{
+    /**
+     * @return \Magento\TestModule3\Service\V1\Entity\Parameter
+     */
+    public function success();
+
+    /**
+     * @return int Status
+     */
+    public function resourceNotFoundException();
+
+    /**
+     * @return int Status
+     */
+    public function serviceException();
+
+    /**
+     * @param \Magento\TestModule3\Service\V1\Entity\Parameter[] $parameters
+     * @return int Status
+     */
+    public function parameterizedServiceException($parameters);
+
+    /**
+     * @return int Status
+     */
+    public function authorizationException();
+
+    /**
+     * @return int Status
+     */
+    public function webapiException();
+
+    /**
+     * @return int Status
+     */
+    public function otherException();
+
+    /**
+     * @return int Status
+     */
+    public function returnIncompatibleDataType();
+
+    /**
+     * @param \Magento\TestModule3\Service\V1\Entity\WrappedErrorParameter[] $wrappedErrorParameters
+     * @return int Status
+     */
+    public function inputException($wrappedErrorParameters);
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule3/etc/acl.xml b/dev/tests/api-functional/_files/Magento/TestModule3/etc/acl.xml
new file mode 100644
index 00000000000..556c0987843
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule3/etc/acl.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/Acl/etc/acl.xsd">
+    <acl>
+        <resources>
+            <resource id="Magento_Adminhtml::admin">
+                <resource id="Magento_TestModule3::all" title="TestModule3" sortOrder="1">
+                    <resource id="Magento_TestModule3::resource1" title="Resource1" sortOrder="20"/>
+                </resource>
+            </resource>
+        </resources>
+    </acl>
+</config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule3/etc/di.xml b/dev/tests/api-functional/_files/Magento/TestModule3/etc/di.xml
new file mode 100644
index 00000000000..b26be009346
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule3/etc/di.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <preference for="Magento\TestModule3\Service\V1\ErrorInterface" type="Magento\TestModule3\Service\V1\Error" />
+</config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule3/etc/module.xml b/dev/tests/api-functional/_files/Magento/TestModule3/etc/module.xml
new file mode 100644
index 00000000000..42ae9667a27
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule3/etc/module.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
+    <module name="Magento_TestModule3" schema_version="1.0"/>
+</config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule3/etc/webapi.xml b/dev/tests/api-functional/_files/Magento/TestModule3/etc/webapi.xml
new file mode 100644
index 00000000000..ca7043e0c42
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule3/etc/webapi.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../app/code/Magento/Webapi/etc/webapi.xsd">
+    <route method="GET" url="/V1/errortest/success">
+        <service class="Magento\TestModule3\Service\V1\ErrorInterface" method="success" />
+        <resources>
+            <resource ref="Magento_TestModule3::resource1" />
+        </resources>
+    </route>
+    <route method="GET" url="/V1/errortest/notfound">
+        <service class="Magento\TestModule3\Service\V1\ErrorInterface" method="resourceNotFoundException" />
+        <resources>
+            <resource ref="Magento_TestModule3::resource1" />
+        </resources>
+    </route>
+    <route method="GET" url="/V1/errortest/serviceexception">
+        <service class="Magento\TestModule3\Service\V1\ErrorInterface" method="serviceException" />
+        <resources>
+            <resource ref="Magento_TestModule3::resource1" />
+        </resources>
+    </route>
+    <route method="POST" url="/V1/errortest/parameterizedserviceexception">
+        <service class="Magento\TestModule3\Service\V1\ErrorInterface" method="parameterizedServiceException" />
+        <resources>
+            <resource ref="Magento_TestModule3::resource1" />
+        </resources>
+    </route>
+    <route method="GET" url="/V1/errortest/unauthorized">
+        <service class="Magento\TestModule3\Service\V1\ErrorInterface" method="authorizationException" />
+        <resources>
+            <resource ref="Magento_TestModule3::resource1" />
+            <resource ref="Magento_TestModule3::resource2" />
+        </resources>
+    </route>
+    <route method="GET" url="/V1/errortest/otherException">
+        <service class="Magento\TestModule3\Service\V1\ErrorInterface" method="otherException" />
+        <resources>
+            <resource ref="Magento_TestModule3::resource1" />
+        </resources>
+    </route>
+    <route method="GET" url="/V1/errortest/returnIncompatibleDataType">
+        <service class="Magento\TestModule3\Service\V1\ErrorInterface" method="returnIncompatibleDataType" />
+        <resources>
+            <resource ref="Magento_TestModule3::resource1" />
+        </resources>
+    </route>
+    <route method="GET" url="/V1/errortest/webapiException">
+        <service class="Magento\TestModule3\Service\V1\ErrorInterface" method="webapiException" />
+        <resources>
+            <resource ref="Magento_TestModule3::resource1" />
+        </resources>
+    </route>
+    <route method="POST" url="/V1/errortest/inputException">
+        <service class="Magento\TestModule3\Service\V1\ErrorInterface" method="inputException" />
+        <resources>
+            <resource ref="Magento_TestModule3::resource1" />
+        </resources>
+    </route>
+</routes>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule4/Model/Resource/Item.php b/dev/tests/api-functional/_files/Magento/TestModule4/Model/Resource/Item.php
new file mode 100644
index 00000000000..346d39bdca4
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule4/Model/Resource/Item.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\TestModule4\Model\Resource;
+
+/**
+ * Sample resource model
+ */
+class Item extends \Magento\Framework\Model\Resource\Db\AbstractDb
+{
+    /**
+     * Initialize connection and define main table
+     *
+     * @return void
+     */
+    protected function _construct()
+    {
+        $this->_init('dummy_item', 'dummy_item_id');
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/DataObjectService.php b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/DataObjectService.php
new file mode 100644
index 00000000000..9c960939015
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/DataObjectService.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule4\Service\V1;
+
+use Magento\TestModule4\Service\V1\Entity\DataObjectRequest;
+use Magento\TestModule4\Service\V1\Entity\DataObjectResponseBuilder;
+use Magento\TestModule4\Service\V1\Entity\ExtensibleRequestInterface;
+use Magento\TestModule4\Service\V1\Entity\NestedDataObjectRequest;
+
+class DataObjectService implements \Magento\TestModule4\Service\V1\DataObjectServiceInterface
+{
+    /**
+     * @var DataObjectResponseBuilder
+     */
+    protected $responseBuilder;
+
+    /**
+     * @param DataObjectResponseBuilder $responseBuilder
+     */
+    public function __construct(DataObjectResponseBuilder $responseBuilder)
+    {
+        $this->responseBuilder = $responseBuilder;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getData($id)
+    {
+        return $this->responseBuilder->setEntityId($id)->setName("Test")->create();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function updateData($id, DataObjectRequest $request)
+    {
+        return $this->responseBuilder->setEntityId($id)->setName($request->getName())->create();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function nestedData($id, NestedDataObjectRequest $request)
+    {
+        return $this->responseBuilder->setEntityId($id)->setName($request->getDetails()->getName())->create();
+    }
+
+    /**
+     * Test return scalar value
+     *
+     * @param int $id
+     * @return int
+     */
+    public function scalarResponse($id)
+    {
+        return $id;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function extensibleDataObject($id, ExtensibleRequestInterface $request)
+    {
+        return $this->responseBuilder->setEntityId($id)->setName($request->getName())->create();
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/DataObjectServiceInterface.php b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/DataObjectServiceInterface.php
new file mode 100644
index 00000000000..f189b2c9ef4
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/DataObjectServiceInterface.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule4\Service\V1;
+
+use Magento\TestModule4\Service\V1\Entity\DataObjectRequest;
+use Magento\TestModule4\Service\V1\Entity\NestedDataObjectRequest;
+
+interface DataObjectServiceInterface
+{
+    /**
+     * @param int $id
+     * @return \Magento\TestModule4\Service\V1\Entity\DataObjectResponse
+     */
+    public function getData($id);
+
+    /**
+     * @param int $id
+     * @param \Magento\TestModule4\Service\V1\Entity\DataObjectRequest $request
+     * @return \Magento\TestModule4\Service\V1\Entity\DataObjectResponse
+     */
+    public function updateData($id, DataObjectRequest $request);
+
+    /**
+     * @param int $id
+     * @param \Magento\TestModule4\Service\V1\Entity\NestedDataObjectRequest $request
+     * @return \Magento\TestModule4\Service\V1\Entity\DataObjectResponse
+     */
+    public function nestedData($id, NestedDataObjectRequest $request);
+
+    /**
+     * Test return scalar value
+     *
+     * @param int $id
+     * @return int
+     */
+    public function scalarResponse($id);
+
+    /**
+     * @param int $id
+     * @param \Magento\TestModule4\Service\V1\Entity\ExtensibleRequestInterface $request
+     * @return \Magento\TestModule4\Service\V1\Entity\DataObjectResponse
+     */
+    public function extensibleDataObject($id, \Magento\TestModule4\Service\V1\Entity\ExtensibleRequestInterface $request);
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/DataObjectRequest.php b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/DataObjectRequest.php
new file mode 100644
index 00000000000..1c3f3dff0f4
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/DataObjectRequest.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule4\Service\V1\Entity;
+
+class DataObjectRequest extends \Magento\Framework\Api\AbstractExtensibleObject
+{
+    /**
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->_get('name');
+    }
+
+    /**
+     * @return int|null
+     */
+    public function getEntityId()
+    {
+        return $this->_get('entity_id');
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/DataObjectRequestBuilder.php b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/DataObjectRequestBuilder.php
new file mode 100644
index 00000000000..d3d92a6d74a
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/DataObjectRequestBuilder.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule4\Service\V1\Entity;
+
+class DataObjectRequestBuilder extends \Magento\Framework\Api\ExtensibleObjectBuilder
+{
+    /**
+     * @param string $name
+     * @return DataObjectRequest
+     */
+    public function setName($name)
+    {
+        return $this->_set('name', $name);
+    }
+
+    /**
+     * @param int $entityId
+     * @return DataObjectRequest
+     */
+    public function setEntityId($entityId)
+    {
+        return $this->_set('entity_id', $entityId);
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/DataObjectResponse.php b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/DataObjectResponse.php
new file mode 100644
index 00000000000..0086eda1095
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/DataObjectResponse.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule4\Service\V1\Entity;
+
+class DataObjectResponse extends \Magento\Framework\Api\AbstractExtensibleObject
+{
+    /**
+     * @return int
+     */
+    public function getEntityId()
+    {
+        return $this->_get('entity_id');
+    }
+
+    /**
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->_get('name');
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/DataObjectResponseBuilder.php b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/DataObjectResponseBuilder.php
new file mode 100644
index 00000000000..288c7229985
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/DataObjectResponseBuilder.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule4\Service\V1\Entity;
+
+class DataObjectResponseBuilder extends \Magento\Framework\Api\ExtensibleObjectBuilder
+{
+    /**
+     * @param int $entityId
+     * @return DataObjectResponseBuilder
+     */
+    public function setEntityId($entityId)
+    {
+        return $this->_set('entity_id', $entityId);
+    }
+
+    /**
+     * @param string $name
+     * @return DataObjectResponseBuilder
+     */
+    public function setName($name)
+    {
+        return $this->_set('name', $name);
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/ExtensibleRequest.php b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/ExtensibleRequest.php
new file mode 100644
index 00000000000..41f78a2ed61
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/ExtensibleRequest.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule4\Service\V1\Entity;
+
+class ExtensibleRequest extends \Magento\Framework\Model\AbstractExtensibleModel
+    implements ExtensibleRequestInterface
+{
+    public function getName()
+    {
+        return $this->getData("name");
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/ExtensibleRequestInterface.php b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/ExtensibleRequestInterface.php
new file mode 100644
index 00000000000..fd258c7af99
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/ExtensibleRequestInterface.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule4\Service\V1\Entity;
+
+interface ExtensibleRequestInterface extends \Magento\Framework\Api\ExtensibleDataInterface
+{
+    /**
+     * @return string
+     */
+    public function getName();
+
+    /**
+     * @return int|null
+     */
+    public function getEntityId();
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/NestedDataObjectRequest.php b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/NestedDataObjectRequest.php
new file mode 100644
index 00000000000..6c2775f006d
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/NestedDataObjectRequest.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule4\Service\V1\Entity;
+
+class NestedDataObjectRequest extends \Magento\Framework\Api\AbstractExtensibleObject
+{
+    /**
+     * @return \Magento\TestModule4\Service\V1\Entity\DataObjectRequest
+     */
+    public function getDetails()
+    {
+        return $this->_get('details');
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/NestedDataObjectRequestBuilder.php b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/NestedDataObjectRequestBuilder.php
new file mode 100644
index 00000000000..68e0123e75e
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule4/Service/V1/Entity/NestedDataObjectRequestBuilder.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule4\Service\V1\Entity;
+
+class NestedDataObjectRequestBuilder extends \Magento\Framework\Api\ExtensibleObjectBuilder
+{
+    /**
+     * @param \Magento\TestModule4\Service\V1\Entity\DataObjectRequest $details
+     * @return \Magento\TestModule4\Service\V1\Entity\DataObjectRequest
+     */
+    public function setDetails(DataObjectRequest $details)
+    {
+        return $this->_set('details', $details);
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule4/etc/acl.xml b/dev/tests/api-functional/_files/Magento/TestModule4/etc/acl.xml
new file mode 100644
index 00000000000..cb35e81b775
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule4/etc/acl.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/Acl/etc/acl.xsd">
+    <acl>
+        <resources>
+            <resource id="Magento_Adminhtml::admin">
+                <resource id="Magento_TestModule4::all" title="TestModule4" sortOrder="1">
+                    <resource id="Magento_TestModule4::resource1" title="Resource1" sortOrder="20"/>
+                    <resource id="Magento_TestModule4::resource2" title="Resource2" sortOrder="10"/>
+                    <resource id="Magento_TestModule4::resource3" title="Resource3" sortOrder="30"/>
+                </resource>
+            </resource>
+        </resources>
+    </acl>
+</config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule4/etc/di.xml b/dev/tests/api-functional/_files/Magento/TestModule4/etc/di.xml
new file mode 100644
index 00000000000..d41a2955c33
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule4/etc/di.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <preference for="Magento\TestModule4\Service\V1\DataObjectServiceInterface" type="Magento\TestModule4\Service\V1\DataObjectService" />
+    <preference for="Magento\TestModule4\Service\V1\Entity\ExtensibleRequestInterface" type="Magento\TestModule4\Service\V1\Entity\ExtensibleRequest" />
+    <type name="Magento\TestModule4\Service\V1\Entity\ExtensibleRequest">
+        <arguments>
+            <argument name="resource" xsi:type="object">Magento\TestModule4\Model\Resource\Item</argument>
+        </arguments>
+    </type>
+</config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule4/etc/module.xml b/dev/tests/api-functional/_files/Magento/TestModule4/etc/module.xml
new file mode 100644
index 00000000000..f433c75e68f
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule4/etc/module.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
+    <module name="Magento_TestModule4" schema_version="1.0"/>
+</config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule4/etc/webapi.xml b/dev/tests/api-functional/_files/Magento/TestModule4/etc/webapi.xml
new file mode 100644
index 00000000000..196aaf5ff2a
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule4/etc/webapi.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../app/code/Magento/Webapi/etc/webapi.xsd">
+    <route method="GET" url="/V1/testmodule4/:id">
+        <service class="Magento\TestModule4\Service\V1\DataObjectServiceInterface" method="getData" />
+        <resources>
+            <resource ref="Magento_TestModule4::resource1" />
+        </resources>
+    </route>
+    <route method="GET" url="/V1/testmodule4/scalar/:id">
+        <service class="Magento\TestModule4\Service\V1\DataObjectServiceInterface" method="scalarResponse" />
+        <resources>
+            <resource ref="Magento_TestModule4::resource1" />
+        </resources>
+    </route>
+    <route method="POST" url="/V1/testmodule4/:id">
+        <service class="Magento\TestModule4\Service\V1\DataObjectServiceInterface" method="updateData" />
+        <resources>
+            <resource ref="Magento_TestModule4::resource2" />
+        </resources>
+    </route>
+    <route method="POST" url="/V1/testmodule4/:id/nested">
+        <service class="Magento\TestModule4\Service\V1\DataObjectServiceInterface" method="nestedData" />
+        <resources>
+            <resource ref="Magento_TestModule4::resource3" />
+        </resources>
+    </route>
+    <route method="POST" url="/V1/testmodule4/extensibleDataObject/:id">
+        <service class="Magento\TestModule4\Service\V1\DataObjectServiceInterface" method="extensibleDataObject" />
+        <resources>
+            <resource ref="Magento_TestModule4::resource3" />
+        </resources>
+    </route>
+</routes>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/AllSoapAndRest.php b/dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/AllSoapAndRest.php
new file mode 100644
index 00000000000..6cf3942fe2d
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/AllSoapAndRest.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule5\Service\V1;
+
+use Magento\TestModule5\Service\V1\Entity\AllSoapAndRestBuilder;
+
+class AllSoapAndRest implements \Magento\TestModule5\Service\V1\AllSoapAndRestInterface
+{
+    /**
+     * @var AllSoapAndRestBuilder
+     */
+    protected $builder;
+
+    /**
+     * @param AllSoapAndRestBuilder $builder
+     */
+    public function __construct(AllSoapAndRestBuilder $builder)
+    {
+        $this->builder = $builder;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function item($entityId)
+    {
+        return $this->builder
+            ->setEntityId($entityId)
+            ->setName('testItemName')
+            ->setIsEnabled(true)
+            ->setHasOrders(true)
+            ->create();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function items()
+    {
+        $allSoapAndRest1 = $this->builder->setEntityId(1)->setName('testProduct1')->create();
+        $allSoapAndRest2 = $this->builder->setEntityId(2)->setName('testProduct2')->create();
+        return [$allSoapAndRest1, $allSoapAndRest2];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function create(\Magento\TestModule5\Service\V1\Entity\AllSoapAndRest $item)
+    {
+        return $this->builder->populate($item)->create();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function update(\Magento\TestModule5\Service\V1\Entity\AllSoapAndRest $entityItem)
+    {
+        return $entityItem;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function nestedUpdate(
+        $parentId,
+        $entityId,
+        \Magento\TestModule5\Service\V1\Entity\AllSoapAndRest $entityItem
+    ) {
+        return $entityItem;
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/AllSoapAndRestInterface.php b/dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/AllSoapAndRestInterface.php
new file mode 100644
index 00000000000..de1b4472479
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/AllSoapAndRestInterface.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule5\Service\V1;
+
+interface AllSoapAndRestInterface
+{
+    /**
+     * Retrieve an item.
+     *
+     * @param int $entityId
+     * @return \Magento\TestModule5\Service\V1\Entity\AllSoapAndRest
+     * @throws \Magento\Webapi\Exception
+     */
+    public function item($entityId);
+
+    /**
+     * Retrieve all items.
+     *
+     * @return \Magento\TestModule5\Service\V1\Entity\AllSoapAndRest[]
+     */
+    public function items();
+
+    /**
+     * Create a new item.
+     *
+     * @param \Magento\TestModule5\Service\V1\Entity\AllSoapAndRest $item
+     * @return \Magento\TestModule5\Service\V1\Entity\AllSoapAndRest
+     */
+    public function create(\Magento\TestModule5\Service\V1\Entity\AllSoapAndRest $item);
+
+    /**
+     * Update existing item.
+     *
+     * @param \Magento\TestModule5\Service\V1\Entity\AllSoapAndRest $entityItem
+     * @return \Magento\TestModule5\Service\V1\Entity\AllSoapAndRest
+     */
+    public function update(\Magento\TestModule5\Service\V1\Entity\AllSoapAndRest $entityItem);
+
+    /**
+     * Update existing item.
+     *
+     * @param string $parentId
+     * @param string $entityId
+     * @param \Magento\TestModule5\Service\V1\Entity\AllSoapAndRest $entityItem
+     * @return \Magento\TestModule5\Service\V1\Entity\AllSoapAndRest
+     */
+    public function nestedUpdate(
+        $parentId,
+        $entityId,
+        \Magento\TestModule5\Service\V1\Entity\AllSoapAndRest $entityItem
+    );
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/Entity/AllSoapAndRest.php b/dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/Entity/AllSoapAndRest.php
new file mode 100644
index 00000000000..19e78efe694
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/Entity/AllSoapAndRest.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule5\Service\V1\Entity;
+
+/**
+ * Some Data Object short description.
+ *
+ * Data Object long
+ * multi line description.
+ */
+class AllSoapAndRest extends \Magento\Framework\Api\AbstractExtensibleObject
+{
+    const ID = 'entity_id';
+    const NAME = 'name';
+    const ENABLED = 'enabled';
+    const HAS_ORDERS = 'orders';
+
+    /**
+     * Retrieve item ID.
+     *
+     * @return int Item ID
+     */
+    public function getEntityId()
+    {
+        return $this->_get(self::ID);
+    }
+
+    /**
+     * Retrieve item Name.
+     *
+     * @return string|null Item name
+     */
+    public function getName()
+    {
+        return $this->_get(self::NAME);
+    }
+
+    /**
+     * Check if entity is enabled
+     *
+     * @return bool
+     */
+    public function isEnabled()
+    {
+        return $this->_get(self::ENABLED);
+    }
+
+    /**
+     * Check if current entity has a property defined
+     *
+     * @return bool
+     */
+    public function hasOrders()
+    {
+        return $this->_get(self::HAS_ORDERS);
+    }
+
+    /**
+     * Method which will not be used when adding complex type field to WSDL.
+     *
+     * @param string $value
+     * @return string
+     */
+    public function getFieldExcludedFromWsdl($value)
+    {
+        return $value;
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/Entity/AllSoapAndRestBuilder.php b/dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/Entity/AllSoapAndRestBuilder.php
new file mode 100644
index 00000000000..70ed93fa515
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/Entity/AllSoapAndRestBuilder.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule5\Service\V1\Entity;
+
+use Magento\Framework\Api\AbstractSimpleObjectBuilder;
+
+/**
+ * Some Data Object short description.
+ *
+ * Data Object long
+ * multi line description.
+ */
+class AllSoapAndRestBuilder extends AbstractSimpleObjectBuilder
+{
+    /**
+     * @param int $id
+     * @return AllSoapAndRestBuilder
+     */
+    public function setEntityId($id)
+    {
+        return $this->_set(AllSoapAndRest::ID, $id);
+    }
+
+    /**
+     * @param string $name
+     * @return AllSoapAndRestBuilder
+     */
+    public function setName($name)
+    {
+        return $this->_set(AllSoapAndRest::NAME, $name);
+    }
+
+    /**
+     * Set flag if entity is enabled
+     *
+     * @param bool $isEnabled
+     * @return AllSoapAndRestBuilder
+     */
+    public function setIsEnabled($isEnabled)
+    {
+        return $this->_set(AllSoapAndRest::ENABLED, $isEnabled);
+    }
+
+    /**
+     * Set flag if entity has orders
+     *
+     * @param bool $hasOrders
+     * @return AllSoapAndRestBuilder
+     */
+    public function setHasOrders($hasOrders)
+    {
+        return $this->_set(AllSoapAndRest::HAS_ORDERS, $hasOrders);
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/OverrideService.php b/dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/OverrideService.php
new file mode 100644
index 00000000000..d5fb874d457
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/OverrideService.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\TestModule5\Service\V1;
+
+use Magento\TestModule5\Service\V1\Entity\AllSoapAndRestBuilder;
+
+class OverrideService implements OverrideServiceInterface
+{
+    /**
+     * @var AllSoapAndRestBuilder
+     */
+    protected $builder;
+
+    /**
+     * @param AllSoapAndRestBuilder $builder
+     */
+    public function __construct(AllSoapAndRestBuilder $builder)
+    {
+        $this->builder = $builder;
+    }
+    /**
+     * {@inheritdoc}
+     */
+    public function scalarUpdate($entityId, $name, $hasOrders)
+    {
+        return $this->builder
+            ->setEntityId($entityId)
+            ->setName($name)
+            ->setHasOrders($hasOrders)
+            ->create();
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/OverrideServiceInterface.php b/dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/OverrideServiceInterface.php
new file mode 100644
index 00000000000..f8ce591980b
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule5/Service/V1/OverrideServiceInterface.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\TestModule5\Service\V1;
+
+interface OverrideServiceInterface
+{
+    /**
+     * Update existing item.
+     *
+     * @param string $entityId
+     * @param string $name
+     * @param bool $orders
+     * @return \Magento\TestModule5\Service\V1\Entity\AllSoapAndRest
+     */
+    public function scalarUpdate($entityId, $name, $orders);
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule5/Service/V2/AllSoapAndRest.php b/dev/tests/api-functional/_files/Magento/TestModule5/Service/V2/AllSoapAndRest.php
new file mode 100644
index 00000000000..e4b006e8fea
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule5/Service/V2/AllSoapAndRest.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule5\Service\V2;
+
+use Magento\TestModule5\Service\V2\Entity\AllSoapAndRest as AllSoapAndRestEntity;
+use Magento\TestModule5\Service\V2\Entity\AllSoapAndRestBuilder;
+
+class AllSoapAndRest implements AllSoapAndRestInterface
+{
+    /**
+     * @var AllSoapAndRestBuilder
+     */
+    protected $builder;
+
+    /**
+     * @param AllSoapAndRestBuilder $builder
+     */
+    public function __construct(AllSoapAndRestBuilder $builder)
+    {
+        $this->builder = $builder;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function item($id)
+    {
+        return $this->builder->setPrice(1)->setId($id)->setName('testItemName')->create();
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function items()
+    {
+        $allSoapAndRest1 = $this->builder->setPrice(1)->setId(1)->setName('testProduct1')->create();
+        $allSoapAndRest2 = $this->builder->setPrice(1)->setId(2)->setName('testProduct2')->create();
+        return [$allSoapAndRest1, $allSoapAndRest2];
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function create(\Magento\TestModule5\Service\V2\Entity\AllSoapAndRest $item)
+    {
+        return $this->builder->populate($item)->create();
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function update(\Magento\TestModule5\Service\V2\Entity\AllSoapAndRest $item)
+    {
+        $item->setName('Updated' . $item->getName());
+        return $this->builder->populate($item)->create();
+    }
+
+    /**
+     * @param string $id
+     * @return AllSoapAndRestEntity
+     * @throws \Magento\Webapi\Exception
+     */
+    public function delete($id)
+    {
+        return $this->builder->setPrice(1)->setId($id)->setName('testItemName')->create();
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule5/Service/V2/AllSoapAndRestInterface.php b/dev/tests/api-functional/_files/Magento/TestModule5/Service/V2/AllSoapAndRestInterface.php
new file mode 100644
index 00000000000..dce9a15f0f5
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule5/Service/V2/AllSoapAndRestInterface.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule5\Service\V2;
+
+interface AllSoapAndRestInterface
+{
+    /**
+     * Retrieve existing item.
+     *
+     * @param int $id
+     * @return \Magento\TestModule5\Service\V2\Entity\AllSoapAndRest
+     * @throws \Magento\Webapi\Exception
+     */
+    public function item($id);
+
+    /**
+     * Retrieve a list of all existing items.
+     *
+     * @return \Magento\TestModule5\Service\V2\Entity\AllSoapAndRest[]
+     */
+    public function items();
+
+    /**
+     * Add new item.
+     *
+     * @param \Magento\TestModule5\Service\V2\Entity\AllSoapAndRest $item
+     * @return \Magento\TestModule5\Service\V2\Entity\AllSoapAndRest
+     */
+    public function create(\Magento\TestModule5\Service\V2\Entity\AllSoapAndRest $item);
+
+    /**
+     * Update one item.
+     *
+     * @param \Magento\TestModule5\Service\V2\Entity\AllSoapAndRest $item
+     * @return \Magento\TestModule5\Service\V2\Entity\AllSoapAndRest
+     */
+    public function update(\Magento\TestModule5\Service\V2\Entity\AllSoapAndRest $item);
+
+    /**
+     * Delete existing item.
+     *
+     * @param string $id
+     * @return \Magento\TestModule5\Service\V2\Entity\AllSoapAndRest
+     */
+    public function delete($id);
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule5/Service/V2/Entity/AllSoapAndRest.php b/dev/tests/api-functional/_files/Magento/TestModule5/Service/V2/Entity/AllSoapAndRest.php
new file mode 100644
index 00000000000..35e3674b679
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule5/Service/V2/Entity/AllSoapAndRest.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule5\Service\V2\Entity;
+
+class AllSoapAndRest extends \Magento\TestModule5\Service\V2\AllSoapAndRest
+{
+    const PRICE = 'price';
+
+    /**
+     * @return int
+     */
+    public function getPrice()
+    {
+        return $this->_get(self::PRICE);
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule5/Service/V2/Entity/AllSoapAndRestBuilder.php b/dev/tests/api-functional/_files/Magento/TestModule5/Service/V2/Entity/AllSoapAndRestBuilder.php
new file mode 100644
index 00000000000..d68589484b3
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule5/Service/V2/Entity/AllSoapAndRestBuilder.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModule5\Service\V2\Entity;
+
+use Magento\TestModule5\Service\V1\Entity;
+
+class AllSoapAndRestBuilder extends \Magento\TestModule5\Service\V1\Entity\AllSoapAndRestBuilder
+{
+    const PRICE = 'price';
+
+    /**
+     * @param int $price
+     * @return \Magento\TestModule5\Service\V2\Entity\AllSoapAndRestBuilder
+     */
+    public function setPrice($price)
+    {
+        return $this->_set(self::PRICE, $price);
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModule5/etc/acl.xml b/dev/tests/api-functional/_files/Magento/TestModule5/etc/acl.xml
new file mode 100644
index 00000000000..ebad51bd78d
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule5/etc/acl.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/Acl/etc/acl.xsd">
+    <acl>
+        <resources>
+            <resource id="Magento_Adminhtml::admin">
+                <resource id="Magento_TestModule5::all" title="TestModule5" sortOrder="1">
+                    <resource id="Magento_TestModule5::resource1" title="Resource1" sortOrder="20"/>
+                    <resource id="Magento_TestModule5::resource2" title="Resource2" sortOrder="10"/>
+                    <resource id="Magento_TestModule5::resource3" title="Resource3" sortOrder="30"/>
+                </resource>
+            </resource>
+        </resources>
+    </acl>
+</config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule5/etc/di.xml b/dev/tests/api-functional/_files/Magento/TestModule5/etc/di.xml
new file mode 100644
index 00000000000..13e121a2d72
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule5/etc/di.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <preference for="Magento\TestModule5\Service\V1\AllSoapAndRestInterface" type="Magento\TestModule5\Service\V1\AllSoapAndRest" />
+    <preference for="Magento\TestModule5\Service\V2\AllSoapAndRestInterface" type="Magento\TestModule5\Service\V2\AllSoapAndRest" />
+    <preference for="Magento\TestModule5\Service\V1\OverrideServiceInterface" type="Magento\TestModule5\Service\V1\OverrideService" />
+</config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule5/etc/module.xml b/dev/tests/api-functional/_files/Magento/TestModule5/etc/module.xml
new file mode 100644
index 00000000000..801468fd880
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule5/etc/module.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
+    <module name="Magento_TestModule5" schema_version="1.0"/>
+</config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModule5/etc/webapi.xml b/dev/tests/api-functional/_files/Magento/TestModule5/etc/webapi.xml
new file mode 100644
index 00000000000..38cbd15afb1
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModule5/etc/webapi.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../app/code/Magento/Webapi/etc/webapi.xsd">
+    <route method="GET" url="/V1/TestModule5/:entityId">
+        <service class="Magento\TestModule5\Service\V1\AllSoapAndRestInterface" method="item" />
+        <resources>
+            <resource ref="Magento_TestModule5::resource1" />
+        </resources>
+    </route>
+    <route method="GET" url="/V1/TestModule5">
+        <service class="Magento\TestModule5\Service\V1\AllSoapAndRestInterface" method="items" />
+        <resources>
+            <resource ref="Magento_TestModule5::resource2" />
+        </resources>
+    </route>
+    <route method="POST" url="/V1/TestModule5">
+        <service class="Magento\TestModule5\Service\V1\AllSoapAndRestInterface" method="create" />
+        <resources>
+            <resource ref="Magento_TestModule5::resource3" />
+        </resources>
+    </route>
+    <route method="PUT" url="/V1/TestModule5/:entityId">
+        <service class="Magento\TestModule5\Service\V1\AllSoapAndRestInterface" method="update" />
+        <resources>
+            <resource ref="Magento_TestModule5::resource1" />
+            <resource ref="Magento_TestModule5::resource2" />
+        </resources>
+    </route>
+    <route method="PUT" url="/V1/TestModule5/:parentId/nestedResource/:entityId">
+        <service class="Magento\TestModule5\Service\V1\AllSoapAndRestInterface" method="nestedUpdate" />
+        <resources>
+            <resource ref="Magento_TestModule5::resource1" />
+            <resource ref="Magento_TestModule5::resource2" />
+        </resources>
+    </route>
+    <route method="PUT" url="/V1/TestModule5/OverrideService/:parentId/nestedResource/:entityId">
+        <service class="Magento\TestModule5\Service\V1\OverrideServiceInterface" method="scalarUpdate" />
+        <resources>
+            <resource ref="Magento_TestModule5::resource1" />
+            <resource ref="Magento_TestModule5::resource2" />
+        </resources>
+    </route>
+    <route method="GET" url="/V2/TestModule5/:id">
+        <service class="Magento\TestModule5\Service\V2\AllSoapAndRestInterface" method="item" />
+        <resources>
+            <resource ref="Magento_TestModule5::resource1" />
+        </resources>
+    </route>
+    <route method="GET" url="/V2/TestModule5">
+        <service class="Magento\TestModule5\Service\V2\AllSoapAndRestInterface" method="items" />
+        <resources>
+            <resource ref="Magento_TestModule5::resource2" />
+        </resources>
+    </route>
+    <route method="POST" url="/V2/TestModule5">
+        <service class="Magento\TestModule5\Service\V2\AllSoapAndRestInterface" method="create" />
+        <resources>
+            <resource ref="Magento_TestModule5::resource3" />
+        </resources>
+    </route>
+    <route method="PUT" url="/V2/TestModule5/:id">
+        <service class="Magento\TestModule5\Service\V2\AllSoapAndRestInterface" method="update" />
+        <resources>
+            <resource ref="Magento_TestModule5::resource1" />
+            <resource ref="Magento_TestModule5::resource2" />
+        </resources>
+    </route>
+    <route method="DELETE" url="/V2/TestModule5/:id">
+        <service class="Magento\TestModule5\Service\V2\AllSoapAndRestInterface" method="delete" />
+        <resources>
+            <resource ref="Magento_TestModule5::resource1" />
+        </resources>
+    </route>
+</routes>
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/Api/AllSoapAndRestInterface.php b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Api/AllSoapAndRestInterface.php
new file mode 100644
index 00000000000..baa4ab49f37
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Api/AllSoapAndRestInterface.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModuleMSC\Api;
+
+interface AllSoapAndRestInterface
+{
+    /**
+     * @param int $itemId
+     * @return \Magento\TestModuleMSC\Api\Data\ItemInterface
+     */
+    public function item($itemId);
+
+    /**
+     * @param string $name
+     * @return \Magento\TestModuleMSC\Api\Data\ItemInterface
+     */
+    public function create($name);
+
+    /**
+     * @param \Magento\TestModuleMSC\Api\Data\ItemInterface $entityItem
+     * @return \Magento\TestModuleMSC\Api\Data\ItemInterface
+     */
+    public function update(\Magento\TestModuleMSC\Api\Data\ItemInterface $entityItem);
+
+    /**
+     * @return \Magento\TestModuleMSC\Api\Data\ItemInterface[]
+     */
+    public function items();
+
+    /**
+     * @param string $name
+     * @return \Magento\TestModuleMSC\Api\Data\ItemInterface
+     */
+    public function testOptionalParam($name = null);
+
+    /**
+     * @param \Magento\TestModuleMSC\Api\Data\ItemInterface $entityItem
+     * @return \Magento\TestModuleMSC\Api\Data\ItemInterface
+     */
+    public function itemAnyType(\Magento\TestModuleMSC\Api\Data\ItemInterface $entityItem);
+
+    /**
+     * @return \Magento\TestModuleMSC\Api\Data\ItemInterface
+     */
+    public function getPreconfiguredItem();
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/Api/Data/CustomAttributeDataObjectInterface.php b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Api/Data/CustomAttributeDataObjectInterface.php
new file mode 100644
index 00000000000..0710ee62a85
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Api/Data/CustomAttributeDataObjectInterface.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModuleMSC\Api\Data;
+
+interface CustomAttributeDataObjectInterface extends \Magento\Framework\Api\ExtensibleDataInterface
+{
+    const NAME = 'name';
+
+    /**
+     * @return string
+     */
+    public function getName();
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/Api/Data/CustomAttributeNestedDataObjectInterface.php b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Api/Data/CustomAttributeNestedDataObjectInterface.php
new file mode 100644
index 00000000000..5c5b634bd15
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Api/Data/CustomAttributeNestedDataObjectInterface.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModuleMSC\Api\Data;
+
+interface CustomAttributeNestedDataObjectInterface extends \Magento\Framework\Api\ExtensibleDataInterface
+{
+    /**
+     * @return string
+     */
+    public function getName();
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/Api/Data/ItemInterface.php b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Api/Data/ItemInterface.php
new file mode 100644
index 00000000000..65595bafe83
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Api/Data/ItemInterface.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModuleMSC\Api\Data;
+
+interface ItemInterface extends \Magento\Framework\Api\ExtensibleDataInterface
+{
+    /**
+     * @return int
+     */
+    public function getItemId();
+
+    /**
+     * @return string
+     */
+    public function getName();
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/AllSoapAndRest.php b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/AllSoapAndRest.php
new file mode 100644
index 00000000000..cca810f6ca4
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/AllSoapAndRest.php
@@ -0,0 +1,107 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModuleMSC\Model;
+
+use Magento\TestModuleMSC\Api\Data\CustomAttributeDataObjectDataBuilder;
+use Magento\TestModuleMSC\Api\Data\ItemDataBuilder;
+
+class AllSoapAndRest implements \Magento\TestModuleMSC\Api\AllSoapAndRestInterface
+{
+    /**
+     * @var ItemDataBuilder
+     */
+    protected $itemDataBuilder;
+
+    /**
+     * @var CustomAttributeDataObjectDataBuilder
+     */
+    protected $customAttributeDataObjectDataBuilder;
+
+    /**
+     * @param ItemDataBuilder $itemDataBuilder
+     * @param CustomAttributeDataObjectDataBuilder $customAttributeNestedDataObjectBuilder
+     */
+    public function __construct(
+        ItemDataBuilder $itemDataBuilder,
+        CustomAttributeDataObjectDataBuilder $customAttributeNestedDataObjectBuilder
+    ) {
+        $this->itemDataBuilder = $itemDataBuilder;
+        $this->customAttributeDataObjectDataBuilder = $customAttributeNestedDataObjectBuilder;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function item($itemId)
+    {
+        return $this->itemDataBuilder->setItemId($itemId)->setName('testProduct1')->create();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function items()
+    {
+        $result1 = $this->itemDataBuilder->setItemId(1)->setName('testProduct1')->create();
+        $result2 = $this->itemDataBuilder->setItemId(2)->setName('testProduct2')->create();
+
+        return [$result1, $result2];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function create($name)
+    {
+        return $this->itemDataBuilder->setItemId(rand())->setName($name)->create();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function update(\Magento\TestModuleMSC\Api\Data\ItemInterface $entityItem)
+    {
+        return $this->itemDataBuilder->setItemId($entityItem->getItemId())
+            ->setName('Updated' . $entityItem->getName())
+            ->create();
+    }
+
+    public function testOptionalParam($name = null)
+    {
+        if (is_null($name)) {
+            return $this->itemDataBuilder->setItemId(3)->setName('No Name')->create();
+        } else {
+            return $this->itemDataBuilder->setItemId(3)->setName($name)->create();
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function itemAnyType(\Magento\TestModuleMSC\Api\Data\ItemInterface $entityItem)
+    {
+        return $entityItem;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPreconfiguredItem()
+    {
+        $customAttributeDataObject = $this->customAttributeDataObjectDataBuilder
+            ->setName('nameValue')
+            ->setCustomAttribute('custom_attribute_int', 1)
+            ->create();
+
+        $item = $this->itemDataBuilder
+            ->setItemId(1)
+            ->setName('testProductAnyType')
+            ->setCustomAttribute('custom_attribute_data_object', $customAttributeDataObject)
+            ->setCustomAttribute('custom_attribute_string', 'someStringValue')
+            ->create();
+
+        return $item;
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/CustomAttributeDataObject.php b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/CustomAttributeDataObject.php
new file mode 100644
index 00000000000..dc3a1c1a17e
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/CustomAttributeDataObject.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModuleMSC\Model\Data;
+
+use Magento\TestModuleMSC\Api\Data\CustomAttributeDataObjectInterface;
+
+class CustomAttributeDataObject extends \Magento\Framework\Api\AbstractExtensibleObject
+    implements CustomAttributeDataObjectInterface
+{
+    /**
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->_data['name'];
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/CustomAttributeNestedDataObject.php b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/CustomAttributeNestedDataObject.php
new file mode 100644
index 00000000000..9ea73d87ace
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/CustomAttributeNestedDataObject.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModuleMSC\Model\Data;
+
+use Magento\TestModuleMSC\Api\Data\CustomAttributeNestedDataObjectInterface;
+
+class CustomAttributeNestedDataObject extends \Magento\Framework\Model\AbstractExtensibleModel
+    implements CustomAttributeNestedDataObjectInterface
+{
+    /**
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->_data['name'];
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/Eav/AttributeMetadata.php b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/Eav/AttributeMetadata.php
new file mode 100644
index 00000000000..2977a6e5069
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/Eav/AttributeMetadata.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModuleMSC\Model\Data\Eav;
+
+use Magento\Framework\Api\AbstractExtensibleObject;
+use Magento\Framework\Api\MetadataObjectInterface;
+
+/**
+ * Class AttributeMetadata
+ */
+class AttributeMetadata extends AbstractExtensibleObject implements MetadataObjectInterface
+{
+    /**#@+
+     * Constants used as keys into $_data
+     */
+    const ATTRIBUTE_ID = 'attribute_id';
+
+    const ATTRIBUTE_CODE = 'attribute_code';
+    /**#@-*/
+
+    /**
+     * Retrieve id of the attribute.
+     *
+     * @return string|null
+     */
+    public function getAttributeId()
+    {
+        return $this->_get(self::ATTRIBUTE_ID);
+    }
+
+    /**
+     * Retrieve code of the attribute.
+     *
+     * @return string|null
+     */
+    public function getAttributeCode()
+    {
+        return $this->_get(self::ATTRIBUTE_CODE);
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/Eav/AttributeMetadataBuilder.php b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/Eav/AttributeMetadataBuilder.php
new file mode 100644
index 00000000000..d037b299cd0
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/Eav/AttributeMetadataBuilder.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModuleMSC\Model\Data\Eav;
+
+use Magento\Framework\Api\AttributeMetadataBuilderInterface;
+use Magento\Framework\Api\ExtensibleObjectBuilder;
+
+/**
+ * Class AttributeMetadataBuilder
+ */
+class AttributeMetadataBuilder extends ExtensibleObjectBuilder implements AttributeMetadataBuilderInterface
+{
+    /**
+     * Set attribute id
+     *
+     * @param  int $attributeId
+     * @return $this
+     */
+    public function setAttributeId($attributeId)
+    {
+        return $this->_set(AttributeMetadata::ATTRIBUTE_ID, $attributeId);
+    }
+
+    /**
+     * Set attribute code
+     *
+     * @param  string $attributeCode
+     * @return $this
+     */
+    public function setAttributeCode($attributeCode)
+    {
+        return $this->_set(AttributeMetadata::ATTRIBUTE_CODE, $attributeCode);
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/Item.php b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/Item.php
new file mode 100644
index 00000000000..5593ffcffb4
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Data/Item.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestModuleMSC\Model\Data;
+
+use Magento\TestModuleMSC\Api\Data\ItemInterface;
+
+class Item extends \Magento\Framework\Model\AbstractExtensibleModel
+    implements ItemInterface
+{
+    /**
+     * @return int
+     */
+    public function getItemId()
+    {
+        return $this->_data['item_id'];
+    }
+
+    /**
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->_data['name'];
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Resource/Item.php b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Resource/Item.php
new file mode 100644
index 00000000000..b1236934e35
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/Model/Resource/Item.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\TestModuleMSC\Model\Resource;
+
+/**
+ * Sample resource model
+ */
+class Item extends \Magento\Framework\Model\Resource\Db\AbstractDb
+{
+    /**
+     * Initialize connection and define main table
+     *
+     * @return void
+     */
+    protected function _construct()
+    {
+        $this->_init('dummy_item', 'dummy_item_id');
+    }
+}
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/acl.xml b/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/acl.xml
new file mode 100644
index 00000000000..923334c57dd
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/acl.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/Acl/etc/acl.xsd">
+    <acl>
+        <resources>
+            <resource id="Magento_Adminhtml::admin">
+                <resource id="Magento_TestModuleMSC::all" title="TestModuleMSC" sortOrder="1">
+                    <resource id="Magento_TestModuleMSC::resource1" title="Resource1" sortOrder="20"/>
+                    <resource id="Magento_TestModuleMSC::resource2" title="Resource2" sortOrder="10"/>
+                    <resource id="Magento_TestModuleMSC::resource3" title="Resource3" sortOrder="30"/>
+                </resource>
+            </resource>
+        </resources>
+    </acl>
+</config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/data_object.xml b/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/data_object.xml
new file mode 100644
index 00000000000..8fed3f6421c
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/data_object.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/Api/etc/data_object.xsd">
+    <custom_attributes for="Magento\TestModuleMSC\Api\Data\ItemInterface">
+        <attribute code="custom_attribute_data_object" type="Magento\TestModuleMSC\Api\Data\CustomAttributeDataObjectInterface" />
+        <attribute code="custom_attribute_string" type="string" />
+    </custom_attributes>
+    <custom_attributes for="Magento\TestModuleMSC\Api\Data\CustomAttributeDataObjectInterface">
+        <attribute code="custom_attribute_nested" type="Magento\TestModuleMSC\Api\Data\CustomAttributeNestedDataObjectInterface" />
+        <attribute code="custom_attribute_int" type="int" />
+    </custom_attributes>
+</config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/di.xml b/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/di.xml
new file mode 100644
index 00000000000..62788df693d
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/di.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+
+    <preference for="Magento\TestModuleMSC\Api\AllSoapAndRestInterface" type="Magento\TestModuleMSC\Model\AllSoapAndRest" />
+
+    <preference for="Magento\TestModuleMSC\Api\Data\ItemInterface" type="Magento\TestModuleMSC\Model\Data\Item" />
+    <preference for="Magento\TestModuleMSC\Api\Data\CustomAttributeDataObjectInterface" type="Magento\TestModuleMSC\Model\Data\CustomAttributeDataObject" />
+    <preference for="Magento\TestModuleMSC\Api\Data\CustomAttributeNestedDataObjectInterface" type="Magento\TestModuleMSC\Model\Data\CustomAttributeNestedDataObject" />
+
+    <virtualType name="Magento\TestModuleMSC\Service\Config\TestModuleMSCMetadataConfig" type="Magento\Framework\Api\Config\MetadataConfig">
+        <arguments>
+            <argument name="attributeMetadataBuilder" xsi:type="object">Magento\TestModuleMSC\Model\Data\Eav\AttributeMetadataBuilder</argument>
+            <argument name="dataObjectClassName" xsi:type="string">Magento\TestModuleMSC\Model\Data\Item</argument>
+        </arguments>
+    </virtualType>
+    <type name="Magento\TestModuleMSC\Model\Data\Item">
+        <arguments>
+            <argument name="resource" xsi:type="object">Magento\TestModuleMSC\Model\Resource\Item</argument>
+            <argument name="metadataService" xsi:type="object">Magento\TestModuleMSC\Service\Config\TestModuleMSCMetadataConfig</argument>
+        </arguments>
+    </type>
+    <type name="Magento\TestModuleMSC\Model\Data\CustomAttributeDataObject">
+        <arguments>
+            <argument name="resource" xsi:type="object">Magento\TestModuleMSC\Model\Resource\Item</argument>
+        </arguments>
+    </type>
+    <type name="Magento\TestModuleMSC\Model\Data\CustomAttributeNestedDataObject">
+        <arguments>
+            <argument name="resource" xsi:type="object">Magento\TestModuleMSC\Model\Resource\Item</argument>
+        </arguments>
+    </type>
+
+</config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/module.xml b/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/module.xml
new file mode 100644
index 00000000000..554ab6d9d91
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/module.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
+    <module name="Magento_TestModuleMSC" schema_version="1.0"/>
+</config>
diff --git a/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/webapi.xml b/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/webapi.xml
new file mode 100644
index 00000000000..ed721a73e8e
--- /dev/null
+++ b/dev/tests/api-functional/_files/Magento/TestModuleMSC/etc/webapi.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../app/code/Magento/Webapi/etc/webapi.xsd">
+
+    <route method="GET" url="/V1/testmoduleMSC/overwritten">
+        <service class="Magento\TestModuleMSC\Api\AllSoapAndRestInterface" method="item" />
+        <resources>
+            <resource ref="Magento_TestModuleMSC::resource1" />
+        </resources>
+        <data>
+            <parameter name="itemId" force="true">-55</parameter>
+        </data>
+    </route>
+
+    <route method="POST" url="/V1/testmoduleMSC/testOptionalParam">
+        <service class="Magento\TestModuleMSC\Api\AllSoapAndRestInterface" method="testOptionalParam" />
+        <resources>
+            <resource ref="Magento_TestModuleMSC::resource1" />
+        </resources>
+        <data>
+            <parameter name="name">Default Name</parameter>
+        </data>
+    </route>
+
+    <route method="GET" url="/V1/testmoduleMSC/:itemId">
+        <service class="Magento\TestModuleMSC\Api\AllSoapAndRestInterface" method="item" />
+        <resources>
+            <resource ref="Magento_TestModuleMSC::resource1" />
+        </resources>
+    </route>
+    <route method="GET" url="/V1/testmoduleMSC">
+        <service class="Magento\TestModuleMSC\Api\AllSoapAndRestInterface" method="items" />
+        <resources>
+            <resource ref="Magento_TestModuleMSC::resource2" />
+        </resources>
+    </route>
+    <route method="POST" url="/V1/testmoduleMSC">
+        <service class="Magento\TestModuleMSC\Api\AllSoapAndRestInterface" method="create" />
+        <resources>
+            <resource ref="Magento_TestModuleMSC::resource3" />
+        </resources>
+    </route>
+    <route method="PUT" url="/V1/testmoduleMSC/:itemId">
+        <service class="Magento\TestModuleMSC\Api\AllSoapAndRestInterface" method="update" />
+        <resources>
+            <resource ref="Magento_TestModuleMSC::resource1" />
+            <resource ref="Magento_TestModuleMSC::resource2" />
+        </resources>
+    </route>
+    <route method="POST" url="/V1/testmoduleMSC/itemAnyType">
+        <service class="Magento\TestModuleMSC\Api\AllSoapAndRestInterface" method="itemAnyType" />
+        <resources>
+            <resource ref="Magento_TestModuleMSC::resource1" />
+            <resource ref="Magento_TestModuleMSC::resource2" />
+        </resources>
+    </route>
+    <route method="GET" url="/V1/testmoduleMSC/itemPreconfigured">
+        <service class="Magento\TestModuleMSC\Api\AllSoapAndRestInterface" method="getPreconfiguredItem" />
+        <resources>
+            <resource ref="Magento_TestModuleMSC::resource1" />
+            <resource ref="Magento_TestModuleMSC::resource2" />
+        </resources>
+    </route>
+</routes>
diff --git a/dev/tests/api-functional/config/install-config-mysql.php.dist b/dev/tests/api-functional/config/install-config-mysql.php.dist
new file mode 100644
index 00000000000..85665d34d61
--- /dev/null
+++ b/dev/tests/api-functional/config/install-config-mysql.php.dist
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Magento console installer options for Web API functional tests. Are used in functional tests bootstrap.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+return [
+    'language'                     => 'en_US',
+    'timezone'                     => 'America/Los_Angeles',
+    'currency'                     => 'USD',
+    'db_host'                      => 'localhost',
+    'db_name'                      => 'magento_functional_tests',
+    'db_user'                      => 'root',
+    'db_pass'                      => '',
+    'backend_frontname'            => 'backend',
+    'base_url'                     => 'http://localhost/',
+    'use_secure'                   => '0',
+    'use_rewrites'                 => '0',
+    'admin_lastname'               => 'Admin',
+    'admin_firstname'              => 'Admin',
+    'admin_email'                  => 'admin@example.com',
+    'admin_username'               => 'admin',
+    'admin_password'               => '123123q',
+    'admin_use_security_key'       => '0',
+    /* PayPal has limitation for order number - 20 characters. 10 digits prefix + 8 digits number is good enough */
+    'sales_order_increment_prefix' => time(),
+    'session_save'                 => 'db',
+    'cleanup_database'             => true,
+];
diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiDataFixture.php b/dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiDataFixture.php
new file mode 100644
index 00000000000..6bc41d3a3f4
--- /dev/null
+++ b/dev/tests/api-functional/framework/Magento/TestFramework/Annotation/ApiDataFixture.php
@@ -0,0 +1,152 @@
+<?php
+/**
+ * Implementation of the magentoApiDataFixture DocBlock annotation.
+ *
+ * The difference of magentoApiDataFixture from magentoDataFixture is
+ * that no transactions should be used for API data fixtures.
+ * Otherwise fixture data will not be accessible to Web API functional tests.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestFramework\Annotation;
+
+class ApiDataFixture
+{
+    /**
+     * @var string
+     */
+    protected $_fixtureBaseDir;
+
+    /**
+     * Fixtures that have been applied
+     *
+     * @var array
+     */
+    private $_appliedFixtures = [];
+
+    /**
+     * Constructor
+     *
+     * @param string $fixtureBaseDir
+     * @throws \Magento\Framework\Exception
+     */
+    public function __construct($fixtureBaseDir)
+    {
+        if (!is_dir($fixtureBaseDir)) {
+            throw new \Magento\Framework\Exception("Fixture base directory '{$fixtureBaseDir}' does not exist.");
+        }
+        $this->_fixtureBaseDir = realpath($fixtureBaseDir);
+    }
+
+    /**
+     * Handler for 'startTest' event
+     *
+     * @param \PHPUnit_Framework_TestCase $test
+     */
+    public function startTest(\PHPUnit_Framework_TestCase $test)
+    {
+        /** Apply method level fixtures if thy are available, apply class level fixtures otherwise */
+        $this->_applyFixtures($this->_getFixtures('method', $test) ?: $this->_getFixtures('class', $test));
+    }
+
+    /**
+     * Handler for 'endTest' event
+     */
+    public function endTest()
+    {
+        $this->_revertFixtures();
+    }
+
+    /**
+     * Retrieve fixtures from annotation
+     *
+     * @param string $scope 'class' or 'method'
+     * @param \PHPUnit_Framework_TestCase $test
+     * @return array
+     * @throws \Magento\Framework\Exception
+     */
+    protected function _getFixtures($scope, \PHPUnit_Framework_TestCase $test)
+    {
+        $annotations = $test->getAnnotations();
+        $result = [];
+        if (!empty($annotations[$scope]['magentoApiDataFixture'])) {
+            foreach ($annotations[$scope]['magentoApiDataFixture'] as $fixture) {
+                if (strpos($fixture, '\\') !== false) {
+                    // usage of a single directory separator symbol streamlines search across the source code
+                    throw new \Magento\Framework\Exception('Directory separator "\\" is prohibited in fixture declaration.');
+                }
+                $fixtureMethod = [get_class($test), $fixture];
+                if (is_callable($fixtureMethod)) {
+                    $result[] = $fixtureMethod;
+                } else {
+                    $result[] = $this->_fixtureBaseDir . '/' . $fixture;
+                }
+            }
+        }
+        return $result;
+    }
+
+    /**
+     * Execute single fixture script
+     *
+     * @param string|array $fixture
+     */
+    protected function _applyOneFixture($fixture)
+    {
+        try {
+            if (is_callable($fixture)) {
+                call_user_func($fixture);
+            } else {
+                require $fixture;
+            }
+        } catch (\Exception $e) {
+            echo 'Exception occurred when running the '
+            . (is_array($fixture) || is_scalar($fixture) ? json_encode($fixture) : 'callback')
+            . ' fixture: ', PHP_EOL, $e;
+        }
+        $this->_appliedFixtures[] = $fixture;
+    }
+
+    /**
+     * Execute fixture scripts if any
+     *
+     * @param array $fixtures
+     * @throws \Magento\Framework\Exception
+     */
+    protected function _applyFixtures(array $fixtures)
+    {
+        /* Execute fixture scripts */
+        foreach ($fixtures as $oneFixture) {
+            /* Skip already applied fixtures */
+            if (!in_array($oneFixture, $this->_appliedFixtures, true)) {
+                $this->_applyOneFixture($oneFixture);
+            }
+        }
+    }
+
+    /**
+     * Revert changes done by fixtures
+     */
+    protected function _revertFixtures()
+    {
+        foreach ($this->_appliedFixtures as $fixture) {
+            if (is_callable($fixture)) {
+                $fixture[1] .= 'Rollback';
+                if (is_callable($fixture)) {
+                    $this->_applyOneFixture($fixture);
+                }
+            } else {
+                $fileInfo = pathinfo($fixture);
+                $extension = '';
+                if (isset($fileInfo['extension'])) {
+                    $extension = '.' . $fileInfo['extension'];
+                }
+                $rollbackScript = $fileInfo['dirname'] . '/' . $fileInfo['filename'] . '_rollback' . $extension;
+                if (file_exists($rollbackScript)) {
+                    $this->_applyOneFixture($rollbackScript);
+                }
+            }
+        }
+        $this->_appliedFixtures = [];
+    }
+}
diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/Authentication/OauthHelper.php b/dev/tests/api-functional/framework/Magento/TestFramework/Authentication/OauthHelper.php
new file mode 100644
index 00000000000..05d33b6bb9f
--- /dev/null
+++ b/dev/tests/api-functional/framework/Magento/TestFramework/Authentication/OauthHelper.php
@@ -0,0 +1,200 @@
+<?php
+/**
+ * Helper class for generating OAuth related credentials
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestFramework\Authentication;
+
+use Magento\TestFramework\Authentication\Rest\OauthClient;
+use Magento\TestFramework\Helper\Bootstrap;
+use OAuth\Common\Consumer\Credentials;
+use Zend\Stdlib\Exception\LogicException;
+
+class OauthHelper
+{
+    /** @var array */
+    protected static $_apiCredentials;
+
+    /**
+     * Generate authentication credentials
+     * @param string $date consumer creation date
+     * @return array
+     * <pre>
+     * array (
+     *   'key' => 'ajdsjashgdkahsdlkjasldkjals', //consumer key
+     *   'secret' => 'alsjdlaskjdlaksjdlasjkdlas', //consumer secret
+     *   'verifier' => 'oiudioqueoiquweoiqwueoqwuii'
+     *   'consumer' => $consumer, // retrieved consumer Model
+     *   'token' => $token // retrieved token Model
+     *   );
+     * </pre>
+     */
+    public static function getConsumerCredentials($date = null)
+    {
+        $integration = self::_createIntegration('all');
+        $objectManager = Bootstrap::getObjectManager();
+        /** @var $oauthService \Magento\Integration\Service\V1\Oauth */
+        $oauthService = $objectManager->get('Magento\Integration\Service\V1\Oauth');
+        $consumer = $oauthService->loadConsumer($integration->getConsumerId());
+        $url = TESTS_BASE_URL;
+        $consumer->setCallbackUrl($url);
+        $consumer->setRejectedCallbackUrl($url);
+        if (!is_null($date)) {
+            $consumer->setCreatedAt($date);
+        }
+        $consumer->save();
+        $token = $objectManager->create('Magento\Integration\Model\Oauth\Token');
+        $verifier = $token->createVerifierToken($consumer->getId())->getVerifier();
+
+        return [
+            'key' => $consumer->getKey(),
+            'secret' => $consumer->getSecret(),
+            'verifier' => $verifier,
+            'consumer' => $consumer,
+            'token' => $token
+        ];
+    }
+
+    /**
+     * Create an access token to associated to a consumer to access APIs. No resources are available to this consumer.
+     *
+     * @return array comprising of token  key and secret
+     * <pre>
+     * array (
+     *   'key' => 'ajdsjashgdkahsdlkjasldkjals', //token key
+     *   'secret' => 'alsjdlaskjdlaksjdlasjkdlas', //token secret
+     *   'oauth_client' => $oauthClient // OauthClient instance used to fetch the access token
+     *   );
+     * </pre>
+     */
+    public static function getAccessToken()
+    {
+        $consumerCredentials = self::getConsumerCredentials();
+        $credentials = new Credentials($consumerCredentials['key'], $consumerCredentials['secret'], TESTS_BASE_URL);
+        $oAuthClient = new OauthClient($credentials);
+        $requestToken = $oAuthClient->requestRequestToken();
+        $accessToken = $oAuthClient->requestAccessToken(
+            $requestToken->getRequestToken(),
+            $consumerCredentials['verifier'],
+            $requestToken->getRequestTokenSecret()
+        );
+
+        /** TODO: Reconsider return format. It is not aligned with method name. */
+        return [
+            'key' => $accessToken->getAccessToken(),
+            'secret' => $accessToken->getAccessTokenSecret(),
+            'oauth_client' => $oAuthClient
+        ];
+    }
+
+    /**
+     * Create an access token, tied to integration which has permissions to all API resources in the system.
+     *
+     * @param array $resources list of resources to grant to the integration
+     * @return array
+     * <pre>
+     * array (
+     *   'key' => 'ajdsjashgdkahsdlkjasldkjals', //token key
+     *   'secret' => 'alsjdlaskjdlaksjdlasjkdlas', //token secret
+     *   'oauth_client' => $oauthClient // OauthClient instance used to fetch the access token
+     *   'integration' => $integration // Integration instance associated with access token
+     *   );
+     * </pre>
+     * @throws LogicException
+     */
+    public static function getApiAccessCredentials($resources = null)
+    {
+        if (!self::$_apiCredentials) {
+            $integration = self::_createIntegration($resources);
+            $objectManager = Bootstrap::getObjectManager();
+            /** @var \Magento\Integration\Service\V1\Oauth $oauthService */
+            $oauthService = $objectManager->get('Magento\Integration\Service\V1\Oauth');
+            $oauthService->createAccessToken($integration->getConsumerId());
+            $accessToken = $oauthService->getAccessToken($integration->getConsumerId());
+            if (!$accessToken) {
+                throw new LogicException('Access token was not created.');
+            }
+            $consumer = $oauthService->loadConsumer($integration->getConsumerId());
+            $credentials = new Credentials($consumer->getKey(), $consumer->getSecret(), TESTS_BASE_URL);
+            /** @var $oAuthClient OauthClient */
+            $oAuthClient = new OauthClient($credentials);
+
+            self::$_apiCredentials = [
+                'key' => $accessToken->getToken(),
+                'secret' => $accessToken->getSecret(),
+                'oauth_client' => $oAuthClient,
+                'integration' => $integration,
+            ];
+        }
+        return self::$_apiCredentials;
+    }
+
+    /**
+     * Forget API access credentials.
+     */
+    public static function clearApiAccessCredentials()
+    {
+        self::$_apiCredentials = false;
+    }
+
+    /**
+     * Remove fs element with nested elements.
+     *
+     * @param string $dir
+     * @param bool   $doSaveRoot
+     */
+    protected static function _rmRecursive($dir, $doSaveRoot = false)
+    {
+        if (is_dir($dir)) {
+            foreach (glob($dir . '/*') as $object) {
+                if (is_dir($object)) {
+                    self::_rmRecursive($object);
+                } else {
+                    unlink($object);
+                }
+            }
+            if (!$doSaveRoot) {
+                rmdir($dir);
+            }
+        } else {
+            unlink($dir);
+        }
+    }
+
+    /**
+     * Create integration instance.
+     *
+     * @param array $resources
+     * @return \Magento\Integration\Model\Integration
+     * @throws \Zend\Stdlib\Exception\LogicException
+     */
+    protected static function _createIntegration($resources)
+    {
+        $objectManager = Bootstrap::getObjectManager();
+        /** @var $integrationService \Magento\Integration\Service\V1\IntegrationInterface */
+        $integrationService = $objectManager->get('Magento\Integration\Service\V1\IntegrationInterface');
+
+        $params = ['name' => 'Integration' . microtime()];
+
+        if ($resources === null || $resources == 'all') {
+            $params['all_resources'] = true;
+        } else {
+            $params['resource'] = $resources;
+        }
+        $integration = $integrationService->create($params);
+        $integration->setStatus(\Magento\Integration\Model\Integration::STATUS_ACTIVE)->save();
+
+        /** Magento cache must be cleared to activate just created ACL role. */
+        $varPath = realpath('../../../var');
+        if (!$varPath) {
+            throw new LogicException("Magento cache cannot be cleared after new ACL role creation.");
+        } else {
+            $cachePath = $varPath . '/cache';
+            if (is_dir($cachePath)) {
+                self::_rmRecursive($cachePath, true);
+            }
+        }
+        return $integration;
+    }
+}
diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/Authentication/Rest/OauthClient.php b/dev/tests/api-functional/framework/Magento/TestFramework/Authentication/Rest/OauthClient.php
new file mode 100644
index 00000000000..021e836e0f3
--- /dev/null
+++ b/dev/tests/api-functional/framework/Magento/TestFramework/Authentication/Rest/OauthClient.php
@@ -0,0 +1,271 @@
+<?php
+/**
+ * oAuth client for Magento REST API.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestFramework\Authentication\Rest;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use OAuth\Common\Consumer\Credentials;
+use OAuth\Common\Http\Client\ClientInterface;
+use OAuth\Common\Http\Exception\TokenResponseException;
+use OAuth\Common\Http\Uri\Uri;
+use OAuth\Common\Http\Uri\UriInterface;
+use OAuth\Common\Storage\TokenStorageInterface;
+use OAuth\OAuth1\Service\AbstractService;
+use OAuth\OAuth1\Signature\SignatureInterface;
+use OAuth\OAuth1\Token\StdOAuth1Token;
+use OAuth\OAuth1\Token\TokenInterface;
+
+class OauthClient extends AbstractService
+{
+    /** @var string|null */
+    protected $_oauthVerifier = null;
+
+    public function __construct(
+        Credentials $credentials,
+        ClientInterface $httpClient = null,
+        TokenStorageInterface $storage = null,
+        SignatureInterface $signature = null,
+        UriInterface $baseApiUri = null
+    ) {
+        if (!isset($httpClient)) {
+            $httpClient = new \OAuth\Common\Http\Client\StreamClient();
+        }
+        if (!isset($storage)) {
+            $storage = new \OAuth\Common\Storage\Session();
+        }
+        if (!isset($signature)) {
+            $signature = new \Magento\TestFramework\Authentication\Rest\OauthClient\Signature($credentials);
+        }
+        parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri);
+    }
+
+    /**
+     * @return UriInterface
+     */
+    public function getRequestTokenEndpoint()
+    {
+        return new Uri(TESTS_BASE_URL . '/oauth/token/request');
+    }
+
+    /**
+     * Returns the authorization API endpoint.
+     *
+     * @return UriInterface
+     */
+    public function getAuthorizationEndpoint()
+    {
+        throw new \OAuth\Common\Exception\Exception(
+            'Magento REST API is 2-legged. Current operation is not available.'
+        );
+    }
+
+    /**
+     * Returns the access token API endpoint.
+     *
+     * @return UriInterface
+     */
+    public function getAccessTokenEndpoint()
+    {
+        return new Uri(TESTS_BASE_URL . '/oauth/token/access');
+    }
+
+    /**
+     * Returns the TestModule1 Rest API endpoint.
+     *
+     * @return UriInterface
+     */
+    public function getTestApiEndpoint()
+    {
+        $defaultStoreCode = Bootstrap::getObjectManager()->get('Magento\Store\Model\StoreManagerInterface')
+            ->getStore()->getCode();
+        return new Uri(TESTS_BASE_URL . '/rest/' . $defaultStoreCode . '/V1/testmodule1');
+    }
+
+    /**
+     * Parses the access token response and returns a TokenInterface.
+     *
+     * @return TokenInterface
+     * @param string $responseBody
+     */
+    protected function parseAccessTokenResponse($responseBody)
+    {
+        return $this->_parseToken($responseBody);
+    }
+
+    /**
+     * Parses the request token response and returns a TokenInterface.
+     *
+     * @return TokenInterface
+     * @param string $responseBody
+     * @throws TokenResponseException
+     */
+    protected function parseRequestTokenResponse($responseBody)
+    {
+        $data = $this->_parseResponseBody($responseBody);
+        if (isset($data['oauth_verifier'])) {
+            $this->_oauthVerifier = $data['oauth_verifier'];
+        }
+        return $this->_parseToken($responseBody);
+    }
+
+    /**
+     * Parse response body and create oAuth token object based on parameters provided.
+     *
+     * @param string $responseBody
+     * @return StdOAuth1Token
+     * @throws TokenResponseException
+     */
+    protected function _parseToken($responseBody)
+    {
+        $data = $this->_parseResponseBody($responseBody);
+        $token = new StdOAuth1Token();
+        $token->setRequestToken($data['oauth_token']);
+        $token->setRequestTokenSecret($data['oauth_token_secret']);
+        $token->setAccessToken($data['oauth_token']);
+        $token->setAccessTokenSecret($data['oauth_token_secret']);
+        $token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES);
+        unset($data['oauth_token'], $data['oauth_token_secret']);
+        $token->setExtraParams($data);
+        return $token;
+    }
+
+    /**
+     * Parse response body and return data in array.
+     *
+     * @param string $responseBody
+     * @return array
+     * @throws \OAuth\Common\Http\Exception\TokenResponseException
+     */
+    protected function _parseResponseBody($responseBody)
+    {
+        if (!is_string($responseBody)) {
+            throw new TokenResponseException("Response body is expected to be a string.");
+        }
+        parse_str($responseBody, $data);
+        if (null === $data || !is_array($data)) {
+            throw new TokenResponseException('Unable to parse response.');
+        } elseif (isset($data['error'])) {
+            throw new TokenResponseException("Error occurred: '{$data['error']}'");
+        }
+        return $data;
+    }
+
+    /**
+     * Retrieve oAuth verifier that was obtained during request token request.
+     *
+     * @return string
+     * @throws \OAuth\Common\Http\Exception\TokenResponseException
+     */
+    public function getOauthVerifier()
+    {
+        if (!isset($this->_oauthVerifier) || isEmpty($this->_oauthVerifier)) {
+            throw new TokenResponseException("oAuth verifier must be obtained during request token request.");
+        }
+        return $this->_oauthVerifier;
+    }
+
+    /**
+     * @override to fix since parent implementation from lib not sending the oauth_verifier when requesting access token
+     * Builds the authorization header for an authenticated API request
+     * @param string $method
+     * @param UriInterface $uri the uri the request is headed
+     * @param \OAuth\OAuth1\Token\TokenInterface $token
+     * @param $bodyParams array
+     * @return string
+     */
+    protected function buildAuthorizationHeaderForAPIRequest(
+        $method,
+        UriInterface $uri,
+        TokenInterface $token,
+        $bodyParams = null
+    ) {
+        $this->signature->setTokenSecret($token->getAccessTokenSecret());
+        $parameters = $this->getBasicAuthorizationHeaderInfo();
+        if (isset($parameters['oauth_callback'])) {
+            unset($parameters['oauth_callback']);
+        }
+
+        $parameters = array_merge($parameters, ['oauth_token' => $token->getAccessToken()]);
+        $parameters = array_merge($parameters, $bodyParams);
+        $parameters['oauth_signature'] = $this->signature->getSignature($uri, $parameters, $method);
+
+        $authorizationHeader = 'OAuth ';
+        $delimiter = '';
+
+        foreach ($parameters as $key => $value) {
+            $authorizationHeader .= $delimiter . rawurlencode($key) . '="' . rawurlencode($value) . '"';
+            $delimiter = ', ';
+        }
+
+        return $authorizationHeader;
+    }
+
+    /**
+     * Builds the oAuth authorization header for an authenticated API request
+     *
+     * @param UriInterface $uri the uri the request is headed
+     * @param \OAuth\OAuth1\Token\TokenInterface $token
+     * @param string $tokenSecret used to verify the passed token
+     * @param array $bodyParams
+     * @param string $method HTTP method to use
+     * @return array
+     */
+    public function buildOauthAuthorizationHeader($uri, $token, $tokenSecret, $bodyParams, $method = 'GET')
+    {
+        $uri = new Uri($uri);
+        $tokenObj = new StdOAuth1Token();
+        $tokenObj->setAccessToken($token);
+        $tokenObj->setAccessTokenSecret($tokenSecret);
+        $tokenObj->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES);
+        return [
+            'Authorization: ' . $this->buildAuthorizationHeaderForAPIRequest($method, $uri, $tokenObj, $bodyParams)
+        ];
+    }
+
+    /**
+     * Builds the bearer token authorization header
+     *
+     * @param string $token
+     * @return array
+     */
+    public function buildBearerTokenAuthorizationHeader($token)
+    {
+        return [
+            'Authorization: Bearer ' . $token
+        ];
+    }
+
+    /**
+     * Validates a Test REST api call access using oauth access token
+     *
+     * @param TokenInterface $token The access token.
+     * @param string $method HTTP method.
+     * @return array
+     * @throws TokenResponseException
+     */
+    public function validateAccessToken($token, $method = 'GET')
+    {
+        //Need to add Accept header else Magento errors out with 503
+        $extraAuthenticationHeaders = ['Accept' => 'application/json'];
+
+        $this->signature->setTokenSecret($token->getAccessTokenSecret());
+
+        $authorizationHeader = [
+            'Authorization' => $this->buildAuthorizationHeaderForAPIRequest(
+                $method,
+                $this->getTestApiEndpoint(),
+                $token,
+                []
+            ),
+        ];
+
+        $headers = array_merge($authorizationHeader, $extraAuthenticationHeaders);
+
+        $responseBody = $this->httpClient->retrieveResponse($this->getTestApiEndpoint(), [], $headers, $method);
+
+        return json_decode($responseBody);
+    }
+}
diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/Authentication/Rest/OauthClient/Signature.php b/dev/tests/api-functional/framework/Magento/TestFramework/Authentication/Rest/OauthClient/Signature.php
new file mode 100644
index 00000000000..2a2a6c73692
--- /dev/null
+++ b/dev/tests/api-functional/framework/Magento/TestFramework/Authentication/Rest/OauthClient/Signature.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\TestFramework\Authentication\Rest\OauthClient;
+
+use OAuth\Common\Http\Uri\UriInterface;
+
+/**
+ * Signature class for Magento REST API.
+ */
+class Signature extends \OAuth\OAuth1\Signature\Signature
+{
+    /**
+     * {@inheritdoc}
+     *
+     * In addition to the original method, allows array parameters for filters.
+     */
+    public function getSignature(UriInterface $uri, array $params, $method = 'POST')
+    {
+        $queryStringData = !$uri->getQuery() ? [] : array_reduce(
+            explode('&', $uri->getQuery()),
+            function ($carry, $item) {
+                list($key, $value) = explode('=', $item, 2);
+                $carry[rawurldecode($key)] = rawurldecode($value);
+                return $carry;
+            },
+            []
+        );
+
+        foreach (array_merge($queryStringData, $params) as $key => $value) {
+            $signatureData[rawurlencode($key)] = rawurlencode($value);
+        }
+
+        ksort($signatureData);
+
+        // determine base uri
+        $baseUri = $uri->getScheme() . '://' . $uri->getRawAuthority();
+
+        if ('/' == $uri->getPath()) {
+            $baseUri .= $uri->hasExplicitTrailingHostSlash() ? '/' : '';
+        } else {
+            $baseUri .= $uri->getPath();
+        }
+
+        $baseString = strtoupper($method) . '&';
+        $baseString .= rawurlencode($baseUri) . '&';
+        $baseString .= rawurlencode($this->buildSignatureDataString($signatureData));
+
+        return base64_encode($this->hash($baseString));
+    }
+}
diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/Bootstrap/WebapiDocBlock.php b/dev/tests/api-functional/framework/Magento/TestFramework/Bootstrap/WebapiDocBlock.php
new file mode 100644
index 00000000000..a764f998886
--- /dev/null
+++ b/dev/tests/api-functional/framework/Magento/TestFramework/Bootstrap/WebapiDocBlock.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * Bootstrap of the custom Web API DocBlock annotations.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestFramework\Bootstrap;
+
+class WebapiDocBlock extends \Magento\TestFramework\Bootstrap\DocBlock
+{
+    /**
+     * Get list of subscribers. In addition, register <b>magentoApiDataFixture</b> annotation processing.
+     *
+     * @param \Magento\TestFramework\Application $application
+     * @return array
+     */
+    protected function _getSubscribers(\Magento\TestFramework\Application $application)
+    {
+        $subscribers = parent::_getSubscribers($application);
+        array_unshift($subscribers, new \Magento\TestFramework\Annotation\ApiDataFixture($this->_fixturesBaseDir));
+        return $subscribers;
+    }
+}
diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/Helper/Customer.php b/dev/tests/api-functional/framework/Magento/TestFramework/Helper/Customer.php
new file mode 100644
index 00000000000..77033575557
--- /dev/null
+++ b/dev/tests/api-functional/framework/Magento/TestFramework/Helper/Customer.php
@@ -0,0 +1,170 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestFramework\Helper;
+
+use Magento\Customer\Api\Data\AddressDataBuilder;
+use Magento\Customer\Api\Data\CustomerDataBuilder;
+use Magento\Customer\Api\Data\CustomerInterface;
+use Magento\Customer\Model\Data\Customer as CustomerData;
+use Magento\Framework\Reflection\DataObjectProcessor;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class Customer extends WebapiAbstract
+{
+    const RESOURCE_PATH = '/V1/customers';
+    const SERVICE_NAME = 'customerAccountManagementV1';
+    const SERVICE_VERSION = 'V1';
+
+    const CONFIRMATION = 'a4fg7h893e39d';
+    const CREATED_AT = '2013-11-05';
+    const CREATED_IN = 'default';
+    const STORE_NAME = 'Store Name';
+    const DOB = '1970-01-01';
+    const GENDER = 'Male';
+    const GROUP_ID = 1;
+    const MIDDLENAME = 'A';
+    const PREFIX = 'Mr.';
+    const STORE_ID = 1;
+    const SUFFIX = 'Esq.';
+    const TAXVAT = '12';
+    const WEBSITE_ID = 1;
+
+    /** Sample values for testing */
+    const FIRSTNAME = 'Jane';
+    const LASTNAME = 'Doe';
+    const PASSWORD = 'test@123';
+
+    const ADDRESS_CITY1 = 'CityM';
+    const ADDRESS_CITY2 = 'CityX';
+    const ADDRESS_REGION_CODE1 = 'AL';
+    const ADDRESS_REGION_CODE2 = 'AL';
+
+    /** @var AddressDataBuilder */
+    private $addressBuilder;
+
+    /** @var CustomerDataBuilder */
+    private $customerBuilder;
+
+    /** @var DataObjectProcessor */
+    private $dataObjectProcessor;
+
+    public function __construct($name = null, array $data = [], $dataName = '')
+    {
+        parent::__construct($name, $data, $dataName);
+
+        $this->addressBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\Customer\Api\Data\AddressDataBuilder'
+        );
+
+        $this->customerBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\Customer\Api\Data\CustomerDataBuilder'
+        );
+
+        $this->dataObjectProcessor = Bootstrap::getObjectManager()->create(
+            'Magento\Framework\Reflection\DataObjectProcessor'
+        );
+    }
+
+    public function createSampleCustomer()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'CreateAccount',
+            ],
+        ];
+        $customerDataArray = $this->dataObjectProcessor->buildOutputDataArray(
+            $this->createSampleCustomerDataObject(),
+            '\Magento\Customer\Api\Data\CustomerInterface'
+        );
+        $requestData = ['customer' => $customerDataArray, 'password' => self::PASSWORD];
+        $customerData = $this->_webApiCall($serviceInfo, $requestData);
+        return $customerData;
+    }
+
+    /**
+     * Create customer using setters.
+     *
+     * @return CustomerInterface
+     */
+    public function createSampleCustomerDataObject()
+    {
+        $this->addressBuilder
+            ->setCountryId('US')
+            ->setDefaultBilling(true)
+            ->setDefaultShipping(true)
+            ->setPostcode('75477')
+            ->setRegion(
+                Bootstrap::getObjectManager()->create('Magento\Customer\Api\Data\RegionDataBuilder')
+                    ->setRegionCode(self::ADDRESS_REGION_CODE1)
+                    ->setRegion('Alabama')
+                    ->setRegionId(1)
+                    ->create()
+            )
+            ->setStreet(['Green str, 67'])
+            ->setTelephone('3468676')
+            ->setCity(self::ADDRESS_CITY1)
+            ->setFirstname('John')
+            ->setLastname('Smith');
+        $address1 = $this->dataObjectProcessor->buildOutputDataArray(
+            $this->addressBuilder->create(),
+            'Magento\Customer\Api\Data\AddressInterface'
+        );
+
+        $this->addressBuilder
+            ->setCountryId('US')
+            ->setDefaultBilling(false)
+            ->setDefaultShipping(false)
+            ->setPostcode('47676')
+            ->setRegion(
+                Bootstrap::getObjectManager()->create('Magento\Customer\Api\Data\RegionDataBuilder')
+                    ->setRegionCode(self::ADDRESS_REGION_CODE2)
+                    ->setRegion('Alabama')
+                    ->setRegionId(1)
+                    ->create()
+            )
+            ->setStreet(['Black str, 48', 'Building D'])
+            ->setCity(self::ADDRESS_CITY2)
+            ->setTelephone('3234676')
+            ->setFirstname('John')
+            ->setLastname('Smith');
+        $address2 = $this->dataObjectProcessor->buildOutputDataArray(
+            $this->addressBuilder->create(),
+            'Magento\Customer\Api\Data\AddressInterface'
+        );
+
+        $customerData = [
+            CustomerData::FIRSTNAME => self::FIRSTNAME,
+            CustomerData::LASTNAME => self::LASTNAME,
+            CustomerData::EMAIL => 'janedoe' . uniqid() . '@example.com',
+            CustomerData::CONFIRMATION => self::CONFIRMATION,
+            CustomerData::CREATED_AT => self::CREATED_AT,
+            CustomerData::CREATED_IN => self::STORE_NAME,
+            CustomerData::DOB => self::DOB,
+            CustomerData::GENDER => self::GENDER,
+            CustomerData::GROUP_ID => self::GROUP_ID,
+            CustomerData::MIDDLENAME => self::MIDDLENAME,
+            CustomerData::PREFIX => self::PREFIX,
+            CustomerData::STORE_ID => self::STORE_ID,
+            CustomerData::SUFFIX => self::SUFFIX,
+            CustomerData::TAXVAT => self::TAXVAT,
+            CustomerData::WEBSITE_ID => self::WEBSITE_ID,
+            CustomerData::KEY_ADDRESSES => [$address1, $address2],
+            'custom_attributes' => [
+                [
+                    'attribute_code' => 'disable_auto_group_change',
+                    'value' => '0',
+                ],
+            ],
+        ];
+        return $this->customerBuilder->populateWithArray($customerData)->create();
+    }
+}
diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/Adapter/Rest.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/Adapter/Rest.php
new file mode 100644
index 00000000000..91a12efba58
--- /dev/null
+++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/Adapter/Rest.php
@@ -0,0 +1,145 @@
+<?php
+/**
+ * Test client for REST API testing.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\TestFramework\TestCase\Webapi\Adapter;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Webapi\Model\Rest\Config;
+
+class Rest implements \Magento\TestFramework\TestCase\Webapi\AdapterInterface
+{
+    /** @var \Magento\Webapi\Model\Config */
+    protected $_config;
+
+    /** @var \Magento\Integration\Model\Oauth\Consumer */
+    protected static $_consumer;
+
+    /** @var \Magento\Integration\Model\Oauth\Token */
+    protected static $_token;
+
+    /** @var string */
+    protected static $_consumerKey;
+
+    /** @var string */
+    protected static $_consumerSecret;
+
+    /** @var string */
+    protected static $_verifier;
+
+    /** @var \Magento\TestFramework\TestCase\Webapi\Adapter\Rest\CurlClient */
+    protected $curlClient;
+
+    /** @var \Magento\TestFramework\TestCase\Webapi\Adapter\Rest\DocumentationGenerator */
+    protected $documentationGenerator;
+
+    /** @var string */
+    protected $defaultStoreCode;
+
+    /**
+     * Initialize dependencies.
+     */
+    public function __construct()
+    {
+        /** @var $objectManager \Magento\TestFramework\ObjectManager */
+        $objectManager = Bootstrap::getObjectManager();
+        $this->_config = $objectManager->get('Magento\Webapi\Model\Config');
+        $this->curlClient = $objectManager->get('Magento\TestFramework\TestCase\Webapi\Adapter\Rest\CurlClient');
+        $this->documentationGenerator = $objectManager->get(
+            'Magento\TestFramework\TestCase\Webapi\Adapter\Rest\DocumentationGenerator'
+        );
+        $this->defaultStoreCode = Bootstrap::getObjectManager()
+            ->get('Magento\Store\Model\StoreManagerInterface')
+            ->getStore()
+            ->getCode();
+    }
+
+    /**
+     * {@inheritdoc}
+     * @throws \Exception
+     */
+    public function call($serviceInfo, $arguments = [])
+    {
+        $resourcePath = '/' . $this->defaultStoreCode . $this->_getRestResourcePath($serviceInfo);
+        $httpMethod = $this->_getRestHttpMethod($serviceInfo);
+        //Get a valid token
+        $accessCredentials = \Magento\TestFramework\Authentication\OauthHelper::getApiAccessCredentials();
+        /** @var $oAuthClient \Magento\TestFramework\Authentication\Rest\OauthClient */
+        $oAuthClient = $accessCredentials['oauth_client'];
+        $urlFormEncoded = false;
+        // we're always using JSON
+        $authHeader = [];
+        $restServiceInfo = $serviceInfo['rest'];
+        if (array_key_exists('token', $restServiceInfo)) {
+            $authHeader = $oAuthClient->buildBearerTokenAuthorizationHeader($restServiceInfo['token']);
+        } else {
+            $authHeader = $oAuthClient->buildOauthAuthorizationHeader(
+                $this->curlClient->constructResourceUrl($resourcePath),
+                $accessCredentials['key'],
+                $accessCredentials['secret'],
+                ($httpMethod == 'PUT' || $httpMethod == 'POST') && $urlFormEncoded ? $arguments : [],
+                $httpMethod
+            );
+        }
+        $authHeader = array_merge($authHeader, ['Accept: application/json', 'Content-Type: application/json']);
+        switch ($httpMethod) {
+            case Config::HTTP_METHOD_GET:
+                $response = $this->curlClient->get($resourcePath, [], $authHeader);
+                break;
+            case Config::HTTP_METHOD_POST:
+                $response = $this->curlClient->post($resourcePath, $arguments, $authHeader);
+                break;
+            case Config::HTTP_METHOD_PUT:
+                $response = $this->curlClient->put($resourcePath, $arguments, $authHeader);
+                break;
+            case Config::HTTP_METHOD_DELETE:
+                $response = $this->curlClient->delete($resourcePath, $authHeader);
+                break;
+            default:
+                throw new \LogicException("HTTP method '{$httpMethod}' is not supported.");
+        }
+        if (defined('GENERATE_REST_DOCUMENTATION') && GENERATE_REST_DOCUMENTATION) {
+            $this->documentationGenerator->generateDocumentation($httpMethod, $resourcePath, $arguments, $response);
+        }
+        return $response;
+    }
+
+    /**
+     * Retrieve REST endpoint from $serviceInfo array and return it to the caller.
+     *
+     * @param array $serviceInfo
+     * @return string
+     * @throws \Exception
+     */
+    protected function _getRestResourcePath($serviceInfo)
+    {
+        if (isset($serviceInfo['rest']['resourcePath'])) {
+            $resourcePath = $serviceInfo['rest']['resourcePath'];
+        }
+        if (!isset($resourcePath)) {
+            throw new \Exception("REST endpoint cannot be identified.");
+        }
+        return $resourcePath;
+    }
+
+    /**
+     * Retrieve HTTP method to be used in REST request.
+     *
+     * @param array $serviceInfo
+     * @return string
+     * @throws \Exception
+     */
+    protected function _getRestHttpMethod($serviceInfo)
+    {
+        if (isset($serviceInfo['rest']['httpMethod'])) {
+            $httpMethod = $serviceInfo['rest']['httpMethod'];
+        }
+        if (!isset($httpMethod)) {
+            throw new \Exception("REST HTTP method cannot be identified.");
+        }
+        return $httpMethod;
+    }
+}
diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/Adapter/Rest/CurlClient.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/Adapter/Rest/CurlClient.php
new file mode 100644
index 00000000000..a907a4ca8b5
--- /dev/null
+++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/Adapter/Rest/CurlClient.php
@@ -0,0 +1,308 @@
+<?php
+/**
+ * Client for invoking REST API
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestFramework\TestCase\Webapi\Adapter\Rest;
+
+class CurlClient
+{
+    const EMPTY_REQUEST_BODY = 'Empty body';
+    /**
+     * @var string REST URL base path
+     */
+    protected $restBasePath = '/rest/';
+
+    /**
+     * @var array Response array
+     */
+    protected $responseArray;
+
+    /**
+     * @var array JSON Error code to error message mapping
+     */
+    protected $_jsonErrorMessages = [
+        JSON_ERROR_DEPTH => 'Maximum depth exceeded',
+        JSON_ERROR_STATE_MISMATCH => 'State mismatch',
+        JSON_ERROR_CTRL_CHAR => 'Unexpected control character found',
+        JSON_ERROR_SYNTAX => 'Syntax error, invalid JSON',
+    ];
+
+    /**
+     * Perform HTTP GET request
+     *
+     * @param string $resourcePath Resource URL like /V1/Resource1/123
+     * @param array $data
+     * @param array $headers
+     * @return mixed
+     */
+    public function get($resourcePath, $data = [], $headers = [])
+    {
+        $url = $this->constructResourceUrl($resourcePath);
+        if (!empty($data)) {
+            $url .= '?' . http_build_query($data);
+        }
+
+        $curlOpts = [];
+        $curlOpts[CURLOPT_CUSTOMREQUEST] = \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET;
+        $resp = $this->_invokeApi($url, $curlOpts, $headers);
+        $respArray = $this->_jsonDecode($resp["body"]);
+        return $respArray;
+    }
+
+    /**
+     * Perform HTTP POST request
+     *
+     * @param string $resourcePath Resource URL like /V1/Resource1/123
+     * @param array $data
+     * @param array $headers
+     * @return mixed
+     */
+    public function post($resourcePath, $data, $headers = [])
+    {
+        return $this->_postOrPut($resourcePath, $data, false, $headers);
+    }
+
+    /**
+     * Perform HTTP PUT request
+     *
+     * @param string $resourcePath Resource URL like /V1/Resource1/123
+     * @param array $data
+     * @param array $headers
+     * @return mixed
+     */
+    public function put($resourcePath, $data, $headers = [])
+    {
+        return $this->_postOrPut($resourcePath, $data, true, $headers);
+    }
+
+    /**
+     * Perform HTTP DELETE request
+     *
+     * @param string $resourcePath Resource URL like /V1/Resource1/123
+     * @param array $headers
+     * @return mixed
+     */
+    public function delete($resourcePath, $headers = [])
+    {
+        $url = $this->constructResourceUrl($resourcePath);
+
+        $curlOpts = [];
+        $curlOpts[CURLOPT_CUSTOMREQUEST] = \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_DELETE;
+
+        $resp = $this->_invokeApi($url, $curlOpts, $headers);
+        $respArray = $this->_jsonDecode($resp["body"]);
+
+        return $respArray;
+    }
+
+    /**
+     * Perform HTTP POST or PUT request
+     *
+     * @param string $resourcePath Resource URL like /V1/Resource1/123
+     * @param array $data
+     * @param boolean $put Set true to post data as HTTP PUT operation (update). If this value is set to false,
+     *        HTTP POST (create) will be used
+     * @param array $headers
+     * @return mixed
+     */
+    protected function _postOrPut($resourcePath, $data, $put = false, $headers = [])
+    {
+        $url = $this->constructResourceUrl($resourcePath);
+
+        if (in_array("Content-Type: application/json", $headers)) {
+            // json encode data
+            if ($data != self::EMPTY_REQUEST_BODY) {
+                $data = $this->_jsonEncode($data);
+            } else {
+                $data = '';
+            }
+        }
+
+        $curlOpts = [];
+        if ($put) {
+            $curlOpts[CURLOPT_CUSTOMREQUEST] = \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_PUT;
+        } else {
+            $curlOpts[CURLOPT_CUSTOMREQUEST] = \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST;
+        }
+        $headers[] = 'Content-Length: ' . strlen($data);
+        $curlOpts[CURLOPT_POSTFIELDS] = $data;
+
+        $this->responseArray = $this->_invokeApi($url, $curlOpts, $headers);
+        $respBodyArray = $this->_jsonDecode($this->responseArray["body"]);
+
+        return $respBodyArray;
+    }
+
+    /**
+     * Set Rest base path if available
+     *
+     * @param string $restBasePath
+     *
+     * @return void
+     */
+    public function setRestBasePath($restBasePath)
+    {
+        $this->restBasePath = $restBasePath;
+    }
+
+    /**
+     * Get current response array
+     *
+     * @return array
+     */
+    public function getCurrentResponseArray()
+    {
+        return $this->responseArray;
+    }
+
+    /**
+     * @param string $resourcePath Resource URL like /V1/Resource1/123
+     * @return string resource URL
+     * @throws \Exception
+     */
+    public function constructResourceUrl($resourcePath)
+    {
+        return rtrim(TESTS_BASE_URL, '/') . $this->restBasePath . ltrim($resourcePath, '/');
+    }
+
+    /**
+     * Makes the REST api call using passed $curl object
+     *
+     * @param string $url
+     * @param array $additionalCurlOpts cURL Options
+     * @param array $headers
+     * @return array
+     * @throws \Exception
+     */
+    protected function _invokeApi($url, $additionalCurlOpts, $headers = [])
+    {
+        // initialize cURL
+        $curl = curl_init($url);
+        if ($curl === false) {
+            throw new \Exception("Error Initializing cURL for baseUrl: " . $url);
+        }
+
+        // get cURL options
+        $curlOpts = $this->_getCurlOptions($additionalCurlOpts, $headers);
+
+        // add CURL opts
+        foreach ($curlOpts as $opt => $val) {
+            curl_setopt($curl, $opt, $val);
+        }
+
+        $response = curl_exec($curl);
+        if ($response === false) {
+            throw new \Exception(curl_error($curl));
+        }
+
+        $resp = [];
+        $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
+        $resp["header"] = substr($response, 0, $headerSize);
+        $resp["body"] = substr($response, $headerSize);
+
+        $resp["meta"] = curl_getinfo($curl);
+        if ($resp["meta"] === false) {
+            throw new \Exception(curl_error($curl));
+        }
+
+        curl_close($curl);
+
+        $meta = $resp["meta"];
+        if ($meta && $meta['http_code'] >= 400) {
+            throw new \Exception($resp["body"], $meta['http_code']);
+        }
+
+        return $resp;
+    }
+
+    /**
+     * Constructs and returns a curl options array
+     *
+     * @param array $customCurlOpts Additional / overridden cURL options
+     * @param array $headers
+     * @return array
+     */
+    protected function _getCurlOptions($customCurlOpts = [], $headers = [])
+    {
+        // default curl options
+        $curlOpts = [
+            CURLOPT_RETURNTRANSFER => true, // return result instead of echoing
+            CURLOPT_SSL_VERIFYPEER => false, // stop cURL from verifying the peer's certificate
+            CURLOPT_FOLLOWLOCATION => false, // follow redirects, Location: headers
+            CURLOPT_MAXREDIRS => 10, // but don't redirect more than 10 times
+            CURLOPT_HTTPHEADER => [],
+            CURLOPT_HEADER => 1,
+        ];
+
+        // merge headers
+        $headers = array_merge($curlOpts[CURLOPT_HTTPHEADER], $headers);
+        if (TESTS_XDEBUG_ENABLED) {
+            $headers[] = 'Cookie: XDEBUG_SESSION=' . TESTS_XDEBUG_SESSION;
+        }
+        $curlOpts[CURLOPT_HTTPHEADER] = $headers;
+
+        // merge custom Curl Options & return
+        foreach ($customCurlOpts as $opt => $val) {
+            $curlOpts[$opt] = $val;
+        }
+
+        return $curlOpts;
+    }
+
+    /**
+     * JSON encode with error checking
+     *
+     * @param mixed $data
+     * @return string
+     * @throws \Exception
+     */
+    protected function _jsonEncode($data)
+    {
+        $ret = json_encode($data);
+        $this->_checkJsonError($data);
+
+        // return the json String
+        return $ret;
+    }
+
+    /**
+     * Decode a JSON string with error checking
+     *
+     * @param string $data
+     * @param bool $asArray
+     * @throws \Exception
+     * @return mixed
+     */
+    protected function _jsonDecode($data, $asArray = true)
+    {
+        $ret = json_decode($data, $asArray);
+        $this->_checkJsonError($data);
+
+        // return the array
+        return $ret;
+    }
+
+    /**
+     * Checks for JSON error in the latest encoding / decoding and throws an exception in case of error
+     *
+     * @throws \Exception
+     */
+    protected function _checkJsonError()
+    {
+        $jsonError = json_last_error();
+        if ($jsonError !== JSON_ERROR_NONE) {
+            // find appropriate error message
+            $message = 'Unknown JSON Error';
+            if (isset($this->_jsonErrorMessages[$jsonError])) {
+                $message = $this->_jsonErrorMessages[$jsonError];
+            }
+
+            throw new \Exception(
+                'JSON Encoding / Decoding error: ' . $message . var_export(func_get_arg(0), true),
+                $jsonError
+            );
+        }
+    }
+}
diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/Adapter/Rest/DocumentationGenerator.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/Adapter/Rest/DocumentationGenerator.php
new file mode 100644
index 00000000000..27cce9d7d62
--- /dev/null
+++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/Adapter/Rest/DocumentationGenerator.php
@@ -0,0 +1,238 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\TestFramework\TestCase\Webapi\Adapter\Rest;
+
+/**
+ * Generator for documentation
+ *
+ */
+class DocumentationGenerator
+{
+    /**
+     * Generate documentation based on request-response data during REST requests.
+     *
+     * @param string $httpMethod
+     * @param string $resourcePath
+     * @param array $arguments
+     * @param array $response
+     */
+    public function generateDocumentation($httpMethod, $resourcePath, $arguments, $response)
+    {
+        $content = $this->generateHtmlContent($httpMethod, $resourcePath, $arguments, $response);
+        $filePath = $this->generateFileName($resourcePath);
+        if (is_null($filePath)) {
+            return;
+        }
+        if (!is_writable(dirname($filePath))) {
+            throw new \RuntimeException('Cannot write to documentation directory.');
+        } elseif (file_exists($filePath)) {
+            $fileContent = file_get_contents($filePath);
+            $endHtml = $this->generateHtmlFooter();
+            $fileContent = str_replace($endHtml, '', $fileContent);
+            $content = "{$fileContent}{$content}";
+            unlink($filePath);
+            file_put_contents($filePath, $content, FILE_APPEND);
+        } else {
+            file_put_contents($filePath, $content, FILE_APPEND);
+        }
+    }
+
+    /**
+     * Prepare HTML for the generated documentation.
+     *
+     * @param string $httpMethod
+     * @param string $resourcePath
+     * @param array $arguments
+     * @param array $response
+     * @return string
+     */
+    protected function generateHtmlContent($httpMethod, $resourcePath, $arguments, $response)
+    {
+        if (empty($arguments)) {
+            $arguments = 'This call does not accept a request body.';
+            $requestParametersHtml = '';
+        } else {
+            $requestParameters = $this->retrieveParametersAsHtml($arguments);
+            $arguments = json_encode($arguments, JSON_PRETTY_PRINT);
+            $requestParametersHtml = <<<HTML
+            <table class="docutils field-list" frame="void" rules="none"  width="400">
+                <colgroup>
+                    <col width="35%" class="field-name">
+                    <col  width="65%" class="field-body">
+                </colgroup>
+                <tbody valign="top">
+                <tr class="field-odd field">
+                    <th class="field-name">Request parameters:</th>
+                    <td class="field-body">
+                        <ul class="first last simple">
+                            {$requestParameters}
+                        </ul>
+                    </td>
+                </tr>
+                </tbody>
+            </table>
+HTML;
+        }
+        if (is_array($response)) {
+            $responseArrayKeys = array_keys($response);
+            $responseParameters = "Parameters should be specified manually.";
+            foreach ($responseArrayKeys as $key) {
+                if (!is_int($key)) {
+                    $responseParameters = '';
+                    break;
+                }
+            }
+        }
+        if (empty($responseParameters)) {
+            $responseParameters = $this->retrieveParametersAsHtml($response);
+        }
+        $response = json_encode($response, JSON_PRETTY_PRINT);
+        $responseParametersHtml = <<<HTML
+        <table class="docutils field-list" frame="void" rules="none"  width="400">
+            <colgroup>
+                <col width="35%" class="field-name">
+                <col  width="65%" class="field-body">
+            </colgroup>
+            <tbody valign="top">
+            <tr class="field-odd field">
+                <th class="field-name">Response attributes:</th>
+                <td class="field-body">
+                    <ul class="first last simple">
+                        {$responseParameters}
+                    </ul>
+                </td>
+            </tr>
+            </tbody>
+        </table>
+HTML;
+        $resourcePath = urldecode($resourcePath);
+        $resource = str_replace('/', '-', preg_replace('#/\w*/V\d+/(.*)#', '${1}', $resourcePath));
+        $lowerCaseResource = strtolower($resource);
+        $lowerCaseMethod = strtolower($httpMethod);
+        $beginningHtml = <<<HTML
+<div class="col-xs-9" role="main">
+    <div class="bs-docs-section">
+HTML;
+        $headingHtml = <<<HTML
+        <h2 class="api2" id="$lowerCaseResource">$resource</h2>
+        <h3 class="api3" id="$lowerCaseMethod-$lowerCaseResource">$httpMethod $resourcePath</h3>
+        <h4 class="api4">Request</h4>
+HTML;
+        $responseHtml = <<<HTML
+        <h4 class="api4" id=”$lowerCaseResource-response>Response</h4>
+HTML;
+        $requestResponseParametersHtml = <<<HTML
+        <h3 class="api3" id="$lowerCaseResource-parameters">Request and response parameters</h3>
+HTML;
+        $endHtml = $this->generateHtmlFooter();
+        $content = "{$beginningHtml}{$headingHtml}<pre>{$arguments}</pre>{$responseHtml}<pre>{$response}"
+            . "</pre>{$requestResponseParametersHtml}{$requestParametersHtml}{$responseParametersHtml}{$endHtml}";
+        return $content;
+    }
+
+    /**
+     * Generate the end html text;
+     *
+     * @return string
+     */
+    protected function generateHtmlFooter()
+    {
+        $endHtml = <<<HTML
+        <h3 class="api3" id="products-responses">Response codes</h3>
+        <table class="docutils field-list" frame="void" rules="none" width="400">
+            <colgroup>
+                <col  width="35%" class="field-name">
+                <col  width="65%" class="field-body">
+            </colgroup>
+            <tbody valign="top">
+            <tr class="field-odd field">
+                <th class="field-name">Normal response codes:</th>
+                <td class="field-body">
+                    <ul class="first last simple">
+                        <li><strong>SUCCESS_CODE</strong> - SUCCESS_DESCRIPTION</li>
+                    </ul>
+                </td>
+            </tr>
+            </tbody>
+        </table>
+        <table class="docutils field-list" frame="void" rules="none" width="400">
+            <colgroup>
+                <col  width="35%" class="field-name">
+                <col  width="65%" class="field-body">
+            </colgroup>
+            <tbody valign="top">
+            <tr class="field-odd field">
+                <th class="field-name">Error response codes:</th>
+                <td class="field-body">
+                    <ul class="first last simple">
+                        <li><strong>ERROR_CODE</strong> - ERROR_DESCRIPTION</li>
+                    </ul>
+                </td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
+</div>
+HTML;
+        return $endHtml;
+    }
+
+    /**
+     * Generate a name of file
+     *
+     * @return string|null
+     * @throws \RuntimeException
+     */
+    protected function generateFileName()
+    {
+        $varDir = realpath(__DIR__ . '/../../../../../../..') . '/var';
+        $documentationDir = $varDir . '/log/rest-documentation/';
+        $debugBackTrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+        $pathToFile = $documentationDir;
+        $fileName = null;
+        foreach ($debugBackTrace as $traceItem) {
+            /** Test invocation trace item is the only item which has 3 elements, other trace items have 5 elements */
+            if (count($traceItem) == 3) {
+                /** Remove 'test' prefix from method name, e.g. testCreate => create */
+                $fileName = lcfirst(substr($traceItem['function'], 4));
+                /** Remove 'Test' suffix from test class name */
+                $pathToFile .= str_replace('\\', '/', substr($traceItem['class'], 0, -4)) . '/';
+                break;
+            }
+        }
+        if (!file_exists($pathToFile)) {
+            if (!mkdir($pathToFile, 0755, true)) {
+                throw new \RuntimeException('Unable to create missing directory for REST documentation generation');
+            }
+        }
+        if (!is_null($fileName)) {
+            $filePath = $pathToFile . $fileName . '.html';
+            return $filePath;
+        }
+        return null;
+    }
+
+    /**
+     * Retrieve parameters of response/request
+     *
+     * @param array|string $parameters
+     * @return string
+     */
+    protected function retrieveParametersAsHtml($parameters)
+    {
+        $parametersAsHtml = '';
+        if (is_array($parameters)) {
+            foreach (array_keys($parameters) as $parameter) {
+                $parametersAsHtml = $parametersAsHtml . '<li><strong>' . $parameter .
+                    '</strong> (<em>Change type manually!</em>) TBD.</li>';
+            }
+        } else {
+            $parametersAsHtml = '<li><strong>' . 'scalar_value' .
+                '</strong> (<em>Change type manually!</em>) TBD.</li>';
+        }
+        return $parametersAsHtml;
+    }
+}
diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/Adapter/Soap.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/Adapter/Soap.php
new file mode 100644
index 00000000000..73f6d8a6582
--- /dev/null
+++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/Adapter/Soap.php
@@ -0,0 +1,238 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestFramework\TestCase\Webapi\Adapter;
+
+use Magento\Framework\Api\SimpleDataObjectConverter;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Webapi\Controller\Soap\Request\Handler as SoapHandler;
+
+/**
+ * Test client for SOAP API testing.
+ */
+class Soap implements \Magento\TestFramework\TestCase\Webapi\AdapterInterface
+{
+    const WSDL_BASE_PATH = '/soap';
+
+    /**
+     * SOAP client initialized with different WSDLs.
+     *
+     * @var \Zend\Soap\Client[]
+     */
+    protected $_soapClients = [];
+
+    /**
+     * @var \Magento\Webapi\Model\Soap\Config
+     */
+    protected $_soapConfig;
+
+    /**
+     * @var \Magento\Webapi\Helper\Data
+     */
+    protected $_helper;
+
+    /**
+     * @var SimpleDataObjectConverter
+     */
+    protected $_converter;
+
+    /**
+     * Initialize dependencies.
+     */
+    public function __construct()
+    {
+        /** @var $objectManager \Magento\TestFramework\ObjectManager */
+        $objectManager = Bootstrap::getObjectManager();
+        $this->_soapConfig = $objectManager->get('Magento\Webapi\Model\Soap\Config');
+        $this->_helper = $objectManager->get('Magento\Webapi\Helper\Data');
+        $this->_converter = $objectManager->get('Magento\Framework\Api\SimpleDataObjectConverter');
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function call($serviceInfo, $arguments = [])
+    {
+        $soapOperation = $this->_getSoapOperation($serviceInfo);
+        $arguments = $this->_converter->convertKeysToCamelCase($arguments);
+        $soapResponse = $this->_getSoapClient($serviceInfo)->$soapOperation($arguments);
+        //Convert to snake case for tests to use same assertion data for both SOAP and REST tests
+        $result = (is_array($soapResponse) || is_object($soapResponse))
+            ? $this->toSnakeCase($this->_converter->convertStdObjectToArray($soapResponse, true))
+            : $soapResponse;
+        /** Remove result wrappers */
+        $result = isset($result[SoapHandler::RESULT_NODE_NAME]) ? $result[SoapHandler::RESULT_NODE_NAME] : $result;
+        return $result;
+    }
+
+    /**
+     * Get proper SOAP client instance that is initialized with with WSDL corresponding to requested service interface.
+     *
+     * @param string $serviceInfo PHP service interface name, should include version if present
+     * @return \Zend\Soap\Client
+     */
+    protected function _getSoapClient($serviceInfo)
+    {
+        $wsdlUrl = $this->generateWsdlUrl(
+            [$this->_getSoapServiceName($serviceInfo) . $this->_getSoapServiceVersion($serviceInfo)]
+        );
+        /** Check if there is SOAP client initialized with requested WSDL available */
+        if (!isset($this->_soapClients[$wsdlUrl])) {
+            $token = isset($serviceInfo['soap']['token']) ? $serviceInfo['soap']['token'] : null;
+            $this->_soapClients[$wsdlUrl] = $this->instantiateSoapClient($wsdlUrl, $token);
+        }
+        return $this->_soapClients[$wsdlUrl];
+    }
+
+    /**
+     * Create SOAP client instance and initialize it with provided WSDL URL.
+     *
+     * @param string $wsdlUrl
+     * @param string $token Authentication token
+     * @return \Zend\Soap\Client
+     */
+    public function instantiateSoapClient($wsdlUrl, $token = null)
+    {
+        $accessCredentials = $token
+            ? $token
+            : \Magento\TestFramework\Authentication\OauthHelper::getApiAccessCredentials()['key'];
+        $opts = ['http' => ['header' => "Authorization: Bearer " . $accessCredentials]];
+        $context = stream_context_create($opts);
+        $soapClient = new \Zend\Soap\Client($wsdlUrl);
+        $soapClient->setSoapVersion(SOAP_1_2);
+        $soapClient->setStreamContext($context);
+        if (TESTS_XDEBUG_ENABLED) {
+            $soapClient->setCookie('XDEBUG_SESSION', 1);
+        }
+        return $soapClient;
+    }
+
+    /**
+     * Generate WSDL URL.
+     *
+     * @param array $services e.g.<pre>
+     * array(
+     *     'catalogProductV1',
+     *     'customerV2'
+     * );</pre>
+     * @return string
+     */
+    public function generateWsdlUrl($services)
+    {
+        /** Sort list of services to avoid having different WSDL URLs for the identical lists of services. */
+        //TODO: This may change since same resource of multiple versions may be allowed after namespace changes
+        ksort($services);
+        /** @var \Magento\Store\Model\StoreManagerInterface $storeManager */
+        $storeManager = Bootstrap::getObjectManager()->get('Magento\Store\Model\StoreManagerInterface');
+        $storeCode = $storeManager->getStore()->getCode();
+        /** TESTS_BASE_URL is initialized in PHPUnit configuration */
+        $wsdlUrl = rtrim(TESTS_BASE_URL, '/') . self::WSDL_BASE_PATH . '/' . $storeCode . '?wsdl=1&services=';
+        $wsdlResourceArray = [];
+        foreach ($services as $serviceName) {
+            $wsdlResourceArray[] = $serviceName;
+        }
+        return $wsdlUrl . implode(",", $wsdlResourceArray);
+    }
+
+    /**
+     * Retrieve SOAP operation name from available service info.
+     *
+     * @param array $serviceInfo
+     * @return string
+     * @throws \LogicException
+     */
+    protected function _getSoapOperation($serviceInfo)
+    {
+        if (isset($serviceInfo['soap']['operation'])) {
+            $soapOperation = $serviceInfo['soap']['operation'];
+        } elseif (isset($serviceInfo['serviceInterface']) && isset($serviceInfo['method'])) {
+            $soapOperation = $this->_soapConfig->getSoapOperation(
+                $serviceInfo['serviceInterface'],
+                $serviceInfo['method']
+            );
+        } else {
+            throw new \LogicException("SOAP operation cannot be identified.");
+        }
+        return $soapOperation;
+    }
+
+    /**
+     * Retrieve service version from available service info.
+     *
+     * @param array $serviceInfo
+     * @return string
+     * @throws \LogicException
+     */
+    protected function _getSoapServiceVersion($serviceInfo)
+    {
+        if (isset($serviceInfo['soap']['operation'])) {
+            /*
+                TODO: Need to rework this to remove version call for serviceInfo array with 'operation' key
+                since version will be part of the service name
+            */
+            return '';
+        } elseif (isset($serviceInfo['serviceInterface'])) {
+            preg_match(
+                \Magento\Webapi\Model\Config::SERVICE_CLASS_PATTERN,
+                $serviceInfo['serviceInterface'],
+                $matches
+            );
+            if (isset($matches[3])) {
+                $version = $matches[3];
+            } else {
+                //TODO: Need to add this temporary version until version is added back for new MSC based services
+                $version = 1;
+                //throw new \LogicException("Service interface name is invalid.");
+            }
+        } else {
+            throw new \LogicException("Service version cannot be identified.");
+        }
+        /** Normalize version */
+        $version = 'V' . ltrim($version, 'vV');
+        return $version;
+    }
+
+    /**
+     * Retrieve service name from available service info.
+     *
+     * @param array $serviceInfo
+     * @return string
+     * @throws \LogicException
+     */
+    protected function _getSoapServiceName($serviceInfo)
+    {
+        if (isset($serviceInfo['soap']['service'])) {
+            $serviceName = $serviceInfo['soap']['service'];
+        } elseif (isset($serviceInfo['serviceInterface'])) {
+            $serviceName = $this->_helper->getServiceName($serviceInfo['serviceInterface'], false);
+        } else {
+            throw new \LogicException("Service name cannot be identified.");
+        }
+        return $serviceName;
+    }
+
+    /**
+     * Recursively transform array keys from camelCase to snake_case.
+     *
+     * Utility method for converting SOAP responses. Webapi framework's SOAP processing outputs
+     * snake case Data Object properties(ex. item_id) as camel case(itemId) to adhere to the WSDL.
+     * This method allows tests to use the same data for asserting both SOAP and REST responses.
+     *
+     * @param array $objectData An array of data.
+     * @return array The array with all camelCase keys converted to snake_case.
+     */
+    protected function toSnakeCase(array $objectData)
+    {
+        $data = [];
+        foreach ($objectData as $key => $value) {
+            $key = strtolower(preg_replace("/(?<=\\w)(?=[A-Z])/", "_$1", $key));
+            if (is_array($value)) {
+                $data[$key] = $this->toSnakeCase($value);
+            } else {
+                $data[$key] = $value;
+            }
+        }
+        return $data;
+    }
+}
diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/AdapterInterface.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/AdapterInterface.php
new file mode 100644
index 00000000000..e34d3cb702d
--- /dev/null
+++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/AdapterInterface.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * API tests adapter interface.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestFramework\TestCase\Webapi;
+
+interface AdapterInterface
+{
+    /**
+     * Perform call to the specified service method.
+     *
+     * @param array $serviceInfo <pre>
+     * array(
+     *     'rest' => array(
+     *         'resourcePath' => $resourcePath, // e.g. /products/:id
+     *         'httpMethod' => $httpMethod,     // e.g. GET
+     *         'token' => '21hasbtlaqy8t3mj73kjh71cxxkqj4aq'    // optional : for token based Authentication. Will
+     *                                                             override default Oauth based authentication provided
+     *                                                             by test framework
+     *     ),
+     *     'soap' => array(
+     *         'service' => $soapService,    // soap service name with Version suffix e.g. catalogProductV1, customerV2
+     *         'operation' => $operation     // soap operation name e.g. catalogProductCreate
+     *     ),
+     *     OR
+     *     'serviceInterface' => $phpServiceInterfaceName, // e.g. \Magento\Catalog\Api\ProductInterface
+     *     'method' => $serviceMethodName                  // e.g. create
+     *     'entityId' => $entityId                         // is used in REST route placeholder (if applicable)
+     * );
+     * </pre>
+     * @param array $arguments
+     * @return array|string|int|float|bool
+     */
+    public function call($serviceInfo, $arguments = []);
+}
diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/Curl.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/Curl.php
new file mode 100644
index 00000000000..655f31579c7
--- /dev/null
+++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/Webapi/Curl.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\TestFramework\TestCase\Webapi;
+
+/**
+ * A Curl client that can be called independently, outside of REST controller.
+ *
+ * Used by CookieManager tests.
+ */
+class Curl extends Adapter\Rest\CurlClient
+{
+    const COOKIE_HEADER = 'Set-Cookie: ';
+
+    /**
+     * @param string $resourcePath Resource URL like /V1/Resource1/123
+     * @return string resource URL
+     * @throws \Exception
+     */
+    public function constructResourceUrl($resourcePath)
+    {
+        return rtrim(TESTS_BASE_URL, '/') . ltrim($resourcePath, '/');
+    }
+
+    /**
+     * Perform HTTP GET request
+     *
+     * @param string $resourcePath Resource URL like /V1/Resource1/123
+     * @param array $data
+     * @param array $headers
+     * @return array
+     */
+    public function get($resourcePath, $data = [], $headers = [])
+    {
+        $url = $this->constructResourceUrl($resourcePath);
+        if (!empty($data)) {
+            $url .= '?' . http_build_query($data);
+        }
+
+        $curlOpts = [];
+        $curlOpts[CURLOPT_CUSTOMREQUEST] = \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET;
+        $curlOpts[CURLOPT_SSLVERSION] = 3;
+        $response = $this->_invokeApi($url, $curlOpts, $headers);
+        $response['cookies'] = $this->cookieParse($response['header']);
+        return $response;
+    }
+
+    /**
+     * Takes a string in the form of an HTTP header block, returns cookie data.
+     *
+     * Return array is in the form of:
+     *  [
+     *      [
+     *          'name' = <cookie_name>,
+     *          'value' = <cookie_value>,
+     *          <cookie_metadata_name> => <cookie_metadata_value> || 'true'
+     *      ],
+     *  ]
+     *
+     * @param $headerBlock
+     * @return array
+     */
+    private function cookieParse($headerBlock)
+    {
+        $header = explode("\r\n", $headerBlock);
+        $cookies = [];
+        foreach ($header as $line) {
+            $line = trim($line);
+            if (substr($line, 0, strlen(self::COOKIE_HEADER)) == self::COOKIE_HEADER) {
+                $line = trim(substr($line, strlen(self::COOKIE_HEADER)));
+                $cookieData = [];
+                // Check if cookie contains attributes
+                if (strpos($line, ';') === false) {
+                    // no attributes, just name and value
+                    list($cookieData['name'], $cookieData['value']) = explode('=', $line);
+                } else {
+                    // has attributes, must parse them out and loop through
+                    list($nvPair, $cookieMetadata) = explode(';', $line, 2);
+                    list($cookieData['name'], $cookieData['value']) = explode('=', $nvPair);
+                    $rawCookieData = explode(';', $cookieMetadata);
+                    foreach ($rawCookieData as $keyValuePairs) {
+                        list($key, $value) = array_merge(explode('=', $keyValuePairs), ['true']);
+                        $cookieData[strtolower(trim($key))] = trim($value);
+                    }
+                }
+                $cookies[] = $cookieData;
+            }
+        }
+        return $cookies;
+    }
+}
diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/WebapiAbstract.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/WebapiAbstract.php
new file mode 100644
index 00000000000..d02247b75a0
--- /dev/null
+++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/WebapiAbstract.php
@@ -0,0 +1,665 @@
+<?php
+/**
+ * Generic test case for Web API functional tests.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestFramework\TestCase;
+
+use Magento\Framework\App\Filesystem\DirectoryList;
+use Magento\Framework\Filesystem;
+use Magento\Webapi\Model\Soap\Fault;
+
+abstract class WebapiAbstract extends \PHPUnit_Framework_TestCase
+{
+    /** TODO: Reconsider implementation of fixture-management methods after implementing several tests */
+    /**#@+
+     * Auto tear down options in setFixture
+     */
+    const AUTO_TEAR_DOWN_DISABLED = 0;
+    const AUTO_TEAR_DOWN_AFTER_METHOD = 1;
+    const AUTO_TEAR_DOWN_AFTER_CLASS = 2;
+    /**#@-*/
+
+    /**#@+
+     * Web API adapters that are used to perform actual calls.
+     */
+    const ADAPTER_SOAP = 'soap';
+    const ADAPTER_REST = 'rest';
+    /**#@-*/
+
+    /**
+     * Application cache model.
+     *
+     * @var \Magento\Framework\App\Cache
+     */
+    protected $_appCache;
+
+    /**
+     * The list of models to be deleted automatically in tearDown().
+     *
+     * @var array
+     */
+    protected $_modelsToDelete = [];
+
+    /**
+     * Namespace for fixtures is different for each test case.
+     *
+     * @var string
+     */
+    protected static $_fixturesNamespace;
+
+    /**
+     * The list of registered fixtures.
+     *
+     * @var array
+     */
+    protected static $_fixtures = [];
+
+    /**
+     * Fixtures to be deleted in tearDown().
+     *
+     * @var array
+     */
+    protected static $_methodLevelFixtures = [];
+
+    /**
+     * Fixtures to be deleted in tearDownAfterClass().
+     *
+     * @var array
+     */
+    protected static $_classLevelFixtures = [];
+
+    /**
+     * Original Magento config values.
+     *
+     * @var array
+     */
+    protected $_origConfigValues = [];
+
+    /**
+     * The list of instantiated Web API adapters.
+     *
+     * @var \Magento\TestFramework\TestCase\Webapi\AdapterInterface[]
+     */
+    protected $_webApiAdapters;
+
+    /**
+     * The list of available Web API adapters.
+     *
+     * @var array
+     */
+    protected $_webApiAdaptersMap = [
+        self::ADAPTER_SOAP => 'Magento\TestFramework\TestCase\Webapi\Adapter\Soap',
+        self::ADAPTER_REST => 'Magento\TestFramework\TestCase\Webapi\Adapter\Rest',
+    ];
+
+    /**
+     * Initialize fixture namespaces.
+     */
+    public static function setUpBeforeClass()
+    {
+        parent::setUpBeforeClass();
+        self::_setFixtureNamespace();
+    }
+
+    /**
+     * Run garbage collector for cleaning memory
+     *
+     * @return void
+     */
+    public static function tearDownAfterClass()
+    {
+        //clear garbage in memory
+        if (version_compare(PHP_VERSION, '5.3', '>=')) {
+            gc_collect_cycles();
+        }
+
+        $fixtureNamespace = self::_getFixtureNamespace();
+        if (isset(self::$_classLevelFixtures[$fixtureNamespace])
+            && count(self::$_classLevelFixtures[$fixtureNamespace])
+        ) {
+            self::_deleteFixtures(self::$_classLevelFixtures[$fixtureNamespace]);
+        }
+
+        //ever disable secure area on class down
+        self::_enableSecureArea(false);
+        self::_unsetFixtureNamespace();
+        parent::tearDownAfterClass();
+    }
+
+    /**
+     * Call safe delete for models which added to delete list
+     * Restore config values changed during the test
+     *
+     * @return void
+     */
+    protected function tearDown()
+    {
+        $fixtureNamespace = self::_getFixtureNamespace();
+        if (isset(self::$_methodLevelFixtures[$fixtureNamespace])
+            && count(self::$_methodLevelFixtures[$fixtureNamespace])
+        ) {
+            self::_deleteFixtures(self::$_methodLevelFixtures[$fixtureNamespace]);
+        }
+        $this->_callModelsDelete();
+        $this->_restoreAppConfig();
+        parent::tearDown();
+    }
+
+    /**
+     * Perform Web API call to the system under test.
+     *
+     * @see \Magento\TestFramework\TestCase\Webapi\AdapterInterface::call()
+     * @param array $serviceInfo
+     * @param array $arguments
+     * @param string|null $webApiAdapterCode
+     * @return array|int|string|float|bool Web API call results
+     */
+    protected function _webApiCall($serviceInfo, $arguments = [], $webApiAdapterCode = null)
+    {
+        if (is_null($webApiAdapterCode)) {
+            /** Default adapter code is defined in PHPUnit configuration */
+            $webApiAdapterCode = strtolower(TESTS_WEB_API_ADAPTER);
+        }
+        return $this->_getWebApiAdapter($webApiAdapterCode)->call($serviceInfo, $arguments);
+    }
+
+    /**
+     * Mark test to be executed for SOAP adapter only.
+     */
+    protected function _markTestAsSoapOnly($message = null)
+    {
+        if (TESTS_WEB_API_ADAPTER != self::ADAPTER_SOAP) {
+            $this->markTestSkipped($message ? $message : "The test is intended to be executed for SOAP adapter only.");
+        }
+    }
+
+    /**
+     * Mark test to be executed for REST adapter only.
+     */
+    protected function _markTestAsRestOnly($message = null)
+    {
+        if (TESTS_WEB_API_ADAPTER != self::ADAPTER_REST) {
+            $this->markTestSkipped($message ? $message : "The test is intended to be executed for REST adapter only.");
+        }
+    }
+
+    /**
+     * Set fixture to registry
+     *
+     * @param string $key
+     * @param mixed $fixture
+     * @param int $tearDown
+     * @return void
+     */
+    public static function setFixture($key, $fixture, $tearDown = self::AUTO_TEAR_DOWN_AFTER_METHOD)
+    {
+        $fixturesNamespace = self::_getFixtureNamespace();
+        if (!isset(self::$_fixtures[$fixturesNamespace])) {
+            self::$_fixtures[$fixturesNamespace] = [];
+        }
+        self::$_fixtures[$fixturesNamespace][$key] = $fixture;
+        if ($tearDown == self::AUTO_TEAR_DOWN_AFTER_METHOD) {
+            if (!isset(self::$_methodLevelFixtures[$fixturesNamespace])) {
+                self::$_methodLevelFixtures[$fixturesNamespace] = [];
+            }
+            self::$_methodLevelFixtures[$fixturesNamespace][] = $key;
+        } else {
+            if ($tearDown == self::AUTO_TEAR_DOWN_AFTER_CLASS) {
+                if (!isset(self::$_classLevelFixtures[$fixturesNamespace])) {
+                    self::$_classLevelFixtures[$fixturesNamespace] = [];
+                }
+                self::$_classLevelFixtures[$fixturesNamespace][] = $key;
+            }
+        }
+    }
+
+    /**
+     * Get fixture by key
+     *
+     * @param string $key
+     * @return mixed
+     */
+    public static function getFixture($key)
+    {
+        $fixturesNamespace = self::_getFixtureNamespace();
+        if (array_key_exists($key, self::$_fixtures[$fixturesNamespace])) {
+            return self::$_fixtures[$fixturesNamespace][$key];
+        }
+        return null;
+    }
+
+    /**
+     * Call safe delete for model
+     *
+     * @param \Magento\Framework\Model\AbstractModel $model
+     * @param bool $secure
+     * @return \Magento\TestFramework\TestCase\WebapiAbstract
+     */
+    public static function callModelDelete($model, $secure = false)
+    {
+        if ($model instanceof \Magento\Framework\Model\AbstractModel && $model->getId()) {
+            if ($secure) {
+                self::_enableSecureArea();
+            }
+            $model->delete();
+            if ($secure) {
+                self::_enableSecureArea(false);
+            }
+        }
+    }
+
+    /**
+     * Call safe delete for model
+     *
+     * @param \Magento\Framework\Model\AbstractModel $model
+     * @param bool $secure
+     * @return \Magento\TestFramework\TestCase\WebapiAbstract
+     */
+    public function addModelToDelete($model, $secure = false)
+    {
+        $this->_modelsToDelete[] = ['model' => $model, 'secure' => $secure];
+        return $this;
+    }
+
+    /**
+     * Get Web API adapter (create if requested one does not exist).
+     *
+     * @param string $webApiAdapterCode
+     * @return \Magento\TestFramework\TestCase\Webapi\AdapterInterface
+     * @throws \LogicException When requested Web API adapter is not declared
+     */
+    protected function _getWebApiAdapter($webApiAdapterCode)
+    {
+        if (!isset($this->_webApiAdapters[$webApiAdapterCode])) {
+            if (!isset($this->_webApiAdaptersMap[$webApiAdapterCode])) {
+                throw new \LogicException(
+                    sprintf('Declaration of the requested Web API adapter "%s" was not found.', $webApiAdapterCode)
+                );
+            }
+            $this->_webApiAdapters[$webApiAdapterCode] = new $this->_webApiAdaptersMap[$webApiAdapterCode]();
+        }
+        return $this->_webApiAdapters[$webApiAdapterCode];
+    }
+
+    /**
+     * Set fixtures namespace
+     *
+     * @throws \RuntimeException
+     */
+    protected static function _setFixtureNamespace()
+    {
+        if (!is_null(self::$_fixturesNamespace)) {
+            throw new \RuntimeException('Fixture namespace is already set.');
+        }
+        self::$_fixturesNamespace = uniqid();
+    }
+
+    /**
+     * Unset fixtures namespace
+     */
+    protected static function _unsetFixtureNamespace()
+    {
+        $fixturesNamespace = self::_getFixtureNamespace();
+        unset(self::$_fixtures[$fixturesNamespace]);
+        self::$_fixturesNamespace = null;
+    }
+
+    /**
+     * Get fixtures namespace
+     *
+     * @throws \RuntimeException
+     * @return string
+     */
+    protected static function _getFixtureNamespace()
+    {
+        $fixtureNamespace = self::$_fixturesNamespace;
+        if (is_null($fixtureNamespace)) {
+            throw new \RuntimeException('Fixture namespace must be set.');
+        }
+        return $fixtureNamespace;
+    }
+
+    /**
+     * Enable secure/admin area
+     *
+     * @param bool $flag
+     * @return void
+     */
+    protected static function _enableSecureArea($flag = true)
+    {
+        /** @var $objectManager \Magento\TestFramework\ObjectManager */
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+        $objectManager->get('Magento\Framework\Registry')->unregister('isSecureArea');
+        if ($flag) {
+            $objectManager->get('Magento\Framework\Registry')->register('isSecureArea', $flag);
+        }
+    }
+
+    /**
+     * Call delete models from list
+     *
+     * @return \Magento\TestFramework\TestCase\WebapiAbstract
+     */
+    protected function _callModelsDelete()
+    {
+        if ($this->_modelsToDelete) {
+            foreach ($this->_modelsToDelete as $key => $modelData) {
+                /** @var $model \Magento\Framework\Model\AbstractModel */
+                $model = $modelData['model'];
+                $this->callModelDelete($model, $modelData['secure']);
+                unset($this->_modelsToDelete[$key]);
+            }
+        }
+        return $this;
+    }
+
+    /**
+     * Check if all error messages are expected ones
+     *
+     * @param array $expectedMessages
+     * @param array $receivedMessages
+     */
+    protected function _assertMessagesEqual($expectedMessages, $receivedMessages)
+    {
+        foreach ($receivedMessages as $message) {
+            $this->assertContains($message, $expectedMessages, "Unexpected message: '{$message}'");
+        }
+        $expectedErrorsCount = count($expectedMessages);
+        $this->assertCount($expectedErrorsCount, $receivedMessages, 'Invalid messages quantity received');
+    }
+
+    /**
+     * Delete array of fixtures
+     *
+     * @param array $fixtures
+     */
+    protected static function _deleteFixtures($fixtures)
+    {
+        foreach ($fixtures as $fixture) {
+            self::deleteFixture($fixture, true);
+        }
+    }
+
+    /**
+     * Delete fixture by key
+     *
+     * @param string $key
+     * @param bool $secure
+     * @return void
+     */
+    public static function deleteFixture($key, $secure = false)
+    {
+        $fixturesNamespace = self::_getFixtureNamespace();
+        if (array_key_exists($key, self::$_fixtures[$fixturesNamespace])) {
+            self::callModelDelete(self::$_fixtures[$fixturesNamespace][$key], $secure);
+            unset(self::$_fixtures[$fixturesNamespace][$key]);
+        }
+    }
+
+    /** TODO: Remove methods below if not used, otherwise fix them (after having some tests implemented)*/
+
+    /**
+     * Get application cache model
+     *
+     * @return \Magento\Framework\App\Cache
+     */
+    protected function _getAppCache()
+    {
+        if (null === $this->_appCache) {
+            //set application path
+            $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+            /** @var \Magento\Framework\App\Config\ScopeConfigInterface $config */
+            $config = $objectManager->get('Magento\Framework\App\Config\ScopeConfigInterface');
+            $options = $config->getOptions();
+            $currentCacheDir = $options->getCacheDir();
+            $currentEtcDir = $options->getEtcDir();
+            /** @var Filesystem $filesystem */
+            $filesystem = $objectManager->get('Magento\Framework\Filesystem');
+            $options->setCacheDir($filesystem->getDirectoryRead(DirectoryList::CACHE)->getAbsolutePath());
+            $options->setEtcDir($filesystem->getDirectoryRead(DirectoryList::CONFIG)->getAbsolutePath());
+
+            $this->_appCache = $objectManager->get('Magento\Framework\App\Cache');
+
+            //revert paths options
+            $options->setCacheDir($currentCacheDir);
+            $options->setEtcDir($currentEtcDir);
+        }
+        return $this->_appCache;
+    }
+
+    /**
+     * Clean config cache of application
+     *
+     * @return bool
+     */
+    protected function _cleanAppConfigCache()
+    {
+        return $this->_getAppCache()->clean(\Magento\Framework\App\Config::CACHE_TAG);
+    }
+
+    /**
+     * Update application config data
+     *
+     * @param string $path              Config path with the form "section/group/node"
+     * @param string|int|null $value    Value of config item
+     * @param bool $cleanAppCache       If TRUE application cache will be refreshed
+     * @param bool $updateLocalConfig   If TRUE local config object will be updated too
+     * @param bool $restore             If TRUE config value will be restored after test run
+     * @return \Magento\TestFramework\TestCase\WebapiAbstract
+     * @throws \RuntimeException
+     */
+    protected function _updateAppConfig(
+        $path,
+        $value,
+        $cleanAppCache = true,
+        $updateLocalConfig = false,
+        $restore = false
+    ) {
+        list($section, $group, $node) = explode('/', $path);
+
+        if (!$section || !$group || !$node) {
+            throw new \RuntimeException(
+                sprintf('Config path must have view as "section/group/node" but now it "%s"', $path)
+            );
+        }
+
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var $config \Magento\Backend\Model\Config */
+        $config = $objectManager->create('Magento\Backend\Model\Config');
+        $data[$group]['fields'][$node]['value'] = $value;
+        $config->setSection($section)->setGroups($data)->save();
+
+        if ($restore && !isset($this->_origConfigValues[$path])) {
+            $this->_origConfigValues[$path] = (string)$objectManager->get(
+                'Magento\Framework\App\Config\ScopeConfigInterface'
+            )->getNode(
+                $path,
+                'default'
+            );
+        }
+
+        //refresh local cache
+        if ($cleanAppCache) {
+            if ($updateLocalConfig) {
+                $objectManager->get('Magento\Framework\App\Config\ReinitableConfigInterface')->reinit();
+                $objectManager->get('Magento\Store\Model\StoreManagerInterface')->reinitStores();
+            }
+
+            if (!$this->_cleanAppConfigCache()) {
+                throw new \RuntimeException('Application configuration cache cannot be cleaned.');
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Restore config values changed during tests
+     */
+    protected function _restoreAppConfig()
+    {
+        foreach ($this->_origConfigValues as $configPath => $origValue) {
+            $this->_updateAppConfig($configPath, $origValue, true, true);
+        }
+    }
+
+    /**
+     * @param \Exception $e
+     * @return array
+     * <pre> ex.
+     * 'message' => "No such entity with %fieldName1 = %value1, %fieldName2 = %value2"
+     * 'parameters' => [
+     *      "fieldName1" => "email",
+     *      "value1" => "dummy@example.com",
+     *      "fieldName2" => "websiteId",
+     *      "value2" => 0
+     * ]
+     *
+     * </pre>
+     */
+    public function processRestExceptionResult(\Exception $e)
+    {
+        $error = json_decode($e->getMessage(), true);
+        //Remove line breaks and replace with space
+        $error['message'] = trim(preg_replace('/\s+/', ' ', $error['message']));
+        // remove trace and type, will only be present if server is in dev mode
+        unset($error['trace']);
+        unset($error['type']);
+        return $error;
+    }
+
+    /**
+     * Verify that SOAP fault contains necessary information.
+     *
+     * @param \SoapFault $soapFault
+     * @param string $expectedMessage
+     * @param string $expectedFaultCode
+     * @param array $expectedErrorParams
+     * @param array $expectedWrappedErrors
+     * @param string $traceString
+     */
+    protected function checkSoapFault(
+        $soapFault,
+        $expectedMessage,
+        $expectedFaultCode,
+        $expectedErrorParams = [],
+        $expectedWrappedErrors = [],
+        $traceString = null
+    ) {
+        $this->assertContains($expectedMessage, $soapFault->getMessage(), "Fault message is invalid.");
+
+        $errorDetailsNode = 'GenericFault';
+        $errorDetails = isset($soapFault->detail->$errorDetailsNode) ? $soapFault->detail->$errorDetailsNode : null;
+        if (!empty($expectedErrorParams) || !empty($expectedWrappedErrors)) {
+            /** Check SOAP fault details */
+            $this->assertNotNull($errorDetails, "Details must be present.");
+            $this->_checkFaultParams($expectedErrorParams, $errorDetails);
+            $this->_checkWrappedErrors($expectedWrappedErrors, $errorDetails);
+        }
+
+        if ($traceString) {
+            /** Check error trace */
+            $traceNode = Fault::NODE_DETAIL_TRACE;
+            $mode = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\App\State')
+                ->getMode();
+            if ($mode == \Magento\Framework\App\State::MODE_DEVELOPER) {
+                /** Developer mode changes tested behavior and it cannot properly be tested for now */
+                $this->assertContains(
+                    $traceString,
+                    $errorDetails->$traceNode,
+                    'Trace Information is incorrect.'
+                );
+            } else {
+                $this->assertNull($errorDetails, "Details are not expected.");
+            }
+        }
+
+        /** Check SOAP fault code */
+        $this->assertNotNull($soapFault->faultcode, "Fault code must not be empty.");
+        $this->assertEquals($expectedFaultCode, $soapFault->faultcode, "Fault code is invalid.");
+    }
+
+    /**
+     * Check additional error parameters.
+     *
+     * @param array $expectedErrorParams
+     * @param \stdClass $errorDetails
+     */
+    protected function _checkFaultParams($expectedErrorParams, $errorDetails)
+    {
+        $paramsNode = Fault::NODE_DETAIL_PARAMETERS;
+        if ($expectedErrorParams) {
+            $paramNode = Fault::NODE_DETAIL_PARAMETER;
+            $paramKey = Fault::NODE_DETAIL_PARAMETER_KEY;
+            $paramValue = Fault::NODE_DETAIL_PARAMETER_VALUE;
+            $actualParams = [];
+            if (isset($errorDetails->$paramsNode->$paramNode)) {
+                if (is_array($errorDetails->$paramsNode->$paramNode)) {
+                    foreach ($errorDetails->$paramsNode->$paramNode as $param) {
+                        $actualParams[$param->$paramKey] = $param->$paramValue;
+                    }
+                } else {
+                    $param = $errorDetails->$paramsNode->$paramNode;
+                    $actualParams[$param->$paramKey] = $param->$paramValue;
+                }
+            }
+            $this->assertEquals(
+                $expectedErrorParams,
+                $actualParams,
+                "Parameters in fault details are invalid."
+            );
+        } else {
+            $this->assertFalse(isset($errorDetails->$paramsNode), "Parameters are not expected in fault details.");
+        }
+    }
+
+    /**
+     * Check additional wrapped errors.
+     *
+     * @param array $expectedWrappedErrors
+     * @param \stdClass $errorDetails
+     */
+    protected function _checkWrappedErrors($expectedWrappedErrors, $errorDetails)
+    {
+        $wrappedErrorsNode = Fault::NODE_DETAIL_WRAPPED_ERRORS;
+        if ($expectedWrappedErrors) {
+            $wrappedErrorNode = Fault::NODE_DETAIL_WRAPPED_ERROR;
+            $wrappedErrorNodeFieldName = 'fieldName';
+            $wrappedErrorNodeValue = Fault::NODE_DETAIL_WRAPPED_ERROR_VALUE;
+            $actualWrappedErrors = [];
+            if (isset($errorDetails->$wrappedErrorsNode->$wrappedErrorNode)) {
+                if (is_array($errorDetails->$wrappedErrorsNode->$wrappedErrorNode)) {
+                    foreach ($errorDetails->$wrappedErrorsNode->$wrappedErrorNode as $error) {
+                        $actualParameters = [];
+                        foreach ($error->parameters->parameter as $parameter) {
+                            $actualParameters[$parameter->key] = $parameter->value;
+                        }
+                        $actualWrappedErrors[] = [
+                            'message' => $error->message,
+                            'params' => $actualParameters,
+                        ];
+                    }
+                } else {
+                    $error = $errorDetails->$wrappedErrorsNode->$wrappedErrorNode;
+                    $actualWrappedErrors[] = [
+                        "fieldName" => $error->$wrappedErrorNodeFieldName,
+                        "value" => $error->$wrappedErrorNodeValue,
+                    ];
+                }
+            }
+            $this->assertEquals(
+                $expectedWrappedErrors,
+                $actualWrappedErrors,
+                "Wrapped errors in fault details are invalid."
+            );
+        } else {
+            $this->assertFalse(
+                isset($errorDetails->$wrappedErrorsNode),
+                "Wrapped errors are not expected in fault details."
+            );
+        }
+    }
+}
diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/WebApiApplication.php b/dev/tests/api-functional/framework/Magento/TestFramework/WebApiApplication.php
new file mode 100644
index 00000000000..055fa381ae2
--- /dev/null
+++ b/dev/tests/api-functional/framework/Magento/TestFramework/WebApiApplication.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\TestFramework;
+
+
+/**
+ * Provides access to the application for the tests
+ *
+ * Allows installation and uninstallation
+ */
+class WebApiApplication extends Application
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function run()
+    {
+        throw new \Exception(
+            "Can't start application: purpose of Web API Application is to use classes and models from the application"
+            . " and don't run it"
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function install()
+    {
+        $installOptions = $this->getInstallConfig();
+
+        /* Install application */
+        if ($installOptions) {
+            $installCmd = 'php -f ' . BP . '/setup/index.php install';
+            $installArgs = [];
+            foreach ($installOptions as $optionName => $optionValue) {
+                if (is_bool($optionValue)) {
+                    if (true === $optionValue) {
+                        $installCmd .= " --$optionName";
+                    }
+                    continue;
+                }
+                if (!empty($optionValue)) {
+                    $installCmd .= " --$optionName=%s";
+                    $installArgs[] = $optionValue;
+                }
+            }
+            $this->_shell->execute($installCmd, $installArgs);
+        }
+    }
+
+    /**
+     * Use the application as is
+     *
+     * {@inheritdoc}
+     */
+    protected function getCustomDirs()
+    {
+        return [];
+    }
+}
diff --git a/dev/tests/api-functional/framework/autoload.php b/dev/tests/api-functional/framework/autoload.php
new file mode 100644
index 00000000000..231e3908088
--- /dev/null
+++ b/dev/tests/api-functional/framework/autoload.php
@@ -0,0 +1,14 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+require_once __DIR__ . '/../../../../app/autoload.php';
+
+$testsBaseDir = dirname(__DIR__);
+$integrationTestsDir = realpath("{$testsBaseDir}/../integration/");
+
+$autoloadWrapper = \Magento\Framework\Autoload\AutoloaderRegistry::getAutoloader();
+$autoloadWrapper->addPsr4('Magento\\TestFramework\\', "{$testsBaseDir}/framework/Magento/TestFramework/");
+$autoloadWrapper->addPsr4('Magento\\TestFramework\\', "{$integrationTestsDir}/framework/Magento/TestFramework/");
+$autoloadWrapper->addPsr4('Magento\\', "{$testsBaseDir}/testsuite/Magento/");
diff --git a/dev/tests/api-functional/framework/bootstrap.php b/dev/tests/api-functional/framework/bootstrap.php
new file mode 100644
index 00000000000..ae037a554b2
--- /dev/null
+++ b/dev/tests/api-functional/framework/bootstrap.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+use Magento\Framework\App\Filesystem\DirectoryList;
+use Magento\Framework\Autoload\AutoloaderRegistry;
+
+require_once __DIR__ . '/../../../../app/bootstrap.php';
+require_once __DIR__ . '/autoload.php';
+
+$testsBaseDir = dirname(__DIR__);
+$integrationTestsDir = realpath("{$testsBaseDir}/../integration");
+
+$logWriter = new \Zend_Log_Writer_Stream('php://output');
+$logWriter->setFormatter(new \Zend_Log_Formatter_Simple('%message%' . PHP_EOL));
+$logger = new \Zend_Log($logWriter);
+
+/** Copy test modules to app/code/Magento to make them visible for Magento instance */
+$pathToCommittedTestModules = __DIR__ . '/../_files/Magento';
+$pathToInstalledMagentoInstanceModules = __DIR__ . '/../../../../app/code/Magento';
+$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($pathToCommittedTestModules));
+/** @var SplFileInfo $file */
+foreach ($iterator as $file) {
+    if (!$file->isDir()) {
+        $source = $file->getPathname();
+        $relativePath = substr($source, strlen($pathToCommittedTestModules));
+        $destination = $pathToInstalledMagentoInstanceModules . $relativePath;
+        $targetDir = dirname($destination);
+        if (!is_dir($targetDir)) {
+            mkdir($targetDir, 0755, true);
+        }
+        copy($source, $destination);
+    }
+}
+unset($iterator, $file);
+
+/* Bootstrap the application */
+$settings = new \Magento\TestFramework\Bootstrap\Settings($testsBaseDir, get_defined_constants());
+$shell = new \Magento\Framework\Shell(new \Magento\Framework\Shell\CommandRenderer(), $logger);
+
+$installConfigFile = $settings->getAsConfigFile('TESTS_INSTALL_CONFIG_FILE');
+if (!file_exists($installConfigFile)) {
+    $installConfigFile = $installConfigFile . '.dist';
+}
+$dirList = new \Magento\Framework\App\Filesystem\DirectoryList(BP);
+$application =  new \Magento\TestFramework\WebApiApplication(
+    $shell,
+    $dirList->getPath(DirectoryList::VAR_DIR),
+    $installConfigFile,
+    BP . '/app/etc/',
+    $settings->get('TESTS_MAGENTO_MODE'),
+    AutoloaderRegistry::getAutoloader()
+);
+
+if (defined('TESTS_MAGENTO_INSTALLATION') && TESTS_MAGENTO_INSTALLATION === 'enabled') {
+    if (defined('TESTS_CLEANUP') && TESTS_CLEANUP === 'enabled') {
+        $application->cleanup();
+    }
+    $application->install();
+}
+
+$bootstrap = new \Magento\TestFramework\Bootstrap(
+    $settings,
+    new \Magento\TestFramework\Bootstrap\Environment(),
+    new \Magento\TestFramework\Bootstrap\WebapiDocBlock("{$integrationTestsDir}/testsuite"),
+    new \Magento\TestFramework\Bootstrap\Profiler(new \Magento\Framework\Profiler\Driver\Standard()),
+    $shell,
+    $application,
+    new \Magento\TestFramework\Bootstrap\MemoryFactory($shell)
+);
+$bootstrap->runBootstrap();
+$application->initialize();
+
+\Magento\TestFramework\Helper\Bootstrap::setInstance(new \Magento\TestFramework\Helper\Bootstrap($bootstrap));
+\Magento\Framework\Test\Utility\Files::setInstance(new \Magento\Framework\Test\Utility\Files(BP));
+unset($bootstrap, $application, $settings, $shell);
diff --git a/dev/tests/api-functional/phpunit.xml.dist b/dev/tests/api-functional/phpunit.xml.dist
new file mode 100644
index 00000000000..b885beab08e
--- /dev/null
+++ b/dev/tests/api-functional/phpunit.xml.dist
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * PHPUnit configuration for Web API functional tests.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+-->
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+         colors="true"
+         bootstrap="./framework/bootstrap.php"
+>
+    <!-- Test suites definition -->
+    <testsuites>
+        <testsuite name="Magento Web API Functional Tests">
+            <directory suffix="Test.php">testsuite</directory>
+        </testsuite>
+    </testsuites>
+
+    <!-- Code coverage filters -->
+    <filter>
+        <whitelist>
+            <!-- All CE modules -->
+            <directory suffix=".php">../../app/code/Magento</directory>
+            <exclude>
+                <!-- Excluding installation and upgrade scripts -->
+                <directory>../../app/code/Magento/*/sql</directory>
+                <!-- Excluding data installation and upgrade scripts -->
+                <directory>../../app/code/Magento/*/data</directory>
+            </exclude>
+        </whitelist>
+    </filter>
+
+    <!-- PHP INI settings and constants definition -->
+    <php>
+        <includePath>./testsuite</includePath>
+        <const name="TESTS_INSTALL_CONFIG_FILE" value="config/install-config-mysql.php"/>
+        <!-- WebSerivice Type. Possible values: soap, rest -->
+        <const name="TESTS_WEB_API_ADAPTER" value="rest"/>
+        <!-- Webserver URL -->
+        <const name="TESTS_BASE_URL" value="http://magento.url"/>
+        <!-- Webserver API user -->
+        <const name="TESTS_WEBSERVICE_USER" value="admin"/>
+        <!-- Webserver API key -->
+        <const name="TESTS_WEBSERVICE_APIKEY" value="123123q"/>
+        <!-- Define if debugger should be started using XDEBUG_SESSION cookie -->
+        <const name="TESTS_XDEBUG_ENABLED" value="false"/>
+        <!-- Define XDEBUG_SESSION cookie value-->
+        <const name="TESTS_XDEBUG_SESSION" value="phpstorm" />
+        <!--Generate documentation from REST tests and put it into var/log/rest-documentation directory-->
+        <const name="GENERATE_REST_DOCUMENTATION" value="false" />
+
+        <ini name="date.timezone" value="America/Los_Angeles"/>
+        <ini name="soap.wsdl_cache_enabled" value="0" />
+
+        <!-- Semicolon-separated 'glob' patterns, that match global XML configuration files -->
+        <const name="TESTS_GLOBAL_CONFIG_DIR" value="../../../app/etc"/>
+        <!-- Whether to cleanup the application before running tests or not -->
+        <const name="TESTS_CLEANUP" value="enabled"/>
+        <!--Defines if Magento should be installed before tests execution-->
+        <const name="TESTS_MAGENTO_INSTALLATION" value="disabled"/>
+        <!-- Magento mode for tests execution. Possible values are "default", "developer" and "production". -->
+        <const name="TESTS_MAGENTO_MODE" value="default"/>
+    </php>
+
+    <!-- Test listeners -->
+    <listeners>
+        <listener class="Magento\TestFramework\Event\PhpUnit"/>
+    </listeners>
+</phpunit>
diff --git a/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductLinkManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductLinkManagementTest.php
new file mode 100644
index 00000000000..078d61a66d8
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductLinkManagementTest.php
@@ -0,0 +1,163 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Bundle\Api;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Webapi\Model\Rest\Config;
+
+class ProductLinkManagementTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    const SERVICE_NAME = 'bundleProductLinkManagementV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/bundle-products';
+
+    /**
+     * @magentoApiDataFixture Magento/Bundle/_files/product.php
+     */
+    public function testGetChildren()
+    {
+        $productSku = 'bundle-product';
+        $expected = [
+            [
+                'sku' => 'simple',
+                'position' => 0,
+                'qty' => 1,
+            ],
+        ];
+
+        $result = $this->getChildren($productSku);
+
+        $this->assertArrayHasKey(0, $result);
+        $this->assertArrayHasKey('option_id', $result[0]);
+        $this->assertArrayHasKey('is_default', $result[0]);
+        $this->assertArrayHasKey('is_defined', $result[0]);
+        $this->assertArrayHasKey('price', $result[0]);
+        $this->assertArrayHasKey('price_type', $result[0]);
+
+        unset($result[0]['option_id'], $result[0]['is_default'], $result[0]['is_defined']);
+        unset($result[0]['price'], $result[0]['price_type']);
+
+        ksort($result[0]);
+        ksort($expected[0]);
+        $this->assertEquals($expected, $result);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Bundle/_files/product.php
+     */
+    public function testRemoveChild()
+    {
+        $productSku = 'bundle-product';
+        $childSku = 'simple';
+        $optionIds = $this->getProductOptions(3);
+        $optionId = array_shift($optionIds);
+        $this->assertTrue($this->removeChild($productSku, $optionId, $childSku));
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Bundle/_files/product.php
+     * @magentoApiDataFixture Magento/Catalog/_files/product_virtual.php
+     */
+    public function testAddChild()
+    {
+        $productSku = 'bundle-product';
+        $children = $this->getChildren($productSku);
+
+        $optionId = $children[0]['option_id'];
+
+        $linkedProduct = [
+            'sku' => 'virtual-product',
+            'option_id' => $optionId,
+            'position' => '1',
+            'is_default' => 1,
+            'priceType' => 2,
+            'price' => 151.34,
+            'qty' => 8,
+            'can_change_quantity' => 1,
+        ];
+
+        $childId = $this->addChild($productSku, $optionId, $linkedProduct);
+        $this->assertGreaterThan(0, $childId);
+    }
+
+    /**
+     * @param string $productSku
+     * @param int $optionId
+     * @param array $linkedProduct
+     * @return string
+     */
+    private function addChild($productSku, $optionId, $linkedProduct)
+    {
+        $resourcePath = self::RESOURCE_PATH . '/:productSku/links/:optionId';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => str_replace(
+                    [':productSku', ':optionId'],
+                    [$productSku, $optionId],
+                    $resourcePath
+                ),
+                'httpMethod' => Config::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'AddChildByProductSku',
+            ],
+        ];
+        return $this->_webApiCall(
+            $serviceInfo,
+            ['productSku' => $productSku, 'optionId' => $optionId, 'linkedProduct' => $linkedProduct]
+        );
+    }
+
+    protected function getProductOptions($productId)
+    {
+        /** @var \Magento\Catalog\Model\Product $product */
+        $product = Bootstrap::getObjectManager()->get('Magento\Catalog\Model\Product');
+        $product->load($productId);
+        /** @var  \Magento\Bundle\Model\Product\Type $type */
+        $type = Bootstrap::getObjectManager()->get('Magento\Bundle\Model\Product\Type');
+        return $type->getOptionsIds($product);
+    }
+
+    protected function removeChild($productSku, $optionId, $childSku)
+    {
+        $resourcePath = self::RESOURCE_PATH . '/%s/option/%s/child/%s';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => sprintf($resourcePath, $productSku, $optionId, $childSku),
+                'httpMethod' => Config::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'removeChild',
+            ],
+        ];
+        $requestData = ['productSku' => $productSku, 'optionId' => $optionId, 'childSku' => $childSku];
+        return $this->_webApiCall($serviceInfo, $requestData);
+    }
+
+    /**
+     * @param string $productSku
+     * @return string
+     */
+    protected function getChildren($productSku)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $productSku . '/children',
+                'httpMethod' => Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'getChildren',
+            ],
+        ];
+        return $this->_webApiCall($serviceInfo, ['productId' => $productSku]);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductOptionRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductOptionRepositoryTest.php
new file mode 100644
index 00000000000..2b35e1c4ff5
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductOptionRepositoryTest.php
@@ -0,0 +1,267 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Bundle\Api;
+
+use Magento\Webapi\Model\Rest\Config;
+
+class ProductOptionRepositoryTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    const SERVICE_NAME = 'bundleProductOptionRepositoryV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/bundle-products/:productSku/option';
+
+    /**
+     * @magentoApiDataFixture Magento/Bundle/_files/product.php
+     */
+    public function testGet()
+    {
+        $productSku = 'bundle-product';
+        $expected = [
+            'required' => true,
+            'position' => 0,
+            'type' => 'select',
+            'title' => 'Bundle Product Items',
+            'sku' => $productSku,
+            'product_links' => [
+                [
+                    'sku' => 'simple',
+                    'qty' => 1,
+                    'position' => 0,
+                    'is_defined' => true,
+                    'is_default' => false,
+                    'price' => null,
+                    'price_type' => null,
+                ],
+            ],
+        ];
+        $optionId = $this->getList($productSku)[0]['option_id'];
+        $result = $this->get($productSku, $optionId);
+
+        $this->assertArrayHasKey('option_id', $result);
+        $expected['product_links'][0]['option_id'] = $result['option_id'];
+        unset($result['option_id']);
+
+        ksort($expected);
+        ksort($result);
+        $this->assertEquals($expected, $result);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Bundle/_files/product.php
+     */
+    public function testGetList()
+    {
+        $productSku = 'bundle-product';
+        $expected = [
+            [
+                'required' => true,
+                'position' => 0,
+                'type' => 'select',
+                'title' => 'Bundle Product Items',
+                'sku' => $productSku,
+                'product_links' => [
+                    [
+                        'sku' => 'simple',
+                        'qty' => 1,
+                        'position' => 0,
+                        'is_defined' => true,
+                        'is_default' => false,
+                        'price' => null,
+                        'price_type' => null,
+                    ],
+                ],
+            ],
+        ];
+        $result = $this->getList($productSku);
+
+        $this->assertArrayHasKey(0, $result);
+        $this->assertArrayHasKey('option_id', $result[0]);
+        $expected[0]['product_links'][0]['option_id'] = $result[0]['option_id'];
+        unset($result[0]['option_id']);
+
+        ksort($expected[0]);
+        ksort($result[0]);
+        $this->assertEquals($expected, $result);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Bundle/_files/product.php
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     */
+    public function testRemove()
+    {
+        $productSku = 'bundle-product';
+
+        $optionId = $this->getList($productSku)[0]['option_id'];
+        $result = $this->remove($productSku, $optionId);
+
+        $this->assertTrue($result);
+
+        try {
+            $this->get($productSku, $optionId);
+        } catch (\Exception $e) {
+            throw new \Magento\Framework\Exception\NoSuchEntityException();
+        }
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Bundle/_files/product.php
+     */
+    public function testAdd()
+    {
+        $productSku = 'bundle-product';
+        $request = [
+            'required' => true,
+            'position' => 0,
+            'type' => 'select',
+            'title' => 'test product',
+            'product_links' => [],
+            'sku' => $productSku,
+        ];
+
+        $optionId = $this->add($request);
+        $this->assertGreaterThan(0, $optionId);
+        $result = $this->get($productSku, $optionId);
+
+        $this->assertArrayHasKey('option_id', $result);
+        $this->assertArrayHasKey('sku', $result);
+        unset($result['option_id']);
+
+        ksort($result);
+        ksort($request);
+        $this->assertEquals($request, $result);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Bundle/_files/product.php
+     */
+    public function testUpdate()
+    {
+        $productSku = 'bundle-product';
+        $request = [
+            'title' => 'someTitle',
+            'sku' => $productSku,
+        ];
+
+        $optionId = $this->getList($productSku)[0]['option_id'];
+        $result = $this->update($optionId, $request);
+
+        $this->assertEquals($result, $optionId);
+
+        $result = $this->get($productSku, $optionId);
+
+        $this->assertCount(7, $result);
+        $this->assertArrayHasKey('title', $result);
+        $this->assertEquals($request['title'], $result['title']);
+    }
+
+    /**
+     * @param int $optionId
+     * @param array $option
+     * @return string
+     */
+    protected function update($optionId, $option)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/bundle-products/option/' . $optionId,
+                'httpMethod' => Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => 'bundleProductOptionManagementV1',
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'bundleProductOptionManagementV1Save',
+            ],
+        ];
+
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            $option['optionId'] = $optionId;
+        }
+        return $this->_webApiCall($serviceInfo, ['option' => $option]);
+    }
+
+    /**
+     * @param array $option
+     * @return string
+     */
+    protected function add($option)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/bundle-products/option/add',
+                'httpMethod' => Config::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => 'bundleProductOptionManagementV1',
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'bundleProductOptionManagementV1Save',
+            ],
+        ];
+        return $this->_webApiCall($serviceInfo, ['option' => $option]);
+    }
+
+    /**
+     * @param string $productSku
+     * @param int $optionId
+     * @return string
+     */
+    protected function remove($productSku, $optionId)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => str_replace(':productSku', $productSku, self::RESOURCE_PATH) . '/' . $optionId,
+                'httpMethod' => Config::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'DeleteById',
+            ],
+        ];
+        return $this->_webApiCall($serviceInfo, ['productSku' => $productSku, 'optionId' => $optionId]);
+    }
+
+    /**
+     * @param string $productSku
+     * @return string
+     */
+    protected function getList($productSku)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => str_replace(':productSku', $productSku, self::RESOURCE_PATH) . '/all',
+                'httpMethod' => Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetList',
+            ],
+        ];
+        return $this->_webApiCall($serviceInfo, ['productSku' => $productSku]);
+    }
+
+    /**
+     * @param string $productSku
+     * @param int $optionId
+     * @return string
+     */
+    protected function get($productSku, $optionId)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => str_replace(':productSku', $productSku, self::RESOURCE_PATH) . '/' . $optionId,
+                'httpMethod' => Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Get',
+            ],
+        ];
+        return $this->_webApiCall($serviceInfo, ['productSku' => $productSku, 'optionId' => $optionId]);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductOptionTypeListTest.php b/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductOptionTypeListTest.php
new file mode 100644
index 00000000000..4d4be9a704c
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductOptionTypeListTest.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Bundle\Api;
+
+use Magento\Webapi\Model\Rest\Config;
+
+class ProductOptionTypeListTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    const SERVICE_READ_NAME = 'bundleProductOptionTypeListV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/bundle-products/option/types';
+
+    public function testGetTypes()
+    {
+        $expected = [
+            ['label' => 'Drop-down', 'code' => 'select'],
+            ['label' => 'Radio Buttons', 'code' => 'radio'],
+            ['label' => 'Checkbox', 'code' => 'checkbox'],
+            ['label' => 'Multiple Select', 'code' => 'multi'],
+        ];
+        $result = $this->getTypes();
+
+        $this->assertEquals($expected, $result);
+    }
+
+    /**
+     * @return string
+     */
+    protected function getTypes()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'getItems',
+            ],
+        ];
+        return $this->_webApiCall($serviceInfo);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductServiceTest.php
new file mode 100644
index 00000000000..68db7d52109
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Bundle/Api/ProductServiceTest.php
@@ -0,0 +1,170 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Bundle\Api;
+
+use Magento\Catalog\Api\Data\ProductInterface;
+use Magento\Framework\Api\AbstractExtensibleObject;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+/**
+ * Class ProductServiceTest for testing Bundle Product API
+ */
+class ProductServiceTest extends WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogProductRepositoryV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/products';
+
+    /**
+     * @var \Magento\Catalog\Model\Resource\Product\Collection
+     */
+    protected $productCollection;
+
+    /**
+     * Execute per test initialization
+     */
+    public function setUp()
+    {
+        $objectManager = Bootstrap::getObjectManager();
+        $this->productCollection = $objectManager->get('Magento\Catalog\Model\Resource\Product\Collection');
+    }
+
+    /**
+     * Execute per test cleanup
+     */
+    public function tearDown()
+    {
+        /** @var \Magento\Framework\Registry $registry */
+        $registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry');
+
+        $registry->unregister('isSecureArea');
+        $registry->register('isSecureArea', true);
+
+        $this->productCollection->addFieldToFilter(
+            'sku',
+            ['in' => ['sku-test-product-bundle']]
+        )->delete();
+        unset($this->productCollection);
+
+        $registry->unregister('isSecureArea');
+        $registry->register('isSecureArea', false);
+        parent::tearDown();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/products_new.php
+     */
+    public function testCreateBundle()
+    {
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            $this->markTestIncomplete('MAGETWO-31016: incompatible with ZF 1.12.9');
+        }
+        $bundleProductOptions = [
+            "attribute_code" => "bundle_product_options",
+            "value" => [
+                [
+                    "title" => "test option",
+                    "type" => "checkbox",
+                    "required" => 1,
+                    "product_links" => [
+                        [
+                            "sku" => 'simple',
+                            "qty" => 1,
+                        ],
+                    ],
+                ],
+            ],
+        ];
+
+        $uniqueId = 'sku-test-product-bundle';
+        $product = [
+            "sku" => $uniqueId,
+            "name" => $uniqueId,
+            "type_id" => "bundle",
+            "price" => 50,
+            'attribute_set_id' => 4,
+            "custom_attributes" => [
+                "price_type" => [
+                    'attribute_code' => 'price_type',
+                    'value' => \Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC
+                ],
+                "bundle_product_options" => $bundleProductOptions,
+                "price_view" => [
+                    "attribute_code" => "price_view",
+                    "value" => "test",
+                ],
+            ],
+        ];
+
+        $response = $this->createProduct($product);
+
+        $this->assertEquals($uniqueId, $response[ProductInterface::SKU]);
+        $this->assertEquals(
+            $bundleProductOptions,
+            $response[AbstractExtensibleObject::CUSTOM_ATTRIBUTES_KEY]["bundle_product_options"]
+        );
+
+        $response = $this->getProduct($uniqueId);
+        $foundBundleProductOptions = false;
+        foreach ($response[AbstractExtensibleObject::CUSTOM_ATTRIBUTES_KEY] as $customAttribute) {
+            if ($customAttribute["attribute_code"] === 'bundle_product_options') {
+                $this->assertEquals('simple', $customAttribute["value"][0]["product_links"][0]["sku"]);
+                $foundBundleProductOptions = true;
+            }
+        }
+        $this->assertTrue($foundBundleProductOptions);
+    }
+
+    /**
+     * Get product
+     *
+     * @param string $productSku
+     * @return array the product data
+     */
+    protected function getProduct($productSku)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $productSku,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Get',
+            ],
+        ];
+
+        $response = (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) ?
+            $this->_webApiCall($serviceInfo, ['productSku' => $productSku]) : $this->_webApiCall($serviceInfo);
+
+        return $response;
+    }
+
+    /**
+     * Create product
+     *
+     * @param array $product
+     * @return array the created product data
+     */
+    protected function createProduct($product)
+    {
+        $serviceInfo = [
+            'rest' => ['resourcePath' => self::RESOURCE_PATH, 'httpMethod' => RestConfig::HTTP_METHOD_POST],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $requestData = ['product' => $product];
+        $response = $this->_webApiCall($serviceInfo, $requestData);
+        $product[ProductInterface::SKU] = $response[ProductInterface::SKU];
+        return $product;
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/AttributeSetManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/AttributeSetManagementTest.php
new file mode 100644
index 00000000000..34dd1076b88
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/AttributeSetManagementTest.php
@@ -0,0 +1,221 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Api;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Exception as HTTPExceptionCodes;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class AttributeSetManagementTest extends WebapiAbstract
+{
+    /**
+     * @var array
+     */
+    private $createServiceInfo;
+
+    protected function setUp()
+    {
+        $this->createServiceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/attribute-sets',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => 'catalogAttributeSetManagementV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'catalogAttributeSetManagementV1Create',
+            ],
+        ];
+    }
+
+    public function testCreate()
+    {
+        $entityTypeCode = 'catalog_product';
+        $entityType = $this->getEntityTypeByCode($entityTypeCode);
+        $attributeSetName = 'new_attribute_set';
+
+        $arguments = [
+            'attributeSet' => [
+                'attribute_set_name' => $attributeSetName,
+                'sort_order' => 500,
+            ],
+            'skeletonId' => $entityType->getDefaultAttributeSetId(),
+        ];
+        $result = $this->_webApiCall($this->createServiceInfo, $arguments);
+        $this->assertNotNull($result);
+        $attributeSet = $this->getAttributeSetByName($attributeSetName);
+        $this->assertNotNull($attributeSet);
+        $this->assertEquals($attributeSet->getId(), $result['attribute_set_id']);
+        $this->assertEquals($attributeSet->getAttributeSetName(), $result['attribute_set_name']);
+        $this->assertEquals($attributeSet->getEntityTypeId(), $result['entity_type_id']);
+        $this->assertEquals($attributeSet->getEntityTypeId(), $entityType->getId());
+        $this->assertEquals($attributeSet->getSortOrder(), $result['sort_order']);
+        $this->assertEquals($attributeSet->getSortOrder(), 500);
+
+        // Clean up database
+        $attributeSet->delete();
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Invalid value
+     */
+    public function testCreateThrowsExceptionIfGivenAttributeSetAlreadyHasId()
+    {
+        $entityTypeCode = 'catalog_product';
+        $entityType = $this->getEntityTypeByCode($entityTypeCode);
+        $attributeSetName = 'new_attribute_set';
+
+        $arguments = [
+            'attributeSet' => [
+                'attribute_set_id' => 1,
+                'attribute_set_name' => $attributeSetName,
+                'sort_order' => 100,
+            ],
+            'skeletonId' => $entityType->getDefaultAttributeSetId(),
+        ];
+        $this->_webApiCall($this->createServiceInfo, $arguments);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Can not create attribute set based on not existing attribute set
+     */
+    public function testCreateThrowsExceptionIfGivenSkeletonIdIsInvalid()
+    {
+        $attributeSetName = 'new_attribute_set';
+        $arguments = [
+            'attributeSet' => [
+                'attribute_set_name' => $attributeSetName,
+                'sort_order' => 200,
+            ],
+            'skeletonId' => 0,
+        ];
+        $this->_webApiCall($this->createServiceInfo, $arguments);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Can not create attribute set based on non product attribute set.
+     */
+    public function testCreateThrowsExceptionIfGivenSkeletonIdHasWrongEntityType()
+    {
+        $attributeSetName = 'new_attribute_set';
+        $arguments = [
+            'attributeSet' => [
+                'attribute_set_name' => $attributeSetName,
+                'sort_order' => 200,
+            ],
+            'skeletonId' => 7,
+        ];
+        $this->_webApiCall($this->createServiceInfo, $arguments);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Can not create attribute set based on not existing attribute set
+     */
+    public function testCreateThrowsExceptionIfGivenSkeletonAttributeSetDoesNotExist()
+    {
+        $attributeSetName = 'new_attribute_set';
+        $arguments = [
+            'attributeSet' => [
+                'attribute_set_name' => $attributeSetName,
+                'sort_order' => 300,
+            ],
+            'skeletonId' => 9999,
+        ];
+        $this->_webApiCall($this->createServiceInfo, $arguments);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Attribute set name is empty.
+     */
+    public function testCreateThrowsExceptionIfAttributeSetNameIsEmpty()
+    {
+        $entityTypeCode = 'catalog_product';
+        $entityType = $this->getEntityTypeByCode($entityTypeCode);
+        $attributeSetName = '';
+
+        $arguments = [
+            'attributeSet' => [
+                'attribute_set_name' => $attributeSetName,
+                'sort_order' => 500,
+            ],
+            'skeletonId' => $entityType->getDefaultAttributeSetId(),
+        ];
+        $this->_webApiCall($this->createServiceInfo, $arguments);
+    }
+
+    public function testCreateThrowsExceptionIfAttributeSetWithGivenNameAlreadyExists()
+    {
+        $entityTypeCode = 'catalog_product';
+        $entityType = $this->getEntityTypeByCode($entityTypeCode);
+        $attributeSetName = 'Default';
+        $expectedMessage = 'An attribute set with the "Default" name already exists.';
+
+        $arguments = [
+            'attributeSet' => [
+                'attribute_set_name' => $attributeSetName,
+                'sort_order' => 550,
+            ],
+            'skeletonId' => $entityType->getDefaultAttributeSetId(),
+        ];
+
+        try {
+            $this->_webApiCall($this->createServiceInfo, $arguments);
+            $this->fail("Expected exception");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "SoapFault does not contain expected message."
+            );
+        } catch (\Exception $e) {
+            $errorObj = $this->processRestExceptionResult($e);
+            $this->assertEquals(
+                $expectedMessage,
+                $errorObj['message']
+            );
+            $this->assertEquals(HTTPExceptionCodes::HTTP_BAD_REQUEST, $e->getCode());
+        }
+    }
+
+    /**
+     * Retrieve attribute set based on given name.
+     * This utility methods assumes that there is only one attribute set with given name,
+     *
+     * @param string $attributeSetName
+     * @return \Magento\Eav\Model\Entity\Attribute\Set|null
+     */
+    protected function getAttributeSetByName($attributeSetName)
+    {
+        $objectManager = Bootstrap::getObjectManager();
+        /** @var \Magento\Eav\Model\Entity\Attribute\Set $attributeSet */
+        $attributeSet = $objectManager->create('Magento\Eav\Model\Entity\Attribute\Set')
+            ->load($attributeSetName, 'attribute_set_name');
+        if ($attributeSet->getId() === null) {
+            return null;
+        }
+        return $attributeSet;
+    }
+
+    /**
+     * Retrieve entity type based on given code.
+     *
+     * @param string $entityTypeCode
+     * @return \Magento\Eav\Model\Entity\Type|null
+     */
+    protected function getEntityTypeByCode($entityTypeCode)
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var \Magento\Eav\Model\Entity\Type $entityType */
+        $entityType = $objectManager->create('Magento\Eav\Model\Config')
+            ->getEntityType($entityTypeCode);
+        return $entityType;
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/AttributeSetRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/AttributeSetRepositoryTest.php
new file mode 100644
index 00000000000..7b2bb1d5b2e
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/AttributeSetRepositoryTest.php
@@ -0,0 +1,228 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Api;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class AttributeSetRepositoryTest extends WebapiAbstract
+{
+    /**
+     * @magentoApiDataFixture Magento/Eav/_files/empty_attribute_set.php
+     */
+    public function testGet()
+    {
+        $attributeSetName = 'empty_attribute_set';
+        $attributeSet = $this->getAttributeSetByName($attributeSetName);
+        $attributeSetId = $attributeSet->getId();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/attribute-sets/' . $attributeSetId,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => 'catalogAttributeSetRepositoryV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'catalogAttributeSetRepositoryV1Get',
+            ],
+        ];
+        $arguments = [
+            'attributeSetId' => $attributeSetId,
+        ];
+        $result = $this->_webApiCall($serviceInfo, $arguments);
+        $this->assertNotNull($result);
+        $this->assertEquals($attributeSet->getId(), $result['attribute_set_id']);
+        $this->assertEquals($attributeSet->getAttributeSetName(), $result['attribute_set_name']);
+        $this->assertEquals($attributeSet->getEntityTypeId(), $result['entity_type_id']);
+        $this->assertEquals($attributeSet->getSortOrder(), $result['sort_order']);
+    }
+
+    /**
+     * @expectedException \Exception
+     */
+    public function testGetThrowsExceptionIfRequestedAttributeSetDoesNotExist()
+    {
+        $attributeSetId = 9999;
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/attribute-sets/' . $attributeSetId,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => 'catalogAttributeSetRepositoryV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'catalogAttributeSetRepositoryV1Get',
+            ],
+        ];
+        $arguments = [
+            'attributeSetId' => $attributeSetId,
+        ];
+        $this->_webApiCall($serviceInfo, $arguments);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Eav/_files/empty_attribute_set.php
+     */
+    public function testSave()
+    {
+        $attributeSetName = 'empty_attribute_set';
+        $attributeSet = $this->getAttributeSetByName($attributeSetName);
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/attribute-sets/' . $attributeSet->getId(),
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => 'catalogAttributeSetRepositoryV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'catalogAttributeSetRepositoryV1Save',
+            ],
+        ];
+
+        $updatedSortOrder = $attributeSet->getSortOrder() + 200;
+
+        $arguments = [
+            'attributeSet' => [
+                'attribute_set_id' => $attributeSet->getId(),
+                // name is the same, because it is used by fixture rollback script
+                'attribute_set_name' => $attributeSet->getAttributeSetName(),
+                'entity_type_id' => $attributeSet->getEntityTypeId(),
+                'sort_order' => $updatedSortOrder,
+            ],
+        ];
+        $result = $this->_webApiCall($serviceInfo, $arguments);
+        $this->assertNotNull($result);
+        // Reload attribute set data
+        $attributeSet = $this->getAttributeSetByName($attributeSetName);
+        $this->assertEquals($attributeSet->getAttributeSetId(), $result['attribute_set_id']);
+        $this->assertEquals($attributeSet->getAttributeSetName(), $result['attribute_set_name']);
+        $this->assertEquals($attributeSet->getEntityTypeId(), $result['entity_type_id']);
+        $this->assertEquals($updatedSortOrder, $result['sort_order']);
+        $this->assertEquals($attributeSet->getSortOrder(), $result['sort_order']);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Eav/_files/empty_attribute_set.php
+     */
+    public function testDeleteById()
+    {
+        $attributeSetName = 'empty_attribute_set';
+        $attributeSet = $this->getAttributeSetByName($attributeSetName);
+        $attributeSetId = $attributeSet->getId();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/attribute-sets/' . $attributeSetId,
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => 'catalogAttributeSetRepositoryV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'catalogAttributeSetRepositoryV1DeleteById',
+            ],
+        ];
+
+        $arguments = [
+            'attributeSetId' => $attributeSetId,
+        ];
+        $this->assertTrue($this->_webApiCall($serviceInfo, $arguments));
+        $this->assertNull($this->getAttributeSetByName($attributeSetName));
+    }
+
+    /**
+     * @expectedException \Exception
+     */
+    public function testDeleteByIdThrowsExceptionIfRequestedAttributeSetDoesNotExist()
+    {
+        $attributeSetId = 9999;
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/attribute-sets/' . $attributeSetId,
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => 'catalogAttributeSetRepositoryV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'catalogAttributeSetRepositoryV1DeleteById',
+            ],
+        ];
+
+        $arguments = [
+            'attributeSetId' => $attributeSetId,
+        ];
+        $this->_webApiCall($serviceInfo, $arguments);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Eav/_files/empty_attribute_set.php
+     */
+    public function testGetList()
+    {
+        $searchCriteria = [
+            'searchCriteria' => [
+                'filter_groups' => [
+                    [
+                        'filters' => [
+                            [
+                                'field' => 'entity_type_code',
+                                'value' => 'catalog_product',
+                                'condition_type' => 'eq',
+                            ],
+                        ],
+                    ],
+                ],
+                'current_page' => 1,
+                'page_size' => 2,
+            ],
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/attribute-sets/sets/list',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => 'catalogAttributeSetRepositoryV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'catalogAttributeSetRepositoryV1GetList',
+            ],
+        ];
+
+        $response = $this->_webApiCall($serviceInfo, $searchCriteria);
+
+        $this->assertArrayHasKey('search_criteria', $response);
+        $this->assertArrayHasKey('total_count', $response);
+        $this->assertArrayHasKey('items', $response);
+
+        $this->assertEquals($searchCriteria['searchCriteria'], $response['search_criteria']);
+        $this->assertTrue($response['total_count'] > 0);
+        $this->assertTrue(count($response['items']) > 0);
+
+        $this->assertNotNull($response['items'][0]['attribute_set_id']);
+        $this->assertNotNull($response['items'][0]['attribute_set_name']);
+    }
+
+    /**
+     * Retrieve attribute set based on given name.
+     * This utility methods assumes that there is only one attribute set with given name,
+     *
+     * @param string $attributeSetName
+     * @return \Magento\Eav\Model\Entity\Attribute\Set|null
+     */
+    protected function getAttributeSetByName($attributeSetName)
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var \Magento\Eav\Model\Entity\Attribute\Set $attributeSet */
+        $attributeSet = $objectManager->create('Magento\Eav\Model\Entity\Attribute\Set')
+            ->load($attributeSetName, 'attribute_set_name');
+        if ($attributeSet->getId() === null) {
+            return null;
+        }
+        return $attributeSet;
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryAttributeOptionManagementInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryAttributeOptionManagementInterfaceTest.php
new file mode 100644
index 00000000000..d7540f1b3a3
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryAttributeOptionManagementInterfaceTest.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Api;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class CategoryAttributeOptionManagementInterfaceTest extends WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogCategoryAttributeOptionManagementV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/categories/attributes';
+
+    public function testGetItems()
+    {
+        $testAttributeCode = 'include_in_menu';
+        $expectedOptions = [
+            [
+                    'label' => 'Yes',
+                    'value' => '1',
+            ],
+            [
+                    'label' => 'No',
+                    'value' => '0',
+            ],
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $testAttributeCode . '/options',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'getItems',
+            ],
+        ];
+
+        $response = $this->_webApiCall($serviceInfo, ['attributeCode' => $testAttributeCode]);
+
+        $this->assertTrue(is_array($response));
+        $this->assertEquals($expectedOptions, $response);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryAttributeRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryAttributeRepositoryTest.php
new file mode 100644
index 00000000000..a2065079711
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryAttributeRepositoryTest.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Api;
+
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class CategoryAttributeRepositoryTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogCategoryAttributeRepositoryV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/categories/attributes';
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/category_attribute.php
+     */
+    public function testGet()
+    {
+        $attributeCode = 'test_attribute_code_666';
+        $attribute = $this->getAttribute($attributeCode);
+
+        $this->assertTrue(is_array($attribute));
+        $this->assertArrayHasKey('attribute_id', $attribute);
+        $this->assertArrayHasKey('attribute_code', $attribute);
+        $this->assertEquals($attributeCode, $attribute['attribute_code']);
+    }
+
+    public function testGetList()
+    {
+        $searchCriteria = [
+            'searchCriteria' => [
+                'filter_groups' => [
+                    [
+                        'filters' => [
+                            [
+                                'field' => 'frontend_input',
+                                'value' => 'text',
+                                'condition_type' => 'eq',
+                            ],
+                        ],
+                    ],
+                ],
+                'current_page' => 1,
+                'page_size' => 2,
+            ],
+            'entityTypeCode' => \Magento\Catalog\Api\Data\CategoryAttributeInterface::ENTITY_TYPE_CODE,
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetList',
+            ],
+        ];
+
+        $response = $this->_webApiCall($serviceInfo, $searchCriteria);
+
+        $this->assertArrayHasKey('search_criteria', $response);
+        $this->assertArrayHasKey('total_count', $response);
+        $this->assertArrayHasKey('items', $response);
+
+        $this->assertEquals($searchCriteria['searchCriteria'], $response['search_criteria']);
+        $this->assertTrue($response['total_count'] > 0);
+        $this->assertTrue(count($response['items']) > 0);
+
+        $this->assertNotNull($response['items'][0]['default_frontend_label']);
+        $this->assertNotNull($response['items'][0]['attribute_id']);
+    }
+
+    /**
+     * @param $attributeCode
+     * @return array|bool|float|int|string
+     */
+    protected function getAttribute($attributeCode)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $attributeCode,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Get',
+            ],
+        ];
+        return $this->_webApiCall($serviceInfo, ['attributeCode' => $attributeCode]);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryLinkManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryLinkManagementTest.php
new file mode 100644
index 00000000000..fc64e880b64
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryLinkManagementTest.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Api;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+class CategoryLinkManagementTest extends WebapiAbstract
+{
+    const SERVICE_WRITE_NAME = 'catalogCategoryLinkManagementV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH_SUFFIX = '/V1/categories';
+    const RESOURCE_PATH_PREFIX = 'products';
+
+    private $modelId = 333;
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/category_product.php
+     */
+    public function testAssignedProducts()
+    {
+        $expected = [
+            [
+                'sku' => 'simple333',
+                'position' => '1',
+                'category_id' => '333',
+            ],
+        ];
+        $result = $this->getAssignedProducts($this->modelId);
+
+        $this->assertEquals($expected, $result);
+    }
+
+    public function testInfoNoSuchEntityException()
+    {
+        try {
+            $this->getAssignedProducts(-1);
+        } catch (\Exception $e) {
+            $this->assertContains('No such entity with %fieldName = %fieldValue', $e->getMessage());
+        }
+    }
+
+    /**
+     * @param int $id category id
+     * @return string
+     */
+    protected function getAssignedProducts($id)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH_SUFFIX . '/' . $id . '/' . self::RESOURCE_PATH_PREFIX,
+                'httpMethod' => Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_WRITE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_WRITE_NAME . 'GetAssignedProducts',
+            ],
+        ];
+        return $this->_webApiCall($serviceInfo, ['categoryId' => $id]);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryLinkRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryLinkRepositoryTest.php
new file mode 100644
index 00000000000..99ecffa03a0
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryLinkRepositoryTest.php
@@ -0,0 +1,149 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Api;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+class CategoryLinkRepositoryTest extends WebapiAbstract
+{
+    const SERVICE_WRITE_NAME = 'catalogCategoryLinkRepositoryV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH_SUFFIX = '/V1/categories';
+    const RESOURCE_PATH_PREFIX = 'products';
+
+    private $categoryId = 333;
+
+    /**
+     * @dataProvider saveDataProvider
+     * @magentoApiDataFixture Magento/Catalog/_files/products_in_category.php
+     * @param int $productId
+     * @param string[] $productLink
+     * @param int $productPosition
+     */
+    public function testSave($productLink, $productId, $productPosition = 0)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH_SUFFIX
+                    . '/' . $this->categoryId . '/' . self::RESOURCE_PATH_PREFIX,
+                'httpMethod' => Config::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_WRITE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_WRITE_NAME . 'Save',
+            ],
+        ];
+        $result = $this->_webApiCall($serviceInfo, ['productLink' => $productLink]);
+        $this->assertTrue($result);
+        $this->assertTrue($this->isProductInCategory($this->categoryId, $productId, $productPosition));
+    }
+
+    public function saveDataProvider()
+    {
+        return [
+            [
+                ['sku' => 'simple_with_cross', 'position' => 7, 'category_id' => $this->categoryId],
+                334,
+                7,
+            ],
+            [
+                ['sku' => 'simple_with_cross', 'category_id' => $this->categoryId],
+                334,
+                0
+            ],
+        ];
+    }
+
+    /**
+     * @dataProvider updateProductProvider
+     * @magentoApiDataFixture Magento/Catalog/_files/products_in_category.php
+     * @param int $productId
+     * @param string[] $productLink
+     * @param int $productPosition
+     */
+    public function testUpdateProduct($productLink, $productId, $productPosition = 0)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH_SUFFIX
+                    . '/' . $this->categoryId . '/' . self::RESOURCE_PATH_PREFIX,
+                'httpMethod' => Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_WRITE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_WRITE_NAME . 'Save',
+            ],
+        ];
+        $result = $this->_webApiCall($serviceInfo, ['productLink' => $productLink]);
+        $this->assertTrue($result);
+        $this->assertFalse($this->isProductInCategory($this->categoryId, $productId, $productPosition));
+    }
+
+    public function updateProductProvider()
+    {
+        return [
+            [
+                ['sku' => 'simple_with_cross', 'position' => 7, 'categoryId' => $this->categoryId],
+                333,
+                4,
+            ],
+            [
+                ['sku' => 'simple_with_cross', 'categoryId' => $this->categoryId],
+                333,
+                0
+            ],
+        ];
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/products_in_category.php
+     */
+    public function testDelete()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH_SUFFIX . '/' . $this->categoryId .
+                    '/' . self::RESOURCE_PATH_PREFIX . '/simple',
+                'httpMethod' => Config::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_WRITE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_WRITE_NAME . 'DeleteByIds',
+            ],
+        ];
+        $result = $this->_webApiCall(
+            $serviceInfo,
+            ['productSku' => 'simple', 'categoryId' => $this->categoryId]
+        );
+        $this->assertTrue($result);
+        $this->assertFalse($this->isProductInCategory($this->categoryId, 333, 10));
+    }
+
+    /**
+     * @param int $categoryId
+     * @param int $productId
+     * @param int $productPosition
+     * @return bool
+     */
+    private function isProductInCategory($categoryId, $productId, $productPosition)
+    {
+        /** @var \Magento\Catalog\Api\CategoryRepositoryInterface $categoryLoader */
+        $categoryLoader = Bootstrap::getObjectManager()->create('Magento\Catalog\Api\CategoryRepositoryInterface');
+        $category = $categoryLoader->get($categoryId);
+        $productsPosition = $category->getProductsPosition();
+
+        if (isset($productsPosition[$productId]) && $productsPosition[$productId] == $productPosition) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryManagementTest.php
new file mode 100644
index 00000000000..eaa58bae0e5
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryManagementTest.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Api;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\ObjectManager;
+
+class CategoryManagementTest extends WebapiAbstract
+{
+    const RESOURCE_PATH = '/V1/categories';
+
+    const SERVICE_NAME = 'catalogCategoryManagementV1';
+
+    /**
+     * @dataProvider treeDataProvider
+     * @magentoApiDataFixture Magento/Catalog/_files/category_tree.php
+     */
+    public function testTree($rootCategoryId, $depth, $expectedLevel, $expectedId)
+    {
+        $requestData = ['rootCategoryId' => $rootCategoryId, 'depth' => $depth];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '?' . http_build_query($requestData),
+                'httpMethod' => Config::HTTP_METHOD_GET
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => 'V1',
+                'operation' => self::SERVICE_NAME . 'GetTree'
+            ]
+        ];
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+
+        for($i = 0; $i < $expectedLevel; $i++) {
+            $result = $result['children_data'][0];
+        }
+        $this->assertEquals($expectedId, $result['id']);
+        $this->assertEmpty($result['children_data']);
+    }
+
+    public function treeDataProvider()
+    {
+        return [
+            [2, 100, 3, 402],
+            [2, null, 3, 402],
+            [400, 1, 1, 401],
+            [401, 0, 0, 401],
+        ];
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/category_tree.php
+     * @dataProvider updateMoveDataProvider
+     */
+    public function testUpdateMove($categoryId, $parentId, $afterId, $expectedPosition)
+    {
+        $expectedPath = '1/2/400/' . $categoryId;
+        $categoryData = ['categoryId' => $categoryId, 'parentId' => $parentId, 'afterId' => $afterId];
+        $serviceInfo =
+            [
+                'rest' => [
+                    'resourcePath' => self::RESOURCE_PATH . '/' . $categoryId . '/move',
+                    'httpMethod' => Config::HTTP_METHOD_PUT
+                ],
+                'soap' => [
+                    'service' => self::SERVICE_NAME,
+                    'serviceVersion' => 'V1',
+                    'operation' => self::SERVICE_NAME . 'Move'
+                ]
+            ];
+        $this->assertTrue($this->_webApiCall($serviceInfo, $categoryData));
+        /** @var \Magento\Catalog\Model\Category $model */
+        $readService = Bootstrap::getObjectManager()->create('Magento\Catalog\Api\CategoryRepositoryInterface');
+        $model = $readService->get($categoryId);
+        $this->assertEquals($expectedPath, $model->getPath());
+        $this->assertEquals($expectedPosition, $model->getPosition());
+        $this->assertEquals($parentId, $model->getParentId());
+    }
+
+    public function updateMoveDataProvider()
+    {
+        return [
+            [402, 400, null, 2],
+            [402, 400, 401, 2],
+            [402, 400, 999, 2],
+            [402, 400, 0, 1]
+        ];
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php
new file mode 100644
index 00000000000..a6a2a5d9efe
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/CategoryRepositoryTest.php
@@ -0,0 +1,253 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Api;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+class CategoryRepositoryTest extends WebapiAbstract
+{
+    const RESOURCE_PATH = '/V1/categories';
+    const SERVICE_NAME = 'catalogCategoryRepositoryV1';
+
+    private $modelId = 333;
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/category_backend.php
+     */
+    public function testGet()
+    {
+        $expected = [
+            'parent_id' => 2,
+            'path' => '1/2/3',
+            'position' => 1,
+            'level' => 2,
+            'available_sort_by' => ['position', 'name'],
+            'include_in_menu' => true,
+            'name' => 'Category 1',
+            'id' => 333,
+            'is_active' => true,
+        ];
+
+        $result = $this->getInfoCategory($this->modelId);
+
+        $this->assertArrayHasKey('created_at', $result);
+        $this->assertArrayHasKey('updated_at', $result);
+        $this->assertArrayHasKey('children', $result);
+        unset($result['created_at'], $result['updated_at'], $result['children']);
+        ksort($expected);
+        ksort($result);
+        $this->assertEquals($expected, $result);
+    }
+
+    public function testInfoNoSuchEntityException()
+    {
+        try {
+            $this->getInfoCategory(-1);
+        } catch (\Exception $e) {
+            $this->assertContains('No such entity with %fieldName = %fieldValue', $e->getMessage());
+        }
+    }
+
+    /**
+     * @param int $id
+     * @return string
+     */
+    protected function getInfoCategory($id)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $id,
+                'httpMethod' => Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => 'V1',
+                'operation' => self::SERVICE_NAME . 'Get',
+            ],
+        ];
+        return $this->_webApiCall($serviceInfo, ['categoryId' => $id]);
+    }
+    /**
+     * @return array
+     */
+    public function categoryCreationProvider()
+    {
+        return [
+            [
+                $this->getSimpleCategoryData(
+                    [
+                        'name' => 'Test Category Name',
+                    ]
+                ),
+            ]
+        ];
+    }
+
+    /**
+     * Test for create category process
+     *
+     * @magentoApiDataFixture Magento/Catalog/Model/Category/_files/service_category_create.php
+     * @dataProvider categoryCreationProvider
+     */
+    public function testCreate($category)
+    {
+        $category = $this->createCategory($category);
+        $this->assertGreaterThan(0, $category['id']);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/category.php
+     */
+    public function testDelete()
+    {
+        $this->assertTrue($this->deleteCategory($this->modelId));
+    }
+
+    public function testDeleteNoSuchEntityException()
+    {
+        try {
+            $this->deleteCategory(-1);
+        } catch (\Exception $e) {
+            $this->assertContains('No such entity with %fieldName = %fieldValue', $e->getMessage());
+        }
+    }
+
+    /**
+     * @dataProvider deleteSystemOrRootDataProvider
+     * @expectedException \Exception
+     */
+    public function testDeleteSystemOrRoot()
+    {
+        $this->deleteCategory($this->modelId);
+    }
+
+    public function deleteSystemOrRootDataProvider()
+    {
+        return [
+            [\Magento\Catalog\Model\Category::TREE_ROOT_ID],
+            [2] //Default root category
+        ];
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/category.php
+     */
+    public function testUpdate()
+    {
+        $categoryId = 333;
+        $categoryData = [
+            'name' => "Update Category Test",
+            'custom_attributes' => [
+                [
+                    'attribute_code' => 'description',
+                    'value' => "Update Category Description Test",
+                ],
+            ],
+        ];
+        $result = $this->updateCategory($categoryId, $categoryData);
+        $this->assertEquals($categoryId, $result['id']);
+        /** @var \Magento\Catalog\Model\Category $model */
+        $model = Bootstrap::getObjectManager()->get('Magento\Catalog\Model\Category');
+        $category = $model->load($categoryId);
+        $this->assertEquals("Update Category Test", $category->getName());
+        $this->assertEquals("Update Category Description Test", $category->getDescription());
+    }
+
+    protected function getSimpleCategoryData($categoryData = [])
+    {
+        return [
+            'path' => '2',
+            'parent_id' => '2',
+            'name' => isset($categoryData['name'])
+                ? $categoryData['name'] : uniqid('Category-', true),
+            'is_active' => '1',
+            'custom_attributes' => [
+                ['attribute_code' => 'url_key', 'value' => ''],
+                ['attribute_code' => 'description', 'value' => 'Custom description'],
+                ['attribute_code' => 'meta_title', 'value' => ''],
+                ['attribute_code' => 'meta_keywords', 'value' => ''],
+                ['attribute_code' => 'meta_description', 'value' => ''],
+                ['attribute_code' => 'include_in_menu', 'value' => '1'],
+                ['attribute_code' => 'display_mode', 'value' => 'PRODUCTS'],
+                ['attribute_code' => 'landing_page', 'value' => ''],
+                ['attribute_code' => 'is_anchor', 'value' => '0'],
+                ['attribute_code' => 'custom_use_parent_settings', 'value' => '0'],
+                ['attribute_code' => 'custom_apply_to_products', 'value' => '0'],
+                ['attribute_code' => 'custom_design', 'value' => ''],
+                ['attribute_code' => 'custom_design_from', 'value' => ''],
+                ['attribute_code' => 'custom_design_to', 'value' => ''],
+                ['attribute_code' => 'page_layout', 'value' => ''],
+            ]
+        ];
+    }
+
+    /**
+     * Create category process
+     *
+     * @param  $category
+     * @return int
+     */
+    protected function createCategory($category)
+    {
+        $serviceInfo = [
+            'rest' => ['resourcePath' => self::RESOURCE_PATH, 'httpMethod' => Config::HTTP_METHOD_POST],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => 'V1',
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $requestData = ['category' => $category];
+        return $this->_webApiCall($serviceInfo, $requestData);
+    }
+
+    /**
+     * @param int $id
+     * @return bool
+     * @throws \Exception
+     */
+    protected function deleteCategory($id)
+    {
+        $serviceInfo =
+            [
+                'rest' => [
+                    'resourcePath' => self::RESOURCE_PATH . '/' . $id,
+                    'httpMethod' => Config::HTTP_METHOD_DELETE,
+                ],
+                'soap' => [
+                    'service' => self::SERVICE_NAME,
+                    'serviceVersion' => 'V1',
+                    'operation' => self::SERVICE_NAME . 'DeleteByIdentifier',
+                ],
+            ];
+        return $this->_webApiCall($serviceInfo, ['categoryId' => $id]);
+    }
+
+    protected function updateCategory($id, $data)
+    {
+        $serviceInfo =
+            [
+                'rest' => [
+                    'resourcePath' => self::RESOURCE_PATH . '/' . $id,
+                    'httpMethod' => Config::HTTP_METHOD_PUT,
+                ],
+                'soap' => [
+                    'service' => self::SERVICE_NAME,
+                    'serviceVersion' => 'V1',
+                    'operation' => self::SERVICE_NAME . 'Save',
+                ],
+            ];
+
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            $data['id'] = $id;
+            return $this->_webApiCall($serviceInfo, ['id' => $id, 'category' => $data]);
+        } else {
+            return $this->_webApiCall($serviceInfo, ['category' => $data]);
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeGroupRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeGroupRepositoryTest.php
new file mode 100644
index 00000000000..daf34f578a9
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeGroupRepositoryTest.php
@@ -0,0 +1,191 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Api;
+
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ProductAttributeGroupRepositoryTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogProductAttributeGroupRepositoryV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/products/attribute-sets';
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/empty_attribute_group.php
+     */
+    public function testCreateGroup()
+    {
+        $attributeSetId = 1;
+        $groupData = $this->createGroupData($attributeSetId);
+        $groupData['attribute_group_name'] = 'empty_attribute_group_updated';
+
+        $result = $this->createGroup($attributeSetId, $groupData);
+        $this->assertArrayHasKey('attribute_group_id', $result);
+        $this->assertNotNull($result['attribute_group_id']);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/empty_attribute_group.php
+     */
+    public function testDeleteGroup()
+    {
+        $group = $this->getGroupByName('empty_attribute_group');
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/groups/" . $group->getId(),
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'DeleteById',
+            ],
+        ];
+        $this->assertTrue($this->_webApiCall($serviceInfo, ['groupId' => $group->getId()]));
+    }
+
+    /**
+     * @expectedException \Exception
+     */
+    public function testCreateGroupWithAttributeSetThatDoesNotExist()
+    {
+        $attributeSetId = -1;
+        $this->createGroup($attributeSetId);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/empty_attribute_group.php
+     */
+    public function testUpdateGroup()
+    {
+        $attributeSetId = 1;
+        $group = $this->getGroupByName('empty_attribute_group');
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $attributeSetId . '/groups',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+
+        $newGroupData = $this->createGroupData($attributeSetId);
+        $newGroupData['attribute_group_name'] = 'empty_attribute_group_updated';
+        $newGroupData['attribute_group_id'] = $group->getId();
+
+        $result = $this->_webApiCall($serviceInfo, ['group' => $newGroupData]);
+
+        $this->assertArrayHasKey('attribute_group_id', $result);
+        $this->assertEquals($group->getId(), $result['attribute_group_id']);
+        $this->assertArrayHasKey('attribute_group_name', $result);
+        $this->assertEquals($newGroupData['attribute_group_name'], $result['attribute_group_name']);
+    }
+
+    public function testGetList()
+    {
+        $searchCriteria = [
+            'searchCriteria' => [
+                'filter_groups' => [
+                    [
+                        'filters' => [
+                            [
+                                'field' => 'attribute_set_id',
+                                'value' => 1,
+                                'condition_type' => 'eq',
+                            ],
+                        ],
+                    ],
+                ],
+                'current_page' => 1,
+                'page_size' => 2,
+            ],
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/groups/list",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetList',
+            ],
+        ];
+
+        $response = $this->_webApiCall($serviceInfo, $searchCriteria);
+
+        $this->assertArrayHasKey('search_criteria', $response);
+        $this->assertArrayHasKey('total_count', $response);
+        $this->assertArrayHasKey('items', $response);
+
+        $this->assertEquals($searchCriteria['searchCriteria'], $response['search_criteria']);
+        $this->assertTrue($response['total_count'] > 0);
+        $this->assertTrue(count($response['items']) > 0);
+
+        $this->assertNotNull($response['items'][0]['attribute_group_name']);
+        $this->assertNotNull($response['items'][0]['attribute_group_id']);
+    }
+
+    /**
+     * @param $attributeSetId
+     * @return array|bool|float|int|string
+     */
+    protected function createGroup($attributeSetId, $groupData = null)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/groups',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        return $this->_webApiCall(
+            $serviceInfo,
+            ['group' => $groupData ? $groupData : $this->createGroupData($attributeSetId)]
+        );
+    }
+
+    /**
+     * @param $attributeSetId
+     * @return array
+     */
+    protected function createGroupData($attributeSetId)
+    {
+        return [
+            'attribute_group_name' => 'empty_attribute_group',
+            'attribute_set_id' => $attributeSetId
+        ];
+    }
+
+    /**
+     * Retrieve attribute group based on given name.
+     * This utility methods assumes that there is only one attribute group with given name,
+     *
+     * @param string $groupName
+     * @return \Magento\Eav\Model\Entity\Attribute\Group|null
+     */
+    protected function getGroupByName($groupName)
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var \Magento\Eav\Model\Entity\Attribute\Group */
+        $attributeGroup = $objectManager->create('Magento\Eav\Model\Entity\Attribute\Group')
+            ->load($groupName, 'attribute_group_name');
+        if ($attributeGroup->getId() === null) {
+            return null;
+        }
+        return $attributeGroup;
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeManagementTest.php
new file mode 100644
index 00000000000..14f8614829e
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeManagementTest.php
@@ -0,0 +1,184 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Api;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Webapi\Exception as HTTPExceptionCodes;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ProductAttributeManagementTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogProductAttributeManagementV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/products/attribute-sets';
+
+    public function testGetAttributes()
+    {
+        $attributeSetId = \Magento\Catalog\Api\Data\ProductAttributeInterface::DEFAULT_ATTRIBUTE_SET_ID;
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $attributeSetId . '/attributes',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetAttributes',
+            ],
+        ];
+        $attributes = $this->_webApiCall($serviceInfo, ['attributeSetId' => $attributeSetId]);
+
+        $this->assertTrue(count($attributes) > 0);
+        $this->assertArrayHasKey('attribute_code', $attributes[0]);
+        $this->assertArrayHasKey('attribute_id', $attributes[0]);
+        $this->assertArrayHasKey('default_frontend_label', $attributes[0]);
+        $this->assertNotNull($attributes[0]['attribute_code']);
+        $this->assertNotNull($attributes[0]['attribute_id']);
+        $this->assertNotNull($attributes[0]['default_frontend_label']);
+    }
+
+    public function testAssignAttribute()
+    {
+        $this->assertNotNull(
+            $this->_webApiCall(
+                $this->getAssignServiceInfo(),
+                $this->getAttributeData()
+            )
+        );
+    }
+
+    public function testAssignAttributeWrongAttributeSet()
+    {
+        $payload = $this->getAttributeData();
+        $payload['attributeSetId'] = -1;
+
+        $expectedMessage = 'AttributeSet with id "' . $payload['attributeSetId'] . '" does not exist.';
+
+        try {
+            $this->_webApiCall($this->getAssignServiceInfo(), $payload);
+            $this->fail("Expected exception");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "SoapFault does not contain expected message."
+            );
+        } catch (\Exception $e) {
+            $errorObj = $this->processRestExceptionResult($e);
+            $this->assertEquals($expectedMessage, $errorObj['message']);
+            $this->assertEquals(HTTPExceptionCodes::HTTP_NOT_FOUND, $e->getCode());
+        }
+    }
+
+    public function testAssignAttributeWrongAttributeGroup()
+    {
+        $payload = $this->getAttributeData();
+        $payload['attributeGroupId'] = -1;
+        $expectedMessage = 'Group with id "' . $payload['attributeGroupId'] . '" does not exist.';
+
+        try {
+            $this->_webApiCall($this->getAssignServiceInfo(), $payload);
+            $this->fail("Expected exception");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "SoapFault does not contain expected message."
+            );
+        } catch (\Exception $e) {
+            $errorObj = $this->processRestExceptionResult($e);
+            $this->assertEquals($expectedMessage, $errorObj['message']);
+            $this->assertEquals(HTTPExceptionCodes::HTTP_NOT_FOUND, $e->getCode());
+        }
+    }
+
+    public function testAssignAttributeWrongAttribute()
+    {
+        $payload = $this->getAttributeData();
+        $payload['attributeCode'] = 'badCode';
+        $expectedMessage = 'Attribute with attributeCode "' . $payload['attributeCode'] . '" does not exist.';
+
+        try {
+            $this->_webApiCall($this->getAssignServiceInfo(), $payload);
+            $this->fail("Expected exception");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "SoapFault does not contain expected message."
+            );
+        } catch (\Exception $e) {
+            $errorObj = $this->processRestExceptionResult($e);
+            $this->assertEquals($expectedMessage, $errorObj['message']);
+            $this->assertEquals(HTTPExceptionCodes::HTTP_NOT_FOUND, $e->getCode());
+        }
+    }
+
+    public function testUnassignAttribute()
+    {
+        $payload = $this->getAttributeData();
+
+        //Assign attribute to attribute set
+        /** @var \Magento\Eav\Model\AttributeManagement $attributeManagement */
+        $attributeManagement = Bootstrap::getObjectManager()->get('Magento\Eav\Model\AttributeManagement');
+        $attributeManagement->assign(
+            \Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE,
+            $payload['attributeSetId'],
+            $payload['attributeGroupId'],
+            $payload['attributeCode'],
+            $payload['sortOrder']
+        );
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH .
+                    '/' . $payload['attributeSetId'] .
+                    '/attributes/' .
+                    $payload['attributeCode'],
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Unassign',
+            ],
+        ];
+        $this->assertTrue($this->_webApiCall(
+                $serviceInfo,
+                [
+                    'attributeSetId' => $payload['attributeSetId'],
+                    'attributeCode' => $payload['attributeCode']
+                ]
+            )
+        );
+    }
+
+    protected function getAttributeData()
+    {
+        return [
+            'attributeSetId' => \Magento\Catalog\Api\Data\ProductAttributeInterface::DEFAULT_ATTRIBUTE_SET_ID,
+            'attributeGroupId' => 8,
+            'attributeCode' => 'cost',
+            'sortOrder' => 3
+        ];
+    }
+
+    protected function getAssignServiceInfo()
+    {
+        return [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/attributes',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Assign',
+            ],
+        ];
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeMediaGalleryManagementInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeMediaGalleryManagementInterfaceTest.php
new file mode 100644
index 00000000000..cb480d3702a
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeMediaGalleryManagementInterfaceTest.php
@@ -0,0 +1,647 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Api;
+
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+use Magento\TestFramework\Helper\Bootstrap;
+
+class ProductAttributeMediaGalleryManagementInterfaceTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    /**
+     * Default create service request information (product with SKU 'simple' is used)
+     *
+     * @var array
+     */
+    protected $createServiceInfo;
+
+    /**
+     * Default update service request information (product with SKU 'simple' is used)
+     *
+     * @var array
+     */
+    protected $updateServiceInfo;
+
+    /**
+     * Default delete service request information (product with SKU 'simple' is used)
+     *
+     * @var array
+     */
+    protected $deleteServiceInfo;
+
+    /**
+     * @var string
+     */
+    protected $testImagePath;
+
+    protected function setUp()
+    {
+        $this->createServiceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/simple/media',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => 'catalogProductAttributeMediaGalleryManagementV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'catalogProductAttributeMediaGalleryManagementV1Create',
+            ],
+        ];
+        $this->updateServiceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/simple/media',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => 'catalogProductAttributeMediaGalleryManagementV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'catalogProductAttributeMediaGalleryManagementV1Update',
+            ],
+        ];
+        $this->deleteServiceInfo = [
+            'rest' => [
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => 'catalogProductAttributeMediaGalleryManagementV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'catalogProductAttributeMediaGalleryManagementV1Remove',
+            ],
+        ];
+        $this->testImagePath = __DIR__ . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'test_image.jpg';
+    }
+
+    /**
+     * Retrieve product that was updated by test
+     *
+     * @return \Magento\Catalog\Model\Product
+     */
+    protected function getTargetSimpleProduct()
+    {
+        $objectManager = Bootstrap::getObjectManager();
+        return $objectManager->get('Magento\Catalog\Model\ProductFactory')->create()->load(1);
+    }
+
+    /**
+     * Retrieve target product image ID
+     *
+     * Target product must have single image if this function is used
+     *
+     * @return int
+     */
+    protected function getTargetGalleryEntryId()
+    {
+        $mediaGallery = $this->getTargetSimpleProduct()->getData('media_gallery');
+        return (int)$mediaGallery['images'][0]['value_id'];
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     */
+    public function testCreate()
+    {
+        $requestData = [
+            'productSku' => 'simple',
+            'entry' => [
+                'id' => null,
+                'label' => 'Image Text',
+                'position' => 1,
+                'types' => ['image'],
+                'is_disabled' => false,
+            ],
+            'entryContent' => [
+                'entry_data' => base64_encode(file_get_contents($this->testImagePath)),
+                'mime_type' => 'image/jpeg',
+                'name' => 'test_image',
+            ],
+            // Store ID is not provided so the default one must be used
+        ];
+
+        $actualResult = $this->_webApiCall($this->createServiceInfo, $requestData);
+        $targetProduct = $this->getTargetSimpleProduct();
+        $mediaGallery = $targetProduct->getData('media_gallery');
+
+        $this->assertCount(1, $mediaGallery['images']);
+        $updatedImage = $mediaGallery['images'][0];
+        $this->assertEquals($actualResult, $updatedImage['value_id']);
+        $this->assertEquals('Image Text', $updatedImage['label']);
+        $this->assertEquals(1, $updatedImage['position']);
+        $this->assertEquals(0, $updatedImage['disabled']);
+        $this->assertEquals('Image Text', $updatedImage['label_default']);
+        $this->assertEquals(1, $updatedImage['position_default']);
+        $this->assertEquals(0, $updatedImage['disabled_default']);
+        $this->assertStringStartsWith('/t/e/test_image', $updatedImage['file']);
+        $this->assertEquals($updatedImage['file'], $targetProduct->getData('image'));
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     */
+    public function testCreateWithNotDefaultStoreId()
+    {
+        $requestData = [
+            'productSku' => 'simple',
+            'entry' => [
+                'id' => null,
+                'label' => 'Image Text',
+                'position' => 1,
+                'types' => ['image'],
+                'is_disabled' => false,
+            ],
+            'entryContent' => [
+                'entry_data' => base64_encode(file_get_contents($this->testImagePath)),
+                'mime_type' => 'image/jpeg',
+                'name' => 'test_image',
+            ],
+            'storeId' => 1,
+        ];
+
+        $actualResult = $this->_webApiCall($this->createServiceInfo, $requestData);
+        $targetProduct = $this->getTargetSimpleProduct();
+        $mediaGallery = $targetProduct->getData('media_gallery');
+        $this->assertCount(1, $mediaGallery['images']);
+        $updatedImage = $mediaGallery['images'][0];
+        // Values for not default store view were provided
+        $this->assertEquals('Image Text', $updatedImage['label']);
+        $this->assertEquals($actualResult, $updatedImage['value_id']);
+        $this->assertEquals(1, $updatedImage['position']);
+        $this->assertEquals(0, $updatedImage['disabled']);
+        $this->assertStringStartsWith('/t/e/test_image', $updatedImage['file']);
+        $this->assertEquals($updatedImage['file'], $targetProduct->getData('image'));
+        // No values for default store view were provided
+        $this->assertNull($updatedImage['label_default']);
+        $this->assertNull($updatedImage['position_default']);
+        $this->assertNull($updatedImage['disabled_default']);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_with_image.php
+     */
+    public function testUpdate()
+    {
+        $requestData = [
+            'productSku' => 'simple',
+            'entry' => [
+                'id' => $this->getTargetGalleryEntryId(),
+                'label' => 'Updated Image Text',
+                'position' => 10,
+                'types' => ['thumbnail'],
+                'is_disabled' => true,
+            ],
+            // Store ID is not provided so the default one must be used
+        ];
+
+        $this->updateServiceInfo['rest']['resourcePath'] = $this->updateServiceInfo['rest']['resourcePath']
+            . '/' . $this->getTargetGalleryEntryId();
+
+        $this->assertTrue($this->_webApiCall($this->updateServiceInfo, $requestData));
+
+        $targetProduct = $this->getTargetSimpleProduct();
+        $this->assertEquals('/m/a/magento_image.jpg', $targetProduct->getData('thumbnail'));
+        $this->assertNull($targetProduct->getData('image'));
+        $this->assertNull($targetProduct->getData('small_image'));
+        $mediaGallery = $targetProduct->getData('media_gallery');
+        $this->assertCount(1, $mediaGallery['images']);
+        $updatedImage = $mediaGallery['images'][0];
+        $this->assertEquals('Updated Image Text', $updatedImage['label']);
+        $this->assertEquals('/m/a/magento_image.jpg', $updatedImage['file']);
+        $this->assertEquals(10, $updatedImage['position']);
+        $this->assertEquals(1, $updatedImage['disabled']);
+        $this->assertEquals('Updated Image Text', $updatedImage['label_default']);
+        $this->assertEquals(10, $updatedImage['position_default']);
+        $this->assertEquals(1, $updatedImage['disabled_default']);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_with_image.php
+     */
+    public function testUpdateWithNotDefaultStoreId()
+    {
+        $requestData = [
+            'productSku' => 'simple',
+            'entry' => [
+                'id' => $this->getTargetGalleryEntryId(),
+                'label' => 'Updated Image Text',
+                'position' => 10,
+                'types' => ['thumbnail'],
+                'is_disabled' => true,
+            ],
+            'storeId' => 1,
+        ];
+
+        $this->updateServiceInfo['rest']['resourcePath'] = $this->updateServiceInfo['rest']['resourcePath']
+            . '/' . $this->getTargetGalleryEntryId();
+
+        $this->assertTrue($this->_webApiCall($this->updateServiceInfo, $requestData));
+
+        $targetProduct = $this->getTargetSimpleProduct();
+        $this->assertEquals('/m/a/magento_image.jpg', $targetProduct->getData('thumbnail'));
+        $this->assertNull($targetProduct->getData('image'));
+        $this->assertNull($targetProduct->getData('small_image'));
+        $mediaGallery = $targetProduct->getData('media_gallery');
+        $this->assertCount(1, $mediaGallery['images']);
+        $updatedImage = $mediaGallery['images'][0];
+        // Not default store view values were updated
+        $this->assertEquals('Updated Image Text', $updatedImage['label']);
+        $this->assertEquals('/m/a/magento_image.jpg', $updatedImage['file']);
+        $this->assertEquals(10, $updatedImage['position']);
+        $this->assertEquals(1, $updatedImage['disabled']);
+        // Default store view values were not updated
+        $this->assertEquals('Image Alt Text', $updatedImage['label_default']);
+        $this->assertEquals(1, $updatedImage['position_default']);
+        $this->assertEquals(0, $updatedImage['disabled_default']);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_with_image.php
+     */
+    public function testDelete()
+    {
+        $entryId = $this->getTargetGalleryEntryId();
+        $this->deleteServiceInfo['rest']['resourcePath'] = "/V1/products/simple/media/{$entryId}";
+        $requestData = [
+            'productSku' => 'simple',
+            'entryId' => $this->getTargetGalleryEntryId(),
+        ];
+
+        $this->assertTrue($this->_webApiCall($this->deleteServiceInfo, $requestData));
+        $targetProduct = $this->getTargetSimpleProduct();
+        $mediaGallery = $targetProduct->getData('media_gallery');
+        $this->assertCount(0, $mediaGallery['images']);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage There is no store with provided ID.
+     */
+    public function testCreateThrowsExceptionIfThereIsNoStoreWithProvidedStoreId()
+    {
+        $requestData = [
+            'productSku' => 'simple',
+            'entry' => [
+                'id' => null,
+                'label' => 'Image Text',
+                'position' => 1,
+                'types' => ['image'],
+                'is_disabled' => false,
+            ],
+            'storeId' => 9999, // target store view does not exist
+            'entryContent' => [
+                'entry_data' => base64_encode(file_get_contents($this->testImagePath)),
+                'mime_type' => 'image/jpeg',
+                'name' => 'test_image',
+            ],
+        ];
+
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage The image content must be valid base64 encoded data.
+     */
+    public function testCreateThrowsExceptionIfProvidedContentIsNotBase64Encoded()
+    {
+        $encodedContent = 'not_a_base64_encoded_content';
+        $requestData = [
+            'productSku' => 'simple',
+            'entry' => [
+                'id' => null,
+                'label' => 'Image Text',
+                'position' => 1,
+                'is_disabled' => false,
+                'types' => ['image'],
+            ],
+            'entryContent' => [
+                'entry_data' => $encodedContent,
+                'mime_type' => 'image/jpeg',
+                'name' => 'test_image',
+            ],
+            'storeId' => 0,
+        ];
+
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage The image content must be valid base64 encoded data.
+     */
+    public function testCreateThrowsExceptionIfProvidedContentIsNotAnImage()
+    {
+        $encodedContent = base64_encode('not_an_image');
+        $requestData = [
+            'productSku' => 'simple',
+            'entry' => [
+                'id' => null,
+                'is_disabled' => false,
+                'label' => 'Image Text',
+                'position' => 1,
+                'types' => ['image'],
+            ],
+            'entryContent' => [
+                'entry_data' => $encodedContent,
+                'mime_type' => 'image/jpeg',
+                'name' => 'test_image',
+            ],
+            'storeId' => 0,
+        ];
+
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage The image MIME type is not valid or not supported.
+     */
+    public function testCreateThrowsExceptionIfProvidedImageHasWrongMimeType()
+    {
+        $encodedContent = base64_encode(file_get_contents($this->testImagePath));
+        $requestData = [
+            'entry' => [
+                'id' => null,
+                'label' => 'Image Text',
+                'position' => 1,
+                'types' => ['image'],
+                'is_disabled' => false,
+            ],
+            'productSku' => 'simple',
+            'entryContent' => [
+                'entry_data' => $encodedContent,
+                'mime_type' => 'wrong_mime_type',
+                'name' => 'test_image',
+            ],
+            'storeId' => 0,
+        ];
+
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Requested product doesn't exist
+     */
+    public function testCreateThrowsExceptionIfTargetProductDoesNotExist()
+    {
+        $this->createServiceInfo['rest']['resourcePath'] = '/V1/products/wrong_product_sku/media';
+        $requestData = [
+            'productSku' => 'wrong_product_sku',
+            'entry' => [
+                'id' => null,
+                'position' => 1,
+                'label' => 'Image Text',
+                'types' => ['image'],
+                'is_disabled' => false,
+            ],
+            'entryContent' => [
+                'entry_data' => base64_encode(file_get_contents($this->testImagePath)),
+                'mime_type' => 'image/jpeg',
+                'name' => 'test_image',
+            ],
+            'storeId' => 0,
+        ];
+
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Provided image name contains forbidden characters.
+     */
+    public function testCreateThrowsExceptionIfProvidedImageNameContainsForbiddenCharacters()
+    {
+        $requestData = [
+            'productSku' => 'simple',
+            'entry' => [
+                'id' => null,
+                'label' => 'Image Text',
+                'position' => 1,
+                'types' => ['image'],
+                'is_disabled' => false,
+            ],
+            'entryContent' => [
+                'entry_data' => base64_encode(file_get_contents($this->testImagePath)),
+                'mime_type' => 'image/jpeg',
+                'name' => 'test/\\{}|:"<>', // Cannot contain \ / : * ? " < > |
+            ],
+            'storeId' => 0,
+        ];
+
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_with_image.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage There is no store with provided ID.
+     */
+    public function testUpdateIfThereIsNoStoreWithProvidedStoreId()
+    {
+        $requestData = [
+            'productSku' => 'simple',
+            'entry' => [
+                'id' => $this->getTargetGalleryEntryId(),
+                'label' => 'Updated Image Text',
+                'position' => 10,
+                'types' => ['thumbnail'],
+                'is_disabled' => true,
+            ],
+            'storeId' => 9999, // target store view does not exist
+        ];
+
+        $this->updateServiceInfo['rest']['resourcePath'] = $this->updateServiceInfo['rest']['resourcePath']
+            . '/' . $this->getTargetGalleryEntryId();
+
+        $this->_webApiCall($this->updateServiceInfo, $requestData);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Requested product doesn't exist
+     */
+    public function testUpdateThrowsExceptionIfTargetProductDoesNotExist()
+    {
+        $this->updateServiceInfo['rest']['resourcePath'] = '/V1/products/wrong_product_sku/media'
+            . '/' . $this->getTargetGalleryEntryId();
+        $requestData = [
+            'productSku' => 'wrong_product_sku',
+            'entry' => [
+                'id' => 9999,
+                'label' => 'Updated Image Text',
+                'position' => 1,
+                'types' => ['thumbnail'],
+                'is_disabled' => true,
+            ],
+            'storeId' => 0,
+        ];
+
+        $this->_webApiCall($this->updateServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_with_image.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage There is no image with provided ID.
+     */
+    public function testUpdateThrowsExceptionIfThereIsNoImageWithGivenId()
+    {
+        $requestData = [
+            'productSku' => 'simple',
+            'entry' => [
+                'id' => 9999,
+                'label' => 'Updated Image Text',
+                'position' => 1,
+                'types' => ['thumbnail'],
+                'is_disabled' => true,
+            ],
+            'storeId' => 0,
+        ];
+
+        $this->updateServiceInfo['rest']['resourcePath'] = $this->updateServiceInfo['rest']['resourcePath']
+            . '/' . $this->getTargetGalleryEntryId();
+
+        $this->_webApiCall($this->updateServiceInfo, $requestData);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Requested product doesn't exist
+     */
+    public function testDeleteThrowsExceptionIfTargetProductDoesNotExist()
+    {
+        $this->deleteServiceInfo['rest']['resourcePath'] = '/V1/products/wrong_product_sku/media/9999';
+        $requestData = [
+            'productSku' => 'wrong_product_sku',
+            'entryId' => 9999,
+        ];
+
+        $this->_webApiCall($this->deleteServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_with_image.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage There is no image with provided ID.
+     */
+    public function testDeleteThrowsExceptionIfThereIsNoImageWithGivenId()
+    {
+        $this->deleteServiceInfo['rest']['resourcePath'] = '/V1/products/simple/media/9999';
+        $requestData = [
+            'productSku' => 'simple',
+            'entryId' => 9999,
+        ];
+
+        $this->_webApiCall($this->deleteServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_with_image.php
+     */
+    public function testGet()
+    {
+        $productSku = 'simple';
+
+        $objectManager = \Magento\TestFramework\ObjectManager::getInstance();
+        /** @var \Magento\Catalog\Model\ProductRepository $repository */
+        $repository = $objectManager->create('Magento\Catalog\Model\ProductRepository');
+        $product = $repository->get($productSku);
+        $image = current($product->getMediaGallery('images'));
+        $imageId = $image['value_id'];
+
+        $expected = [
+            'label' => $image['label'],
+            'position' => $image['position'],
+            'is_disabled' => (bool)$image['disabled'],
+            'file' => $image['file'],
+            'types' => ['image', 'small_image', 'thumbnail'],
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/' . $productSku . '/media/' . $imageId,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => 'catalogProductAttributeMediaGalleryManagementV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'catalogProductAttributeMediaGalleryManagementV1Get',
+            ],
+        ];
+        $requestData = [
+            'productSku' => $productSku,
+            'imageId' => $imageId,
+        ];
+        $data = $this->_webApiCall($serviceInfo, $requestData);
+        $actual = (array) $data;
+        $this->assertEquals($expected['label'], $actual['label']);
+        $this->assertEquals($expected['position'], $actual['position']);
+        $this->assertEquals($expected['file'], $actual['file']);
+        $this->assertEquals($expected['types'], $actual['types']);
+        $this->assertEquals($expected['is_disabled'], (bool)$actual['is_disabled']);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_with_image.php
+     */
+    public function testGetList()
+    {
+        $productSku = 'simple'; //from fixture
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/' . urlencode($productSku) . '/media',
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => 'catalogProductAttributeMediaGalleryManagementV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'catalogProductAttributeMediaGalleryManagementV1GetList',
+            ],
+        ];
+
+        $requestData = [
+            'productSku' => $productSku,
+        ];
+        $imageList = $this->_webApiCall($serviceInfo, $requestData);
+
+        $image = reset($imageList);
+        $this->assertEquals('/m/a/magento_image.jpg', $image['file']);
+        $this->assertNotEmpty($image['types']);
+        $imageTypes = $image['types'];
+        $this->assertContains('image', $imageTypes);
+        $this->assertContains('small_image', $imageTypes);
+        $this->assertContains('thumbnail', $imageTypes);
+    }
+
+    public function testGetListForAbsentSku()
+    {
+        $productSku = 'absent_sku_' . time();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/' . urlencode($productSku) . '/media',
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => 'catalogProductAttributeMediaGalleryManagementV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'catalogProductAttributeMediaGalleryManagementV1GetList',
+            ],
+        ];
+
+        $requestData = [
+            'productSku' => $productSku,
+        ];
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            $this->setExpectedException('SoapFault', 'Requested product doesn\'t exist');
+        } else {
+            $this->setExpectedException('Exception', '', 404);
+        }
+        $this->_webApiCall($serviceInfo, $requestData);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionManagementInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionManagementInterfaceTest.php
new file mode 100644
index 00000000000..1b687f2a6f4
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeOptionManagementInterfaceTest.php
@@ -0,0 +1,152 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Api;
+
+use Magento\Eav\Api\Data\AttributeOptionInterface;
+use Magento\Eav\Api\Data\AttributeOptionLabelInterface;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ProductAttributeOptionManagementInterfaceTest extends WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogProductAttributeOptionManagementV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/products/attributes';
+
+    public function testGetItems()
+    {
+        $testAttributeCode = 'quantity_and_stock_status';
+        $expectedOptions = [
+            [
+                AttributeOptionInterface::VALUE => '1',
+                AttributeOptionInterface::LABEL => 'In Stock',
+            ],
+            [
+                AttributeOptionInterface::VALUE => '0',
+                AttributeOptionInterface::LABEL => 'Out of Stock',
+            ],
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $testAttributeCode . '/options',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'getItems',
+            ],
+        ];
+
+        $response = $this->_webApiCall($serviceInfo, ['attributeCode' => $testAttributeCode]);
+
+        $this->assertTrue(is_array($response));
+        $this->assertEquals($expectedOptions, $response);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/Model/Product/Attribute/_files/select_attribute.php
+     */
+    public function testAdd()
+    {
+        $testAttributeCode = 'select_attribute';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $testAttributeCode . '/options',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'add',
+            ],
+        ];
+
+        $optionData = [
+            AttributeOptionInterface::LABEL => 'new color',
+            AttributeOptionInterface::VALUE => 'grey',
+            AttributeOptionInterface::SORT_ORDER => 100,
+            AttributeOptionInterface::IS_DEFAULT => true,
+            AttributeOptionInterface::STORE_LABELS => [
+                [
+                    AttributeOptionLabelInterface::LABEL => 'DE label',
+                    AttributeOptionLabelInterface::STORE_ID => 1,
+                ],
+            ],
+        ];
+
+        $response = $this->_webApiCall(
+            $serviceInfo,
+            [
+                'attributeCode' => $testAttributeCode,
+                'option' => $optionData,
+            ]
+        );
+
+        $this->assertTrue($response);
+        $updatedData = $this->getAttributeOptions($testAttributeCode);
+        $lastOption = array_pop($updatedData);
+        $this->assertEquals(
+            $optionData[AttributeOptionInterface::STORE_LABELS][0][AttributeOptionLabelInterface::LABEL],
+            $lastOption['label']
+        );
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/Model/Product/Attribute/_files/select_attribute.php
+     */
+    public function testDelete()
+    {
+        $attributeCode = 'select_attribute';
+        //get option Id
+        $optionList = $this->getAttributeOptions($attributeCode);
+        $this->assertGreaterThan(0, count($optionList));
+        $lastOption = array_pop($optionList);
+        $this->assertNotEmpty($lastOption['value']);
+        $optionId = $lastOption['value'];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $attributeCode . '/options/' . $optionId,
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'delete',
+            ],
+        ];
+        $this->assertTrue($this->_webApiCall(
+            $serviceInfo,
+            [
+                'attributeCode' => $attributeCode,
+                'optionId' => $optionId,
+            ]
+        ));
+        $updatedOptions = $this->getAttributeOptions($attributeCode);
+        $this->assertEquals($optionList, $updatedOptions);
+    }
+
+    /**
+     * @param $testAttributeCode
+     * @return array|bool|float|int|string
+     */
+    private function getAttributeOptions($testAttributeCode)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $testAttributeCode . '/options',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'getItems',
+            ],
+        ];
+        return $this->_webApiCall($serviceInfo, ['attributeCode' => $testAttributeCode]);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php
new file mode 100644
index 00000000000..20742ba9ee0
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php
@@ -0,0 +1,266 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Api;
+
+use Magento\Webapi\Exception as HTTPExceptionCodes;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ProductAttributeRepositoryTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogProductAttributeRepositoryV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/products/attributes';
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_attribute.php
+     */
+    public function testGet()
+    {
+        $attributeCode = 'test_attribute_code_333';
+        $attribute = $this->getAttribute($attributeCode);
+
+        $this->assertTrue(is_array($attribute));
+        $this->assertArrayHasKey('attribute_id', $attribute);
+        $this->assertArrayHasKey('attribute_code', $attribute);
+        $this->assertEquals($attributeCode, $attribute['attribute_code']);
+    }
+
+    public function testGetList()
+    {
+        $searchCriteria = [
+            'searchCriteria' => [
+                'filter_groups' => [
+                    [
+                        'filters' => [
+                            [
+                                'field' => 'frontend_input',
+                                'value' => 'textarea',
+                                'condition_type' => 'eq',
+                            ],
+                        ],
+                    ],
+                ],
+                'current_page' => 1,
+                'page_size' => 2,
+            ],
+            'entityTypeCode' => \Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE,
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetList',
+            ],
+        ];
+        $response = $this->_webApiCall($serviceInfo, $searchCriteria);
+
+        $this->assertArrayHasKey('search_criteria', $response);
+        $this->assertArrayHasKey('total_count', $response);
+        $this->assertArrayHasKey('items', $response);
+
+        $this->assertEquals($searchCriteria['searchCriteria'], $response['search_criteria']);
+        $this->assertTrue($response['total_count'] > 0);
+        $this->assertTrue(count($response['items']) > 0);
+
+        $this->assertNotNull($response['items'][0]['default_frontend_label']);
+        $this->assertNotNull($response['items'][0]['attribute_id']);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/Model/Product/Attribute/_files/create_attribute_service.php
+     */
+    public function testCreate()
+    {
+        $attributeCode = 'label_attr_code3df4tr3';
+        $attribute = $this->createAttribute($attributeCode);
+        $this->assertArrayHasKey('attribute_id', $attribute);
+        $this->assertEquals($attributeCode, $attribute['attribute_code']);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_attribute.php
+     */
+    public function testCreateWithExceptionIfAttributeAlreadyExists()
+    {
+        $attributeCode = 'test_attribute_code_333';
+        try {
+            $this->createAttribute($attributeCode);
+            $this->fail("Expected exception");
+        } catch (\SoapFault $e) {
+            //Expects soap exception
+        } catch (\Exception $e) {
+            $this->assertEquals(HTTPExceptionCodes::HTTP_INTERNAL_ERROR, $e->getCode());
+        }
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_attribute.php
+     */
+    public function testUpdate()
+    {
+        $attributeCode = 'test_attribute_code_333';
+        $attribute = $this->getAttribute($attributeCode);
+
+        $attributeData = [
+            'attribute' => [
+                'attribute_code' => $attributeCode,
+                'frontend_labels' => [
+                    ['store_id' => 0, 'label' => 'front_lbl_new'],
+                ],
+                'default_value' => 'default value new',
+                'is_required' => false,
+                'frontend_input' => 'text',
+            ],
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $attribute['attribute_id'],
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            $attributeData['attribute']['attributeId'] = $attribute['attribute_id'];
+        }
+        $result = $this->_webApiCall($serviceInfo, $attributeData);
+
+        $this->assertEquals($attribute['attribute_id'], $result['attribute_id']);
+        $this->assertEquals($attributeCode, $result['attribute_code']);
+        $this->assertEquals('default value new', $result['default_value']);
+        $this->assertEquals('front_lbl_new', $result['default_frontend_label']);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_attribute.php
+     */
+    public function testDeleteById()
+    {
+        $attributeCode = 'test_attribute_code_333';
+        $this->assertTrue($this->deleteAttribute($attributeCode));
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_attribute.php
+     */
+    public function testDeleteNoSuchEntityException()
+    {
+        $attributeCode = 'some_test_code';
+        $expectedMessage = 'Attribute with attributeCode "' . $attributeCode . '" does not exist.';
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $attributeCode,
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'deleteById',
+            ],
+        ];
+
+        try {
+            $this->_webApiCall($serviceInfo, ['attributeCode' => $attributeCode]);
+            $this->fail("Expected exception");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "SoapFault does not contain expected message."
+            );
+        } catch (\Exception $e) {
+            $errorObj = $this->processRestExceptionResult($e);
+            $this->assertEquals($expectedMessage, $errorObj['message']);
+            $this->assertEquals(HTTPExceptionCodes::HTTP_NOT_FOUND, $e->getCode());
+        }
+    }
+
+    /**
+     * @param $attributeCode
+     * @return array|bool|float|int|string
+     */
+    protected function createAttribute($attributeCode)
+    {
+        $attributeData = [
+            'attribute' => [
+                'attribute_code' => $attributeCode,
+                'frontend_labels' => [
+                    ['store_id' => 0, 'label' => 'front_lbl'],
+                ],
+                'default_value' => 'default value',
+                'frontend_input' => 'textarea',
+                'is_required' => true,
+            ],
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        return $this->_webApiCall($serviceInfo, $attributeData);
+    }
+
+    /**
+     * @param $attributeCode
+     * @return array|bool|float|int|string
+     */
+    protected function getAttribute($attributeCode)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $attributeCode,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Get',
+            ],
+        ];
+
+        return $this->_webApiCall($serviceInfo, ['attributeCode' => $attributeCode]);
+    }
+
+    /**
+     * Delete attribute by code
+     *
+     * @param $attributeCode
+     * @return array|bool|float|int|string
+     */
+    protected function deleteAttribute($attributeCode)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $attributeCode,
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'deleteById',
+            ],
+        ];
+        return $this->_webApiCall($serviceInfo, ['attributeCode' => $attributeCode]);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeTypesListTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeTypesListTest.php
new file mode 100644
index 00000000000..5967b8503bf
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeTypesListTest.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Api;
+
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ProductAttributeTypesListTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogProductAttributeTypesListV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/products/attributes';
+
+    public function testGetItems()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/types',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetItems',
+            ],
+        ];
+        $types = $this->_webApiCall($serviceInfo);
+
+        $this->assertTrue(count($types) > 0);
+        $this->assertArrayHasKey('value', $types[0]);
+        $this->assertArrayHasKey('label', $types[0]);
+        $this->assertNotNull($types[0]['value']);
+        $this->assertNotNull($types[0]['label']);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php
new file mode 100644
index 00000000000..1995c194bd5
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionRepositoryTest.php
@@ -0,0 +1,367 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Catalog\Api;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+
+class ProductCustomOptionRepositoryTest extends WebapiAbstract
+{
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    const SERVICE_NAME = 'catalogProductCustomOptionRepositoryV1';
+
+    /**
+     * @var \Magento\Catalog\Model\ProductFactory
+     */
+    protected $productFactory;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->productFactory = $this->objectManager->get('Magento\Catalog\Model\ProductFactory');
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_with_options.php
+     * @magentoAppIsolation enabled
+     */
+    public function testRemove()
+    {
+        $sku = 'simple';
+        /** @var  \Magento\Catalog\Model\Product $product */
+        $product = $this->objectManager->create('Magento\Catalog\Model\Product');
+        $product->load(1);
+        $customOptions = $product->getOptions();
+        $optionId = array_pop($customOptions)->getId();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => "/V1/products/$sku/options/$optionId",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => 'V1',
+                'operation' => self::SERVICE_NAME . 'DeleteByIdentifier',
+            ],
+        ];
+        $this->assertTrue($this->_webApiCall($serviceInfo, ['productSku' => $sku, 'optionId' => $optionId]));
+        /** @var  \Magento\Catalog\Model\Product $product */
+        $product = $this->objectManager->create('Magento\Catalog\Model\Product');
+        $product->load(1);
+        $this->assertNull($product->getOptionById($optionId));
+        $this->assertEquals(9, count($product->getOptions()));
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_with_options.php
+     * @magentoAppIsolation enabled
+     */
+    public function testGet()
+    {
+        $productSku = 'simple';
+        /** @var \Magento\Catalog\Api\ProductCustomOptionRepositoryInterface $service */
+        $service = Bootstrap::getObjectManager()
+            ->get('Magento\Catalog\Api\ProductCustomOptionRepositoryInterface');
+        $options = $service->getList('simple');
+        $option = current($options);
+        $optionId = $option->getOptionId();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/' . $productSku . "/options/" . $optionId,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => 'V1',
+                'operation' => self::SERVICE_NAME . 'Get',
+            ],
+        ];
+        $option = $this->_webApiCall($serviceInfo, ['productSku' => $productSku, 'optionId' => $optionId]);
+        unset($option['product_sku']);
+        unset($option['option_id']);
+        $excepted = include '_files/product_options.php';
+        $this->assertEquals($excepted[0], $option);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_with_options.php
+     * @magentoAppIsolation enabled
+     */
+    public function testGetList()
+    {
+        $productSku = 'simple';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/' . $productSku . "/options",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => 'V1',
+                'operation' => self::SERVICE_NAME . 'GetList',
+            ],
+        ];
+        $options = $this->_webApiCall($serviceInfo, ['productSku' => $productSku]);
+
+        /** Unset dynamic data */
+        foreach ($options as $key => $value) {
+            unset($options[$key]['product_sku']);
+            unset($options[$key]['option_id']);
+            if (!empty($options[$key]['values'])) {
+                foreach ($options[$key]['values'] as $newKey => $valueData) {
+                    unset($options[$key]['values'][$newKey]['option_type_id']);
+                }
+            }
+        }
+
+        $excepted = include '_files/product_options.php';
+        $this->assertEquals(count($excepted), count($options));
+
+        //in order to make assertion result readable we need to check each element separately
+        foreach ($excepted as $index => $value) {
+            $this->assertEquals($value, $options[$index]);
+        }
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_without_options.php
+     * @magentoAppIsolation enabled
+     * @dataProvider optionDataProvider
+     */
+    public function testSave($optionData)
+    {
+        $productSku = 'simple';
+
+        $optionDataPost = $optionData;
+        $optionDataPost['product_sku'] = $productSku;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/options',
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => 'V1',
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+
+        $result = $this->_webApiCall($serviceInfo, ['option' => $optionDataPost]);
+        unset($result['product_sku']);
+        unset($result['option_id']);
+        if (!empty($result['values'])) {
+            foreach ($result['values'] as $key => $value) {
+                unset($result['values'][$key]['option_type_id']);
+            }
+        }
+        $this->assertEquals($optionData, $result);
+    }
+
+    public function optionDataProvider()
+    {
+        $fixtureOptions = [];
+        $fixture = include '_files/product_options.php';
+        foreach ($fixture as $item) {
+            $fixtureOptions[$item['type']] = [
+                'optionData' => $item,
+            ];
+        };
+
+        return $fixtureOptions;
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_without_options.php
+     * @magentoAppIsolation enabled
+     * @dataProvider optionNegativeDataProvider
+     */
+    public function testAddNegative($optionData)
+    {
+        $productSku = 'simple';
+        $optionDataPost = $optionData;
+        $optionDataPost['product_sku'] = $productSku;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => "/V1/products/options",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => 'V1',
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            $this->setExpectedException('SoapFault', 'Could not save product option');
+        } else {
+            $this->setExpectedException('Exception', '', 400);
+        }
+        $this->_webApiCall($serviceInfo, ['option' => $optionDataPost]);
+    }
+
+    public function optionNegativeDataProvider()
+    {
+        $fixtureOptions = [];
+        $fixture = include '_files/product_options_negative.php';
+        foreach ($fixture as $key => $item) {
+            $fixtureOptions[$key] = [
+                'optionData' => $item,
+            ];
+        };
+
+        return $fixtureOptions;
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_with_options.php
+     * @magentoAppIsolation enabled
+     */
+    public function testUpdate()
+    {
+        $productSku = 'simple';
+        /** @var \Magento\Catalog\Model\ProductRepository $optionReadService */
+        $productRepository = $this->objectManager->create(
+            'Magento\Catalog\Model\ProductRepository'
+        );
+
+        $options = $productRepository->get($productSku, true)->getOptions();
+        $option = array_shift($options);
+        $optionId = $option->getOptionId();
+        $optionDataPost = [
+            'product_sku' => $productSku,
+            'title' => $option->getTitle() . "_updated",
+            'type' => $option->getType(),
+            'sort_order' => $option->getSortOrder(),
+            'is_require' => $option->getIsRequire(),
+            'price' => $option->getPrice(),
+            'price_type' => $option->getPriceType(),
+            'sku' => $option->getSku(),
+            'max_characters' => 500,
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/options/' . $optionId,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => 'V1',
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            $optionDataPost['option_id'] = $optionId;
+            $updatedOption = $this->_webApiCall(
+                $serviceInfo, [ 'id' => $optionId, 'option' => $optionDataPost]
+            );
+        } else {
+            $updatedOption = $this->_webApiCall(
+                $serviceInfo, ['option' => $optionDataPost]
+            );
+        }
+
+        unset($updatedOption['values']);
+        $optionDataPost['option_id'] = $option->getOptionId();
+        $this->assertEquals($optionDataPost, $updatedOption);
+    }
+
+    /**
+     * @param string $optionType
+     *
+     * @magentoApiDataFixture Magento/Catalog/_files/product_with_options.php
+     * @magentoAppIsolation enabled
+     * @dataProvider validOptionDataProvider
+     */
+    public function testUpdateOptionAddingNewValue($optionType)
+    {
+        $productId = 1;
+        $fixtureOption = null;
+        $valueData = [
+            'price' => 100500,
+            'price_type' => 'fixed',
+            'sku' => 'new option sku ' . $optionType,
+            'title' => 'New Option Title',
+            'sort_order' => 100,
+        ];
+
+        $product = $this->productFactory->create();
+        $product->load($productId);
+
+        /**@var $option \Magento\Catalog\Model\Product\Option */
+        foreach ($product->getOptions() as $option) {
+            if ($option->getType() == $optionType) {
+                $fixtureOption = $option;
+                break;
+            }
+        }
+
+        $values = [];
+        foreach ($option->getValues() as $key => $value) {
+            $values[] = [
+                'price' => $value->getPrice(),
+                'price_type' => $value->getPriceType(),
+                'sku' => $value->getSku(),
+                'title' => $value->getTitle(),
+                'sort_order' => $value->getSortOrder(),
+        ];
+        }
+        $values[] = $valueData;
+        $data = [
+            'product_sku' => $option->getProductSku(),
+            'title' => $option->getTitle(),
+            'type' => $option->getType(),
+            'is_require' => $option->getIsRequire(),
+            'sort_order' => $option->getSortOrder(),
+            'values' => $values,
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/options/' . $fixtureOption->getId(),
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => 'V1',
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            $data['option_id'] = $fixtureOption->getId();
+            $valueObject = $this->_webApiCall(
+                $serviceInfo, [ 'option_id' => $fixtureOption->getId(), 'option' => $data]
+            );
+        } else {
+            $valueObject = $this->_webApiCall(
+                $serviceInfo, ['option' => $data]
+            );
+        }
+
+        $values = end($valueObject['values']);
+        $this->assertEquals($valueData['price'], $values['price']);
+        $this->assertEquals($valueData['price_type'], $values['price_type']);
+        $this->assertEquals($valueData['sku'], $values['sku']);
+        $this->assertEquals('New Option Title', $values['title']);
+        $this->assertEquals(100, $values['sort_order']);
+    }
+
+    public function validOptionDataProvider()
+    {
+        return [
+            'drop_down' => ['drop_down'],
+            'checkbox' => ['checkbox'],
+            'radio' => ['radio'],
+            'multiple' => ['multiple']
+        ];
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionTypeListTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionTypeListTest.php
new file mode 100644
index 00000000000..eb0f890231e
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductCustomOptionTypeListTest.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Catalog\Api;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+
+class ProductCustomOptionTypeListTest extends WebapiAbstract
+{
+    const RESOURCE_PATH = '/V1/products/options/';
+
+    const SERVICE_NAME = 'catalogProductCustomOptionTypeListV1';
+
+    /**
+     * @magentoAppIsolation enabled
+     */
+    public function testGetTypes()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "types",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => 'V1',
+                'operation' => self::SERVICE_NAME . 'GetItems',
+            ],
+        ];
+        $types = $this->_webApiCall($serviceInfo);
+        $excepted = [
+            'label' => __('Drop-down'),
+            'code' => 'drop_down',
+            'group' => __('Select'),
+        ];
+        $this->assertGreaterThanOrEqual(10, count($types));
+        $this->assertContains($excepted, $types);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductGroupPriceManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductGroupPriceManagementTest.php
new file mode 100644
index 00000000000..03593130251
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductGroupPriceManagementTest.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Catalog\Api;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ProductGroupPriceManagementTest extends WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogProductGroupPriceManagementV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/products/';
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_group_prices.php
+     */
+    public function testGetList()
+    {
+        $productSku = 'simple_with_group_price';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $productSku . '/group-prices',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetList',
+            ],
+        ];
+        $groupPriceList = $this->_webApiCall($serviceInfo, ['productSku' => $productSku]);
+        $this->assertCount(2, $groupPriceList);
+        $this->assertEquals(9, $groupPriceList[0]['value']);
+        $this->assertEquals(7, $groupPriceList[1]['value']);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_group_prices.php
+     */
+    public function testDelete()
+    {
+        $productSku = 'simple_with_group_price';
+        $customerGroupId = \Magento\Customer\Model\GroupManagement::NOT_LOGGED_IN_ID;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $productSku . "/group-prices/" . $customerGroupId,
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Remove',
+            ],
+        ];
+        $requestData = ['productSku' => $productSku, 'customerGroupId' => $customerGroupId];
+        $this->assertTrue($this->_webApiCall($serviceInfo, $requestData));
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     */
+    public function testAdd()
+    {
+        $productSku = 'simple';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/' . $productSku . '/group-prices/1/price/10',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Add',
+            ],
+        ];
+        $this->_webApiCall($serviceInfo, ['productSku' => $productSku, 'customerGroupId' => 1, 'price' => 10]);
+        $objectManager = \Magento\TestFramework\ObjectManager::getInstance();
+        /** @var \Magento\Catalog\Api\ProductGroupPriceManagementInterface $service */
+        $service = $objectManager->get('Magento\Catalog\Api\ProductGroupPriceManagementInterface');
+        $prices = $service->getList($productSku);
+        $this->assertCount(1, $prices);
+        $this->assertEquals(10, $prices[0]->getValue());
+        $this->assertEquals(1, $prices[0]->getCustomerGroupId());
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     * @magentoApiDataFixture Magento/Store/_files/website.php
+     */
+    public function testAddForDifferentWebsite()
+    {
+        $productSku = 'simple';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/' . $productSku . '/group-prices/1/price/10',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Add',
+            ],
+
+        ];
+        $this->_webApiCall($serviceInfo, ['productSku' => $productSku, 'customerGroupId' => 1, 'price' => 10]);
+        $objectManager = \Magento\TestFramework\ObjectManager::getInstance();
+        /** @var \Magento\Catalog\Api\ProductGroupPriceManagementInterface $service */
+        $service = $objectManager->get('Magento\Catalog\Api\ProductGroupPriceManagementInterface');
+        $prices = $service->getList($productSku);
+        $this->assertCount(1, $prices);
+        $this->assertEquals(10, $prices[0]->getValue());
+        $this->assertEquals(1, $prices[0]->getCustomerGroupId());
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductLinkManagementInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductLinkManagementInterfaceTest.php
new file mode 100644
index 00000000000..67df2361c2c
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductLinkManagementInterfaceTest.php
@@ -0,0 +1,143 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Api;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ProductLinkManagementInterfaceTest extends WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogProductLinkManagementV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/products/';
+
+    /**
+     * @var \Magento\Framework\ObjectManager
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/products_crosssell.php
+     */
+    public function testGetLinkedProductsCrossSell()
+    {
+        $productSku = 'simple_with_cross';
+        $linkType = 'crosssell';
+
+        $this->assertLinkedProducts($productSku, $linkType);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/products_related.php
+     */
+    public function testGetLinkedProductsRelated()
+    {
+        $productSku = 'simple_with_cross';
+        $linkType = 'related';
+
+        $this->assertLinkedProducts($productSku, $linkType);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/products_upsell.php
+     */
+    public function testGetLinkedProductsUpSell()
+    {
+        $productSku = 'simple_with_upsell';
+        $linkType = 'upsell';
+
+        $this->assertLinkedProducts($productSku, $linkType);
+    }
+
+    /**
+     * @param string $productSku
+     * @param int $linkType
+     */
+    protected function assertLinkedProducts($productSku, $linkType)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $productSku . '/links/' . $linkType,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetLinkedItemsByType',
+            ],
+        ];
+
+        $actual = $this->_webApiCall($serviceInfo, ['productSku' => $productSku, 'type' => $linkType]);
+
+        $this->assertEquals('simple', $actual[0]['linked_product_type']);
+        $this->assertEquals('simple', $actual[0]['linked_product_sku']);
+        $this->assertEquals(1, $actual[0]['position']);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     * @magentoApiDataFixture Magento/Catalog/_files/product_virtual.php
+     */
+    public function testAssign()
+    {
+        $linkType = 'related';
+        $productSku = 'simple';
+        $linkData = [
+            'linked_product_type' => 'virtual',
+            'linked_product_sku' => 'virtual-product',
+            'position' => 100,
+            'product_sku' => 'simple',
+            'link_type' => 'related',
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $productSku . '/links/' . $linkType,
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'SetProductLinks',
+            ],
+        ];
+
+        $arguments = [
+            'productSku' => $productSku,
+            'items' => [$linkData],
+            'type' => $linkType,
+        ];
+
+        $this->_webApiCall($serviceInfo, $arguments);
+        $actual = $this->getLinkedProducts($productSku, 'related');
+        array_walk($actual, function (&$item) {
+            $item = $item->__toArray();
+        });
+        $this->assertEquals([$linkData], $actual);
+    }
+
+    /**
+     * Get list of linked products
+     *
+     * @param string $sku
+     * @param string $linkType
+     * @return \Magento\Catalog\Api\Data\ProductLinkInterface[]
+     */
+    protected function getLinkedProducts($sku, $linkType)
+    {
+        /** @var \Magento\Catalog\Model\ProductLink\Management $linkManagement */
+        $linkManagement = $this->objectManager->get('Magento\Catalog\Api\ProductLinkManagementInterface');
+        $linkedProducts = $linkManagement->getLinkedItemsByType($sku, $linkType);
+
+        return $linkedProducts;
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductLinkRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductLinkRepositoryInterfaceTest.php
new file mode 100644
index 00000000000..ff04d9044a1
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductLinkRepositoryInterfaceTest.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Api;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ProductLinkRepositoryInterfaceTest extends WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogProductLinkRepositoryV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/products/';
+
+    /**
+     * @var \Magento\Framework\ObjectManager
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/products_related_multiple.php
+     * @magentoAppIsolation enabled
+     */
+    public function testDelete()
+    {
+        $productSku = 'simple_with_cross';
+        $linkedSku = 'simple';
+        $linkType = 'related';
+        $this->_webApiCall(
+            [
+                'rest' => [
+                    'resourcePath' => self::RESOURCE_PATH . $productSku . '/links/' . $linkType . '/' . $linkedSku,
+                    'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+                ],
+                'soap' => [
+                    'service' => self::SERVICE_NAME,
+                    'serviceVersion' => self::SERVICE_VERSION,
+                    'operation' => self::SERVICE_NAME . 'DeleteById',
+                ],
+            ],
+            [
+                'productSku' => $productSku,
+                'type' => $linkType,
+                'linkedProductSku' => $linkedSku
+            ]
+        );
+        /** @var \Magento\Catalog\Model\ProductLink\Management $linkManagement */
+        $linkManagement = $this->objectManager->create('Magento\Catalog\Api\ProductLinkManagementInterface');
+        $linkedProducts = $linkManagement->getLinkedItemsByType($productSku, $linkType);
+        $this->assertCount(1, $linkedProducts);
+        /** @var \Magento\Catalog\Api\Data\ProductLinkInterface $product */
+        $product = current($linkedProducts);
+        $this->assertEquals($product->getLinkedProductSku(), 'simple_with_cross_two');
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/products_related.php
+     */
+    public function testSave()
+    {
+        $productSku = 'simple_with_cross';
+        $linkType = 'related';
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $productSku . '/links/' . $linkType,
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+
+        $this->_webApiCall(
+            $serviceInfo,
+            [
+                'entity' => [
+                    'product_sku' => 'simple_with_cross',
+                    'link_type' => 'related',
+                    'linked_product_sku' => 'simple',
+                    'linked_product_type' => 'simple',
+                    'position' => 1000,
+                ]
+            ]
+        );
+
+        /** @var \Magento\Catalog\Model\ProductLink\Management $linkManagement */
+        $linkManagement = $this->objectManager->get('Magento\Catalog\Api\ProductLinkManagementInterface');
+        $actual = $linkManagement->getLinkedItemsByType($productSku, $linkType);
+        $this->assertCount(1, $actual, 'Invalid actual linked products count');
+        $this->assertEquals(1000, $actual[0]->getPosition(), 'Product position is not updated');
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductLinkTypeListTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductLinkTypeListTest.php
new file mode 100644
index 00000000000..3fb46da2b49
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductLinkTypeListTest.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Api;
+
+use Magento\Catalog\Model\Product\Link;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ProductLinkTypeListTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogProductLinkTypeListV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/products/';
+
+    public function testGetItems()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . 'links/types',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetItems',
+            ],
+        ];
+        $actual = $this->_webApiCall($serviceInfo);
+        $expectedItems = ['name' => 'related', 'code' => Link::LINK_TYPE_RELATED];
+        $this->assertContains($expectedItems, $actual);
+    }
+
+    public function testGetItemAttributes()
+    {
+        $linkType = 'related';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . 'links/' . $linkType . '/attributes',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetItemAttributes',
+            ],
+        ];
+        $actual = $this->_webApiCall($serviceInfo, ['type' => $linkType]);
+        $expected = [['code' => 'position', 'type' => 'int']];
+        $this->assertEquals($expected, $actual);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductMediaAttributeManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductMediaAttributeManagementTest.php
new file mode 100644
index 00000000000..8939bf5c362
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductMediaAttributeManagementTest.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Api;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ProductMediaAttributeManagementTest extends WebapiAbstract
+{
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/attribute_set_with_image_attribute.php
+     */
+    public function testGetList()
+    {
+        $attributeSetName = 'attribute_set_with_media_attribute';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/media/types/' . $attributeSetName,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => 'catalogProductMediaAttributeManagementV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'catalogProductMediaAttributeManagementV1GetList',
+            ],
+        ];
+
+        $requestData = [
+            'attributeSetName' => $attributeSetName,
+        ];
+
+        $mediaAttributes = $this->_webApiCall($serviceInfo, $requestData);
+
+        $this->assertNotEmpty($mediaAttributes);
+        $attribute = $this->getAttributeByCode($mediaAttributes,  'funny_image');
+        $this->assertNotNull($attribute);
+        $this->assertEquals('Funny image', $attribute['default_frontend_label']);
+        $this->assertEquals(1, $attribute['is_user_defined']);
+    }
+
+    /**
+     * Retrieve attribute based on given attribute code
+     *
+     * @param array $attributeList
+     * @param string $attributeCode
+     * @return array|null
+     */
+    protected function getAttributeByCode($attributeList, $attributeCode)
+    {
+        foreach ($attributeList as $attribute) {
+            if ($attributeCode == $attribute['attribute_code']) {
+                return $attribute;
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php
new file mode 100644
index 00000000000..7b9e84a65f4
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductRepositoryInterfaceTest.php
@@ -0,0 +1,279 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Api;
+
+use Magento\Catalog\Api\Data\ProductInterface;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Exception as HTTPExceptionCodes;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ProductRepositoryInterfaceTest extends WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogProductRepositoryV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/products';
+
+    private $productData = [
+        [
+            ProductInterface::SKU => 'simple',
+            ProductInterface::NAME => 'Simple Related Product',
+            ProductInterface::TYPE_ID => 'simple',
+            ProductInterface::PRICE => 10,
+        ],
+        [
+            ProductInterface::SKU => 'simple_with_cross',
+            ProductInterface::NAME => 'Simple Product With Related Product',
+            ProductInterface::TYPE_ID => 'simple',
+            ProductInterface::PRICE => 10
+        ],
+    ];
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/products_related.php
+     */
+    public function testGet()
+    {
+        $productData = $this->productData[0];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $productData[ProductInterface::SKU],
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Get',
+            ],
+        ];
+
+        $response = $this->_webApiCall($serviceInfo, ['productSku' => $productData[ProductInterface::SKU]]);
+        foreach ([ProductInterface::SKU, ProductInterface::NAME, ProductInterface::PRICE] as $key) {
+            $this->assertEquals($productData[$key], $response[$key]);
+        }
+    }
+
+    public function testGetNoSuchEntityException()
+    {
+        $invalidSku = '(nonExistingSku)';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $invalidSku,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Get',
+            ],
+        ];
+
+        $expectedMessage = 'Requested product doesn\'t exist';
+
+        try {
+            $this->_webApiCall($serviceInfo, ['productSku' => $invalidSku]);
+            $this->fail("Expected throwing exception");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "SoapFault does not contain expected message."
+            );
+        } catch (\Exception $e) {
+            $errorObj = $this->processRestExceptionResult($e);
+            $this->assertEquals($expectedMessage, $errorObj['message']);
+            $this->assertEquals(HTTPExceptionCodes::HTTP_NOT_FOUND, $e->getCode());
+        }
+    }
+
+    /**
+     * @return array
+     */
+    public function productCreationProvider()
+    {
+        $productBuilder = function ($data) {
+            return array_replace_recursive(
+                $this->getSimpleProductData(),
+                $data
+            );
+        };
+        return [
+            [$productBuilder([ProductInterface::TYPE_ID => 'simple', ProductInterface::SKU => 'psku-test-1'])],
+            [$productBuilder([ProductInterface::TYPE_ID => 'virtual', ProductInterface::SKU => 'psku-test-2'])],
+        ];
+    }
+
+    /**
+     * @dataProvider productCreationProvider
+     */
+    public function testCreate($product)
+    {
+        $response = $this->saveProduct($product);
+        $this->assertArrayHasKey(ProductInterface::SKU, $response);
+        $this->deleteProduct($product[ProductInterface::SKU]);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     */
+    public function testUpdate()
+    {
+        $productData = [
+            ProductInterface::NAME => 'Very Simple Product', //new name
+            ProductInterface::SKU => 'simple', //sku from fixture
+        ];
+        $product = $this->getSimpleProductData($productData);
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_REST) {
+            $product[ProductInterface::SKU] = null;
+        }
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $productData[ProductInterface::SKU],
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $requestData = ['product' => $product];
+        $response =  $this->_webApiCall($serviceInfo, $requestData);
+
+        $this->assertArrayHasKey(ProductInterface::SKU, $response);
+        $this->assertArrayHasKey(ProductInterface::NAME, $response);
+        $this->assertEquals($productData[ProductInterface::NAME], $response[ProductInterface::NAME]);
+        $this->assertEquals($productData[ProductInterface::SKU], $response[ProductInterface::SKU]);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     */
+    public function testDelete()
+    {
+        $response = $this->deleteProduct('simple');
+        $this->assertTrue($response);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     */
+    public function testGetList()
+    {
+        $searchCriteria = [
+            'searchCriteria' => [
+                'filter_groups' => [
+                    [
+                        'filters' => [
+                            [
+                                'field' => 'sku',
+                                'value' => 'simple',
+                                'condition_type' => 'eq',
+                            ],
+                        ],
+                    ],
+                ],
+                'current_page' => 1,
+                'page_size' => 2,
+            ],
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetList',
+            ],
+        ];
+
+        $response = $this->_webApiCall($serviceInfo, $searchCriteria);
+
+        $this->assertArrayHasKey('search_criteria', $response);
+        $this->assertArrayHasKey('total_count', $response);
+        $this->assertArrayHasKey('items', $response);
+
+        $this->assertEquals($searchCriteria['searchCriteria'], $response['search_criteria']);
+        $this->assertTrue($response['total_count'] > 0);
+        $this->assertTrue(count($response['items']) > 0);
+
+        $this->assertNotNull($response['items'][0]['sku']);
+        $this->assertEquals('simple', $response['items'][0]['sku']);
+    }
+
+    /**
+     * Get Simple Product Data
+     *
+     * @param array $productData
+     * @return array
+     */
+    protected function getSimpleProductData($productData = [])
+    {
+        return [
+            ProductInterface::SKU => isset($productData[ProductInterface::SKU])
+                ? $productData[ProductInterface::SKU] : uniqid('sku-', true),
+            ProductInterface::NAME => isset($productData[ProductInterface::NAME])
+                ? $productData[ProductInterface::NAME] : uniqid('sku-', true),
+            ProductInterface::VISIBILITY => 4,
+            ProductInterface::TYPE_ID => 'simple',
+            ProductInterface::PRICE => 3.62,
+            ProductInterface::STATUS => 1,
+            ProductInterface::TYPE_ID => 'simple',
+            ProductInterface::ATTRIBUTE_SET_ID => 4,
+            'custom_attributes' => [
+                ['attribute_code' => 'cost', 'value' => ''],
+                ['attribute_code' => 'description', 'value' => 'Description'],
+            ]
+        ];
+    }
+
+    /**
+     * @param $product
+     * @return mixed
+     */
+    protected function saveProduct($product)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $requestData = ['product' => $product];
+        return $this->_webApiCall($serviceInfo, $requestData);
+    }
+
+    /**
+     * Delete Product
+     *
+     * @param string $sku
+     * @return boolean
+     */
+    protected function deleteProduct($sku)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $sku,
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'DeleteById',
+            ],
+        ];
+
+        return (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) ?
+            $this->_webApiCall($serviceInfo, ['productSku' => $sku]) : $this->_webApiCall($serviceInfo);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductTierPriceManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductTierPriceManagementTest.php
new file mode 100644
index 00000000000..04f3d9c3d44
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductTierPriceManagementTest.php
@@ -0,0 +1,205 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Catalog\Api;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ProductTierPriceManagementTest extends WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogProductTierPriceManagementV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/products/';
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     * @dataProvider getListDataProvider
+     */
+    public function testGetList($customerGroupId, $count, $value, $qty)
+    {
+        $productSku = 'simple';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $productSku . '/group-prices/' . $customerGroupId . '/tiers',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetList',
+            ],
+        ];
+
+        $groupPriceList = $this->_webApiCall(
+                $serviceInfo,
+                ['productSku' => $productSku, 'customerGroupId' => $customerGroupId]
+            );
+
+        $this->assertCount($count, $groupPriceList);
+        if ($count) {
+            $this->assertEquals($value, $groupPriceList[0]['value']);
+            $this->assertEquals($qty, $groupPriceList[0]['qty']);
+        }
+    }
+
+    public function getListDataProvider()
+    {
+        return [
+            [0, 1, 5, 3],
+            [1, 0, null, null],
+            ['all', 2, 8, 2],
+        ];
+    }
+
+    /**
+     * @param string|int $customerGroupId
+     * @param int $qty
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     * @dataProvider deleteDataProvider
+     */
+    public function testDelete($customerGroupId, $qty)
+    {
+        $productSku = 'simple';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' =>   self::RESOURCE_PATH
+                    . $productSku . "/group-prices/" . $customerGroupId . "/tiers/" . $qty,
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Remove',
+            ],
+        ];
+        $requestData = ['productSku' => $productSku, 'customerGroupId' => $customerGroupId, 'qty' => $qty];
+        $this->assertTrue($this->_webApiCall($serviceInfo, $requestData));
+    }
+
+    public function deleteDataProvider()
+    {
+        return [
+            'delete_tier_price_for_specific_customer_group' => [0, 3],
+            'delete_tier_price_for_all_customer_group' => ['all', 5]
+        ];
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     * @magentoAppIsolation enabled
+     */
+    public function testAdd()
+    {
+        $productSku = 'simple';
+        $customerGroupId = 1;
+        $qty = 50;
+        $price = 10;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/' . $productSku
+                    . '/group-prices/' . $customerGroupId . '/tiers/' . $qty . '/price/' . $price,
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Add',
+            ],
+        ];
+
+        $requestData = [
+            'productSku' => $productSku,
+            'customerGroupId' => $customerGroupId,
+            'qty' => $qty,
+            'price' => $price,
+        ];
+        $this->_webApiCall($serviceInfo, $requestData);
+        $objectManager = \Magento\TestFramework\ObjectManager::getInstance();
+        /** @var \Magento\Catalog\Api\ProductTierPriceManagementInterface $service */
+        $service = $objectManager->get('Magento\Catalog\Api\ProductTierPriceManagementInterface');
+        $prices = $service->getList($productSku, 1);
+        $this->assertCount(1, $prices);
+        $this->assertEquals(10, $prices[0]->getValue());
+        $this->assertEquals(50, $prices[0]->getQty());
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     * @magentoAppIsolation enabled
+     */
+    public function testAddWithAllCustomerGrouped()
+    {
+        $productSku = 'simple';
+        $customerGroupId = 'all';
+        $qty = 50;
+        $price = 20;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/' . $productSku
+                    . '/group-prices/' . $customerGroupId . '/tiers/' . $qty . '/price/' . $price,
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Add',
+            ],
+        ];
+        $requestData = [
+            'productSku' => $productSku,
+            'customerGroupId' => $customerGroupId,
+            'qty' => $qty,
+            'price' => $price,
+        ];
+        $this->_webApiCall($serviceInfo, $requestData);
+        $objectManager = \Magento\TestFramework\ObjectManager::getInstance();
+        /** @var \Magento\Catalog\Api\ProductTierPriceManagementInterface $service */
+        $service = $objectManager->get('Magento\Catalog\Api\ProductTierPriceManagementInterface');
+        $prices = $service->getList($productSku, 'all');
+        $this->assertCount(3, $prices);
+        $this->assertEquals(20, (int)$prices[2]->getValue());
+        $this->assertEquals(50, (int)$prices[2]->getQty());
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     * @magentoAppIsolation enabled
+     */
+    public function testUpdateWithAllGroups()
+    {
+        $productSku = 'simple';
+        $customerGroupId = 'all';
+        $qty = 2;
+        $price = 20;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/' . $productSku
+                    . '/group-prices/' . $customerGroupId . '/tiers/' . $qty . '/price/' . $price,
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Add',
+            ],
+        ];
+        $requestData = [
+            'productSku' => $productSku,
+            'customerGroupId' => $customerGroupId,
+            'qty' => $qty,
+            'price' => $price,
+        ];
+        $this->_webApiCall($serviceInfo, $requestData);
+        $objectManager = \Magento\TestFramework\ObjectManager::getInstance();
+        /** @var \Magento\Catalog\Api\ProductTierPriceManagementInterface $service */
+        $service = $objectManager->get('Magento\Catalog\Api\ProductTierPriceManagementInterface');
+        $prices = $service->getList($productSku, 'all');
+        $this->assertCount(2, $prices);
+        $this->assertEquals(20, (int)$prices[0]->getValue());
+        $this->assertEquals(2, (int)$prices[0]->getQty());
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductTypeListTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductTypeListTest.php
new file mode 100644
index 00000000000..da15ba53f92
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductTypeListTest.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Catalog\Api;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ProductTypeListTest extends WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogProductTypeListV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/products/';
+
+    public function testGetProductTypes()
+    {
+        $expectedProductTypes = [
+            [
+                'name' => 'simple',
+                'label' => 'Simple Product',
+            ],
+            [
+                'name' => 'virtual',
+                'label' => 'Virtual Product',
+            ],
+            [
+                'name' => 'downloadable',
+                'label' => 'Downloadable Product',
+            ],
+            [
+                'name' => 'bundle',
+                'label' => 'Bundle Product',
+            ],
+            [
+                'name' => 'configurable',
+                'label' => 'Configurable Product',
+            ],
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/types',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetProductTypes',
+            ],
+        ];
+
+        $productTypes = $this->_webApiCall($serviceInfo);
+
+        foreach ($expectedProductTypes as $expectedProductType) {
+            $this->assertContains($expectedProductType, $productTypes);
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/_files/product_options.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/_files/product_options.php
new file mode 100644
index 00000000000..a302a11ae93
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/_files/product_options.php
@@ -0,0 +1,162 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+return [
+    [
+        'title' => 'test_option_code_1',
+        'type' => 'field',
+        'sort_order' => 1,
+        'is_require' => 1,
+        'price' => 10,
+        'price_type' => 'fixed',
+        'sku' => 'sku1',
+        'max_characters' => 10,
+        'values' => [],
+    ],
+    [
+        'title' => 'area option',
+        'type' => 'area',
+        'sort_order' => 2,
+        'is_require' => 0,
+        'price' => 20,
+        'price_type' => 'percent',
+        'sku' => 'sku2',
+        'max_characters' => 20,
+        'values' => []
+    ],
+    [
+        'title' => 'file option',
+        'type' => 'file',
+        'sort_order' => 3,
+        'is_require' => 1,
+        'price' => 30,
+        'price_type' => 'percent',
+        'sku' => 'sku3',
+        'file_extension' => 'jpg, png, gif',
+        'image_size_x' => 10,
+        'image_size_y' => 20,
+        'values' => []
+    ],
+    [
+        'title' => 'drop_down option',
+        'type' => 'drop_down',
+        'sort_order' => 4,
+        'is_require' => 1,
+        'values' => [
+            [
+                'title' => 'drop_down option 1',
+                'sort_order' => 1,
+                'price' => 10,
+                'price_type' => 'fixed',
+                'sku' => 'drop_down option 1 sku',
+
+            ],
+            [
+                'title' => 'drop_down option 2',
+                'sort_order' => 2,
+                'price' => 20,
+                'price_type' => 'fixed',
+                'sku' => 'drop_down option 2 sku'
+            ],
+        ],
+    ],
+    [
+        'title' => 'radio option',
+        'type' => 'radio',
+        'sort_order' => 5,
+        'is_require' => 1,
+        'values' => [
+            [
+                'title' => 'radio option 1',
+                'sort_order' => 1,
+                'price' => 10,
+                'price_type' => 'fixed',
+                'sku' => 'radio option 1 sku',
+            ],
+            [
+                'title' => 'radio option 2',
+                'sort_order' => 2,
+                'price' => 20,
+                'price_type' => 'fixed',
+                'sku' => 'radio option 2 sku',
+            ],
+        ],
+    ],
+    [
+        'title' => 'checkbox option',
+        'type' => 'checkbox',
+        'sort_order' => 6,
+        'is_require' => 1,
+        'values' => [
+            [
+                'title' => 'checkbox option 1',
+                'sort_order' => 1,
+                'price' => 10,
+                'price_type' => 'fixed',
+                'sku' => 'checkbox option 1 sku',
+            ],
+            [
+                'title' => 'checkbox option 2',
+                'sort_order' => 2,
+                'price' => 20,
+                'price_type' => 'fixed',
+                'sku' => 'checkbox option 2 sku'
+            ],
+        ],
+    ],
+    [
+        'title' => 'multiple option',
+        'type' => 'multiple',
+        'sort_order' => 7,
+        'is_require' => 1,
+        'values' => [
+            [
+                'title' => 'multiple option 1',
+                'sort_order' => 1,
+                'price' => 10,
+                'price_type' => 'fixed',
+                'sku' => 'multiple option 1 sku',
+            ],
+            [
+                'title' => 'multiple option 2',
+                'sort_order' => 2,
+                'price' => 20,
+                'price_type' => 'fixed',
+                'sku' => 'multiple option 2 sku'
+            ],
+        ],
+    ],
+    [
+        'title' => 'date option',
+        'type' => 'date',
+        'is_require' => 1,
+        'sort_order' => 8,
+        'price' => 80.0,
+        'price_type' => 'fixed',
+        'sku' => 'date option sku',
+        'values' => []
+
+    ],
+    [
+        'title' => 'date_time option',
+        'type' => 'date_time',
+        'is_require' => 1,
+        'sort_order' => 9,
+        'price' => 90.0,
+        'price_type' => 'fixed',
+        'sku' => 'date_time option sku',
+        'values' => []
+    ],
+    [
+        'title' => 'time option',
+        'type' => 'time',
+        'is_require' => 1,
+        'sort_order' => 10,
+        'price' => 100.0,
+        'price_type' => 'fixed',
+        'sku' => 'time option sku',
+        'values' => []
+    ],
+];
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/_files/product_options_negative.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/_files/product_options_negative.php
new file mode 100644
index 00000000000..24fb82474ec
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/_files/product_options_negative.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+return [
+    'empty_required_field' => [
+        'title' => '',
+        'type' => 'field',
+        'sort_order' => 1,
+        'is_require' => 1,
+        'price' => 10,
+        'price_type' => 'fixed',
+        'sku' => 'sku1',
+        'max_characters' => 10,
+    ],
+    'negative_price' => [
+        'title' => 'area option',
+        'type' => 'area',
+        'sort_order' => 2,
+        'is_require' => 0,
+        'price' => -20,
+        'price_type' => 'percent',
+        'sku' => 'sku2',
+        'max_characters' => 20,
+
+    ],
+    'negative_value_of_image_size' => [
+        'title' => 'file option',
+        'type' => 'file',
+        'sort_order' => 3,
+        'is_require' => 1,
+        'price' => 30,
+        'price_type' => 'percent',
+        'sku' => 'sku3',
+        'file_extension' => 'jpg',
+        'image_size_x' => -10,
+        'image_size_y' => -20,
+    ],
+    'option_with_type_select_without_options' => [
+        'title' => 'drop_down option',
+        'type' => 'drop_down',
+        'sort_order' => 4,
+        'is_require' => 1,
+    ],
+    'title_is_empty' => [
+        'title' => 'radio option',
+        'type' => 'radio',
+        'sort_order' => 5,
+        'is_require' => 1,
+        'values' => [
+            [
+                'price' => 10,
+                'price_type' => 'fixed',
+                'sku' => 'radio option 1 sku',
+                'title' => '',
+                'sort_order' => 1,
+            ],
+        ],
+    ],
+    'option_with_non_existing_price_type' => [
+        'title' => 'checkbox option',
+        'type' => 'checkbox',
+        'sort_order' => 6,
+        'is_require' => 1,
+        'values' => [
+            [
+                'price' => 10,
+                'price_type' => 'fixed_one',
+                'sku' => 'checkbox option 1 sku',
+                'title' => 'checkbox option 1',
+                'sort_order' => 1,
+            ],
+        ],
+    ],
+    'option_with_non_existing_option_type' => [
+        'title' => 'multiple option',
+        'type' => 'multiple_some_value',
+        'sort_order' => 7,
+        'is_require' => 1,
+        'values' => [
+            [
+                'price' => 10,
+                'price_type' => 'fixed',
+                'sku' => 'multiple option 1 sku',
+                'title' => 'multiple option 1',
+                'sort_order' => 1,
+            ],
+        ],
+    ],
+];
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/_files/test_image.jpg b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/_files/test_image.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..ad6b747f73dd9d20f73b8fc780e74d1ff7952762
GIT binary patch
literal 2004
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

literal 0
HcmV?d00001

diff --git a/dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/LowStockItemsTest.php b/dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/LowStockItemsTest.php
new file mode 100644
index 00000000000..67c42fe79b8
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/LowStockItemsTest.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\CatalogInventory\Api;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+/**
+ * Class LowStockItemsTest
+ */
+class LowStockItemsTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/stockItem/lowStock/';
+
+    /**
+     * @param float $qty
+     * @param int $currentPage
+     * @param int $pageSize
+     * @param array $result
+     * @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php
+     * @dataProvider getLowStockItemsDataProvider
+     */
+    public function testGetLowStockItems($qty, $currentPage, $pageSize, $result)
+    {
+        $requestData = ['websiteId' => 1, 'qty' => $qty, 'pageSize' => $pageSize, 'currentPage' => $currentPage];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '?' . http_build_query($requestData),
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => 'catalogInventoryStockRegistryV1',
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'catalogInventoryStockRegistryV1GetLowStockItems',
+            ],
+        ];
+        $output = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertArrayHasKey('items', $output);
+    }
+
+    /**
+     * @return array
+     */
+    public function getLowStockItemsDataProvider()
+    {
+        return [
+            [
+                100,
+                1,
+                10,
+                [
+                    'search_criteria' => ['current_page' => 1, 'page_size' => 10, 'qty' => 100],
+                    'total_count' => 2,
+                    'items' => [
+                        [
+                            'product_id' => 10,
+                            'website_id' => 1,
+                            'stock_id' => 1,
+                            'qty' => 100,
+                            'stock_status' => null,
+                            'stock_item' => null,
+                        ],
+                        [
+                            'product_id' => 12,
+                            'website_id' => 1,
+                            'stock_id' => 1,
+                            'qty' => 140,
+                            'stock_status' => null,
+                            'stock_item' => null
+                        ],
+                    ]
+                ],
+            ],
+        ];
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/StockItemTest.php b/dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/StockItemTest.php
new file mode 100644
index 00000000000..bab5b01aa08
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/StockItemTest.php
@@ -0,0 +1,222 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\CatalogInventory\Api;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+
+/**
+ * Class StockItemTest
+ */
+class StockItemTest extends WebapiAbstract
+{
+    /**
+     * Service name
+     */
+    const SERVICE_NAME = 'catalogInventoryStockItemApi';
+
+    /**
+     * Service version
+     */
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * Resource path
+     */
+    const RESOURCE_PATH = '/V1/stockItem';
+
+    /** @var \Magento\Catalog\Model\Resource\Product\Collection */
+    protected $productCollection;
+
+    /** @var \Magento\Framework\ObjectManagerInterface */
+    protected $objectManager;
+
+    /**
+     * Execute per test initialization
+     */
+    public function setUp()
+    {
+        $this->objectManager = Bootstrap::getObjectManager();
+        $this->productCollection = $this->objectManager->get('Magento\Catalog\Model\Resource\Product\Collection');
+    }
+
+    /**
+     * Execute per test cleanup
+     */
+    public function tearDown()
+    {
+        /** @var \Magento\Framework\Registry $registry */
+        $registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry');
+
+        $registry->unregister('isSecureArea');
+        $registry->register('isSecureArea', true);
+
+        $this->productCollection->addFieldToFilter('entity_id', ['in' => [10, 11, 12]])->delete();
+        unset($this->productCollection);
+
+        $registry->unregister('isSecureArea');
+        $registry->register('isSecureArea', false);
+    }
+
+    /**
+     * @param array $result
+     * @return array
+     */
+    protected function getStockItemBySku($result)
+    {
+        $productSku = 'simple1';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/$productSku",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => 'catalogInventoryStockRegistryV1',
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'catalogInventoryStockRegistryV1GetStockItemBySku',
+            ],
+        ];
+        $arguments = ['productSku' => $productSku];
+        $apiResult = $this->_webApiCall($serviceInfo, $arguments);
+        $result['item_id'] = $apiResult['item_id'];
+        $this->assertEquals($result, $apiResult, 'The stock data does not match.');
+        return $apiResult;
+    }
+
+    /**
+     * @param array $newData
+     * @param array $expectedResult
+     * @param array $fixtureData
+     * @magentoApiDataFixture Magento/Catalog/_files/multiple_products.php
+     * @dataProvider saveStockItemBySkuWithWrongInputDataProvider
+     */
+    public function testStockItemPUTWithWrongInput($newData, $expectedResult, $fixtureData)
+    {
+        $stockItemOld = $this->getStockItemBySku($fixtureData);
+        $productSku = 'simple1';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/$productSku",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => 'catalogInventoryStockRegistryV1',
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'catalogInventoryStockRegistryV1UpdateStockItemBySku',
+            ],
+        ];
+
+        $stockItemDetailsDo = $this->objectManager->get(
+            'Magento\CatalogInventory\Api\Data\StockItemInterfaceBuilder'
+        )->populateWithArray($newData)->create();
+        $arguments = ['productSku' => $productSku, 'stockItem' => $stockItemDetailsDo->getData()];
+        $this->assertEquals($stockItemOld['item_id'], $this->_webApiCall($serviceInfo, $arguments));
+
+        $stockItemFactory = $this->objectManager->get('Magento\CatalogInventory\Api\Data\StockItemInterfaceFactory');
+        $stockItem = $stockItemFactory->create();
+        $stockItemResource = $this->objectManager->get('Magento\CatalogInventory\Model\Resource\Stock\Item');
+        $stockItemResource->loadByProductId($stockItem, $stockItemOld['product_id'], $stockItemOld['website_id']);
+        $expectedResult['item_id'] = $stockItem->getItemId();
+        $this->assertEquals($expectedResult, $stockItem->getData());
+    }
+
+    /**
+     * @return array
+     */
+    public function saveStockItemBySkuWithWrongInputDataProvider()
+    {
+        return [
+            [
+                [
+                    'item_id' => 222,
+                    'product_id' => 222,
+                    'stock_id' => 1,
+                    'website_id' => 1,
+                    'qty' => '111.0000',
+                    'min_qty' => '0.0000',
+                    'use_config_min_qty' => 1,
+                    'is_qty_decimal' => 0,
+                    'backorders' => 0,
+                    'use_config_backorders' => 1,
+                    'min_sale_qty' => '1.0000',
+                    'use_config_min_sale_qty' => 1,
+                    'max_sale_qty' => '0.0000',
+                    'use_config_max_sale_qty' => 1,
+                    'is_in_stock' => 1,
+                    'low_stock_date' => '',
+                    'notify_stock_qty' => NULL,
+                    'use_config_notify_stock_qty' => 1,
+                    'manage_stock' => 0,
+                    'use_config_manage_stock' => 1,
+                    'stock_status_changed_auto' => 0,
+                    'use_config_qty_increments' => 1,
+                    'qty_increments' => '0.0000',
+                    'use_config_enable_qty_inc' => 1,
+                    'enable_qty_increments' => 0,
+                    'is_decimal_divided' => 0,
+                    'show_default_notification_message' => false,
+                ],
+                [
+                    'item_id' => '1',
+                    'product_id' => '10',
+                    'stock_id' => '1',
+                    'qty' => '111.0000',
+                    'min_qty' => '0.0000',
+                    'use_config_min_qty' => '1',
+                    'is_qty_decimal' => '0',
+                    'backorders' => '0',
+                    'use_config_backorders' => '1',
+                    'min_sale_qty' => '1.0000',
+                    'use_config_min_sale_qty' => '1',
+                    'max_sale_qty' => '0.0000',
+                    'use_config_max_sale_qty' => '1',
+                    'is_in_stock' => '1',
+                    'low_stock_date' => NULL,
+                    'notify_stock_qty' => NULL,
+                    'use_config_notify_stock_qty' => '1',
+                    'manage_stock' => '0',
+                    'use_config_manage_stock' => '1',
+                    'stock_status_changed_auto' => '0',
+                    'use_config_qty_increments' => '1',
+                    'qty_increments' => '0.0000',
+                    'use_config_enable_qty_inc' => '1',
+                    'enable_qty_increments' => '0',
+                    'is_decimal_divided' => '0',
+                    'website_id' => '1',
+                    'type_id' => 'simple',
+                ],
+                [
+                    'item_id' => 1,
+                    'product_id' => 10,
+                    'website_id' => 1,
+                    'stock_id' => 1,
+                    'qty' => 100,
+                    'is_in_stock' => 1,
+                    'is_qty_decimal' => '',
+                    'show_default_notification_message' => '',
+                    'use_config_min_qty' => 1,
+                    'min_qty' => 0,
+                    'use_config_min_sale_qty' => 1,
+                    'min_sale_qty' => 1,
+                    'use_config_max_sale_qty' => 1,
+                    'max_sale_qty' => 10000,
+                    'use_config_backorders' => 1,
+                    'backorders' => 0,
+                    'use_config_notify_stock_qty' => 1,
+                    'notify_stock_qty' => 1,
+                    'use_config_qty_increments' => 1,
+                    'qty_increments' => 0,
+                    'use_config_enable_qty_inc' => 1,
+                    'enable_qty_increments' => '',
+                    'use_config_manage_stock' => 1,
+                    'manage_stock' => 1,
+                    'low_stock_date' => 0,
+                    'is_decimal_divided' => '',
+                    'stock_status_changed_auto' => 0
+                ],
+            ],
+        ];
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/StockStatusTest.php b/dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/StockStatusTest.php
new file mode 100644
index 00000000000..1ab00d4b085
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/CatalogInventory/Api/StockStatusTest.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\CatalogInventory\Api;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+/**
+ * Class StockStatusTest
+ */
+class StockStatusTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/stockStatus';
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     */
+    public function testGetProductStockStatus()
+    {
+        $productSku = 'simple';
+        $objectManager = Bootstrap::getObjectManager();
+
+        /** @var \Magento\Catalog\Model\Product $product */
+        $product = $objectManager->get('Magento\Catalog\Model\Product')->load(1);
+        $expectedData = $product->getQuantityAndStockStatus();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/$productSku",
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => 'catalogInventoryStockRegistryV1',
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'catalogInventoryStockRegistryV1GetStockStatusBySku',
+            ],
+        ];
+
+        $requestData = ['productSku' => $productSku];
+        $actualData = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertArrayHasKey('stock_item', $actualData);
+        $this->assertEquals($expectedData['is_in_stock'], $actualData['stock_item']['is_in_stock']);
+        $this->assertEquals($expectedData['qty'], $actualData['stock_item']['qty']);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Address/Billing/ReadServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Address/Billing/ReadServiceTest.php
new file mode 100644
index 00000000000..961d7caf314
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Address/Billing/ReadServiceTest.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Checkout\Service\V1\Address\Billing;
+
+use Magento\Checkout\Service\V1\Data\Cart\Address;
+use Magento\Checkout\Service\V1\Data\Cart\Address\Region;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ReadServiceTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+    const SERVICE_NAME = 'checkoutAddressBillingReadServiceV1';
+    const RESOURCE_PATH = '/V1/carts/';
+
+    /**
+     * @var \Magento\TestFramework\ObjectManager
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php
+     */
+    public function testGetAddress()
+    {
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_1', 'reserved_order_id');
+
+        /** @var \Magento\Sales\Model\Quote\Address $address */
+        $address = $quote->getBillingAddress();
+
+        $data = [
+            Address::KEY_COUNTRY_ID => $address->getCountryId(),
+            Address::KEY_ID => (int)$address->getId(),
+            Address::KEY_CUSTOMER_ID => $address->getCustomerId(),
+            Address::KEY_REGION => [
+                Region::REGION => $address->getRegion(),
+                Region::REGION_ID => $address->getRegionId(),
+                Region::REGION_CODE => $address->getRegionCode(),
+            ],
+            Address::KEY_STREET => $address->getStreet(),
+            Address::KEY_COMPANY => $address->getCompany(),
+            Address::KEY_TELEPHONE => $address->getTelephone(),
+            Address::KEY_POSTCODE => $address->getPostcode(),
+            Address::KEY_CITY => $address->getCity(),
+            Address::KEY_FIRSTNAME => $address->getFirstname(),
+            Address::KEY_LASTNAME => $address->getLastname(),
+            Address::KEY_EMAIL => $address->getEmail(),
+            Address::CUSTOM_ATTRIBUTES_KEY => [['attribute_code' => 'disable_auto_group_change', 'value' => null]],
+        ];
+
+        $cartId = $quote->getId();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/billing-address',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetAddress',
+            ],
+        ];
+
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            unset($data[Address::KEY_PREFIX]);
+            unset($data[Address::KEY_SUFFIX]);
+            unset($data[Address::KEY_MIDDLENAME]);
+            unset($data[Address::KEY_FAX]);
+            unset($data[Address::KEY_VAT_ID]);
+        }
+
+        $requestData = ["cartId" => $cartId];
+        $this->assertEquals($data, $this->_webApiCall($serviceInfo, $requestData));
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Address/Billing/WriteServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Address/Billing/WriteServiceTest.php
new file mode 100644
index 00000000000..d69ab59b5d9
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Address/Billing/WriteServiceTest.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Checkout\Service\V1\Address\Billing;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class WriteServiceTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+    const SERVICE_NAME = 'checkoutAddressBillingWriteServiceV1';
+    const RESOURCE_PATH = '/V1/carts/';
+
+    /**
+     * @var \Magento\TestFramework\ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * @var \Magento\Checkout\Service\V1\Data\Cart\AddressBuilder
+     */
+    protected $builder;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->builder = $this->objectManager->create('Magento\Checkout\Service\V1\Data\Cart\AddressBuilder');
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php
+     */
+    public function testSetAddress()
+    {
+        /** @var \Magento\Sales\Model\Quote $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_1', 'reserved_order_id');
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $quote->getId() . '/billing-address',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'SetAddress',
+            ],
+        ];
+
+        $addressData = [
+            'firstname' => 'John',
+            'lastname' => 'Smith',
+            'email' => 'cat@dog.com',
+            'company' => 'eBay Inc',
+            'street' => ['Typical Street', 'Tiny House 18'],
+            'city' => 'Big City',
+            'region' => [
+                'region_id' => 12,
+                'region' => 'California',
+                'region_code' => 'CA',
+            ],
+            'postcode' => '0985432',
+            'country_id' => 'US',
+            'telephone' => '88776655',
+            'fax' => '44332255',
+        ];
+        $requestData = [
+            "cartId" => $quote->getId(),
+            'addressData' => $addressData,
+        ];
+
+        $addressId = $this->_webApiCall($serviceInfo, $requestData);
+
+        //reset $quote to reload data
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_1', 'reserved_order_id');
+        $savedData  = $quote->getBillingAddress()->getData();
+        $this->assertEquals($addressId, $savedData['address_id']);
+        //custom checks for street, region and address_type
+        foreach ($addressData['street'] as $streetLine) {
+            $this->assertContains($streetLine, $quote->getBillingAddress()->getStreet());
+        }
+        unset($addressData['street']);
+        $this->assertEquals($addressData['region']['region_id'], $savedData['region_id']);
+        $this->assertEquals($addressData['region']['region'], $savedData['region']);
+        unset($addressData['region']);
+        $this->assertEquals('billing', $savedData['address_type']);
+        //check the rest of fields
+        foreach ($addressData as $key => $value) {
+            $this->assertEquals($value, $savedData[$key]);
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Address/Shipping/ReadServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Address/Shipping/ReadServiceTest.php
new file mode 100644
index 00000000000..da2908227ab
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Address/Shipping/ReadServiceTest.php
@@ -0,0 +1,111 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Checkout\Service\V1\Address\Shipping;
+
+use Magento\Checkout\Service\V1\Data\Cart\Address;
+use Magento\Checkout\Service\V1\Data\Cart\Address\Region;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ReadServiceTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+    const SERVICE_NAME = 'checkoutAddressShippingReadServiceV1';
+    const RESOURCE_PATH = '/V1/carts/';
+
+    /**
+     * @var \Magento\TestFramework\ObjectManager
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php
+     */
+    public function testGetAddress()
+    {
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_1', 'reserved_order_id');
+
+        /** @var \Magento\Sales\Model\Quote\Address  $address */
+        $address = $quote->getShippingAddress();
+
+        $data = [
+            Address::KEY_COUNTRY_ID => $address->getCountryId(),
+            Address::KEY_ID => (int)$address->getId(),
+            Address::KEY_CUSTOMER_ID => $address->getCustomerId(),
+            Address::KEY_REGION => [
+                Region::REGION => $address->getRegion(),
+                Region::REGION_ID => $address->getRegionId(),
+                Region::REGION_CODE => $address->getRegionCode(),
+            ],
+            Address::KEY_STREET => $address->getStreet(),
+            Address::KEY_COMPANY => $address->getCompany(),
+            Address::KEY_TELEPHONE => $address->getTelephone(),
+            Address::KEY_POSTCODE => $address->getPostcode(),
+            Address::KEY_CITY => $address->getCity(),
+            Address::KEY_FIRSTNAME => $address->getFirstname(),
+            Address::KEY_LASTNAME => $address->getLastname(),
+            Address::KEY_EMAIL => $address->getEmail(),
+            Address::CUSTOM_ATTRIBUTES_KEY => [['attribute_code' => 'disable_auto_group_change', 'value' => null]],
+        ];
+
+        $cartId = $quote->getId();
+
+        $serviceInfo = $this->getServiceInfo();
+        $serviceInfo['rest']['resourcePath'] = str_replace('{cart_id}', $cartId, $serviceInfo['rest']['resourcePath']);
+
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            unset($data[Address::KEY_PREFIX]);
+            unset($data[Address::KEY_SUFFIX]);
+            unset($data[Address::KEY_MIDDLENAME]);
+            unset($data[Address::KEY_FAX]);
+            unset($data[Address::KEY_VAT_ID]);
+        }
+
+        $requestData = ["cartId" => $cartId];
+        $this->assertEquals($data, $this->_webApiCall($serviceInfo, $requestData));
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_virtual_product_and_address.php
+     *
+     * @expectedException \Exception
+     * @expectedExceptionMessage Cart contains virtual product(s) only. Shipping address is not applicable
+     */
+    public function testGetAddressOfQuoteWithVirtualProduct()
+    {
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $cartId = $quote->load('test_order_with_virtual_product', 'reserved_order_id')->getId();
+
+        $serviceInfo = $this->getServiceInfo();
+        $serviceInfo['rest']['resourcePath'] = str_replace('{cart_id}', $cartId, $serviceInfo['rest']['resourcePath']);
+
+        $this->_webApiCall($serviceInfo, ["cartId" => $cartId]);
+    }
+
+    /**
+     * @return array
+     */
+    protected function getServiceInfo()
+    {
+        return $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '{cart_id}/shipping-address',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetAddress',
+            ],
+        ];
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Address/Shipping/WriteServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Address/Shipping/WriteServiceTest.php
new file mode 100644
index 00000000000..1a8e322508d
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Address/Shipping/WriteServiceTest.php
@@ -0,0 +1,147 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Checkout\Service\V1\Address\Shipping;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class WriteServiceTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+    const SERVICE_NAME = 'checkoutAddressShippingWriteServiceV1';
+    const RESOURCE_PATH = '/V1/carts/';
+
+    /**
+     * @var \Magento\TestFramework\ObjectManager
+     */
+    protected $objectManager;
+
+    /**
+     * @var \Magento\Checkout\Service\V1\Data\Cart\AddressBuilder
+     */
+    protected $builder;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->builder = $this->objectManager->create('Magento\Checkout\Service\V1\Data\Cart\AddressBuilder');
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php
+     */
+    public function testSetAddress()
+    {
+        /** @var \Magento\Sales\Model\Quote $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_1', 'reserved_order_id');
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $quote->getId() . '/shipping-address',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'SetAddress',
+            ],
+        ];
+
+        $addressData = [
+            'firstname' => 'John',
+            'lastname' => 'Smith',
+            'email' => 'cat@dog.com',
+            'company' => 'eBay Inc',
+            'street' => ['Typical Street', 'Tiny House 18'],
+            'city' => 'Big City',
+            'region' => [
+                'region_id' => 12,
+                'region' => 'California',
+                'region_code' => 'CA',
+            ],
+            'postcode' => '0985432',
+            'country_id' => 'US',
+            'telephone' => '88776655',
+            'fax' => '44332255',
+        ];
+        $requestData = [
+            "cartId" => $quote->getId(),
+            'addressData' => $addressData,
+        ];
+
+        $addressId = $this->_webApiCall($serviceInfo, $requestData);
+
+        //reset $quote to reload data
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_1', 'reserved_order_id');
+        $savedData  = $quote->getShippingAddress()->getData();
+        $this->assertEquals($addressId, $savedData['address_id']);
+        $this->assertEquals(0, $savedData['same_as_billing']);
+        //custom checks for street, region and address_type
+        $this->assertEquals($addressData['street'], $quote->getShippingAddress()->getStreet());
+        unset($addressData['street']);
+        $this->assertEquals($addressData['region']['region_id'], $savedData['region_id']);
+        $this->assertEquals($addressData['region']['region'], $savedData['region']);
+        unset($addressData['region']);
+        $this->assertEquals('shipping', $savedData['address_type']);
+        //check the rest of fields
+        foreach ($addressData as $key => $value) {
+            $this->assertEquals($value, $savedData[$key]);
+        }
+    }
+
+    /**
+     * Set address to quote with virtual products only
+     *
+     * @expectedException \Exception
+     * @expectedExceptionMessage Cart contains virtual product(s) only. Shipping address is not applicable
+     *
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_virtual_product_and_address.php
+     */
+    public function testSetAddressForVirtualQuote()
+    {
+        /** @var \Magento\Sales\Model\Quote $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_with_virtual_product', 'reserved_order_id');
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $quote->getId() . '/shipping-address',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'SetAddress',
+            ],
+        ];
+
+        $addressData = [
+            'firstname' => 'John',
+            'lastname' => 'Smith',
+            'email' => 'cat@dog.com',
+            'company' => 'eBay Inc',
+            'street' => ['Typical Street', 'Tiny House 18'],
+            'city' => 'Big City',
+            'region' => [
+                'region_id' => 12,
+                'region' => 'California',
+                'region_code' => 'CA',
+            ],
+            'postcode' => '0985432',
+            'country_id' => 'US',
+            'telephone' => '88776655',
+            'fax' => '44332255',
+        ];
+        $requestData = [
+            "cartId" => $quote->getId(),
+            'addressData' => $addressData,
+        ];
+
+        $this->_webApiCall($serviceInfo, $requestData);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Cart/ReadServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Cart/ReadServiceTest.php
new file mode 100644
index 00000000000..2d2f8063b35
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Cart/ReadServiceTest.php
@@ -0,0 +1,297 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Checkout\Service\V1\Cart;
+
+use Magento\Checkout\Service\V1\Data\Cart;
+use Magento\Framework\Api\FilterBuilder;
+use Magento\Framework\Api\SearchCriteria;
+use Magento\Framework\Api\SearchCriteriaBuilder;
+use Magento\TestFramework\ObjectManager;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ReadServiceTest extends WebapiAbstract
+{
+    /**
+     * @var ObjectManager
+     */
+    private $objectManager;
+
+    /**
+     * @var SearchCriteriaBuilder
+     */
+    private $searchBuilder;
+
+    /**
+     * @var SortOrderBuilder
+     */
+    private $sortOrderBuilder;
+
+    /**
+     * @var FilterBuilder
+     */
+    private $filterBuilder;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->filterBuilder = $this->objectManager->create(
+            'Magento\Framework\Api\FilterBuilder'
+        );
+        $this->sortOrderBuilder = $this->objectManager->create(
+            'Magento\Framework\Api\SortOrderBuilder'
+        );
+        $this->searchBuilder = $this->objectManager->create(
+            'Magento\Framework\Api\SearchCriteriaBuilder'
+        );
+    }
+
+    protected function tearDown()
+    {
+        try {
+            $cart = $this->getCart('test01');
+            $cart->delete();
+        } catch (\InvalidArgumentException $e) {
+            // Do nothing if cart fixture was not used
+        }
+        parent::tearDown();
+    }
+
+    /**
+     * Retrieve quote by given reserved order ID
+     *
+     * @param string $reservedOrderId
+     * @return \Magento\Sales\Model\Quote
+     * @throws \InvalidArgumentException
+     */
+    protected function getCart($reservedOrderId)
+    {
+        /** @var $cart \Magento\Sales\Model\Quote */
+        $cart = $this->objectManager->get('Magento\Sales\Model\Quote');
+        $cart->load($reservedOrderId, 'reserved_order_id');
+        if (!$cart->getId()) {
+            throw new \InvalidArgumentException('There is no quote with provided reserved order ID.');
+        }
+        return $cart;
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/quote.php
+     */
+    public function testGetCart()
+    {
+        $cart = $this->getCart('test01');
+        $cartId = $cart->getId();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/carts/' . $cartId,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => 'checkoutCartReadServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'checkoutCartReadServiceV1GetCart',
+            ],
+        ];
+
+        $requestData = ['cartId' => $cartId];
+        $cartData = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals($cart->getId(), $cartData['id']);
+        $this->assertEquals($cart->getCreatedAt(), $cartData['created_at']);
+        $this->assertEquals($cart->getUpdatedAt(), $cartData['updated_at']);
+        $this->assertEquals($cart->getStoreId(), $cartData['store_id']);
+        $this->assertEquals($cart->getIsActive(), $cartData['is_active']);
+        $this->assertEquals($cart->getIsVirtual(), $cartData['is_virtual']);
+        $this->assertEquals($cart->getOrigOrderId(), $cartData['orig_order_id']);
+        $this->assertEquals($cart->getItemsCount(), $cartData['items_count']);
+        $this->assertEquals($cart->getItemsQty(), $cartData['items_qty']);
+
+        $this->assertContains('customer', $cartData);
+        $this->assertEquals(1, $cartData['customer']['is_guest']);
+        $this->assertContains('totals', $cartData);
+        $this->assertEquals($cart->getSubtotal(), $cartData['totals']['subtotal']);
+        $this->assertEquals($cart->getGrandTotal(), $cartData['totals']['grand_total']);
+        $this->assertContains('currency', $cartData);
+        $this->assertEquals($cart->getGlobalCurrencyCode(), $cartData['currency']['global_currency_code']);
+        $this->assertEquals($cart->getBaseCurrencyCode(), $cartData['currency']['base_currency_code']);
+        $this->assertEquals($cart->getQuoteCurrencyCode(), $cartData['currency']['quote_currency_code']);
+        $this->assertEquals($cart->getStoreCurrencyCode(), $cartData['currency']['store_currency_code']);
+        $this->assertEquals($cart->getBaseToGlobalRate(), $cartData['currency']['base_to_global_rate']);
+        $this->assertEquals($cart->getBaseToQuoteRate(), $cartData['currency']['base_to_quote_rate']);
+        $this->assertEquals($cart->getStoreToBaseRate(), $cartData['currency']['store_to_base_rate']);
+        $this->assertEquals($cart->getStoreToQuoteRate(), $cartData['currency']['store_to_quote_rate']);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage No such entity with
+     */
+    public function testGetCartThrowsExceptionIfThereIsNoCartWithProvidedId()
+    {
+        $cartId = 9999;
+
+        $serviceInfo = [
+            'soap' => [
+                'service' => 'checkoutCartReadServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'checkoutCartReadServiceV1GetCart',
+            ],
+            'rest' => [
+                'resourcePath' => '/V1/carts/' . $cartId,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+        ];
+
+        $requestData = ['cartId' => $cartId];
+        $this->_webApiCall($serviceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/quote_with_customer.php
+     */
+    public function testGetCartForCustomer()
+    {
+        $cart = $this->getCart('test01');
+        $customerId = $cart->getCustomer()->getId();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/customer/' . $customerId . '/cart',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => 'checkoutCartReadServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'checkoutCartReadServiceV1GetCartForCustomer',
+            ],
+        ];
+
+        $requestData = ['customerId' => $customerId];
+        $cartData = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals($cart->getId(), $cartData['id']);
+        $this->assertEquals($cart->getCreatedAt(), $cartData['created_at']);
+        $this->assertEquals($cart->getUpdatedAt(), $cartData['updated_at']);
+        $this->assertEquals($cart->getStoreId(), $cartData['store_id']);
+        $this->assertEquals($cart->getIsActive(), $cartData['is_active']);
+        $this->assertEquals($cart->getIsVirtual(), $cartData['is_virtual']);
+        $this->assertEquals($cart->getOrigOrderId(), $cartData['orig_order_id']);
+        $this->assertEquals($cart->getItemsCount(), $cartData['items_count']);
+        $this->assertEquals($cart->getItemsQty(), $cartData['items_qty']);
+
+        $this->assertContains('customer', $cartData);
+        $this->assertEquals(0, $cartData['customer']['is_guest']);
+        $this->assertContains('totals', $cartData);
+        $this->assertEquals($cart->getSubtotal(), $cartData['totals']['subtotal']);
+        $this->assertEquals($cart->getGrandTotal(), $cartData['totals']['grand_total']);
+        $this->assertContains('currency', $cartData);
+        $this->assertEquals($cart->getGlobalCurrencyCode(), $cartData['currency']['global_currency_code']);
+        $this->assertEquals($cart->getBaseCurrencyCode(), $cartData['currency']['base_currency_code']);
+        $this->assertEquals($cart->getQuoteCurrencyCode(), $cartData['currency']['quote_currency_code']);
+        $this->assertEquals($cart->getStoreCurrencyCode(), $cartData['currency']['store_currency_code']);
+        $this->assertEquals($cart->getBaseToGlobalRate(), $cartData['currency']['base_to_global_rate']);
+        $this->assertEquals($cart->getBaseToQuoteRate(), $cartData['currency']['base_to_quote_rate']);
+        $this->assertEquals($cart->getStoreToBaseRate(), $cartData['currency']['store_to_base_rate']);
+        $this->assertEquals($cart->getStoreToQuoteRate(), $cartData['currency']['store_to_quote_rate']);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/quote.php
+     */
+    public function testGetCartList()
+    {
+        $cart = $this->getCart('test01');
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/carts',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => 'checkoutCartReadServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'checkoutCartReadServiceV1GetCartList',
+            ],
+        ];
+
+        // The following two filters are used as alternatives. The target cart does not match the first one.
+        $grandTotalFilter = $this->filterBuilder->setField('grand_total')
+            ->setConditionType('gteq')
+            ->setValue(15)
+            ->create();
+        $subtotalFilter = $this->filterBuilder->setField('subtotal')
+            ->setConditionType('eq')
+            ->setValue($cart->getSubtotal())
+            ->create();
+
+        $yesterdayDate = (new \DateTime())->sub(new \DateInterval('P1D'))->format('Y-m-d');
+        $tomorrowDate = (new \DateTime())->add(new \DateInterval('P1D'))->format('Y-m-d');
+        $minCreatedAtFilter = $this->filterBuilder->setField(Cart::CREATED_AT)
+            ->setConditionType('gteq')
+            ->setValue($yesterdayDate)
+            ->create();
+        $maxCreatedAtFilter = $this->filterBuilder->setField(Cart::CREATED_AT)
+            ->setConditionType('lteq')
+            ->setValue($tomorrowDate)
+            ->create();
+
+        $this->searchBuilder->addFilter([$grandTotalFilter, $subtotalFilter]);
+        $this->searchBuilder->addFilter([$minCreatedAtFilter]);
+        $this->searchBuilder->addFilter([$maxCreatedAtFilter]);
+        /** @var SortOrder $sortOrder */
+        $sortOrder = $this->sortOrderBuilder->setField('subtotal')->setDirection(SearchCriteria::SORT_ASC)->create();
+        $this->searchBuilder->setSortOrders([$sortOrder]);
+        $searchCriteria = $this->searchBuilder->create()->__toArray();
+
+        $requestData = ['searchCriteria' => $searchCriteria];
+        $searchResult = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertArrayHasKey('total_count', $searchResult);
+        $this->assertEquals(1, $searchResult['total_count']);
+        $this->assertArrayHasKey('items', $searchResult);
+        $this->assertCount(1, $searchResult['items']);
+
+        $cartData = $searchResult['items'][0];
+        $this->assertEquals($cart->getId(), $cartData['id']);
+        $this->assertEquals($cart->getCreatedAt(), $cartData['created_at']);
+        $this->assertEquals($cart->getUpdatedAt(), $cartData['updated_at']);
+        $this->assertEquals($cart->getIsActive(), $cartData['is_active']);
+        $this->assertEquals($cart->getStoreId(), $cartData['store_id']);
+
+        $this->assertContains('totals', $cartData);
+        $this->assertEquals($cart->getBaseSubtotal(), $cartData['totals']['base_subtotal']);
+        $this->assertEquals($cart->getBaseGrandTotal(), $cartData['totals']['base_grand_total']);
+        $this->assertContains('customer', $cartData);
+        $this->assertEquals(1, $cartData['customer']['is_guest']);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Field 'invalid_field' cannot be used for search.
+     */
+    public function testGetCartListThrowsExceptionIfProvidedSearchFieldIsInvalid()
+    {
+        $serviceInfo = [
+            'soap' => [
+                'service' => 'checkoutCartReadServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'checkoutCartReadServiceV1GetCartList',
+            ],
+            'rest' => [
+                'resourcePath' => '/V1/carts',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+        ];
+
+        $invalidFilter = $this->filterBuilder->setField('invalid_field')
+            ->setConditionType('eq')
+            ->setValue(0)
+            ->create();
+
+        $this->searchBuilder->addFilter([$invalidFilter]);
+        $searchCriteria = $this->searchBuilder->create()->__toArray();
+        $requestData = ['searchCriteria' => $searchCriteria];
+        $this->_webApiCall($serviceInfo, $requestData);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Cart/TotalsServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Cart/TotalsServiceTest.php
new file mode 100644
index 00000000000..9c6a50f2d7e
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Cart/TotalsServiceTest.php
@@ -0,0 +1,174 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Checkout\Service\V1\Cart;
+
+use Magento\Checkout\Service\V1\Data\Cart\Totals;
+use Magento\Checkout\Service\V1\Data\Cart\Totals\Item as ItemTotals;
+use Magento\Framework\Api\FilterBuilder;
+use Magento\Framework\Api\SearchCriteriaBuilder;
+use Magento\TestFramework\ObjectManager;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class TotalsServiceTest extends WebapiAbstract
+{
+    /**
+     * @var ObjectManager
+     */
+    private $objectManager;
+
+    /**
+     * @var SearchCriteriaBuilder
+     */
+    private $searchBuilder;
+
+    /**
+     * @var FilterBuilder
+     */
+    private $filterBuilder;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->searchBuilder = $this->objectManager->create(
+            'Magento\Framework\Api\SearchCriteriaBuilder'
+        );
+        $this->filterBuilder = $this->objectManager->create(
+            'Magento\Framework\Api\FilterBuilder'
+        );
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_shipping_method.php
+     */
+    public function testGetTotals()
+    {
+        /** @var \Magento\Sales\Model\Quote $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_1', 'reserved_order_id');
+        $cartId = $quote->getId();
+
+        /** @var \Magento\Sales\Model\Quote\Address $shippingAddress */
+        $shippingAddress = $quote->getShippingAddress();
+
+        $data = [
+            Totals::BASE_GRAND_TOTAL => $quote->getBaseGrandTotal(),
+            Totals::GRAND_TOTAL => $quote->getGrandTotal(),
+            Totals::BASE_SUBTOTAL => $quote->getBaseSubtotal(),
+            Totals::SUBTOTAL => $quote->getSubtotal(),
+            Totals::BASE_SUBTOTAL_WITH_DISCOUNT => $quote->getBaseSubtotalWithDiscount(),
+            Totals::SUBTOTAL_WITH_DISCOUNT => $quote->getSubtotalWithDiscount(),
+            Totals::DISCOUNT_AMOUNT => $shippingAddress->getDiscountAmount(),
+            Totals::BASE_DISCOUNT_AMOUNT => $shippingAddress->getBaseDiscountAmount(),
+            Totals::SHIPPING_AMOUNT => $shippingAddress->getShippingAmount(),
+            Totals::BASE_SHIPPING_AMOUNT => $shippingAddress->getBaseShippingAmount(),
+            Totals::SHIPPING_DISCOUNT_AMOUNT => $shippingAddress->getShippingDiscountAmount(),
+            Totals::BASE_SHIPPING_DISCOUNT_AMOUNT => $shippingAddress->getBaseShippingDiscountAmount(),
+            Totals::TAX_AMOUNT => $shippingAddress->getTaxAmount(),
+            Totals::BASE_TAX_AMOUNT => $shippingAddress->getBaseTaxAmount(),
+            Totals::SHIPPING_TAX_AMOUNT => $shippingAddress->getShippingTaxAmount(),
+            Totals::BASE_SHIPPING_TAX_AMOUNT => $shippingAddress->getBaseShippingTaxAmount(),
+            Totals::SUBTOTAL_INCL_TAX => $shippingAddress->getSubtotalInclTax(),
+            Totals::BASE_SUBTOTAL_INCL_TAX => $shippingAddress->getBaseSubtotalTotalInclTax(),
+            Totals::SHIPPING_INCL_TAX => $shippingAddress->getShippingInclTax(),
+            Totals::BASE_SHIPPING_INCL_TAX => $shippingAddress->getBaseShippingInclTax(),
+            Totals::BASE_CURRENCY_CODE => $quote->getBaseCurrencyCode(),
+            Totals::QUOTE_CURRENCY_CODE => $quote->getQuoteCurrencyCode(),
+            Totals::ITEMS => [$this->getQuoteItemTotalsData($quote)],
+        ];
+
+        $requestData = ['cartId' => $cartId];
+
+        $data = $this->formatTotalsData($data);
+
+        $this->assertEquals($data, $this->_webApiCall($this->getServiceInfoForTotalsService($cartId), $requestData));
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage No such entity
+     */
+    public function testGetTotalsWithAbsentQuote()
+    {
+        $cartId = 'unknownCart';
+        $requestData = ['cartId' => $cartId];
+        $this->_webApiCall($this->getServiceInfoForTotalsService($cartId), $requestData);
+    }
+
+    /**
+     * Get service info for totals service
+     *
+     * @param string $cartId
+     * @return array
+     */
+    protected function getServiceInfoForTotalsService($cartId)
+    {
+        return [
+            'soap' => [
+                'service' => 'checkoutCartTotalsServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'checkoutCartTotalsServiceV1GetTotals',
+            ],
+            'rest' => [
+                'resourcePath' => '/V1/carts/' . $cartId . '/totals',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+        ];
+    }
+
+    /**
+     * Adjust response details for SOAP protocol
+     *
+     * @param array $data
+     * @return array
+     */
+    protected function formatTotalsData($data)
+    {
+        foreach ($data as $key => $field) {
+            if (is_numeric($field)) {
+                $data[$key] = round($field, 1);
+                if ($data[$key] === null) {
+                    $data[$key] = 0.0;
+                }
+            }
+        }
+
+        unset($data[Totals::BASE_SUBTOTAL_INCL_TAX]);
+
+        return $data;
+    }
+
+    /**
+     * Fetch quote item totals data from quote
+     *
+     * @param \Magento\Sales\Model\Quote $quote
+     * @return array
+     */
+    protected function getQuoteItemTotalsData(\Magento\Sales\Model\Quote $quote)
+    {
+        $items = $quote->getAllItems();
+        $item = array_shift($items);
+
+        return [
+            ItemTotals::PRICE => $item->getPrice(),
+            ItemTotals::BASE_PRICE => $item->getBasePrice(),
+            ItemTotals::QTY => $item->getQty(),
+            ItemTotals::ROW_TOTAL => $item->getRowTotal(),
+            ItemTotals::BASE_ROW_TOTAL => $item->getBaseRowTotal(),
+            ItemTotals::ROW_TOTAL_WITH_DISCOUNT => $item->getRowTotalWithDiscount(),
+            ItemTotals::TAX_AMOUNT => $item->getTaxAmount(),
+            ItemTotals::BASE_TAX_AMOUNT => $item->getBaseTaxAmount(),
+            ItemTotals::TAX_PERCENT => $item->getTaxPercent(),
+            ItemTotals::DISCOUNT_AMOUNT => $item->getDiscountAmount(),
+            ItemTotals::BASE_DISCOUNT_AMOUNT => $item->getBaseDiscountAmount(),
+            ItemTotals::DISCOUNT_PERCENT => $item->getDiscountPercent(),
+            ItemTotals::PRICE_INCL_TAX => $item->getPriceInclTax(),
+            ItemTotals::BASE_PRICE_INCL_TAX => $item->getBasePriceInclTax(),
+            ItemTotals::ROW_TOTAL_INCL_TAX => $item->getRowTotalInclTax(),
+            ItemTotals::BASE_ROW_TOTAL_INCL_TAX => $item->getBaseRowTotalInclTax(),
+        ];
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Cart/WriteServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Cart/WriteServiceTest.php
new file mode 100644
index 00000000000..781ce89f50b
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Cart/WriteServiceTest.php
@@ -0,0 +1,299 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Checkout\Service\V1\Cart;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class WriteServiceTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+    const SERVICE_NAME = 'checkoutCartWriteServiceV1';
+    const RESOURCE_PATH = '/V1/carts/';
+
+    protected $createdQuotes = [];
+
+    /**
+     * @var \Magento\TestFramework\ObjectManager
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    public function testCreate()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Create',
+            ],
+        ];
+
+        $quoteId = $this->_webApiCall($serviceInfo);
+        $this->assertGreaterThan(0, $quoteId);
+        $this->createdQuotes[] = $quoteId;
+    }
+
+    public function tearDown()
+    {
+        /** @var \Magento\Sales\Model\Quote $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        foreach ($this->createdQuotes as $quoteId) {
+            $quote->load($quoteId);
+            $quote->delete();
+        }
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/quote.php
+     * @magentoApiDataFixture Magento/Customer/_files/customer.php
+     */
+    public function testAssignCustomer()
+    {
+        /** @var $quote \Magento\Sales\Model\Quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote')->load('test01', 'reserved_order_id');
+        $cartId = $quote->getId();
+        /** @var $repository \Magento\Customer\Api\CustomerRepositoryInterface */
+        $repository = $this->objectManager->create('Magento\Customer\Api\CustomerRepositoryInterface');
+        /** @var $customer \Magento\Customer\Api\Data\CustomerInterface */
+        $customer = $repository->getById(1);
+        $customerId = $customer->getId();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/carts/' . $cartId,
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => 'checkoutCartWriteServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'checkoutCartWriteServiceV1AssignCustomer',
+            ],
+        ];
+
+        $requestData = [
+            'cartId' => $cartId,
+            'customerId' => $customerId,
+        ];
+        // Cart must be anonymous (see fixture)
+        $this->assertEmpty($quote->getCustomerId());
+
+        $this->assertTrue($this->_webApiCall($serviceInfo, $requestData));
+        // Reload target quote
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote')->load('test01', 'reserved_order_id');
+        $this->assertEquals(0, $quote->getCustomerIsGuest());
+        $this->assertEquals($customer->getId(), $quote->getCustomerId());
+        $this->assertEquals($customer->getFirstname(), $quote->getCustomerFirstname());
+        $this->assertEquals($customer->getLastname(), $quote->getCustomerLastname());
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/quote.php
+     * @expectedException \Exception
+     */
+    public function testAssignCustomerThrowsExceptionIfThereIsNoCustomerWithGivenId()
+    {
+        /** @var $quote \Magento\Sales\Model\Quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote')->load('test01', 'reserved_order_id');
+        $cartId = $quote->getId();
+        $customerId = 9999;
+        $serviceInfo = [
+            'soap' => [
+                'serviceVersion' => 'V1',
+                'service' => 'checkoutCartWriteServiceV1',
+                'operation' => 'checkoutCartWriteServiceV1AssignCustomer',
+            ],
+            'rest' => [
+                'resourcePath' => '/V1/carts/' . $cartId,
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+        ];
+        $requestData = [
+            'cartId' => $cartId,
+            'customerId' => $customerId,
+        ];
+
+        $this->_webApiCall($serviceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Customer/_files/customer.php
+     * @expectedException \Exception
+     */
+    public function testAssignCustomerThrowsExceptionIfThereIsNoCartWithGivenId()
+    {
+        $cartId = 9999;
+        $customerId = 1;
+        $serviceInfo = [
+            'soap' => [
+                'service' => 'checkoutCartWriteServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'checkoutCartWriteServiceV1AssignCustomer',
+            ],
+            'rest' => [
+                'resourcePath' => '/V1/carts/' . $cartId,
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+        ];
+        $requestData = [
+            'cartId' => $cartId,
+            'customerId' => $customerId,
+        ];
+
+        $this->_webApiCall($serviceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/quote_with_customer.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Cannot assign customer to the given cart. The cart is not anonymous.
+     */
+    public function testAssignCustomerThrowsExceptionIfTargetCartIsNotAnonymous()
+    {
+        /** @var $customer \Magento\Customer\Model\Customer */
+        $customer = $this->objectManager->create('Magento\Customer\Model\Customer')->load(1);
+        $customerId = $customer->getId();
+        /** @var $quote \Magento\Sales\Model\Quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote')->load('test01', 'reserved_order_id');
+        $cartId = $quote->getId();
+
+        $serviceInfo = [
+            'rest' => [
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+                'resourcePath' => '/V1/carts/' . $cartId,
+            ],
+            'soap' => [
+                'service' => 'checkoutCartWriteServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'checkoutCartWriteServiceV1AssignCustomer',
+            ],
+        ];
+
+        $requestData = [
+            'cartId' => $cartId,
+            'customerId' => $customerId,
+        ];
+        $this->_webApiCall($serviceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/quote.php
+     * @magentoApiDataFixture Magento/Customer/_files/customer_non_default_website_id.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Cannot assign customer to the given cart. The cart belongs to different store.
+     */
+    public function testAssignCustomerThrowsExceptionIfCartIsAssignedToDifferentStore()
+    {
+        $repository = $this->objectManager->create('Magento\Customer\Api\CustomerRepositoryInterface');
+        /** @var $customer \Magento\Customer\Api\Data\CustomerInterface */
+        $customer = $repository->getById(1);
+        /** @var $quote \Magento\Sales\Model\Quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote')->load('test01', 'reserved_order_id');
+
+        $customerId = $customer->getId();
+        $cartId = $quote->getId();
+
+        $serviceInfo = [
+            'soap' => [
+                'service' => 'checkoutCartWriteServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'checkoutCartWriteServiceV1AssignCustomer',
+            ],
+            'rest' => [
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+                'resourcePath' => '/V1/carts/' . $cartId,
+            ],
+        ];
+
+        $requestData = [
+            'cartId' => $cartId,
+            'customerId' => $customerId,
+        ];
+        $this->_webApiCall($serviceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php
+     * @magentoApiDataFixture Magento/Sales/_files/quote.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Cannot assign customer to the given cart. Customer already has active cart.
+     */
+    public function testAssignCustomerThrowsExceptionIfCustomerAlreadyHasActiveCart()
+    {
+        /** @var $customer \Magento\Customer\Model\Customer */
+        $customer = $this->objectManager->create('Magento\Customer\Model\Customer')->load(1);
+        // Customer has a quote with reserved order ID test_order_1 (see fixture)
+        /** @var $customerQuote \Magento\Sales\Model\Quote */
+        $customerQuote = $this->objectManager->create('Magento\Sales\Model\Quote')
+            ->load('test_order_1', 'reserved_order_id');
+        $customerQuote->setIsActive(1)->save();
+        /** @var $quote \Magento\Sales\Model\Quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote')->load('test01', 'reserved_order_id');
+
+        $cartId = $quote->getId();
+        $customerId = $customer->getId();
+
+        $serviceInfo = [
+            'soap' => [
+                'service' => 'checkoutCartWriteServiceV1',
+                'operation' => 'checkoutCartWriteServiceV1AssignCustomer',
+                'serviceVersion' => 'V1',
+            ],
+            'rest' => [
+                'resourcePath' => '/V1/carts/' . $cartId,
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+        ];
+
+        $requestData = [
+            'cartId' => $cartId,
+            'customerId' => $customerId,
+        ];
+        $this->_webApiCall($serviceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_check_payment.php
+     */
+    public function testOrderPlacesOrder()
+    {
+        /** @var $quote \Magento\Sales\Model\Quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote')->load('test_order_1', 'reserved_order_id');
+
+        $cartId = $quote->getId();
+
+        $serviceInfo = [
+            'soap' => [
+                'service' => 'checkoutCartWriteServiceV1',
+                'operation' => 'checkoutCartWriteServiceV1Order',
+                'serviceVersion' => 'V1',
+            ],
+            'rest' => [
+                'resourcePath' => '/V1/carts/' . $cartId . '/order',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+        ];
+
+        $requestData = [
+            'cartId' => $cartId,
+        ];
+        $this->_webApiCall($serviceInfo, $requestData);
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->load(1);
+        $items = $order->getAllItems();
+        $this->assertCount(1, $items);
+        $this->assertEquals('Simple Product', $items[0]->getName());
+        $quote->delete();
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Coupon/ReadServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Coupon/ReadServiceTest.php
new file mode 100644
index 00000000000..d36d4289fec
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Coupon/ReadServiceTest.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Checkout\Service\V1\Coupon;
+
+use Magento\Checkout\Service\V1\Data\Cart\Coupon as Coupon;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ReadServiceTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+    const SERVICE_NAME = 'checkoutCouponReadServiceV1';
+    const RESOURCE_PATH = '/V1/carts/';
+
+    /**
+     * @var \Magento\TestFramework\ObjectManager
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_coupon_saved.php
+     */
+    public function testGet()
+    {
+        /** @var \Magento\Sales\Model\Quote  $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_1', 'reserved_order_id');
+        $cartId = $quote->getId();
+        $data = [
+            Coupon::COUPON_CODE => $quote->getCouponCode(),
+        ];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/coupons',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Get',
+            ],
+        ];
+
+        $requestData = ["cartId" => $cartId];
+        $this->assertEquals($data, $this->_webApiCall($serviceInfo, $requestData));
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Coupon/WriteServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Coupon/WriteServiceTest.php
new file mode 100644
index 00000000000..f6dfbf57eb0
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Coupon/WriteServiceTest.php
@@ -0,0 +1,129 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Checkout\Service\V1\Coupon;
+
+use Magento\Checkout\Service\V1\Data\Cart\Coupon;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class WriteServiceTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+    const SERVICE_NAME = 'checkoutCouponWriteServiceV1';
+    const RESOURCE_PATH = '/V1/carts/';
+
+    /**
+     * @var \Magento\TestFramework\ObjectManager
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_coupon_saved.php
+     */
+    public function testDelete()
+    {
+        /** @var \Magento\Sales\Model\Quote $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_1', 'reserved_order_id');
+        $cartId = $quote->getId();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/coupons',
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Delete',
+            ],
+        ];
+        $requestData = ["cartId" => $cartId];
+        $this->assertTrue($this->_webApiCall($serviceInfo, $requestData));
+        $quote->load('test_order_1', 'reserved_order_id');
+        $this->assertEquals('', $quote->getCouponCode());
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Coupon code is not valid
+     */
+    public function testSetCouponThrowsExceptionIfCouponDoesNotExist()
+    {
+        /** @var \Magento\Sales\Model\Quote $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_1', 'reserved_order_id');
+        $cartId = $quote->getId();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/coupons',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Set',
+            ],
+        ];
+
+        $data = [Coupon::COUPON_CODE => 'invalid_coupon_code'];
+
+        $requestData = [
+            "cartId" => $cartId,
+            "couponCodeData" => $data,
+        ];
+
+        $this->_webApiCall($serviceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/quote.php
+     * @magentoApiDataFixture Magento/Checkout/_files/discount_10percent.php
+     */
+    public function testSetCouponSuccess()
+    {
+        /** @var \Magento\Sales\Model\Quote $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test01', 'reserved_order_id');
+        $cartId = $quote->getId();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/coupons',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Set',
+            ],
+        ];
+
+        $salesRule = $this->objectManager->create('Magento\SalesRule\Model\Rule');
+        $salesRule->load('Test Coupon', 'name');
+
+        $couponCode = $salesRule->getCouponCode();
+        $data = [Coupon::COUPON_CODE => $couponCode];
+
+        $requestData = [
+            "cartId" => $cartId,
+            "couponCodeData" => $data,
+        ];
+
+        $this->assertTrue($this->_webApiCall($serviceInfo, $requestData));
+
+        $quoteWithCoupon = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quoteWithCoupon->load('test01', 'reserved_order_id');
+
+        $this->assertEquals($quoteWithCoupon->getCouponCode(), $couponCode);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Item/ReadServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Item/ReadServiceTest.php
new file mode 100644
index 00000000000..6f099951a76
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Item/ReadServiceTest.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Checkout\Service\V1\Item;
+
+use Magento\Checkout\Service\V1\Data\Cart\Item as Item;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ReadServiceTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+    const SERVICE_NAME = 'checkoutItemReadServiceV1';
+    const RESOURCE_PATH = '/V1/carts/';
+
+    /**
+     * @var \Magento\TestFramework\ObjectManager
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_items_saved.php
+     */
+    public function testGetList()
+    {
+        /** @var \Magento\Sales\Model\Quote  $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_item_with_items', 'reserved_order_id');
+        $cartId = $quote->getId();
+        $output = [];
+        foreach ($quote->getAllItems() as $item) {
+            $data = [
+                Item::ITEM_ID => $item->getId(),
+                Item::SKU => $item->getSku(),
+                Item::NAME => $item->getName(),
+                Item::PRICE => $item->getPrice(),
+                Item::QTY => $item->getQty(),
+                Item::PRODUCT_TYPE => $item->getProductType(),
+            ];
+
+            $output[] = $data;
+        }
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/items',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetList',
+            ],
+        ];
+
+        $requestData = ["cartId" => $cartId];
+        $this->assertEquals($output, $this->_webApiCall($serviceInfo, $requestData));
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Item/WriteServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Item/WriteServiceTest.php
new file mode 100644
index 00000000000..857475f87e8
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/Item/WriteServiceTest.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Checkout\Service\V1\Item;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class WriteServiceTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+    const SERVICE_NAME = 'checkoutItemWriteServiceV1';
+    const RESOURCE_PATH = '/V1/carts/';
+
+    /**
+     * @var \Magento\TestFramework\ObjectManager
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     */
+    public function testAddItem()
+    {
+        $product = $this->objectManager->create('Magento\Catalog\Model\Product')->load(2);
+        $productSku = $product->getSku();
+        /** @var \Magento\Sales\Model\Quote  $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_1', 'reserved_order_id');
+        $cartId = $quote->getId();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/items',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'AddItem',
+            ],
+        ];
+
+        $requestData = [
+            "cartId" => $cartId,
+            "data" => [
+                "sku" => $productSku,
+                "qty" => 7,
+            ],
+        ];
+        $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertTrue($quote->hasProductId(2));
+        $this->assertEquals(7, $quote->getItemByProduct($product)->getQty());
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_items_saved.php
+     */
+    public function testRemoveItem()
+    {
+        /** @var \Magento\Sales\Model\Quote  $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_item_with_items', 'reserved_order_id');
+        $cartId = $quote->getId();
+        $product = $this->objectManager->create('Magento\Catalog\Model\Product');
+        $productId = $product->getIdBySku('simple_one');
+        $product->load($productId);
+        $itemId = $quote->getItemByProduct($product)->getId();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/items/' . $itemId,
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'RemoveItem',
+            ],
+        ];
+
+        $requestData = [
+            "cartId" => $cartId,
+            "itemId" => $itemId,
+        ];
+        $this->assertTrue($this->_webApiCall($serviceInfo, $requestData));
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_item_with_items', 'reserved_order_id');
+        $this->assertFalse($quote->hasProductId($productId));
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_items_saved.php
+     */
+    public function testUpdateItem()
+    {
+        /** @var \Magento\Sales\Model\Quote  $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_item_with_items', 'reserved_order_id');
+        $cartId = $quote->getId();
+        $product = $this->objectManager->create('Magento\Catalog\Model\Product');
+        $productId = $product->getIdBySku('simple_one');
+        $product->load($productId);
+        $itemId = $quote->getItemByProduct($product)->getId();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/items/' . $itemId,
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'UpdateItem',
+            ],
+        ];
+
+        $requestData = [
+            "cartId" => $cartId,
+            "itemId" => $itemId,
+            "data" => [
+                "qty" => 5,
+            ],
+        ];
+        $this->assertTrue($this->_webApiCall($serviceInfo, $requestData));
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_item_with_items', 'reserved_order_id');
+        $this->assertTrue($quote->hasProductId(1));
+        $this->assertEquals(5, $quote->getItemByProduct($product)->getQty());
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/PaymentMethod/ReadServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/PaymentMethod/ReadServiceTest.php
new file mode 100644
index 00000000000..befd81cb2cd
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/PaymentMethod/ReadServiceTest.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Checkout\Service\V1\PaymentMethod;
+
+use Magento\Checkout\Service\V1\Data\PaymentMethod;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ReadServiceTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+    const SERVICE_NAME = 'checkoutPaymentMethodReadServiceV1';
+    const RESOURCE_PATH = '/V1/carts/';
+
+    /**
+     * @var \Magento\TestFramework\ObjectManager
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php
+     */
+    public function testGetList()
+    {
+        /** @var \Magento\Sales\Model\Quote  $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_1', 'reserved_order_id');
+        $cartId = $quote->getId();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/payment-methods',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'getList',
+            ],
+        ];
+
+        $requestData = ["cartId" => $cartId];
+        $requestResponse = $this->_webApiCall($serviceInfo, $requestData);
+
+        $expectedResponse = [
+            PaymentMethod::CODE => 'checkmo',
+            PaymentMethod::TITLE => 'Check / Money order',
+        ];
+
+        $this->assertGreaterThan(0, count($requestResponse));
+        $this->assertContains($expectedResponse, $requestResponse);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_payment_saved.php
+     */
+    public function testGetPayment()
+    {
+        /** @var \Magento\Sales\Model\Quote  $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_1_with_payment', 'reserved_order_id');
+        $cartId = $quote->getId();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/selected-payment-methods',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'getPayment',
+            ],
+        ];
+
+        $requestData = ["cartId" => $cartId];
+        $requestResponse = $this->_webApiCall($serviceInfo, $requestData);
+
+        $this->assertArrayHasKey('method', $requestResponse);
+        $this->assertEquals('checkmo', $requestResponse['method']);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/PaymentMethod/WriteServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/PaymentMethod/WriteServiceTest.php
new file mode 100644
index 00000000000..fd796eeb90d
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/PaymentMethod/WriteServiceTest.php
@@ -0,0 +1,211 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Checkout\Service\V1\PaymentMethod;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class WriteServiceTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+    const SERVICE_NAME = 'checkoutPaymentMethodWriteServiceV1';
+    const RESOURCE_PATH = '/V1/carts/';
+
+    /**
+     * @var \Magento\TestFramework\ObjectManager
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_payment_saved.php
+     */
+    public function testReSetPayment()
+    {
+        /** @var \Magento\Sales\Model\Quote  $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_1_with_payment', 'reserved_order_id');
+        $cartId = $quote->getId();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/selected-payment-methods',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'set',
+            ],
+        ];
+
+        $requestData = [
+            "cartId" => $cartId,
+            "method" => [
+                'method' => 'checkmo',
+                'po_number' => null,
+                'cc_owner' => 'John',
+                'cc_type' => null,
+                'cc_exp_year' => null,
+                'cc_exp_month' => null,
+            ],
+        ];
+
+        $this->_webApiCall($serviceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_virtual_product_and_address.php
+     */
+    public function testSetPaymentWithVirtualProduct()
+    {
+        /** @var \Magento\Sales\Model\Quote  $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_with_virtual_product', 'reserved_order_id');
+        $cartId = $quote->getId();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/selected-payment-methods',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'set',
+            ],
+        ];
+
+        $requestData = [
+            "cartId" => $cartId,
+            "method" => [
+                'method' => 'checkmo',
+                'po_number' => '200',
+                'cc_owner' => 'tester',
+                'cc_type' => 'test',
+                'cc_exp_year' => '2014',
+                'cc_exp_month' => '1',
+            ],
+        ];
+        $this->assertNotNull($this->_webApiCall($serviceInfo, $requestData));
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php
+     */
+    public function testSetPaymentWithSimpleProduct()
+    {
+        /** @var \Magento\Sales\Model\Quote  $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_1', 'reserved_order_id');
+        $cartId = $quote->getId();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/selected-payment-methods',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'set',
+            ],
+        ];
+
+        $requestData = [
+            "cartId" => $cartId,
+            "method" => [
+                'method' => 'checkmo',
+                'po_number' => '200',
+                'cc_owner' => 'tester',
+                'cc_type' => 'test',
+                'cc_exp_year' => '2014',
+                'cc_exp_month' => '1',
+            ],
+        ];
+
+        $this->assertNotNull($this->_webApiCall($serviceInfo, $requestData));
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_virtual_product_saved.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Billing address is not set
+     */
+    public function testSetPaymentWithVirtualProductWithoutAddress()
+    {
+        /** @var \Magento\Sales\Model\Quote  $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_with_virtual_product_without_address', 'reserved_order_id');
+        $cartId = $quote->getId();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/selected-payment-methods',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'set',
+            ],
+        ];
+
+        $requestData = [
+            "cartId" => $cartId,
+            "method" => [
+                'method' => 'checkmo',
+                'po_number' => '200',
+                'cc_owner' => 'tester',
+                'cc_type' => 'test',
+                'cc_exp_year' => '2014',
+                'cc_exp_month' => '1',
+            ],
+        ];
+        $this->_webApiCall($serviceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Shipping address is not set
+     */
+    public function testSetPaymentWithSimpleProductWithoutAddress()
+    {
+        /** @var \Magento\Sales\Model\Quote  $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_with_simple_product_without_address', 'reserved_order_id');
+        $cartId = $quote->getId();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/selected-payment-methods',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'set',
+            ],
+        ];
+
+        $requestData = [
+            "cartId" => $cartId,
+            "method" => [
+                'method' => 'checkmo',
+                'po_number' => '200',
+                'cc_owner' => 'tester',
+                'cc_type' => 'test',
+                'cc_exp_year' => '2014',
+                'cc_exp_month' => '1',
+            ],
+        ];
+        $this->_webApiCall($serviceInfo, $requestData);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/ShippingMethod/ReadServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/ShippingMethod/ReadServiceTest.php
new file mode 100644
index 00000000000..a1d95dea7a1
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/ShippingMethod/ReadServiceTest.php
@@ -0,0 +1,174 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Checkout\Service\V1\ShippingMethod;
+
+use Magento\Checkout\Service\V1\Data\Cart\ShippingMethod;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ReadServiceTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+    const SERVICE_NAME = 'checkoutShippingMethodReadServiceV1';
+    const RESOURCE_PATH = '/V1/carts/';
+
+    /**
+     * @var \Magento\TestFramework\ObjectManager
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_shipping_method.php
+     */
+    public function testGetMethod()
+    {
+        /** @var \Magento\Sales\Model\Quote $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_1', 'reserved_order_id');
+
+        $cartId = $quote->getId();
+
+        $shippingAddress = $quote->getShippingAddress();
+        list($carrierCode, $methodCode) = explode('_', $shippingAddress->getShippingMethod());
+        list($carrierTitle, $methodTitle) = explode(' - ', $shippingAddress->getShippingDescription());
+        $data = [
+            ShippingMethod::CARRIER_CODE => $carrierCode,
+            ShippingMethod::METHOD_CODE => $methodCode,
+            ShippingMethod::CARRIER_TITLE => $carrierTitle,
+            ShippingMethod::METHOD_TITLE => $methodTitle,
+            ShippingMethod::SHIPPING_AMOUNT => $shippingAddress->getShippingAmount(),
+            ShippingMethod::BASE_SHIPPING_AMOUNT => $shippingAddress->getBaseShippingAmount(),
+            ShippingMethod::AVAILABLE => true,
+        ];
+
+        $requestData = ["cartId" => $cartId];
+        $this->assertEquals($data, $this->_webApiCall($this->getSelectedMethodServiceInfo($cartId), $requestData));
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_virtual_product_and_address.php
+     */
+    public function testGetMethodOfVirtualCart()
+    {
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $cartId = $quote->load('test_order_with_virtual_product', 'reserved_order_id')->getId();
+
+        $result = $this->_webApiCall($this->getSelectedMethodServiceInfo($cartId), ["cartId" => $cartId]);
+        $this->assertEquals([], $result);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php
+     */
+    public function testGetMethodOfCartWithNoShippingMethod()
+    {
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $cartId = $quote->load('test_order_1', 'reserved_order_id')->getId();
+
+        $result = $this->_webApiCall($this->getSelectedMethodServiceInfo($cartId), ["cartId" => $cartId]);
+        $this->assertEquals([], $result);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_virtual_product_and_address.php
+     *
+     */
+    public function testGetListForVirtualCart()
+    {
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $cartId = $quote->load('test_order_with_virtual_product', 'reserved_order_id')->getId();
+
+        $this->assertEquals([], $this->_webApiCall($this->getListServiceInfo($cartId), ["cartId" => $cartId]));
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php
+     */
+    public function testGetList()
+    {
+        /** @var \Magento\Sales\Model\Quote $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_1', 'reserved_order_id');
+        $cartId = $quote->getId();
+        if (!$cartId) {
+            $this->fail('quote fixture failed');
+        }
+        $quote->getShippingAddress()->collectShippingRates();
+        $expectedRates = $quote->getShippingAddress()->getGroupedAllShippingRates();
+
+        $expectedData = $this->convertRates($expectedRates, $quote->getQuoteCurrencyCode());
+
+        $requestData = ["cartId" => $cartId];
+
+        $returnedRates = $this->_webApiCall($this->getListServiceInfo($cartId), $requestData);
+        $this->assertEquals($expectedData, $returnedRates);
+    }
+
+    /**
+     * @param string $cartId
+     * @return array
+     */
+    protected function getSelectedMethodServiceInfo($cartId)
+    {
+        return $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/selected-shipping-method',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetMethod',
+            ],
+        ];
+    }
+
+    /**
+     * Service info
+     *
+     * @param int $cartId
+     * @return array
+     */
+    protected function getListServiceInfo($cartId)
+    {
+        return [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/shipping-methods',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetList',
+            ],
+        ];
+    }
+
+    /**
+     * Convert rate models array to data array
+     *
+     * @param string $currencyCode
+     * @param \Magento\Sales\Model\Quote\Address\Rate[] $groupedRates
+     * @return array
+     */
+    protected function convertRates($groupedRates, $currencyCode)
+    {
+        $result = [];
+        /** @var \Magento\Checkout\Service\V1\Data\Cart\ShippingMethodConverter $converter */
+        $converter = $this->objectManager->create('Magento\Checkout\Service\V1\Data\Cart\ShippingMethodConverter');
+        foreach ($groupedRates as $carrierRates) {
+            foreach ($carrierRates as $rate) {
+                $result[] = $converter->modelToDataObject($rate, $currencyCode)->__toArray();
+            }
+        }
+        return $result;
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/ShippingMethod/WriteServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/ShippingMethod/WriteServiceTest.php
new file mode 100644
index 00000000000..95539b9aa22
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Checkout/Service/V1/ShippingMethod/WriteServiceTest.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Checkout\Service\V1\ShippingMethod;
+
+use Magento\TestFramework\ObjectManager;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class WriteServiceTest extends WebapiAbstract
+{
+    /**
+     * @var ObjectManager
+     */
+    private $objectManager;
+
+    /**
+     * @var \Magento\Sales\Model\Quote
+     */
+    protected $quote;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+    }
+
+    protected function getServiceInfo()
+    {
+        return [
+            'rest' => [
+                'resourcePath' => '/V1/carts/' . $this->quote->getId() . '/selected-shipping-method',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => 'checkoutShippingMethodWriteServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'checkoutShippingMethodWriteServiceV1SetMethod',
+            ],
+        ];
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php
+     */
+    public function testSetMethod()
+    {
+        $this->quote->load('test_order_1', 'reserved_order_id');
+        $serviceInfo = $this->getServiceInfo();
+
+        $requestData = [
+            'cartId' => $this->quote->getId(),
+            'carrierCode' => 'flatrate',
+            'methodCode' => 'flatrate',
+        ];
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(true, $result);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_address_saved.php
+     */
+    public function testSetMethodWrongMethod()
+    {
+        $this->quote->load('test_order_1', 'reserved_order_id');
+        $serviceInfo = $this->getServiceInfo();
+
+        $requestData = [
+            'cartId' => $this->quote->getId(),
+            'carrierCode' => 'flatrate',
+            'methodCode' => 'wrongMethod',
+        ];
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+        } catch (\SoapFault $e) {
+            $message = $e->getMessage();
+        } catch (\Exception $e) {
+            $message = json_decode($e->getMessage())->message;
+        }
+        $this->assertEquals('Carrier with such method not found: flatrate, wrongMethod', $message);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Checkout/_files/quote_with_simple_product_saved.php
+     */
+    public function testSetMethodWithoutShippingAddress()
+    {
+        $this->quote->load('test_order_with_simple_product_without_address', 'reserved_order_id');
+        $serviceInfo = $this->getServiceInfo();
+
+        $requestData = [
+            'cartId' => $this->quote->getId(),
+            'carrierCode' => 'flatrate',
+            'methodCode' => 'flatrate',
+        ];
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+        } catch (\SoapFault $e) {
+            $message = $e->getMessage();
+        } catch (\Exception $e) {
+            $message = json_decode($e->getMessage())->message;
+        }
+        $this->assertEquals('Shipping address is not set', $message);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/CheckoutAgreements/Service/V1/Agreement/ReadServiceTest.php b/dev/tests/api-functional/testsuite/Magento/CheckoutAgreements/Service/V1/Agreement/ReadServiceTest.php
new file mode 100644
index 00000000000..db6133696df
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/CheckoutAgreements/Service/V1/Agreement/ReadServiceTest.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\CheckoutAgreements\Service\V1\Agreement;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ReadServiceTest extends WebapiAbstract
+{
+    /**
+     * @var array
+     */
+    private $listServiceInfo;
+
+    protected function setUp()
+    {
+        $this->listServiceInfo = [
+            'soap' => [
+                'service' => 'checkoutAgreementsAgreementReadServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'checkoutAgreementsAgreementReadServiceV1GetList',
+            ],
+            'rest' => [
+                'resourcePath' => '/V1/carts/licence/',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+        ];
+    }
+
+    /**
+     * Retrieve agreement by given name
+     *
+     * @param string $name
+     * @return \Magento\CheckoutAgreements\Model\Agreement
+     * @throws \InvalidArgumentException
+     */
+    protected function getAgreementByName($name)
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var $agreement \Magento\CheckoutAgreements\Model\Agreement */
+        $agreement = $objectManager->create('Magento\CheckoutAgreements\Model\Agreement');
+        $agreement->load($name, 'name');
+        if (!$agreement->getId()) {
+            throw new \InvalidArgumentException('There is no checkout agreement with provided ID.');
+        }
+        return $agreement;
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_active_with_html_content.php
+     * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_inactive_with_text_content.php
+     */
+    public function testGetListReturnsEmptyListIfCheckoutAgreementsAreDisabledOnFrontend()
+    {
+        // Checkout agreements are disabled by default
+        $agreements = $this->_webApiCall($this->listServiceInfo, []);
+        $this->assertEmpty($agreements);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_active_with_html_content.php
+     * @magentoApiDataFixture Magento/CheckoutAgreements/_files/agreement_inactive_with_text_content.php
+     */
+    public function testGetListReturnsTheListOfActiveCheckoutAgreements()
+    {
+        // checkout/options/enable_agreements must be set to 1 in system configuration
+        // @todo remove next statement when \Magento\TestFramework\TestCase\WebapiAbstract::_updateAppConfig is fixed
+        $this->markTestIncomplete('This test relies on system configuration state.');
+        $agreementModel = $this->getAgreementByName('Checkout Agreement (active)');
+
+        $agreements = $this->_webApiCall($this->listServiceInfo, []);
+        $this->assertCount(1, $agreements);
+        $agreementData = $agreements[0];
+        $this->assertEquals($agreementModel->getId(), $agreementData['id']);
+        $this->assertEquals($agreementModel->getName(), $agreementData['name']);
+        $this->assertEquals($agreementModel->getContent(), $agreementData['content']);
+        $this->assertEquals($agreementModel->getContentHeight(), $agreementData['content_height']);
+        $this->assertEquals($agreementModel->getCheckboxText(), $agreementData['checkbox_text']);
+        $this->assertEquals($agreementModel->getIsActive(), $agreementData['active']);
+        $this->assertEquals($agreementModel->getIsHtml(), $agreementData['html']);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/ConfigurableProductManagementTest.php b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/ConfigurableProductManagementTest.php
new file mode 100644
index 00000000000..487580b0035
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/ConfigurableProductManagementTest.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\ConfigurableProduct\Api;
+
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+use Magento\TestFramework\Helper\Bootstrap;
+
+class ConfigurableProductManagementTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    const SERVICE_NAME = 'configurableProductConfigurableProductManagementV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/configurable-products/variation';
+
+    /**
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/configurable_attribute.php
+     */
+    public function testGetVariation()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GenerateVariation'
+            ]
+        ];
+        /** @var \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository */
+        $attributeRepository = Bootstrap::getObjectManager()->get(
+            'Magento\Catalog\Api\ProductAttributeRepositoryInterface'
+        );
+        $attribute = $attributeRepository->get('test_configurable');
+        $attributeOptionValue = $attribute->getOptions()[0]->getValue();
+        $data = [
+            'product' => [
+                'sku' => 'test',
+                'price' => 10.0
+            ],
+            'options' => [
+                [
+                    'attribute_id' => 'test_configurable',
+                    'values' => [
+                        [
+                            'value_index' => $attributeOptionValue,
+                            'pricing_value' => 100.0
+                        ]
+                    ]
+                ]
+            ]
+
+        ];
+        $actual = $this->_webApiCall($serviceInfo, $data);
+
+        $expectedItems = [
+            [
+                'sku' => 'test-',
+                'price' => 110.0,
+                'name' => '-',
+                'store_id' => 1,
+                'status' => 1,
+                'visibility' => \Magento\Catalog\Model\Product\Visibility::VISIBILITY_NOT_VISIBLE,
+                'custom_attributes' => [
+                    [
+                        'attribute_code' => 'test_configurable',
+                        'value' => $attributeOptionValue
+                    ]
+                ]
+            ]
+        ];
+        ksort($expectedItems);
+        ksort($actual);
+        $this->assertEquals($expectedItems, $actual);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/LinkManagementTest.php b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/LinkManagementTest.php
new file mode 100644
index 00000000000..e6c37af767e
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/LinkManagementTest.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\ConfigurableProduct\Api;
+
+use Magento\Webapi\Model\Rest\Config;
+
+class LinkManagementTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    const SERVICE_NAME = 'configurableProductLinkManagementV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/configurable-products';
+
+    /**
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     */
+    public function testGetChildren()
+    {
+        $productSku = 'configurable';
+
+        /** @var array $result */
+        $result = $this->getChildren($productSku);
+        $this->assertCount(2, $result);
+
+        foreach ($result as $product) {
+            $this->assertArrayHasKey('custom_attributes', $product);
+            $this->assertArrayHasKey('price', $product);
+            $this->assertArrayHasKey('updated_at', $product);
+
+            $this->assertArrayHasKey('name', $product);
+            $this->assertContains('Configurable Option', $product['name']);
+
+            $this->assertArrayHasKey('sku', $product);
+            $this->assertContains('simple_', $product['sku']);
+
+            $this->assertArrayHasKey('status', $product);
+            $this->assertEquals('1', $product['status']);
+
+            $this->assertArrayHasKey('visibility', $product);
+            $this->assertEquals('1', $product['visibility']);
+        }
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/delete_association.php
+     */
+    public function testAddChild()
+    {
+        $productSku = 'configurable';
+        $childSku = 'simple_10';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $productSku . '/child',
+                'httpMethod' => Config::HTTP_METHOD_POST
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'AddChild'
+            ]
+        ];
+        $res = $this->_webApiCall($serviceInfo, ['productSku' => $productSku, 'childSku' => $childSku]);
+        $this->assertTrue($res);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     */
+    public function testRemoveChild()
+    {
+        $productSku = 'configurable';
+        $childSku = 'simple_10';
+        $this->assertTrue($this->removeChild($productSku, $childSku));
+    }
+
+    protected function removeChild($productSku, $childSku)
+    {
+        $resourcePath = self::RESOURCE_PATH . '/%s/child/%s';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => sprintf($resourcePath, $productSku, $childSku),
+                'httpMethod' => Config::HTTP_METHOD_DELETE
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'RemoveChild'
+            ]
+        ];
+        $requestData = ['productSku' => $productSku, 'childSku' => $childSku];
+        return $this->_webApiCall($serviceInfo, $requestData);
+    }
+
+    /**
+     * @param string $productSku
+     * @return string
+     */
+    protected function getChildren($productSku)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $productSku  . '/children',
+                'httpMethod' => Config::HTTP_METHOD_GET
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetChildren'
+            ]
+        ];
+        return $this->_webApiCall($serviceInfo, ['productSku' => $productSku]);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/OptionRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/OptionRepositoryTest.php
new file mode 100644
index 00000000000..01f3bd7a1bd
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/OptionRepositoryTest.php
@@ -0,0 +1,289 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\ConfigurableProduct\Api;
+
+use Magento\Webapi\Model\Rest\Config;
+
+class OptionRepositoryTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    const SERVICE_NAME = 'configurableProductOptionRepositoryV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/configurable-products';
+
+    /**
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     */
+    public function testGet()
+    {
+        $productSku = 'configurable';
+
+        $options = $this->getList($productSku);
+        $this->assertTrue(is_array($options));
+        $this->assertNotEmpty($options);
+
+        foreach ($options as $option) {
+            /** @var array $result */
+            $result = $this->get($productSku, $option['id']);
+
+            $this->assertTrue(is_array($result));
+            $this->assertNotEmpty($result);
+
+            $this->assertArrayHasKey('id', $result);
+            $this->assertEquals($option['id'], $result['id']);
+
+            $this->assertArrayHasKey('attribute_id', $result);
+            $this->assertEquals($option['attribute_id'], $result['attribute_id']);
+
+            $this->assertArrayHasKey('label', $result);
+            $this->assertEquals($option['label'], $result['label']);
+
+            $this->assertArrayHasKey('values', $result);
+            $this->assertTrue(is_array($result['values']));
+            $this->assertEquals($option['values'], $result['values']);
+        }
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     */
+    public function testGetList()
+    {
+        $productSku = 'configurable';
+
+        /** @var array $result */
+        $result = $this->getList($productSku);
+
+        $this->assertNotEmpty($result);
+        $this->assertTrue(is_array($result));
+        $this->assertArrayHasKey(0, $result);
+
+        $option = $result[0];
+
+        $this->assertNotEmpty($option);
+        $this->assertTrue(is_array($option));
+
+        $this->assertArrayHasKey('id', $option);
+        $this->assertArrayHasKey('label', $option);
+        $this->assertEquals($option['label'], 'Test Configurable');
+
+        $this->assertArrayHasKey('values', $option);
+        $this->assertTrue(is_array($option));
+        $this->assertNotEmpty($option);
+
+        $expectedValues = [
+            ['pricing_value' => 5, 'is_percent' => 0],
+            ['pricing_value' => 5, 'is_percent' => 0]
+        ];
+
+        $this->assertCount(count($expectedValues), $option['values']);
+
+        foreach ($option['values'] as $key => $value) {
+            $this->assertTrue(is_array($value));
+            $this->assertNotEmpty($value);
+
+            $this->assertArrayHasKey($key, $expectedValues);
+            $expectedValue = $expectedValues[$key];
+
+            $this->assertArrayHasKey('pricing_value', $value);
+            $this->assertEquals($expectedValue['pricing_value'], $value['pricing_value']);
+
+            $this->assertArrayHasKey('is_percent', $value);
+            $this->assertEquals($expectedValue['is_percent'], $value['is_percent']);
+        }
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Requested product doesn't exist
+     */
+    public function testGetUndefinedProduct()
+    {
+        $productSku = 'product_not_exist';
+        $this->getList($productSku);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Requested option doesn't exist: -42
+     */
+    public function testGetUndefinedOption()
+    {
+        $productSku = 'configurable';
+        $attributeId = -42;
+        $this->get($productSku, $attributeId);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     */
+    public function testDelete()
+    {
+        $productSku = 'configurable';
+
+        $optionList = $this->getList($productSku);
+        $optionId = $optionList[0]['id'];
+        $resultRemove = $this->delete($productSku, $optionId);
+        $optionListRemoved = $this->getList($productSku);
+
+        $this->assertTrue($resultRemove);
+        $this->assertEquals(count($optionList) - 1, count($optionListRemoved));
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/configurable_attribute.php
+     */
+    public function testAdd()
+    {
+        $productSku = 'simple';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $productSku . '/options',
+                'httpMethod' => Config::HTTP_METHOD_POST
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save'
+            ]
+        ];
+        $option = [
+            'attribute_id' => 'test_configurable',
+            'type' => 'select',
+            'label' => 'Test',
+            'values' => [
+                [
+                    'value_index' => 1,
+                    'pricing_value' => '3',
+                    'is_percent' => 0
+                ]
+            ],
+        ];
+        /** @var int $result */
+        $result = $this->_webApiCall($serviceInfo, ['productSku' => $productSku, 'option' => $option]);
+        $this->assertGreaterThan(0, $result);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+     */
+    public function testUpdate()
+    {
+        $productSku = 'configurable';
+        $configurableAttribute = $this->getConfigurableAttribute($productSku);
+        $optionId = $configurableAttribute[0]['id'];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $productSku . '/options' . '/' . $optionId,
+                'httpMethod' => Config::HTTP_METHOD_PUT
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save'
+            ]
+        ];
+
+        $option = [
+            'label' => 'Update Test Configurable'
+        ];
+
+        $requestBody = ['option' => $option];
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            $requestBody['productSku'] = $productSku;
+            $requestBody['option']['id'] = $optionId;
+        }
+
+        $result = $this->_webApiCall($serviceInfo, $requestBody);
+        $this->assertGreaterThan(0, $result);
+        $configurableAttribute = $this->getConfigurableAttribute($productSku);
+        $this->assertEquals($option['label'], $configurableAttribute[0]['label']);
+    }
+
+    /**
+     * @param string $productSku
+     * @return array
+     */
+    protected function getConfigurableAttribute($productSku)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $productSku . '/options/all',
+                'httpMethod' => Config::HTTP_METHOD_GET
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetList'
+            ]
+        ];
+        return $this->_webApiCall($serviceInfo, ['productSku' => $productSku]);
+    }
+
+    /**
+     * @param string $productSku
+     * @param int $optionId
+     * @return bool
+     */
+    private function delete($productSku, $optionId)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $productSku . '/options/' . $optionId,
+                'httpMethod' => Config::HTTP_METHOD_DELETE
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'DeleteById'
+            ]
+        ];
+        return $this->_webApiCall($serviceInfo, ['productSku' => $productSku, 'optionId' => $optionId]);
+    }
+
+    /**
+     * @param $productSku
+     * @param $optionId
+     * @return array
+     */
+    protected function get($productSku, $optionId)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $productSku . '/options/' . $optionId,
+                'httpMethod'   => Config::HTTP_METHOD_GET
+            ],
+            'soap' => [
+                'service'        => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation'      => self::SERVICE_NAME . 'Get'
+            ]
+        ];
+        return $this->_webApiCall($serviceInfo, ['productSku' => $productSku, 'optionId' => $optionId]);
+    }
+
+    /**
+     * @param $productSku
+     * @return array
+     */
+    protected function getList($productSku)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $productSku . '/options/all',
+                'httpMethod'   => Config::HTTP_METHOD_GET
+            ],
+            'soap' => [
+                'service'        => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation'      => self::SERVICE_NAME . 'GetList'
+            ]
+        ];
+        return $this->_webApiCall($serviceInfo, ['productSku' => $productSku]);
+    }
+
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/OptionTypesListTest.php b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/OptionTypesListTest.php
new file mode 100644
index 00000000000..1a99fd960db
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/ConfigurableProduct/Api/OptionTypesListTest.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\ConfigurableProduct\Api;
+
+use Magento\Webapi\Model\Rest\Config;
+
+class OptionTypesListTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    const SERVICE_READ_NAME = 'configurableProductOptionTypesListV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/configurable-products/:productSku/options/';
+
+    public function testGetTypes()
+    {
+        $expectedTypes = ['multiselect', 'select'];
+        $result = $this->getTypes();
+        $this->assertEquals($expectedTypes, $result);
+    }
+
+    /**
+     * @return array
+     */
+    protected function getTypes()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => str_replace(':productSku/', '', self::RESOURCE_PATH) . 'types',
+                'httpMethod'   => Config::HTTP_METHOD_GET
+            ],
+            'soap' => [
+                'service'        => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation'      => self::SERVICE_READ_NAME . 'GetItems'
+            ]
+        ];
+        return $this->_webApiCall($serviceInfo);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php
new file mode 100644
index 00000000000..32eca4e2256
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementMeTest.php
@@ -0,0 +1,335 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Customer\Api;
+
+use Magento\Customer\Api\Data\CustomerInterface;
+use Magento\Customer\Model\CustomerRegistry;
+use Magento\Integration\Model\Oauth\Token as TokenModel;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\Helper\Customer as CustomerHelper;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+/**
+ * Class AccountManagementMeTest
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ * @magentoApiDataFixture Magento/Customer/_files/customer.php
+ * @magentoApiDataFixture Magento/Customer/_files/customer_two_addresses.php
+ */
+class AccountManagementMeTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    const RESOURCE_PATH = '/V1/customers/me';
+    const RESOURCE_PATH_CUSTOMER_TOKEN = "/V1/integration/customer/token";
+
+    /**
+     * @var CustomerRepositoryInterface
+     */
+    private $customerRepository;
+
+    /**
+     * @var AccountManagementInterface
+     */
+    private $customerAccountManagement;
+
+    /**
+     * @var CustomerRegistry
+     */
+    private $customerRegistry;
+
+    /**
+     * @var CustomerHelper
+     */
+    private $customerHelper;
+
+    /**
+     * @var TokenModel
+     */
+    private $token;
+
+    /**
+     * @var CustomerInterface
+     */
+    private $customerData;
+
+    /**
+     * @var \Magento\Framework\Reflection\DataObjectProcessor
+     */
+    private $dataObjectProcessor;
+
+    /**
+     * Execute per test initialization.
+     */
+    public function setUp()
+    {
+        $this->_markTestAsRestOnly();
+
+        $this->customerRegistry = Bootstrap::getObjectManager()->get(
+            'Magento\Customer\Model\CustomerRegistry'
+        );
+
+        $this->customerRepository = Bootstrap::getObjectManager()->get(
+            'Magento\Customer\Api\CustomerRepositoryInterface',
+            ['customerRegistry' => $this->customerRegistry]
+        );
+
+        $this->customerAccountManagement = Bootstrap::getObjectManager()
+            ->get('Magento\Customer\Api\AccountManagementInterface');
+
+        $this->customerHelper = new CustomerHelper();
+        $this->customerData = $this->customerHelper->createSampleCustomer();
+
+        // get token
+        $this->resetTokenForCustomerSampleData();
+
+        $this->dataObjectProcessor = Bootstrap::getObjectManager()->create(
+            'Magento\Framework\Reflection\DataObjectProcessor'
+        );
+    }
+
+    /**
+     * Ensure that fixture customer and his addresses are deleted.
+     */
+    public function tearDown()
+    {
+        unset($this->customerRepository);
+
+        /** @var \Magento\Framework\Registry $registry */
+        $registry = Bootstrap::getObjectManager()->get('Magento\Framework\Registry');
+        $registry->unregister('isSecureArea');
+        $registry->register('isSecureArea', true);
+
+        $registry->unregister('isSecureArea');
+        $registry->register('isSecureArea', false);
+        parent::tearDown();
+    }
+
+    public function testChangePassword()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/password',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+                'token' => $this->token,
+            ],
+        ];
+        $requestData = ['currentPassword' => 'test@123', 'newPassword' => '123@test'];
+        $this->assertTrue($this->_webApiCall($serviceInfo, $requestData));
+
+        $customerResponseData = $this->customerAccountManagement
+            ->authenticate($this->customerData[CustomerInterface::EMAIL], '123@test');
+        $this->assertEquals($this->customerData[CustomerInterface::ID], $customerResponseData->getId());
+    }
+
+    public function testUpdateCustomer()
+    {
+        $customerData = $this->_getCustomerData($this->customerData[CustomerInterface::ID]);
+        $lastName = $customerData->getLastname();
+
+        $updatedCustomerData = $this->dataObjectProcessor->buildOutputDataArray(
+            $customerData,
+            'Magento\Customer\Api\Data\CustomerInterface'
+        );
+        $updatedCustomerData[CustomerInterface::LASTNAME] = $lastName . 'Updated';
+        $updatedCustomerData[CustomerInterface::ID] = 25;
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+                'token' => $this->token,
+            ],
+        ];
+        $requestData = ['customer' => $updatedCustomerData];
+
+        $response = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals($lastName . "Updated", $response[CustomerInterface::LASTNAME]);
+
+        $customerData = $this->_getCustomerData($this->customerData[CustomerInterface::ID]);
+        $this->assertEquals($lastName . "Updated", $customerData->getLastname());
+    }
+
+    public function testGetCustomerData()
+    {
+        //Get expected details from the Service directly
+        $customerData = $this->_getCustomerData($this->customerData[CustomerInterface::ID]);
+        $expectedCustomerDetails = $this->dataObjectProcessor->buildOutputDataArray(
+            $customerData,
+            'Magento\Customer\Api\Data\CustomerInterface'
+        );
+        $expectedCustomerDetails['addresses'][0]['id'] =
+            (int)$expectedCustomerDetails['addresses'][0]['id'];
+
+        $expectedCustomerDetails['addresses'][1]['id'] =
+            (int)$expectedCustomerDetails['addresses'][1]['id'];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+                'token' => $this->token,
+            ],
+        ];
+        $customerDetailsResponse = $this->_webApiCall($serviceInfo);
+
+        unset($expectedCustomerDetails['custom_attributes']);
+        unset($customerDetailsResponse['custom_attributes']); //for REST
+
+        $this->assertEquals($expectedCustomerDetails, $customerDetailsResponse);
+    }
+
+    public function testGetCustomerActivateCustomer()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/activate',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+                'token' => $this->token,
+            ],
+        ];
+        $requestData = ['confirmationKey' => $this->customerData[CustomerInterface::CONFIRMATION]];
+        $customerResponseData = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals($this->customerData[CustomerInterface::ID], $customerResponseData[CustomerInterface::ID]);
+        // Confirmation key is removed after confirmation
+        $this->assertFalse(isset($customerResponseData[CustomerInterface::CONFIRMATION]));
+    }
+
+    /**
+     * Return the customer details.
+     *
+     * @param int $customerId
+     * @return \Magento\Customer\Api\Data\CustomerInterface
+     */
+    protected function _getCustomerData($customerId)
+    {
+        $data = $this->customerRepository->getById($customerId);
+        $this->customerRegistry->remove($customerId);
+        return $data;
+    }
+
+    public function testGetDefaultBillingAddress()
+    {
+        $this->resetTokenForCustomerFixture();
+
+        $fixtureCustomerId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => "/V1/customers/me/billingAddress",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+                'token' => $this->token,
+            ],
+        ];
+        $requestData = ['customerId' => $fixtureCustomerId];
+        $addressData = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(
+            $this->getFirstFixtureAddressData(),
+            $addressData,
+            "Default billing address data is invalid."
+        );
+    }
+
+    public function testGetDefaultShippingAddress()
+    {
+        $this->resetTokenForCustomerFixture();
+
+        $fixtureCustomerId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => "/V1/customers/me/shippingAddress",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+                'token' => $this->token,
+            ],
+        ];
+        $requestData = ['customerId' => $fixtureCustomerId];
+        $addressData = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(
+            $this->getFirstFixtureAddressData(),
+            $addressData,
+            "Default shipping address data is invalid."
+        );
+    }
+
+    /**
+     * Retrieve data of the first fixture address.
+     *
+     * @return array
+     */
+    protected function getFirstFixtureAddressData()
+    {
+        return [
+            'firstname' => 'John',
+            'lastname' => 'Smith',
+            'city' => 'CityM',
+            'country_id' => 'US',
+            'company' => 'CompanyName',
+            'postcode' => '75477',
+            'telephone' => '3468676',
+            'street' => ['Green str, 67'],
+            'id' => 1,
+            'default_billing' => true,
+            'default_shipping' => true,
+            'customer_id' => '1',
+            'region' => ['region' => 'Alabama', 'region_id' => 1, 'region_code' => 'AL'],
+        ];
+    }
+
+    /**
+     * Retrieve data of the second fixture address.
+     *
+     * @return array
+     */
+    protected function getSecondFixtureAddressData()
+    {
+        return [
+            'firstname' => 'John',
+            'lastname' => 'Smith',
+            'city' => 'CityX',
+            'country_id' => 'US',
+            'postcode' => '47676',
+            'telephone' => '3234676',
+            'street' => ['Black str, 48'],
+            'id' => 2,
+            'default_billing' => false,
+            'default_shipping' => false,
+            'customer_id' => '1',
+            'region' => ['region' => 'Alabama', 'region_id' => 1, 'region_code' => 'AL'],
+        ];
+    }
+
+    /**
+     * Sets the test's access token for the customer fixture
+     */
+    protected function resetTokenForCustomerFixture()
+    {
+        $this->resetTokenForCustomer('customer@example.com', 'password');
+    }
+
+    /**
+     * Sets the test's access token for the created customer sample data
+     */
+    protected function resetTokenForCustomerSampleData()
+    {
+        $this->resetTokenForCustomer($this->customerData[CustomerInterface::EMAIL], 'test@123');
+    }
+
+    /**
+     * Sets the test's access token for a particular username and password.
+     *
+     * @param string $username
+     * @param string $password
+     */
+    protected function resetTokenForCustomer($username, $password)
+    {
+        // get customer ID token
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH_CUSTOMER_TOKEN,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+            ],
+        ];
+        $requestData = ['username' => $username, 'password' => $password];
+        $this->token = $this->_webApiCall($serviceInfo, $requestData);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php
new file mode 100644
index 00000000000..50a2790634c
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AccountManagementTest.php
@@ -0,0 +1,778 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Customer\Api;
+
+use Magento\Customer\Api\Data\CustomerInterface as Customer;
+use Magento\Customer\Model\AccountManagement;
+use Magento\Framework\Exception\InputException;
+use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\Helper\Customer as CustomerHelper;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Exception as HTTPExceptionCodes;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+/**
+ * Test class for Magento\Customer\Api\AccountManagementInterface
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class AccountManagementTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+    const SERVICE_NAME = 'customerAccountManagementV1';
+    const RESOURCE_PATH = '/V1/customers';
+
+    /**
+     * Sample values for testing
+     */
+    const ATTRIBUTE_CODE = 'attribute_code';
+    const ATTRIBUTE_VALUE = 'attribute_value';
+
+    /**
+     * @var AccountManagementInterface
+     */
+    private $accountManagement;
+
+    /**
+     * @var \Magento\Customer\Api\Data\AddressDataBuilder
+     */
+    private $addressBuilder;
+
+    /**
+     * @var \Magento\Customer\Api\Data\CustomerDataBuilder
+     */
+    private $customerBuilder;
+
+    /**
+     * @var \Magento\Framework\Api\SearchCriteriaBuilder
+     */
+    private $searchCriteriaBuilder;
+
+    /**
+     * @var \Magento\Framework\Api\SortOrderBuilder
+     */
+    private $sortOrderBuilder;
+
+    /**
+     * @var \Magento\Framework\Api\Search\FilterGroupBuilder
+     */
+    private $filterGroupBuilder;
+
+    /**
+     * @var CustomerHelper
+     */
+    private $customerHelper;
+
+    /**
+     * @var array
+     */
+    private $currentCustomerId;
+
+    /**
+     * @var \Magento\Framework\Reflection\DataObjectProcessor
+     */
+    private $dataObjectProcessor;
+
+    /**
+     * Execute per test initialization.
+     */
+    public function setUp()
+    {
+        $this->accountManagement = Bootstrap::getObjectManager()->get(
+            'Magento\Customer\Api\AccountManagementInterface'
+        );
+        $this->addressBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\Customer\Api\Data\AddressDataBuilder'
+        );
+        $this->customerBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\Customer\Api\Data\CustomerDataBuilder'
+        );
+        $this->searchCriteriaBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\Framework\Api\SearchCriteriaBuilder'
+        );
+        $this->sortOrderBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\Framework\Api\SortOrderBuilder'
+        );
+        $this->filterGroupBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\Framework\Api\Search\FilterGroupBuilder'
+        );
+        $this->customerHelper = new CustomerHelper();
+
+        $this->dataObjectProcessor = Bootstrap::getObjectManager()->create(
+            'Magento\Framework\Reflection\DataObjectProcessor'
+        );
+    }
+
+    public function tearDown()
+    {
+        if (!empty($this->currentCustomerId)) {
+            foreach ($this->currentCustomerId as $customerId) {
+                $serviceInfo = [
+                    'rest' => [
+                        'resourcePath' => self::RESOURCE_PATH . '/' . $customerId,
+                        'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+                    ],
+                    'soap' => [
+                        'service' => CustomerRepositoryTest::SERVICE_NAME,
+                        'serviceVersion' => self::SERVICE_VERSION,
+                        'operation' => CustomerRepositoryTest::SERVICE_NAME . 'DeleteById',
+                    ],
+                ];
+
+                $response = $this->_webApiCall($serviceInfo, ['customerId' => $customerId]);
+
+                $this->assertTrue($response);
+            }
+        }
+        unset($this->accountManagement);
+    }
+
+    public function testCreateCustomer()
+    {
+        $customerData = $this->_createCustomer();
+        $this->assertNotNull($customerData['id']);
+    }
+
+    public function testCreateCustomerWithErrors()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => RestConfig::HTTP_METHOD_POST, ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'CreateAccount',
+            ],
+        ];
+
+        $customerDataArray = $this->dataObjectProcessor->buildOutputDataArray(
+            $this->customerHelper->createSampleCustomerDataObject(),
+            '\Magento\Customer\Api\Data\CustomerInterface'
+        );
+        $invalidEmail = 'invalid';
+        $customerDataArray['email'] = $invalidEmail;
+        $requestData = ['customer' => $customerDataArray, 'password' => CustomerHelper::PASSWORD];
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+            $this->fail('Expected exception did not occur.');
+        } catch (\Exception $e) {
+            if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+                $expectedException = new InputException();
+                $expectedException->addError(
+                    InputException::INVALID_FIELD_VALUE,
+                    ['fieldName' => 'email', 'value' => $invalidEmail]
+                );
+                $this->assertInstanceOf('SoapFault', $e);
+                $this->checkSoapFault(
+                    $e,
+                    $expectedException->getRawMessage(),
+                    'env:Sender',
+                    $expectedException->getParameters() // expected error parameters
+                );
+            } else {
+                $this->assertEquals(HTTPExceptionCodes::HTTP_BAD_REQUEST, $e->getCode());
+                $exceptionData = $this->processRestExceptionResult($e);
+                $expectedExceptionData = [
+                    'message' => InputException::INVALID_FIELD_VALUE,
+                    'parameters' => [
+                        'fieldName' => 'email',
+                        'value' => $invalidEmail,
+                    ],
+                ];
+                $this->assertEquals($expectedExceptionData, $exceptionData);
+            }
+        }
+    }
+
+    /**
+     * Test customer activation when it is required
+     *
+     * @magentoConfigFixture default_store customer/create_account/confirm 0
+     */
+    public function testActivateCustomer()
+    {
+        $customerData = $this->_createCustomer();
+        $this->assertNotNull($customerData[Customer::CONFIRMATION], 'Customer activation is not required');
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $customerData[Customer::EMAIL] . '/activate',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Activate',
+            ],
+        ];
+
+        $requestData = [
+            'email' => $customerData[Customer::EMAIL],
+            'confirmationKey' => $customerData[Customer::CONFIRMATION],
+        ];
+
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+
+        $this->assertEquals($customerData[Customer::ID], $result[Customer::ID], 'Wrong customer!');
+        $this->assertTrue(
+            !isset($result[Customer::CONFIRMATION]) || $result[Customer::CONFIRMATION] === null,
+            'Customer is not activated!'
+        );
+    }
+
+    public function testGetCustomerActivateCustomer()
+    {
+        $customerData = $this->_createCustomer();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $customerData[Customer::EMAIL] . '/activate',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Activate',
+            ],
+        ];
+        $requestData = [
+            'email' => $customerData[Customer::EMAIL],
+            'confirmationKey' => $customerData[Customer::CONFIRMATION],
+        ];
+
+        $customerResponseData = $this->_webApiCall($serviceInfo, $requestData);
+
+        $this->assertEquals($customerData[Customer::ID], $customerResponseData[Customer::ID]);
+        // Confirmation key is removed after confirmation
+        $this->assertFalse(isset($customerResponseData[Customer::CONFIRMATION]));
+    }
+
+    public function testValidateResetPasswordLinkToken()
+    {
+        $customerData = $this->_createCustomer();
+        /** @var \Magento\Customer\Model\Customer $customerModel */
+        $customerModel = Bootstrap::getObjectManager()->create('Magento\Customer\Model\CustomerFactory')
+            ->create();
+        $customerModel->load($customerData[Customer::ID]);
+        $rpToken = 'lsdj579slkj5987slkj595lkj';
+        $customerModel->setRpToken('lsdj579slkj5987slkj595lkj');
+        $customerModel->setRpTokenCreatedAt(date('Y-m-d'));
+        $customerModel->save();
+        $path = self::RESOURCE_PATH . '/' . $customerData[Customer::ID] . '/password/resetLinkToken/' . $rpToken;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $path,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'ValidateResetPasswordLinkToken',
+            ],
+        ];
+
+        $this->_webApiCall(
+            $serviceInfo,
+            ['customerId' => $customerData['id'], 'resetPasswordLinkToken' => $rpToken]
+        );
+    }
+
+    public function testValidateResetPasswordLinkTokenInvalidToken()
+    {
+        $customerData = $this->_createCustomer();
+        $invalidToken = 'fjjkafjie';
+        $path = self::RESOURCE_PATH . '/' . $customerData[Customer::ID] . '/password/resetLinkToken/' . $invalidToken;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $path,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'ValidateResetPasswordLinkToken',
+            ],
+        ];
+
+        $expectedMessage = 'Reset password token mismatch.';
+
+        try {
+            if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+                $this->_webApiCall(
+                    $serviceInfo,
+                    ['customerId' => $customerData['id'], 'resetPasswordLinkToken' => 'invalid']
+                );
+            } else {
+                $this->_webApiCall($serviceInfo);
+            }
+            $this->fail("Expected exception to be thrown.");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "Exception message does not match"
+            );
+        } catch (\Exception $e) {
+            $errorObj = $this->processRestExceptionResult($e);
+            $this->assertEquals($expectedMessage, $errorObj['message']);
+            $this->assertEquals(HTTPExceptionCodes::HTTP_BAD_REQUEST, $e->getCode());
+        }
+    }
+
+    public function testInitiatePasswordMissingRequiredFields()
+    {
+        $this->_markTestAsRestOnly('Soap clients explicitly check for required fields based on WSDL.');
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/password',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ]
+        ];
+
+        try {
+            $this->_webApiCall($serviceInfo);
+        } catch (\Exception $e) {
+            $this->assertEquals(\Magento\Webapi\Exception::HTTP_BAD_REQUEST, $e->getCode());
+            $exceptionData = $this->processRestExceptionResult($e);
+            $expectedExceptionData = [
+                'message' => InputException::DEFAULT_MESSAGE,
+                'errors' => [
+                    [
+                        'message' => InputException::REQUIRED_FIELD,
+                        'parameters' => [
+                            'fieldName' => 'email',
+                        ],
+                    ],
+                    [
+                        'message' => InputException::REQUIRED_FIELD,
+                        'parameters' => [
+                            'fieldName' => 'template',
+                        ]
+                    ],
+                ],
+            ];
+            $this->assertEquals($expectedExceptionData, $exceptionData);
+        }
+    }
+
+    public function testInitiatePasswordReset()
+    {
+        $customerData = $this->_createCustomer();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/password',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'InitiatePasswordReset',
+            ],
+        ];
+        $requestData = [
+            'email' => $customerData[Customer::EMAIL],
+            'template' => AccountManagement::EMAIL_RESET,
+            'websiteId' => $customerData[Customer::WEBSITE_ID],
+        ];
+        // This api doesn't return any response.
+        // No exception or response means the request was processed successfully.
+        // The webapi framework does not return the header information as yet. A check for HTTP 200 would be ideal here
+        $this->_webApiCall($serviceInfo, $requestData);
+    }
+
+    public function testSendPasswordResetLinkBadEmailOrWebsite()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/password',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'InitiatePasswordReset',
+            ],
+        ];
+        $requestData = [
+            'email' => 'dummy@example.com',
+            'template' => AccountManagement::EMAIL_RESET,
+            'websiteId' => 0,
+        ];
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+        } catch (\Exception $e) {
+            $expectedErrorParameters =
+                [
+                    'fieldName' => 'email',
+                    'fieldValue' => 'dummy@example.com',
+                    'field2Name' => 'websiteId',
+                    'field2Value' => 0,
+                ];
+            if (TESTS_WEB_API_ADAPTER == self::ADAPTER_REST) {
+                $errorObj = $this->processRestExceptionResult($e);
+                $this->assertEquals(
+                    NoSuchEntityException::MESSAGE_DOUBLE_FIELDS,
+                    $errorObj['message']
+                );
+                $this->assertEquals($expectedErrorParameters, $errorObj['parameters']);
+                $this->assertEquals(HTTPExceptionCodes::HTTP_NOT_FOUND, $e->getCode());
+            } else {
+                $this->assertInstanceOf('SoapFault', $e);
+                $this->checkSoapFault(
+                    $e,
+                    NoSuchEntityException::MESSAGE_DOUBLE_FIELDS,
+                    'env:Sender',
+                    $expectedErrorParameters
+                );
+            }
+        }
+    }
+
+    public function testGetConfirmationStatus()
+    {
+        $customerData = $this->_createCustomer();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $customerData[Customer::ID] . '/confirm',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetConfirmationStatus',
+            ],
+        ];
+
+        $confirmationResponse = $this->_webApiCall($serviceInfo, ['customerId' => $customerData['id']]);
+
+        $this->assertEquals(AccountManagement::ACCOUNT_CONFIRMATION_NOT_REQUIRED, $confirmationResponse);
+    }
+
+    public function testResendConfirmation()
+    {
+        $customerData = $this->_createCustomer();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/confirm',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'ResendConfirmation',
+            ],
+        ];
+        $requestData = [
+            'email' => $customerData[Customer::EMAIL],
+            'websiteId' => $customerData[Customer::WEBSITE_ID],
+        ];
+        // This api doesn't return any response.
+        // No exception or response means the request was processed successfully.
+        // The webapi framework does not return the header information as yet. A check for HTTP 200 would be ideal here
+        $this->_webApiCall($serviceInfo, $requestData);
+    }
+
+    public function testResendConfirmationBadEmailOrWebsite()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/confirm',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'ResendConfirmation',
+            ],
+        ];
+        $requestData = [
+            'email' => 'dummy@example.com',
+            'websiteId' => 0,
+        ];
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+        } catch (\Exception $e) {
+            $expectedErrorParameters =
+                [
+                    'fieldName' => 'email',
+                    'fieldValue' => 'dummy@example.com',
+                    'field2Name' => 'websiteId',
+                    'field2Value' => 0,
+                ];
+            if (TESTS_WEB_API_ADAPTER == self::ADAPTER_REST) {
+                $errorObj = $this->processRestExceptionResult($e);
+                $this->assertEquals(
+                    NoSuchEntityException::MESSAGE_DOUBLE_FIELDS,
+                    $errorObj['message']
+                );
+                $this->assertEquals($expectedErrorParameters, $errorObj['parameters']);
+                $this->assertEquals(HTTPExceptionCodes::HTTP_NOT_FOUND, $e->getCode());
+            } else {
+                $this->assertInstanceOf('SoapFault', $e);
+                $this->checkSoapFault(
+                    $e,
+                    NoSuchEntityException::MESSAGE_DOUBLE_FIELDS,
+                    'env:Sender',
+                    $expectedErrorParameters
+                );
+            }
+        }
+    }
+
+    public function testValidateCustomerData()
+    {
+        $customerData = $this->customerHelper->createSampleCustomerDataObject();
+        $customerData = $this->customerBuilder->populate($customerData)
+            ->setFirstname(null)->setLastname(null)->create();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/validate',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Validate',
+            ],
+        ];
+        $customerData = $this->dataObjectProcessor->buildOutputDataArray(
+            $customerData,
+            '\Magento\Customer\Api\Data\CustomerInterface'
+        );
+        $requestData = ['customer' => $customerData];
+        $validationResponse = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertFalse($validationResponse['valid']);
+        $this->assertEquals('The first name cannot be empty.', $validationResponse['messages'][0]);
+        $this->assertEquals('The last name cannot be empty.', $validationResponse['messages'][1]);
+    }
+
+    public function testIsReadonly()
+    {
+        $customerData = $this->_createCustomer();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $customerData[Customer::ID] . '/permissions/readonly',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'IsReadonly',
+            ],
+        ];
+
+        $response = $this->_webApiCall($serviceInfo, ['customerId' => $customerData['id']]);
+
+        $this->assertFalse($response);
+    }
+
+    public function testEmailAvailable()
+    {
+        $customerData = $this->_createCustomer();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/isEmailAvailable',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'IsEmailAvailable',
+            ],
+        ];
+        $requestData = [
+            'customerEmail' => $customerData[Customer::EMAIL],
+            'websiteId' => $customerData[Customer::WEBSITE_ID],
+        ];
+        $this->assertFalse($this->_webApiCall($serviceInfo, $requestData));
+    }
+
+    public function testEmailAvailableInvalidEmail()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/isEmailAvailable',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'IsEmailAvailable',
+            ],
+        ];
+        $requestData = [
+            'customerEmail' => 'invalid',
+            'websiteId' => 0,
+        ];
+        $this->assertTrue($this->_webApiCall($serviceInfo, $requestData));
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Customer/_files/attribute_user_defined_address.php
+     * @magentoApiDataFixture Magento/Customer/_files/attribute_user_defined_customer.php
+     */
+    public function testCustomAttributes()
+    {
+        //Sample customer data comes with the disable_auto_group_change custom attribute
+        $customerData = $this->customerHelper->createSampleCustomerDataObject();
+        //address attribute code from fixture
+        $fixtureAddressAttributeCode = 'address_user_attribute';
+        //customer attribute code from fixture
+        $fixtureCustomerAttributeCode = 'user_attribute';
+        //Custom Attribute Values
+        $address1CustomAttributeValue = 'value1';
+        $address2CustomAttributeValue = 'value2';
+        $customerCustomAttributeValue = 'value3';
+
+        $addresses = $customerData->getAddresses();
+        $address1 = $this->addressBuilder
+            ->populate($addresses[0])
+            ->setCustomAttribute($fixtureAddressAttributeCode, $address1CustomAttributeValue)
+            ->create();
+        $address2 = $this->addressBuilder
+            ->populate($addresses[1])
+            ->setCustomAttribute($fixtureAddressAttributeCode, $address2CustomAttributeValue)
+            ->create();
+
+        $customer = $this->customerBuilder
+            ->populate($customerData)
+            ->setAddresses([$address1, $address2])
+            ->setCustomAttribute($fixtureCustomerAttributeCode, $customerCustomAttributeValue)
+            ->create();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'CreateAccount',
+            ],
+        ];
+
+        $customerDataArray = $this->dataObjectProcessor->buildOutputDataArray(
+            $customer,
+            '\Magento\Customer\Api\Data\CustomerInterface'
+        );
+        $requestData = ['customer' => $customerDataArray, 'password' => CustomerHelper::PASSWORD];
+        $customerData = $this->_webApiCall($serviceInfo, $requestData);
+        $customerId = $customerData['id'];
+        //TODO: Fix assertions to verify custom attributes
+        $this->assertNotNull($customerData);
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $customerId ,
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => CustomerRepositoryTest::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => CustomerRepositoryTest::SERVICE_NAME . 'DeleteById',
+            ],
+        ];
+
+        $response = $this->_webApiCall($serviceInfo, ['customerId' => $customerId]);
+        $this->assertTrue($response);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Customer/_files/customer.php
+     * @magentoApiDataFixture Magento/Customer/_files/customer_two_addresses.php
+     */
+    public function testGetDefaultBillingAddress()
+    {
+        $fixtureCustomerId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/$fixtureCustomerId/billingAddress",
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetDefaultBillingAddress',
+            ],
+        ];
+        $requestData = ['customerId' => $fixtureCustomerId];
+        $addressData = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(
+            $this->getFirstFixtureAddressData(),
+            $addressData,
+            "Default billing address data is invalid."
+        );
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Customer/_files/customer.php
+     * @magentoApiDataFixture Magento/Customer/_files/customer_two_addresses.php
+     */
+    public function testGetDefaultShippingAddress()
+    {
+        $fixtureCustomerId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/$fixtureCustomerId/shippingAddress",
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetDefaultShippingAddress',
+            ],
+        ];
+        $requestData = ['customerId' => $fixtureCustomerId];
+        $addressData = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(
+            $this->getFirstFixtureAddressData(),
+            $addressData,
+            "Default shipping address data is invalid."
+        );
+    }
+
+    /**
+     * @return array|bool|float|int|string
+     */
+    protected function _createCustomer()
+    {
+        $customerData = $this->customerHelper->createSampleCustomer();
+        $this->currentCustomerId[] = $customerData['id'];
+        return $customerData;
+    }
+
+    /**
+     * Retrieve data of the first fixture address.
+     *
+     * @return array
+     */
+    protected function getFirstFixtureAddressData()
+    {
+        return [
+            'firstname' => 'John',
+            'lastname' => 'Smith',
+            'city' => 'CityM',
+            'country_id' => 'US',
+            'company' => 'CompanyName',
+            'postcode' => '75477',
+            'telephone' => '3468676',
+            'street' => ['Green str, 67'],
+            'id' => 1,
+            'default_billing' => true,
+            'default_shipping' => true,
+            'customer_id' => '1',
+            'region' => ['region' => 'Alabama', 'region_id' => 1, 'region_code' => 'AL'],
+        ];
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AddressMetadataTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AddressMetadataTest.php
new file mode 100644
index 00000000000..f3acea94fc9
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AddressMetadataTest.php
@@ -0,0 +1,274 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Customer\Api;
+
+use Magento\Customer\Api\Data\AddressInterface as Address;
+use Magento\Customer\Model\Data\AttributeMetadata;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+
+/**
+ * Class AddressMetadataTest
+ */
+class AddressMetadataTest extends WebapiAbstract
+{
+    const SERVICE_NAME = "customerAddressMetadataV1";
+    const SERVICE_VERSION = "V1";
+    const RESOURCE_PATH = "/V1/attributeMetadata/customerAddress";
+
+    /**
+     * Test retrieval of attribute metadata for the address entity type.
+     *
+     * @param string $attributeCode The attribute code of the requested metadata.
+     * @param array $expectedMetadata Expected entity metadata for the attribute code.
+     * @dataProvider getAttributeMetadataDataProvider
+     */
+    public function testGetAttributeMetadata($attributeCode, $expectedMetadata)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/attribute/$attributeCode",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetAttributeMetadata',
+            ],
+        ];
+
+        $requestData = [
+            'attributeCode' => $attributeCode,
+        ];
+
+        $attributeMetadata = $this->_webapiCall($serviceInfo, $requestData);
+        $validationResult = $this->checkValidationRules($expectedMetadata, $attributeMetadata);
+        list($expectedMetadata, $attributeMetadata) = $validationResult;
+        $this->assertEquals($expectedMetadata, $attributeMetadata);
+    }
+
+    /**
+     * Data provider for testGetAttributeMetadata.
+     *
+     * @return array
+     */
+    public function getAttributeMetadataDataProvider()
+    {
+        return [
+            Address::POSTCODE => [
+                Address::POSTCODE,
+                [
+                    AttributeMetadata::ATTRIBUTE_CODE => 'postcode',
+                    AttributeMetadata::FRONTEND_INPUT => 'text',
+                    AttributeMetadata::INPUT_FILTER => '',
+                    AttributeMetadata::STORE_LABEL => 'Zip/Postal Code',
+                    AttributeMetadata::VALIDATION_RULES => [],
+                    AttributeMetadata::VISIBLE => true,
+                    AttributeMetadata::REQUIRED => false,
+                    AttributeMetadata::MULTILINE_COUNT => 0,
+                    AttributeMetadata::DATA_MODEL => 'Magento\Customer\Model\Attribute\Data\Postcode',
+                    AttributeMetadata::OPTIONS => [],
+                    AttributeMetadata::FRONTEND_CLASS => '',
+                    AttributeMetadata::FRONTEND_LABEL => 'Zip/Postal Code',
+                    AttributeMetadata::NOTE => '',
+                    AttributeMetadata::SYSTEM => true,
+                    AttributeMetadata::USER_DEFINED => false,
+                    AttributeMetadata::BACKEND_TYPE => 'varchar',
+                    AttributeMetadata::SORT_ORDER => 110
+                ],
+            ]
+        ];
+    }
+
+    /**
+     * Test retrieval of all address attribute metadata.
+     */
+    public function testGetAllAttributesMetadata()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetAllAttributesMetadata',
+            ],
+        ];
+
+        $attributeMetadata = $this->_webApiCall($serviceInfo);
+        $this->assertCount(19, $attributeMetadata);
+        $postcode = $this->getAttributeMetadataDataProvider()[Address::POSTCODE][1];
+        $validationResult = $this->checkMultipleAttributesValidationRules($postcode, $attributeMetadata);
+        list($postcode, $attributeMetadata) = $validationResult;
+        $this->assertContains($postcode, $attributeMetadata);
+    }
+
+    /**
+     * Test retrieval of custom address attribute metadata.
+     *
+     * @magentoApiDataFixture Magento/Customer/_files/attribute_user_defined_address_custom_attribute.php
+     */
+    public function testGetCustomAttributesMetadata()
+    {
+        $customAttributeCode = 'custom_attribute1';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/custom',
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetCustomAttributesMetadata',
+            ],
+        ];
+
+        $requestData = ['attribute_code' => $customAttributeCode];
+        $attributeMetadata = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertCount(2, $attributeMetadata);
+        $this->assertEquals($customAttributeCode, $attributeMetadata[0]['attribute_code']);
+    }
+
+    /**
+     * Test retrieval of attributes
+     *
+     * @param string $formCode Form code
+     * @param array $expectedMetadata The expected attribute metadata
+     * @dataProvider getAttributesDataProvider
+     */
+    public function testGetAttributes($formCode, $expectedMetadata)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/form/$formCode",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetAttributes',
+            ],
+        ];
+
+        $requestData = [
+            'formCode' => $formCode,
+        ];
+
+        $attributeMetadataList = $this->_webApiCall($serviceInfo, $requestData);
+        foreach ($attributeMetadataList as $attributeMetadata) {
+            if (isset($attributeMetadata['attribute_code'])
+                && $attributeMetadata['attribute_code'] == $expectedMetadata['attribute_code']
+            ) {
+                $validationResult = $this->checkValidationRules($expectedMetadata, $attributeMetadata);
+                list($expectedMetadata, $attributeMetadata) = $validationResult;
+                $this->assertEquals($expectedMetadata, $attributeMetadata);
+                break;
+            }
+        }
+    }
+
+    /**
+     * Data provider for testGetAttributes.
+     *
+     * @return array
+     */
+    public function getAttributesDataProvider()
+    {
+        $attributeMetadata = $this->getAttributeMetadataDataProvider();
+        return [
+            [
+                'customer_address_edit',
+                $attributeMetadata[Address::POSTCODE][1],
+            ]
+        ];
+    }
+
+    /**
+     * Checks that expected and actual attribute metadata validation rules are equal
+     * and removes the validation rules entry from expected and actual attribute metadata
+     *
+     * @param array $expectedResult
+     * @param array $actualResult
+     * @return array
+     */
+    public function checkValidationRules($expectedResult, $actualResult)
+    {
+        $expectedRules = [];
+        $actualRules = [];
+
+        if (isset($expectedResult[AttributeMetadata::VALIDATION_RULES])) {
+            $expectedRules = $expectedResult[AttributeMetadata::VALIDATION_RULES];
+            unset($expectedResult[AttributeMetadata::VALIDATION_RULES]);
+        }
+        if (isset($actualResult[AttributeMetadata::VALIDATION_RULES])) {
+            $actualRules = $actualResult[AttributeMetadata::VALIDATION_RULES];
+            unset($actualResult[AttributeMetadata::VALIDATION_RULES]);
+        }
+
+        if (is_array($expectedRules) && is_array($actualRules)) {
+            foreach ($expectedRules as $expectedRule) {
+                if (isset($expectedRule['name']) && isset($expectedRule['value'])) {
+                    $found = false;
+                    foreach ($actualRules as $actualRule) {
+                        if (isset($actualRule['name']) && isset($actualRule['value'])) {
+                            if ($expectedRule['name'] == $actualRule['name']
+                                && $expectedRule['value'] == $actualRule['value']
+                            ) {
+                                $found = true;
+                                break;
+                            }
+                        }
+                    }
+                    $this->assertTrue($found);
+                }
+            }
+        }
+        return [$expectedResult, $actualResult];
+    }
+
+    /**
+     * Check specific attribute validation rules in set of multiple attributes
+     *
+     * @param array $expectedResult Set of expected attribute metadata
+     * @param array $actualResultSet Set of actual attribute metadata
+     * @return array
+     */
+    public function checkMultipleAttributesValidationRules($expectedResult, $actualResultSet)
+    {
+        if (is_array($expectedResult) && is_array($actualResultSet)) {
+            if (isset($expectedResult[AttributeMetadata::ATTRIBUTE_CODE])) {
+                foreach ($actualResultSet as $actualAttributeKey => $actualAttribute) {
+                    if (isset($actualAttribute[AttributeMetadata::ATTRIBUTE_CODE])
+                        && $expectedResult[AttributeMetadata::ATTRIBUTE_CODE]
+                        == $actualAttribute[AttributeMetadata::ATTRIBUTE_CODE]
+                    ) {
+                        $this->checkValidationRules($expectedResult, $actualAttribute);
+                        unset($actualResultSet[$actualAttributeKey][AttributeMetadata::VALIDATION_RULES]);
+                    }
+                }
+                unset($expectedResult[AttributeMetadata::VALIDATION_RULES]);
+            }
+        }
+        return [$expectedResult, $actualResultSet];
+    }
+
+    /**
+     * Remove test attribute
+     */
+    public static function tearDownAfterClass()
+    {
+        parent::tearDownAfterClass();
+        /** @var \Magento\Customer\Model\Attribute $attribute */
+        $attribute = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            'Magento\Customer\Model\Attribute'
+        );
+        foreach (['custom_attribute1', 'custom_attribute2'] as $attributeCode) {
+            $attribute->loadByCode('customer_address', $attributeCode);
+            $attribute->delete();
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/AddressRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AddressRepositoryTest.php
new file mode 100644
index 00000000000..5bc344be717
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/AddressRepositoryTest.php
@@ -0,0 +1,166 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Customer\Api;
+
+use Magento\TestFramework\Helper\Bootstrap;
+
+class AddressRepositoryTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    const SOAP_SERVICE_NAME = 'customerAddressRepositoryV1';
+    const SOAP_SERVICE_VERSION = 'V1';
+
+    /** @var \Magento\Customer\Api\AddressRepositoryInterface */
+    protected $addressRepository;
+
+    /** @var \Magento\Customer\Api\CustomerRepositoryInterface */
+    protected $customerRepository;
+
+    protected function setUp()
+    {
+        $objectManager = Bootstrap::getObjectManager();
+        $this->customerRepository = $objectManager->get(
+            'Magento\Customer\Api\CustomerRepositoryInterface'
+        );
+        $this->addressRepository = $objectManager->get(
+            'Magento\Customer\Api\AddressRepositoryInterface'
+        );
+        parent::setUp();
+    }
+
+    /**
+     * Ensure that fixture customer and his addresses are deleted.
+     */
+    protected function tearDown()
+    {
+        /** @var \Magento\Framework\Registry $registry */
+        $registry = Bootstrap::getObjectManager()->get('Magento\Framework\Registry');
+        $registry->unregister('isSecureArea');
+        $registry->register('isSecureArea', true);
+
+        try {
+            $fixtureFirstAddressId = 1;
+            $this->addressRepository->deleteById($fixtureFirstAddressId);
+        } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
+            /** First address fixture was not used */
+        }
+        try {
+            $fixtureSecondAddressId = 2;
+            $this->addressRepository->deleteById($fixtureSecondAddressId);
+        } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
+            /** Second address fixture was not used */
+        }
+        try {
+            $fixtureCustomerId = 1;
+            $this->customerRepository->deleteById($fixtureCustomerId);
+        } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
+            /** Customer fixture was not used */
+        }
+
+        $registry->unregister('isSecureArea');
+        $registry->register('isSecureArea', false);
+        parent::tearDown();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Customer/_files/customer.php
+     * @magentoApiDataFixture Magento/Customer/_files/customer_address.php
+     */
+    public function testGetAddress()
+    {
+        $fixtureAddressId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => "/V1/customers/addresses/{$fixtureAddressId}",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SOAP_SERVICE_NAME,
+                'serviceVersion' => self::SOAP_SERVICE_VERSION,
+                'operation' => self::SOAP_SERVICE_NAME . 'GetById',
+            ],
+        ];
+        $requestData = ['addressId' => $fixtureAddressId];
+        $addressData = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(
+            $this->getFirstFixtureAddressData(),
+            $addressData,
+            "Address data is invalid."
+        );
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Customer/_files/customer.php
+     * @magentoApiDataFixture Magento/Customer/_files/customer_address.php
+     */
+    public function testDeleteAddress()
+    {
+        $fixtureAddressId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => "/V1/addresses/{$fixtureAddressId}",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SOAP_SERVICE_NAME,
+                'serviceVersion' => self::SOAP_SERVICE_VERSION,
+                'operation' => self::SOAP_SERVICE_NAME . 'DeleteById',
+            ],
+        ];
+        $requestData = ['addressId' => $fixtureAddressId];
+        $response = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertTrue($response, 'Expected response should be true.');
+
+        $this->setExpectedException('Magento\Framework\Exception\NoSuchEntityException', 'No such entity with addressId = 1');
+        $this->addressRepository->getById($fixtureAddressId);
+    }
+
+    /**
+     * Retrieve data of the first fixture address.
+     *
+     * @return array
+     */
+    protected function getFirstFixtureAddressData()
+    {
+        return [
+            'firstname' => 'John',
+            'lastname' => 'Smith',
+            'city' => 'CityM',
+            'country_id' => 'US',
+            'company' => 'CompanyName',
+            'postcode' => '75477',
+            'telephone' => '3468676',
+            'street' => ['Green str, 67'],
+            'id' => 1,
+            'default_billing' => true,
+            'default_shipping' => true,
+            'customer_id' => '1',
+            'region' => ['region' => 'Alabama', 'region_id' => 1, 'region_code' => 'AL'],
+        ];
+    }
+
+    /**
+     * Retrieve data of the second fixture address.
+     *
+     * @return array
+     */
+    protected function getSecondFixtureAddressData()
+    {
+        return [
+            'firstname' => 'John',
+            'lastname' => 'Smith',
+            'city' => 'CityX',
+            'country_id' => 'US',
+            'postcode' => '47676',
+            'telephone' => '3234676',
+            'street' => ['Black str, 48'],
+            'id' => 2,
+            'default_billing' => false,
+            'default_shipping' => false,
+            'customer_id' => '1',
+            'region' => ['region' => 'Alabama', 'region_id' => 1, 'region_code' => 'AL'],
+        ];
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerMetadataTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerMetadataTest.php
new file mode 100644
index 00000000000..bba031a61cc
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerMetadataTest.php
@@ -0,0 +1,321 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Customer\Api;
+
+use Magento\Customer\Api\Data\CustomerInterface as Customer;
+use Magento\Customer\Model\Data\AttributeMetadata;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+
+/**
+ * Class CustomerMetadataTest
+ */
+class CustomerMetadataTest extends WebapiAbstract
+{
+    const SERVICE_NAME = "customerCustomerMetadataV1";
+    const SERVICE_VERSION = "V1";
+    const RESOURCE_PATH = "/V1/attributeMetadata/customer";
+
+    /**
+     * Test retrieval of attribute metadata for the customer entity type.
+     *
+     * @param string $attributeCode The attribute code of the requested metadata.
+     * @param array $expectedMetadata Expected entity metadata for the attribute code.
+     * @dataProvider getAttributeMetadataDataProvider
+     */
+    public function testGetAttributeMetadata($attributeCode, $expectedMetadata)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/attribute/$attributeCode",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetAttributeMetadata',
+            ],
+        ];
+
+        $requestData = [
+            'attributeCode' => $attributeCode,
+        ];
+
+        $attributeMetadata = $this->_webapiCall($serviceInfo, $requestData);
+
+        $validationResult = $this->checkValidationRules($expectedMetadata, $attributeMetadata);
+        list($expectedMetadata, $attributeMetadata) = $validationResult;
+        $this->assertEquals($expectedMetadata, $attributeMetadata);
+    }
+
+    /**
+     * Data provider for testGetAttributeMetadata.
+     *
+     * @return array
+     */
+    public function getAttributeMetadataDataProvider()
+    {
+        return [
+            Customer::FIRSTNAME => [
+                Customer::FIRSTNAME,
+                [
+                    AttributeMetadata::ATTRIBUTE_CODE   => 'firstname',
+                    AttributeMetadata::FRONTEND_INPUT   => 'text',
+                    AttributeMetadata::INPUT_FILTER     => '',
+                    AttributeMetadata::STORE_LABEL      => 'First Name',
+                    AttributeMetadata::VALIDATION_RULES => [
+                        ['name' => 'min_text_length', 'value' => 1],
+                        ['name' => 'max_text_length', 'value' => 255],
+                    ],
+                    AttributeMetadata::VISIBLE          => true,
+                    AttributeMetadata::REQUIRED         => true,
+                    AttributeMetadata::MULTILINE_COUNT  => 0,
+                    AttributeMetadata::DATA_MODEL       => '',
+                    AttributeMetadata::OPTIONS          => [],
+                    AttributeMetadata::FRONTEND_CLASS   => ' required-entry',
+                    AttributeMetadata::FRONTEND_LABEL   => 'First Name',
+                    AttributeMetadata::NOTE             => '',
+                    AttributeMetadata::SYSTEM           => true,
+                    AttributeMetadata::USER_DEFINED     => false,
+                    AttributeMetadata::BACKEND_TYPE     => 'varchar',
+                    AttributeMetadata::SORT_ORDER       => 40
+                ],
+            ],
+            Customer::GENDER => [
+                Customer::GENDER,
+                [
+                    AttributeMetadata::ATTRIBUTE_CODE   => 'gender',
+                    AttributeMetadata::FRONTEND_INPUT   => 'select',
+                    AttributeMetadata::INPUT_FILTER     => '',
+                    AttributeMetadata::STORE_LABEL      => 'Gender',
+                    AttributeMetadata::VALIDATION_RULES => [],
+                    AttributeMetadata::VISIBLE          => false,
+                    AttributeMetadata::REQUIRED         => false,
+                    AttributeMetadata::MULTILINE_COUNT  => 0,
+                    AttributeMetadata::DATA_MODEL       => '',
+                    AttributeMetadata::OPTIONS          => [
+                        ['label' => '', 'value' => ''],
+                        ['label' => 'Male', 'value' => '1'],
+                        ['label' => 'Female', 'value' => '2'],
+                    ],
+                    AttributeMetadata::FRONTEND_CLASS   => '',
+                    AttributeMetadata::FRONTEND_LABEL   => 'Gender',
+                    AttributeMetadata::NOTE             => '',
+                    AttributeMetadata::SYSTEM           => false,
+                    AttributeMetadata::USER_DEFINED     => false,
+                    AttributeMetadata::BACKEND_TYPE     => 'int',
+                    AttributeMetadata::SORT_ORDER       => 110
+                ],
+            ],
+            Customer::WEBSITE_ID => [
+                Customer::WEBSITE_ID,
+                [
+                    AttributeMetadata::ATTRIBUTE_CODE   => 'website_id',
+                    AttributeMetadata::FRONTEND_INPUT   => 'select',
+                    AttributeMetadata::INPUT_FILTER     => '',
+                    AttributeMetadata::STORE_LABEL      => 'Associate to Website',
+                    AttributeMetadata::VALIDATION_RULES => [],
+                    AttributeMetadata::VISIBLE          => true,
+                    AttributeMetadata::REQUIRED         => true,
+                    AttributeMetadata::MULTILINE_COUNT  => 0,
+                    AttributeMetadata::DATA_MODEL       => '',
+                    AttributeMetadata::OPTIONS          => [
+                        ['label' => 'Admin', 'value' => '0'],
+                        ['label' => 'Main Website', 'value' => '1'],
+                    ],
+                    AttributeMetadata::FRONTEND_CLASS   => ' required-entry',
+                    AttributeMetadata::FRONTEND_LABEL   => 'Associate to Website',
+                    AttributeMetadata::NOTE             => '',
+                    AttributeMetadata::SYSTEM           => true,
+                    AttributeMetadata::USER_DEFINED     => false,
+                    AttributeMetadata::BACKEND_TYPE     => 'static',
+                    AttributeMetadata::SORT_ORDER       => 10
+                ],
+            ]
+        ];
+    }
+
+    /**
+     * Test retrieval of all customer attribute metadata.
+     */
+    public function testGetAllAttributesMetadata()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetAllAttributesMetadata',
+            ],
+        ];
+
+        $attributeMetadata = $this->_webApiCall($serviceInfo);
+
+        $this->assertCount(23, $attributeMetadata);
+
+        $firstName = $this->getAttributeMetadataDataProvider()[Customer::FIRSTNAME][1];
+        $validationResult = $this->checkMultipleAttributesValidationRules($firstName, $attributeMetadata);
+        list($firstName, $attributeMetadata) = $validationResult;
+        $this->assertContains($firstName, $attributeMetadata);
+
+        $websiteId = $this->getAttributeMetadataDataProvider()[Customer::WEBSITE_ID][1];
+        $validationResult = $this->checkMultipleAttributesValidationRules($websiteId, $attributeMetadata);
+        list($websiteId, $attributeMetadata) = $validationResult;
+        $this->assertContains($websiteId, $attributeMetadata);
+    }
+
+    /**
+     * Test retrieval of custom customer attribute metadata.
+     */
+    public function testGetCustomAttributesMetadata()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/custom',
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetCustomAttributesMetadata',
+            ],
+        ];
+
+        $attributeMetadata = $this->_webApiCall($serviceInfo);
+
+        //Default custom attribute code 'disable_auto_group_change'
+        $this->assertCount(1, $attributeMetadata);
+        $this->assertEquals('disable_auto_group_change', $attributeMetadata[0]['attribute_code']);
+    }
+
+    /**
+     * Test retrieval of attributes
+     *
+     * @param string $formCode Form code
+     * @param array $expectedMetadata The expected attribute metadata
+     * @dataProvider getAttributesDataProvider
+     */
+    public function testGetAttributes($formCode, $expectedMetadata)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/form/$formCode",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetAttributes',
+            ],
+        ];
+
+        $requestData = [
+            'formCode' => $formCode,
+        ];
+
+        $attributeMetadataList = $this->_webApiCall($serviceInfo, $requestData);
+        foreach ($attributeMetadataList as $attributeMetadata) {
+            if (isset($attributeMetadata['attribute_code'])
+                && $attributeMetadata['attribute_code'] == $expectedMetadata['attribute_code']) {
+                $validationResult = $this->checkValidationRules($expectedMetadata, $attributeMetadata);
+                list($expectedMetadata, $attributeMetadata) = $validationResult;
+                $this->assertEquals($expectedMetadata, $attributeMetadata);
+                break;
+            }
+        }
+    }
+
+    /**
+     * Data provider for testGetAttributes.
+     *
+     * @return array
+     */
+    public function getAttributesDataProvider()
+    {
+        $attributeMetadata = $this->getAttributeMetadataDataProvider();
+        return [
+            [
+                'adminhtml_customer',
+                $attributeMetadata[Customer::FIRSTNAME][1],
+            ],
+            [
+                'adminhtml_customer',
+                $attributeMetadata[Customer::GENDER][1]
+            ]
+        ];
+    }
+
+    /**
+     * Checks that expected and actual attribute metadata validation rules are equal
+     * and removes the validation rules entry from expected and actual attribute metadata
+     *
+     * @param array $expectedResult
+     * @param array $actualResult
+     * @return array
+     */
+    public function checkValidationRules($expectedResult, $actualResult)
+    {
+        $expectedRules = [];
+        $actualRules   = [];
+
+        if (isset($expectedResult[AttributeMetadata::VALIDATION_RULES])) {
+            $expectedRules = $expectedResult[AttributeMetadata::VALIDATION_RULES];
+            unset($expectedResult[AttributeMetadata::VALIDATION_RULES]);
+        }
+        if (isset($actualResult[AttributeMetadata::VALIDATION_RULES])) {
+            $actualRules = $actualResult[AttributeMetadata::VALIDATION_RULES];
+            unset($actualResult[AttributeMetadata::VALIDATION_RULES]);
+        }
+
+        if (is_array($expectedRules) && is_array($actualRules)) {
+            foreach ($expectedRules as $expectedRule) {
+                if (isset($expectedRule['name']) && isset($expectedRule['value'])) {
+                    $found = false;
+                    foreach ($actualRules as $actualRule) {
+                        if (isset($actualRule['name']) && isset($actualRule['value'])) {
+                            if ($expectedRule['name'] == $actualRule['name']
+                                && $expectedRule['value'] == $actualRule['value']
+                            ) {
+                                $found = true;
+                                break;
+                            }
+                        }
+                    }
+                    $this->assertTrue($found);
+                }
+            }
+        }
+        return [$expectedResult, $actualResult];
+    }
+
+    /**
+     * Check specific attribute validation rules in set of multiple attributes
+     *
+     * @param array $expectedResult Set of expected attribute metadata
+     * @param array $actualResultSet Set of actual attribute metadata
+     * @return array
+     */
+    public function checkMultipleAttributesValidationRules($expectedResult, $actualResultSet)
+    {
+        if (is_array($expectedResult) && is_array($actualResultSet)) {
+            if (isset($expectedResult[AttributeMetadata::ATTRIBUTE_CODE])) {
+                foreach ($actualResultSet as $actualAttributeKey => $actualAttribute) {
+                    if (isset($actualAttribute[AttributeMetadata::ATTRIBUTE_CODE])
+                        && $expectedResult[AttributeMetadata::ATTRIBUTE_CODE]
+                        == $actualAttribute[AttributeMetadata::ATTRIBUTE_CODE]
+                    ) {
+                        $this->checkValidationRules($expectedResult, $actualAttribute);
+                        unset($actualResultSet[$actualAttributeKey][AttributeMetadata::VALIDATION_RULES]);
+                    }
+                }
+                unset($expectedResult[AttributeMetadata::VALIDATION_RULES]);
+            }
+        }
+        return [$expectedResult, $actualResultSet];
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerRepositoryTest.php
new file mode 100644
index 00000000000..db1b03f1f47
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerRepositoryTest.php
@@ -0,0 +1,659 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Customer\Api;
+
+use Magento\Customer\Api\Data\CustomerInterface as Customer;
+use Magento\Framework\Api\SearchCriteria;
+use Magento\Framework\Exception\InputException;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\Helper\Customer as CustomerHelper;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Exception as HTTPExceptionCodes;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+/**
+ * Test class for Magento\Customer\Api\CustomerRepositoryInterface
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class CustomerRepositoryTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+    const SERVICE_NAME = 'customerCustomerRepositoryV1';
+    const RESOURCE_PATH = '/V1/customers';
+
+    /**
+     * Sample values for testing
+     */
+    const ATTRIBUTE_CODE = 'attribute_code';
+    const ATTRIBUTE_VALUE = 'attribute_value';
+
+    /**
+     * @var CustomerRepositoryInterface
+     */
+    private $customerRepository;
+
+    /**
+     * @var \Magento\Customer\Api\Data\AddressDataBuilder
+     */
+    private $addressBuilder;
+
+    /**
+     * @var \Magento\Customer\Api\Data\CustomerDataBuilder
+     */
+    private $customerBuilder;
+
+    /**
+     * @var \Magento\Framework\Api\SearchCriteriaBuilder
+     */
+    private $searchCriteriaBuilder;
+
+    /**
+     * @var \Magento\Framework\Api\SortOrderBuilder
+     */
+    private $sortOrderBuilder;
+
+    /**
+     * @var \Magento\Framework\Api\Search\FilterGroupBuilder
+     */
+    private $filterGroupBuilder;
+
+    /**
+     * @var \Magento\Customer\Model\CustomerRegistry
+     */
+    private $customerRegistry;
+
+    /**
+     * @var CustomerHelper
+     */
+    private $customerHelper;
+
+    /**
+     * @var array
+     */
+    private $currentCustomerId;
+
+    /**
+     * @var \Magento\Framework\Reflection\DataObjectProcessor
+     */
+    private $dataObjectProcessor;
+
+    /**
+     * Execute per test initialization.
+     */
+    public function setUp()
+    {
+        $this->customerRegistry = Bootstrap::getObjectManager()->get(
+            'Magento\Customer\Model\CustomerRegistry'
+        );
+
+        $this->customerRepository = Bootstrap::getObjectManager()->get(
+            'Magento\Customer\Api\CustomerRepositoryInterface',
+            ['customerRegistry' => $this->customerRegistry]
+        );
+        $this->addressBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\Customer\Api\Data\AddressDataBuilder'
+        );
+        $this->customerBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\Customer\Api\Data\CustomerDataBuilder'
+        );
+        $this->searchCriteriaBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\Framework\Api\SearchCriteriaBuilder'
+        );
+        $this->sortOrderBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\Framework\Api\SortOrderBuilder'
+        );
+        $this->filterGroupBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\Framework\Api\Search\FilterGroupBuilder'
+        );
+        $this->customerHelper = new CustomerHelper();
+
+        $this->dataObjectProcessor = Bootstrap::getObjectManager()->create(
+            'Magento\Framework\Reflection\DataObjectProcessor'
+        );
+    }
+
+    public function tearDown()
+    {
+        if (!empty($this->currentCustomerId)) {
+            foreach ($this->currentCustomerId as $customerId) {
+                $serviceInfo = [
+                    'rest' => [
+                        'resourcePath' => self::RESOURCE_PATH . '/' . $customerId,
+                        'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+                    ],
+                    'soap' => [
+                        'service' => self::SERVICE_NAME,
+                        'serviceVersion' => self::SERVICE_VERSION,
+                        'operation' => self::SERVICE_NAME . 'DeleteById',
+                    ],
+                ];
+
+                $response = $this->_webApiCall($serviceInfo, ['customerId' => $customerId]);
+
+                $this->assertTrue($response);
+            }
+        }
+        unset($this->customerRepository);
+    }
+
+    public function testDeleteCustomer()
+    {
+        $customerData = $this->_createCustomer();
+        $this->currentCustomerId = [];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $customerData[Customer::ID],
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'DeleteById',
+            ],
+        ];
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            $response = $this->_webApiCall($serviceInfo, ['customerId' => $customerData['id']]);
+        } else {
+            $response = $this->_webApiCall($serviceInfo);
+        }
+
+        $this->assertTrue($response);
+
+        //Verify if the customer is deleted
+        $this->setExpectedException(
+            'Magento\Framework\Exception\NoSuchEntityException',
+            sprintf("No such entity with customerId = %s", $customerData[Customer::ID])
+        );
+        $this->_getCustomerData($customerData[Customer::ID]);
+    }
+
+    public function testDeleteCustomerInvalidCustomerId()
+    {
+        $invalidId = -1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $invalidId,
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'DeleteById',
+            ],
+        ];
+
+        $expectedMessage = 'No such entity with %fieldName = %fieldValue';
+
+        try {
+            $this->_webApiCall($serviceInfo, ['customerId' => $invalidId]);
+
+            $this->fail("Expected exception");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "SoapFault does not contain expected message."
+            );
+        } catch (\Exception $e) {
+            $errorObj = $this->processRestExceptionResult($e);
+            $this->assertEquals($expectedMessage, $errorObj['message']);
+            $this->assertEquals(['fieldName' => 'customerId', 'fieldValue' => $invalidId], $errorObj['parameters']);
+            $this->assertEquals(HTTPExceptionCodes::HTTP_NOT_FOUND, $e->getCode());
+        }
+    }
+
+    public function testUpdateCustomer()
+    {
+        $customerData = $this->_createCustomer();
+        $existingCustomerDataObject = $this->_getCustomerData($customerData[Customer::ID]);
+        $lastName = $existingCustomerDataObject->getLastname();
+        $customerData[Customer::LASTNAME] = $lastName . 'Updated';
+        $newCustomerDataObject = $this->customerBuilder->populateWithArray($customerData)->create();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/{$customerData[Customer::ID]}",
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $newCustomerDataObject = $this->dataObjectProcessor->buildOutputDataArray(
+            $newCustomerDataObject,
+            'Magento\Customer\Api\Data\CustomerInterface'
+        );
+        $requestData = ['customer' => $newCustomerDataObject];
+        $response = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertTrue(!is_null($response));
+
+        //Verify if the customer is updated
+        $existingCustomerDataObject = $this->_getCustomerData($customerData[Customer::ID]);
+        $this->assertEquals($lastName . "Updated", $existingCustomerDataObject->getLastname());
+    }
+
+    /**
+     * Verify expected behavior when the website id is not set
+     */
+    public function testUpdateCustomerNoWebsiteId()
+    {
+        $customerData = $this->customerHelper->createSampleCustomer();
+        $existingCustomerDataObject = $this->_getCustomerData($customerData[Customer::ID]);
+        $lastName = $existingCustomerDataObject->getLastname();
+        $customerData[Customer::LASTNAME] = $lastName . 'Updated';
+        $newCustomerDataObject = $this->customerBuilder->populateWithArray($customerData)->create();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/{$customerData[Customer::ID]}",
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $newCustomerDataObject = $this->dataObjectProcessor->buildOutputDataArray(
+            $newCustomerDataObject,
+            'Magento\Customer\Api\Data\CustomerInterface'
+        );
+        unset($newCustomerDataObject['website_id']);
+        $requestData = ['customer' => $newCustomerDataObject];
+
+        $expectedMessage = '"Associate to Website" is a required value.';
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+            $this->fail("Expected exception.");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "SoapFault does not contain expected message."
+            );
+        } catch (\Exception $e) {
+            $errorObj =  $this->customerHelper->processRestExceptionResult($e);
+            $this->assertEquals($expectedMessage, $errorObj['message'], 'Invalid message: "' . $e->getMessage() . '"');
+            $this->assertEquals(HTTPExceptionCodes::HTTP_BAD_REQUEST, $e->getCode());
+        }
+    }
+
+    public function testUpdateCustomerException()
+    {
+        $customerData = $this->_createCustomer();
+        $existingCustomerDataObject = $this->_getCustomerData($customerData[Customer::ID]);
+        $lastName = $existingCustomerDataObject->getLastname();
+
+        //Set non-existent id = -1
+        $customerData[Customer::LASTNAME] = $lastName . 'Updated';
+        $customerData[Customer::ID] = -1;
+
+        $newCustomerDataObject = $this->customerBuilder->populateWithArray($customerData)->create();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/-1",
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $newCustomerDataObject = $this->dataObjectProcessor->buildOutputDataArray(
+            $newCustomerDataObject,
+            'Magento\Customer\Api\Data\CustomerInterface'
+        );
+        $requestData = ['customer' => $newCustomerDataObject];
+
+        $expectedMessage = 'No such entity with %fieldName = %fieldValue';
+
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+            $this->fail("Expected exception.");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "SoapFault does not contain expected message."
+            );
+        } catch (\Exception $e) {
+            $errorObj = $this->processRestExceptionResult($e);
+            $this->assertEquals($expectedMessage, $errorObj['message']);
+            $this->assertEquals(['fieldName' => 'customerId', 'fieldValue' => -1], $errorObj['parameters']);
+            $this->assertEquals(HTTPExceptionCodes::HTTP_NOT_FOUND, $e->getCode());
+        }
+    }
+
+    /**
+     * Test with a single filter
+     */
+    public function testSearchCustomers()
+    {
+        $builder = Bootstrap::getObjectManager()->create('Magento\Framework\Api\FilterBuilder');
+        $customerData = $this->_createCustomer();
+        $filter = $builder
+            ->setField(Customer::EMAIL)
+            ->setValue($customerData[Customer::EMAIL])
+            ->create();
+        $this->searchCriteriaBuilder->addFilter([$filter]);
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/search',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'getList',
+            ],
+        ];
+        $searchData = $this->dataObjectProcessor->buildOutputDataArray(
+            $this->searchCriteriaBuilder->create(),
+            'Magento\Framework\Api\SearchCriteriaInterface'
+        );
+        $requestData = ['searchCriteria' => $searchData];
+        $searchResults = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(1, $searchResults['total_count']);
+        $this->assertEquals($customerData[Customer::ID], $searchResults['items'][0][Customer::ID]);
+    }
+
+    /**
+     * Test with a single filter using GET
+     */
+    public function testSearchCustomersUsingGET()
+    {
+        $this->_markTestAsRestOnly('SOAP test is covered in testSearchCustomers');
+        $builder = Bootstrap::getObjectManager()->create('Magento\Framework\Api\FilterBuilder');
+        $customerData = $this->_createCustomer();
+        $filter = $builder
+            ->setField(Customer::EMAIL)
+            ->setValue($customerData[Customer::EMAIL])
+            ->create();
+        $this->searchCriteriaBuilder->addFilter([$filter]);
+
+        $searchData = $this->searchCriteriaBuilder->create()->__toArray();
+        $requestData = ['searchCriteria' => $searchData];
+        $searchQueryString = http_build_query($requestData);
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/search?' . $searchQueryString,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+        ];
+        $searchResults = $this->_webApiCall($serviceInfo);
+        $this->assertEquals(1, $searchResults['total_count']);
+        $this->assertEquals($customerData[Customer::ID], $searchResults['items'][0][Customer::ID]);
+    }
+
+    /**
+     * Test with empty GET based filter
+     */
+    public function testSearchCustomersUsingGETEmptyFilter()
+    {
+        $this->_markTestAsRestOnly('Soap clients explicitly check for required fields based on WSDL.');
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/search',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+        ];
+        try {
+            $this->_webApiCall($serviceInfo);
+        } catch (\Exception $e) {
+            $this->assertEquals(HTTPExceptionCodes::HTTP_BAD_REQUEST, $e->getCode());
+            $exceptionData = $this->processRestExceptionResult($e);
+            $expectedExceptionData = [
+                'message' => InputException::REQUIRED_FIELD,
+                'parameters' => [
+                    'fieldName' => 'searchCriteria'
+                ],
+            ];
+            $this->assertEquals($expectedExceptionData, $exceptionData);
+        }
+    }
+
+    /**
+     * Test using multiple filters
+     */
+    public function testSearchCustomersMultipleFiltersWithSort()
+    {
+        $builder = Bootstrap::getObjectManager()->create('Magento\Framework\Api\FilterBuilder');
+        $customerData1 = $this->_createCustomer();
+        $customerData2 = $this->_createCustomer();
+        $filter1 = $builder->setField(Customer::EMAIL)
+            ->setValue($customerData1[Customer::EMAIL])
+            ->create();
+        $filter2 = $builder->setField(Customer::EMAIL)
+            ->setValue($customerData2[Customer::EMAIL])
+            ->create();
+        $filter3 = $builder->setField(Customer::LASTNAME)
+            ->setValue($customerData1[Customer::LASTNAME])
+            ->create();
+        $this->searchCriteriaBuilder->addFilter([$filter1, $filter2]);
+        $this->searchCriteriaBuilder->addFilter([$filter3]);
+
+        /**@var \Magento\Framework\Api\SortOrderBuilder $sortOrderBuilder */
+        $sortOrderBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\Framework\Api\SortOrderBuilder'
+        );
+        /** @var \Magento\Framework\Api\SortOrder $sortOrder */
+        $sortOrder = $sortOrderBuilder->setField(Customer::EMAIL)->setDirection(SearchCriteria::SORT_ASC)->create();
+        $this->searchCriteriaBuilder->setSortOrders([$sortOrder]);
+
+        $searchCriteria = $this->searchCriteriaBuilder->create();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/search',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'getList',
+            ],
+        ];
+        $searchData = $searchCriteria->__toArray();
+        $requestData = ['searchCriteria' => $searchData];
+        $searchResults = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(2, $searchResults['total_count']);
+        $this->assertEquals($customerData1[Customer::ID], $searchResults['items'][0][Customer::ID]);
+        $this->assertEquals($customerData2[Customer::ID], $searchResults['items'][1][Customer::ID]);
+    }
+
+    /**
+     * Test using multiple filters using GET
+     */
+    public function testSearchCustomersMultipleFiltersWithSortUsingGET()
+    {
+        $this->_markTestAsRestOnly('SOAP test is covered in testSearchCustomers');
+        $builder = Bootstrap::getObjectManager()->create('Magento\Framework\Api\FilterBuilder');
+        $customerData1 = $this->_createCustomer();
+        $customerData2 = $this->_createCustomer();
+        $filter1 = $builder->setField(Customer::EMAIL)
+            ->setValue($customerData1[Customer::EMAIL])
+            ->create();
+        $filter2 = $builder->setField(Customer::EMAIL)
+            ->setValue($customerData2[Customer::EMAIL])
+            ->create();
+        $filter3 = $builder->setField(Customer::LASTNAME)
+            ->setValue($customerData1[Customer::LASTNAME])
+            ->create();
+        $this->searchCriteriaBuilder->addFilter([$filter1, $filter2]);
+        $this->searchCriteriaBuilder->addFilter([$filter3]);
+        $this->searchCriteriaBuilder->setSortOrders([Customer::EMAIL => SearchCriteria::SORT_ASC]);
+        $searchCriteria = $this->searchCriteriaBuilder->create();
+        $searchData = $searchCriteria->__toArray();
+        $requestData = ['searchCriteria' => $searchData];
+        $searchQueryString = http_build_query($requestData);
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/search?' . $searchQueryString,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+        ];
+        $searchResults = $this->_webApiCall($serviceInfo);
+        $this->assertEquals(2, $searchResults['total_count']);
+        $this->assertEquals($customerData1[Customer::ID], $searchResults['items'][0][Customer::ID]);
+        $this->assertEquals($customerData2[Customer::ID], $searchResults['items'][1][Customer::ID]);
+    }
+
+    /**
+     * Test and verify multiple filters using And-ed non-existent filter value
+     */
+    public function testSearchCustomersNonExistentMultipleFilters()
+    {
+        $builder = Bootstrap::getObjectManager()->create('Magento\Framework\Api\FilterBuilder');
+        $customerData1 = $this->_createCustomer();
+        $customerData2 = $this->_createCustomer();
+        $filter1 = $filter1 = $builder->setField(Customer::EMAIL)
+            ->setValue($customerData1[Customer::EMAIL])
+            ->create();
+        $filter2 = $builder->setField(Customer::EMAIL)
+            ->setValue($customerData2[Customer::EMAIL])
+            ->create();
+        $filter3 = $builder->setField(Customer::LASTNAME)
+            ->setValue('INVALID')
+            ->create();
+        $this->searchCriteriaBuilder->addFilter([$filter1, $filter2]);
+        $this->searchCriteriaBuilder->addFilter([$filter3]);
+        $searchCriteria = $this->searchCriteriaBuilder->create();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/search',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'getList',
+            ],
+        ];
+        $searchData = $searchCriteria->__toArray();
+        $requestData = ['searchCriteria' => $searchData];
+        $searchResults = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(0, $searchResults['total_count'], 'No results expected for non-existent email.');
+    }
+
+    /**
+     * Test and verify multiple filters using And-ed non-existent filter value using GET
+     */
+    public function testSearchCustomersNonExistentMultipleFiltersGET()
+    {
+        $this->_markTestAsRestOnly('SOAP test is covered in testSearchCustomers');
+        $builder = Bootstrap::getObjectManager()->create('Magento\Framework\Api\FilterBuilder');
+        $customerData1 = $this->_createCustomer();
+        $customerData2 = $this->_createCustomer();
+        $filter1 = $filter1 = $builder->setField(Customer::EMAIL)
+            ->setValue($customerData1[Customer::EMAIL])
+            ->create();
+        $filter2 = $builder->setField(Customer::EMAIL)
+            ->setValue($customerData2[Customer::EMAIL])
+            ->create();
+        $filter3 = $builder->setField(Customer::LASTNAME)
+            ->setValue('INVALID')
+            ->create();
+        $this->searchCriteriaBuilder->addFilter([$filter1, $filter2]);
+        $this->searchCriteriaBuilder->addFilter([$filter3]);
+        $searchCriteria = $this->searchCriteriaBuilder->create();
+        $searchData = $searchCriteria->__toArray();
+        $requestData = ['searchCriteria' => $searchData];
+        $searchQueryString = http_build_query($requestData);
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/search?' . $searchQueryString,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+        ];
+        $searchResults = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(0, $searchResults['total_count'], 'No results expected for non-existent email.');
+    }
+
+    /**
+     * Test using multiple filters
+     */
+    public function testSearchCustomersMultipleFilterGroups()
+    {
+        $customerData1 = $this->_createCustomer();
+
+        /** @var \Magento\Framework\Api\FilterBuilder $builder */
+        $builder = Bootstrap::getObjectManager()->create('Magento\Framework\Api\FilterBuilder');
+        $filter1 = $builder->setField(Customer::EMAIL)
+            ->setValue($customerData1[Customer::EMAIL])
+            ->create();
+        $filter2 = $builder->setField(Customer::MIDDLENAME)
+            ->setValue($customerData1[Customer::MIDDLENAME])
+            ->create();
+        $filter3 = $builder->setField(Customer::MIDDLENAME)
+            ->setValue('invalid')
+            ->create();
+        $filter4 = $builder->setField(Customer::LASTNAME)
+            ->setValue($customerData1[Customer::LASTNAME])
+            ->create();
+
+        $this->searchCriteriaBuilder->addFilter([$filter1]);
+        $this->searchCriteriaBuilder->addFilter([$filter2, $filter3]);
+        $this->searchCriteriaBuilder->addFilter([$filter4]);
+        $searchCriteria = $this->searchCriteriaBuilder->setCurrentPage(1)->setPageSize(10)->create();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/search',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'getList',
+            ],
+        ];
+        $searchData = $searchCriteria->__toArray();
+        $requestData = ['searchCriteria' => $searchData];
+        $searchResults = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(1, $searchResults['total_count']);
+        $this->assertEquals($customerData1[Customer::ID], $searchResults['items'][0][Customer::ID]);
+
+        // Add an invalid And-ed data with multiple groups to yield no result
+        $filter4 = $builder->setField(Customer::LASTNAME)
+            ->setValue('invalid')
+            ->create();
+
+        $this->searchCriteriaBuilder->addFilter([$filter1]);
+        $this->searchCriteriaBuilder->addFilter([$filter2, $filter3]);
+        $this->searchCriteriaBuilder->addFilter([$filter4]);
+        $searchCriteria = $this->searchCriteriaBuilder->create();
+        $searchData = $searchCriteria->__toArray();
+        $requestData = ['searchCriteria' => $searchData];
+        $searchResults = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(0, $searchResults['total_count']);
+    }
+
+    /**
+     * Retrieve customer data by Id
+     *
+     * @param int $customerId
+     * @return \Magento\Customer\Api\Data\CustomerInterface
+     */
+    protected function _getCustomerData($customerId)
+    {
+        $customerData =  $this->customerRepository->getById($customerId);
+        $this->customerRegistry->remove($customerId);
+        return $customerData;
+    }
+
+    /**
+     * @return array|bool|float|int|string
+     */
+    protected function _createCustomer()
+    {
+        $customerData = $this->customerHelper->createSampleCustomer();
+        $this->currentCustomerId[] = $customerData['id'];
+        return $customerData;
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/GroupManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/GroupManagementTest.php
new file mode 100644
index 00000000000..70c6294ebb9
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/GroupManagementTest.php
@@ -0,0 +1,228 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Customer\Api;
+
+use Magento\Customer\Model\Data\Group as CustomerGroup;
+use Magento\Customer\Model\GroupRegistry;
+use Magento\Customer\Model\Resource\GroupRepository;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+
+/**
+ * Class GroupManagementTest
+ */
+class GroupManagementTest extends WebapiAbstract
+{
+    const SERVICE_NAME = "customerGroupManagementV1";
+    const SERVICE_VERSION = "V1";
+    const RESOURCE_PATH = "/V1/customerGroups";
+
+    /**
+     * @var GroupRegistry
+     */
+    private $groupRegistry;
+
+    /**
+     * @var GroupRepository
+     */
+    private $groupRepository;
+
+    /**
+     * Execute per test initialization.
+     */
+    public function setUp()
+    {
+        $objectManager = Bootstrap::getObjectManager();
+        $this->groupRegistry = $objectManager->get('Magento\Customer\Model\GroupRegistry');
+        $this->groupRepository = $objectManager->get('Magento\Customer\Model\Resource\GroupRepository');
+    }
+
+    /**
+     * Verify the retrieval of the default group for storeId equal to 1.
+     *
+     * @param int $storeId The store Id
+     * @param array $defaultGroupData The default group data for the store with the specified Id.
+     *
+     * @dataProvider getDefaultGroupDataProvider
+     */
+    public function testGetDefaultGroup($storeId, $defaultGroupData)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/default/$storeId",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'customerGroupManagementV1GetDefaultGroup',
+            ],
+        ];
+        $requestData = ['storeId' => $storeId];
+        $groupData = $this->_webApiCall($serviceInfo, $requestData);
+
+        $this->assertEquals($defaultGroupData, $groupData, "The default group does not match.");
+    }
+
+    /**
+     * The testGetDefaultGroup data provider.
+     *
+     * @return array
+     */
+    public function getDefaultGroupDataProvider()
+    {
+        return [
+            'admin' => [
+                0,
+                [
+                    CustomerGroup::ID => 1,
+                    CustomerGroup::CODE => 'General',
+                    CustomerGroup::TAX_CLASS_ID => 3,
+                    CustomerGroup::TAX_CLASS_NAME => 'Retail Customer'
+                ],
+            ],
+            'base' => [
+                1,
+                [
+                    CustomerGroup::ID => 1,
+                    CustomerGroup::CODE => 'General',
+                    CustomerGroup::TAX_CLASS_ID => 3,
+                    CustomerGroup::TAX_CLASS_NAME => 'Retail Customer'
+                ],
+            ]
+        ];
+    }
+
+    /**
+     * Verify the retrieval of a non-existent storeId will return an expected fault.
+     */
+    public function testGetDefaultGroupNonExistentStore()
+    {
+        /* Store id should not exist */
+        $nonExistentStoreId = 9876;
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/default/$nonExistentStoreId",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'customerGroupManagementV1GetDefaultGroup',
+            ],
+        ];
+        $requestData = ['storeId' => $nonExistentStoreId];
+        $expectedMessage = 'No such entity with %fieldName = %fieldValue';
+
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+            $this->fail("Expected exception");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "SoapFault does not contain expected message."
+            );
+        } catch (\Exception $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "Exception does not contain expected message."
+            );
+            $this->assertContains((string)$nonExistentStoreId, $e->getMessage());
+        }
+    }
+
+    /**
+     * Verify that the group with the specified Id can or cannot be deleted.
+     *
+     * @param int $groupId The group Id
+     * @param bool $isDeleteable Whether the group can or cannot be deleted.
+     *
+     * @dataProvider isReadonlyDataProvider
+     */
+    public function testIsReadonly($groupId, $isDeleteable)
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/$groupId/permissions",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'customerGroupManagementV1IsReadonly',
+            ],
+        ];
+
+        $requestData = [CustomerGroup::ID => $groupId];
+
+        $isReadonly = $this->_webApiCall($serviceInfo, $requestData);
+
+        $failureMessage = $isDeleteable
+            ? 'The group should be deleteable.' : 'The group should not be deleteable.';
+        $this->assertEquals($isDeleteable, !$isReadonly, $failureMessage);
+    }
+
+    /**
+     * The testIsReadonly data provider.
+     *
+     * @return array
+     */
+    public function isReadonlyDataProvider()
+    {
+        return [
+            'NOT LOGGED IN' => [0, false],
+            'General' => [1, false],
+            'Wholesale' => [2, true],
+            'Retailer' => [3, true]
+        ];
+    }
+
+    /**
+     * Verify that the group with the specified Id can or cannot be deleted.
+     */
+    public function testIsReadonlyNoSuchGroup()
+    {
+        /* This group ID should not exist in the store. */
+        $groupId = 9999;
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/$groupId/permissions",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'customerGroupManagementV1IsReadonly',
+            ],
+        ];
+
+        $requestData = [CustomerGroup::ID => $groupId];
+
+        $expectedMessage = 'No such entity with %fieldName = %fieldValue';
+
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+            $this->fail("Expected exception.");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "SoapFault does not contain expected message."
+            );
+        } catch (\Exception $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "Exception does not contain expected message."
+            );
+            $this->assertContains((string)$groupId, $e->getMessage());
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/GroupRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/GroupRepositoryTest.php
new file mode 100644
index 00000000000..862349c1cbe
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/GroupRepositoryTest.php
@@ -0,0 +1,1007 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Customer\Api;
+
+use Magento\Customer\Model\Data\Group as CustomerGroup;
+use Magento\Customer\Model\GroupRegistry;
+use Magento\Customer\Model\Resource\GroupRepository;
+use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+
+/**
+ * Class GroupRepositoryTest
+ */
+class GroupRepositoryTest extends WebapiAbstract
+{
+    const SERVICE_NAME = "customerGroupRepositoryV1";
+    const SERVICE_VERSION = "V1";
+    const RESOURCE_PATH = "/V1/customerGroups";
+
+    /**
+     * @var GroupRegistry
+     */
+    private $groupRegistry;
+
+    /**
+     * @var GroupRepository
+     */
+    private $groupRepository;
+
+    /**
+     * Execute per test initialization.
+     */
+    public function setUp()
+    {
+        $objectManager = Bootstrap::getObjectManager();
+        $this->groupRegistry = $objectManager->get('Magento\Customer\Model\GroupRegistry');
+        $this->groupRepository = $objectManager->get('Magento\Customer\Model\Resource\GroupRepository');
+    }
+
+    /**
+     * Execute per test cleanup.
+     */
+    public function tearDown()
+    {
+    }
+
+    /**
+     * Cleaning up the extra groups that might have been created as part of the testing.
+     */
+    public static function tearDownAfterClass()
+    {
+    }
+
+    /**
+     * Verify the retrieval of a customer group by Id.
+     *
+     * @param array $testGroup The group data for the group being retrieved.
+     *
+     * @dataProvider getGroupDataProvider
+     */
+    public function testGetGroupById($testGroup)
+    {
+        $groupId = $testGroup[CustomerGroup::ID];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/$groupId",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'customerGroupRepositoryV1GetById',
+            ],
+        ];
+        $requestData = [CustomerGroup::ID => $groupId];
+        $groupData = $this->_webApiCall($serviceInfo, $requestData);
+
+        $this->assertEquals($testGroup, $groupData, "The group data does not match.");
+    }
+
+    /**
+     * The testGetGroup data provider.
+     *
+     * @return array
+     */
+    public function getGroupDataProvider()
+    {
+        return [
+            'NOT LOGGED IN' => [
+                [
+                    CustomerGroup::ID => 0,
+                    CustomerGroup::CODE => 'NOT LOGGED IN',
+                    CustomerGroup::TAX_CLASS_ID => 3,
+                    CustomerGroup::TAX_CLASS_NAME => 'Retail Customer',
+                ],
+            ],
+            'General' => [
+                [
+                    CustomerGroup::ID => 1,
+                    CustomerGroup::CODE => 'General',
+                    CustomerGroup::TAX_CLASS_ID => 3,
+                    CustomerGroup::TAX_CLASS_NAME => 'Retail Customer',
+                ],
+            ],
+            'Wholesale' => [
+                [
+                    CustomerGroup::ID => 2,
+                    CustomerGroup::CODE => 'Wholesale',
+                    CustomerGroup::TAX_CLASS_ID => 3,
+                    CustomerGroup::TAX_CLASS_NAME => 'Retail Customer',
+                ],
+            ],
+            'Retailer' => [
+                [
+                    CustomerGroup::ID => 3,
+                    CustomerGroup::CODE => 'Retailer',
+                    CustomerGroup::TAX_CLASS_ID => 3,
+                    CustomerGroup::TAX_CLASS_NAME => 'Retail Customer',
+                ],
+            ],
+        ];
+    }
+
+    /**
+     * Verify that creating a new group works via REST.
+     */
+    public function testCreateGroupRest()
+    {
+        $this->_markTestAsRestOnly();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+            ],
+        ];
+
+        $groupData = [
+            CustomerGroup::ID => null,
+            CustomerGroup::CODE => 'Create Group REST',
+            CustomerGroup::TAX_CLASS_ID => 3,
+        ];
+        $requestData = ['group' => $groupData];
+
+        $groupId = $this->_webApiCall($serviceInfo, $requestData)[CustomerGroup::ID];
+        $this->assertNotNull($groupId);
+
+        $newGroup = $this->groupRepository->getById($groupId);
+        $this->assertEquals($groupId, $newGroup->getId(), 'The group id does not match.');
+        $this->assertEquals($groupData[CustomerGroup::CODE], $newGroup->getCode(), 'The group code does not match.');
+        $this->assertEquals(
+            $groupData[CustomerGroup::TAX_CLASS_ID],
+            $newGroup->getTaxClassId(),
+            'The group tax class id does not match.'
+        );
+    }
+
+    /**
+     * Verify that creating a new group with a duplicate group name fails with an error via REST.
+     */
+    public function testCreateGroupDuplicateGroupRest()
+    {
+        $builder = Bootstrap::getObjectManager()->create('Magento\Customer\Api\Data\GroupDataBuilder');
+        $this->_markTestAsRestOnly();
+
+        $duplicateGroupCode = 'Duplicate Group Code REST';
+
+        $this->createGroup(
+            $builder->populateWithArray([
+                CustomerGroup::ID => null,
+                CustomerGroup::CODE => $duplicateGroupCode,
+                CustomerGroup::TAX_CLASS_ID => 3,
+            ])->create()
+        );
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+            ],
+        ];
+
+        $groupData = [
+            CustomerGroup::ID => null,
+            CustomerGroup::CODE => $duplicateGroupCode,
+            CustomerGroup::TAX_CLASS_ID => 3,
+        ];
+        $requestData = ['group' => $groupData];
+
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+            $this->fail("Expected exception");
+        } catch (\Exception $e) {
+            $errorData = json_decode($e->getMessage(), true);
+
+            $this->assertEquals(
+                'Customer Group already exists.',
+                $errorData['message']
+            );
+            $this->assertEquals(400, $e->getCode(), 'Invalid HTTP code');
+        }
+    }
+
+    /**
+     * Verify that creating a new group works via REST if tax class id is empty, defaults 3.
+     */
+    public function testCreateGroupDefaultTaxClassIdRest()
+    {
+        $this->_markTestAsRestOnly();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+            ],
+        ];
+
+        $groupData = [
+            CustomerGroup::ID => null,
+            CustomerGroup::CODE => 'Default Class Tax ID REST',
+            CustomerGroup::TAX_CLASS_ID => null,
+        ];
+        $requestData = ['group' => $groupData];
+
+        $groupId = $this->_webApiCall($serviceInfo, $requestData)[CustomerGroup::ID];
+        $this->assertNotNull($groupId);
+
+        $newGroup = $this->groupRepository->getById($groupId);
+        $this->assertEquals($groupId, $newGroup->getId(), 'The group id does not match.');
+        $this->assertEquals($groupData[CustomerGroup::CODE], $newGroup->getCode(), 'The group code does not match.');
+        $this->assertEquals(
+            GroupRepository::DEFAULT_TAX_CLASS_ID,
+            $newGroup->getTaxClassId(),
+            'The group tax class id does not match.'
+        );
+    }
+
+    /**
+     * Verify that creating a new group without a code fails with an error.
+     */
+    public function testCreateGroupNoCodeExpectExceptionRest()
+    {
+        $this->_markTestAsRestOnly();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+            ],
+        ];
+
+        $groupData = [
+            CustomerGroup::ID => null,
+            CustomerGroup::CODE => null,
+            CustomerGroup::TAX_CLASS_ID => null,
+        ];
+        $requestData = ['group' => $groupData];
+
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+            $this->fail("Expected exception");
+        } catch (\Exception $e) {
+            // @codingStandardsIgnoreStart
+            $this->assertContains(
+                '{"message":"%fieldName is a required field.","parameters":{"fieldName":"code"}',
+                $e->getMessage(),
+                "Exception does not contain expected message."
+            );
+            // @codingStandardsIgnoreEnd
+        }
+    }
+
+    /**
+     * Verify that creating a new group with an invalid tax class id fails with an error.
+     */
+    public function testCreateGroupInvalidTaxClassIdRest()
+    {
+        $this->_markTestAsRestOnly();
+
+        $invalidTaxClassId = 9999;
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+            ],
+        ];
+
+        $groupData = [
+            CustomerGroup::ID => null,
+            CustomerGroup::CODE => 'Invalid Tax Class Id Code',
+            CustomerGroup::TAX_CLASS_ID => $invalidTaxClassId,
+        ];
+        $requestData = ['group' => $groupData];
+
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+            $this->fail("Expected exception");
+        } catch (\Exception $e) {
+            // @codingStandardsIgnoreStart
+            $this->assertContains(
+                '{"message":"Invalid value of \"%value\" provided for the %fieldName field.","parameters":{"fieldName":"taxClassId","value":9999}',
+                $e->getMessage(),
+                "Exception does not contain expected message."
+            );
+            // codingStandardsIgnoreEnd
+        }
+    }
+
+    /**
+     * Verify that an attempt to update via POST is not allowed.
+     */
+    public function testCreateGroupWithIdRest()
+    {
+        $this->_markTestAsRestOnly();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+            ],
+        ];
+
+        $groupData = [
+            CustomerGroup::ID => 88,
+            CustomerGroup::CODE => 'Create Group With Id REST',
+            CustomerGroup::TAX_CLASS_ID => 3,
+        ];
+        $requestData = ['group' => $groupData];
+
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+            $this->fail('Expected exception');
+        } catch (\Exception $e) {
+            $this->assertContains(
+                '{"message":"No such entity with %fieldName = %fieldValue","parameters":{"fieldName":"id","fieldValue":88}',
+                $e->getMessage(),
+                "Exception does not contain expected message."
+            );
+        }
+    }
+
+    /**
+     * Verify that creating a new group fails via SOAP if there is an Id specified.
+     */
+    public function testCreateGroupWithIdSoap()
+    {
+        $this->_markTestAsSoapOnly();
+
+        $serviceInfo = [
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'customerGroupRepositoryV1Save',
+            ],
+        ];
+
+        $groupData = [
+            CustomerGroup::ID => 88,
+            CustomerGroup::CODE => 'Create Group with Id SOAP',
+            CustomerGroup::TAX_CLASS_ID => 3,
+        ];
+        $requestData = ['group' => $groupData];
+
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+            $this->fail("Expected exception");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                'No such entity with %fieldName = %fieldValue',
+                $e->getMessage(),
+                "SoapFault does not contain expected message."
+            );
+        }
+    }
+
+    /**
+     * Verify that updating an existing group works via REST.
+     */
+    public function testUpdateGroupRest()
+    {
+        $this->_markTestAsRestOnly();
+        $builder = Bootstrap::getObjectManager()->create('Magento\Customer\Api\Data\GroupDataBuilder');
+        $groupId = $this->createGroup(
+            $builder->populateWithArray([
+                CustomerGroup::ID => null,
+                CustomerGroup::CODE => 'New Group REST',
+                CustomerGroup::TAX_CLASS_ID => 3,
+            ])->create()
+        );
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/$groupId",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_PUT,
+            ],
+        ];
+
+        $groupData = [
+            CustomerGroup::ID => $groupId,
+            CustomerGroup::CODE => 'Updated Group REST',
+            CustomerGroup::TAX_CLASS_ID => 3,
+        ];
+        $requestData = ['group' => $groupData];
+
+        $this->assertEquals($groupId, $this->_webApiCall($serviceInfo, $requestData)[CustomerGroup::ID]);
+
+        $group = $this->groupRepository->getById($groupId);
+        $this->assertEquals($groupData[CustomerGroup::CODE], $group->getCode(), 'The group code did not change.');
+        $this->assertEquals(
+            $groupData[CustomerGroup::TAX_CLASS_ID],
+            $group->getTaxClassId(),
+            'The group tax class id did not change'
+        );
+    }
+
+    /**
+     * Verify that updating a non-existing group throws an exception.
+     */
+    public function testUpdateGroupNotExistingGroupRest()
+    {
+        $this->_markTestAsRestOnly();
+
+        $nonExistentGroupId = '9999';
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/$nonExistentGroupId",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_PUT,
+            ],
+        ];
+
+        $groupData = [
+            CustomerGroup::ID => $nonExistentGroupId,
+            CustomerGroup::CODE => 'Updated Group REST Does Not Exist',
+            CustomerGroup::TAX_CLASS_ID => 3,
+        ];
+        $requestData = ['group' => $groupData];
+
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+            $this->fail('Expected exception');
+        } catch (\Exception $e) {
+            $expectedMessage = '{"message":"No such entity with %fieldName = %fieldValue",'
+             . '"parameters":{"fieldName":"id","fieldValue":9999}';
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "Exception does not contain expected message."
+            );
+        }
+    }
+
+    /**
+     * Verify that creating a new group works via SOAP.
+     */
+    public function testCreateGroupSoap()
+    {
+        $this->_markTestAsSoapOnly();
+
+        $serviceInfo = [
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'customerGroupRepositoryV1Save',
+            ],
+        ];
+
+        $groupData = [
+            CustomerGroup::ID => null,
+            CustomerGroup::CODE => 'Create Group SOAP',
+            'taxClassId' => 3,
+        ];
+        $requestData = ['group' => $groupData];
+
+        $groupId = $this->_webApiCall($serviceInfo, $requestData)[CustomerGroup::ID];
+        $this->assertNotNull($groupId);
+
+        $newGroup = $this->groupRepository->getById($groupId);
+        $this->assertEquals($groupId, $newGroup->getId(), "The group id does not match.");
+        $this->assertEquals($groupData[CustomerGroup::CODE], $newGroup->getCode(), "The group code does not match.");
+        $this->assertEquals(
+            $groupData['taxClassId'],
+            $newGroup->getTaxClassId(),
+            "The group tax class id does not match."
+        );
+    }
+
+    /**
+     * Verify that creating a new group with a duplicate code fails with an error via SOAP.
+     */
+    public function testCreateGroupDuplicateGroupSoap()
+    {
+        $this->_markTestAsSoapOnly();
+        $builder = Bootstrap::getObjectManager()->create('Magento\Customer\Api\Data\GroupDataBuilder');
+        $duplicateGroupCode = 'Duplicate Group Code SOAP';
+
+        $this->createGroup(
+            $builder->populateWithArray([
+                CustomerGroup::ID => null,
+                CustomerGroup::CODE => $duplicateGroupCode,
+                CustomerGroup::TAX_CLASS_ID => 3,
+            ])->create()
+        );
+
+        $serviceInfo = [
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'customerGroupRepositoryV1Save',
+            ],
+        ];
+
+        $groupData = [
+            CustomerGroup::ID => null,
+            CustomerGroup::CODE => $duplicateGroupCode,
+            'taxClassId' => 3,
+        ];
+        $requestData = ['group' => $groupData];
+
+        $expectedMessage = 'Customer Group already exists.';
+
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+            $this->fail("Expected exception");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "Exception does not contain expected message."
+            );
+        }
+    }
+
+    /**
+     * Verify that creating a new group works via SOAP if tax class id is empty, defaults 3.
+     */
+    public function testCreateGroupDefaultTaxClassIdSoap()
+    {
+        $this->_markTestAsSoapOnly();
+
+        $serviceInfo = [
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'customerGroupRepositoryV1Save',
+            ],
+        ];
+
+        $groupData = [
+            CustomerGroup::ID => null,
+            CustomerGroup::CODE => 'Default Class Tax ID SOAP',
+            'taxClassId' => null,
+            'taxClassName' => null,
+        ];
+        $requestData = ['group' => $groupData];
+
+        $groupResponseData = $this->_webApiCall($serviceInfo, $requestData);
+        $groupId = $groupResponseData[CustomerGroup::ID];
+        $this->assertNotNull($groupId);
+
+        $newGroup = $this->groupRepository->getById($groupId);
+        $this->assertEquals($groupId, $newGroup->getId(), "The group id does not match.");
+        $this->assertEquals($groupData[CustomerGroup::CODE], $newGroup->getCode(), "The group code does not match.");
+        $this->assertEquals(
+            GroupRepository::DEFAULT_TAX_CLASS_ID,
+            $newGroup->getTaxClassId(),
+            "The group tax class id does not match."
+        );
+    }
+
+    /**
+     * Verify that creating a new group without a code fails with an error.
+     */
+    public function testCreateGroupNoCodeExpectExceptionSoap()
+    {
+        $this->_markTestAsSoapOnly();
+
+        $serviceInfo = [
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'customerGroupRepositoryV1Save',
+            ],
+        ];
+
+        $groupData = [
+            CustomerGroup::ID => null,
+            CustomerGroup::CODE => null,
+            'taxClassId' => null,
+        ];
+        $requestData = ['group' => $groupData];
+
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+            $this->fail("Expected exception");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                '%fieldName is a required field.',
+                $e->getMessage(),
+                "SoapFault does not contain expected message."
+            );
+        }
+    }
+
+    /**
+     * Verify that creating a new group fails via SOAP if tax class id is invalid.
+     */
+    public function testCreateGroupInvalidTaxClassIdSoap()
+    {
+        $this->_markTestAsSoapOnly();
+
+        $invalidTaxClassId = 9999;
+
+        $serviceInfo = [
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'customerGroupRepositoryV1Save',
+            ],
+        ];
+
+        $groupData = [
+            CustomerGroup::ID => null,
+            CustomerGroup::CODE => 'Invalid Class Tax ID SOAP',
+            'taxClassId' => $invalidTaxClassId,
+        ];
+        $requestData = ['group' => $groupData];
+
+        $expectedMessage = 'Invalid value of "%value" provided for the %fieldName field.';
+
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+            $this->fail("Expected exception");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "SoapFault does not contain expected message."
+            );
+        }
+    }
+
+    /**
+     * Verify that updating an existing group works via SOAP.
+     */
+    public function testUpdateGroupSoap()
+    {
+        $this->_markTestAsSoapOnly();
+        $builder = Bootstrap::getObjectManager()->create('Magento\Customer\Api\Data\GroupDataBuilder');
+        $groupId = $this->createGroup(
+            $builder->populateWithArray([
+                    CustomerGroup::ID => null,
+                    CustomerGroup::CODE => 'New Group SOAP',
+                    CustomerGroup::TAX_CLASS_ID => 3,
+                ])->create()
+        );
+
+        $serviceInfo = [
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'customerGroupRepositoryV1Save',
+            ],
+        ];
+
+        $groupData = [
+            CustomerGroup::ID => $groupId,
+            CustomerGroup::CODE => 'Updated Group SOAP',
+            'taxClassId' => 3,
+        ];
+        $this->_webApiCall($serviceInfo, ['group' => $groupData]);
+
+        $group = $this->groupRepository->getById($groupId);
+        $this->assertEquals($groupData[CustomerGroup::CODE], $group->getCode(), 'The group code did not change.');
+        $this->assertEquals(
+            $groupData['taxClassId'],
+            $group->getTaxClassId(),
+            'The group tax class id did not change'
+        );
+    }
+
+    /**
+     * Verify that updating a non-existing group throws an exception via SOAP.
+     */
+    public function testUpdateGroupNotExistingGroupSoap()
+    {
+        $this->_markTestAsSoapOnly();
+
+        $nonExistentGroupId = '9999';
+
+        $serviceInfo = [
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'customerGroupRepositoryV1Save',
+            ],
+        ];
+
+        $groupData = [
+            CustomerGroup::ID => $nonExistentGroupId,
+            CustomerGroup::CODE => 'Updated Non-Existent Group SOAP',
+            'taxClassId' => 3,
+        ];
+        $requestData = ['group' => $groupData];
+
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+        } catch (\Exception $e) {
+            $expectedMessage = 'No such entity with %fieldName = %fieldValue';
+
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "Exception does not contain expected message."
+            );
+        }
+    }
+
+    /**
+     * Verify that deleting an existing group works.
+     */
+    public function testDeleteGroupExists()
+    {
+        $builder = Bootstrap::getObjectManager()->create('Magento\Customer\Api\Data\GroupDataBuilder');
+        $groupId = $this->createGroup(
+            $builder->populateWithArray([
+                CustomerGroup::ID => null,
+                CustomerGroup::CODE => 'Delete Group',
+                CustomerGroup::TAX_CLASS_ID => 3,
+            ])->create()
+        );
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/$groupId",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'customerGroupRepositoryV1DeleteById',
+            ],
+        ];
+
+        $requestData = [CustomerGroup::ID => $groupId];
+        $response = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertTrue($response, 'Expected response should be true.');
+
+        try {
+            $this->groupRepository->getById($groupId);
+            $this->fail('An expected NoSuchEntityException was not thrown.');
+        } catch (NoSuchEntityException $e) {
+            $exception = NoSuchEntityException::singleField(CustomerGroup::ID, $groupId);
+            $this->assertEquals(
+                $exception->getMessage(),
+                $e->getMessage(),
+                'Exception message does not match expected message.'
+            );
+        }
+    }
+
+    /**
+     * Verify that deleting an non-existing group works.
+     */
+    public function testDeleteGroupNotExists()
+    {
+        $groupId = 4200;
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/$groupId",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'customerGroupRepositoryV1DeleteById',
+            ],
+        ];
+
+        $requestData = [CustomerGroup::ID => $groupId];
+        $expectedMessage = NoSuchEntityException::MESSAGE_SINGLE_FIELD;
+        $expectedParameters = ['fieldName' => CustomerGroup::ID, 'fieldValue' => $groupId];
+
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+        } catch (\SoapFault $e) {
+            $this->assertContains($expectedMessage, $e->getMessage(), "SoapFault does not contain expected message.");
+        } catch (\Exception $e) {
+            $errorObj = $this->processRestExceptionResult($e);
+            $this->assertEquals($expectedMessage, $errorObj['message']);
+            $this->assertEquals($expectedParameters, $errorObj['parameters']);
+        }
+    }
+
+    /**
+     * Verify that the group with the specified Id cannot be deleted because it is the default group and a proper
+     * fault is returned.
+     */
+    public function testDeleteGroupCannotDelete()
+    {
+        $groupIdAssignedDefault = 1;
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/$groupIdAssignedDefault",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'customerGroupRepositoryV1DeleteById',
+            ],
+        ];
+
+        $requestData = [CustomerGroup::ID => $groupIdAssignedDefault];
+        $expectedMessage = "Cannot delete group.";
+
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+            $this->fail("Expected exception");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "SoapFault does not contain expected message."
+            );
+        } catch (\Exception $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "Exception does not contain expected message."
+            );
+        }
+
+        $this->assertNotNull($this->groupRepository->getById($groupIdAssignedDefault));
+    }
+
+    /**
+     * Create a test group.
+     *
+     * @param CustomerGroup $group The group to create and save.
+     * @return int The group Id of the group that was created.
+     */
+    private function createGroup($group)
+    {
+        $groupId = $this->groupRepository->save($group)->getId();
+        $this->assertNotNull($groupId);
+
+        $newGroup = $this->groupRepository->getById($groupId);
+        $this->assertEquals($groupId, $newGroup->getId(), 'The group id does not match.');
+        $this->assertEquals($group->getCode(), $newGroup->getCode(), 'The group code does not match.');
+        $this->assertEquals(
+            $group->getTaxClassId(),
+            $newGroup->getTaxClassId(),
+            'The group tax class id does not match.'
+        );
+
+        $this->groupRegistry->remove($groupId);
+
+        return $groupId;
+    }
+
+    /**
+     * Data provider for testSearchGroups
+     */
+    public function testSearchGroupsDataProvider()
+    {
+        return [
+            ['tax_class_id', '3', []],
+            ['tax_class_id', '0', null],
+            ['code', md5(mt_rand(0, 10000000000) . time()), null],
+            [
+                'id',
+                '0',
+                [
+                    'id' => '0',
+                    'code' => 'NOT LOGGED IN',
+                    'tax_class_id' => '3',
+                    'tax_class_name' => 'Retail Customer'
+                ]
+            ],
+            [
+                'code',
+                'General',
+                [
+                    'id' => '1',
+                    'code' => 'General',
+                    'tax_class_id' => '3',
+                    'tax_class_name' => 'Retail Customer'
+                ]
+            ],
+            [
+                'id',
+                '2',
+                [
+                    'id' => '2',
+                    'code' => 'Wholesale',
+                    'tax_class_id' => '3',
+                    'tax_class_name' => 'Retail Customer'
+                ]
+            ],
+            [
+                'code',
+                'Retailer',
+                [
+                    'id' => '3',
+                    'code' => 'Retailer',
+                    'tax_class_id' => '3',
+                    'tax_class_name' => 'Retail Customer'
+                ]
+            ]
+        ];
+    }
+
+    /**
+     * Test search customer group
+     *
+     * @param string $filterField Customer Group field to filter by
+     * @param string $filterValue Value of the field to be filtered by
+     * @param array $expectedResult Expected search result
+     *
+     * @dataProvider testSearchGroupsDataProvider
+     */
+    public function testSearchGroups($filterField, $filterValue, $expectedResult)
+    {
+        $filterBuilder = Bootstrap::getObjectManager()->create('Magento\Framework\Api\FilterBuilder');
+        $searchCriteriaBuilder =  Bootstrap::getObjectManager()
+            ->create('Magento\Framework\Api\SearchCriteriaBuilder');
+        $filter = $filterBuilder
+                    ->setField($filterField)
+                    ->setValue($filterValue)
+                    ->create();
+        $searchCriteriaBuilder->addFilter([$filter]);
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/search",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => 'customerGroupRepositoryV1GetList',
+            ],
+        ];
+
+        $searchData = $searchCriteriaBuilder->create()->__toArray();
+        $requestData = ['searchCriteria' => $searchData];
+
+        $searchResult = $this->_webApiCall($serviceInfo, $requestData);
+
+        if (is_null($expectedResult)) {
+            $this->assertEquals(0, $searchResult['total_count']);
+        } elseif (is_array($expectedResult)) {
+            $this->assertGreaterThan(0, $searchResult['total_count']);
+            if (!empty($expectedResult)) {
+                $this->assertEquals($expectedResult, $searchResult['items'][0]);
+            }
+        }
+    }
+
+    /**
+     * Test search customer group using GET
+     *
+     * @param string $filterField Customer Group field to filter by
+     * @param string $filterValue Value of the field to be filtered by
+     * @param array $expectedResult Expected search result
+     *
+     * @dataProvider testSearchGroupsDataProvider
+     */
+    public function testSearchGroupsWithGET($filterField, $filterValue, $expectedResult)
+    {
+        $this->_markTestAsRestOnly('SOAP is covered in ');
+        $filterBuilder = Bootstrap::getObjectManager()->create('Magento\Framework\Api\FilterBuilder');
+        $searchCriteriaBuilder =  Bootstrap::getObjectManager()
+            ->create('Magento\Framework\Api\SearchCriteriaBuilder');
+        $filter = $filterBuilder
+            ->setField($filterField)
+            ->setValue($filterValue)
+            ->create();
+        $searchCriteriaBuilder->addFilter([$filter]);
+        $searchData = $searchCriteriaBuilder->create()->__toArray();
+        $requestData = ['searchCriteria' => $searchData];
+        $searchQueryString = http_build_query($requestData);
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/search?' . $searchQueryString,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+        ];
+        $searchResult = $this->_webApiCall($serviceInfo);
+
+        if (is_null($expectedResult)) {
+            $this->assertEquals(0, $searchResult['total_count']);
+        } elseif (is_array($expectedResult)) {
+            $this->assertGreaterThan(0, $searchResult['total_count']);
+            if (!empty($expectedResult)) {
+                $this->assertEquals($expectedResult, $searchResult['items'][0]);
+            }
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/ReadServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/ReadServiceTest.php
new file mode 100644
index 00000000000..4bade515700
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/ReadServiceTest.php
@@ -0,0 +1,155 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Downloadable\Service\V1\DownloadableLink;
+
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ReadServiceTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    /**
+     * @dataProvider getListForAbsentProductProvider()
+     */
+    public function testGetListForAbsentProduct($urlTail, $method)
+    {
+        $sku = 'absent-product' . time();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/' . $sku . $urlTail,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => 'downloadableDownloadableLinkReadServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'downloadableDownloadableLinkReadServiceV1' . $method,
+            ],
+        ];
+
+        $requestData = ['productSku' => $sku];
+
+        $expectedMessage = 'Requested product doesn\'t exist';
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+        } catch (\SoapFault $e) {
+            $this->assertEquals($expectedMessage, $e->getMessage());
+        } catch (\Exception $e) {
+            $this->assertContains($expectedMessage, $e->getMessage());
+        }
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     * @dataProvider getListForAbsentProductProvider
+     */
+    public function testGetListForSimpleProduct($urlTail, $method)
+    {
+        $sku = 'simple';
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/' . $sku . $urlTail,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => 'downloadableDownloadableLinkReadServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'downloadableDownloadableLinkReadServiceV1' . $method,
+            ],
+        ];
+
+        $requestData = ['productSku' => $sku];
+
+        $list = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEmpty($list);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable_with_files.php
+     * @dataProvider getListForAbsentProductProvider
+     */
+    public function testGetList($urlTail, $method, $expectations)
+    {
+        $sku = 'downloadable-product';
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/' . $sku . $urlTail,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => 'downloadableDownloadableLinkReadServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'downloadableDownloadableLinkReadServiceV1' . $method,
+            ],
+        ];
+
+        $requestData = ['productSku' => $sku];
+
+        $list = $this->_webApiCall($serviceInfo, $requestData);
+
+        $this->assertEquals(1, count($list));
+
+        $link = reset($list);
+        foreach ($expectations['fields'] as $index => $value) {
+            $this->assertEquals($value, $link[$index]);
+        }
+
+        foreach ($expectations['resources'] as $name => $fields) {
+            $this->assertNotEmpty($link[$name]);
+            $this->assertEquals($fields['file'], $link[$name]['file']);
+            $this->assertEquals($fields['type'], $link[$name]['type']);
+        }
+    }
+
+    public function getListForAbsentProductProvider()
+    {
+        $sampleIndex = 'sample_resource';
+        $linkIndex = 'link_resource';
+
+        $linkExpectation = [
+            'fields' => [
+                'shareable' => 2,
+                'price' => 15,
+                'number_of_downloads' => 15,
+            ],
+            'resources' => [
+                $sampleIndex => [
+                    'file' => '/n/d/jellyfish_1_3.jpg',
+                    'type' => 'file',
+                ],
+                $linkIndex => [
+                    'file' => '/j/e/jellyfish_2_4.jpg',
+                    'type' => 'file',
+                ],
+            ],
+        ];
+
+        $sampleExpectation = [
+            'fields' => [
+                'title' => 'Downloadable Product Sample Title',
+                'sort_order' => 0,
+            ],
+            'resources' => [
+                $sampleIndex => [
+                    'file' => '/f/u/jellyfish_1_4.jpg',
+                    'type' => 'file',
+                ],
+            ],
+        ];
+
+        return [
+            'links' => [
+                '/downloadable-links',
+                'GetLinks',
+                $linkExpectation,
+            ],
+            'samples' => [
+                '/downloadable-links/samples',
+                'GetSamples',
+                $sampleExpectation,
+            ],
+        ];
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/WriteServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/WriteServiceTest.php
new file mode 100644
index 00000000000..6f96f195175
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/WriteServiceTest.php
@@ -0,0 +1,796 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Downloadable\Service\V1\DownloadableLink;
+
+use Magento\Catalog\Model\Product;
+use Magento\Downloadable\Model\Link;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class WriteServiceTest extends WebapiAbstract
+{
+    /**
+
+     * @var array
+     */
+    protected $createServiceInfo;
+
+    /**
+     * @var array
+     */
+    protected $updateServiceInfo;
+
+    /**
+     * @var array
+     */
+    protected $deleteServiceInfo;
+
+    /**
+     * @var string
+     */
+    protected $testImagePath;
+
+    protected function setUp()
+    {
+        $this->createServiceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/downloadable-product/downloadable-links',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => 'downloadableDownloadableLinkWriteServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'downloadableDownloadableLinkWriteServiceV1Create',
+            ],
+        ];
+
+        $this->updateServiceInfo = [
+            'rest' => [
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => 'downloadableDownloadableLinkWriteServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'downloadableDownloadableLinkWriteServiceV1Update',
+            ],
+        ];
+
+        $this->deleteServiceInfo = [
+            'rest' => [
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => 'downloadableDownloadableLinkWriteServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'downloadableDownloadableLinkWriteServiceV1Delete',
+            ],
+        ];
+
+        $this->testImagePath = __DIR__ . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'test_image.jpg';
+    }
+
+    /**
+     * Retrieve product that was updated by test
+     *
+     * @param bool $isScopeGlobal if true product store ID will be set to 0
+     * @return Product
+     */
+    protected function getTargetProduct($isScopeGlobal = false)
+    {
+        $objectManager = Bootstrap::getObjectManager();
+        $product = $objectManager->get('Magento\Catalog\Model\ProductFactory')->create()->load(1);
+        if ($isScopeGlobal) {
+            $product->setStoreId(0);
+        }
+        return $product;
+    }
+
+    /**
+     * Retrieve product link by its ID (or first link if ID is not specified)
+     *
+     * @param Product $product
+     * @param int|null $linkId
+     * @return Link|null
+     */
+    protected function getTargetLink(Product $product, $linkId = null)
+    {
+        $links = $product->getTypeInstance()->getLinks($product);
+        if (!is_null($linkId)) {
+            return isset($links[$linkId]) ? $links[$linkId] : null;
+        }
+        // return first link
+        return reset($links);
+    }
+
+    /**
+     *  @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     */
+    public function testCreateUploadsProvidedFileContent()
+    {
+        $requestData = [
+            'isGlobalScopeContent' => true,
+            'productSku' => 'downloadable-product',
+            'linkContent' => [
+                'title' => 'Title',
+                'sort_order' => 1,
+                'price' => 10.1,
+                'shareable' => true,
+                'number_of_downloads' => 100,
+                'link_type' => 'file',
+                'link_file' => [
+                    'data' => base64_encode(file_get_contents($this->testImagePath)),
+                    'name' => 'image.jpg',
+                ],
+                'sample_file' => [
+                    'data' => base64_encode(file_get_contents($this->testImagePath)),
+                    'name' => 'image.jpg',
+                ],
+                'sample_type' => 'file',
+            ],
+        ];
+
+        $newLinkId = $this->_webApiCall($this->createServiceInfo, $requestData);
+        $globalScopeLink = $this->getTargetLink($this->getTargetProduct(true), $newLinkId);
+        $link = $this->getTargetLink($this->getTargetProduct(), $newLinkId);
+        $this->assertNotNull($link);
+        $this->assertEquals($requestData['linkContent']['title'], $link->getTitle());
+        $this->assertEquals($requestData['linkContent']['title'], $globalScopeLink->getTitle());
+        $this->assertEquals($requestData['linkContent']['sort_order'], $link->getSortOrder());
+        $this->assertEquals($requestData['linkContent']['price'], $link->getPrice());
+        $this->assertEquals($requestData['linkContent']['price'], $globalScopeLink->getPrice());
+        $this->assertEquals($requestData['linkContent']['shareable'], $link->getIsShareable());
+        $this->assertEquals($requestData['linkContent']['number_of_downloads'], $link->getNumberOfDownloads());
+        $this->assertEquals($requestData['linkContent']['link_type'], $link->getLinkType());
+        $this->assertEquals($requestData['linkContent']['sample_type'], $link->getSampleType());
+        $this->assertStringEndsWith('.jpg', $link->getSampleFile());
+        $this->assertStringEndsWith('.jpg', $link->getLinkFile());
+        $this->assertNull($link->getLinkUrl());
+        $this->assertNull($link->getSampleUrl());
+    }
+
+    /**
+     *  @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     */
+    public function testCreateSavesPriceAndTitleInStoreViewScope()
+    {
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'downloadable-product',
+            'linkContent' => [
+                'title' => 'Store View Title',
+                'sort_order' => 1,
+                'price' => 150,
+                'shareable' => true,
+                'number_of_downloads' => 100,
+                'link_url' => 'http://www.example.com/',
+                'link_type' => 'url',
+                'sample_url' => 'http://www.sample.example.com/',
+                'sample_type' => 'url',
+            ],
+        ];
+
+        $newLinkId = $this->_webApiCall($this->createServiceInfo, $requestData);
+        $link = $this->getTargetLink($this->getTargetProduct(), $newLinkId);
+        $globalScopeLink = $this->getTargetLink($this->getTargetProduct(true), $newLinkId);
+        $this->assertNotNull($link);
+        $this->assertEquals($requestData['linkContent']['title'], $link->getTitle());
+        $this->assertEquals($requestData['linkContent']['sort_order'], $link->getSortOrder());
+        $this->assertEquals($requestData['linkContent']['price'], $link->getPrice());
+        $this->assertEquals($requestData['linkContent']['shareable'], $link->getIsShareable());
+        $this->assertEquals($requestData['linkContent']['number_of_downloads'], $link->getNumberOfDownloads());
+        $this->assertEquals($requestData['linkContent']['link_url'], $link->getLinkUrl());
+        $this->assertEquals($requestData['linkContent']['link_type'], $link->getLinkType());
+        $this->assertEquals($requestData['linkContent']['sample_url'], $link->getSampleUrl());
+        $this->assertEquals($requestData['linkContent']['sample_type'], $link->getSampleType());
+        $this->assertEmpty($globalScopeLink->getTitle());
+        $this->assertEmpty($globalScopeLink->getPrice());
+    }
+
+    /**
+     *  @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     */
+    public function testCreateSavesProvidedUrls()
+    {
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'downloadable-product',
+            'linkContent' => [
+                'title' => 'Link with URL resources',
+                'sort_order' => 1,
+                'price' => 10.1,
+                'shareable' => true,
+                'number_of_downloads' => 100,
+                'link_url' => 'http://www.example.com/',
+                'link_type' => 'url',
+                'sample_url' => 'http://www.sample.example.com/',
+                'sample_type' => 'url',
+            ],
+        ];
+
+        $newLinkId = $this->_webApiCall($this->createServiceInfo, $requestData);
+        $link = $this->getTargetLink($this->getTargetProduct(), $newLinkId);
+        $this->assertNotNull($link);
+        $this->assertEquals($requestData['linkContent']['title'], $link->getTitle());
+        $this->assertEquals($requestData['linkContent']['sort_order'], $link->getSortOrder());
+        $this->assertEquals($requestData['linkContent']['price'], $link->getPrice());
+        $this->assertEquals($requestData['linkContent']['shareable'], $link->getIsShareable());
+        $this->assertEquals($requestData['linkContent']['number_of_downloads'], $link->getNumberOfDownloads());
+        $this->assertEquals($requestData['linkContent']['link_url'], $link->getLinkUrl());
+        $this->assertEquals($requestData['linkContent']['link_type'], $link->getLinkType());
+        $this->assertEquals($requestData['linkContent']['sample_type'], $link->getSampleType());
+        $this->assertEquals($requestData['linkContent']['sample_url'], $link->getSampleUrl());
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Invalid link type.
+     */
+    public function testCreateThrowsExceptionIfLinkTypeIsNotSpecified()
+    {
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'downloadable-product',
+            'linkContent' => [
+                'title' => 'Link with URL resources',
+                'sort_order' => 1,
+                'price' => 10.1,
+                'shareable' => true,
+                'number_of_downloads' => 100,
+            ],
+        ];
+
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Provided content must be valid base64 encoded data.
+     */
+    public function testCreateThrowsExceptionIfLinkFileContentIsNotAValidBase64EncodedString()
+    {
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'downloadable-product',
+            'linkContent' => [
+                'title' => 'Link Title',
+                'sort_order' => 1,
+                'price' => 10,
+                'shareable' => true,
+                'number_of_downloads' => 100,
+                'link_type' => 'url',
+                'link_url' => 'http://www.example.com/',
+                'sample_type' => 'file',
+                'sample_file' => [
+                    'data' => 'not_a_base64_encoded_content',
+                    'name' => 'image.jpg',
+                ],
+            ],
+        ];
+
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Provided content must be valid base64 encoded data.
+     */
+    public function testCreateThrowsExceptionIfSampleFileContentIsNotAValidBase64EncodedString()
+    {
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'downloadable-product',
+            'linkContent' => [
+                'title' => 'Link Title',
+                'sort_order' => 1,
+                'price' => 10,
+                'shareable' => true,
+                'number_of_downloads' => 100,
+                'link_type' => 'file',
+                'link_file' => [
+                    'data' => 'not_a_base64_encoded_content',
+                    'name' => 'image.jpg',
+                ],
+            ],
+        ];
+
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Provided file name contains forbidden characters.
+     */
+    public function testCreateThrowsExceptionIfLinkFileNameContainsForbiddenCharacters()
+    {
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'downloadable-product',
+            'linkContent' => [
+                'title' => 'Title',
+                'sort_order' => 15,
+                'price' => 10,
+                'shareable' => true,
+                'number_of_downloads' => 100,
+                'link_type' => 'file',
+                'link_file' => [
+                    'data' => base64_encode(file_get_contents($this->testImagePath)),
+                    'name' => 'name/with|forbidden{characters',
+                ],
+            ],
+        ];
+
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Provided file name contains forbidden characters.
+     */
+    public function testCreateThrowsExceptionIfSampleFileNameContainsForbiddenCharacters()
+    {
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'downloadable-product',
+            'linkContent' => [
+                'title' => 'Link Title',
+                'sort_order' => 1,
+                'price' => 10,
+                'shareable' => true,
+                'number_of_downloads' => 100,
+                'link_type' => 'url',
+                'link_url' => 'http://www.example.com/',
+                'sample_type' => 'file',
+                'sample_file' => [
+                    'data' => base64_encode(file_get_contents($this->testImagePath)),
+                    'name' => 'name/with|forbidden{characters',
+                ],
+            ],
+        ];
+
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Link URL must have valid format.
+     */
+    public function testCreateThrowsExceptionIfLinkUrlHasWrongFormat()
+    {
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'downloadable-product',
+            'linkContent' => [
+                'title' => 'Link Title',
+                'sort_order' => 1,
+                'price' => 10,
+                'shareable' => true,
+                'number_of_downloads' => 100,
+                'link_type' => 'url',
+                'link_url' => 'http://example<.>com/',
+            ],
+        ];
+
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Sample URL must have valid format.
+     */
+    public function testCreateThrowsExceptionIfSampleUrlHasWrongFormat()
+    {
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'downloadable-product',
+            'linkContent' => [
+                'title' => 'Link Title',
+                'sort_order' => 1,
+                'price' => 150,
+                'shareable' => true,
+                'number_of_downloads' => 0,
+                'sample_type' => 'url',
+                'sample_url' => 'http://example<.>com/',
+                'link_type' => 'url',
+                'link_url' => 'http://example.com/',
+            ],
+        ];
+
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Link price must have numeric positive value.
+     * @dataProvider getInvalidLinkPrice
+     */
+    public function testCreateThrowsExceptionIfLinkPriceIsInvalid($linkPrice)
+    {
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'downloadable-product',
+            'linkContent' => [
+                'title' => 'Link Title',
+                'sort_order' => 1,
+                'price' => $linkPrice,
+                'shareable' => true,
+                'number_of_downloads' => 0,
+                'sample_type' => 'url',
+                'sample_url' => 'http://example.com/',
+                'link_type' => 'url',
+                'link_url' => 'http://example.com/',
+            ],
+        ];
+
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @return array
+     */
+    public function getInvalidLinkPrice()
+    {
+        return [
+            ['string_value'],
+            [-1.5],
+        ];
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Sort order must be a positive integer.
+     * @dataProvider getInvalidSortOrder
+     */
+    public function testCreateThrowsExceptionIfSortOrderIsInvalid($sortOrder)
+    {
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'downloadable-product',
+            'linkContent' => [
+                'title' => 'Link Title',
+                'sort_order' => $sortOrder,
+                'price' => 10,
+                'shareable' => false,
+                'number_of_downloads' => 0,
+                'sample_type' => 'url',
+                'sample_url' => 'http://example.com/',
+                'link_type' => 'url',
+                'link_url' => 'http://example.com/',
+            ],
+        ];
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @return array
+     */
+    public function getInvalidSortOrder()
+    {
+        return [
+            [-1],
+        ];
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Number of downloads must be a positive integer.
+     * @dataProvider getInvalidNumberOfDownloads
+     */
+    public function testCreateThrowsExceptionIfNumberOfDownloadsIsInvalid($numberOfDownloads)
+    {
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'downloadable-product',
+            'linkContent' => [
+                'title' => 'Link Title',
+                'sort_order' => 0,
+                'price' => 10,
+                'shareable' => false,
+                'number_of_downloads' => $numberOfDownloads,
+                'sample_type' => 'url',
+                'sample_url' => 'http://example.com/',
+                'link_type' => 'url',
+                'link_url' => 'http://example.com/',
+            ],
+        ];
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @return array
+     */
+    public function getInvalidNumberOfDownloads()
+    {
+        return [
+            [-1],
+        ];
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Product type of the product must be 'downloadable'.
+     */
+    public function testCreateThrowsExceptionIfTargetProductTypeIsNotDownloadable()
+    {
+        $this->createServiceInfo['rest']['resourcePath'] = '/V1/products/simple/downloadable-links';
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'simple',
+            'linkContent' => [
+                'title' => 'Link Title',
+                'sort_order' => 50,
+                'price' => 200,
+                'shareable' => false,
+                'number_of_downloads' => 10,
+                'sample_type' => 'url',
+                'sample_url' => 'http://example.com/',
+                'link_type' => 'url',
+                'link_url' => 'http://example.com/',
+            ],
+        ];
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Requested product doesn't exist
+     */
+    public function testCreateThrowsExceptionIfTargetProductDoesNotExist()
+    {
+        $this->createServiceInfo['rest']['resourcePath'] = '/V1/products/wrong-sku/downloadable-links';
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'wrong-sku',
+            'linkContent' => [
+                'title' => 'Link Title',
+                'sort_order' => 15,
+                'price' => 200,
+                'shareable' => true,
+                'number_of_downloads' => 100,
+                'sample_type' => 'url',
+                'sample_url' => 'http://example.com/',
+                'link_type' => 'url',
+                'link_url' => 'http://example.com/',
+            ],
+        ];
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     */
+    public function testUpdate()
+    {
+        $linkId = $this->getTargetLink($this->getTargetProduct())->getId();
+        $this->updateServiceInfo['rest']['resourcePath']
+            = "/V1/products/downloadable-product/downloadable-links/{$linkId}";
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'linkId' => $linkId,
+            'productSku' => 'downloadable-product',
+            'linkContent' => [
+                'title' => 'Updated Title',
+                'sort_order' => 2,
+                'price' => 100.10,
+                'shareable' => false,
+                'number_of_downloads' => 50,
+            ],
+        ];
+
+        $this->assertTrue($this->_webApiCall($this->updateServiceInfo, $requestData));
+        $link = $this->getTargetLink($this->getTargetProduct(), $linkId);
+        $this->assertNotNull($link);
+        $this->assertEquals($requestData['linkContent']['title'], $link->getTitle());
+        $this->assertEquals($requestData['linkContent']['sort_order'], $link->getSortOrder());
+        $this->assertEquals($requestData['linkContent']['price'], $link->getPrice());
+        $this->assertEquals($requestData['linkContent']['shareable'], (bool)$link->getIsShareable());
+        $this->assertEquals($requestData['linkContent']['number_of_downloads'], $link->getNumberOfDownloads());
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     */
+    public function testUpdateSavesDataInGlobalScopeAndDoesNotAffectValuesStoredInStoreViewScope()
+    {
+        $originalLink = $this->getTargetLink($this->getTargetProduct());
+        $linkId = $originalLink->getId();
+        $this->updateServiceInfo['rest']['resourcePath']
+            = "/V1/products/downloadable-product/downloadable-links/{$linkId}";
+        $requestData = [
+            'isGlobalScopeContent' => true,
+            'linkId' => $linkId,
+            'productSku' => 'downloadable-product',
+            'linkContent' => [
+                'title' => 'Updated Title',
+                'sort_order' => 2,
+                'price' => 100.10,
+                'shareable' => false,
+                'number_of_downloads' => 50,
+            ],
+        ];
+
+        $this->assertTrue($this->_webApiCall($this->updateServiceInfo, $requestData));
+        $link = $this->getTargetLink($this->getTargetProduct(), $linkId);
+        $globalScopeLink = $this->getTargetLink($this->getTargetProduct(true), $linkId);
+        $this->assertNotNull($link);
+        // Title and price were set on store view level in fixture so they must be the same
+        $this->assertEquals($originalLink->getTitle(), $link->getTitle());
+        $this->assertEquals($originalLink->getPrice(), $link->getPrice());
+        $this->assertEquals($requestData['linkContent']['title'], $globalScopeLink->getTitle());
+        $this->assertEquals($requestData['linkContent']['price'], $globalScopeLink->getPrice());
+        $this->assertEquals($requestData['linkContent']['sort_order'], $link->getSortOrder());
+        $this->assertEquals($requestData['linkContent']['shareable'], (bool)$link->getIsShareable());
+        $this->assertEquals($requestData['linkContent']['number_of_downloads'], $link->getNumberOfDownloads());
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Requested product doesn't exist
+     */
+    public function testUpdateThrowsExceptionIfTargetProductDoesNotExist()
+    {
+        $this->updateServiceInfo['rest']['resourcePath'] = '/V1/products/wrong-sku/downloadable-links/1';
+        $requestData = [
+            'isGlobalScopeContent' => true,
+            'linkId' => 1,
+            'productSku' => 'wrong-sku',
+            'linkContent' => [
+                'title' => 'Updated Title',
+                'sort_order' => 2,
+                'price' => 100.10,
+                'shareable' => false,
+                'number_of_downloads' => 50,
+            ],
+        ];
+        $this->_webApiCall($this->updateServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage There is no downloadable link with provided ID.
+     */
+    public function testUpdateThrowsExceptionIfThereIsNoDownloadableLinkWithGivenId()
+    {
+        $linkId = 9999;
+        $this->updateServiceInfo['rest']['resourcePath']
+            = "/V1/products/downloadable-product/downloadable-links/{$linkId}";
+        $requestData = [
+            'isGlobalScopeContent' => true,
+            'linkId' => 9999,
+            'productSku' => 'downloadable-product',
+            'linkContent' => [
+                'title' => 'Title',
+                'sort_order' => 2,
+                'price' => 100.10,
+                'shareable' => false,
+                'number_of_downloads' => 50,
+            ],
+        ];
+
+        $this->_webApiCall($this->updateServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Link price must have numeric positive value.
+     * @dataProvider getInvalidLinkPrice
+     */
+    public function testUpdateThrowsExceptionIfLinkPriceIsInvalid($linkPrice)
+    {
+        $linkId = $this->getTargetLink($this->getTargetProduct())->getId();
+        $this->updateServiceInfo['rest']['resourcePath']
+            = "/V1/products/downloadable-product/downloadable-links/{$linkId}";
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'linkId' => $linkId,
+            'productSku' => 'downloadable-product',
+            'linkContent' => [
+                'title' => 'Updated Link Title',
+                'sort_order' => 2,
+                'price' => $linkPrice,
+                'shareable' => false,
+                'number_of_downloads' => 50,
+            ],
+        ];
+
+        $this->_webApiCall($this->updateServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Sort order must be a positive integer.
+     * @dataProvider getInvalidSortOrder
+     */
+    public function testUpdateThrowsExceptionIfSortOrderIsInvalid($sortOrder)
+    {
+        $linkId = $this->getTargetLink($this->getTargetProduct())->getId();
+        $this->updateServiceInfo['rest']['resourcePath']
+            = "/V1/products/downloadable-product/downloadable-links/{$linkId}";
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'linkId' => $linkId,
+            'productSku' => 'downloadable-product',
+            'linkContent' => [
+                'title' => 'Updated Link Title',
+                'sort_order' => $sortOrder,
+                'price' => 100.50,
+                'shareable' => false,
+                'number_of_downloads' => 50,
+            ],
+        ];
+        $this->_webApiCall($this->updateServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Number of downloads must be a positive integer.
+     * @dataProvider getInvalidNumberOfDownloads
+     */
+    public function testUpdateThrowsExceptionIfNumberOfDownloadsIsInvalid($numberOfDownloads)
+    {
+        $linkId = $this->getTargetLink($this->getTargetProduct())->getId();
+        $this->updateServiceInfo['rest']['resourcePath']
+            = "/V1/products/downloadable-product/downloadable-links/{$linkId}";
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'linkId' => $linkId,
+            'productSku' => 'downloadable-product',
+            'linkContent' => [
+                'title' => 'Updated Link Title',
+                'sort_order' => 200,
+                'price' => 100.50,
+                'shareable' => false,
+                'number_of_downloads' => $numberOfDownloads,
+            ],
+        ];
+        $this->_webApiCall($this->updateServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     */
+    public function testDelete()
+    {
+        $linkId = $this->getTargetLink($this->getTargetProduct())->getId();
+        $this->deleteServiceInfo['rest']['resourcePath'] = "/V1/products/downloadable-links/{$linkId}";
+        $requestData = [
+            'linkId' => $linkId,
+        ];
+
+        $this->assertTrue($this->_webApiCall($this->deleteServiceInfo, $requestData));
+        $link = $this->getTargetLink($this->getTargetProduct(), $linkId);
+        $this->assertNull($link);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage There is no downloadable link with provided ID.
+     */
+    public function testDeleteThrowsExceptionIfThereIsNoDownloadableLinkWithGivenId()
+    {
+        $linkId = 9999;
+        $this->deleteServiceInfo['rest']['resourcePath'] = "/V1/products/downloadable-links/{$linkId}";
+        $requestData = [
+            'linkId' => $linkId,
+        ];
+
+        $this->_webApiCall($this->deleteServiceInfo, $requestData);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/_files/test_image.jpg b/dev/tests/api-functional/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/_files/test_image.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..ad6b747f73dd9d20f73b8fc780e74d1ff7952762
GIT binary patch
literal 2004
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

literal 0
HcmV?d00001

diff --git a/dev/tests/api-functional/testsuite/Magento/Downloadable/Service/V1/DownloadableSample/WriteServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Downloadable/Service/V1/DownloadableSample/WriteServiceTest.php
new file mode 100644
index 00000000000..542e1527f8e
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Downloadable/Service/V1/DownloadableSample/WriteServiceTest.php
@@ -0,0 +1,509 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Downloadable\Service\V1\DownloadableSample;
+
+use Magento\Catalog\Model\Product;
+use Magento\Downloadable\Model\Sample;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class WriteServiceTest extends WebapiAbstract
+{
+    /**
+     * @var array
+     */
+    protected $createServiceInfo;
+
+    /**
+     * @var string
+     */
+    protected $testImagePath;
+
+    /**
+     * @var array
+     */
+    protected $updateServiceInfo;
+
+    /**
+     * @var array
+     */
+    protected $deleteServiceInfo;
+
+    protected function setUp()
+    {
+        $this->createServiceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/products/downloadable-product/downloadable-links/samples',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => 'downloadableDownloadableSampleWriteServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'downloadableDownloadableSampleWriteServiceV1Create',
+            ],
+        ];
+
+        $this->updateServiceInfo = [
+            'rest' => [
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => 'downloadableDownloadableSampleWriteServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'downloadableDownloadableSampleWriteServiceV1Update',
+            ],
+        ];
+
+        $this->deleteServiceInfo = [
+            'rest' => [
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => 'downloadableDownloadableSampleWriteServiceV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'downloadableDownloadableSampleWriteServiceV1Delete',
+            ],
+        ];
+
+        $this->testImagePath = __DIR__
+            . str_replace('/', DIRECTORY_SEPARATOR, '/../DownloadableLink/_files/test_image.jpg');
+    }
+
+    /**
+     * Retrieve product that was updated by test
+     *
+     * @param bool $isScopeGlobal if true product store ID will be set to 0
+     * @return Product
+     */
+    protected function getTargetProduct($isScopeGlobal = false)
+    {
+        $product = Bootstrap::getObjectManager()->get('Magento\Catalog\Model\ProductFactory')->create()->load(1);
+        if ($isScopeGlobal) {
+            $product->setStoreId(0);
+        }
+        return $product;
+    }
+
+    /**
+     * Retrieve product sample by its ID (or first sample if ID is not specified)
+     *
+     * @param Product $product
+     * @param int|null $sampleId
+     * @return Sample|null
+     */
+    protected function getTargetSample(Product $product, $sampleId = null)
+    {
+        /** @var $samples \Magento\Downloadable\Model\Resource\Sample\Collection */
+        $samples = $product->getTypeInstance()->getSamples($product);
+        if (!is_null($sampleId)) {
+            /* @var $sample \Magento\Downloadable\Model\Sample  */
+            foreach ($samples as $sample) {
+                if ($sample->getId() == $sampleId) {
+                    return $sample;
+                }
+            }
+            return null;
+        }
+        // return first sample
+        return $samples->getFirstItem();
+    }
+
+    /**
+     *  @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     */
+    public function testCreateUploadsProvidedFileContent()
+    {
+        $requestData = [
+            'isGlobalScopeContent' => true,
+            'productSku' => 'downloadable-product',
+            'sampleContent' => [
+                'title' => 'Title',
+                'sort_order' => 1,
+                'sample_file' => [
+                    'data' => base64_encode(file_get_contents($this->testImagePath)),
+                    'name' => 'image.jpg',
+                ],
+                'sample_type' => 'file',
+            ],
+        ];
+
+        $newSampleId = $this->_webApiCall($this->createServiceInfo, $requestData);
+        $globalScopeSample = $this->getTargetSample($this->getTargetProduct(true), $newSampleId);
+        $sample = $this->getTargetSample($this->getTargetProduct(), $newSampleId);
+        $this->assertNotNull($sample);
+        $this->assertEquals($requestData['sampleContent']['title'], $sample->getTitle());
+        $this->assertEquals($requestData['sampleContent']['title'], $globalScopeSample->getTitle());
+        $this->assertEquals($requestData['sampleContent']['sort_order'], $sample->getSortOrder());
+        $this->assertEquals($requestData['sampleContent']['sample_type'], $sample->getSampleType());
+        $this->assertStringEndsWith('.jpg', $sample->getSampleFile());
+        $this->assertNull($sample->getSampleUrl());
+    }
+
+    /**
+     *  @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     */
+    public function testCreateSavesTitleInStoreViewScope()
+    {
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'downloadable-product',
+            'sampleContent' => [
+                'title' => 'Store View Title',
+                'sort_order' => 1,
+                'sample_url' => 'http://www.sample.example.com/',
+                'sample_type' => 'url',
+            ],
+        ];
+
+        $newSampleId = $this->_webApiCall($this->createServiceInfo, $requestData);
+        $sample = $this->getTargetSample($this->getTargetProduct(), $newSampleId);
+        $globalScopeSample = $this->getTargetSample($this->getTargetProduct(true), $newSampleId);
+        $this->assertNotNull($sample);
+        $this->assertEquals($requestData['sampleContent']['title'], $sample->getTitle());
+        $this->assertEquals($requestData['sampleContent']['sort_order'], $sample->getSortOrder());
+        $this->assertEquals($requestData['sampleContent']['sample_url'], $sample->getSampleUrl());
+        $this->assertEquals($requestData['sampleContent']['sample_type'], $sample->getSampleType());
+        $this->assertEmpty($globalScopeSample->getTitle());
+    }
+
+    /**
+     *  @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     */
+    public function testCreateSavesProvidedUrls()
+    {
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'downloadable-product',
+            'sampleContent' => [
+                'title' => 'Sample with URL resource',
+                'sort_order' => 1,
+                'sample_url' => 'http://www.sample.example.com/',
+                'sample_type' => 'url',
+            ],
+        ];
+
+        $newSampleId = $this->_webApiCall($this->createServiceInfo, $requestData);
+        $sample = $this->getTargetSample($this->getTargetProduct(), $newSampleId);
+        $this->assertNotNull($sample);
+        $this->assertEquals($requestData['sampleContent']['title'], $sample->getTitle());
+        $this->assertEquals($requestData['sampleContent']['sort_order'], $sample->getSortOrder());
+        $this->assertEquals($requestData['sampleContent']['sample_type'], $sample->getSampleType());
+        $this->assertEquals($requestData['sampleContent']['sample_url'], $sample->getSampleUrl());
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Invalid sample type.
+     */
+    public function testCreateThrowsExceptionIfSampleTypeIsNotSpecified()
+    {
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'downloadable-product',
+            'sampleContent' => [
+                'title' => 'Sample with URL resource',
+                'sort_order' => 1,
+            ],
+        ];
+
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Provided content must be valid base64 encoded data.
+     */
+    public function testCreateThrowsExceptionIfSampleFileContentIsNotAValidBase64EncodedString()
+    {
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'downloadable-product',
+            'sampleContent' => [
+                'title' => 'Sample Title',
+                'sort_order' => 1,
+                'sample_type' => 'file',
+                'sample_file' => [
+                    'data' => 'not_a_base64_encoded_content',
+                    'name' => 'image.jpg',
+                ],
+            ],
+        ];
+
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Provided file name contains forbidden characters.
+     */
+    public function testCreateThrowsExceptionIfSampleFileNameContainsForbiddenCharacters()
+    {
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'downloadable-product',
+            'sampleContent' => [
+                'title' => 'Title',
+                'sort_order' => 15,
+                'sample_type' => 'file',
+                'sample_file' => [
+                    'data' => base64_encode(file_get_contents($this->testImagePath)),
+                    'name' => 'name/with|forbidden{characters',
+                ],
+            ],
+        ];
+
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Sample URL must have valid format.
+     */
+    public function testCreateThrowsExceptionIfSampleUrlHasWrongFormat()
+    {
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'downloadable-product',
+            'sampleContent' => [
+                'title' => 'Sample Title',
+                'sort_order' => 1,
+                'sample_type' => 'url',
+                'sample_url' => 'http://example<.>com/',
+            ],
+        ];
+
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Sort order must be a positive integer.
+     * @dataProvider getInvalidSortOrder
+     */
+    public function testCreateThrowsExceptionIfSortOrderIsInvalid($sortOrder)
+    {
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'downloadable-product',
+            'sampleContent' => [
+                'title' => 'Sample Title',
+                'sort_order' => $sortOrder,
+                'sample_type' => 'url',
+                'sample_url' => 'http://example.com/',
+            ],
+        ];
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @return array
+     */
+    public function getInvalidSortOrder()
+    {
+        return [
+            [-1],
+        ];
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/product_simple.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Product type of the product must be 'downloadable'.
+     */
+    public function testCreateThrowsExceptionIfTargetProductTypeIsNotDownloadable()
+    {
+        $this->createServiceInfo['rest']['resourcePath']
+            = '/V1/products/simple/downloadable-links/samples';
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'simple',
+            'sampleContent' => [
+                'title' => 'Sample Title',
+                'sort_order' => 50,
+                'sample_type' => 'url',
+                'sample_url' => 'http://example.com/',
+            ],
+        ];
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Requested product doesn't exist
+     */
+    public function testCreateThrowsExceptionIfTargetProductDoesNotExist()
+    {
+        $this->createServiceInfo['rest']['resourcePath']
+            = '/V1/products/wrong-sku/downloadable-links/samples';
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'productSku' => 'wrong-sku',
+            'sampleContent' => [
+                'title' => 'Title',
+                'sort_order' => 15,
+                'sample_type' => 'url',
+                'sample_url' => 'http://example.com/',
+            ],
+        ];
+        $this->_webApiCall($this->createServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable_with_files.php
+     */
+    public function testUpdate()
+    {
+        $sampleId = $this->getTargetSample($this->getTargetProduct())->getId();
+        $this->updateServiceInfo['rest']['resourcePath']
+            = "/V1/products/downloadable-product/downloadable-links/samples/{$sampleId}";
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'sampleId' => $sampleId,
+            'productSku' => 'downloadable-product',
+            'sampleContent' => [
+                'title' => 'Updated Title',
+                'sort_order' => 2,
+            ],
+        ];
+
+        $this->assertTrue($this->_webApiCall($this->updateServiceInfo, $requestData));
+        $sample = $this->getTargetSample($this->getTargetProduct(), $sampleId);
+        $this->assertNotNull($sample);
+        $this->assertEquals($requestData['sampleContent']['title'], $sample->getTitle());
+        $this->assertEquals($requestData['sampleContent']['sort_order'], $sample->getSortOrder());
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable_with_files.php
+     */
+    public function testUpdateSavesDataInGlobalScopeAndDoesNotAffectValuesStoredInStoreViewScope()
+    {
+        $originalSample = $this->getTargetSample($this->getTargetProduct());
+        $sampleId = $originalSample->getId();
+        $this->updateServiceInfo['rest']['resourcePath']
+            = "/V1/products/downloadable-product/downloadable-links/samples/{$sampleId}";
+        $requestData = [
+            'isGlobalScopeContent' => true,
+            'sampleId' => $sampleId,
+            'productSku' => 'downloadable-product',
+            'sampleContent' => [
+                'title' => 'Updated Title',
+                'sort_order' => 2,
+            ],
+        ];
+
+        $this->assertTrue($this->_webApiCall($this->updateServiceInfo, $requestData));
+        $sample = $this->getTargetSample($this->getTargetProduct(), $sampleId);
+        $globalScopeSample = $this->getTargetSample($this->getTargetProduct(true), $sampleId);
+        $this->assertNotNull($sample);
+        // Title was set on store view level in fixture so it must be the same
+        $this->assertEquals($originalSample->getTitle(), $sample->getTitle());
+        $this->assertEquals($requestData['sampleContent']['title'], $globalScopeSample->getTitle());
+        $this->assertEquals($requestData['sampleContent']['sort_order'], $sample->getSortOrder());
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Requested product doesn't exist
+     */
+    public function testUpdateThrowsExceptionIfTargetProductDoesNotExist()
+    {
+        $this->updateServiceInfo['rest']['resourcePath'] = '/V1/products/wrong-sku/downloadable-links/samples/1';
+        $requestData = [
+            'isGlobalScopeContent' => true,
+            'sampleId' => 1,
+            'productSku' => 'wrong-sku',
+            'sampleContent' => [
+                'title' => 'Updated Title',
+                'sort_order' => 2,
+            ],
+        ];
+        $this->_webApiCall($this->updateServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable_with_files.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage There is no downloadable sample with provided ID.
+     */
+    public function testUpdateThrowsExceptionIfThereIsNoDownloadableSampleWithGivenId()
+    {
+        $sampleId = 9999;
+        $this->updateServiceInfo['rest']['resourcePath']
+            = "/V1/products/downloadable-product/downloadable-links/samples/{$sampleId}";
+        $requestData = [
+            'isGlobalScopeContent' => true,
+            'sampleId' => 9999,
+            'productSku' => 'downloadable-product',
+            'sampleContent' => [
+                'title' => 'Title',
+                'sort_order' => 2,
+            ],
+        ];
+
+        $this->_webApiCall($this->updateServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable_with_files.php
+     * @expectedException \Exception
+     * @expectedExceptionMessage Sort order must be a positive integer.
+     * @dataProvider getInvalidSortOrder
+     */
+    public function testUpdateThrowsExceptionIfSortOrderIsInvalid($sortOrder)
+    {
+        $sampleId = $this->getTargetSample($this->getTargetProduct())->getId();
+        $this->updateServiceInfo['rest']['resourcePath']
+            = "/V1/products/downloadable-product/downloadable-links/samples/{$sampleId}";
+        $requestData = [
+            'isGlobalScopeContent' => false,
+            'sampleId' => $sampleId,
+            'productSku' => 'downloadable-product',
+            'sampleContent' => [
+                'title' => 'Updated Sample Title',
+                'sort_order' => $sortOrder,
+            ],
+        ];
+        $this->_webApiCall($this->updateServiceInfo, $requestData);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Downloadable/_files/product_downloadable_with_files.php
+     */
+    public function testDelete()
+    {
+        $sampleId = $this->getTargetSample($this->getTargetProduct())->getId();
+        $this->deleteServiceInfo['rest']['resourcePath'] = "/V1/products/downloadable-links/samples/{$sampleId}";
+        $requestData = [
+            'sampleId' => $sampleId,
+        ];
+
+        $this->assertTrue($this->_webApiCall($this->deleteServiceInfo, $requestData));
+        $sample = $this->getTargetSample($this->getTargetProduct(), $sampleId);
+        $this->assertNull($sample);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage There is no downloadable sample with provided ID.
+     */
+    public function testDeleteThrowsExceptionIfThereIsNoDownloadableSampleWithGivenId()
+    {
+        $sampleId = 9999;
+        $this->deleteServiceInfo['rest']['resourcePath']
+            = "/V1/products/downloadable-links/samples/{$sampleId}";
+        $requestData = [
+            'sampleId' => $sampleId,
+        ];
+
+        $this->_webApiCall($this->deleteServiceInfo, $requestData);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Eav/Api/AttributeSetManagementTest.php b/dev/tests/api-functional/testsuite/Magento/Eav/Api/AttributeSetManagementTest.php
new file mode 100644
index 00000000000..83166269a7c
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Eav/Api/AttributeSetManagementTest.php
@@ -0,0 +1,235 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Eav\Api;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Exception as HTTPExceptionCodes;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class AttributeSetManagementTest extends WebapiAbstract
+{
+    /**
+     * @var array
+     */
+    private $createServiceInfo;
+
+    protected function setUp()
+    {
+        $this->createServiceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/eav/attribute-sets',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => 'eavAttributeSetManagementV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'eavAttributeSetManagementV1Create',
+            ],
+        ];
+    }
+
+    public function testCreate()
+    {
+        $entityTypeCode = 'catalog_product';
+        $entityType = $this->getEntityTypeByCode($entityTypeCode);
+        $attributeSetName = 'new_attribute_set';
+
+        $arguments = [
+            'entityTypeCode' => $entityTypeCode,
+            'attributeSet' => [
+                'attribute_set_name' => $attributeSetName,
+                'sort_order' => 500,
+            ],
+            'skeletonId' => $entityType->getDefaultAttributeSetId(),
+        ];
+        $result = $this->_webApiCall($this->createServiceInfo, $arguments);
+        $this->assertNotNull($result);
+        $attributeSet = $this->getAttributeSetByName($attributeSetName);
+        $this->assertNotNull($attributeSet);
+        $this->assertEquals($attributeSet->getId(), $result['attribute_set_id']);
+        $this->assertEquals($attributeSet->getAttributeSetName(), $result['attribute_set_name']);
+        $this->assertEquals($attributeSet->getEntityTypeId(), $result['entity_type_id']);
+        $this->assertEquals($attributeSet->getEntityTypeId(), $entityType->getId());
+        $this->assertEquals($attributeSet->getSortOrder(), $result['sort_order']);
+        $this->assertEquals($attributeSet->getSortOrder(), 500);
+
+        // Clean up database
+        $attributeSet->delete();
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Invalid value
+     */
+    public function testCreateThrowsExceptionIfGivenAttributeSetAlreadyHasId()
+    {
+        $entityTypeCode = 'catalog_product';
+        $entityType = $this->getEntityTypeByCode($entityTypeCode);
+        $attributeSetName = 'new_attribute_set';
+
+        $arguments = [
+            'entityTypeCode' => $entityTypeCode,
+            'attributeSet' => [
+                'attribute_set_id' => 1,
+                'attribute_set_name' => $attributeSetName,
+                'sort_order' => 100,
+            ],
+            'skeletonId' => $entityType->getDefaultAttributeSetId(),
+        ];
+        $this->_webApiCall($this->createServiceInfo, $arguments);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Invalid value
+     */
+    public function testCreateThrowsExceptionIfGivenSkeletonIdIsInvalid()
+    {
+        $entityTypeCode = 'catalog_product';
+        $attributeSetName = 'new_attribute_set';
+
+        $arguments = [
+            'entityTypeCode' => $entityTypeCode,
+            'attributeSet' => [
+                'attribute_set_name' => $attributeSetName,
+                'sort_order' => 200,
+            ],
+            'skeletonId' => 0,
+        ];
+        $this->_webApiCall($this->createServiceInfo, $arguments);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage No such entity
+     */
+    public function testCreateThrowsExceptionIfGivenSkeletonAttributeSetDoesNotExist()
+    {
+        $attributeSetName = 'new_attribute_set';
+        $entityTypeCode = 'catalog_product';
+
+        $arguments = [
+            'entityTypeCode' => $entityTypeCode,
+            'attributeSet' => [
+                'attribute_set_name' => $attributeSetName,
+                'sort_order' => 300,
+            ],
+            'skeletonId' => 9999,
+        ];
+        $this->_webApiCall($this->createServiceInfo, $arguments);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Invalid entity_type specified: invalid_entity_type
+     */
+    public function testCreateThrowsExceptionIfGivenEntityTypeDoesNotExist()
+    {
+        $entityTypeCode = 'catalog_product';
+        $entityType = $this->getEntityTypeByCode($entityTypeCode);
+        $attributeSetName = 'new_attribute_set';
+
+        $arguments = [
+            'entityTypeCode' => 'invalid_entity_type',
+            'attributeSet' => [
+                'attribute_set_name' => $attributeSetName,
+                'sort_order' => 400,
+            ],
+            'skeletonId' => $entityType->getDefaultAttributeSetId(),
+        ];
+        $this->_webApiCall($this->createServiceInfo, $arguments);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Attribute set name is empty.
+     */
+    public function testCreateThrowsExceptionIfAttributeSetNameIsEmpty()
+    {
+        $entityTypeCode = 'catalog_product';
+        $entityType = $this->getEntityTypeByCode($entityTypeCode);
+        $attributeSetName = '';
+
+        $arguments = [
+            'entityTypeCode' => $entityTypeCode,
+            'attributeSet' => [
+                'attribute_set_name' => $attributeSetName,
+                'sort_order' => 500,
+            ],
+            'skeletonId' => $entityType->getDefaultAttributeSetId(),
+        ];
+        $this->_webApiCall($this->createServiceInfo, $arguments);
+    }
+
+    public function testCreateThrowsExceptionIfAttributeSetWithGivenNameAlreadyExists()
+    {
+        $entityTypeCode = 'catalog_product';
+        $entityType = $this->getEntityTypeByCode($entityTypeCode);
+        $attributeSetName = 'Default';
+        $expectedMessage = 'An attribute set with the "Default" name already exists.';
+
+        $arguments = [
+            'entityTypeCode' => $entityTypeCode,
+            'attributeSet' => [
+                'attribute_set_name' => $attributeSetName,
+                'sort_order' => 550,
+            ],
+            'skeletonId' => $entityType->getDefaultAttributeSetId(),
+        ];
+
+        try {
+            $this->_webApiCall($this->createServiceInfo, $arguments);
+            $this->fail("Expected exception");
+        } catch (\SoapFault $e) {
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "SoapFault does not contain expected message."
+            );
+        } catch (\Exception $e) {
+            $errorObj = $this->processRestExceptionResult($e);
+            $this->assertEquals(
+                $expectedMessage,
+                $errorObj['message']
+            );
+            $this->assertEquals(HTTPExceptionCodes::HTTP_BAD_REQUEST, $e->getCode());
+        }
+    }
+
+    /**
+     * Retrieve attribute set based on given name.
+     * This utility methods assumes that there is only one attribute set with given name,
+     *
+     * @param string $attributeSetName
+     * @return \Magento\Eav\Model\Entity\Attribute\Set|null
+     */
+    protected function getAttributeSetByName($attributeSetName)
+    {
+        $objectManager = Bootstrap::getObjectManager();
+        /** @var \Magento\Eav\Model\Entity\Attribute\Set $attributeSet */
+        $attributeSet = $objectManager->create('Magento\Eav\Model\Entity\Attribute\Set')
+            ->load($attributeSetName, 'attribute_set_name');
+        if ($attributeSet->getId() === null) {
+            return null;
+        }
+        return $attributeSet;
+    }
+
+    /**
+     * Retrieve entity type based on given code.
+     *
+     * @param string $entityTypeCode
+     * @return \Magento\Eav\Model\Entity\Type|null
+     */
+    protected function getEntityTypeByCode($entityTypeCode)
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var \Magento\Eav\Model\Entity\Type $entityType */
+        $entityType = $objectManager->create('Magento\Eav\Model\Config')
+            ->getEntityType($entityTypeCode);
+        return $entityType;
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Eav/Api/AttributeSetRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Eav/Api/AttributeSetRepositoryTest.php
new file mode 100644
index 00000000000..2a7024a290a
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Eav/Api/AttributeSetRepositoryTest.php
@@ -0,0 +1,260 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Eav\Api;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class AttributeSetRepositoryTest extends WebapiAbstract
+{
+    /**
+     * @magentoApiDataFixture Magento/Eav/_files/empty_attribute_set.php
+     */
+    public function testGet()
+    {
+        $attributeSetName = 'empty_attribute_set';
+        $attributeSet = $this->getAttributeSetByName($attributeSetName);
+        $attributeSetId = $attributeSet->getId();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/eav/attribute-sets/' . $attributeSetId,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => 'eavAttributeSetRepositoryV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'eavAttributeSetRepositoryV1Get',
+            ],
+        ];
+        $arguments = [
+            'attributeSetId' => $attributeSetId,
+        ];
+        $result = $this->_webApiCall($serviceInfo, $arguments);
+        $this->assertNotNull($result);
+        $this->assertEquals($attributeSet->getId(), $result['attribute_set_id']);
+        $this->assertEquals($attributeSet->getAttributeSetName(), $result['attribute_set_name']);
+        $this->assertEquals($attributeSet->getEntityTypeId(), $result['entity_type_id']);
+        $this->assertEquals($attributeSet->getSortOrder(), $result['sort_order']);
+    }
+
+    /**
+     * @expectedException \Exception
+     */
+    public function testGetThrowsExceptionIfRequestedAttributeSetDoesNotExist()
+    {
+        $attributeSetId = 9999;
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/eav/attribute-sets/' . $attributeSetId,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => 'eavAttributeSetRepositoryV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'eavAttributeSetRepositoryV1Get',
+            ],
+        ];
+        $arguments = [
+            'attributeSetId' => $attributeSetId,
+        ];
+        $this->_webApiCall($serviceInfo, $arguments);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Eav/_files/empty_attribute_set.php
+     */
+    public function testSave()
+    {
+        $attributeSetName = 'empty_attribute_set';
+        $attributeSet = $this->getAttributeSetByName($attributeSetName);
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/eav/attribute-sets',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => 'eavAttributeSetRepositoryV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'eavAttributeSetRepositoryV1Save',
+            ],
+        ];
+
+        $updatedSortOrder = $attributeSet->getSortOrder() + 200;
+
+        $arguments = [
+            'attributeSet' => [
+                'attribute_set_id' => $attributeSet->getId(),
+                // name is the same, because it is used by fixture rollback script
+                'attribute_set_name' => $attributeSet->getAttributeSetName(),
+                'entity_type_id' => $attributeSet->getEntityTypeId(),
+                'sort_order' => $updatedSortOrder,
+            ],
+        ];
+        $result = $this->_webApiCall($serviceInfo, $arguments);
+        $this->assertNotNull($result);
+        // Reload attribute set data
+        $attributeSet = $this->getAttributeSetByName($attributeSetName);
+        $this->assertEquals($attributeSet->getAttributeSetId(), $result['attribute_set_id']);
+        $this->assertEquals($attributeSet->getAttributeSetName(), $result['attribute_set_name']);
+        $this->assertEquals($attributeSet->getEntityTypeId(), $result['entity_type_id']);
+        $this->assertEquals($updatedSortOrder, $result['sort_order']);
+        $this->assertEquals($attributeSet->getSortOrder(), $result['sort_order']);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Eav/_files/empty_attribute_set.php
+     */
+    public function testDeleteById()
+    {
+        $attributeSetName = 'empty_attribute_set';
+        $attributeSet = $this->getAttributeSetByName($attributeSetName);
+        $attributeSetId = $attributeSet->getId();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/eav/attribute-sets/' . $attributeSetId,
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => 'eavAttributeSetRepositoryV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'eavAttributeSetRepositoryV1DeleteById',
+            ],
+        ];
+
+        $arguments = [
+            'attributeSetId' => $attributeSetId,
+        ];
+        $this->assertTrue($this->_webApiCall($serviceInfo, $arguments));
+        $this->assertNull($this->getAttributeSetByName($attributeSetName));
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Default attribute set can not be deleted
+     */
+    public function testDeleteByIdDefaultAttributeSet()
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var \Magento\Eav\Model\Config */
+        $eavConfig = $objectManager->create('Magento\Eav\Model\Config');
+
+        $defaultAttributeSetId = $eavConfig
+            ->getEntityType(\Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE)
+            ->getDefaultAttributeSetId();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/eav/attribute-sets/' . $defaultAttributeSetId,
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => 'eavAttributeSetRepositoryV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'eavAttributeSetRepositoryV1DeleteById',
+            ],
+        ];
+
+        $arguments = [
+            'attributeSetId' => $defaultAttributeSetId,
+        ];
+        $this->assertTrue($this->_webApiCall($serviceInfo, $arguments));
+    }
+
+    /**
+     * @expectedException \Exception
+     */
+    public function testDeleteByIdThrowsExceptionIfRequestedAttributeSetDoesNotExist()
+    {
+        $attributeSetId = 9999;
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/eav/attribute-sets/' . $attributeSetId,
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => 'eavAttributeSetRepositoryV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'eavAttributeSetRepositoryV1DeleteById',
+            ],
+        ];
+
+        $arguments = [
+            'attributeSetId' => $attributeSetId,
+        ];
+        $this->_webApiCall($serviceInfo, $arguments);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Eav/_files/empty_attribute_set.php
+     */
+    public function testGetList()
+    {
+        $searchCriteria = [
+            'searchCriteria' => [
+                'filter_groups' => [
+                    [
+                        'filters' => [
+                            [
+                                'field' => 'entity_type_code',
+                                'value' => 'catalog_product',
+                                'condition_type' => 'eq',
+                            ],
+                        ],
+                    ],
+                ],
+                'current_page' => 1,
+                'page_size' => 2,
+            ],
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/eav/attribute-sets/list',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => 'eavAttributeSetRepositoryV1',
+                'serviceVersion' => 'V1',
+                'operation' => 'eavAttributeSetRepositoryV1GetList',
+            ],
+        ];
+
+        $response = $this->_webApiCall($serviceInfo, $searchCriteria);
+
+        $this->assertArrayHasKey('search_criteria', $response);
+        $this->assertArrayHasKey('total_count', $response);
+        $this->assertArrayHasKey('items', $response);
+
+        $this->assertEquals($searchCriteria['searchCriteria'], $response['search_criteria']);
+        $this->assertTrue($response['total_count'] > 0);
+        $this->assertTrue(count($response['items']) > 0);
+
+        $this->assertNotNull($response['items'][0]['attribute_set_id']);
+        $this->assertNotNull($response['items'][0]['attribute_set_name']);
+    }
+
+    /**
+     * Retrieve attribute set based on given name.
+     * This utility methods assumes that there is only one attribute set with given name,
+     *
+     * @param string $attributeSetName
+     * @return \Magento\Eav\Model\Entity\Attribute\Set|null
+     */
+    protected function getAttributeSetByName($attributeSetName)
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var \Magento\Eav\Model\Entity\Attribute\Set $attributeSet */
+        $attributeSet = $objectManager->create('Magento\Eav\Model\Entity\Attribute\Set')
+            ->load($attributeSetName, 'attribute_set_name');
+        if ($attributeSet->getId() === null) {
+            return null;
+        }
+        return $attributeSet;
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Framework/Stdlib/CookieManagerTest.php b/dev/tests/api-functional/testsuite/Magento/Framework/Stdlib/CookieManagerTest.php
new file mode 100644
index 00000000000..1c90fcc223e
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Framework/Stdlib/CookieManagerTest.php
@@ -0,0 +1,164 @@
+<?php
+namespace Magento\Framework\Stdlib;
+
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\Webapi\Curl;
+
+/**
+ * End to end test of the Cookie Manager, using curl.
+ *
+ * Uses controllers in TestModule1 to set and delete cookies and verify 'Set-Cookie' headers that come back.
+ */
+class CookieManagerTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    private $cookieTesterUrl = 'testmoduleone/CookieTester';
+
+    /** @var Curl */
+    protected $curlClient;
+
+    public function setUp()
+    {
+        $objectManager = Bootstrap::getObjectManager();
+        $this->config = $objectManager->get('Magento\Webapi\Model\Config');
+        $this->curlClient = $objectManager->get('Magento\TestFramework\TestCase\Webapi\Curl');
+    }
+
+    /**
+     * Set a sensitive Cookie and delete it.
+     *
+     */
+    public function testSensitiveCookie()
+    {
+        $url = $this->cookieTesterUrl . '/SetSensitiveCookie';
+        $cookieParams =
+            [
+                'cookie_name' => 'test-sensitive-cookie',
+                'cookie_value' => 'test-sensitive-cookie-value',
+            ];
+        $response = $this->curlClient->get($url, $cookieParams);
+
+        $cookie = $this->findCookie($cookieParams['cookie_name'], $response['cookies']);
+        $this->assertNotNull($cookie);
+        $this->assertEquals($cookieParams['cookie_name'], $cookie['name']);
+        $this->assertEquals($cookieParams['cookie_value'], $cookie['value']);
+        $this->assertFalse(isset($cookie['domain']));
+        $this->assertFalse(isset($cookie['path']));
+        $this->assertEquals('true', $cookie['httponly']);
+        $this->assertFalse(isset($cookie['secure']));
+        $this->assertFalse(isset($cookie['max-age']));
+    }
+
+    /**
+     * Set a public cookie
+     *
+     */
+    public function testPublicCookieNameValue()
+    {
+        $url = $this->cookieTesterUrl . '/SetPublicCookie';
+        $cookieParams =
+            [
+                'cookie_name' => 'test-cookie',
+                'cookie_value' => 'test-cookie-value',
+            ];
+
+        $response = $this->curlClient->get($url, $cookieParams);
+
+        $cookie = $this->findCookie($cookieParams['cookie_name'], $response['cookies']);
+        $this->assertNotNull($cookie);
+        $this->assertEquals($cookieParams['cookie_name'], $cookie['name']);
+        $this->assertEquals($cookieParams['cookie_value'], $cookie['value']);
+        $this->assertFalse(isset($cookie['domain']));
+        $this->assertFalse(isset($cookie['path']));
+        $this->assertFalse(isset($cookie['httponly']));
+        $this->assertFalse(isset($cookie['secure']));
+        $this->assertFalse(isset($cookie['max-age']));
+    }
+
+    /**
+     * Set a public cookie
+     *
+     */
+    public function testPublicCookieAll()
+    {
+        $url = $this->cookieTesterUrl . '/SetPublicCookie';
+        $cookieParams =
+            [
+                'cookie_name' => 'test-cookie',
+                'cookie_value' => 'test-cookie-value',
+                'cookie_domain' => 'www.example.com',
+                'cookie_path' => '/test/path',
+                'cookie_httponly' => 'true',
+                'cookie_secure' => 'true',
+                'cookie_duration' => '600',
+            ];
+
+        $response = $this->curlClient->get($url, $cookieParams);
+
+        $cookie = $this->findCookie($cookieParams['cookie_name'], $response['cookies']);
+        $this->assertNotNull($cookie);
+        $this->assertEquals($cookieParams['cookie_name'], $cookie['name']);
+        $this->assertEquals($cookieParams['cookie_value'], $cookie['value']);
+        $this->assertEquals($cookieParams['cookie_domain'], $cookie['domain']);
+        $this->assertEquals($cookieParams['cookie_path'], $cookie['path']);
+        $this->assertEquals($cookieParams['cookie_httponly'], $cookie['httponly']);
+        $this->assertEquals($cookieParams['cookie_secure'], $cookie['secure']);
+        if (isset($cookie['max-age'])) {
+            $this->assertEquals($cookieParams['cookie_duration'], $cookie['max-age']);
+        }
+        $this->assertTrue(isset($cookie['expires']));
+    }
+
+    /**
+     * Delete a cookie
+     *
+     */
+    public function testDeleteCookie()
+    {
+        $url = $this->cookieTesterUrl . '/DeleteCookie';
+        $cookieParams =
+            [
+                'cookie_name' => 'test-cookie',
+                'cookie_value' => 'test-cookie-value',
+            ];
+
+        $response = $this->curlClient->get(
+            $url,
+            $cookieParams,
+            ['Cookie: test-cookie=test-cookie-value; anothertestcookie=anothertestcookievalue']
+        );
+
+        $cookie = $this->findCookie($cookieParams['cookie_name'], $response['cookies']);
+        $this->assertNotNull($cookie);
+        $this->assertEquals($cookieParams['cookie_name'], $cookie['name']);
+        $this->assertEquals('deleted', $cookie['value']);
+        $this->assertFalse(isset($cookie['domain']));
+        $this->assertFalse(isset($cookie['path']));
+        $this->assertFalse(isset($cookie['httponly']));
+        $this->assertFalse(isset($cookie['secure']));
+        if (isset($cookie['max-age'])) {
+            $this->assertEquals(0, $cookie['max-age']);
+        }
+        $this->assertEquals('Thu, 01-Jan-1970 00:00:01 GMT', $cookie['expires']);
+    }
+
+    /**
+     * Find cookie with given name in the list of cookies
+     *
+     * @param string $cookieName
+     * @param array $cookies
+     * @return $cookie|null
+     */
+    private function findCookie($cookieName, $cookies)
+    {
+        foreach ($cookies as $cookieIndex => $cookie) {
+            if ($cookie['name'] === $cookieName) {
+                return $cookie;
+            }
+        }
+        return null;
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/GiftMessage/Service/V1/ReadServiceTest.php b/dev/tests/api-functional/testsuite/Magento/GiftMessage/Service/V1/ReadServiceTest.php
new file mode 100644
index 00000000000..a287d6c8e51
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/GiftMessage/Service/V1/ReadServiceTest.php
@@ -0,0 +1,101 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\GiftMessage\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ReadServiceTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+    const SERVICE_NAME = 'giftMessageReadServiceV1';
+    const RESOURCE_PATH = '/V1/carts/';
+
+    /**
+     * @var \Magento\TestFramework\ObjectManager
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/GiftMessage/_files/quote_with_message.php
+     */
+    public function testGet()
+    {
+        /** @var \Magento\Sales\Model\Quote $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('message_order_21', 'reserved_order_id');
+
+        $cartId = $quote->getId();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/gift-message',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Get',
+            ],
+        ];
+
+        $expectedMessage = [
+            'recipient' => 'Mercutio',
+            'sender' => 'Romeo',
+            'message' => 'I thought all for the best.',
+        ];
+
+        $requestData = ["cartId" => $cartId];
+        $resultMessage = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertCount(5, $resultMessage);
+        unset($resultMessage['gift_message_id']);
+        unset($resultMessage['customer_id']);
+        $this->assertEquals($expectedMessage, $resultMessage);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/GiftMessage/_files/quote_with_item_message.php
+     */
+    public function testGetItemMessage()
+    {
+        /** @var \Magento\Sales\Model\Quote $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_item_with_message', 'reserved_order_id');
+        $product = $this->objectManager->create('Magento\Catalog\Model\Product');
+        $product->load($product->getIdBySku('simple_with_message'));
+        $itemId = $quote->getItemByProduct($product)->getId();
+        /** @var  \Magento\Catalog\Model\Product $product */
+        $cartId = $quote->getId();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/gift-message/' . $itemId,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'getItemMessage',
+            ],
+        ];
+
+        $expectedMessage = [
+            'recipient' => 'Jane Roe',
+            'sender' => 'John Doe',
+            'message' => 'Gift Message Text',
+        ];
+
+        $requestData = ["cartId" => $cartId, "itemId" => $itemId];
+        $resultMessage = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertCount(5, $resultMessage);
+        unset($resultMessage['gift_message_id']);
+        unset($resultMessage['customer_id']);
+        $this->assertEquals($expectedMessage, $resultMessage);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/GiftMessage/Service/V1/WriteServiceTest.php b/dev/tests/api-functional/testsuite/Magento/GiftMessage/Service/V1/WriteServiceTest.php
new file mode 100644
index 00000000000..79185a68dca
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/GiftMessage/Service/V1/WriteServiceTest.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\GiftMessage\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class WriteServiceTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+    const SERVICE_NAME = 'giftMessageWriteServiceV1';
+    const RESOURCE_PATH = '/V1/carts/';
+
+    /**
+     * @var \Magento\TestFramework\ObjectManager
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/GiftMessage/_files/quote_with_item_message.php
+     */
+    public function testSetForQuote()
+    {
+        // sales/gift_options/allow_order must be set to 1 in system configuration
+        // @todo remove next statement when \Magento\TestFramework\TestCase\WebapiAbstract::_updateAppConfig is fixed
+        $this->markTestIncomplete('This test relies on system configuration state.');
+        /** @var \Magento\Sales\Model\Quote $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_item_with_message', 'reserved_order_id');
+
+        $cartId = $quote->getId();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/gift-message',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'SetForQuote',
+            ],
+        ];
+
+        $requestData = [
+            'cartId' => $cartId,
+            'giftMessage' => [
+                'recipient' => 'John Doe',
+                'sender' => 'Jane Roe',
+                'message' => 'Gift Message Text New',
+            ],
+        ];
+        $this->assertTrue($this->_webApiCall($serviceInfo, $requestData));
+        $quote->load('test_order_item_with_message', 'reserved_order_id');
+        $quote->getGiftMessageId();
+        /** @var  \Magento\GiftMessage\Model\Message $message */
+        $message = $this->objectManager->create('Magento\GiftMessage\Model\Message')->load($quote->getGiftMessageId());
+        $this->assertEquals('John Doe', $message->getRecipient());
+        $this->assertEquals('Jane Roe', $message->getSender());
+        $this->assertEquals('Gift Message Text New', $message->getMessage());
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/GiftMessage/_files/quote_with_item_message.php
+     */
+    public function testSetForItem()
+    {
+        // sales/gift_options/allow_items must be set to 1 in system configuration
+        // @todo remove next statement when \Magento\TestFramework\TestCase\WebapiAbstract::_updateAppConfig is fixed
+        $this->markTestIncomplete('This test relies on system configuration state.');
+        /** @var \Magento\Sales\Model\Quote $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->load('test_order_item_with_message', 'reserved_order_id');
+        $cartId = $quote->getId();
+        $product = $this->objectManager->create('Magento\Catalog\Model\Product');
+        $product->load($product->getIdBySku('simple_with_message'));
+        $itemId = $quote->getItemByProduct($product)->getId();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $cartId . '/gift-message/' .  $itemId,
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'SetForItem',
+            ],
+        ];
+
+        $requestData = [
+            'cartId' => $cartId,
+            'itemId' => $itemId,
+            'giftMessage' => [
+                'recipient' => 'John Doe',
+                'sender' => 'Jane Roe',
+                'message' => 'Gift Message Text New',
+            ],
+        ];
+        $this->assertTrue($this->_webApiCall($serviceInfo, $requestData));
+//        $quote->load('test_order_item_with_message', 'reserved_order_id');
+        $messageId = $quote->getItemByProduct($product)->getGiftMessageId();
+        /** @var  \Magento\GiftMessage\Model\Message $message */
+        $message = $this->objectManager->create('Magento\GiftMessage\Model\Message')->load($messageId);
+        $this->assertEquals('John Doe', $message->getRecipient());
+        $this->assertEquals('Jane Roe', $message->getSender());
+        $this->assertEquals('Gift Message Text New', $message->getMessage());
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkManagementTest.php b/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkManagementTest.php
new file mode 100644
index 00000000000..4a6ce3ac19f
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkManagementTest.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\GroupedProduct\Api;
+
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ProductLinkManagementTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogProductLinkManagementV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/products/';
+
+    /**
+     * @magentoApiDataFixture Magento/GroupedProduct/_files/product_grouped.php
+     */
+    public function testGetLinkedItemsByType()
+    {
+        $productSku = 'grouped-product';
+        $linkType = 'associated';
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $productSku . '/links/' . $linkType,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetLinkedItemsByType',
+            ],
+        ];
+
+        $actual = $this->_webApiCall($serviceInfo, ['productSku' => $productSku, 'type' => $linkType]);
+
+        $expected = [
+            [
+                'product_sku' => 'grouped-product',
+                'link_type' => 'associated',
+                'linked_product_sku' => 'simple-1',
+                'linked_product_type' => 'simple',
+                'position' => 1,
+            ],
+            [
+                'product_sku' => 'grouped-product',
+                'link_type' => 'associated',
+                'linked_product_sku' => 'virtual-product',
+                'linked_product_type' => 'virtual',
+                'position' => 2,
+            ],
+        ];
+
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            array_walk(
+                $expected,
+                function (&$item) {
+                    $item['custom_attributes'] = [['attribute_code' => 'qty', 'value' => 1.0000]];
+                }
+            );
+        } else {
+            array_walk(
+                $expected,
+                function (&$item) {
+                    $item['custom_attributes'] = [['attribute_code' => 'qty', 'value' => 1.0000]];
+                }
+            );
+        }
+        $this->assertEquals($expected, $actual);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkRepositoryTest.php
new file mode 100644
index 00000000000..80e1ca73707
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkRepositoryTest.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\GroupedProduct\Api;
+
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+use Magento\TestFramework\Helper\Bootstrap;
+
+class ProductLinkRepositoryTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogProductLinkRepositoryV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/products/';
+
+    /**
+     * @var \Magento\Framework\ObjectManager
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = Bootstrap::getObjectManager();
+    }
+    /**
+     * @magentoApiDataFixture Magento/Catalog/_files/products_new.php
+     * @magentoApiDataFixture Magento/GroupedProduct/_files/product_grouped.php
+     */
+    public function testSave()
+    {
+        $productSku = 'grouped-product';
+        $linkType = 'associated';
+        $productData = [
+            'product_sku' => $productSku,
+            'link_type' => $linkType,
+            'linked_product_type' => 'simple',
+            'linked_product_sku' => 'simple',
+            'position' => 3,
+            'custom_attributes' => [
+                'qty' => ['attribute_code' => 'qty', 'value' => (float) 300.0000],
+            ],
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . $productSku . '/links/' . $linkType,
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $this->_webApiCall($serviceInfo, ['entity' => $productData]);
+
+        /** @var \Magento\Catalog\Model\ProductLink\Management $linkManagement */
+        $linkManagement = $this->objectManager->get('Magento\Catalog\Api\ProductLinkManagementInterface');
+        $actual = $linkManagement->getLinkedItemsByType($productSku, $linkType);
+        array_walk($actual, function (&$item) {
+            $item = $item->__toArray();
+        });
+        $this->assertEquals($productData, $actual[2]);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkTypeListTest.php b/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkTypeListTest.php
new file mode 100644
index 00000000000..cec4ba0b677
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/GroupedProduct/Api/ProductLinkTypeListTest.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\GroupedProduct\Api;
+
+use Magento\GroupedProduct\Model\Resource\Product\Link;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ProductLinkTypeListTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    const SERVICE_NAME = 'catalogProductLinkTypeListV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/products/';
+
+    public function testGetItems()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . 'links/types',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetItems',
+            ],
+        ];
+
+        $actual = $this->_webApiCall($serviceInfo);
+
+        /**
+         * Validate that product type links provided by Magento_GroupedProduct module are present
+         */
+        $expectedItems = ['name' => 'associated', 'code' => Link::LINK_TYPE_GROUPED];
+        $this->assertContains($expectedItems, $actual);
+    }
+
+    public function testGetItemAttributes()
+    {
+        $linkType = 'associated';
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . 'links/' . $linkType . '/attributes',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetItemAttributes',
+            ],
+        ];
+
+        $actual = $this->_webApiCall($serviceInfo, ['type' => $linkType]);
+
+        $expected = [
+            ['code' => 'position', 'type' => 'int'],
+            ['code' => 'qty', 'type' => 'decimal'],
+        ];
+        $this->assertEquals($expected, $actual);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Integration/Service/V1/AdminTokenServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Integration/Service/V1/AdminTokenServiceTest.php
new file mode 100644
index 00000000000..91e6a4cad97
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Integration/Service/V1/AdminTokenServiceTest.php
@@ -0,0 +1,159 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Integration\Service\V1;
+
+use Magento\Framework\Exception\InputException;
+use Magento\Integration\Model\Oauth\Token as TokenModel;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\User\Model\User as UserModel;
+use Magento\Webapi\Exception as HTTPExceptionCodes;
+
+/**
+ * api-functional test for \Magento\Integration\Service\V1\AdminTokenService.
+ */
+class AdminTokenServiceTest extends WebapiAbstract
+{
+    const SERVICE_NAME = "integrationAdminTokenServiceV1";
+    const SERVICE_VERSION = "V1";
+    const RESOURCE_PATH_ADMIN_TOKEN = "/V1/integration/admin/token";
+    const RESOURCE_PATH_CUSTOMER_TOKEN = "/V1/integration/customer/token";
+
+    /**
+     * @var AdminTokenServiceInterface
+     */
+    private $tokenService;
+
+    /**
+     * @var TokenModel
+     */
+    private $tokenModel;
+
+    /**
+     * @var UserModel
+     */
+    private $userModel;
+
+    /**
+     * Setup AdminTokenService
+     */
+    public function setUp()
+    {
+        $this->_markTestAsRestOnly();
+        $this->tokenService = Bootstrap::getObjectManager()->get('Magento\Integration\Service\V1\AdminTokenService');
+        $this->tokenModel = Bootstrap::getObjectManager()->get('Magento\Integration\Model\Oauth\Token');
+        $this->userModel = Bootstrap::getObjectManager()->get('Magento\User\Model\User');
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/User/_files/user_with_role.php
+     */
+    public function testCreateAdminAccessToken()
+    {
+        $adminUserNameFromFixture = 'adminUser';
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH_ADMIN_TOKEN,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+            ],
+        ];
+        $requestData = [
+            'username' => $adminUserNameFromFixture,
+            'password' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD,
+        ];
+        $accessToken = $this->_webApiCall($serviceInfo, $requestData);
+
+        $adminUserId = $this->userModel->loadByUsername($adminUserNameFromFixture)->getId();
+        /** @var $token TokenModel */
+        $token = $this->tokenModel
+            ->loadByAdminId($adminUserId)
+            ->getToken();
+        $this->assertEquals($accessToken, $token);
+    }
+
+    /**
+     * @dataProvider validationDataProvider
+     */
+    public function testCreateAdminAccessTokenEmptyOrNullCredentials()
+    {
+        try {
+            $serviceInfo = [
+                'rest' => [
+                    'resourcePath' => self::RESOURCE_PATH_ADMIN_TOKEN,
+                    'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+                ],
+            ];
+            $requestData = ['username' => '', 'password' => ''];
+            $this->_webApiCall($serviceInfo, $requestData);
+        } catch (\Exception $e) {
+            $this->assertInputExceptionMessages($e);
+        }
+    }
+
+    public function testCreateAdminAccessTokenInvalidCustomer()
+    {
+        $customerUserName = 'invalid';
+        $password = 'invalid';
+        try {
+            $serviceInfo = [
+                'rest' => [
+                    'resourcePath' => self::RESOURCE_PATH_CUSTOMER_TOKEN,
+                    'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+                ],
+            ];
+            $requestData = ['username' => $customerUserName, 'password' => $password];
+            $this->_webApiCall($serviceInfo, $requestData);
+        } catch (\Exception $e) {
+            $this->assertEquals(HTTPExceptionCodes::HTTP_UNAUTHORIZED, $e->getCode());
+            $exceptionData = $this->processRestExceptionResult($e);
+            $expectedExceptionData = ['message' => 'Invalid login or password.'];
+        }
+        $this->assertEquals($expectedExceptionData, $exceptionData);
+    }
+
+    /**
+     * Provider to test input validation
+     *
+     * @return array
+     */
+    public function validationDataProvider()
+    {
+        return [
+            'Check for empty credentials' => ['', ''],
+            'Check for null credentials' => [null, null]
+        ];
+    }
+
+    /**
+     * Assert for presence of Input exception messages
+     *
+     * @param \Exception $e
+     */
+    private function assertInputExceptionMessages($e)
+    {
+        $this->assertEquals(HTTPExceptionCodes::HTTP_BAD_REQUEST, $e->getCode());
+        $exceptionData = $this->processRestExceptionResult($e);
+        $expectedExceptionData = [
+            'message' => InputException::DEFAULT_MESSAGE,
+            'errors' => [
+                [
+                    'message' => InputException::REQUIRED_FIELD,
+                    'parameters' => [
+                        'fieldName' => 'username',
+                    ],
+                ],
+                [
+                    'message' => InputException::REQUIRED_FIELD,
+                    'parameters' => [
+                        'fieldName' => 'password',
+                    ]
+                ],
+            ],
+        ];
+        $this->assertEquals($expectedExceptionData, $exceptionData);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Integration/Service/V1/CustomerTokenServiceTest.php b/dev/tests/api-functional/testsuite/Magento/Integration/Service/V1/CustomerTokenServiceTest.php
new file mode 100644
index 00000000000..f6a4f4f2ce2
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Integration/Service/V1/CustomerTokenServiceTest.php
@@ -0,0 +1,164 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Integration\Service\V1;
+
+use Magento\Customer\Api\AccountManagementInterface;
+use Magento\Framework\Exception\InputException;
+use Magento\Integration\Model\Oauth\Token as TokenModel;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\User\Model\User as UserModel;
+use Magento\Webapi\Exception as HTTPExceptionCodes;
+
+/**
+ * api-functional test for \Magento\Integration\Service\V1\CustomerTokenService.
+ */
+class CustomerTokenServiceTest extends WebapiAbstract
+{
+    const SERVICE_NAME = "integrationCustomerTokenServiceV1";
+    const SERVICE_VERSION = "V1";
+    const RESOURCE_PATH_CUSTOMER_TOKEN = "/V1/integration/customer/token";
+    const RESOURCE_PATH_ADMIN_TOKEN = "/V1/integration/admin/token";
+
+    /**
+     * @var CustomerTokenServiceInterface
+     */
+    private $tokenService;
+
+    /**
+     * @var AccountManagementInterface
+     */
+    private $customerAccountManagement;
+
+    /**
+     * @var TokenModel
+     */
+    private $tokenModel;
+
+    /**
+     * @var UserModel
+     */
+    private $userModel;
+
+    /**
+     * Setup CustomerTokenService
+     */
+    public function setUp()
+    {
+        $this->_markTestAsRestOnly();
+        $this->tokenService = Bootstrap::getObjectManager()->get('Magento\Integration\Service\V1\CustomerTokenService');
+        $this->customerAccountManagement = Bootstrap::getObjectManager()->get(
+            'Magento\Customer\Api\AccountManagementInterface'
+        );
+        $this->tokenModel = Bootstrap::getObjectManager()->get('Magento\Integration\Model\Oauth\Token');
+        $this->userModel = Bootstrap::getObjectManager()->get('Magento\User\Model\User');
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Customer/_files/customer.php
+     */
+    public function testCreateCustomerAccessToken()
+    {
+        $customerUserName = 'customer@example.com';
+        $password = 'password';
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH_CUSTOMER_TOKEN,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+            ],
+        ];
+        $requestData = ['username' => $customerUserName, 'password' => $password];
+        $accessToken = $this->_webApiCall($serviceInfo, $requestData);
+
+        $customerData = $this->customerAccountManagement->authenticate($customerUserName, $password);
+        /** @var $token TokenModel */
+        $token = $this->tokenModel->loadByCustomerId($customerData->getId())->getToken();
+        $this->assertEquals($accessToken, $token);
+    }
+
+    /**
+     * @dataProvider validationDataProvider
+     */
+    public function testCreateCustomerAccessTokenEmptyOrNullCredentials($username, $password)
+    {
+        try {
+            $serviceInfo = [
+                'rest' => [
+                    'resourcePath' => self::RESOURCE_PATH_CUSTOMER_TOKEN,
+                    'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+                ],
+            ];
+            $requestData = ['username' => '', 'password' => ''];
+            $this->_webApiCall($serviceInfo, $requestData);
+        } catch (\Exception $e) {
+            $this->assertInputExceptionMessages($e);
+        }
+    }
+
+    public function testCreateCustomerAccessTokenInvalidCustomer()
+    {
+        $customerUserName = 'invalid';
+        $password = 'invalid';
+        try {
+            $serviceInfo = [
+                'rest' => [
+                    'resourcePath' => self::RESOURCE_PATH_CUSTOMER_TOKEN,
+                    'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+                ],
+            ];
+            $requestData = ['username' => $customerUserName, 'password' => $password];
+            $this->_webApiCall($serviceInfo, $requestData);
+        } catch (\Exception $e) {
+            $this->assertEquals(HTTPExceptionCodes::HTTP_UNAUTHORIZED, $e->getCode());
+            $exceptionData = $this->processRestExceptionResult($e);
+            $expectedExceptionData = ['message' => 'Invalid login or password.'];
+        }
+        $this->assertEquals($expectedExceptionData, $exceptionData);
+    }
+
+    /**
+     * Provider to test input validation
+     *
+     * @return array
+     */
+    public function validationDataProvider()
+    {
+        return [
+            'Check for empty credentials' => ['', ''],
+            'Check for null credentials' => [null, null]
+        ];
+    }
+
+    /**
+     * Assert for presence of Input exception messages
+     *
+     * @param \Exception $e
+     */
+    private function assertInputExceptionMessages($e)
+    {
+        $this->assertEquals(HTTPExceptionCodes::HTTP_BAD_REQUEST, $e->getCode());
+        $exceptionData = $this->processRestExceptionResult($e);
+        $expectedExceptionData = [
+            'message' => InputException::DEFAULT_MESSAGE,
+            'errors' => [
+                [
+                    'message' => InputException::REQUIRED_FIELD,
+                    'parameters' => [
+                        'fieldName' => 'username',
+                    ],
+                ],
+                [
+                    'message' => InputException::REQUIRED_FIELD,
+                    'parameters' => [
+                        'fieldName' => 'password',
+                    ]
+                ],
+            ],
+        ];
+        $this->assertEquals($expectedExceptionData, $exceptionData);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoAddCommentTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoAddCommentTest.php
new file mode 100644
index 00000000000..885bcb8f8b7
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoAddCommentTest.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\Sales\Api\Data\CreditmemoCommentInterface as Comment;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+/**
+ * Class CreditmemoAddCommentTest
+ */
+class CreditmemoAddCommentTest extends WebapiAbstract
+{
+    /**
+     * Service read name
+     */
+    const SERVICE_READ_NAME = 'salesCreditmemoCommentRepositoryV1';
+
+    /**
+     * Service version
+     */
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * Creditmemo increment id
+     */
+    const CREDITMEMO_INCREMENT_ID = '100000001';
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    /**
+     * Set up
+     *
+     * @return void
+     */
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * Test creditmemo add comment service
+     *
+     * @magentoApiDataFixture Magento/Sales/_files/creditmemo_with_list.php
+     */
+    public function testCreditmemoAddComment()
+    {
+        /** @var \Magento\Sales\Model\Resource\Order\Creditmemo\Collection $creditmemoCollection */
+        $creditmemoCollection = $this->objectManager->get('Magento\Sales\Model\Resource\Order\Creditmemo\Collection');
+        $creditmemo = $creditmemoCollection->getFirstItem();
+
+        $commentData = [
+            Comment::COMMENT => 'Hello world!',
+            Comment::ENTITY_ID => null,
+            Comment::CREATED_AT => null,
+            Comment::PARENT_ID => $creditmemo->getId(),
+            Comment::IS_VISIBLE_ON_FRONT => true,
+            Comment::IS_CUSTOMER_NOTIFIED => true,
+        ];
+
+        $requestData = ['entity' => $commentData];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/creditmemo/comment',
+                'httpMethod' => Config::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'save',
+            ],
+        ];
+
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertNotEmpty($result);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoCancelTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoCancelTest.php
new file mode 100644
index 00000000000..e7ad70a5765
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoCancelTest.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+/**
+ * Class CreditmemoCancelTest
+ */
+class CreditmemoCancelTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+
+    const SERVICE_NAME = 'salesCreditmemoManagementV1';
+
+    const CREDITMEMO_INCREMENT_ID = '100000001';
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/creditmemo_with_list.php
+     */
+    public function testCreditmemoCancel()
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+        /** @var \Magento\Sales\Model\Resource\Order\Creditmemo\Collection $creditmemoCollection */
+        $creditmemoCollection = $objectManager->get('Magento\Sales\Model\Resource\Order\Creditmemo\Collection');
+        $creditmemo = $creditmemoCollection->getFirstItem();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/creditmemo/' . $creditmemo->getId(),
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'cancel',
+            ],
+        ];
+        $requestData = ['id' => $creditmemo->getId()];
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertTrue($result);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoCommentsListTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoCommentsListTest.php
new file mode 100644
index 00000000000..25662567474
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoCommentsListTest.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\Sales\Api\Data\CreditmemoCommentInterface;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+/**
+ * Class CreditmemoCommentsListTest
+ */
+class CreditmemoCommentsListTest extends WebapiAbstract
+{
+    const SERVICE_NAME = 'salesCreditmemoManagementV1';
+
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/creditmemo_for_get.php
+     */
+    public function testCreditmemoCommentsList()
+    {
+        $comment = 'Test comment';
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var \Magento\Sales\Model\Resource\Order\Creditmemo\Collection $creditmemoCollection */
+        $creditmemoCollection = $objectManager->get('Magento\Sales\Model\Resource\Order\Creditmemo\Collection');
+        $creditmemo = $creditmemoCollection->getFirstItem();
+        $creditmemoComment = $objectManager->get('Magento\Sales\Model\Order\Creditmemo\Comment');
+
+        $commentData = [
+            CreditmemoCommentInterface::COMMENT => 'Hello world!',
+            CreditmemoCommentInterface::ENTITY_ID => null,
+            CreditmemoCommentInterface::CREATED_AT => null,
+            CreditmemoCommentInterface::PARENT_ID => $creditmemo->getId(),
+            CreditmemoCommentInterface::IS_VISIBLE_ON_FRONT => true,
+            CreditmemoCommentInterface::IS_CUSTOMER_NOTIFIED => true,
+        ];
+        $creditmemoComment->setData($commentData)->save();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/creditmemo/' . $creditmemo->getId() . '/comments',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'getCommentsList',
+            ],
+        ];
+        $requestData = ['id' => $creditmemo->getId()];
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        // TODO Test fails, due to the inability of the framework API to handle data collection
+        $this->assertNotEmpty($result);
+        foreach ($result['items'] as $item) {
+            $comment = $objectManager->get('Magento\Sales\Model\Order\Creditmemo\Comment')->load($item['entity_id']);
+            $this->assertEquals($comment->getComment(), $item['comment']);
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoCreateTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoCreateTest.php
new file mode 100644
index 00000000000..e7fb134e9d2
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoCreateTest.php
@@ -0,0 +1,111 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+/**
+ * Class CreditmemoCreateTest
+ */
+class CreditmemoCreateTest extends WebapiAbstract
+{
+    const RESOURCE_PATH = '/V1/creditmemo';
+
+    const SERVICE_READ_NAME = 'salesCreditmemoRepositoryV1';
+
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/invoice.php
+     */
+    public function testInvoke()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $orderCollection = $this->objectManager->get('Magento\Sales\Model\Resource\Order\Collection');
+        $order = $orderCollection->getFirstItem();
+
+//        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+        /** @var \Magento\Sales\Model\Order\Item $orderItem */
+        $orderItem = current($order->getAllItems());
+        $items = [
+            $orderItem->getId() => ['qty' => $orderItem->getQtyInvoiced(), 'order_item_id' => $orderItem->getId()],
+        ];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => Config::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'save',
+            ],
+        ];
+        $data = [
+            'adjustment' => null,
+            'adjustment_negative' => null,
+            'adjustment_positive' => null,
+            'base_adjustment' => null,
+            'base_adjustment_negative' => null,
+            'base_adjustment_positive' => null,
+            'base_currency_code' => null,
+            'base_discount_amount' => null,
+            'base_grand_total' => null,
+            'base_hidden_tax_amount' => null,
+            'base_shipping_amount' => null,
+            'base_shipping_hidden_tax_amnt' => null,
+            'base_shipping_incl_tax' => null,
+            'base_shipping_tax_amount' => null,
+            'base_subtotal' => null,
+            'base_subtotal_incl_tax' => null,
+            'base_tax_amount' => null,
+            'base_to_global_rate' => null,
+            'base_to_order_rate' => null,
+            'billing_address_id' => null,
+            'created_at' => null,
+            'creditmemo_status' => null,
+            'discount_amount' => null,
+            'discount_description' => null,
+            'email_sent' => null,
+            'entity_id' => null,
+            'global_currency_code' => null,
+            'grand_total' => null,
+            'hidden_tax_amount' => null,
+            'increment_id' => null,
+            'invoice_id' => null,
+            'order_currency_code' => null,
+            'order_id' => $order->getId(),
+            'shipping_address_id' => null,
+            'shipping_amount' => null,
+            'shipping_hidden_tax_amount' => null,
+            'shipping_incl_tax' => null,
+            'shipping_tax_amount' => null,
+            'state' => null,
+            'store_currency_code' => null,
+            'store_id' => null,
+            'store_to_base_rate' => null,
+            'store_to_order_rate' => null,
+            'subtotal' => null,
+            'subtotal_incl_tax' => null,
+            'tax_amount' => null,
+            'transaction_id' => null,
+            'updated_at' => null,
+            'items' => $items,
+        ];
+        $result = $this->_webApiCall($serviceInfo, ['entity' => $data]);
+        $this->assertNotEmpty($result);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoEmailTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoEmailTest.php
new file mode 100644
index 00000000000..828a0338c36
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoEmailTest.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+/**
+ * Class CreditmemoEmailTest
+ */
+class CreditmemoEmailTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+
+    const SERVICE_NAME = 'salesCreditmemoManagementV1';
+
+    const CREDITMEMO_INCREMENT_ID = '100000001';
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/creditmemo_with_list.php
+     */
+    public function testCreditmemoEmail()
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+        /** @var \Magento\Sales\Model\Resource\Order\Creditmemo\Collection $creditmemoCollection */
+        $creditmemoCollection = $objectManager->get('Magento\Sales\Model\Resource\Order\Creditmemo\Collection');
+        $creditmemo = $creditmemoCollection->getFirstItem();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/creditmemo/' . $creditmemo->getId(),
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'notify',
+            ],
+        ];
+        $requestData = ['id' => $creditmemo->getId()];
+        $this->_webApiCall($serviceInfo, $requestData);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoGetTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoGetTest.php
new file mode 100644
index 00000000000..2e11ef7791c
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoGetTest.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+/**
+ * Class CreditmemoGetTest
+ */
+class CreditmemoGetTest extends WebapiAbstract
+{
+    /**
+     * Resource path
+     */
+    const RESOURCE_PATH = '/V1/creditmemo';
+
+    /**
+     * Service read name
+     */
+    const SERVICE_READ_NAME = 'salesCreditmemoRepositoryV1';
+
+    /**
+     * Service version
+     */
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * Creditmemo id
+     */
+    const CREDITMEMO_INCREMENT_ID = '100000001';
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    /**
+     * Required fields are in the answer
+     *
+     * @var array
+     */
+    protected $requiredFields = [
+        'entity_id',
+        'store_id',
+        'base_shipping_tax_amount',
+        'base_discount_amount',
+        'grand_total',
+        'base_subtotal_incl_tax',
+        'shipping_amount',
+        'subtotal_incl_tax',
+        'base_shipping_amount',
+        'base_adjustment',
+        'base_subtotal',
+        'discount_amount',
+        'subtotal',
+        'adjustment',
+        'base_grand_total',
+        'base_tax_amount',
+        'shipping_tax_amount',
+        'tax_amount',
+        'order_id',
+        'state',
+        'increment_id',
+    ];
+
+    /**
+     * Set up
+     */
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * Test creditmemo get service
+     *
+     * @magentoApiDataFixture Magento/Sales/_files/creditmemo_for_get.php
+     */
+    public function testCreditmemoGet()
+    {
+        /** @var \Magento\Sales\Model\Resource\Order\Creditmemo\Collection $creditmemoCollection */
+        $creditmemoCollection = $this->objectManager->get('Magento\Sales\Model\Resource\Order\Creditmemo\Collection');
+        $creditmemo = $creditmemoCollection->getFirstItem();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $creditmemo->getId(),
+                'httpMethod' => Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'get',
+            ],
+        ];
+
+        $actual = $this->_webApiCall($serviceInfo, ['id' => $creditmemo->getId()]);
+        $expected = $creditmemo->getData();
+
+        foreach ($this->requiredFields as $field) {
+            $this->assertArrayHasKey($field, $actual);
+            $this->assertEquals($expected[$field], $actual[$field]);
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoListTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoListTest.php
new file mode 100644
index 00000000000..a3b4dd59b1c
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/CreditmemoListTest.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+/**
+ * Class CreditmemoListTest
+ */
+class CreditmemoListTest extends WebapiAbstract
+{
+    /**
+     * Resource path
+     */
+    const RESOURCE_PATH = '/V1/creditmemos';
+
+    /**
+     * Service read name
+     */
+    const SERVICE_READ_NAME = 'salesCreditmemoRepositoryV1';
+
+    /**
+     * Service version
+     */
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    /**
+     * Set up
+     */
+    protected function setUp()
+    {
+        $this->objectManager = Bootstrap::getObjectManager();
+    }
+
+    /**
+     * Test creditmemo list service
+     *
+     * @magentoApiDataFixture Magento/Sales/_files/creditmemo_with_list.php
+     */
+    public function testCreditmemoList()
+    {
+        /** @var $searchCriteriaBuilder  \Magento\Framework\Api\SearchCriteriaBuilder */
+        $searchCriteriaBuilder = $this->objectManager->create(
+            'Magento\Framework\Api\SearchCriteriaBuilder'
+        );
+
+        /** @var $filterBuilder  \Magento\Framework\Api\FilterBuilder */
+        $filterBuilder = $this->objectManager->create(
+            'Magento\Framework\Api\FilterBuilder'
+        );
+
+        $searchCriteriaBuilder->addFilter(
+            [
+                $filterBuilder
+                    ->setField('state')
+                    ->setValue(\Magento\Sales\Model\Order\Creditmemo::STATE_OPEN)
+                    ->create(),
+            ]
+        );
+        $searchData = $searchCriteriaBuilder->create()->__toArray();
+
+        $requestData = ['criteria' => $searchData];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '?' . http_build_query($requestData),
+                'httpMethod' => Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'getList',
+            ],
+        ];
+
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        // TODO Test fails, due to the inability of the framework API to handle data collection
+        $this->assertArrayHasKey('items', $result);
+        $this->assertCount(1, $result['items']);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceAddCommentTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceAddCommentTest.php
new file mode 100644
index 00000000000..d76ae8a2778
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceAddCommentTest.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\Sales\Api\Data\InvoiceCommentInterface;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+/**
+ * Class InvoiceAddCommentTest
+ */
+class InvoiceAddCommentTest extends WebapiAbstract
+{
+    /**
+     * Service read name
+     */
+    const SERVICE_READ_NAME = 'salesInvoiceCommentRepositoryV1';
+
+    /**
+     * Service version
+     */
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * Test invoice add comment service
+     *
+     * @magentoApiDataFixture Magento/Sales/_files/invoice.php
+     */
+    public function testInvoiceAddComment()
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var \Magento\Sales\Model\Order\Invoice $invoice */
+        $invoiceCollection = $objectManager->get('Magento\Sales\Model\Resource\Order\Invoice\Collection');
+        $invoice = $invoiceCollection->getFirstItem();
+
+        $commentData = [
+            InvoiceCommentInterface::COMMENT => 'Hello world!',
+            InvoiceCommentInterface::ENTITY_ID => null,
+            InvoiceCommentInterface::CREATED_AT => null,
+            InvoiceCommentInterface::PARENT_ID => $invoice->getId(),
+            InvoiceCommentInterface::IS_VISIBLE_ON_FRONT => true,
+            InvoiceCommentInterface::IS_CUSTOMER_NOTIFIED => true,
+        ];
+
+        $requestData = ['entity' => $commentData];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/invoice/comment',
+                'httpMethod' => Config::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'save',
+            ],
+        ];
+
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertNotEmpty($result);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceCaptureTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceCaptureTest.php
new file mode 100644
index 00000000000..ca013830487
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceCaptureTest.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+/**
+ * Class InvoiceCaptureTest
+ */
+class InvoiceCaptureTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+
+    const SERVICE_NAME = 'salesInvoiceManagementV1';
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/invoice.php
+     * @expectedException \Exception
+     */
+    public function testInvoiceCapture()
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var \Magento\Sales\Model\Order\Invoice $invoice */
+        $invoice = $objectManager->get('Magento\Sales\Model\Order\Invoice')->loadByIncrementId('100000001');
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/invoices/' . $invoice->getId() . '/capture',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'setCapture',
+            ],
+        ];
+        $requestData = ['id' => $invoice->getId()];
+        $this->_webApiCall($serviceInfo, $requestData);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceCommentsListTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceCommentsListTest.php
new file mode 100644
index 00000000000..1c5d7a5f343
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceCommentsListTest.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+/**
+ * Class InvoiceCommentsListTest
+ */
+class InvoiceCommentsListTest extends WebapiAbstract
+{
+    const SERVICE_NAME = 'salesInvoiceManagementV1';
+
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/invoice.php
+     */
+    public function testInvoiceCommentsList()
+    {
+        $comment = 'Test comment';
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+        /** @var \Magento\Sales\Model\Resource\Order\Invoice\Collection $invoiceCollection */
+        $invoiceCollection = $objectManager->get('Magento\Sales\Model\Resource\Order\Invoice\Collection');
+        $invoice = $invoiceCollection->getFirstItem();
+        $invoiceComment = $objectManager->get('Magento\Sales\Model\Order\Invoice\Comment');
+        $invoiceComment->setComment($comment);
+        $invoiceComment->setParentId($invoice->getId());
+        $invoiceComment->save();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/invoice/' . $invoice->getId() . '/comments',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'getCommentsList',
+            ],
+        ];
+        $requestData = ['id' => $invoice->getId()];
+        // TODO Test fails, due to the inability of the framework API to handle data collection
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        foreach ($result['items'] as $item) {
+            /** @var \Magento\Sales\Model\Order\Invoice\Comment $invoiceHistoryStatus */
+            $invoiceHistoryStatus = $objectManager->get('Magento\Sales\Model\Order\Invoice\Comment')
+                ->load($item['entity_id']);
+            $this->assertEquals($invoiceHistoryStatus->getComment(), $item['comment']);
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceCreateTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceCreateTest.php
new file mode 100644
index 00000000000..fc5600ccfa7
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceCreateTest.php
@@ -0,0 +1,127 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+/**
+ * Class InvoiceCreateTest
+ */
+class InvoiceCreateTest extends WebapiAbstract
+{
+    const RESOURCE_PATH = '/V1/invoice';
+
+    const SERVICE_READ_NAME = 'salesInvoiceRepositoryV1';
+
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/order.php
+     */
+    public function testInvoke()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => Config::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'save',
+            ],
+        ];
+        $orderItems = $order->getAllItems();
+        $data = [
+            'order_id' => $order->getId(),
+            'base_currency_code' => null,
+            'base_discount_amount' => null,
+            'base_grand_total' => null,
+            'base_hidden_tax_amount' => null,
+            'base_shipping_amount' => null,
+            'base_shipping_hidden_tax_amnt' => null,
+            'base_shipping_incl_tax' => null,
+            'base_shipping_tax_amount' => null,
+            'base_subtotal' => null,
+            'base_subtotal_incl_tax' => null,
+            'base_tax_amount' => null,
+            'base_total_refunded' => null,
+            'base_to_global_rate' => null,
+            'base_to_order_rate' => null,
+            'billing_address_id' => null,
+            'can_void_flag' => null,
+            'created_at' => null,
+            'discount_amount' => null,
+            'discount_description' => null,
+            'email_sent' => null,
+            'entity_id' => null,
+            'global_currency_code' => null,
+            'grand_total' => null,
+            'hidden_tax_amount' => null,
+            'increment_id' => null,
+            'is_used_for_refund' => null,
+            'order_currency_code' => null,
+            'shipping_address_id' => null,
+            'shipping_amount' => null,
+            'shipping_hidden_tax_amount' => null,
+            'shipping_incl_tax' => null,
+            'shipping_tax_amount' => null,
+            'state' => null,
+            'store_currency_code' => null,
+            'store_id' => null,
+            'store_to_base_rate' => null,
+            'store_to_order_rate' => null,
+            'subtotal' => null,
+            'subtotal_incl_tax' => null,
+            'tax_amount' => null,
+            'total_qty' => '1',
+            'transaction_id' => null,
+            'updated_at' => null,
+            'items' => [
+                [
+                    'orderItemId' => $orderItems[0]->getId(),
+                    'qty' => 2,
+                    'additionalData' => null,
+                    'baseCost' => null,
+                    'baseDiscountAmount' => null,
+                    'baseHiddenTaxAmount' => null,
+                    'basePrice' => null,
+                    'basePriceInclTax' => null,
+                    'baseRowTotal' => null,
+                    'baseRowTotalInclTax' => null,
+                    'baseTaxAmount' => null,
+                    'description' => null,
+                    'discountAmount' => null,
+                    'hiddenTaxAmount' => null,
+                    'name' => null,
+                    'entity_id' => null,
+                    'parentId' => null,
+                    'price' => null,
+                    'priceInclTax' => null,
+                    'productId' => null,
+                    'rowTotal' => null,
+                    'rowTotalInclTax' => null,
+                    'sku' => 'sku' . uniqid(),
+                    'taxAmount' => null,
+                ],
+            ],
+        ];
+        $result = $this->_webApiCall($serviceInfo, ['entity' => $data]);
+        $this->assertNotEmpty($result);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceEmailTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceEmailTest.php
new file mode 100644
index 00000000000..51ab88ff60a
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceEmailTest.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+/**
+ * Class InvoiceEmailTest
+ */
+class InvoiceEmailTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+
+    const SERVICE_NAME = 'salesInvoiceManagementV1';
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/invoice.php
+     */
+    public function testInvoiceEmail()
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $invoiceCollection = $objectManager->get('Magento\Sales\Model\Resource\Order\Invoice\Collection');
+        $invoice = $invoiceCollection->getFirstItem();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/invoice/' . $invoice->getId() . '/email',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'notify',
+            ],
+        ];
+        $requestData = ['id' => $invoice->getId()];
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertTrue($result);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceGetTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceGetTest.php
new file mode 100644
index 00000000000..5de3f1ff0a5
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceGetTest.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+/**
+ * Class InvoiceGetTest
+ */
+class InvoiceGetTest extends WebapiAbstract
+{
+    const RESOURCE_PATH = '/V1/invoice';
+
+    const SERVICE_READ_NAME = 'salesInvoiceRepositoryV1';
+
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/invoice.php
+     */
+    public function testInvoiceGet()
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var \Magento\Sales\Model\Order\Invoice $invoice */
+        $invoiceCollection = $objectManager->get('Magento\Sales\Model\Resource\Order\Invoice\Collection');
+        $invoice = $invoiceCollection->getFirstItem();
+        $expectedInvoiceData = [
+            'grand_total' => '100.0000',
+            'subtotal' => '100.0000',
+            'increment_id' => $invoice->getIncrementId(),
+        ];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $invoice->getId(),
+                'httpMethod' => Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'get',
+            ],
+        ];
+        $result = $this->_webApiCall($serviceInfo, ['id' => $invoice->getId()]);
+        foreach ($expectedInvoiceData as $field => $value) {
+            $this->assertArrayHasKey($field, $result);
+            $this->assertEquals($value, $result[$field]);
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceListTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceListTest.php
new file mode 100644
index 00000000000..ea0565c64bb
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceListTest.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+/**
+ * Class InvoiceListTest
+ */
+class InvoiceListTest extends WebapiAbstract
+{
+    const RESOURCE_PATH = '/V1/invoices';
+
+    const SERVICE_READ_NAME = 'salesInvoiceRepositoryV1';
+
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/invoice.php
+     */
+    public function testInvoiceList()
+    {
+        /** @var $searchCriteriaBuilder  \Magento\Framework\Api\SearchCriteriaBuilder */
+        $searchCriteriaBuilder = $this->objectManager->create(
+            'Magento\Framework\Api\SearchCriteriaBuilder'
+        );
+
+        /** @var $filterBuilder  \Magento\Framework\Api\FilterBuilder */
+        $filterBuilder = $this->objectManager->create(
+            'Magento\Framework\Api\FilterBuilder'
+        );
+
+        $searchCriteriaBuilder->addFilter(
+            [
+                $filterBuilder
+                    ->setField('state')
+                    ->setValue(2)
+                    ->create(),
+            ]
+        );
+        $searchData = $searchCriteriaBuilder->create()->__toArray();
+
+        $requestData = ['criteria' => $searchData];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '?' . http_build_query($requestData),
+                'httpMethod' => Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'getList',
+            ],
+        ];
+
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        // TODO Test fails, due to the inability of the framework API to handle data collection
+        $this->assertArrayHasKey('items', $result);
+        $this->assertCount(1, $result['items']);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceVoidTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceVoidTest.php
new file mode 100644
index 00000000000..58fe16154eb
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/InvoiceVoidTest.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+/**
+ * Class InvoiceVoidTest
+ */
+class InvoiceVoidTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+
+    const SERVICE_NAME = 'salesInvoiceManagementV1';
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/invoice.php
+     * @expectedException \Exception
+     */
+    public function testInvoiceVoid()
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var \Magento\Sales\Model\Order\Invoice $invoice */
+        $invoice = $objectManager->get('Magento\Sales\Model\Order\Invoice')->loadByIncrementId('100000001');
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/invoices/' . $invoice->getId() . '/void',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'setVoid',
+            ],
+        ];
+        $requestData = ['id' => $invoice->getId()];
+        $this->_webApiCall($serviceInfo, $requestData);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderAddressUpdateTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderAddressUpdateTest.php
new file mode 100644
index 00000000000..5b99a39ca69
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderAddressUpdateTest.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\Sales\Api\Data\OrderAddressInterface as OrderAddress;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+/**
+ * Class OrderAddressUpdateTest
+ */
+class OrderAddressUpdateTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+
+    const SERVICE_NAME = 'salesOrderAddressRepositoryV1';
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/order.php
+     */
+    public function testOrderAddressUpdate()
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $objectManager->get('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+
+        $address = [
+            OrderAddress::REGION => 'CA',
+            OrderAddress::POSTCODE => '11111',
+            OrderAddress::LASTNAME => 'lastname',
+            OrderAddress::STREET => ['street'],
+            OrderAddress::CITY => 'city',
+            OrderAddress::EMAIL => 'email@email.com',
+            OrderAddress::COMPANY => 'company',
+            OrderAddress::TELEPHONE => 't123456789',
+            OrderAddress::COUNTRY_ID => 'US',
+            OrderAddress::FIRSTNAME => 'firstname',
+            OrderAddress::ADDRESS_TYPE => 'billing',
+            OrderAddress::PARENT_ID => $order->getId(),
+            OrderAddress::ENTITY_ID => $order->getBillingAddressId(),
+            OrderAddress::CUSTOMER_ADDRESS_ID => null,
+            OrderAddress::CUSTOMER_ID => null,
+            OrderAddress::FAX => null,
+            OrderAddress::MIDDLENAME => null,
+            OrderAddress::PREFIX => null,
+            OrderAddress::QUOTE_ADDRESS_ID => null,
+            OrderAddress::REGION_ID => null,
+            OrderAddress::SUFFIX => null,
+            OrderAddress::VAT_ID => null,
+            OrderAddress::VAT_IS_VALID => null,
+            OrderAddress::VAT_REQUEST_DATE => null,
+            OrderAddress::VAT_REQUEST_ID => null,
+            OrderAddress::VAT_REQUEST_SUCCESS => null,
+        ];
+        $requestData = ['entity' => $address];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/order/' . $order->getId(),
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'save',
+            ],
+        ];
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertGreaterThan(1, count($result));
+
+        /** @var \Magento\Sales\Model\Order $actualOrder */
+        $actualOrder = $objectManager->get('Magento\Sales\Model\Order')->load($order->getId());
+        $billingAddress = $actualOrder->getBillingAddress();
+
+        $validate = [
+            OrderAddress::REGION => 'CA',
+            OrderAddress::POSTCODE => '11111',
+            OrderAddress::LASTNAME => 'lastname',
+            OrderAddress::STREET => 'street',
+            OrderAddress::CITY => 'city',
+            OrderAddress::EMAIL => 'email@email.com',
+            OrderAddress::COMPANY => 'company',
+            OrderAddress::TELEPHONE => 't123456789',
+            OrderAddress::COUNTRY_ID => 'US',
+            OrderAddress::FIRSTNAME => 'firstname',
+            OrderAddress::ADDRESS_TYPE => 'billing',
+            OrderAddress::PARENT_ID => $order->getId(),
+            OrderAddress::ENTITY_ID => $order->getBillingAddressId(),
+        ];
+        foreach ($validate as $key => $field) {
+            $this->assertEquals($validate[$key], $billingAddress->getData($key));
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderCancelTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderCancelTest.php
new file mode 100644
index 00000000000..39a1efd249f
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderCancelTest.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class OrderCancelTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+
+    const SERVICE_NAME = 'salesOrderManagementV1';
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/order.php
+     */
+    public function testOrderCancel()
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $order = $objectManager->get('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/order/' . $order->getId() . '/cancel',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'cancel',
+            ],
+        ];
+        $requestData = ['id' => $order->getId()];
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertTrue($result);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderCommentsListTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderCommentsListTest.php
new file mode 100644
index 00000000000..6137432d163
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderCommentsListTest.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class OrderCommentsListTest extends WebapiAbstract
+{
+    const SERVICE_NAME = 'salesOrderManagementV1';
+
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/order.php
+     */
+    public function testOrderCommentsList()
+    {
+        $comment = 'Test comment';
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $objectManager->get('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+        $history = $order->addStatusHistoryComment($comment, $order->getStatus());
+        $history->save();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/order/' . $order->getId() . '/comments',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'getCommentsList',
+            ],
+        ];
+        $requestData = ['id' => $order->getId()];
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        foreach ($result['items'] as $history) {
+            $orderHistoryStatus = $objectManager->get('Magento\Sales\Model\Order\Status\History')
+                ->load($history['entity_id']);
+            $this->assertEquals($orderHistoryStatus->getComment(), $history['comment']);
+            $this->assertEquals($orderHistoryStatus->getStatus(), $history['status']);
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderCreateTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderCreateTest.php
new file mode 100644
index 00000000000..9e7bd417de6
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderCreateTest.php
@@ -0,0 +1,128 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\Sales\Api\Data\OrderInterface;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+class OrderCreateTest extends WebapiAbstract
+{
+    const RESOURCE_PATH = '/V1/order';
+
+    const SERVICE_READ_NAME = 'salesOrderRepositoryV1';
+
+    const SERVICE_VERSION = 'V1';
+
+    const ORDER_INCREMENT_ID = '100000001';
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    protected function prepareOrder()
+    {
+        /** @var \Magento\Sales\Model\Order $orderBuilder */
+        $orderFactory = $this->objectManager->get('Magento\Sales\Model\OrderFactory');
+        /** @var \Magento\Sales\Service\V1\Data\OrderItemBuilder $orderItemBuilder */
+        $orderItemFactory = $this->objectManager->get('Magento\Sales\Model\Order\ItemFactory');
+        /** @var \Magento\Sales\Service\V1\Data\OrderPaymentBuilder $orderPaymentBuilder */
+        $orderPaymentFactory = $this->objectManager->get('Magento\Sales\Model\Order\PaymentFactory');
+        /** @var \Magento\Sales\Service\V1\Data\OrderAddressBuilder $orderAddressBuilder */
+        $orderAddressFactory = $this->objectManager->get('Magento\Sales\Model\Order\AddressFactory');
+
+        $order = $orderFactory->create(
+            ['data' => $this->getDataStructure('Magento\Sales\Api\Data\OrderInterface')]
+        );
+        $orderItem = $orderItemFactory->create(
+            ['data' => $this->getDataStructure('Magento\Sales\Api\Data\OrderItemInterface')]
+        );
+        $orderPayment = $orderPaymentFactory->create(
+            ['data' => $this->getDataStructure('Magento\Sales\Api\Data\OrderPaymentInterface')]
+        );
+        $orderAddressBilling = $orderAddressFactory->create(
+            ['data' => $this->getDataStructure('Magento\Sales\Api\Data\OrderAddressInterface')]
+        );
+
+        $email = uniqid() . 'email@example.com';
+        $orderItem->setSku('sku#1');
+        $orderPayment->setCcLast4('4444');
+        $orderPayment->setMethod('checkmo');
+        $orderPayment->setAccountStatus('ok');
+        $orderPayment->setAdditionalInformation([]);
+        $order->setCustomerEmail($email);
+        $order->setBaseGrandTotal(100);
+        $order->setGrandTotal(100);
+        $order->setItems([$orderItem->getData()]);
+        $order->setPayments([$orderPayment->getData()]);
+        $orderAddressBilling->setCity('City');
+        $orderAddressBilling->setPostcode('12345');
+        $orderAddressBilling->setLastname('Last Name');
+        $orderAddressBilling->setFirstname('First Name');
+        $orderAddressBilling->setTelephone('+00(000)-123-45-57');
+        $orderAddressBilling->setStreet(['Street']);
+        $orderAddressBilling->setCountryId(1);
+        $orderAddressBilling->setAddressType('billing');
+
+        $orderAddressShipping = $orderAddressFactory->create(
+            ['data' => $this->getDataStructure('Magento\Sales\Api\Data\OrderAddressInterface')]
+        );
+        $orderAddressShipping->setCity('City');
+        $orderAddressShipping->setPostcode('12345');
+        $orderAddressShipping->setLastname('Last Name');
+        $orderAddressShipping->setFirstname('First Name');
+        $orderAddressShipping->setTelephone('+00(000)-123-45-57');
+        $orderAddressShipping->setStreet(['Street']);
+        $orderAddressShipping->setCountryId(1);
+        $orderAddressShipping->setAddressType('shipping');
+
+        $orderData = $order->getData();
+        $orderData['billing_address'] = $orderAddressBilling->getData();
+        $orderData['billing_address']['street'] = ['Street'];
+        $orderData['shipping_address'] = $orderAddressShipping->getData();
+        $orderData['shipping_address']['street'] = ['Street'];
+        return $orderData;
+    }
+
+    protected function getDataStructure($className)
+    {
+        $refClass = new \ReflectionClass($className);
+        $constants = $refClass->getConstants();
+        $data = array_fill_keys($constants, null);
+        unset($data['custom_attributes']);
+        return $data;
+    }
+
+    public function testOrderCreate()
+    {
+        $order = $this->prepareOrder();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => Config::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'save',
+            ],
+        ];
+        $this->assertNotEmpty($this->_webApiCall($serviceInfo, ['entity' => $order]));
+
+        /** @var \Magento\Sales\Model\Order $model */
+        $model = $this->objectManager->get('Magento\Sales\Model\Order');
+        $model->load($order['customer_email'], 'customer_email');
+        $this->assertTrue((bool)$model->getId());
+        $this->assertEquals($order['base_grand_total'], $model->getBaseGrandTotal());
+        $this->assertEquals($order['grand_total'], $model->getGrandTotal());
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderEmailTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderEmailTest.php
new file mode 100644
index 00000000000..3bdb00820ba
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderEmailTest.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class OrderEmailTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+
+    const SERVICE_NAME = 'salesOrderManagementV1';
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/order.php
+     */
+    public function testOrderEmail()
+    {
+        $order = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
+            ->create('Magento\Sales\Model\Order');
+        $order->loadByIncrementId('100000001');
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/order/' . $order->getId() . '/email',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'notify',
+            ],
+        ];
+        $requestData = ['id' => $order->getId()];
+        $this->assertTrue($this->_webApiCall($serviceInfo, $requestData));
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderGetStatusTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderGetStatusTest.php
new file mode 100644
index 00000000000..97786a34970
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderGetStatusTest.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+/**
+ * Class OrderGetStatusTest
+ * @package Magento\Sales\Service\V1
+ */
+class OrderGetStatusTest extends WebapiAbstract
+{
+    const RESOURCE_PATH = '/V1/order/%d/status';
+
+    const SERVICE_READ_NAME = 'salesOrderManagementV1';
+
+    const SERVICE_VERSION = 'V1';
+
+    const ORDER_INCREMENT_ID = '100000001';
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/order.php
+     */
+    public function testOrderGetStatus()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order');
+        $order->loadByIncrementId(self::ORDER_INCREMENT_ID);
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => sprintf(self::RESOURCE_PATH, $order->getId()),
+                'httpMethod' => Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'getStatus',
+            ],
+        ];
+
+        $this->assertEquals($order->getStatus(), $this->_webApiCall($serviceInfo, ['id' => $order->getId()]));
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderGetTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderGetTest.php
new file mode 100644
index 00000000000..d9421a9d4cd
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderGetTest.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+class OrderGetTest extends WebapiAbstract
+{
+    const RESOURCE_PATH = '/V1/order';
+
+    const SERVICE_READ_NAME = 'salesOrderRepositoryV1';
+
+    const SERVICE_VERSION = 'V1';
+
+    const ORDER_INCREMENT_ID = '100000001';
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/order.php
+     */
+    public function testOrderGet()
+    {
+        $expectedOrderData = [
+            'base_subtotal' => '100.0000',
+            'subtotal' => '100.0000',
+            'customer_is_guest' => '1',
+            'increment_id' => self::ORDER_INCREMENT_ID,
+        ];
+        $expectedPayments = ['method' => 'checkmo'];
+        $expectedBillingAddressNotEmpty = [
+            'city',
+            'postcode',
+            'lastname',
+            'street',
+            'region',
+            'telephone',
+            'country_id',
+            'firstname',
+        ];
+
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order');
+        $order->loadByIncrementId(self::ORDER_INCREMENT_ID);
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $order->getId(),
+                'httpMethod' => Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'get',
+            ],
+        ];
+        $result = $this->_webApiCall($serviceInfo, ['id' => $order->getId()]);
+
+        foreach ($expectedOrderData as $field => $value) {
+            $this->assertArrayHasKey($field, $result);
+            $this->assertEquals($value, $result[$field]);
+        }
+
+        $this->assertArrayHasKey('payments', $result);
+        foreach ($expectedPayments as $field => $value) {
+            $paymentsKey = key($result['payments']);
+            $this->assertArrayHasKey($field, $result['payments'][$paymentsKey]);
+            $this->assertEquals($value, $result['payments'][$paymentsKey][$field]);
+        }
+
+        $this->assertArrayHasKey('billing_address', $result);
+        $this->assertArrayHasKey('shipping_address', $result);
+        foreach ($expectedBillingAddressNotEmpty as $field) {
+            $this->assertArrayHasKey($field, $result['billing_address']);
+            $this->assertArrayHasKey($field, $result['shipping_address']);
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderHoldTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderHoldTest.php
new file mode 100644
index 00000000000..a8bdc8e78a4
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderHoldTest.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class OrderHoldTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+
+    const SERVICE_NAME = 'salesOrderManagementV1';
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/order.php
+     */
+    public function testOrderHold()
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $order = $objectManager->get('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/order/' . $order->getId() . '/hold',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'hold',
+            ],
+        ];
+        $requestData = ['id' => $order->getId()];
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertTrue($result);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderListTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderListTest.php
new file mode 100644
index 00000000000..a0d9743fdbc
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderListTest.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+/**
+ * Class OrderListTest
+ * @package Magento\Sales\Service\V1
+ */
+class OrderListTest extends WebapiAbstract
+{
+    const RESOURCE_PATH = '/V1/orders';
+
+    const SERVICE_READ_NAME = 'salesOrderRepositoryV1';
+
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/order.php
+     */
+    public function testOrderList()
+    {
+        /** @var $searchCriteriaBuilder  \Magento\Framework\Api\SearchCriteriaBuilder */
+        $searchCriteriaBuilder = $this->objectManager->create(
+            'Magento\Framework\Api\SearchCriteriaBuilder'
+        );
+
+        /** @var $filterBuilder  \Magento\Framework\Api\FilterBuilder */
+        $filterBuilder = $this->objectManager->create(
+            'Magento\Framework\Api\FilterBuilder'
+        );
+
+        $searchCriteriaBuilder->addFilter(
+            [
+                $filterBuilder
+                    ->setField('status')
+                    ->setValue('processing')
+                    ->create(),
+            ]
+        );
+        $searchData = $searchCriteriaBuilder->create()->__toArray();
+
+        $requestData = ['criteria' => $searchData];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '?' . http_build_query($requestData),
+                'httpMethod' => Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'getList',
+            ],
+        ];
+
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertArrayHasKey('items', $result);
+        $this->assertCount(1, $result['items']);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderStatusHistoryAddTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderStatusHistoryAddTest.php
new file mode 100644
index 00000000000..c9a46103a9c
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderStatusHistoryAddTest.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\Sales\Api\Data\OrderStatusHistoryInterface;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+/**
+ * Class OrderCommentAddTest
+ * @package Magento\Sales\Service\V1
+ */
+class OrderStatusHistoryAddTest extends WebapiAbstract
+{
+    const SERVICE_READ_NAME = 'salesOrderManagementV1';
+
+    const SERVICE_VERSION = 'V1';
+
+    const ORDER_INCREMENT_ID = '100000001';
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/order.php
+     */
+    public function testOrderCommentAdd()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order');
+        $order->loadByIncrementId(self::ORDER_INCREMENT_ID);
+
+        $commentData = [
+            OrderStatusHistoryInterface::COMMENT => 'Hello',
+            OrderStatusHistoryInterface::ENTITY_ID => null,
+            OrderStatusHistoryInterface::IS_CUSTOMER_NOTIFIED => true,
+            OrderStatusHistoryInterface::CREATED_AT => null,
+            OrderStatusHistoryInterface::PARENT_ID => $order->getId(),
+            OrderStatusHistoryInterface::ENTITY_NAME => null,
+            OrderStatusHistoryInterface::STATUS => null,
+            OrderStatusHistoryInterface::IS_VISIBLE_ON_FRONT => true,
+        ];
+
+        $requestData = ['id' => $order->getId(), 'statusHistory' => $commentData];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/order/' . $order->getId() . '/comment',
+                'httpMethod' => Config::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'addComment',
+            ],
+        ];
+
+        $this->_webApiCall($serviceInfo, $requestData);
+
+        //Verification
+        $comments = $order->load($order->getId())->getAllStatusHistory();
+
+        $commentData = reset($comments);
+        foreach ($commentData as $key => $value) {
+            $this->assertEquals($commentData[OrderStatusHistoryInterface::COMMENT], $statusHistoryComment->getComment());
+            $this->assertEquals($commentData[OrderStatusHistoryInterface::PARENT_ID], $statusHistoryComment->getParentId());
+            $this->assertEquals(
+                $commentData[OrderStatusHistoryInterface::IS_CUSTOMER_NOTIFIED], $statusHistoryComment->getIsCustomerNotified()
+            );
+            $this->assertEquals(
+                $commentData[OrderStatusHistoryInterface::IS_VISIBLE_ON_FRONT], $statusHistoryComment->getIsVisibleOnFront()
+            );
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderUnHoldTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderUnHoldTest.php
new file mode 100644
index 00000000000..41d877f25b7
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/OrderUnHoldTest.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class OrderUnHoldTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+
+    const SERVICE_NAME = 'salesOrderManagementV1';
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/order.php
+     */
+    public function testOrderUnHold()
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $objectManager->get('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+        if ($order->canHold()) {
+            $order->hold()->save();
+        }
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/order/' . $order->getId() . '/unhold',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'unHold',
+            ],
+        ];
+        $requestData = ['id' => $order->getId()];
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertTrue($result);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentAddCommentTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentAddCommentTest.php
new file mode 100644
index 00000000000..dbdd8768fce
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentAddCommentTest.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\Sales\Api\Data\ShipmentCommentInterface;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+/**
+ * Class ShipmentAddCommentTest
+ */
+class ShipmentAddCommentTest extends WebapiAbstract
+{
+    /**
+     * Service read name
+     */
+    const SERVICE_READ_NAME = 'salesShipmentCommentRepositoryV1';
+
+    /**
+     * Service version
+     */
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * Shipment increment id
+     */
+    const SHIPMENT_INCREMENT_ID = '100000001';
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * Test shipment add comment service
+     *
+     * @magentoApiDataFixture Magento/Sales/_files/shipment.php
+     */
+    public function testShipmentAddComment()
+    {
+        /** @var \Magento\Sales\Model\Resource\Order\Shipment\Collection $shipmentCollection */
+        $shipmentCollection = $this->objectManager->get('Magento\Sales\Model\Resource\Order\Shipment\Collection');
+        $shipment = $shipmentCollection->getFirstItem();
+
+        $commentData = [
+            ShipmentCommentInterface::COMMENT => 'Hello world!',
+            ShipmentCommentInterface::ENTITY_ID => null,
+            ShipmentCommentInterface::CREATED_AT => null,
+            ShipmentCommentInterface::PARENT_ID => $shipment->getId(),
+            ShipmentCommentInterface::IS_VISIBLE_ON_FRONT => true,
+            ShipmentCommentInterface::IS_CUSTOMER_NOTIFIED => true,
+        ];
+
+        $requestData = ['entity' => $commentData];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/shipment/comment',
+                'httpMethod' => Config::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'save',
+            ],
+        ];
+
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertNotEmpty($result);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentAddTrackTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentAddTrackTest.php
new file mode 100644
index 00000000000..af1e624793a
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentAddTrackTest.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\Sales\Api\Data\ShipmentTrackInterface;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+/**
+ * Class ShipmentAddTrackTest
+ */
+class ShipmentAddTrackTest extends WebapiAbstract
+{
+    /**
+     * Service read name
+     */
+    const SERVICE_READ_NAME = 'salesShipmentTrackRepositoryV1';
+
+    /**
+     * Service version
+     */
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * Shipment increment id
+     */
+    const SHIPMENT_INCREMENT_ID = '100000001';
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * Test shipment add track service
+     *
+     * @magentoApiDataFixture Magento/Sales/_files/shipment.php
+     */
+    public function testShipmentAddTrack()
+    {
+        /** @var \Magento\Sales\Model\Order\Shipment $shipment */
+        $shipmentCollection = $this->objectManager->get('Magento\Sales\Model\Resource\Order\Shipment\Collection');
+        $shipment = $shipmentCollection->getFirstItem();
+
+        $trackData = [
+            ShipmentTrackInterface::ENTITY_ID => null,
+            ShipmentTrackInterface::ORDER_ID => $shipment->getOrderId(),
+            ShipmentTrackInterface::CREATED_AT => null,
+            ShipmentTrackInterface::PARENT_ID => $shipment->getId(),
+            ShipmentTrackInterface::WEIGHT => 20,
+            ShipmentTrackInterface::QTY => 5,
+            ShipmentTrackInterface::TRACK_NUMBER => 2,
+            ShipmentTrackInterface::DESCRIPTION => 'Shipment description',
+            ShipmentTrackInterface::TITLE => 'Shipment title',
+            ShipmentTrackInterface::CARRIER_CODE => \Magento\Sales\Model\Order\Shipment\Track::CUSTOM_CARRIER_CODE,
+            ShipmentTrackInterface::CREATED_AT => null,
+            ShipmentTrackInterface::UPDATED_AT => null,
+        ];
+
+        $requestData = ['entity' => $trackData];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/shipment/track',
+                'httpMethod' => Config::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'save',
+            ],
+        ];
+
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertNotEmpty($result);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentCommentsListTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentCommentsListTest.php
new file mode 100644
index 00000000000..ea79127aee8
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentCommentsListTest.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+/**
+ * Class ShipmentCommentsListTest
+ */
+class ShipmentCommentsListTest extends WebapiAbstract
+{
+    const SERVICE_NAME = 'salesShipmentManagementV1';
+
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/shipment.php
+     */
+    public function testShipmentCommentsList()
+    {
+        $comment = 'Test comment';
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+        /** @var \Magento\Sales\Model\Resource\Order\Shipment\Collection $shipmentCollection */
+        $shipmentCollection = $objectManager->get('Magento\Sales\Model\Resource\Order\Shipment\Collection');
+        $shipment = $shipmentCollection->getFirstItem();
+        $shipmentComment = $objectManager->get('Magento\Sales\Model\Order\Shipment\Comment');
+        $shipmentComment->setComment($comment);
+        $shipmentComment->setParentId($shipment->getId());
+        $shipmentComment->save();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/shipment/' . $shipment->getId() . '/comments',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'getCommentsList',
+            ],
+        ];
+        $requestData = ['id' => $shipment->getId()];
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        // TODO Test fails, due to the inability of the framework API to handle data collection
+        foreach ($result['items'] as $item) {
+            /** @var \Magento\Sales\Model\Order\Shipment\Comment $shipmentHistoryStatus */
+            $shipmentHistoryStatus = $objectManager->get('Magento\Sales\Model\Order\Shipment\Comment')
+                ->load($item['entity_id']);
+            $this->assertEquals($shipmentHistoryStatus->getComment(), $item['comment']);
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentCreateTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentCreateTest.php
new file mode 100644
index 00000000000..b73cd43ee82
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentCreateTest.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+/**
+ * Class ShipmentCreateTest
+ */
+class ShipmentCreateTest extends WebapiAbstract
+{
+    const RESOURCE_PATH = '/V1/shipment';
+
+    const SERVICE_READ_NAME = 'salesShipmentRepositoryV1';
+
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/order.php
+     */
+    public function testInvoke()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+        $orderItem = current($order->getAllItems());
+        $items = [
+            [
+                'order_item_id' => $orderItem->getId(),
+                'qty' => $orderItem->getQtyOrdered(),
+                'additional_data' => null,
+                'description' => null,
+                'entity_id' => null,
+                'name' => null,
+                'parent_id' => null,
+                'price' => null,
+                'product_id' => null,
+                'row_total' => null,
+                'sku' => null,
+                'weight' => null,
+            ],
+        ];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => Config::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'save',
+            ],
+        ];
+        $data = [
+            'order_id' => $order->getId(),
+            'entity_id' => null,
+            'store_id' => null,
+            'total_weight' => null,
+            'total_qty' => null,
+            'email_sent' => null,
+            'customer_id' => null,
+            'shipping_address_id' => null,
+            'billing_address_id' => null,
+            'shipment_status' => null,
+            'increment_id' => null,
+            'created_at' => null,
+            'updated_at' => null,
+//            'packages' => null,
+            'shipping_label' => null,
+            'tracks' => [],
+            'items' => $items,
+            'comments' => [],
+        ];
+        $result = $this->_webApiCall($serviceInfo, ['entity' => $data]);
+        $this->assertNotEmpty($result);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentEmailTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentEmailTest.php
new file mode 100644
index 00000000000..3329e8addf0
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentEmailTest.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+/**
+ * Class ShipmentEmailTest
+ */
+class ShipmentEmailTest extends WebapiAbstract
+{
+    const SERVICE_VERSION = 'V1';
+
+    const SERVICE_NAME = 'salesShipmentManagementV1';
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/shipment.php
+     */
+    public function testShipmentEmail()
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $shipmentCollection = $objectManager->get('Magento\Sales\Model\Resource\Order\Shipment\Collection');
+        $shipment = $shipmentCollection->getFirstItem();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/shipment/' . $shipment->getId() . '/email',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'notify',
+            ],
+        ];
+        $requestData = ['id' => $shipment->getId()];
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertTrue($result);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentGetTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentGetTest.php
new file mode 100644
index 00000000000..5bc2a21698d
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentGetTest.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+/**
+ * Class ShipmentGetTest
+ */
+class ShipmentGetTest extends WebapiAbstract
+{
+    const RESOURCE_PATH = '/V1/shipment';
+    const SERVICE_READ_NAME = 'salesShipmentRepositoryV1';
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/shipment.php
+     */
+    public function testShipmentGet()
+    {
+        /** @var \Magento\Sales\Model\Order\Shipment $shipment */
+        $shipmentCollection = $this->objectManager->get('Magento\Sales\Model\Resource\Order\Shipment\Collection');
+        $shipment = $shipmentCollection->getFirstItem();
+        $shipment->load($shipment->getId());
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $shipment->getId(),
+                'httpMethod' => Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'get',
+            ],
+        ];
+        $result = $this->_webApiCall($serviceInfo, ['id' => $shipment->getId()]);
+        $data = $result;
+        $this->assertArrayHasKey('items', $result);
+        $this->assertArrayHasKey('tracks', $result);
+        unset($data['items']);
+        unset($data['packages']);
+        unset($data['tracks']);
+        foreach ($data as $key => $value) {
+            if (!empty($value)) {
+                $this->assertEquals($shipment->getData($key), $value, $key);
+            }
+        }
+        $shipmentItem = $this->objectManager->get('Magento\Sales\Model\Order\Shipment\Item');
+        foreach ($result['items'] as $item) {
+            $shipmentItem->load($item['entity_id']);
+            foreach ($item as $key => $value) {
+                $this->assertEquals($shipmentItem->getData($key), $value, $key);
+            }
+        }
+        $shipmentTrack = $this->objectManager->get('Magento\Sales\Model\Order\Shipment\Track');
+        foreach ($result['tracks'] as $item) {
+            $shipmentTrack->load($item['entity_id']);
+            foreach ($item as $key => $value) {
+                $this->assertEquals($shipmentTrack->getData($key), $value, $key);
+            }
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentLabelGetTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentLabelGetTest.php
new file mode 100644
index 00000000000..f03bad65a11
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentLabelGetTest.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+/**
+ * Class ShipmentLabelGetTest
+ */
+class ShipmentLabelGetTest extends WebapiAbstract
+{
+    const RESOURCE_PATH = '/V1/shipment';
+    const SERVICE_READ_NAME = 'salesShipmentManagementV1';
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/shipment.php
+     */
+    public function testShipmentGet()
+    {
+        /** @var \Magento\Sales\Model\Order\Shipment $shipment */
+        $shipmentCollection = $this->objectManager->get('Magento\Sales\Model\Resource\Order\Shipment\Collection');
+        $shipment = $shipmentCollection->getFirstItem();
+        $shipment->setShippingLabel('test_shipping_label');
+        $shipment->save();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $shipment->getId() . '/label',
+                'httpMethod' => Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'getLabel',
+            ],
+        ];
+        $result = $this->_webApiCall($serviceInfo, ['id' => $shipment->getId()]);
+        $this->assertEquals($result, 'test_shipping_label');
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentListTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentListTest.php
new file mode 100644
index 00000000000..b68d6900eab
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentListTest.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+/**
+ * Class ShipmentListTest
+ */
+class ShipmentListTest extends WebapiAbstract
+{
+    const RESOURCE_PATH = '/V1/shipments';
+
+    const SERVICE_READ_NAME = 'salesShipmentRepositoryV1';
+
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Sales/_files/shipment.php
+     */
+    public function testShipmentList()
+    {
+        /** @var $searchCriteriaBuilder  \Magento\Framework\Api\SearchCriteriaBuilder */
+        $searchCriteriaBuilder = $this->objectManager->create(
+            'Magento\Framework\Api\SearchCriteriaBuilder'
+        );
+
+        /** @var $filterBuilder  \Magento\Framework\Api\FilterBuilder */
+        $filterBuilder = $this->objectManager->create(
+            'Magento\Framework\Api\FilterBuilder'
+        );
+
+        $searchCriteriaBuilder->addFilter([$filterBuilder->setField('shipment_status')->setValue(1)->create()]);
+        $searchData = $searchCriteriaBuilder->create()->__toArray();
+
+        $requestData = ['criteria' => $searchData];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '?' . http_build_query($requestData),
+                'httpMethod' => Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'getList',
+            ],
+        ];
+
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        // TODO Test fails, due to the inability of the framework API to handle data collection
+        $this->assertArrayHasKey('items', $result);
+        $this->assertCount(1, $result['items']);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentRemoveTrackTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentRemoveTrackTest.php
new file mode 100644
index 00000000000..4dc7637b37d
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/ShipmentRemoveTrackTest.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Sales\Service\V1;
+
+use Magento\Sales\Api\Data\ShipmentTrackInterface;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+/**
+ * Class ShipmentRemoveTrackTest
+ */
+class ShipmentRemoveTrackTest extends WebapiAbstract
+{
+    /**
+     * Service read name
+     */
+    const SERVICE_READ_NAME = 'salesShipmentTrackRepositoryV1';
+
+    /**
+     * Service version
+     */
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * Shipment increment id
+     */
+    const SHIPMENT_INCREMENT_ID = '100000001';
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * Test shipment remove track service
+     *
+     * @magentoApiDataFixture Magento/Sales/_files/shipment.php
+     */
+    public function testShipmentRemoveTrack()
+    {
+        /** @var \Magento\Sales\Model\Order\Shipment $shipment */
+        $shipmentCollection = $this->objectManager->get('Magento\Sales\Model\Resource\Order\Shipment\Collection');
+        $shipment = $shipmentCollection->getFirstItem();
+
+        /** @var \Magento\Sales\Model\Order\Shipment\Track $track */
+        $track = $this->objectManager->create('Magento\Sales\Model\Order\Shipment\TrackFactory')->create();
+        $track->addData(
+            [
+                ShipmentTrackInterface::ENTITY_ID => null,
+                ShipmentTrackInterface::ORDER_ID => 12,
+                ShipmentTrackInterface::CREATED_AT => null,
+                ShipmentTrackInterface::PARENT_ID => $shipment->getId(),
+                ShipmentTrackInterface::WEIGHT => 20,
+                ShipmentTrackInterface::QTY => 5,
+                ShipmentTrackInterface::TRACK_NUMBER => 2,
+                ShipmentTrackInterface::DESCRIPTION => 'Shipment description',
+                ShipmentTrackInterface::TITLE => 'Shipment title',
+                ShipmentTrackInterface::CARRIER_CODE => \Magento\Sales\Model\Order\Shipment\Track::CUSTOM_CARRIER_CODE,
+                ShipmentTrackInterface::CREATED_AT => null,
+                ShipmentTrackInterface::UPDATED_AT => null,
+            ]
+        );
+        $track->save();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/shipment/track/' . $track->getId(),
+                'httpMethod' => Config::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'deleteById',
+            ],
+        ];
+
+        $result = $this->_webApiCall($serviceInfo, ['id' => $track->getId()]);
+        $this->assertNotEmpty($result);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/TransactionTest.php b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/TransactionTest.php
new file mode 100644
index 00000000000..2138fd6a6af
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Sales/Service/V1/TransactionTest.php
@@ -0,0 +1,190 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Sales\Service\V1;
+
+use Magento\Sales\Model\Order;
+use Magento\Sales\Model\Order\Payment;
+use Magento\Sales\Model\Order\Payment\Transaction;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config;
+
+/**
+ * Class TransactionReadTest
+ */
+class TransactionTest extends WebapiAbstract
+{
+    /**
+     * Service read name
+     */
+    const SERVICE_READ_NAME = 'salesTransactionRepositoryV1';
+
+    /**
+     * Resource path for REST
+     */
+    const RESOURCE_PATH = '/V1/transactions';
+
+    /**
+     * Service version
+     */
+    const SERVICE_VERSION = 'V1';
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * Tests list of order transactions
+     *
+     * @magentoApiDataFixture Magento/Sales/_files/transactions_detailed.php
+     */
+    public function testTransactionGet()
+    {
+        /** @var Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order');
+        $order->loadByIncrementId('100000006');
+
+        /** @var Payment $payment */
+        $payment = $order->getPayment();
+        /** @var Transaction $transaction */
+        $transaction = $payment->getTransaction('trx_auth');
+
+        $childTransactions = $transaction->getChildTransactions();
+        $childTransaction = reset($childTransactions);
+
+        $expectedData = $this->getPreparedTransactionData($transaction);
+        $childTransactionData = $this->getPreparedTransactionData($childTransaction);
+        $expectedData['child_transactions'][] = $childTransactionData;
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $transaction->getId(),
+                'httpMethod' => Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'get',
+            ],
+        ];
+        $result = $this->_webApiCall($serviceInfo, ['id' => $transaction->getId()]);
+        ksort($expectedData);
+        ksort($result);
+        $this->assertEquals($expectedData, $result);
+    }
+
+    /**
+     * Tests list of order transactions
+     * @dataProvider filtersDataProvider
+     */
+    public function testTransactionList($filters)
+    {
+        /** @var Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order');
+        $order->loadByIncrementId('100000006');
+
+        /** @var Payment $payment */
+        $payment = $order->getPayment();
+        /** @var Transaction $transaction */
+        $transaction = $payment->getTransaction('trx_auth');
+
+        $childTransactions = $transaction->getChildTransactions();
+
+        $childTransaction = reset($childTransactions);
+
+        /** @var $searchCriteriaBuilder  \Magento\Framework\Api\SearchCriteriaBuilder */
+        $searchCriteriaBuilder = $this->objectManager->create(
+            'Magento\Framework\Api\SearchCriteriaBuilder'
+        );
+
+        $searchCriteriaBuilder->addFilter($filters);
+        $searchData = $searchCriteriaBuilder->create()->__toArray();
+
+        $requestData = ['criteria' => $searchData];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '?' . http_build_query($requestData),
+                'httpMethod' => Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_READ_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_READ_NAME . 'getList',
+            ],
+        ];
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+
+        $this->assertArrayHasKey('items', $result);
+
+        $transactionData = $this->getPreparedTransactionData($transaction);
+        $childTransactionData = $this->getPreparedTransactionData($childTransaction);
+        $transactionData['child_transactions'][] = $childTransactionData;
+        $expectedData = [$transactionData, $childTransactionData];
+
+        $this->assertEquals($expectedData, $result['items']);
+    }
+
+    /**
+     * @param Transaction $transaction
+     * @return array
+     */
+    private function getPreparedTransactionData(Transaction $transaction)
+    {
+        $additionalInfo = [];
+        foreach ($transaction->getAdditionalInformation() as $value) {
+            $additionalInfo[] = $value;
+        }
+
+        $expectedData = ['transaction_id' => (int)$transaction->getId()];
+
+        if (!is_null($transaction->getParentId())) {
+            $expectedData['parent_id'] = (int)$transaction->getParentId();
+        }
+
+        $expectedData = array_merge(
+            $expectedData,
+            [
+                'order_id' => (int)$transaction->getOrderId(),
+                'payment_id' => (int)$transaction->getPaymentId(),
+                'txn_id' => $transaction->getTxnId(),
+                'parent_txn_id' => ($transaction->getParentTxnId() ? (string)$transaction->getParentTxnId() : ''),
+                'txn_type' => $transaction->getTxnType(),
+                'is_closed' => (int)$transaction->getIsClosed(),
+                'additional_information' => ['data'],
+                'created_at' => $transaction->getCreatedAt(),
+                'child_transactions' => [],
+            ]
+        );
+
+        return $expectedData;
+    }
+
+    /**
+     * @return array
+     */
+    public function filtersDataProvider()
+    {
+        /** @var $filterBuilder  \Magento\Framework\Api\FilterBuilder */
+        $filterBuilder = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            'Magento\Framework\Api\FilterBuilder'
+        );
+
+        return [
+            [
+                [
+                    $filterBuilder->setField('created_at')->setValue('2020-12-12 00:00:00')
+                        ->setConditionType('lteq')->create(),
+                ],
+            ]
+        ];
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxClassRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxClassRepositoryTest.php
new file mode 100644
index 00000000000..4a462cbc3fb
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxClassRepositoryTest.php
@@ -0,0 +1,309 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Tax\Api;
+
+use Magento\Framework\Api\FilterBuilder;
+use Magento\Framework\Api\SearchCriteriaBuilder;
+use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Tax\Api\Data\TaxClassDataBuilder;
+use Magento\Tax\Model\ClassModelRegistry;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+/**
+ * Tests for tax class service.
+ */
+class TaxClassRepositoryTest extends WebapiAbstract
+{
+    const SERVICE_NAME = 'taxTaxClassRepositoryV1';
+    const SERVICE_VERSION = 'V1';
+    const RESOURCE_PATH = '/V1/taxClass';
+
+    /** @var SearchCriteriaBuilder */
+    private $searchCriteriaBuilder;
+
+    /** @var FilterBuilder */
+    private $filterBuilder;
+
+    /** @var TaxClassDataBuilder */
+    private $taxClassBuilder;
+
+    /** @var TaxClassRepositoryInterface */
+    private $taxClassRepository;
+
+    /** @var ClassModelRegistry */
+    private $taxClassRegistry;
+
+    const SAMPLE_TAX_CLASS_NAME = 'Wholesale Customer';
+
+    /**
+     * Execute per test initialization.
+     */
+    public function setUp()
+    {
+        $this->searchCriteriaBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\Framework\Api\SearchCriteriaBuilder'
+        );
+        $this->filterBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\Framework\Api\FilterBuilder'
+        );
+        $this->taxClassBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\Tax\Api\Data\TaxClassDataBuilder'
+        );
+        $this->taxClassRegistry = Bootstrap::getObjectManager()->create(
+            'Magento\Tax\Model\ClassModelRegistry'
+        );
+        $this->taxClassRepository = Bootstrap::getObjectManager()->create(
+            'Magento\Tax\Model\TaxClass\Repository',
+            ['classModelRegistry' => $this->taxClassRegistry]
+        );
+    }
+
+    /**
+     * Test create Data\TaxClassInterface
+     */
+    public function testCreateTaxClass()
+    {
+        $taxClassName = self::SAMPLE_TAX_CLASS_NAME . uniqid();
+        /** @var  \Magento\Tax\Api\Data\TaxClassInterface $taxClassDataObject */
+        $taxClassDataObject = $this->taxClassBuilder->setClassName($taxClassName)
+            ->setClassType(TaxClassManagementInterface::TYPE_CUSTOMER)
+            ->create();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+
+        $requestData = ['taxClass' => [
+                'class_id' => $taxClassDataObject->getClassId(),
+                'class_name' => $taxClassDataObject->getClassName(),
+                'class_type' => $taxClassDataObject->getClassType(),
+            ],
+        ];
+        $taxClassId = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertNotNull($taxClassId);
+
+        //Verify by getting the Data\TaxClassInterface
+        $taxClassData = $this->taxClassRepository->get($taxClassId);
+        $this->assertEquals($taxClassData->getClassName(), $taxClassName);
+        $this->assertEquals($taxClassData->getClassType(), TaxClassManagementInterface::TYPE_CUSTOMER);
+    }
+
+    /**
+     * Test create Data\TaxClassInterface
+     */
+    public function testUpdateTaxClass()
+    {
+        //Create Tax Class
+        $taxClassDataObject = $this->taxClassBuilder->setClassName(self::SAMPLE_TAX_CLASS_NAME . uniqid())
+            ->setClassType(TaxClassManagementInterface::TYPE_CUSTOMER)
+            ->create();
+        $taxClassId = $this->taxClassRepository->save($taxClassDataObject);
+        $this->assertNotNull($taxClassId);
+
+        //Update Tax Class
+        $updatedTaxClassName = self::SAMPLE_TAX_CLASS_NAME . uniqid();
+        $updatedTaxClassDataObject = $this->taxClassBuilder
+            ->populate($taxClassDataObject)
+            ->setClassName($updatedTaxClassName)
+            ->create();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $taxClassId,
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+
+        $taxClass = [
+                'class_id' => $updatedTaxClassDataObject->getClassId(),
+                'class_name' => $updatedTaxClassDataObject->getClassName(),
+                'class_type' => $updatedTaxClassDataObject->getClassType(),
+            ];
+
+        $requestData = ['taxClass' => $taxClass, 'ClassId' => $taxClassId];
+
+        $this->assertEquals($taxClassId, $this->_webApiCall($serviceInfo, $requestData));
+
+        //Verify by getting the Data\TaxClassInterface
+        $this->taxClassRegistry->remove($taxClassId);
+        $taxClassData = $this->taxClassRepository->get($taxClassId);
+        $this->assertEquals($taxClassData->getClassName(), $updatedTaxClassName);
+    }
+
+    public function testGetTaxClass()
+    {
+        //Create Tax Class
+        $taxClassName = self::SAMPLE_TAX_CLASS_NAME . uniqid();
+        $taxClassDataObject = $this->taxClassBuilder->setClassName($taxClassName)
+            ->setClassType(TaxClassManagementInterface::TYPE_CUSTOMER)
+            ->create();
+        $taxClassId = $this->taxClassRepository->save($taxClassDataObject);
+        $this->assertNotNull($taxClassId);
+
+        //Verify by getting the Data\TaxClassInterface
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $taxClassId,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Get',
+            ],
+        ];
+        $requestData = ['taxClassId' => $taxClassId];
+        $taxClassData = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals($taxClassData[Data\TaxClassInterface::KEY_NAME], $taxClassName);
+        $this->assertEquals(
+            $taxClassData[Data\TaxClassInterface::KEY_TYPE],
+            TaxClassManagementInterface::TYPE_CUSTOMER
+        );
+    }
+
+    /**
+     * Test delete Tax class
+     */
+    public function testDeleteTaxClass()
+    {
+        $taxClassDataObject = $this->taxClassBuilder->setClassName(self::SAMPLE_TAX_CLASS_NAME . uniqid())
+            ->setClassType(TaxClassManagementInterface::TYPE_CUSTOMER)
+            ->create();
+        $taxClassId = $this->taxClassRepository->save($taxClassDataObject);
+        $this->assertNotNull($taxClassId);
+
+        //Verify by getting the Data\TaxClassInterface
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/' . $taxClassId,
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'DeleteById',
+            ],
+        ];
+        $requestData = ['taxClassId' => $taxClassId];
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertTrue($result);
+
+        try {
+            $this->taxClassRegistry->remove($taxClassId);
+            $this->taxClassRepository->get($taxClassId);
+            $this->fail("Tax class was not expected to be returned after being deleted.");
+        } catch (NoSuchEntityException $e) {
+            $this->assertEquals('No such entity with class_id = ' . $taxClassId, $e->getMessage());
+        }
+    }
+
+    /**
+     * Test with a single filter
+     */
+    public function testSearchTaxClass()
+    {
+        $taxClassName = 'Retail Customer';
+        $taxClassNameField = Data\TaxClassInterface::KEY_NAME;
+        $filter = $this->filterBuilder->setField($taxClassNameField)
+            ->setValue($taxClassName)
+            ->create();
+        $this->searchCriteriaBuilder->addFilter([$filter]);
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/search',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetList',
+            ],
+        ];
+        $searchData = $this->searchCriteriaBuilder->create()->__toArray();
+        $requestData = ['searchCriteria' => $searchData];
+        $searchResults = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(1, $searchResults['total_count']);
+        $this->assertEquals($taxClassName, $searchResults['items'][0][$taxClassNameField]);
+    }
+
+    /**
+     * Test using multiple filters
+     */
+    public function testSearchTaxClassMultipleFilterGroups()
+    {
+        $productTaxClass = [
+            Data\TaxClassInterface::KEY_NAME => 'Taxable Goods',
+            Data\TaxClassInterface::KEY_TYPE => 'PRODUCT',
+        ];
+        $customerTaxClass = [Data\TaxClassInterface::KEY_NAME => 'Retail Customer',
+            Data\TaxClassInterface::KEY_TYPE => 'CUSTOMER', ];
+
+        $filter1 = $this->filterBuilder->setField(Data\TaxClassInterface::KEY_NAME)
+            ->setValue($productTaxClass[Data\TaxClassInterface::KEY_NAME])
+            ->create();
+        $filter2 = $this->filterBuilder->setField(Data\TaxClassInterface::KEY_NAME)
+            ->setValue($customerTaxClass[Data\TaxClassInterface::KEY_NAME])
+            ->create();
+        $filter3 = $this->filterBuilder->setField(Data\TaxClassInterface::KEY_TYPE)
+            ->setValue($productTaxClass[Data\TaxClassInterface::KEY_TYPE])
+            ->create();
+        $filter4 = $this->filterBuilder->setField(Data\TaxClassInterface::KEY_TYPE)
+            ->setValue($customerTaxClass[Data\TaxClassInterface::KEY_TYPE])
+            ->create();
+
+        /**
+         * (class_name == 'Retail Customer' || class_name == 'Taxable Goods)
+         * && ( class_type == 'CUSTOMER' || class_type == 'PRODUCT')
+         */
+        $this->searchCriteriaBuilder->addFilter([$filter1, $filter2]);
+        $this->searchCriteriaBuilder->addFilter([$filter3, $filter4]);
+        $searchCriteria = $this->searchCriteriaBuilder->setCurrentPage(1)->setPageSize(10)->create();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/search',
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetList',
+            ],
+        ];
+        $searchData = $searchCriteria->__toArray();
+        $requestData = ['searchCriteria' => $searchData];
+        $searchResults = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(2, $searchResults['total_count']);
+        $this->assertEquals($productTaxClass[Data\TaxClassInterface::KEY_NAME],
+            $searchResults['items'][0][Data\TaxClassInterface::KEY_NAME]);
+        $this->assertEquals($customerTaxClass[Data\TaxClassInterface::KEY_NAME],
+            $searchResults['items'][1][Data\TaxClassInterface::KEY_NAME]);
+
+        /** class_name == 'Retail Customer' && ( class_type == 'CUSTOMER' || class_type == 'PRODUCT') */
+        $this->searchCriteriaBuilder->addFilter([$filter2]);
+        $this->searchCriteriaBuilder->addFilter([$filter3, $filter4]);
+        $searchCriteria = $this->searchCriteriaBuilder->create();
+        $searchData = $searchCriteria->__toArray();
+        $requestData = ['searchCriteria' => $searchData];
+        $searchResults = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(1, $searchResults['total_count']);
+        $this->assertEquals($customerTaxClass[Data\TaxClassInterface::KEY_NAME],
+            $searchResults['items'][0][Data\TaxClassInterface::KEY_NAME]);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRateRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRateRepositoryTest.php
new file mode 100644
index 00000000000..0122bdfa3d7
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRateRepositoryTest.php
@@ -0,0 +1,660 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Tax\Api;
+
+use Magento\Framework\Api\FilterBuilder;
+use Magento\Framework\Api\SearchCriteria;
+use Magento\Framework\Api\SearchCriteriaBuilder;
+use Magento\Framework\Api\SortOrderBuilder;
+use Magento\Tax\Api\Data\TaxRateInterface as TaxRate;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+
+class TaxRateRepositoryTest extends WebapiAbstract
+{
+    const SERVICE_NAME = "taxTaxRateRepositoryV1";
+    const SERVICE_VERSION = "V1";
+    const RESOURCE_PATH = "/V1/taxRate";
+
+    /** @var \Magento\Tax\Model\Calculation\Rate[] */
+    private $fixtureTaxRates;
+
+    /** @var \Magento\Tax\Model\ClassModel[] */
+    private $fixtureTaxClasses;
+
+    /** @var \Magento\Tax\Model\Calculation\Rule[] */
+    private $fixtureTaxRules;
+
+    /**
+     * @var \Magento\Tax\Api\TaxRateRepositoryInterface
+     */
+    private $taxRateService;
+
+    /** @var FilterBuilder */
+    private $filterBuilder;
+
+    /** @var SearchCriteriaBuilder */
+    private $searchCriteriaBuilder;
+
+    /** @var  SortOrderBuilder */
+    private $sortOrderBuilder;
+
+    /**
+     * Other rates created during tests, to be deleted in tearDown()
+     *
+     * @var \Magento\Tax\Model\Calculation\Rate[]
+     */
+    private $otherRates = [];
+
+    /**
+     * Execute per test initialization.
+     */
+    public function setUp()
+    {
+        $objectManager = Bootstrap::getObjectManager();
+        $this->taxRateService = $objectManager->get('Magento\Tax\Api\TaxRateRepositoryInterface');
+        $this->searchCriteriaBuilder = $objectManager->create(
+            'Magento\Framework\Api\SearchCriteriaBuilder'
+        );
+        $this->filterBuilder = $objectManager->create(
+            'Magento\Framework\Api\FilterBuilder'
+        );
+        $this->sortOrderBuilder = $objectManager->create(
+            'Magento\Framework\Api\SortOrderBuilder'
+        );
+        /** Initialize tax classes, tax rates and tax rules defined in fixture Magento/Tax/_files/tax_classes.php */
+        $this->getFixtureTaxRates();
+        $this->getFixtureTaxClasses();
+        $this->getFixtureTaxRules();
+    }
+
+    public function tearDown()
+    {
+        $taxRules = $this->getFixtureTaxRules();
+        if (count($taxRules)) {
+            $taxRates = $this->getFixtureTaxRates();
+            $taxClasses = $this->getFixtureTaxClasses();
+            foreach ($taxRules as $taxRule) {
+                $taxRule->delete();
+            }
+            foreach ($taxRates as $taxRate) {
+                $taxRate->delete();
+            }
+            foreach ($taxClasses as $taxClass) {
+                $taxClass->delete();
+            }
+        }
+        if (count($this->otherRates)) {
+            foreach ($this->otherRates as $taxRate) {
+                $taxRate->delete();
+            }
+        }
+    }
+
+    public function testCreateTaxRateExistingCode()
+    {
+        $data = [
+            'tax_rate' => [
+                'tax_country_id' => 'US',
+                'tax_region_id' => 12,
+                'tax_postcode' => '*',
+                'code' => 'US-CA-*-Rate 1',
+                'rate' => '8.2501',
+            ],
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        try {
+            $this->_webApiCall($serviceInfo, $data);
+            $this->fail('Expected exception was not raised');
+        } catch (\Exception $e) {
+            $expectedMessage = 'Code already exists.';
+
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "Exception does not contain expected message."
+            );
+        }
+    }
+
+    public function testCreateTaxRate()
+    {
+        $data = [
+            'tax_rate' => [
+                'tax_country_id' => 'US',
+                'tax_region_id' => 12,
+                'tax_postcode' => '*',
+                'code' => 'Test Tax Rate ' . microtime(),
+                'rate' => '8.2501',
+            ],
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $result = $this->_webApiCall($serviceInfo, $data);
+        $this->assertArrayHasKey('id', $result);
+        $taxRateId = $result['id'];
+        /** Ensure that tax rate was actually created in DB */
+        /** @var \Magento\Tax\Model\Calculation\Rate $taxRate */
+        $taxRate = Bootstrap::getObjectManager()->create('Magento\Tax\Model\Calculation\Rate');
+        $this->assertEquals($taxRateId, $taxRate->load($taxRateId)->getId(), 'Tax rate was not created in  DB.');
+        $taxRate->delete();
+    }
+
+    public function testCreateTaxRateWithZipRange()
+    {
+        $data = [
+            'tax_rate' => [
+                'tax_country_id' => 'US',
+                'tax_region_id' => 12,
+                'code' => 'Test Tax Rate ' . microtime(),
+                'rate' => '8.2501',
+                'zip_is_range' => 1,
+                'zip_from' => 17,
+                'zip_to' => 25,
+            ],
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $result = $this->_webApiCall($serviceInfo, $data);
+        $this->assertArrayHasKey('id', $result);
+        $taxRateId = $result['id'];
+        /** Ensure that tax rate was actually created in DB */
+        /** @var \Magento\Tax\Model\Calculation\Rate $taxRate */
+        $taxRate = Bootstrap::getObjectManager()->create('Magento\Tax\Model\Calculation\Rate');
+        $this->assertEquals($taxRateId, $taxRate->load($taxRateId)->getId(), 'Tax rate was not created in  DB.');
+        $this->assertEquals('17-25', $taxRate->getTaxPostcode(), 'Zip range is not saved in DB.');
+        $taxRate->delete();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Tax/_files/tax_classes.php
+     */
+    public function testUpdateTaxRate()
+    {
+        $fixtureRate = $this->getFixtureTaxRates()[0];
+
+        $data = [
+            'tax_rate' => [
+                'id' => $fixtureRate->getId(),
+                'tax_region_id' => 43,
+                'tax_country_id' => 'US',
+                'tax_postcode' => '07400',
+                'code' => 'Test Tax Rate ' . microtime(),
+                'rate' => 3.456,
+            ],
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $this->_webApiCall($serviceInfo, $data);
+        $expectedRateData = $data['tax_rate'];
+        /** Ensure that tax rate was actually updated in DB */
+        /** @var \Magento\Tax\Model\Calculation\Rate $taxRate */
+        $taxRate = Bootstrap::getObjectManager()->create('Magento\Tax\Model\Calculation\Rate');
+        $taxRateModel = $taxRate->load($fixtureRate->getId());
+        $this->assertEquals($expectedRateData['id'], $taxRateModel->getId(), 'Tax rate was not updated in  DB.');
+        $this->assertEquals(
+            $expectedRateData['tax_region_id'],
+            $taxRateModel->getTaxRegionId(),
+            'Tax rate was not updated in  DB.'
+        );
+        $this->assertEquals(
+            $expectedRateData['tax_country_id'],
+            $taxRateModel->getTaxCountryId(),
+            'Tax rate was not updated in  DB.'
+        );
+        $this->assertEquals(
+            $expectedRateData['tax_postcode'],
+            $taxRateModel->getTaxPostcode(),
+            'Tax rate was not updated in  DB.'
+        );
+        $this->assertEquals($expectedRateData['code'], $taxRateModel->getCode(), 'Tax rate was not updated in  DB.');
+        $this->assertEquals(
+            $expectedRateData['rate'],
+            $taxRateModel->getRate(),
+            'Tax rate was not updated in  DB.'
+        );
+    }
+
+    public function testUpdateTaxRateNotExisting()
+    {
+        $data = [
+            'tax_rate' => [
+                'id' => 555,
+                'tax_region_id' => 43,
+                'tax_country_id' => 'US',
+                'tax_postcode' => '07400',
+                'code' => 'Test Tax Rate ' . microtime(),
+                'rate' => 3.456,
+            ],
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        try {
+            $this->_webApiCall($serviceInfo, $data);
+            $this->fail('Expected exception was not raised');
+        } catch (\Exception $e) {
+            $expectedMessage = 'No such entity with %fieldName = %fieldValue';
+
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "Exception does not contain expected message."
+            );
+        }
+    }
+
+    public function testGetTaxRate()
+    {
+        $taxRateId = 2;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/$taxRateId",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Get',
+            ],
+        ];
+
+        $result = $this->_webApiCall($serviceInfo, ['rateId' => $taxRateId]);
+        $expectedRateData = [
+            'id' => 2,
+            'tax_country_id' => 'US',
+            'tax_region_id' => 43,
+            'tax_postcode' => '*',
+            'code' => 'US-NY-*-Rate 1',
+            'rate' => 8.375,
+            'titles' => [],
+            'region_name' => 'NY',
+        ];
+        $this->assertEquals($expectedRateData, $result);
+    }
+
+    public function testGetTaxRateNotExist()
+    {
+        $taxRateId = 37865;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/$taxRateId",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Get',
+            ],
+        ];
+        try {
+            $this->_webApiCall($serviceInfo, ['rateId' => $taxRateId]);
+            $this->fail('Expected exception was not raised');
+        } catch (\Exception $e) {
+            $expectedMessage = 'No such entity with %fieldName = %fieldValue';
+
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "Exception does not contain expected message."
+            );
+        }
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Tax/_files/tax_classes.php
+     */
+    public function testDeleteTaxRate()
+    {
+        /** Tax rules must be deleted since tax rate cannot be deleted if there are any tax rules associated with it */
+        $taxRules = $this->getFixtureTaxRules();
+        foreach ($taxRules as $taxRule) {
+            $taxRule->delete();
+        }
+
+        $fixtureRate = $this->getFixtureTaxRates()[0];
+        $taxRateId = $fixtureRate->getId();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/$taxRateId",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'DeleteById',
+            ],
+        ];
+
+        $result = $this->_webApiCall($serviceInfo, ['rateId' => $taxRateId]);
+        $this->assertTrue($result);
+        /** Ensure that tax rate was actually removed from DB */
+        /** @var \Magento\Tax\Model\Calculation\Rate $taxRate */
+        $taxRate = Bootstrap::getObjectManager()->create('Magento\Tax\Model\Calculation\Rate');
+        $this->assertNull($taxRate->load($taxRateId)->getId(), 'Tax rate was not deleted from DB.');
+    }
+
+    /**
+     * Insure that tax rate cannot be deleted if it is used for a tax rule.
+     *
+     * @magentoApiDataFixture Magento/Tax/_files/tax_classes.php
+     */
+    public function testCannotDeleteTaxRate()
+    {
+        $fixtureRate = $this->getFixtureTaxRates()[0];
+        $taxRateId = $fixtureRate->getId();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/$taxRateId",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'DeleteById',
+            ],
+        ];
+        try {
+            $this->_webApiCall($serviceInfo, ['rateId' => $taxRateId]);
+            $this->fail('Expected exception was not raised');
+        } catch (\Exception $e) {
+            $expectedMessage = 'The tax rate cannot be removed. It exists in a tax rule.';
+
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "Exception does not contain expected message."
+            );
+        }
+    }
+
+    public function testSearchTaxRates()
+    {
+        $rates = $this->setupTaxRatesForSearch();
+
+        // Find rates whose code is 'codeUs12'
+        $filter = $this->filterBuilder->setField(TaxRate::KEY_CODE)
+            ->setValue('codeUs12')
+            ->create();
+
+        $this->searchCriteriaBuilder->addFilter([$filter]);
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/search',
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetList',
+            ],
+        ];
+        $searchData = $this->searchCriteriaBuilder->create()->__toArray();
+        $requestData = ['searchCriteria' => $searchData];
+
+        /** @var \Magento\Framework\Api\SearchResults $searchResults */
+        $searchResults = $this->_webApiCall($serviceInfo, $requestData);
+
+        $this->assertEquals(1, $searchResults['total_count']);
+
+        $expectedRuleData = [
+            [
+                'id' => (int)$rates['codeUs12']->getId(),
+                'tax_country_id' => $rates['codeUs12']->getTaxCountryId(),
+                'tax_region_id' => (int)$rates['codeUs12']->getTaxRegionId(),
+                'region_name' => 'CA',
+                'tax_postcode' => $rates['codeUs12']->getTaxPostcode(),
+                'code' =>  $rates['codeUs12']->getCode(),
+                'rate' => ((float) $rates['codeUs12']->getRate()),
+                'titles' => [],
+            ],
+        ];
+        $this->assertEquals($expectedRuleData, $searchResults['items']);
+    }
+
+    public function testSearchTaxRatesCz()
+    {
+        // TODO: This test fails in SOAP, a generic bug searching in SOAP
+        $this->_markTestAsRestOnly();
+        $rates = $this->setupTaxRatesForSearch();
+
+        // Find rates which country id 'CZ'
+        $filter = $this->filterBuilder->setField(TaxRate::KEY_COUNTRY_ID)
+            ->setValue('CZ')
+            ->create();
+        $sortOrder = $this->sortOrderBuilder
+            ->setField(TaxRate::KEY_POSTCODE)
+            ->setDirection(SearchCriteria::SORT_DESC)
+            ->create();
+        // Order them by descending postcode (not the default order)
+        $this->searchCriteriaBuilder->addFilter([$filter])
+            ->addSortOrder($sortOrder);
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/search',
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetList',
+            ],
+        ];
+        $searchData = $this->searchCriteriaBuilder->create()->__toArray();
+        $requestData = ['searchCriteria' => $searchData];
+
+        /** @var \Magento\Framework\Api\SearchResults $searchResults */
+        $searchResults = $this->_webApiCall($serviceInfo, $requestData);
+
+        $this->assertEquals(2, $searchResults['total_count']);
+
+        $expectedRuleData = [
+            [
+                'id' => (int)$rates['codeCz2']->getId(),
+                'tax_country_id' => $rates['codeCz2']->getTaxCountryId(),
+                'tax_postcode' => $rates['codeCz2']->getTaxPostcode(),
+                'code' =>  $rates['codeCz2']->getCode(),
+                'rate' =>  ((float) $rates['codeCz2']->getRate()),
+                'tax_region_id' => 0,
+                'titles' => [],
+            ],
+            [
+                'id' => (int)$rates['codeCz1']->getId(),
+                'tax_country_id' => $rates['codeCz1']->getTaxCountryId(),
+                'tax_postcode' => $rates['codeCz1']->getTaxPostcode(),
+                'code' => $rates['codeCz1']->getCode(),
+                'rate' => ((float) $rates['codeCz1']->getRate()),
+                'tax_region_id' => 0,
+                'titles' => [],
+            ],
+        ];
+        $this->assertEquals($expectedRuleData, $searchResults['items']);
+    }
+
+    /**
+     * Get tax rates created in Magento\Tax\_files\tax_classes.php
+     *
+     * @return \Magento\Tax\Model\Calculation\Rate[]
+     */
+    private function getFixtureTaxRates()
+    {
+        if (is_null($this->fixtureTaxRates)) {
+            $this->fixtureTaxRates = [];
+            if ($this->getFixtureTaxRules()) {
+                $taxRateIds = (array)$this->getFixtureTaxRules()[0]->getRates();
+                foreach ($taxRateIds as $taxRateId) {
+                    /** @var \Magento\Tax\Model\Calculation\Rate $taxRate */
+                    $taxRate = Bootstrap::getObjectManager()->create('Magento\Tax\Model\Calculation\Rate');
+                    $this->fixtureTaxRates[] = $taxRate->load($taxRateId);
+                }
+            }
+        }
+        return $this->fixtureTaxRates;
+    }
+
+    /**
+     * Get tax classes created in Magento\Tax\_files\tax_classes.php
+     *
+     * @return \Magento\Tax\Model\ClassModel[]
+     */
+    private function getFixtureTaxClasses()
+    {
+        if (is_null($this->fixtureTaxClasses)) {
+            $this->fixtureTaxClasses = [];
+            if ($this->getFixtureTaxRules()) {
+                $taxClassIds = array_merge(
+                    (array)$this->getFixtureTaxRules()[0]->getCustomerTaxClasses(),
+                    (array)$this->getFixtureTaxRules()[0]->getProductTaxClasses()
+                );
+                foreach ($taxClassIds as $taxClassId) {
+                    /** @var \Magento\Tax\Model\ClassModel $taxClass */
+                    $taxClass = Bootstrap::getObjectManager()->create('Magento\Tax\Model\ClassModel');
+                    $this->fixtureTaxClasses[] = $taxClass->load($taxClassId);
+                }
+            }
+        }
+        return $this->fixtureTaxClasses;
+    }
+
+    /**
+     * Get tax rule created in Magento\Tax\_files\tax_classes.php
+     *
+     * @return \Magento\Tax\Model\Calculation\Rule[]
+     */
+    private function getFixtureTaxRules()
+    {
+        if (is_null($this->fixtureTaxRules)) {
+            $this->fixtureTaxRules = [];
+            $taxRuleCodes = ['Test Rule Duplicate', 'Test Rule'];
+            foreach ($taxRuleCodes as $taxRuleCode) {
+                /** @var \Magento\Tax\Model\Calculation\Rule $taxRule */
+                $taxRule = Bootstrap::getObjectManager()->create('Magento\Tax\Model\Calculation\Rule');
+                $taxRule->load($taxRuleCode, 'code');
+                if ($taxRule->getId()) {
+                    $this->fixtureTaxRules[] = $taxRule;
+                }
+            }
+        }
+        return $this->fixtureTaxRules;
+    }
+
+    /**
+     * Creates rates for search tests.
+     *
+     * @return \Magento\Tax\Model\Calculation\Rate[]
+     */
+    private function setupTaxRatesForSearch()
+    {
+        $objectManager = Bootstrap::getObjectManager();
+
+        $taxRateUs12 = [
+            'tax_country_id' => 'US',
+            'tax_region_id' => 12,
+            'tax_postcode' => '*',
+            'code' => 'codeUs12',
+            'rate' => 22,
+            'region_name' => 'CA',
+        ];
+        $rates['codeUs12'] = $objectManager->create('Magento\Tax\Model\Calculation\Rate')
+            ->setData($taxRateUs12)
+            ->save();
+
+        $taxRateUs14 = [
+            'tax_country_id' => 'US',
+            'tax_region_id' => 14,
+            'tax_postcode' => '*',
+            'code' => 'codeUs14',
+            'rate' => 22,
+        ];
+        $rates['codeUs14'] = $objectManager->create('Magento\Tax\Model\Calculation\Rate')
+            ->setData($taxRateUs14)
+            ->save();
+        $taxRateBr13 = [
+            'tax_country_id' => 'BR',
+            'tax_region_id' => 13,
+            'tax_postcode' => '*',
+            'code' => 'codeBr13',
+            'rate' => 7.5,
+        ];
+        $rates['codeBr13'] = $objectManager->create('Magento\Tax\Model\Calculation\Rate')
+            ->setData($taxRateBr13)
+            ->save();
+
+        $taxRateCz1 = [
+            'tax_country_id' => 'CZ',
+            'tax_postcode' => '110 00',
+            'code' => 'codeCz1',
+            'rate' => 1.1,
+        ];
+        $rates['codeCz1'] = $objectManager->create('Magento\Tax\Model\Calculation\Rate')
+            ->setData($taxRateCz1)
+            ->save();
+        $taxRateCz2 = [
+            'tax_country_id' => 'CZ',
+            'tax_postcode' => '250 00',
+            'code' => 'codeCz2',
+            'rate' => 2.2,
+        ];
+        $rates['codeCz2'] = $objectManager->create('Magento\Tax\Model\Calculation\Rate')
+            ->setData($taxRateCz2)
+            ->save();
+
+        // Set class variable so rates will be deleted on tearDown()
+        $this->otherRates = $rates;
+        return $rates;
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRuleRepositoryInterfaceTest.php b/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRuleRepositoryInterfaceTest.php
new file mode 100644
index 00000000000..277b0611d7a
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRuleRepositoryInterfaceTest.php
@@ -0,0 +1,606 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Tax\Api;
+
+use Magento\Framework\Api\FilterBuilder;
+use Magento\Framework\Api\SearchCriteriaBuilder;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\TestCase\WebapiAbstract;
+use Magento\Webapi\Model\Rest\Config as HttpConstants;
+
+class TaxRuleRepositoryInterfaceTest extends WebapiAbstract
+{
+    const SERVICE_NAME = "taxTaxRuleRepositoryV1";
+    const SERVICE_VERSION = "V1";
+    const RESOURCE_PATH = "/V1/taxRules";
+
+    /** @var \Magento\Tax\Model\Calculation\Rate[] */
+    private $fixtureTaxRates;
+
+    /** @var \Magento\Tax\Model\ClassModel[] */
+    private $fixtureTaxClasses;
+
+    /** @var \Magento\Tax\Model\Calculation\Rule[] */
+    private $fixtureTaxRules;
+
+    /** @var FilterBuilder */
+    private $filterBuilder;
+
+    /** @var SearchCriteriaBuilder */
+    private $searchCriteriaBuilder;
+
+    /**
+     * Execute per test initialization.
+     */
+    public function setUp()
+    {
+        $this->searchCriteriaBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\Framework\Api\SearchCriteriaBuilder'
+        );
+        $this->filterBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\Framework\Api\FilterBuilder'
+        );
+        $objectManager = Bootstrap::getObjectManager();
+
+        $this->searchCriteriaBuilder = $objectManager->create(
+            'Magento\Framework\Api\SearchCriteriaBuilder'
+        );
+        $this->filterBuilder = $objectManager->create(
+            'Magento\Framework\Api\FilterBuilder'
+        );
+
+        /** Initialize tax classes, tax rates and tax rules defined in fixture Magento/Tax/_files/tax_classes.php */
+        $this->getFixtureTaxRates();
+        $this->getFixtureTaxClasses();
+        $this->getFixtureTaxRules();
+    }
+
+    public function tearDown()
+    {
+        $taxRules = $this->getFixtureTaxRules();
+        if (count($taxRules)) {
+            $taxRates = $this->getFixtureTaxRates();
+            $taxClasses = $this->getFixtureTaxClasses();
+            foreach ($taxRules as $taxRule) {
+                $taxRule->delete();
+            }
+            foreach ($taxRates as $taxRate) {
+                $taxRate->delete();
+            }
+            foreach ($taxClasses as $taxClass) {
+                $taxClass->delete();
+            }
+        }
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Tax/_files/tax_classes.php
+     */
+    public function testDeleteTaxRule()
+    {
+        $fixtureRule = $this->getFixtureTaxRules()[0];
+        $taxRuleId = $fixtureRule->getId();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/$taxRuleId",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_DELETE,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'DeleteById',
+            ],
+        ];
+        $requestData = ['ruleId' => $taxRuleId];
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertTrue($result);
+        /** Ensure that tax rule was actually removed from DB */
+        /** @var \Magento\Tax\Model\Calculation\Rule $taxRule */
+        $taxRate = Bootstrap::getObjectManager()->create('Magento\Tax\Model\Calculation\Rate');
+        $this->assertNull($taxRate->load($taxRuleId)->getId(), 'Tax rule was not deleted from DB.');
+    }
+
+    public function testCreateTaxRule()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => HttpConstants::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $requestData = [
+            'rule' => [
+                'code' => 'Test Rule ' . microtime(),
+                'position' => 10,
+                'priority' => 5,
+                'customer_tax_class_ids' => [3],
+                'product_tax_class_ids' => [2],
+                'tax_rate_ids' => [1, 2],
+                'calculate_subtotal' => 1,
+            ],
+        ];
+        $taxRuleData = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertArrayHasKey('id', $taxRuleData, "Tax rule ID is expected");
+        $this->assertGreaterThan(0, $taxRuleData['id']);
+        $taxRuleId = $taxRuleData['id'];
+        unset($taxRuleData['id']);
+        $this->assertEquals($requestData['rule'], $taxRuleData, "Tax rule is created with invalid data.");
+        /** Ensure that tax rule was actually created in DB */
+        /** @var \Magento\Tax\Model\Calculation\Rule $taxRule */
+        $taxRule = Bootstrap::getObjectManager()->create('Magento\Tax\Model\Calculation\Rule');
+        $this->assertEquals($taxRuleId, $taxRule->load($taxRuleId)->getId(), 'Tax rule was not created in DB.');
+        $taxRule->delete();
+    }
+
+    public function testCreateTaxRuleInvalidTaxClassIds()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => HttpConstants::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $requestData = [
+            'rule' => [
+                'code' => 'Test Rule ' . microtime(),
+                'position' => 10,
+                'priority' => 5,
+                'customer_tax_class_ids' => [2],
+                'product_tax_class_ids' => [3],
+                'tax_rate_ids' => [1, 2],
+                'calculate_subtotal' => 1,
+            ],
+        ];
+
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+            $this->fail('Did not throw expected InputException');
+        } catch (\SoapFault $e) {
+            $this->assertContains('No such entity with customer_tax_class_ids = %fieldValue', $e->getMessage());
+        } catch (\Exception $e) {
+            $this->assertContains('No such entity with customer_tax_class_ids = %fieldValue', $e->getMessage());
+        }
+    }
+
+    public function testCreateTaxRuleExistingCode()
+    {
+        $requestData = [
+            'rule' => [
+                'code' => 'Test Rule ' . microtime(),
+                'position' => 10,
+                'priority' => 5,
+                'customer_tax_class_ids' => [3],
+                'product_tax_class_ids' => [2],
+                'tax_rate_ids' => [1, 2],
+                'calculate_subtotal' => 0,
+            ],
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $newTaxRuleData = $this->_webApiCall($serviceInfo, $requestData);
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+            $this->fail('Expected exception was not raised');
+        } catch (\Exception $e) {
+            $expectedMessage = 'Code already exists.';
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "Exception does not contain expected message."
+            );
+        }
+
+        // Clean up the new tax rule so it won't affect other tests
+        /** @var \Magento\Tax\Model\Calculation\Rule $taxRule */
+        $taxRule = Bootstrap::getObjectManager()->create('Magento\Tax\Model\Calculation\Rule');
+        $taxRule->load($newTaxRuleData['id']);
+        $taxRule->delete();
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Tax/_files/tax_classes.php
+     */
+    public function testGetTaxRule()
+    {
+        $fixtureRule = $this->getFixtureTaxRules()[0];
+        $taxRuleId = $fixtureRule->getId();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/$taxRuleId",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Get',
+            ],
+        ];
+
+        $expectedRuleData = [
+            'id' => $taxRuleId,
+            'code' => 'Test Rule Duplicate',
+            'priority' => '0',
+            'position' => '0',
+            'customer_tax_class_ids' => array_values(array_unique($fixtureRule->getCustomerTaxClasses())),
+            'product_tax_class_ids' => array_values(array_unique($fixtureRule->getProductTaxClasses())),
+            'tax_rate_ids' => array_values(array_unique($fixtureRule->getRates())),
+            'calculate_subtotal' => false,
+        ];
+        $requestData = ['ruleId' => $taxRuleId];
+        $result = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals($expectedRuleData, $result);
+    }
+    /**
+     * @magentoApiDataFixture Magento/Tax/_files/tax_classes.php
+     */
+    public function testSearchTaxRulesSimple()
+    {
+        // Find rules whose code is 'Test Rule'
+        $filter = $this->filterBuilder->setField('code')
+            ->setValue('Test Rule')
+            ->create();
+
+        $this->searchCriteriaBuilder->addFilter([$filter]);
+
+        $fixtureRule = $this->getFixtureTaxRules()[1];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/search',
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetList',
+            ],
+        ];
+        $searchData = $this->searchCriteriaBuilder->create()->__toArray();
+        $requestData = ['searchCriteria' => $searchData];
+
+        /** @var \Magento\Framework\Api\SearchResults $searchResults */
+        $searchResults = $this->_webApiCall($serviceInfo, $requestData);
+
+        $this->assertEquals(1, $searchResults['total_count']);
+
+        $expectedRuleData = [
+            [
+                'id' => $fixtureRule->getId(),
+                'code' => 'Test Rule',
+                'priority' => 0,
+                'position' => 0,
+                'calculate_subtotal' => 0,
+                'customer_tax_class_ids' => array_values(array_unique($fixtureRule->getCustomerTaxClasses())),
+                'product_tax_class_ids' => array_values(array_unique($fixtureRule->getProductTaxClasses())),
+                'tax_rate_ids' => array_values(array_unique($fixtureRule->getRates())),
+            ],
+        ];
+        $this->assertEquals($expectedRuleData, $searchResults['items']);
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Tax/_files/tax_classes.php
+     */
+    public function testSearchTaxRulesCodeLike()
+    {
+        // Find rules whose code starts with 'Test Rule'
+        $filter = $this->filterBuilder
+            ->setField('code')
+            ->setValue('Test Rule%')
+            ->setConditionType('like')
+            ->create();
+
+        $sortFilter = $this->filterBuilder
+            ->setField('position')
+            ->setValue(0)
+            ->create();
+
+        $this->searchCriteriaBuilder->addFilter([$filter, $sortFilter]);
+
+        $fixtureRule = $this->getFixtureTaxRules()[1];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/search',
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetList',
+            ],
+        ];
+        $searchData = $this->searchCriteriaBuilder->create()->__toArray();
+        $requestData = ['searchCriteria' => $searchData];
+
+        /** @var \Magento\Framework\Api\SearchResults $searchResults */
+        $searchResults = $this->_webApiCall($serviceInfo, $requestData);
+
+        $this->assertEquals(2, $searchResults['total_count']);
+
+        $expectedRuleData = [
+            [
+                'id' => $fixtureRule->getId(),
+                'code' => 'Test Rule',
+                'priority' => 0,
+                'position' => 0,
+                'calculate_subtotal' => 0,
+                'customer_tax_class_ids' => array_values(array_unique($fixtureRule->getCustomerTaxClasses())),
+                'product_tax_class_ids' => array_values(array_unique($fixtureRule->getProductTaxClasses())),
+                'tax_rate_ids' => array_values(array_unique($fixtureRule->getRates())),
+            ],
+            [
+                'id' => $this->getFixtureTaxRules()[0]->getId(),
+                'code' => 'Test Rule Duplicate',
+                'priority' => 0,
+                'position' => 0,
+                'calculate_subtotal' => 0,
+                'customer_tax_class_ids' => array_values(array_unique($fixtureRule->getCustomerTaxClasses())),
+                'product_tax_class_ids' => array_values(array_unique($fixtureRule->getProductTaxClasses())),
+                'tax_rate_ids' => array_values(array_unique($fixtureRule->getRates()))
+            ],
+        ];
+        $this->assertEquals($expectedRuleData, $searchResults['items']);
+    }
+
+    public function testGetTaxRuleNotExist()
+    {
+        $taxRuleId = 37865;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . "/$taxRuleId",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Get',
+            ],
+        ];
+        $requestData = ['ruleId' => $taxRuleId];
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+            $this->fail('Expected exception was not raised');
+        } catch (\Exception $e) {
+            $expectedMessage = 'No such entity with %fieldName = %fieldValue';
+
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "Exception does not contain expected message."
+            );
+        }
+    }
+    /**
+     * @magentoApiDataFixture Magento/Tax/_files/tax_classes.php
+     */
+    public function testUpdateTaxRule()
+    {
+        $fixtureRule = $this->getFixtureTaxRules()[0];
+        $requestData = [
+            'rule' => [
+                'id' => $fixtureRule->getId(),
+                'code' => 'Test Rule ' . microtime(),
+                'position' => 10,
+                'priority' => 5,
+                'customer_tax_class_ids' => [3],
+                'product_tax_class_ids' => [2],
+                'tax_rate_ids' => [1, 2],
+                'calculate_subtotal' => 1,
+            ],
+        ];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        $this->_webApiCall($serviceInfo, $requestData);
+        $expectedRuleData = $requestData['rule'];
+        /** Ensure that tax rule was actually updated in DB */
+        /** @var \Magento\Tax\Model\Calculation $taxCalculation */
+        $taxCalculation = Bootstrap::getObjectManager()->create('Magento\Tax\Model\Calculation');
+        /** @var \Magento\Tax\Model\Calculation\Rule $taxRule */
+        $taxRule = Bootstrap::getObjectManager()->create(
+            'Magento\Tax\Model\Calculation\Rule',
+            ['calculation' => $taxCalculation]
+        );
+        $taxRuleModel = $taxRule->load($fixtureRule->getId());
+        $this->assertEquals($expectedRuleData['id'], $taxRuleModel->getId(), 'Tax rule was not updated in DB.');
+        $this->assertEquals(
+            $expectedRuleData['code'],
+            $taxRuleModel->getCode(),
+            'Tax rule code was updated incorrectly.'
+        );
+        $this->assertEquals(
+            $expectedRuleData['position'],
+            $taxRuleModel->getPosition(),
+            'Tax rule sort order was updated incorrectly.'
+        );
+        $this->assertEquals(
+            $expectedRuleData['priority'],
+            $taxRuleModel->getPriority(),
+            'Tax rule priority was updated incorrectly.'
+        );
+        $this->assertEquals(
+            $expectedRuleData['customer_tax_class_ids'],
+            array_values(array_unique($taxRuleModel->getCustomerTaxClasses())),
+            'Customer Tax classes were updated incorrectly'
+        );
+        $this->assertEquals(
+            $expectedRuleData['product_tax_class_ids'],
+            array_values(array_unique($taxRuleModel->getProductTaxClasses())),
+            'Product Tax classes were updated incorrectly.'
+        );
+        $this->assertEquals(
+            $expectedRuleData['tax_rate_ids'],
+            array_values(array_unique($taxRuleModel->getRates())),
+            'Tax rates were updated incorrectly.'
+        );
+    }
+    public function testUpdateTaxRuleNotExisting()
+    {
+        $requestData = [
+            'rule' => [
+                'id' => 12345,
+                'code' => 'Test Rule ' . microtime(),
+                'position' => 10,
+                'priority' => 5,
+                'customer_tax_class_ids' => [3],
+                'product_tax_class_ids' => [2],
+                'tax_rate_ids' => [1, 2],
+            ],
+        ];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'Save',
+            ],
+        ];
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+            $this->fail('Expected exception was not raised');
+        } catch (\Exception $e) {
+            $expectedMessage = 'No such entity with %fieldName = %fieldValue';
+
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "Exception does not contain expected message."
+            );
+        }
+    }
+
+    /**
+     * @magentoApiDataFixture Magento/Tax/_files/tax_classes.php
+     */
+    public function testSearchTaxRule()
+    {
+        $fixtureRule = $this->getFixtureTaxRules()[0];
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => self::RESOURCE_PATH . '/search',
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => [
+                'service' => self::SERVICE_NAME,
+                'serviceVersion' => self::SERVICE_VERSION,
+                'operation' => self::SERVICE_NAME . 'GetList',
+            ],
+        ];
+
+        $filter = $this->filterBuilder->setField('code')
+            ->setValue($fixtureRule->getCode())
+            ->create();
+        $this->searchCriteriaBuilder->addFilter([$filter]);
+        $searchData = $this->searchCriteriaBuilder->create()->__toArray();
+        $requestData = ['searchCriteria' => $searchData];
+        $searchResults = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(1, $searchResults['total_count']);
+        $this->assertEquals($fixtureRule->getId(), $searchResults['items'][0]["id"]);
+        $this->assertEquals($fixtureRule->getCode(), $searchResults['items'][0]['code']);
+    }
+
+    /**
+     * Get tax rates created in Magento\Tax\_files\tax_classes.php
+     *
+     * @return \Magento\Tax\Model\Calculation\Rate[]
+     */
+    private function getFixtureTaxRates()
+    {
+        if (is_null($this->fixtureTaxRates)) {
+            $this->fixtureTaxRates = [];
+            if ($this->getFixtureTaxRules()) {
+                $taxRateIds = (array)$this->getFixtureTaxRules()[0]->getRates();
+                foreach ($taxRateIds as $taxRateId) {
+                    /** @var \Magento\Tax\Model\Calculation\Rate $taxRate */
+                    $taxRate = Bootstrap::getObjectManager()->create('Magento\Tax\Model\Calculation\Rate');
+                    $this->fixtureTaxRates[] = $taxRate->load($taxRateId);
+                }
+            }
+        }
+        return $this->fixtureTaxRates;
+    }
+
+    /**
+     * Get tax classes created in Magento\Tax\_files\tax_classes.php
+     *
+     * @return \Magento\Tax\Model\ClassModel[]
+     */
+    private function getFixtureTaxClasses()
+    {
+        if (is_null($this->fixtureTaxClasses)) {
+            $this->fixtureTaxClasses = [];
+            if ($this->getFixtureTaxRules()) {
+                $taxClassIds = array_merge(
+                    (array)$this->getFixtureTaxRules()[0]->getCustomerTaxClasses(),
+                    (array)$this->getFixtureTaxRules()[0]->getProductTaxClasses()
+                );
+                foreach ($taxClassIds as $taxClassId) {
+                    /** @var \Magento\Tax\Model\ClassModel $taxClass */
+                    $taxClass = Bootstrap::getObjectManager()->create('Magento\Tax\Model\ClassModel');
+                    $this->fixtureTaxClasses[] = $taxClass->load($taxClassId);
+                }
+            }
+        }
+        return $this->fixtureTaxClasses;
+    }
+
+    /**
+     * Get tax rule created in Magento\Tax\_files\tax_classes.php
+     *
+     * @return \Magento\Tax\Model\Calculation\Rule[]
+     */
+    private function getFixtureTaxRules()
+    {
+        if (is_null($this->fixtureTaxRules)) {
+            $this->fixtureTaxRules = [];
+            $taxRuleCodes = ['Test Rule Duplicate', 'Test Rule'];
+            foreach ($taxRuleCodes as $taxRuleCode) {
+                /** @var \Magento\Tax\Model\Calculation\Rule $taxRule */
+                $taxRule = Bootstrap::getObjectManager()->create('Magento\Tax\Model\Calculation\Rule');
+                $taxRule->load($taxRuleCode, 'code');
+                if ($taxRule->getId()) {
+                    $this->fixtureTaxRules[] = $taxRule;
+                }
+            }
+        }
+        return $this->fixtureTaxRules;
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/Authentication/RestTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/Authentication/RestTest.php
new file mode 100644
index 00000000000..3f8bd45445a
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/Authentication/RestTest.php
@@ -0,0 +1,203 @@
+<?php
+/**
+ * Test authentication mechanisms in REST.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Webapi\Authentication;
+
+/**
+ * @magentoApiDataFixture consumerFixture
+ */
+class RestTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    /** @var \Magento\TestFramework\Authentication\Rest\OauthClient[] */
+    protected $_oAuthClients = [];
+
+    /** @var \Magento\Integration\Model\Oauth\Consumer */
+    protected static $_consumer;
+
+    /** @var \Magento\Integration\Model\Oauth\Token */
+    protected static $_token;
+
+    /** @var string */
+    protected static $_consumerKey;
+
+    /** @var string */
+    protected static $_consumerSecret;
+
+    /** @var string */
+    protected static $_verifier;
+
+    protected function setUp()
+    {
+        $this->_markTestAsRestOnly();
+        parent::setUp();
+    }
+
+    /**
+     * Create a consumer
+     */
+    public static function consumerFixture($date = null)
+    {
+        /** Clear the credentials because during the fixture generation, any previous credentials are invalidated */
+        \Magento\TestFramework\Authentication\OauthHelper::clearApiAccessCredentials();
+
+        $consumerCredentials = \Magento\TestFramework\Authentication\OauthHelper::getConsumerCredentials($date);
+        self::$_consumerKey = $consumerCredentials['key'];
+        self::$_consumerSecret = $consumerCredentials['secret'];
+        self::$_verifier = $consumerCredentials['verifier'];
+        self::$_consumer = $consumerCredentials['consumer'];
+        self::$_token = $consumerCredentials['token'];
+    }
+
+    protected function tearDown()
+    {
+        parent::tearDown();
+        $this->_oAuthClients = [];
+        if (isset(self::$_consumer)) {
+            self::$_consumer->delete();
+            self::$_token->delete();
+        }
+    }
+
+    public function testGetRequestToken()
+    {
+        /** @var $oAuthClient \Magento\TestFramework\Authentication\Rest\OauthClient */
+        $oAuthClient = $this->_getOauthClient(self::$_consumerKey, self::$_consumerSecret);
+        $requestToken = $oAuthClient->requestRequestToken();
+
+        $this->assertNotEmpty($requestToken->getRequestToken(), "Request token value is not set");
+        $this->assertNotEmpty($requestToken->getRequestTokenSecret(), "Request token secret is not set");
+
+        $this->assertEquals(
+            \Magento\Framework\Oauth\Helper\Oauth::LENGTH_TOKEN,
+            strlen($requestToken->getRequestToken()),
+            "Request token value length should be " . \Magento\Framework\Oauth\Helper\Oauth::LENGTH_TOKEN
+        );
+        $this->assertEquals(
+            \Magento\Framework\Oauth\Helper\Oauth::LENGTH_TOKEN_SECRET,
+            strlen($requestToken->getRequestTokenSecret()),
+            "Request token secret length should be " . \Magento\Framework\Oauth\Helper\Oauth::LENGTH_TOKEN_SECRET
+        );
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage HTTP/1.1 401
+     */
+    public function testGetRequestTokenExpiredConsumer()
+    {
+        $this::consumerFixture('2012-01-01 00:00:00');
+        /** @var $oAuthClient \Magento\TestFramework\Authentication\Rest\OauthClient */
+        $oAuthClient = $this->_getOauthClient(self::$_consumerKey, self::$_consumerSecret);
+        $oAuthClient->requestRequestToken();
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage HTTP/1.1 401
+     */
+    public function testGetRequestTokenInvalidConsumerKey()
+    {
+        $oAuthClient = $this->_getOauthClient('invalid_key', self::$_consumerSecret);
+        $oAuthClient->requestRequestToken();
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage HTTP/1.1 401
+     */
+    public function testGetRequestTokenInvalidConsumerSecret()
+    {
+        $oAuthClient = $this->_getOauthClient(self::$_consumerKey, 'invalid_secret');
+        $oAuthClient->requestRequestToken();
+    }
+
+    public function testGetAccessToken()
+    {
+        $oAuthClient = $this->_getOauthClient(self::$_consumerKey, self::$_consumerSecret);
+        $requestToken = $oAuthClient->requestRequestToken();
+        $accessToken = $oAuthClient->requestAccessToken(
+            $requestToken->getRequestToken(),
+            self::$_verifier,
+            $requestToken->getRequestTokenSecret()
+        );
+        $this->assertNotEmpty($accessToken->getAccessToken(), "Access token value is not set.");
+        $this->assertNotEmpty($accessToken->getAccessTokenSecret(), "Access token secret is not set.");
+
+        $this->assertEquals(
+            \Magento\Framework\Oauth\Helper\Oauth::LENGTH_TOKEN,
+            strlen($accessToken->getAccessToken()),
+            "Access token value length should be " . \Magento\Framework\Oauth\Helper\Oauth::LENGTH_TOKEN
+        );
+        $this->assertEquals(
+            \Magento\Framework\Oauth\Helper\Oauth::LENGTH_TOKEN_SECRET,
+            strlen($accessToken->getAccessTokenSecret()),
+            "Access token secret length should be " . \Magento\Framework\Oauth\Helper\Oauth::LENGTH_TOKEN_SECRET
+        );
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage HTTP/1.1 401
+     */
+    public function testGetAccessTokenInvalidVerifier()
+    {
+        $oAuthClient = $this->_getOauthClient(self::$_consumerKey, self::$_consumerSecret);
+        $requestToken = $oAuthClient->requestRequestToken();
+        $oAuthClient->requestAccessToken(
+            $requestToken->getRequestToken(),
+            'invalid verifier',
+            $requestToken->getRequestTokenSecret()
+        );
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage HTTP/1.1 401
+     */
+    public function testGetAccessTokenConsumerMismatch()
+    {
+        $oAuthClientA = $this->_getOauthClient(self::$_consumerKey, self::$_consumerSecret);
+        $requestTokenA = $oAuthClientA->requestRequestToken();
+        $oauthVerifierA = self::$_verifier;
+
+        self::consumerFixture();
+        $oAuthClientB = $this->_getOauthClient(self::$_consumerKey, self::$_consumerSecret);
+
+        $oAuthClientB->requestAccessToken(
+            $requestTokenA->getRequestToken(),
+            $oauthVerifierA,
+            $requestTokenA->getRequestTokenSecret()
+        );
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage HTTP/1.1 401
+     */
+    public function testAccessApiInvalidAccessToken()
+    {
+        $oAuthClient = $this->_getOauthClient(self::$_consumerKey, self::$_consumerSecret);
+        $requestToken = $oAuthClient->requestRequestToken();
+        $accessToken = $oAuthClient->requestAccessToken(
+            $requestToken->getRequestToken(),
+            self::$_verifier,
+            $requestToken->getRequestTokenSecret()
+        );
+        $accessToken->setAccessToken('invalid');
+        $oAuthClient->validateAccessToken($accessToken);
+    }
+
+    protected function _getOauthClient($consumerKey, $consumerSecret)
+    {
+        if (!isset($this->_oAuthClients[$consumerKey])) {
+            $credentials = new \OAuth\Common\Consumer\Credentials($consumerKey, $consumerSecret, TESTS_BASE_URL);
+            $this->_oAuthClients[$consumerKey] = new \Magento\TestFramework\Authentication\Rest\OauthClient(
+                $credentials
+            );
+        }
+        return $this->_oAuthClients[$consumerKey];
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/DataObjectSerialization/CustomAttributeSerializationMSCTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/DataObjectSerialization/CustomAttributeSerializationMSCTest.php
new file mode 100644
index 00000000000..7b1f33148d9
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/DataObjectSerialization/CustomAttributeSerializationMSCTest.php
@@ -0,0 +1,244 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Webapi\DataObjectSerialization;
+
+use Magento\Framework\Reflection\DataObjectProcessor;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestModuleMSC\Api\Data\ItemDataBuilder;
+use Magento\Webapi\Controller\Rest\Response\DataObjectConverter;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+/**
+ * api-functional/testsuite/Magento/Webapi/DataObjectSerialization/CustomAttributeSerializationMSCTest.php
+ * Class to test if custom attributes are serialized correctly for the new Module Service Contract approach
+ */
+class CustomAttributeSerializationMSCTest extends \Magento\Webapi\Routing\BaseService
+{
+    /**
+     * @var string
+     */
+    protected $_version;
+    /**
+     * @var string
+     */
+    protected $_restResourcePath;
+    /**
+     * @var string
+     */
+    protected $_soapService = 'testModuleMSCAllSoapAndRest';
+
+    /**
+     * @var ItemDataBuilder
+     */
+    protected $itemDataBuilder;
+
+    /**
+     * @var \Magento\TestModuleMSC\Api\Data\CustomAttributeNestedDataObjectDataBuilder
+     */
+    protected $customAttributeNestedDataObjectDataBuilder;
+
+    /**
+     * @var \Magento\TestModuleMSC\Api\Data\CustomAttributeDataObjectDataBuilder
+     */
+    protected $customAttributeDataObjectDataBuilder;
+
+    /**
+     * @var DataObjectProcessor $dataObjectProcessor
+     */
+    protected $dataObjectProcessor;
+
+    /**
+     * @var DataObjectConverter $dataObjectConverter
+     */
+    protected $dataObjectConverter;
+
+    /**
+     * Set up custom attribute related data objects
+     */
+    protected function setUp()
+    {
+        $this->markTestSkipped('This test become irrelevant according to new API Contract');
+        $this->_version = 'V1';
+        $this->_soapService = 'testModuleMSCAllSoapAndRestV1';
+        $this->_restResourcePath = "/{$this->_version}/testmoduleMSC/";
+
+        $this->itemDataBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\TestModuleMSC\Api\Data\ItemDataBuilder'
+        );
+
+        $this->customAttributeNestedDataObjectDataBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\TestModuleMSC\Api\Data\CustomAttributeNestedDataObjectDataBuilder'
+        );
+
+        $this->customAttributeDataObjectDataBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\TestModuleMSC\Api\Data\CustomAttributeDataObjectDataBuilder'
+        );
+
+        $this->dataObjectProcessor = Bootstrap::getObjectManager()->create(
+            'Magento\Framework\Reflection\DataObjectProcessor'
+        );
+
+        $this->dataObjectConverter = Bootstrap::getObjectManager()->create(
+            'Magento\Webapi\Controller\Rest\Response\DataObjectConverter'
+        );
+    }
+
+    public function testSimpleAndNonExistentCustomAttributes()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . 'itemAnyType',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'ItemAnyType'],
+        ];
+        $requestData = [
+            'item_id' => 1,
+            'name' => 'testProductAnyType',
+            'custom_attributes' => [
+                    'non_existent' => [
+                            'attribute_code' => 'non_existent',
+                            'value' => 'test',
+                        ],
+                    'custom_attribute_string' => [
+                            'attribute_code' => 'custom_attribute_string',
+                            'value' => 'someStringValue',
+                        ],
+                ],
+        ];
+        $result = $this->_webApiCall($serviceInfo, ['entityItem' => $requestData]);
+
+        //The non_existent custom attribute should be dropped since its not a defined custom attribute
+        $expectedResponse = [
+            'item_id' => 1,
+            'name' => 'testProductAnyType',
+            'custom_attributes' => [
+                    [
+                        'attribute_code' => 'custom_attribute_string',
+                        'value' => 'someStringValue',
+                    ],
+                ],
+        ];
+
+        //\Magento\TestModuleMSC\Api\AllSoapAndRest::itemAnyType just return the input data back as response
+        $this->assertEquals($expectedResponse, $result);
+    }
+
+    public function testDataObjectCustomAttributes()
+    {
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            $this->markTestIncomplete('MAGETWO-31016: incompatible with ZF 1.12.9');
+        }
+        $customAttributeDataObject = $this->customAttributeDataObjectDataBuilder
+            ->setName('nameValue')
+            ->setCustomAttribute('custom_attribute_int', 1)
+            ->create();
+
+        $item = $this->itemDataBuilder
+            ->setItemId(1)
+            ->setName('testProductAnyType')
+            ->setCustomAttribute('custom_attribute_data_object', $customAttributeDataObject)
+            ->setCustomAttribute('custom_attribute_string', 'someStringValue')
+            ->create();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . 'itemAnyType',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'ItemAnyType'],
+        ];
+        $requestData = $this->dataObjectProcessor->buildOutputDataArray($item, get_class($item));
+        $result = $this->_webApiCall($serviceInfo, ['entityItem' => $requestData]);
+
+        $expectedResponse = $this->dataObjectConverter->processServiceOutput(
+            $item,
+            '\Magento\TestModuleMSC\Api\AllSoapAndRestInterface',
+            'itemAnyType'
+        );
+        //\Magento\TestModuleMSC\Api\AllSoapAndRest::itemAnyType just return the input data back as response
+        $this->assertEquals($expectedResponse, $result);
+    }
+
+    public function testDataObjectCustomAttributesPreconfiguredItem()
+    {
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            $this->markTestIncomplete('MAGETWO-31016: incompatible with ZF 1.12.9');
+        }
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . 'itemPreconfigured',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'GetPreconfiguredItem'],
+        ];
+
+        $result = $this->_webApiCall($serviceInfo, []);
+
+        $customAttributeDataObject = $this->customAttributeDataObjectDataBuilder
+            ->setName('nameValue')
+            ->setCustomAttribute('custom_attribute_int', 1)
+            ->create();
+
+        $item = $this->itemDataBuilder
+            ->setItemId(1)
+            ->setName('testProductAnyType')
+            ->setCustomAttribute('custom_attribute_data_object', $customAttributeDataObject)
+            ->setCustomAttribute('custom_attribute_string', 'someStringValue')
+            ->create();
+
+        $expectedResponse = $this->dataObjectConverter->processServiceOutput(
+            $item,
+            '\Magento\TestModuleMSC\Api\AllSoapAndRestInterface',
+            'getPreconfiguredItem'
+        );
+        $this->assertEquals($expectedResponse, $result);
+    }
+
+    public function testNestedDataObjectCustomAttributes()
+    {
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            $this->markTestIncomplete('MAGETWO-31016: incompatible with ZF 1.12.9');
+        }
+        $customAttributeNestedDataObject = $this->customAttributeNestedDataObjectDataBuilder
+            ->setName('nestedNameValue')
+            ->create();
+
+        $customAttributeDataObject = $this->customAttributeDataObjectDataBuilder
+            ->setName('nameValue')
+            ->setCustomAttribute('custom_attribute_nested', $customAttributeNestedDataObject)
+            ->setCustomAttribute('custom_attribute_int', 1)
+            ->create();
+
+        $item = $this->itemDataBuilder
+            ->setItemId(1)
+            ->setName('testProductAnyType')
+            ->setCustomAttribute('custom_attribute_data_object', $customAttributeDataObject)
+            ->setCustomAttribute('custom_attribute_string', 'someStringValue')
+            ->create();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . 'itemAnyType',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'ItemAnyType'],
+        ];
+        $requestData = $this->dataObjectProcessor->buildOutputDataArray(
+            $item,
+            '\Magento\TestModuleMSC\Api\Data\ItemInterface'
+        );
+        $result = $this->_webApiCall($serviceInfo, ['entityItem' => $requestData]);
+
+        $expectedResponse = $this->dataObjectConverter->processServiceOutput(
+            $item,
+            '\Magento\TestModuleMSC\Api\AllSoapAndRestInterface',
+            'itemAnyType'
+        );
+        //\Magento\TestModuleMSC\Api\AllSoapAndRest::itemAnyType just return the input data back as response
+        $this->assertEquals($expectedResponse, $result);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/DataObjectSerialization/CustomAttributeSerializationTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/DataObjectSerialization/CustomAttributeSerializationTest.php
new file mode 100644
index 00000000000..4baca07992c
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/DataObjectSerialization/CustomAttributeSerializationTest.php
@@ -0,0 +1,228 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+/**
+ * Class to test if custom attributes are serialized correctly
+ */
+namespace Magento\Webapi\DataObjectSerialization;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestModule1\Service\V1\Entity\ItemBuilder;
+use Magento\Webapi\Controller\Rest\Response\DataObjectConverter;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class CustomAttributeSerializationTest extends \Magento\Webapi\Routing\BaseService
+{
+    /**
+     * @var string
+     */
+    protected $_version;
+    /**
+     * @var string
+     */
+    protected $_restResourcePath;
+    /**
+     * @var string
+     */
+    protected $_soapService = 'testModule1AllSoapAndRest';
+
+    /**
+     * @var ItemBuilder
+     */
+    protected $itemBuilder;
+
+    /**
+     * @var \Magento\TestModule1\Service\V1\Entity\CustomAttributeNestedDataObjectBuilder
+     */
+    protected $customAttributeNestedDataObjectBuilder;
+
+    /**
+     * @var \Magento\TestModule1\Service\V1\Entity\CustomAttributeDataObjectBuilder
+     */
+    protected $customAttributeDataObjectBuilder;
+
+    /**
+     * @var DataObjectConverter $dataObjectConverter
+     */
+    protected $dataObjectConverter;
+
+    /**
+     * Set up custom attribute related data objects
+     */
+    protected function setUp()
+    {
+        $this->_version = 'V1';
+        $this->_soapService = 'testModule1AllSoapAndRestV1';
+        $this->_restResourcePath = "/{$this->_version}/testmodule1/";
+
+        $this->itemBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\TestModule1\Service\V1\Entity\ItemBuilder'
+        );
+
+        $this->customAttributeNestedDataObjectBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\TestModule1\Service\V1\Entity\CustomAttributeNestedDataObjectBuilder'
+        );
+
+        $this->customAttributeDataObjectBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\TestModule1\Service\V1\Entity\CustomAttributeDataObjectBuilder'
+        );
+
+        $this->dataObjectConverter = Bootstrap::getObjectManager()->create(
+            'Magento\Webapi\Controller\Rest\Response\DataObjectConverter'
+        );
+    }
+
+    public function testSimpleAndNonExistentCustomAttributes()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . 'itemAnyType',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'ItemAnyType'],
+        ];
+        $requestData = [
+            'item_id' => 1,
+            'name' => 'testProductAnyType',
+            'custom_attributes' => [
+                    'non_existent' => [
+                            'attribute_code' => 'non_existent',
+                            'value' => 'test',
+                        ],
+                    'custom_attribute_string' => [
+                            'attribute_code' => 'custom_attribute_string',
+                            'value' => 'someStringValue',
+                        ],
+                ],
+        ];
+        $result = $this->_webApiCall($serviceInfo, ['entityItem' => $requestData]);
+
+        //The non_existent custom attribute should be dropped since its not a defined custom attribute
+        $expectedResponse = [
+            'item_id' => 1,
+            'name' => 'testProductAnyType',
+            'custom_attributes' => [
+                    [
+                        'attribute_code' => 'custom_attribute_string',
+                        'value' => 'someStringValue',
+                    ],
+                ],
+        ];
+
+        //\Magento\TestModule1\Service\V1\AllSoapAndRest::itemAnyType just return the input data back as response
+        $this->assertEquals($expectedResponse, $result);
+    }
+
+    public function testDataObjectCustomAttributes()
+    {
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            $this->markTestIncomplete('MAGETWO-31016: incompatible with ZF 1.12.9');
+        }
+        $customAttributeDataObject = $this->customAttributeDataObjectBuilder
+            ->setName('nameValue')
+            ->setCustomAttribute('custom_attribute_int', 1)
+            ->create();
+
+        $item = $this->itemBuilder
+            ->setItemId(1)
+            ->setName('testProductAnyType')
+            ->setCustomAttribute('custom_attribute_data_object', $customAttributeDataObject)
+            ->setCustomAttribute('custom_attribute_string', 'someStringValue')
+            ->create();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . 'itemAnyType',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'ItemAnyType'],
+        ];
+        $requestData = $item->__toArray();
+        $result = $this->_webApiCall($serviceInfo, ['entityItem' => $requestData]);
+
+        $expectedResponse = $this->dataObjectConverter->processServiceOutput(
+            $item,
+            '\Magento\TestModule1\Service\V1\AllSoapAndRestInterface',
+            'itemAnyType'
+        );
+        //\Magento\TestModule1\Service\V1\AllSoapAndRest::itemAnyType just return the input data back as response
+        $this->assertEquals($expectedResponse, $result);
+    }
+
+    public function testDataObjectCustomAttributesPreconfiguredItem()
+    {
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            $this->markTestIncomplete('MAGETWO-31016: incompatible with ZF 1.12.9');
+        }
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . 'itemPreconfigured',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'GetPreconfiguredItem'],
+        ];
+
+        $result = $this->_webApiCall($serviceInfo, []);
+
+        $customAttributeDataObject = $this->customAttributeDataObjectBuilder
+            ->setName('nameValue')
+            ->setCustomAttribute('custom_attribute_int', 1)
+            ->create();
+
+        $item = $this->itemBuilder
+            ->setItemId(1)
+            ->setName('testProductAnyType')
+            ->setCustomAttribute('custom_attribute_data_object', $customAttributeDataObject)
+            ->setCustomAttribute('custom_attribute_string', 'someStringValue')
+            ->create();
+        $expectedResponse = $this->dataObjectConverter->processServiceOutput(
+            $item,
+            '\Magento\TestModule1\Service\V1\AllSoapAndRestInterface',
+            'getPreconfiguredItem'
+        );
+        $this->assertEquals($expectedResponse, $result);
+    }
+
+    public function testNestedDataObjectCustomAttributes()
+    {
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            $this->markTestIncomplete('MAGETWO-31016: incompatible with ZF 1.12.9');
+        }
+        $customAttributeNestedDataObject = $this->customAttributeNestedDataObjectBuilder
+            ->setName('nestedNameValue')
+            ->create();
+
+        $customAttributeDataObject = $this->customAttributeDataObjectBuilder
+            ->setName('nameValue')
+            ->setCustomAttribute('custom_attribute_nested', $customAttributeNestedDataObject)
+            ->setCustomAttribute('custom_attribute_int', 1)
+            ->create();
+
+        $item = $this->itemBuilder
+            ->setItemId(1)
+            ->setName('testProductAnyType')
+            ->setCustomAttribute('custom_attribute_data_object', $customAttributeDataObject)
+            ->setCustomAttribute('custom_attribute_string', 'someStringValue')
+            ->create();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . 'itemAnyType',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'ItemAnyType'],
+        ];
+        $requestData = $item->__toArray();
+        $result = $this->_webApiCall($serviceInfo, ['entityItem' => $requestData]);
+
+        $expectedResponse = $this->dataObjectConverter->processServiceOutput(
+            $item,
+            '\Magento\TestModule1\Service\V1\AllSoapAndRestInterface',
+            'itemAnyType'
+        );
+        //\Magento\TestModule1\Service\V1\AllSoapAndRest::itemAnyType just return the input data back as response
+        $this->assertEquals($expectedResponse, $result);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/DataObjectSerialization/ServiceSerializationTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/DataObjectSerialization/ServiceSerializationTest.php
new file mode 100644
index 00000000000..ce7aa7ea452
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/DataObjectSerialization/ServiceSerializationTest.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Webapi\DataObjectSerialization;
+
+class ServiceSerializationTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    /**
+     * @var string
+     */
+    protected $_version;
+
+    /**
+     * @var string
+     */
+    protected $_restResourcePath;
+
+    protected function setUp()
+    {
+        $this->_markTestAsRestOnly();
+        $this->_version = 'V1';
+        $this->_restResourcePath = "/{$this->_version}/testmodule4/";
+    }
+
+    /**
+     *  Test simple request data
+     */
+    public function testGetServiceCall()
+    {
+        $itemId = 1;
+        $name = 'Test';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . $itemId,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+        ];
+        $item = $this->_webApiCall($serviceInfo, []);
+        $this->assertEquals($itemId, $item['entity_id'], 'id field returned incorrectly');
+        $this->assertEquals($name, $item['name'], 'name field returned incorrectly');
+    }
+
+    /**
+     *  Test multiple params with Data Object
+     */
+    public function testUpdateServiceCall()
+    {
+        $itemId = 1;
+        $name = 'Test';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . $itemId,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+            ],
+        ];
+        $item = $this->_webApiCall($serviceInfo, ['request' => ['name' => $name]]);
+        $this->assertEquals($itemId, $item['entity_id'], 'id field returned incorrectly');
+        $this->assertEquals($name, $item['name'], 'name field returned incorrectly');
+    }
+
+    /**
+     *  Test nested Data Object
+     */
+    public function testNestedDataObjectCall()
+    {
+        $itemId = 1;
+        $name = 'Test';
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . $itemId . '/nested',
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+            ],
+        ];
+        $item = $this->_webApiCall($serviceInfo, ['request' => ['details' => ['name' => $name]]]);
+        $this->assertEquals($itemId, $item['entity_id'], 'id field returned incorrectly');
+        $this->assertEquals($name, $item['name'], 'name field returned incorrectly');
+    }
+
+    public function testScalarResponse()
+    {
+        $id = 2;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => "{$this->_restResourcePath}scalar/{$id}",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+        ];
+        $this->assertEquals($id, $this->_webApiCall($serviceInfo), 'Scalar service output is serialized incorrectly.');
+    }
+
+    public function testExtensibleCall()
+    {
+        $id = 2;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => "{$this->_restResourcePath}extensibleDataObject/{$id}",
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_POST,
+            ],
+        ];
+
+        $name = 'Magento';
+        $requestData = [
+          'name' => $name,
+        ];
+        $item = $this->_webApiCall($serviceInfo, ['request' => $requestData]);
+        $this->assertEquals($id, $item['entity_id'], 'id field returned incorrectly');
+        $this->assertEquals($name, $item['name'], 'name field returned incorrectly');
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/DeserializationTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/DeserializationTest.php
new file mode 100644
index 00000000000..06a701a2ec6
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/DeserializationTest.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Webapi;
+
+use Magento\TestFramework\TestCase\Webapi\Adapter\Rest\CurlClient;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class DeserializationTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    /**
+     * @var string
+     */
+    protected $_version;
+
+    /**
+     * @var string
+     */
+    protected $_restResourcePath;
+
+    protected function setUp()
+    {
+        $this->_version = 'V1';
+        $this->_restResourcePath = "/{$this->_version}/TestModule5/";
+    }
+
+    /**
+     *  Test POST request with empty body
+     */
+    public function testPostRequestWithEmptyBody()
+    {
+        $this->_markTestAsRestOnly();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath,
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+        ];
+        $expectedMessage = '{"message":"%fieldName is a required field.","parameters":{"fieldName":"item"}}';
+        try {
+            $this->_webApiCall($serviceInfo, CurlClient::EMPTY_REQUEST_BODY);
+        } catch (\Exception $e) {
+            $this->assertEquals(\Magento\Webapi\Exception::HTTP_BAD_REQUEST, $e->getCode());
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "Response does not contain expected message."
+            );
+        }
+    }
+
+    /**
+     *  Test PUT request with empty body
+     */
+    public function testPutRequestWithEmptyBody()
+    {
+        $this->_markTestAsRestOnly();
+        $itemId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . $itemId,
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+        ];
+        $expectedMessage = '{"message":"%fieldName is a required field.","parameters":{"fieldName":"entityItem"}}';
+        try {
+            $this->_webApiCall($serviceInfo, CurlClient::EMPTY_REQUEST_BODY);
+        } catch (\Exception $e) {
+            $this->assertEquals(\Magento\Webapi\Exception::HTTP_BAD_REQUEST, $e->getCode());
+            $this->assertContains(
+                $expectedMessage,
+                $e->getMessage(),
+                "Response does not contain expected message."
+            );
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/PartialResponseTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/PartialResponseTest.php
new file mode 100644
index 00000000000..36b79d9157b
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/PartialResponseTest.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Webapi;
+
+use Magento\Customer\Api\AccountManagementTest;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestFramework\Helper\Customer as CustomerHelper;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class PartialResponseTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    /** @var CustomerHelper */
+    protected $customerHelper;
+
+    /** @var string */
+    protected $customerData;
+
+    protected function setUp()
+    {
+        $this->_markTestAsRestOnly('Partial response functionality available in REST mode only.');
+
+        $this->customerHelper = Bootstrap::getObjectManager()
+            ->get('Magento\TestFramework\Helper\Customer');
+
+        $this->customerData = $this->customerHelper->createSampleCustomer();
+    }
+
+    public function testCustomerWithEmailFilter()
+    {
+        $filter = 'email';
+        $expected = ['email' => $this->customerData['email']];
+        $result = $this->_getCustomerWithFilter($filter, $this->customerData['id']);
+        $this->assertEquals($expected, $result);
+    }
+
+    public function testCustomerWithEmailAndAddressFilter()
+    {
+        $filter = 'email,addresses[city]';
+        $expected = [
+            'email' => $this->customerData['email'],
+            'addresses' => [
+                ['city' => CustomerHelper::ADDRESS_CITY1],
+                ['city' => CustomerHelper::ADDRESS_CITY2],
+            ],
+        ];
+        $result = $this->_getCustomerWithFilter($filter, $this->customerData['id']);
+        $this->assertEquals($expected, $result);
+    }
+
+    public function testCustomerWithNestedAddressFilter()
+    {
+        $filter = 'addresses[region[region_code]]';
+        $expected = [
+            'addresses' => [
+                ['region' => ['region_code' => CustomerHelper::ADDRESS_REGION_CODE1]],
+                ['region' => ['region_code' => CustomerHelper::ADDRESS_REGION_CODE2]],
+            ],
+        ];
+        $result = $this->_getCustomerWithFilter($filter, $this->customerData['id']);
+        $this->assertEquals($expected, $result);
+    }
+
+    public function testCustomerInvalidFilter()
+    {
+        // Invalid filter should return an empty result
+        $result = $this->_getCustomerWithFilter('invalid', $this->customerData['id']);
+        $this->assertEmpty($result);
+    }
+
+    public function testFilterForCustomerApiWithSimpleResponse()
+    {
+        $result = $this->_getCustomerWithFilter('customers', $this->customerData['id'], '/permissions/readonly');
+        // assert if filter is ignored and a normal response is returned
+        $this->assertFalse($result);
+    }
+
+    protected function _getCustomerWithFilter($filter, $customerId, $path = '')
+    {
+        $resourcePath = sprintf(
+            '%s/%d%s?fields=%s',
+            AccountManagementTest::RESOURCE_PATH,
+            $customerId,
+            $path,
+            $filter
+        );
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $resourcePath,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+        ];
+
+        return $this->_webApiCall($serviceInfo);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/BaseService.php b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/BaseService.php
new file mode 100644
index 00000000000..5312762a3ae
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/BaseService.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Webapi\Routing;
+
+use Magento\Framework\Exception\AuthorizationException;
+use Magento\Webapi\Exception as WebapiException;
+
+/**
+ * Base class for all Service based routing tests
+ */
+abstract class BaseService extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    /**
+     * Check a particular adapter and assert unauthorized access
+     *
+     * @param array      $serviceInfo
+     * @param array|null $requestData
+     */
+    protected function assertUnauthorizedException($serviceInfo, $requestData = null)
+    {
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            $this->_assertSoapException($serviceInfo, $requestData, 'Consumer is not authorized to access %resources');
+        } elseif (TESTS_WEB_API_ADAPTER == self::ADAPTER_REST) {
+            $this->_assertRestUnauthorizedException($serviceInfo, $requestData);
+        }
+    }
+
+    /**
+     * Invoke the REST api and assert access is unauthorized
+     *
+     * @param array      $serviceInfo
+     * @param array|null $requestData
+     */
+    protected function _assertRestUnauthorizedException($serviceInfo, $requestData = null)
+    {
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+        } catch (\Exception $e) {
+            $this->assertContains(
+                '{"message":"' . AuthorizationException::NOT_AUTHORIZED . '"',
+                $e->getMessage(),
+                sprintf(
+                    'REST routing did not fail as expected for the method "%s" of service "%s"',
+                    $serviceInfo['rest']['httpMethod'],
+                    $serviceInfo['rest']['resourcePath']
+                )
+            );
+            $this->assertEquals(WebapiException::HTTP_UNAUTHORIZED, $e->getCode());
+        }
+    }
+
+    /**
+     * Check a particular adapter and assert the exception
+     *
+     * @param array      $serviceInfo
+     * @param array|null $requestData
+     */
+    protected function _assertNoRouteOrOperationException($serviceInfo, $requestData = null)
+    {
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            $this->_assertSoapException($serviceInfo, $requestData);
+        } elseif (TESTS_WEB_API_ADAPTER == self::ADAPTER_REST) {
+            $this->_assertNoRestRouteException($serviceInfo, $requestData);
+        }
+    }
+
+    /**
+     * Invoke the REST api and assert for test cases that no such REST route exist
+     *
+     * @param array      $serviceInfo
+     * @param array|null $requestData
+     */
+    protected function _assertNoRestRouteException($serviceInfo, $requestData = null)
+    {
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+        } catch (\Exception $e) {
+            $error = json_decode($e->getMessage(), true);
+            $this->assertEquals('Request does not match any route.', $error['message']);
+            $this->assertEquals(WebapiException::HTTP_NOT_FOUND, $e->getCode());
+        }
+    }
+
+    /**
+     * Invoke the SOAP api and assert for the NoWebApiXmlTestTest test cases that no such SOAP route exists
+     *
+     * @param array      $serviceInfo
+     * @param array|null $requestData
+     * @param string     $expectedMessage
+     */
+    protected function _assertSoapException($serviceInfo, $requestData = null, $expectedMessage = '')
+    {
+        try {
+            $this->_webApiCall($serviceInfo, $requestData);
+        } catch (\Exception $e) {
+            if (get_class($e) !== 'SoapFault') {
+                $this->fail(
+                    sprintf(
+                        'Expected SoapFault exception not generated for Service - "%s" and Operation - "%s"',
+                        $serviceInfo['soap']['service'],
+                        $serviceInfo['soap']['operation']
+                    )
+                );
+            }
+
+            if ($expectedMessage) {
+                $this->assertEquals($expectedMessage, $e->getMessage());
+            }
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/CoreRoutingTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/CoreRoutingTest.php
new file mode 100644
index 00000000000..e1959e4f59f
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/CoreRoutingTest.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+/**
+ * Class to test Core Web API routing
+ */
+namespace Magento\Webapi\Routing;
+
+class CoreRoutingTest extends \Magento\Webapi\Routing\BaseService
+{
+    public function testBasicRoutingExplicitPath()
+    {
+        $itemId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/testmodule1/' . $itemId,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => 'testModule1AllSoapAndRestV1',
+                'operation' => 'testModule1AllSoapAndRestV1Item',
+            ],
+        ];
+        $requestData = ['itemId' => $itemId];
+        $item = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals('testProduct1', $item['name'], "Item was retrieved unsuccessfully");
+    }
+
+    public function testDisabledIntegrationAuthorizationException()
+    {
+        $itemId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/testmodule1/' . $itemId,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => 'testModule1AllSoapAndRestV1',
+                'operation' => 'testModule1AllSoapAndRestV1Item',
+            ],
+        ];
+        $requestData = ['itemId' => $itemId];
+
+        /** Disable integration associated with active OAuth credentials. */
+        $credentials = \Magento\TestFramework\Authentication\OauthHelper::getApiAccessCredentials();
+        /** @var \Magento\Integration\Model\Integration $integration */
+        $integration = $credentials['integration'];
+        $originalStatus = $integration->getStatus();
+        $integration->setStatus(\Magento\Integration\Model\Integration::STATUS_INACTIVE)->save();
+
+        try {
+            $this->assertUnauthorizedException($serviceInfo, $requestData);
+        } catch (\Exception $e) {
+            /** Restore original status of integration associated with active OAuth credentials */
+            $integration->setStatus($originalStatus)->save();
+            throw $e;
+        }
+        $integration->setStatus($originalStatus)->save();
+    }
+
+    public function testExceptionSoapInternalError()
+    {
+        $this->_markTestAsSoapOnly();
+        $serviceInfo = [
+            'soap' => [
+                'service' => 'testModule3ErrorV1',
+                'operation' => 'testModule3ErrorV1ServiceException',
+            ],
+        ];
+        $this->setExpectedException('SoapFault', 'Generic service exception');
+        $this->_webApiCall($serviceInfo);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/GettersTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/GettersTest.php
new file mode 100644
index 00000000000..5dfc7fb4a6e
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/GettersTest.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Webapi\Routing;
+
+use Magento\TestModule5\Service\V1\Entity\AllSoapAndRest;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class GettersTest extends \Magento\Webapi\Routing\BaseService
+{
+    /**
+     * @var string
+     */
+    protected $_version;
+
+    /**
+     * @var string
+     */
+    protected $_restResourcePath;
+
+    /**
+     * @var string
+     */
+    protected $_soapService = 'testModule5AllSoapAndRest';
+
+    protected function setUp()
+    {
+        $this->_version = 'V1';
+        $this->_soapService = "testModule5AllSoapAndRest{$this->_version}";
+        $this->_restResourcePath = "/{$this->_version}/TestModule5/";
+    }
+
+    public function testGetters()
+    {
+        $itemId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . $itemId,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => $this->_soapService,
+                'operation' => $this->_soapService . 'Item',
+            ],
+        ];
+        $requestData = [AllSoapAndRest::ID => $itemId];
+        $item = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals($itemId, $item[AllSoapAndRest::ID], 'Item was retrieved unsuccessfully');
+        $isEnabled = isset($item[AllSoapAndRest::ENABLED]) && $item[AllSoapAndRest::ENABLED] === true;
+        $this->assertTrue($isEnabled, 'Getter with "is" prefix is processed incorrectly.');
+        $hasOrder = isset($item[AllSoapAndRest::HAS_ORDERS]) && $item[AllSoapAndRest::HAS_ORDERS] === true;
+        $this->assertTrue($hasOrder, 'Getter with "has" prefix is processed incorrectly.');
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/NoWebApiXmlTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/NoWebApiXmlTest.php
new file mode 100644
index 00000000000..819429fb003
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/NoWebApiXmlTest.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Webapi\Routing;
+
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+/**
+ * Class to test routing with a service that has no webapi.xml
+ */
+class NoWebApiXmlTest extends \Magento\Webapi\Routing\BaseService
+{
+    /**
+     * @var string
+     */
+    private $_version;
+
+    /**
+     * @var string
+     */
+    private $_restResourcePath;
+
+    protected function setUp()
+    {
+        $this->_version = 'V1';
+        $this->_restResourcePath = "/{$this->_version}/testModule2NoWebApiXml/";
+    }
+
+    /**
+     *  Test get item
+     */
+    public function testItem()
+    {
+        $this->_markTestAsRestOnly();
+        $itemId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . $itemId,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+        ];
+        $requestData = ['id' => $itemId];
+        $this->_assertNoRestRouteException($serviceInfo, $requestData);
+    }
+
+    /**
+     * Test fetching all items
+     */
+    public function testItems()
+    {
+        $this->_markTestAsRestOnly();
+        $serviceInfo = [
+            'rest' => ['resourcePath' => $this->_restResourcePath, 'httpMethod' => RestConfig::HTTP_METHOD_GET],
+        ];
+        $this->_assertNoRestRouteException($serviceInfo);
+    }
+
+    /**
+     *  Test create item
+     */
+    public function testCreate()
+    {
+        $this->_markTestAsRestOnly();
+        $createdItemName = 'createdItemName';
+        $serviceInfo = [
+            'rest' => ['resourcePath' => $this->_restResourcePath, 'httpMethod' => RestConfig::HTTP_METHOD_POST],
+        ];
+        $requestData = ['name' => $createdItemName];
+        $this->_assertNoRestRouteException($serviceInfo, $requestData);
+    }
+
+    /**
+     *  Test update item
+     */
+    public function testUpdate()
+    {
+        $this->_markTestAsRestOnly();
+        $itemId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . $itemId,
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+        ];
+        $requestData = ['id' => $itemId];
+        $this->_assertNoRestRouteException($serviceInfo, $requestData);
+    }
+
+    /**
+     *  Test remove item
+     */
+    public function testRemove()
+    {
+        $this->_markTestAsRestOnly();
+        $itemId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . $itemId,
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+        ];
+        $requestData = ['id' => $itemId];
+        $this->_assertNoRestRouteException($serviceInfo, $requestData);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/RequestIdOverrideTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/RequestIdOverrideTest.php
new file mode 100644
index 00000000000..6ed32b0349f
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/RequestIdOverrideTest.php
@@ -0,0 +1,160 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Webapi\Routing;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+/**
+ * Class to test overriding request body identifier property with id passed in url path parameter
+ *
+ * Refer to \Magento\Webapi\Controller\Rest\Request::overrideRequestBodyIdWithPathParam
+ */
+class RequestIdOverrideTest extends \Magento\Webapi\Routing\BaseService
+{
+    /**
+     * @var string
+     */
+    protected $_version;
+
+    /**
+     * @var string
+     */
+    protected $_restResourcePath;
+
+    /**
+     * @var \Magento\TestModule5\Service\V1\Entity\AllSoapAndRestBuilder
+     */
+    protected $itemBuilder;
+
+    /**
+     * @var string
+     */
+    protected $_soapService = 'testModule5AllSoapAndRest';
+
+    protected function setUp()
+    {
+        $this->_markTestAsRestOnly('Request Id overriding is a REST based feature.');
+        $this->_version = 'V1';
+        $this->_restResourcePath = "/{$this->_version}/TestModule5/";
+        $this->itemBuilder = Bootstrap::getObjectManager()
+            ->create('Magento\TestModule5\Service\V1\Entity\AllSoapAndRestBuilder');
+    }
+
+    public function testOverride()
+    {
+        $itemId = 1;
+        $incorrectItemId = 2;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . $itemId,
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+        ];
+        $item = $this->itemBuilder
+            ->setEntityId($incorrectItemId)
+            ->setName('test')
+            ->create();
+        $requestData = ['entityItem' => $item->__toArray()];
+        $item = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(
+            $itemId,
+            $item[\Magento\TestModule5\Service\V1\Entity\AllSoapAndRest::ID],
+            'Identifier overriding failed.'
+        );
+    }
+
+    public function testOverrideNested()
+    {
+        $firstItemId = 1;
+        $secondItemId = 11;
+        $incorrectItemId = 2;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . $firstItemId . '/nestedResource/' . $secondItemId,
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+        ];
+        $item = $this->itemBuilder
+            ->setEntityId($incorrectItemId)
+            ->setName('test')
+            ->create();
+        $requestData = ['entityItem' => $item->__toArray()];
+        $item = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(
+            $secondItemId,
+            $item[\Magento\TestModule5\Service\V1\Entity\AllSoapAndRest::ID],
+            'Identifier overriding failed for nested resource request.'
+        );
+    }
+
+    public function testOverrideAdd()
+    {
+        $itemId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . $itemId,
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+        ];
+        $item = $this->itemBuilder
+            ->setName('test')
+            ->create();
+        $requestData = ['entityItem' => $item->__toArray()];
+        $item = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(
+            $itemId,
+            $item[\Magento\TestModule5\Service\V1\Entity\AllSoapAndRest::ID],
+            'Identifier replacing failed.'
+        );
+    }
+
+    /**
+     * Test if the framework works if camelCase path parameters are provided instead of valid snake case ones.
+     * Webapi Framework currently accepts both cases due to shortcoming in Serialization (MAGETWO-29833).
+     * Unless it is fixed this use case is valid.
+     */
+    public function testAddCaseMismatch()
+    {
+        $itemId = 1;
+        $incorrectItemId = 2;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . $itemId,
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+        ];
+        $requestData = ['entityItem' => ['entityId' => $incorrectItemId, 'name' => 'test']];
+        $item = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(
+            $itemId,
+            $item[\Magento\TestModule5\Service\V1\Entity\AllSoapAndRest::ID],
+            'Identifier overriding failed.'
+        );
+    }
+
+    public function testOverrideWithScalarValues()
+    {
+        $firstItemId = 1;
+        $secondItemId = 11;
+        $incorrectItemId = 2;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => "/{$this->_version}/TestModule5/OverrideService/" . $firstItemId
+                    . '/nestedResource/' . $secondItemId,
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+        ];
+
+        $requestData = ['entity_id' => $incorrectItemId, 'name' => 'test', 'orders' => true];
+        $item = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals(
+            $secondItemId,
+            $item[\Magento\TestModule5\Service\V1\Entity\AllSoapAndRest::ID],
+            'Identifier overriding failed.'
+        );
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/RestErrorHandlingTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/RestErrorHandlingTest.php
new file mode 100644
index 00000000000..18d169911f9
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/RestErrorHandlingTest.php
@@ -0,0 +1,160 @@
+<?php
+/**
+ * Test Web API error codes.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Webapi\Routing;
+
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Webapi\Exception as WebapiException;
+
+class RestErrorHandlingTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    /**
+     * @var string
+     */
+    protected $mode;
+
+    protected function setUp()
+    {
+        $this->_markTestAsRestOnly();
+        $this->mode = Bootstrap::getObjectManager()->get('Magento\Framework\App\State')->getMode();
+        parent::setUp();
+    }
+
+    public function testSuccess()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/errortest/success',
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+        ];
+
+        $item = $this->_webApiCall($serviceInfo);
+
+        // TODO: check Http Status = 200, cannot do yet due to missing header info returned
+
+        $this->assertEquals('a good id', $item['value'], 'Success case is correct');
+    }
+
+    public function testNotFound()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/errortest/notfound',
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+        ];
+
+        // \Magento\Framework\Api\ResourceNotFoundException
+        $this->_errorTest(
+            $serviceInfo,
+            ['resource_id' => 'resourceY'],
+            WebapiException::HTTP_NOT_FOUND,
+            'Resource with ID "%resource_id" not found.'
+        );
+    }
+
+    public function testUnauthorized()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/errortest/unauthorized',
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+        ];
+
+        // \Magento\Framework\Api\AuthorizationException
+        $this->_errorTest(
+            $serviceInfo,
+            [],
+            WebapiException::HTTP_UNAUTHORIZED,
+            'Consumer is not authorized to access %resources',
+            ['resources' => 'resourceN']
+        );
+    }
+
+    public function testOtherException()
+    {
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => '/V1/errortest/otherexception',
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+        ];
+
+        /* TODO : Fix as part MAGETWO-31330
+        $expectedMessage = $this->mode == \Magento\Framework\App\State::MODE_DEVELOPER
+            ? 'Non service exception'
+            : 'Internal Error. Details are available in Magento log file. Report ID: webapi-XXX';
+        */
+        $expectedMessage = 'Internal Error. Details are available in Magento log file. Report ID: webapi-XXX';
+        $this->_errorTest(
+            $serviceInfo,
+            [],
+            WebapiException::HTTP_INTERNAL_ERROR,
+            $expectedMessage,
+            null,
+            'Magento\TestModule3\Service\V1\Error->otherException()' // Check if trace contains proper error source
+        );
+    }
+
+    /**
+     * Perform a negative REST api call test case and compare the results with expected values.
+     *
+     * @param string $serviceInfo - REST Service information (i.e. resource path and HTTP method)
+     * @param array $data - Data for the cal
+     * @param int $httpStatus - Expected HTTP status
+     * @param string|array $errorMessage - \Exception error message
+     * @param array $parameters - Optional parameters array, or null if no parameters
+     * @param string $traceString - Optional trace string to verify
+     */
+    protected function _errorTest(
+        $serviceInfo,
+        $data,
+        $httpStatus,
+        $errorMessage,
+        $parameters = [],
+        $traceString = null
+    ) {
+        try {
+            $this->_webApiCall($serviceInfo, $data);
+        } catch (\Exception $e) {
+            $this->assertEquals($httpStatus, $e->getCode(), 'Checking HTTP status code');
+
+            $body = json_decode($e->getMessage(), true);
+
+            $errorMessages = is_array($errorMessage) ? $errorMessage : [$errorMessage];
+            $actualMessage = $body['message'];
+            $matches = [];
+            //Report ID was created dynamically, so we need to replace it with some static value in order to test
+            if (preg_match('/.*Report\sID\:\s([a-zA-Z0-9\-]*)/', $actualMessage, $matches)) {
+                $actualMessage = str_replace($matches[1], 'webapi-XXX', $actualMessage);
+            }
+            //make sure that the match for a report with an id is found if Internal error was reported
+            //Refer : \Magento\Webapi\Controller\ErrorProcessor::INTERNAL_SERVER_ERROR_MSG
+            if (count($matches) > 1) {
+                $this->assertTrue(!empty($matches[1]), 'Report id missing for internal error.');
+            }
+            $this->assertContains(
+                $actualMessage,
+                $errorMessages,
+                "Message is invalid. Actual: '{$actualMessage}'. Expected one of: {'" . implode(
+                    "', '",
+                    $errorMessages
+                ) . "'}"
+            );
+
+            if ($parameters) {
+                $this->assertEquals($parameters, $body['parameters'], 'Checking body parameters');
+            }
+
+            if ($this->mode == \Magento\Framework\App\State::MODE_DEVELOPER && $traceString) {
+                // TODO : Fix as part MAGETWO-31330
+                //$this->assertContains($traceString, $body['trace'], 'Trace information is incorrect.');
+            }
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/ServiceVersionV1Test.php b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/ServiceVersionV1Test.php
new file mode 100644
index 00000000000..d0e97d268f3
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/ServiceVersionV1Test.php
@@ -0,0 +1,267 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+/**
+ * Class to test routing based on Service Versioning(for V1 version of a service)
+ */
+namespace Magento\Webapi\Routing;
+
+use Magento\Framework\Api\AttributeValue;
+use Magento\TestFramework\Authentication\OauthHelper;
+use Magento\TestFramework\Helper\Bootstrap;
+use Magento\TestModule1\Service\V1\Entity\ItemBuilder;
+use Magento\Webapi\Model\Rest\Config as RestConfig;
+
+class ServiceVersionV1Test extends \Magento\Webapi\Routing\BaseService
+{
+    /**
+     * @var string
+     */
+    protected $_version;
+    /**
+     * @var string
+     */
+    protected $_restResourcePath;
+    /**
+     * @var string
+     */
+    protected $_soapService = 'testModule1AllSoapAndRest';
+
+    /** @var \Magento\Framework\Api\AttributeDataBuilder */
+    protected $valueBuilder;
+
+    /** @var ItemBuilder */
+    protected $itemBuilder;
+
+    protected function setUp()
+    {
+        $this->_version = 'V1';
+        $this->_soapService = 'testModule1AllSoapAndRestV1';
+        $this->_restResourcePath = "/{$this->_version}/testmodule1/";
+
+        $this->valueBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\Framework\Api\AttributeDataBuilder'
+        );
+
+        $this->itemBuilder = Bootstrap::getObjectManager()->create(
+            'Magento\TestModule1\Service\V1\Entity\ItemBuilder'
+        );
+    }
+
+    /**
+     *  Test get item
+     */
+    public function testItem()
+    {
+        $itemId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . $itemId,
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'Item'],
+        ];
+        $requestData = ['itemId' => $itemId];
+        $item = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals('testProduct1', $item['name'], 'Item was retrieved unsuccessfully');
+    }
+
+    /**
+     *  Test get item with any type
+     */
+    public function testItemAnyType()
+    {
+        $this->_markTestAsRestOnly('Test will fail for SOAP because attribute values get converted to strings.');
+        $customerAttributes = [
+            ItemBuilder::CUSTOM_ATTRIBUTE_1 => [
+                AttributeValue::ATTRIBUTE_CODE => ItemBuilder::CUSTOM_ATTRIBUTE_1,
+                AttributeValue::VALUE => '12345',
+            ],
+            ItemBuilder::CUSTOM_ATTRIBUTE_2 => [
+                AttributeValue::ATTRIBUTE_CODE => ItemBuilder::CUSTOM_ATTRIBUTE_2,
+                AttributeValue::VALUE => 12345,
+            ],
+            ItemBuilder::CUSTOM_ATTRIBUTE_3 => [
+                AttributeValue::ATTRIBUTE_CODE => ItemBuilder::CUSTOM_ATTRIBUTE_3,
+                AttributeValue::VALUE => true,
+            ],
+        ];
+
+        $attributeValue1 = $this->valueBuilder
+            ->setAttributeCode(ItemBuilder::CUSTOM_ATTRIBUTE_1)
+            ->setValue('12345')
+            ->create();
+        $attributeValue2 = $this->valueBuilder
+            ->setAttributeCode(ItemBuilder::CUSTOM_ATTRIBUTE_2)
+            ->setValue(12345)
+            ->create();
+        $attributeValue3 = $this->valueBuilder
+            ->setAttributeCode(ItemBuilder::CUSTOM_ATTRIBUTE_3)
+            ->setValue(true)
+            ->create();
+
+        $item = $this->itemBuilder
+            ->setItemId(1)
+            ->setName('testProductAnyType')
+            ->setCustomAttributes([$attributeValue1, $attributeValue2, $attributeValue3])
+            ->create();
+
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . 'itemAnyType',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'ItemAnyType'],
+        ];
+        $requestData = $item->__toArray();
+        $item = $this->_webApiCall($serviceInfo, ['entityItem' => $requestData]);
+
+        $this->assertSame(
+            $attributeValue1->getValue(),
+            $item['custom_attributes'][0]['value'],
+            'Serialized attribute value type does\'t match pre-defined type.'
+        ); // string '12345' is expected
+
+        $this->assertSame(
+            $attributeValue2->getValue(),
+            $item['custom_attributes'][1]['value'],
+            'Serialized attribute value type does\'t match pre-defined type.'
+        ); // integer 12345 is expected
+
+        $this->assertSame(
+            $attributeValue3->getValue(),
+            $item['custom_attributes'][2]['value'],
+            'Serialized attribute value type does\'t match pre-defined type.'
+        ); // boolean true is expected
+    }
+
+    /**
+     * Test fetching all items
+     */
+    public function testItems()
+    {
+        $itemArr = [['item_id' => 1, 'name' => 'testProduct1'], ['item_id' => 2, 'name' => 'testProduct2']];
+        $serviceInfo = [
+            'rest' => ['resourcePath' => $this->_restResourcePath, 'httpMethod' => RestConfig::HTTP_METHOD_GET],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'Items'],
+        ];
+        $item = $this->_webApiCall($serviceInfo);
+        $this->assertEquals($itemArr, $item, 'Items were not retrieved');
+    }
+
+    /**
+     *  Test create item
+     */
+    public function testCreate()
+    {
+        $createdItemName = 'createdItemName';
+        $serviceInfo = [
+            'rest' => ['resourcePath' => $this->_restResourcePath, 'httpMethod' => RestConfig::HTTP_METHOD_POST],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'Create'],
+        ];
+        $requestData = ['name' => $createdItemName];
+        $item = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals($createdItemName, $item['name'], 'Item creation failed');
+    }
+
+    /**
+     *  Test create item with missing proper resources
+     */
+    public function testCreateWithoutResources()
+    {
+        $createdItemName = 'createdItemName';
+        $serviceInfo = [
+            'rest' => ['resourcePath' => $this->_restResourcePath, 'httpMethod' => RestConfig::HTTP_METHOD_POST],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'Create'],
+        ];
+        $requestData = ['name' => $createdItemName];
+
+        // getting new credentials that do not match the api resources
+        OauthHelper::clearApiAccessCredentials();
+        OauthHelper::getApiAccessCredentials([]);
+        try {
+            $this->assertUnauthorizedException($serviceInfo, $requestData);
+        } catch (\Exception $e) {
+            OauthHelper::clearApiAccessCredentials();
+            throw $e;
+        }
+        // to allow good credentials to be restored (this is statically stored on OauthHelper)
+        OauthHelper::clearApiAccessCredentials();
+    }
+
+    /**
+     *  Test update item
+     */
+    public function testUpdate()
+    {
+        $itemId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . $itemId,
+                'httpMethod' => RestConfig::HTTP_METHOD_PUT,
+            ],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'Update'],
+        ];
+        $requestData = ['entityItem' => ['itemId' => $itemId, 'name' => 'testName']];
+        $item = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals('Updated' . $requestData['entityItem']['name'], $item['name'], 'Item update failed');
+    }
+
+    /**
+     *  Negative Test: Invoking non-existent delete api which is only available in V2
+     */
+    public function testDelete()
+    {
+        $itemId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . $itemId,
+                'httpMethod' => RestConfig::HTTP_METHOD_DELETE,
+            ],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'Delete'],
+        ];
+        $requestData = ['itemId' => $itemId, 'name' => 'testName'];
+        $this->_assertNoRouteOrOperationException($serviceInfo, $requestData);
+    }
+
+    public function testOverwritten()
+    {
+        $this->_markTestAsRestOnly();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . 'overwritten',
+                'httpMethod' => RestConfig::HTTP_METHOD_GET,
+            ],
+        ];
+        $item = $this->_webApiCall($serviceInfo, []);
+        $this->assertEquals(['item_id' => -55, 'name' => 'testProduct1'], $item);
+    }
+
+    public function testDefaulted()
+    {
+        $this->_markTestAsRestOnly();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . 'testOptionalParam',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+        ];
+        $item = $this->_webApiCall($serviceInfo, []);
+        $this->assertEquals(['item_id' => 3, 'name' => 'Default Name'], $item);
+    }
+
+    public function testDefaultedWithValue()
+    {
+        $this->_markTestAsRestOnly();
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . 'testOptionalParam',
+                'httpMethod' => RestConfig::HTTP_METHOD_POST,
+            ],
+        ];
+        $item = $this->_webApiCall($serviceInfo, ['name' => 'Ms. LaGrange']);
+        $this->assertEquals(['item_id' => 3, 'name' => 'Ms. LaGrange'], $item);
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/ServiceVersionV2Test.php b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/ServiceVersionV2Test.php
new file mode 100644
index 00000000000..44707fb779d
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/ServiceVersionV2Test.php
@@ -0,0 +1,142 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+namespace Magento\Webapi\Routing;
+
+class ServiceVersionV2Test extends \Magento\Webapi\Routing\BaseService
+{
+    protected function setUp()
+    {
+        $this->_version = 'V2';
+        $this->_soapService = 'testModule1AllSoapAndRestV2';
+        $this->_restResourcePath = "/{$this->_version}/testmodule1/";
+    }
+
+    /**
+     *  Test to assert overriding of the existing 'Item' api in V2 version of the same service
+     */
+    public function testItem()
+    {
+        $itemId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . $itemId,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'Item'],
+        ];
+        $requestData = ['id' => $itemId];
+        $item = $this->_webApiCall($serviceInfo, $requestData);
+        // Asserting for additional attribute returned by the V2 api
+        $this->assertEquals(1, $item['price'], 'Item was retrieved unsuccessfully from V2');
+    }
+
+    /**
+     * Test fetching all items
+     */
+    public function testItems()
+    {
+        $itemArr = [
+            ['id' => 1, 'name' => 'testProduct1', 'price' => '1'],
+            ['id' => 2, 'name' => 'testProduct2', 'price' => '2'],
+        ];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'Items'],
+        ];
+        $item = $this->_webApiCall($serviceInfo);
+        $this->assertEquals($itemArr, $item, 'Items were not retrieved');
+    }
+
+    /**
+     * Test fetching items when filters are applied
+     *
+     * @param string[] $filters
+     * @param array $expectedResult
+     * @dataProvider itemsWithFiltersDataProvider
+     */
+    public function testItemsWithFilters($filters, $expectedResult)
+    {
+        $restFilter = '';
+        foreach ($filters as $filterItemKey => $filterMetadata) {
+            foreach ($filterMetadata as $filterMetaKey => $filterMetaValue) {
+                $paramsDelimiter = empty($restFilter) ? '?' : '&';
+                $restFilter .= "{$paramsDelimiter}filters[{$filterItemKey}][{$filterMetaKey}]={$filterMetaValue}";
+            }
+        }
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . $restFilter,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => [
+                'service' => $this->_soapService,
+                'operation' => $this->_soapService . 'Items',
+            ],
+        ];
+        $requestData = [];
+        if (!empty($filters)) {
+            $requestData['filters'] = $filters;
+        }
+        $item = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals($expectedResult, $item, 'Filtration does not seem to work correctly.');
+    }
+
+    public function itemsWithFiltersDataProvider()
+    {
+        $firstItem = ['id' => 1, 'name' => 'testProduct1', 'price' => 1];
+        $secondItem = ['id' => 2, 'name' => 'testProduct2', 'price' => 2];
+        return [
+            'Both items filter' => [
+                [
+                    ['field' => 'id', 'conditionType' => 'eq','value' => 1],
+                    ['field' => 'id', 'conditionType' => 'eq','value' => 2],
+                ],
+                [$firstItem, $secondItem],
+            ],
+            'First item filter' => [[['field' => 'id', 'conditionType' => 'eq','value' => 1]], [$firstItem]],
+            'Second item filter' => [[['field' => 'id', 'conditionType' => 'eq','value' => 2]], [$secondItem]],
+            'Empty filter' => [[], [$firstItem, $secondItem]],
+        ];
+    }
+
+    /**
+     *  Test update item
+     */
+    public function testUpdate()
+    {
+        $itemId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . $itemId,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_PUT,
+            ],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'Update'],
+        ];
+        $requestData = ['entityItem' => ['id' => $itemId, 'name' => 'testName', 'price' => '4']];
+        $item = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals('Updated' . $requestData['entityItem']['name'], $item['name'], 'Item update failed');
+    }
+
+    /**
+     *  Test to assert presence of new 'delete' api added in V2 version of the same service
+     */
+    public function testDelete()
+    {
+        $itemId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . $itemId,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_DELETE,
+            ],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'Delete'],
+        ];
+        $requestData = ['id' => $itemId, 'name' => 'testName'];
+        $item = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals($itemId, $item['id'], "Item delete failed");
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/SoapErrorHandlingTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/SoapErrorHandlingTest.php
new file mode 100644
index 00000000000..d84f5fe8198
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/SoapErrorHandlingTest.php
@@ -0,0 +1,163 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Webapi\Routing;
+
+use Magento\Framework\Exception\AuthorizationException;
+
+/**
+ * SOAP error handling test.
+ */
+class SoapErrorHandlingTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    protected function setUp()
+    {
+        $this->_markTestAsSoapOnly();
+        parent::setUp();
+    }
+
+    public function testWebapiException()
+    {
+        $serviceInfo = [
+            'soap' => [
+                'service' => 'testModule3ErrorV1',
+                'operation' => 'testModule3ErrorV1WebapiException',
+            ],
+        ];
+        try {
+            $this->_webApiCall($serviceInfo);
+            $this->fail("SoapFault was not raised as expected.");
+        } catch (\SoapFault $e) {
+            $this->checkSoapFault(
+                $e,
+                'Service not found',
+                'env:Sender'
+            );
+        }
+    }
+
+    public function testUnknownException()
+    {
+        $serviceInfo = [
+            'soap' => [
+                'service' => 'testModule3ErrorV1',
+                'operation' => 'testModule3ErrorV1OtherException',
+            ],
+        ];
+        try {
+            $this->_webApiCall($serviceInfo);
+            $this->fail("SoapFault was not raised as expected.");
+        } catch (\SoapFault $e) {
+            /** In developer mode message is masked, so checks should be different in two modes */
+            if (strpos($e->getMessage(), 'Internal Error') === false) {
+                $this->checkSoapFault(
+                    $e,
+                    'Non service exception',
+                    'env:Receiver',
+                    null,
+                    null,
+                    'Magento\TestModule3\Service\V1\Error->otherException()'
+                );
+            } else {
+                $this->checkSoapFault(
+                    $e,
+                    'Internal Error. Details are available in Magento log file. Report ID:',
+                    'env:Receiver'
+                );
+            }
+        }
+    }
+
+    public function testEmptyInputException()
+    {
+        $parameters = [];
+        $this->_testWrappedError($parameters);
+    }
+
+    public function testSingleWrappedErrorException()
+    {
+        $parameters = [
+            ['fieldName' => 'key1', 'value' => 'value1'],
+        ];
+        $this->_testWrappedError($parameters);
+    }
+
+    public function testMultipleWrappedErrorException()
+    {
+        $parameters = [
+            ['fieldName' => 'key1', 'value' => 'value1'],
+            ['fieldName' => 'key2', 'value' => 'value2'],
+        ];
+        $this->_testWrappedError($parameters);
+    }
+
+    public function testUnauthorized()
+    {
+        $serviceInfo = [
+            'soap' => [
+                'service' => 'testModule3ErrorV1',
+                'operation' => 'testModule3ErrorV1AuthorizationException',
+                'token' => 'invalidToken',
+            ],
+        ];
+
+        $expectedException = new AuthorizationException(
+            AuthorizationException::NOT_AUTHORIZED,
+            ['resources' => 'Magento_TestModule3::resource1, Magento_TestModule3::resource2']
+        );
+
+        try {
+            $this->_webApiCall($serviceInfo);
+            $this->fail("SoapFault was not raised as expected.");
+        } catch (\SoapFault $e) {
+            $this->checkSoapFault(
+                $e,
+                $expectedException->getRawMessage(),
+                'env:Sender',
+                $expectedException->getParameters() // expected error parameters
+            );
+        }
+    }
+
+    protected function _testWrappedError($parameters)
+    {
+        $serviceInfo = [
+            'soap' => [
+                'service' => 'testModule3ErrorV1',
+                'operation' => 'testModule3ErrorV1InputException',
+            ],
+        ];
+
+        $expectedException = new \Magento\Framework\Exception\InputException();
+        foreach ($parameters as $error) {
+            $expectedException->addError(\Magento\Framework\Exception\InputException::INVALID_FIELD_VALUE, $error);
+        }
+
+        $arguments = [
+            'wrappedErrorParameters' => $parameters,
+        ];
+
+        $expectedErrors = [];
+        foreach ($expectedException->getErrors() as $key => $error) {
+            $expectedErrors[$key] = [
+                'message' => $error->getRawMessage(),
+                'params' => $error->getParameters(),
+            ];
+        }
+
+        try {
+            $this->_webApiCall($serviceInfo, $arguments);
+            $this->fail("SoapFault was not raised as expected.");
+        } catch (\SoapFault $e) {
+            $this->checkSoapFault(
+                $e,
+                $expectedException->getRawMessage(),
+                'env:Sender',
+                $expectedException->getParameters(), // expected error parameters
+                $expectedErrors                      // expected wrapped errors
+            );
+        }
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/SubsetTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/SubsetTest.php
new file mode 100644
index 00000000000..e9b3aac72be
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/Routing/SubsetTest.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+/**
+ * Class to test routing based on a Service that exposes subset of operations
+ */
+namespace Magento\Webapi\Routing;
+
+class SubsetTest extends \Magento\Webapi\Routing\BaseService
+{
+    /**
+     * @var string
+     */
+    protected $_version;
+
+    /**
+     * @var string
+     */
+    protected $_restResourcePath;
+
+    /**
+     * @var string
+     */
+    protected $_soapService;
+
+    /**
+     * @Override
+     */
+    protected function setUp()
+    {
+        $this->_version = 'V1';
+        $this->_restResourcePath = "/{$this->_version}/testModule2SubsetRest/";
+        $this->_soapService = 'testModule2SubsetRestV1';
+    }
+
+    /**
+     * @Override
+     * Test get item
+     */
+    public function testItem()
+    {
+        $itemId = 1;
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath . $itemId,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'Item'],
+        ];
+        $requestData = ['id' => $itemId];
+        $item = $this->_webApiCall($serviceInfo, $requestData);
+        $this->assertEquals($itemId, $item['id'], 'Item was retrieved unsuccessfully');
+    }
+
+    /**
+     * @Override
+     * Test fetching all items
+     */
+    public function testItems()
+    {
+        $itemArr = [['id' => 1, 'name' => 'testItem1'], ['id' => 2, 'name' => 'testItem2']];
+        $serviceInfo = [
+            'rest' => [
+                'resourcePath' => $this->_restResourcePath,
+                'httpMethod' => \Magento\Webapi\Model\Rest\Config::HTTP_METHOD_GET,
+            ],
+            'soap' => ['service' => $this->_soapService, 'operation' => $this->_soapService . 'Items'],
+        ];
+
+        $item = $this->_webApiCall($serviceInfo);
+        $this->assertEquals($itemArr, $item, 'Items were not retrieved');
+    }
+}
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/WsdlGenerationFromDataObjectTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/WsdlGenerationFromDataObjectTest.php
new file mode 100644
index 00000000000..3f27b6179ec
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/WsdlGenerationFromDataObjectTest.php
@@ -0,0 +1,735 @@
+<?php
+/**
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ */
+
+namespace Magento\Webapi;
+
+use Magento\TestFramework\Helper\Bootstrap;
+
+/**
+ * Test WSDL generation mechanisms.
+ */
+class WsdlGenerationFromDataObjectTest extends \Magento\TestFramework\TestCase\WebapiAbstract
+{
+    /** @var string */
+    protected $_baseUrl = TESTS_BASE_URL;
+
+    /** @var string */
+    protected $_storeCode;
+
+    /** @var string */
+    protected $_soapUrl;
+
+    protected function setUp()
+    {
+        $this->_markTestAsSoapOnly("WSDL generation tests are intended to be executed for SOAP adapter only.");
+        $this->_storeCode = Bootstrap::getObjectManager()->get('Magento\Store\Model\StoreManagerInterface')
+            ->getStore()->getCode();
+        $this->_soapUrl = "{$this->_baseUrl}/soap/{$this->_storeCode}?services%3DtestModule5AllSoapAndRestV1%2CtestModule5AllSoapAndRestV2";
+        parent::setUp();
+    }
+
+    public function testMultiServiceWsdl()
+    {
+        if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
+            $this->markTestIncomplete('MAGETWO-31016: incompatible with ZF 1.12.9');
+        }
+        $wsdlUrl = $this->_getBaseWsdlUrl() . 'testModule5AllSoapAndRestV1,testModule5AllSoapAndRestV2';
+        $wsdlContent = $this->_convertXmlToString($this->_getWsdlContent($wsdlUrl));
+
+        $this->_checkTypesDeclaration($wsdlContent);
+        $this->_checkPortTypeDeclaration($wsdlContent);
+        $this->_checkBindingDeclaration($wsdlContent);
+        $this->_checkServiceDeclaration($wsdlContent);
+        $this->_checkMessagesDeclaration($wsdlContent);
+        $this->_checkFaultsDeclaration($wsdlContent);
+    }
+
+    public function testInvalidWsdlUrlNoServices()
+    {
+        $responseContent = $this->_getWsdlContent($this->_getBaseWsdlUrl());
+        $this->assertContains("Requested services are missing.", $responseContent);
+    }
+
+    public function testInvalidWsdlUrlInvalidParameter()
+    {
+        $wsdlUrl = $this->_getBaseWsdlUrl() . '&invalid';
+        $responseContent = $this->_getWsdlContent($wsdlUrl);
+        $this->assertContains("Not allowed parameters", $responseContent);
+    }
+
+    /**
+     * Remove unnecessary spaces and line breaks from xml string.
+     *
+     * @param string $xml
+     * @return string
+     */
+    protected function _convertXmlToString($xml)
+    {
+        return str_replace(['    ', "\n", "\r", "&#13;", "&#10;"], '', $xml);
+    }
+
+    /**
+     * Retrieve WSDL content.
+     *
+     * @param string $wsdlUrl
+     * @return string|boolean
+     */
+    protected function _getWsdlContent($wsdlUrl)
+    {
+        $connection = curl_init($wsdlUrl);
+        curl_setopt($connection, CURLOPT_RETURNTRANSFER, 1);
+        $responseContent = curl_exec($connection);
+        $responseDom = new \DOMDocument();
+        $this->assertTrue(
+            $responseDom->loadXML($responseContent),
+            "Valid XML is always expected as a response for WSDL request."
+        );
+        return $responseContent;
+    }
+
+    /**
+     * Generate base WSDL URL (without any services specified)
+     *
+     * @return string
+     */
+    protected function _getBaseWsdlUrl()
+    {
+        /** @var \Magento\TestFramework\TestCase\Webapi\Adapter\Soap $soapAdapter */
+        $soapAdapter = $this->_getWebApiAdapter(self::ADAPTER_SOAP);
+        $wsdlUrl = $soapAdapter->generateWsdlUrl([]);
+        return $wsdlUrl;
+    }
+
+    /**
+     * Ensure that types section has correct structure.
+     *
+     * @param string $wsdlContent
+     */
+    protected function _checkTypesDeclaration($wsdlContent)
+    {
+        // @codingStandardsIgnoreStart
+        $typesSectionDeclaration = <<< TYPES_SECTION_DECLARATION
+<types>
+    <xsd:schema targetNamespace="{$this->_soapUrl}">
+TYPES_SECTION_DECLARATION;
+        // @codingStandardsIgnoreEnd
+        $this->assertContains(
+            $this->_convertXmlToString($typesSectionDeclaration),
+            $wsdlContent,
+            'Types section declaration is invalid'
+        );
+        $this->_checkElementsDeclaration($wsdlContent);
+        $this->_checkComplexTypesDeclaration($wsdlContent);
+    }
+
+    /**
+     * @param string $wsdlContent
+     */
+    protected function _checkElementsDeclaration($wsdlContent)
+    {
+        $requestElement = <<< REQUEST_ELEMENT
+<xsd:element name="testModule5AllSoapAndRestV1ItemRequest" type="tns:TestModule5AllSoapAndRestV1ItemRequest"/>
+REQUEST_ELEMENT;
+        $this->assertContains(
+            $this->_convertXmlToString($requestElement),
+            $wsdlContent,
+            'Request element declaration in types section is invalid'
+        );
+        $responseElement = <<< RESPONSE_ELEMENT
+<xsd:element name="testModule5AllSoapAndRestV1ItemResponse" type="tns:TestModule5AllSoapAndRestV1ItemResponse"/>
+RESPONSE_ELEMENT;
+        $this->assertContains(
+            $this->_convertXmlToString($responseElement),
+            $wsdlContent,
+            'Response element declaration in types section is invalid'
+        );
+    }
+
+    /**
+     * @param string $wsdlContent
+     */
+    protected function _checkComplexTypesDeclaration($wsdlContent)
+    {
+        // @codingStandardsIgnoreStart
+        $requestType = <<< REQUEST_TYPE
+<xsd:complexType name="TestModule5AllSoapAndRestV1ItemRequest">
+    <xsd:annotation>
+        <xsd:documentation>Retrieve an item.</xsd:documentation>
+        <xsd:appinfo xmlns:inf="{$this->_soapUrl}"/>
+    </xsd:annotation>
+    <xsd:sequence>
+        <xsd:element name="entityId" minOccurs="1" maxOccurs="1" type="xsd:int">
+            <xsd:annotation>
+                <xsd:documentation></xsd:documentation>
+                <xsd:appinfo xmlns:inf="{$this->_soapUrl}">
+                    <inf:min/>
+                    <inf:max/>
+                    <inf:callInfo>
+                        <inf:callName>testModule5AllSoapAndRestV1Item</inf:callName>
+                        <inf:requiredInput>Yes</inf:requiredInput>
+                    </inf:callInfo>
+                </xsd:appinfo>
+            </xsd:annotation>
+        </xsd:element>
+    </xsd:sequence>
+</xsd:complexType>
+REQUEST_TYPE;
+        // @codingStandardsIgnoreEnd
+        $this->assertContains(
+            $this->_convertXmlToString($requestType),
+            $wsdlContent,
+            'Request type declaration in types section is invalid'
+        );
+        // @codingStandardsIgnoreStart
+        $responseType = <<< RESPONSE_TYPE
+<xsd:complexType name="TestModule5AllSoapAndRestV1ItemResponse">
+    <xsd:annotation>
+        <xsd:documentation>
+            Response container for the testModule5AllSoapAndRestV1Item call.
+        </xsd:documentation>
+        <xsd:appinfo xmlns:inf="{$this->_soapUrl}"/>
+    </xsd:annotation>
+    <xsd:sequence>
+        <xsd:element name="result" minOccurs="1" maxOccurs="1" type="tns:TestModule5V1EntityAllSoapAndRest">
+            <xsd:annotation>
+                <xsd:documentation></xsd:documentation>
+                <xsd:appinfo xmlns:inf="{$this->_soapUrl}">
+                    <inf:callInfo>
+                        <inf:callName>testModule5AllSoapAndRestV1Item</inf:callName>
+                        <inf:returned>Always</inf:returned>
+                    </inf:callInfo>
+                </xsd:appinfo>
+            </xsd:annotation>
+        </xsd:element>
+    </xsd:sequence>
+</xsd:complexType>
+RESPONSE_TYPE;
+        // @codingStandardsIgnoreEnd
+        $this->assertContains(
+            $this->_convertXmlToString($responseType),
+            $wsdlContent,
+            'Response type declaration in types section is invalid'
+        );
+        $this->_checkReferencedTypeDeclaration($wsdlContent);
+    }
+
+    /**
+     * Ensure that complex type generated from Data Object is correct.
+     *
+     * @param string $wsdlContent
+     */
+    protected function _checkReferencedTypeDeclaration($wsdlContent)
+    {
+        // @codingStandardsIgnoreStart
+        $referencedType = <<< RESPONSE_TYPE
+<xsd:complexType name="TestModule5V1EntityAllSoapAndRest">
+    <xsd:annotation>
+        <xsd:documentation>Some Data Object short description. Data Object long multi line description.</xsd:documentation>
+        <xsd:appinfo xmlns:inf="{$this->_soapUrl}"/>
+    </xsd:annotation>
+    <xsd:sequence>
+        <xsd:element name="entityId" minOccurs="1" maxOccurs="1" type="xsd:int">
+            <xsd:annotation>
+                <xsd:documentation>Item ID</xsd:documentation>
+                <xsd:appinfo xmlns:inf="{$this->_soapUrl}">
+                    <inf:min/>
+                    <inf:max/>
+                    <inf:callInfo>
+                        <inf:callName>testModule5AllSoapAndRestV1Item</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1Create</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1Update</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1NestedUpdate</inf:callName>
+                        <inf:returned>Always</inf:returned>
+                    </inf:callInfo>
+                    <inf:callInfo>
+                        <inf:callName>testModule5AllSoapAndRestV1Create</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1Update</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1NestedUpdate</inf:callName>
+                        <inf:requiredInput>Yes</inf:requiredInput>
+                    </inf:callInfo>
+                </xsd:appinfo>
+            </xsd:annotation>
+        </xsd:element>
+        <xsd:element name="name" minOccurs="0" maxOccurs="1" type="xsd:string">
+            <xsd:annotation>
+                <xsd:documentation>Item name</xsd:documentation>
+                <xsd:appinfo xmlns:inf="{$this->_soapUrl}">
+                    <inf:maxLength/>
+                    <inf:callInfo>
+                        <inf:callName>testModule5AllSoapAndRestV1Item</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1Create</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1Update</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1NestedUpdate</inf:callName>
+                        <inf:returned>Conditionally</inf:returned>
+                    </inf:callInfo>
+                    <inf:callInfo>
+                        <inf:callName>testModule5AllSoapAndRestV1Create</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1Update</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1NestedUpdate</inf:callName>
+                        <inf:requiredInput>No</inf:requiredInput>
+                    </inf:callInfo>
+                </xsd:appinfo>
+            </xsd:annotation>
+        </xsd:element>
+        <xsd:element name="enabled" minOccurs="1" maxOccurs="1" type="xsd:boolean">
+            <xsd:annotation>
+                <xsd:documentation></xsd:documentation>
+                <xsd:appinfo xmlns:inf="{$this->_soapUrl}">
+                    <inf:default>false</inf:default>
+                    <inf:callInfo>
+                        <inf:callName>testModule5AllSoapAndRestV1Item</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1Create</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1Update</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1NestedUpdate</inf:callName>
+                        <inf:returned>Conditionally</inf:returned>
+                    </inf:callInfo>
+                    <inf:callInfo>
+                        <inf:callName>testModule5AllSoapAndRestV1Create</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1Update</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1NestedUpdate</inf:callName>
+                        <inf:requiredInput>No</inf:requiredInput>
+                    </inf:callInfo>
+                </xsd:appinfo>
+            </xsd:annotation>
+        </xsd:element>
+        <xsd:element name="orders" minOccurs="1" maxOccurs="1" type="xsd:boolean">
+            <xsd:annotation>
+                <xsd:documentation></xsd:documentation>
+                <xsd:appinfo xmlns:inf="{$this->_soapUrl}">
+                    <inf:default>false</inf:default>
+                    <inf:callInfo>
+                        <inf:callName>testModule5AllSoapAndRestV1Item</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1Create</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1Update</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1NestedUpdate</inf:callName>
+                        <inf:returned>Conditionally</inf:returned>
+                    </inf:callInfo>
+                    <inf:callInfo>
+                        <inf:callName>testModule5AllSoapAndRestV1Create</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1Update</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1NestedUpdate</inf:callName>
+                        <inf:requiredInput>No</inf:requiredInput>
+                    </inf:callInfo>
+                </xsd:appinfo>
+            </xsd:annotation>
+        </xsd:element>
+        <xsd:element name="customAttributes" type="tns:ArrayOfFrameworkAttributeInterface" minOccurs="0">
+            <xsd:annotation>
+                <xsd:documentation></xsd:documentation>
+                <xsd:appinfo xmlns:inf="{$this->_soapUrl}">
+                    <inf:natureOfType>array</inf:natureOfType>
+                    <inf:callInfo>
+                        <inf:callName>testModule5AllSoapAndRestV1Item</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1Create</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1Update</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1NestedUpdate</inf:callName>
+                        <inf:returned>Conditionally</inf:returned>
+                    </inf:callInfo>
+                    <inf:callInfo>
+                        <inf:callName>testModule5AllSoapAndRestV1Create</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1Update</inf:callName>
+                        <inf:callName>testModule5AllSoapAndRestV1NestedUpdate</inf:callName>
+                        <inf:requiredInput>No</inf:requiredInput>
+                    </inf:callInfo>
+                </xsd:appinfo>
+            </xsd:annotation>
+    </xsd:element>
+    </xsd:sequence>
+</xsd:complexType>
+RESPONSE_TYPE;
+        // @codingStandardsIgnoreEnd
+        $this->assertContains(
+            $this->_convertXmlToString($referencedType),
+            $wsdlContent,
+            'Declaration of complex type generated from Data Object, which is referenced in response, is invalid'
+        );
+    }
+
+    /**
+     * Ensure that port type sections have correct structure.
+     *
+     * @param string $wsdlContent
+     */
+    protected function _checkPortTypeDeclaration($wsdlContent)
+    {
+        $firstPortType = <<< FIRST_PORT_TYPE
+<portType name="testModule5AllSoapAndRestV1PortType">
+FIRST_PORT_TYPE;
+        $this->assertContains(
+            $this->_convertXmlToString($firstPortType),
+            $wsdlContent,
+            'Port type declaration is missing or invalid'
+        );
+        $secondPortType = <<< SECOND_PORT_TYPE
+<portType name="testModule5AllSoapAndRestV2PortType">
+SECOND_PORT_TYPE;
+        $this->assertContains(
+            $this->_convertXmlToString($secondPortType),
+            $wsdlContent,
+            'Port type declaration is missing or invalid'
+        );
+        $operationDeclaration = <<< OPERATION_DECLARATION
+<operation name="testModule5AllSoapAndRestV2Item">
+    <input message="tns:testModule5AllSoapAndRestV2ItemRequest"/>
+    <output message="tns:testModule5AllSoapAndRestV2ItemResponse"/>
+    <fault name="GenericFault" message="tns:GenericFault"/>
+</operation>
+<operation name="testModule5AllSoapAndRestV2Items">
+    <input message="tns:testModule5AllSoapAndRestV2ItemsRequest"/>
+    <output message="tns:testModule5AllSoapAndRestV2ItemsResponse"/>
+    <fault name="GenericFault" message="tns:GenericFault"/>
+</operation>
+OPERATION_DECLARATION;
+        $this->assertContains(
+            $this->_convertXmlToString($operationDeclaration),
+            $wsdlContent,
+            'Operation in port type is invalid'
+        );
+    }
+
+    /**
+     * Ensure that binding sections have correct structure.
+     *
+     * @param string $wsdlContent
+     */
+    protected function _checkBindingDeclaration($wsdlContent)
+    {
+        $firstBinding = <<< FIRST_BINDING
+<binding name="testModule5AllSoapAndRestV1Binding" type="tns:testModule5AllSoapAndRestV1PortType">
+    <soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
+FIRST_BINDING;
+        $this->assertContains(
+            $this->_convertXmlToString($firstBinding),
+            $wsdlContent,
+            'Binding declaration is missing or invalid'
+        );
+        $secondBinding = <<< SECOND_BINDING
+<binding name="testModule5AllSoapAndRestV2Binding" type="tns:testModule5AllSoapAndRestV2PortType">
+    <soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
+SECOND_BINDING;
+        $this->assertContains(
+            $this->_convertXmlToString($secondBinding),
+            $wsdlContent,
+            'Binding declaration is missing or invalid'
+        );
+        $operationDeclaration = <<< OPERATION_DECLARATION
+<operation name="testModule5AllSoapAndRestV1Item">
+    <soap:operation soapAction="testModule5AllSoapAndRestV1Item"/>
+    <input>
+        <soap12:body use="literal"/>
+    </input>
+    <output>
+        <soap12:body use="literal"/>
+    </output>
+    <fault name="GenericFault">
+        <soap12:fault use="literal" name="GenericFault"/>
+    </fault>
+</operation>
+<operation name="testModule5AllSoapAndRestV1Items">
+    <soap:operation soapAction="testModule5AllSoapAndRestV1Items"/>
+    <input>
+        <soap12:body use="literal"/>
+    </input>
+    <output>
+        <soap12:body use="literal"/>
+    </output>
+    <fault name="GenericFault">
+        <soap12:fault use="literal" name="GenericFault"/>
+    </fault>
+</operation>
+OPERATION_DECLARATION;
+        $this->assertContains(
+            $this->_convertXmlToString($operationDeclaration),
+            $wsdlContent,
+            'Operation in binding is invalid'
+        );
+    }
+
+    /**
+     * Ensure that service sections have correct structure.
+     *
+     * @param string $wsdlContent
+     */
+    protected function _checkServiceDeclaration($wsdlContent)
+    {
+        // @codingStandardsIgnoreStart
+        $firstServiceDeclaration = <<< FIRST_SERVICE_DECLARATION
+<service name="testModule5AllSoapAndRestV1Service">
+    <port name="testModule5AllSoapAndRestV1Port" binding="tns:testModule5AllSoapAndRestV1Binding">
+        <soap:address location="{$this->_baseUrl}/soap/{$this->_storeCode}?services=testModule5AllSoapAndRestV1%2CtestModule5AllSoapAndRestV2"/>
+    </port>
+</service>
+FIRST_SERVICE_DECLARATION;
+        // @codingStandardsIgnoreEnd
+        $this->assertContains(
+            $this->_convertXmlToString($firstServiceDeclaration),
+            $wsdlContent,
+            'First service section is invalid'
+        );
+
+        // @codingStandardsIgnoreStart
+        $secondServiceDeclaration = <<< SECOND_SERVICE_DECLARATION
+<service name="testModule5AllSoapAndRestV2Service">
+    <port name="testModule5AllSoapAndRestV2Port" binding="tns:testModule5AllSoapAndRestV2Binding">
+        <soap:address location="{$this->_baseUrl}/soap/{$this->_storeCode}?services=testModule5AllSoapAndRestV1%2CtestModule5AllSoapAndRestV2"/>
+    </port>
+</service>
+SECOND_SERVICE_DECLARATION;
+        // @codingStandardsIgnoreEnd
+        $this->assertContains(
+            $this->_convertXmlToString($secondServiceDeclaration),
+            $wsdlContent,
+            'Second service section is invalid'
+        );
+    }
+
+    /**
+     * Ensure that messages sections have correct structure.
+     *
+     * @param string $wsdlContent
+     */
+    protected function _checkMessagesDeclaration($wsdlContent)
+    {
+        $itemMessagesDeclaration = <<< MESSAGES_DECLARATION
+<message name="testModule5AllSoapAndRestV2ItemRequest">
+    <part name="messageParameters" element="tns:testModule5AllSoapAndRestV2ItemRequest"/>
+</message>
+<message name="testModule5AllSoapAndRestV2ItemResponse">
+    <part name="messageParameters" element="tns:testModule5AllSoapAndRestV2ItemResponse"/>
+</message>
+MESSAGES_DECLARATION;
+        $this->assertContains(
+            $this->_convertXmlToString($itemMessagesDeclaration),
+            $wsdlContent,
+            'Messages section for "item" operation is invalid'
+        );
+        $itemsMessagesDeclaration = <<< MESSAGES_DECLARATION
+<message name="testModule5AllSoapAndRestV2ItemsRequest">
+    <part name="messageParameters" element="tns:testModule5AllSoapAndRestV2ItemsRequest"/>
+</message>
+<message name="testModule5AllSoapAndRestV2ItemsResponse">
+    <part name="messageParameters" element="tns:testModule5AllSoapAndRestV2ItemsResponse"/>
+</message>
+MESSAGES_DECLARATION;
+        $this->assertContains(
+            $this->_convertXmlToString($itemsMessagesDeclaration),
+            $wsdlContent,
+            'Messages section for "items" operation is invalid'
+        );
+    }
+
+    /**
+     * Ensure that SOAP faults are declared properly.
+     *
+     * @param string $wsdlContent
+     */
+    protected function _checkFaultsDeclaration($wsdlContent)
+    {
+        $this->_checkFaultsPortTypeSection($wsdlContent);
+        $this->_checkFaultsBindingSection($wsdlContent);
+        $this->_checkFaultsMessagesSection($wsdlContent);
+        $this->_checkFaultsComplexTypeSection($wsdlContent);
+    }
+
+    /**
+     * @param string $wsdlContent
+     */
+    protected function _checkFaultsPortTypeSection($wsdlContent)
+    {
+        $faultsInPortType = <<< FAULT_IN_PORT_TYPE
+<fault name="GenericFault" message="tns:GenericFault"/>
+FAULT_IN_PORT_TYPE;
+        $this->assertContains(
+            $this->_convertXmlToString($faultsInPortType),
+            $wsdlContent,
+            'SOAP Fault section in port type section is invalid'
+        );
+    }
+
+    /**
+     * @param string $wsdlContent
+     */
+    protected function _checkFaultsBindingSection($wsdlContent)
+    {
+        $faultsInBinding = <<< FAULT_IN_BINDING
+<fault name="GenericFault">
+    <soap12:fault use="literal" name="GenericFault"/>
+</fault>
+FAULT_IN_BINDING;
+        $this->assertContains(
+            $this->_convertXmlToString($faultsInBinding),
+            $wsdlContent,
+            'SOAP Fault section in binding section is invalid'
+        );
+    }
+
+    /**
+     * @param string $wsdlContent
+     */
+    protected function _checkFaultsMessagesSection($wsdlContent)
+    {
+        $genericFaultMessage = <<< GENERIC_FAULT_IN_MESSAGES
+<message name="GenericFault">
+    <part name="messageParameters" element="tns:GenericFault"/>
+</message>
+GENERIC_FAULT_IN_MESSAGES;
+        $this->assertContains(
+            $this->_convertXmlToString($genericFaultMessage),
+            $wsdlContent,
+            'Generic SOAP Fault declaration in messages section is invalid'
+        );
+    }
+
+    /**
+     * @param string $wsdlContent
+     */
+    protected function _checkFaultsComplexTypeSection($wsdlContent)
+    {
+        $this->assertContains(
+            $this->_convertXmlToString('<xsd:element name="GenericFault" type="tns:GenericFault"/>'),
+            $wsdlContent,
+            'Default SOAP Fault complex type element declaration is invalid'
+        );
+
+        // @codingStandardsIgnoreStart
+        $genericFaultType = <<< GENERIC_FAULT_COMPLEX_TYPE
+<xsd:complexType name="GenericFault">
+    <xsd:sequence>
+        <xsd:element name="Trace" minOccurs="0" maxOccurs="1" type="xsd:string">
+            <xsd:annotation>
+                <xsd:documentation>Exception calls stack trace.</xsd:documentation>
+                <xsd:appinfo xmlns:inf="{$this->_soapUrl}">
+                    <inf:maxLength/>
+                </xsd:appinfo>
+            </xsd:annotation>
+        </xsd:element>
+        <xsd:element name="Parameters" type="tns:ArrayOfGenericFaultParameter" minOccurs="0">
+            <xsd:annotation>
+                <xsd:documentation>Additional exception parameters.</xsd:documentation>
+                <xsd:appinfo xmlns:inf="{$this->_soapUrl}">
+                    <inf:natureOfType>array</inf:natureOfType>
+                </xsd:appinfo>
+            </xsd:annotation>
+        </xsd:element>
+        <xsd:element name="WrappedErrors" type="tns:ArrayOfWrappedError" minOccurs="0">
+            <xsd:annotation>
+                <xsd:documentation>Additional wrapped errors.</xsd:documentation>
+                <xsd:appinfo xmlns:inf="{$this->_soapUrl}">
+                    <inf:natureOfType>array</inf:natureOfType>
+                </xsd:appinfo>
+            </xsd:annotation>
+        </xsd:element>
+    </xsd:sequence>
+</xsd:complexType>
+GENERIC_FAULT_COMPLEX_TYPE;
+        $this->assertContains(
+            $this->_convertXmlToString($genericFaultType),
+            $wsdlContent,
+            'Default SOAP Fault complex types declaration is invalid'
+        );
+
+        $detailsParameterType = <<< PARAM_COMPLEX_TYPE
+<xsd:complexType name="GenericFaultParameter">
+    <xsd:sequence>
+        <xsd:element name="key" minOccurs="1" maxOccurs="1" type="xsd:string">
+            <xsd:annotation>
+                <xsd:documentation></xsd:documentation>
+                <xsd:appinfo xmlns:inf="{$this->_soapUrl}">
+                    <inf:maxLength/>
+                </xsd:appinfo>
+            </xsd:annotation>
+        </xsd:element>
+        <xsd:element name="value" minOccurs="1" maxOccurs="1" type="xsd:string">
+            <xsd:annotation>
+                <xsd:documentation></xsd:documentation>
+                <xsd:appinfo xmlns:inf="{$this->_soapUrl}">
+                    <inf:maxLength/>
+                </xsd:appinfo>
+            </xsd:annotation>
+        </xsd:element>
+    </xsd:sequence>
+</xsd:complexType>
+PARAM_COMPLEX_TYPE;
+        $this->assertContains(
+            $this->_convertXmlToString($detailsParameterType),
+            $wsdlContent,
+            'Details parameter complex types declaration is invalid.'
+        );
+
+        $detailsWrappedErrorType = <<< WRAPPED_ERROR_COMPLEX_TYPE
+<xsd:complexType name="WrappedError">
+    <xsd:sequence>
+        <xsd:element name="message" minOccurs="1" maxOccurs="1" type="xsd:string">
+            <xsd:annotation>
+                <xsd:documentation></xsd:documentation>
+                <xsd:appinfo xmlns:inf="{$this->_baseUrl}/soap/{$this->_storeCode}?services%3DtestModule5AllSoapAndRestV1%2CtestModule5AllSoapAndRestV2">
+                    <inf:maxLength/>
+                </xsd:appinfo>
+            </xsd:annotation>
+        </xsd:element>
+        <xsd:element name="parameters" type="tns:ArrayOfGenericFaultParameter" minOccurs="0">
+            <xsd:annotation>
+                <xsd:documentation>Message parameters.</xsd:documentation>
+                <xsd:appinfo xmlns:inf="{$this->_baseUrl}/soap/{$this->_storeCode}?services%3DtestModule5AllSoapAndRestV1%2CtestModule5AllSoapAndRestV2">
+                    <inf:natureOfType>array</inf:natureOfType>
+                </xsd:appinfo>
+            </xsd:annotation>
+        </xsd:element>
+    </xsd:sequence>
+</xsd:complexType>
+WRAPPED_ERROR_COMPLEX_TYPE;
+        $this->assertContains(
+            $this->_convertXmlToString($detailsWrappedErrorType),
+            $wsdlContent,
+            'Details wrapped error complex types declaration is invalid.'
+        );
+
+        $detailsParametersType = <<< PARAMETERS_COMPLEX_TYPE
+<xsd:complexType name="ArrayOfGenericFaultParameter">
+    <xsd:annotation>
+        <xsd:documentation>An array of GenericFaultParameter items.</xsd:documentation>
+        <xsd:appinfo xmlns:inf="{$this->_soapUrl}"/>
+    </xsd:annotation>
+    <xsd:sequence>
+        <xsd:element name="item" minOccurs="0" maxOccurs="unbounded" type="tns:GenericFaultParameter">
+            <xsd:annotation>
+                <xsd:documentation>An item of ArrayOfGenericFaultParameter.</xsd:documentation>
+                <xsd:appinfo xmlns:inf="{$this->_soapUrl}"/>
+            </xsd:annotation>
+        </xsd:element>
+    </xsd:sequence>
+</xsd:complexType>
+PARAMETERS_COMPLEX_TYPE;
+        // @codingStandardsIgnoreEnd
+        $this->assertContains(
+            $this->_convertXmlToString($detailsParametersType),
+            $wsdlContent,
+            'Details parameters (array of parameters) complex types declaration is invalid.'
+        );
+
+        $detailsWrappedErrorsType = <<< WRAPPED_ERRORS_COMPLEX_TYPE
+<xsd:complexType name="ArrayOfWrappedError">
+    <xsd:annotation>
+        <xsd:documentation>An array of WrappedError items.</xsd:documentation>
+        <xsd:appinfo xmlns:inf="{$this->_baseUrl}/soap/{$this->_storeCode}?services%3DtestModule5AllSoapAndRestV1%2CtestModule5AllSoapAndRestV2"/>
+    </xsd:annotation>
+    <xsd:sequence>
+        <xsd:element name="item" minOccurs="0" maxOccurs="unbounded" type="tns:WrappedError">
+            <xsd:annotation>
+                <xsd:documentation>An item of ArrayOfWrappedError.</xsd:documentation>
+                <xsd:appinfo xmlns:inf="{$this->_baseUrl}/soap/{$this->_storeCode}?services%3DtestModule5AllSoapAndRestV1%2CtestModule5AllSoapAndRestV2"/>
+            </xsd:annotation>
+        </xsd:element>
+    </xsd:sequence>
+</xsd:complexType>
+WRAPPED_ERRORS_COMPLEX_TYPE;
+        // @codingStandardsIgnoreEnd
+        $this->assertContains(
+            $this->_convertXmlToString($detailsWrappedErrorsType),
+            $wsdlContent,
+            'Details wrapped errors (array of wrapped errors) complex types declaration is invalid.'
+        );
+    }
+}
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/reference.txt b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/reference.txt
index 1d55de7b275..c6bac2ba9f3 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/reference.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/_files/blacklist/reference.txt
@@ -37,3 +37,17 @@ Model3
 \Magento\Wonderland\Model\Data\FakeRegion
 \Magento\Wonderland\Model\Data\FakeAddress
 \Magento\Framework\Error\Processor
+\Magento\TestModule3\Service\V1\Entity\Parameter
+\Magento\TestModule3\Service\V1\Entity\ParameterBuilder
+\Magento\TestModuleMSC\Api\Data\ItemInterface
+\Magento\TestModule5\Service\V1\Entity\AllSoapAndRest
+\Magento\TestModule5\Service\V2\Entity\AllSoapAndRest
+\Magento\TestModule5\Service\V2\Entity\AllSoapAndRestBuilder
+\Magento\TestModule1\Service\V1\Entity\Item
+\Magento\TestModule1\Service\V1\Entity\ItemBuilder
+\Magento\TestModule1\Service\V2\Entity\Item
+\Magento\TestModule1\Service\V2\Entity\ItemBuilder
+\Magento\TestModule2\Service\V1\Entity\Item
+\Magento\TestModule2\Service\V1\Entity\ItemBuilder
+\Magento\TestModule4\Service\V1\Entity\DataObjectResponse
+\Magento\TestModule4\Service\V1\Entity\DataObjectRequest
-- 
GitLab


From 1d7b54ae39eda5d64dbed4854d37ae8154de0dd2 Mon Sep 17 00:00:00 2001
From: Vinai Kopp <vinai@netzarbeiter.com>
Date: Mon, 5 Jan 2015 18:09:15 +0100
Subject: [PATCH 70/71] Specify date fixture and fix expectations

* Fix date_format expectation for month part
* Make test independent of current time
---
 .../Framework/Data/Form/Element/DateTest.php       | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/dev/tests/integration/testsuite/Magento/Framework/Data/Form/Element/DateTest.php b/dev/tests/integration/testsuite/Magento/Framework/Data/Form/Element/DateTest.php
index 65ed2f489ee..53ab713ea45 100644
--- a/dev/tests/integration/testsuite/Magento/Framework/Data/Form/Element/DateTest.php
+++ b/dev/tests/integration/testsuite/Magento/Framework/Data/Form/Element/DateTest.php
@@ -48,29 +48,29 @@ class DateTest extends \PHPUnit_Framework_TestCase
      */
     public function getValueDataProvider()
     {
-        $currentTime = time();
+        $testTimestamp = strtotime('2014-05-18 12:08:16');
         return [
             [
                 [
                     'date_format' => \Magento\Framework\Stdlib\DateTime\TimezoneInterface::FORMAT_TYPE_SHORT,
                     'time_format' => \Magento\Framework\Stdlib\DateTime\TimezoneInterface::FORMAT_TYPE_SHORT,
-                    'value' => $currentTime,
+                    'value' => $testTimestamp,
                 ],
-                date('m/j/y g:i A', $currentTime),
+                date('n/j/y g:i A', $testTimestamp),
             ],
             [
                 [
                     'time_format' => \Magento\Framework\Stdlib\DateTime\TimezoneInterface::FORMAT_TYPE_SHORT,
-                    'value' => $currentTime,
+                    'value' => $testTimestamp,
                 ],
-                date('g:i A', $currentTime)
+                date('g:i A', $testTimestamp)
             ],
             [
                 [
                     'date_format' => \Magento\Framework\Stdlib\DateTime\TimezoneInterface::FORMAT_TYPE_SHORT,
-                    'value' => $currentTime,
+                    'value' => $testTimestamp,
                 ],
-                date('m/j/y', $currentTime)
+                date('n/j/y', $testTimestamp)
             ]
         ];
     }
-- 
GitLab


From 61f84f719703d4e058e7233f36e3d082baaf7450 Mon Sep 17 00:00:00 2001
From: Vladimir Pelipenko <vpelipenko@ebay.com>
Date: Tue, 6 Jan 2015 13:20:02 +0200
Subject: [PATCH 71/71] MAGEDOC-2015: Create content for Code Contribution
 Guidelines

- updated CONTRIBUTING.md
- removed unused images
---
 CONTRIBUTING.md   |  41 ++++++++++++++++++++++-------------------
 success.png       | Bin 62084 -> 0 bytes
 success_admin.png | Bin 98522 -> 0 bytes
 3 files changed, 22 insertions(+), 19 deletions(-)
 delete mode 100644 success.png
 delete mode 100644 success_admin.png

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f3e88912e5b..673dcfb25a0 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,28 +1,31 @@
-# Contribution Guide
+# Contributing to Magento 2 code
 
-The Magento 2 development team will review all issues and contributions submitted by the community of developers. Contributions can take the form of new components/features, changes to existing features, tests, documentation (such as developer guides, user guides, examples, or specifications), bug fixes, optimizations or just good suggestions. To assist in the expediency of the review process, we strongly encourage you to follow all the proper requirements stated below in Definition of Done, before submitting any code for consideration.
+Contributions to the Magento 2 codebase are done using the fork & pull model.
+This contribution model has contributors maintaining their own copy of the forked codebase (which can easily be synced with the main copy). The forked repository is then used to submit a request to the base repository to “pull” a set of changes (hence the phrase “pull request”).
 
-## Contribution Process
+Contributions can take the form of new components/features, changes to existing features, tests, documentation (such as developer guides, user guides, examples, or specifications), bug fixes, optimizations or just good suggestions.
 
-If you are a new GitHub user, we recommend that you create your own [free github account](https://github.com/signup/free). By doing that, you will be able to collaborate with the Magento 2 development team, “fork” the Magento 2 project and be able to easily send “pull requests”.
-
-1. Search current [listed issues](https://github.com/magento/magento2/issues) (open or closed) for similar proposals of intended contribution before starting work on a new contribution.
-2. Review the [Contributor License Agreement](https://github.com/magento/magento2/blob/master/CONTRIBUTOR_LICENSE_AGREEMENT.html) if this is your first time contributing.
-3. Create and test your work.
-4. Fork the Magento 2 repository according to [github's Fork A Repo instructions](https://help.github.com/articles/fork-a-repo) and when you are ready to send us a Pull Request – follow [github's Using Pull Requests instructions](https://help.github.com/articles/using-pull-requests).
-5. Once your contribution is received, Magento 2 development team will review the contribution and collaborate with you as needed to improve the quality of the contribution.
+The Magento 2 development team will review all issues and contributions submitted by the community of developers in the first in, first out order. During the review we might require clarifications from the contributor. If there is no response from the contributor for two weeks, the issue is closed.
 
-### Contribution Acceptance Criteria
 
-1. Code changes must be covered with automated tests and supplied along with the patch (or fork). Author chooses the best approach for testing as deemed necessary. See [Magento Automated Testing Standard](https://github.com/magento/magento2/wiki/Magento-Automated-Testing-Standard) for additional guidance.
-2. New features or proposals must be supplied with documentation -- functional (how a feature works) or technical (how it is implemented/designed), or both.
+## Contribution requirements
 
-## Frequently Asked Questions
+1. Contributions must adhere to [Magento coding standards](http://devdocs.magento.com/guides/v1.0/coding-standards/bk-coding-standards.html).
+2. Pull requests (PRs) must be accompanied by a meaningful description of their purpose. Comprehensive descriptions increase the chances of a pull request to be merged quickly and without additional clarification requests.
+3. Commits must be accompanied by meaningful commit messages.
+4. PRs which include bug fixing, must be accompanied with step-by-step description of how to reproduce the bug.
+3. PRs which include new logic or new features must be submitted along with:
+* Unit/integration test coverage (we will be releasing more information on writing test coverage in the near future).
+* Proposed [documentation](http://devdocs.magento.com) update. Documentation contributions can be submitted [here](https://github.com/magento/devdocs).
+4. For large features or changes, please [open an issue](https://github.com/magento/magento2/issues) and discuss first. This may prevent duplicate or unnecessary effort, and it may gain you some additional contributors.
+5. All automated tests are passed successfully (all builds on [Travis CI](https://travis-ci.org/magento/magento2) must be green).
 
-**Do I need to follow all requirements of the contribution process?**
+## Contribution process
 
-Yes. We strongly encourage that you follow the requirements as stated, before submitting your code or patch for Magento 2 development team's review. Properly submitted contributions will help the Magento 2 development team to quickly assess your contribution and incorporate it into the Magento 2 project if deemed beneficial.
-
-**Do you accept all contributions?**
+If you are a new GitHub user, we recommend that you create your own [free github account](https://github.com/signup/free). By doing that, you will be able to collaborate with the Magento 2 development team, “fork” the Magento 2 project and be able to easily send “pull requests”.
 
-Not all contributions will be used or incorporated into the code for the project. The decision to incorporate the code or not is at the discretion of the Magento 2 development team.
+1. Search current [listed issues](https://github.com/magento/magento2/issues) (open or closed) for similar proposals of intended contribution before starting work on a new contribution.
+2. Review the [Contributor License Agreement](https://github.com/magento/magento2/blob/master/CONTRIBUTOR_LICENSE_AGREEMENT.html) if this is your first time contributing.
+3. Create and test your work.
+4. Fork the Magento 2 repository according to [Fork a repository instructions](http://devdocs.magento.com/guides/v1.0/contributor-guide/CONTRIBUTING.html#fork) and when you are ready to send us a pull request – follow [Create a pull request instructions](http://devdocs.magento.com/guides/v1.0/contributor-guide/CONTRIBUTING.html#pull_request).
+5. Once your contribution is received, Magento 2 development team will review the contribution and collaborate with you as needed to improve the quality of the contribution.
diff --git a/success.png b/success.png
deleted file mode 100644
index c2853cfc0cbb8856e5baa894332e6f4063428c80..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 62084
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

diff --git a/success_admin.png b/success_admin.png
deleted file mode 100644
index 0901763600a4271438c4b604df881ba079dc934f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 98522
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
Hj6VGbkSzN_

-- 
GitLab