diff --git a/app/code/Magento/Backend/Model/Auth.php b/app/code/Magento/Backend/Model/Auth.php
index 427ac932f515ff4ee9f90d0f09ef72d0b2983fc6..a15f8e1526e0708180402d9d9c9295d2b28ce890 100644
--- a/app/code/Magento/Backend/Model/Auth.php
+++ b/app/code/Magento/Backend/Model/Auth.php
@@ -93,6 +93,7 @@ class Auth
      * If auth storage was not defined outside - returns default object of auth storage
      *
      * @return \Magento\Backend\Model\Auth\StorageInterface
+     * @codeCoverageIgnore
      */
     public function getAuthStorage()
     {
@@ -126,6 +127,7 @@ class Auth
      * Return credential storage object
      *
      * @return null|\Magento\Backend\Model\Auth\Credential\StorageInterface
+     * @codeCoverageIgnore
      */
     public function getCredentialStorage()
     {
diff --git a/app/code/Magento/Backend/Model/Auth/Session.php b/app/code/Magento/Backend/Model/Auth/Session.php
index 6d0965dc1bbbefdb31093fceccc029e5c75d9d90..fec438f70c744d7b7cc9999d8574f3e4deef862c 100644
--- a/app/code/Magento/Backend/Model/Auth/Session.php
+++ b/app/code/Magento/Backend/Model/Auth/Session.php
@@ -253,6 +253,7 @@ class Session extends \Magento\Framework\Session\SessionManager implements \Mage
      * @param string $path
      * @return bool
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @codeCoverageIgnore
      */
     public function isValidForPath($path)
     {
diff --git a/app/code/Magento/Backend/Model/Search/Order.php b/app/code/Magento/Backend/Model/Search/Order.php
index f25de8f9881e108572b247ef3de2dbccaf4cd062..314b6a375ee686fcaa2a929aec29265ddafe4856 100644
--- a/app/code/Magento/Backend/Model/Search/Order.php
+++ b/app/code/Magento/Backend/Model/Search/Order.php
@@ -76,12 +76,7 @@ class Order extends \Magento\Framework\Object
                 'id' => 'order/1/' . $order->getId(),
                 'type' => __('Order'),
                 'name' => __('Order #%1', $order->getIncrementId()),
-                'description' => $order->getBillingFirstname() . ' ' . $order->getBillingLastname(),
-                'form_panel_title' => __(
-                    'Order #%1 (%2)',
-                    $order->getIncrementId(),
-                    $order->getBillingFirstname() . ' ' . $order->getBillingLastname()
-                ),
+                'description' => $order->getFirstname() . ' ' . $order->getLastname(),
                 'url' => $this->_adminhtmlData->getUrl('sales/order/view', ['order_id' => $order->getId()]),
             ];
         }
diff --git a/app/code/Magento/Backend/Test/Unit/Model/Auth/SessionTest.php b/app/code/Magento/Backend/Test/Unit/Model/Auth/SessionTest.php
index 68b5d21f85416fdd874179162000c651d3f91e5c..3e41177e72c0cae37f1f4324caa310d63e471e2c 100644
--- a/app/code/Magento/Backend/Test/Unit/Model/Auth/SessionTest.php
+++ b/app/code/Magento/Backend/Test/Unit/Model/Auth/SessionTest.php
@@ -38,6 +38,11 @@ class SessionTest extends \PHPUnit_Framework_TestCase
      */
     protected $storage;
 
+    /**
+     * @var \Magento\Framework\Acl\Builder | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $aclBuilder;
+
     /**
      * @var Session
      */
@@ -61,7 +66,13 @@ class SessionTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $this->storage = $this->getMock('Magento\Framework\Session\Storage', ['getUser'], [], '', false);
+        $this->storage = $this->getMock(
+            'Magento\Framework\Session\Storage',
+            ['getUser', 'getAcl', 'setAcl'],
+            [],
+            '',
+            false
+        );
         $this->sessionConfig = $this->getMock(
             'Magento\Framework\Session\Config',
             ['getCookiePath', 'getCookieDomain', 'getCookieSecure', 'getCookieHttpOnly'],
@@ -69,6 +80,9 @@ class SessionTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
+        $this->aclBuilder = $this->getMockBuilder('Magento\Framework\Acl\Builder')
+            ->disableOriginalConstructor()
+            ->getMock();
         $objectManager = new ObjectManager($this);
         $this->session = $objectManager->getObject(
             'Magento\Backend\Model\Auth\Session',
@@ -77,7 +91,8 @@ class SessionTest extends \PHPUnit_Framework_TestCase
                 'sessionConfig' => $this->sessionConfig,
                 'cookieManager' => $this->cookieManager,
                 'cookieMetadataFactory' => $this->cookieMetadataFactory,
-                'storage' => $this->storage
+                'storage' => $this->storage,
+                'aclBuilder' => $this->aclBuilder
             ]
         );
     }
@@ -89,6 +104,40 @@ class SessionTest extends \PHPUnit_Framework_TestCase
         $this->session = null;
     }
 
+    /**
+     * @dataProvider refreshAclDataProvider
+     * @param $isUserPassedViaParams
+     */
+    public function testRefreshAcl($isUserPassedViaParams)
+    {
+        $aclMock = $this->getMockBuilder('Magento\Framework\Acl')->disableOriginalConstructor()->getMock();
+        $this->aclBuilder->expects($this->any())->method('getAcl')->willReturn($aclMock);
+        $userMock = $this->getMockBuilder('Magento\User\Model\User')
+            ->setMethods(['getReloadAclFlag', 'setReloadAclFlag', 'unsetData', 'save'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $userMock->expects($this->any())->method('getReloadAclFlag')->willReturn(true);
+        $userMock->expects($this->once())->method('setReloadAclFlag')->with('0')->willReturnSelf();
+        $userMock->expects($this->once())->method('save');
+        $this->storage->expects($this->once())->method('setAcl')->with($aclMock);
+        $this->storage->expects($this->any())->method('getAcl')->willReturn($aclMock);
+        if ($isUserPassedViaParams) {
+            $this->session->refreshAcl($userMock);
+        } else {
+            $this->storage->expects($this->once())->method('getUser')->willReturn($userMock);
+            $this->session->refreshAcl();
+        }
+        $this->assertSame($aclMock, $this->session->getAcl());
+    }
+
+    public function refreshAclDataProvider()
+    {
+        return [
+            'User set via params' => [true],
+            'User set to session object' => [false]
+        ];
+    }
+
     public function testIsLoggedInPositive()
     {
         $lifetime = 900;
@@ -176,4 +225,58 @@ class SessionTest extends \PHPUnit_Framework_TestCase
 
         $this->assertLessThanOrEqual(time(), $this->session->getUpdatedAt());
     }
+
+    /**
+     * @dataProvider isAllowedDataProvider
+     * @param bool $isUserDefined
+     * @param bool $isAclDefined
+     * @param bool $isAllowed
+     * @param true $expectedResult
+     */
+    public function testIsAllowed($isUserDefined, $isAclDefined, $isAllowed, $expectedResult)
+    {
+        $userAclRole = 'userAclRole';
+        if ($isAclDefined) {
+            $aclMock = $this->getMockBuilder('Magento\Framework\Acl')->disableOriginalConstructor()->getMock();
+            $this->storage->expects($this->any())->method('getAcl')->willReturn($aclMock);
+        }
+        if ($isUserDefined) {
+            $userMock = $this->getMockBuilder('Magento\User\Model\User')->disableOriginalConstructor()->getMock();
+            $this->storage->expects($this->once())->method('getUser')->willReturn($userMock);
+        }
+        if ($isAclDefined && $isUserDefined) {
+            $userMock->expects($this->any())->method('getAclRole')->willReturn($userAclRole);
+            $aclMock->expects($this->once())->method('isAllowed')->with($userAclRole)->willReturn($isAllowed);
+        }
+
+        $this->assertEquals($expectedResult, $this->session->isAllowed('resource'));
+    }
+
+    public function isAllowedDataProvider()
+    {
+        return [
+            "Negative: User not defined" => [false, true, true, false],
+            "Negative: Acl not defined" => [true, false, true, false],
+            "Negative: Permission denied" => [true, true, false, false],
+            "Positive: Permission granted" => [true, true, false, false],
+        ];
+    }
+
+    /**
+     * @dataProvider firstPageAfterLoginDataProvider
+     * @param bool $isFirstPageAfterLogin
+     */
+    public function testFirstPageAfterLogin($isFirstPageAfterLogin)
+    {
+        $this->session->setIsFirstPageAfterLogin($isFirstPageAfterLogin);
+        $this->assertEquals($isFirstPageAfterLogin, $this->session->isFirstPageAfterLogin());
+    }
+
+    public function firstPageAfterLoginDataProvider()
+    {
+        return [
+            'First page after login' => [true],
+            'Not first page after login' => [false],
+        ];
+    }
 }
diff --git a/app/code/Magento/Bundle/view/frontend/templates/email/order/items/creditmemo/default.phtml b/app/code/Magento/Bundle/view/frontend/templates/email/order/items/creditmemo/default.phtml
index fdeaac8ee26557106b9de8418a9671ae7ac5c773..0caea13b65b5a392e18217bfa682c4a46e70c0d0 100644
--- a/app/code/Magento/Bundle/view/frontend/templates/email/order/items/creditmemo/default.phtml
+++ b/app/code/Magento/Bundle/view/frontend/templates/email/order/items/creditmemo/default.phtml
@@ -17,7 +17,7 @@
 
 <?php foreach ($items as $_item): ?>
 
-<?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
+<?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
     <?php $_showlastRow = true ?>
 <?php else: ?>
     <?php $_showlastRow = false ?>
diff --git a/app/code/Magento/Bundle/view/frontend/templates/email/order/items/invoice/default.phtml b/app/code/Magento/Bundle/view/frontend/templates/email/order/items/invoice/default.phtml
index cf6b520bcd00f4501b049b16a7ab8d1ba1df82cd..4aec9e983e7c5e86238ee178f30a331d77e3c907 100644
--- a/app/code/Magento/Bundle/view/frontend/templates/email/order/items/invoice/default.phtml
+++ b/app/code/Magento/Bundle/view/frontend/templates/email/order/items/invoice/default.phtml
@@ -18,7 +18,7 @@
 
 <?php foreach ($items as $_item): ?>
 
-<?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
+<?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
     <?php $_showlastRow = true ?>
 <?php else: ?>
     <?php $_showlastRow = false ?>
diff --git a/app/code/Magento/Bundle/view/frontend/templates/email/order/items/order/default.phtml b/app/code/Magento/Bundle/view/frontend/templates/email/order/items/order/default.phtml
index 876a77f7726ca088c68b7d713c25f701784ae431..c40ac91faf20a0c999997f46c23e9cec3403874e 100644
--- a/app/code/Magento/Bundle/view/frontend/templates/email/order/items/order/default.phtml
+++ b/app/code/Magento/Bundle/view/frontend/templates/email/order/items/order/default.phtml
@@ -14,7 +14,7 @@
 <?php $parentItem = $block->getItem() ?>
 <?php $items = array_merge([$parentItem], $parentItem->getChildrenItems()); ?>
 
-<?php if ($block->getItemOptions() || $_item->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order_item', $_item) && $_item->getGiftMessageId()): ?>
+<?php if ($block->getItemOptions() || $_item->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $_item) && $_item->getGiftMessageId()): ?>
     <?php $_showlastRow = true ?>
 <?php else: ?>
     <?php $_showlastRow = false ?>
diff --git a/app/code/Magento/Bundle/view/frontend/templates/email/order/items/shipment/default.phtml b/app/code/Magento/Bundle/view/frontend/templates/email/order/items/shipment/default.phtml
index 8b9c86c24780d8d2cf798a5798c9bdd20d52df06..c485ea7524906bce8ab030dbf5d8ff6263875b8e 100644
--- a/app/code/Magento/Bundle/view/frontend/templates/email/order/items/shipment/default.phtml
+++ b/app/code/Magento/Bundle/view/frontend/templates/email/order/items/shipment/default.phtml
@@ -16,7 +16,7 @@
 
 <?php foreach ($items as $_item): ?>
 
-<?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
+<?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
     <?php $_showlastRow = true ?>
 <?php else: ?>
     <?php $_showlastRow = false ?>
diff --git a/app/code/Magento/Bundle/view/frontend/templates/sales/order/creditmemo/items/renderer.phtml b/app/code/Magento/Bundle/view/frontend/templates/sales/order/creditmemo/items/renderer.phtml
index 92d5f48d962c250205098b11690e9c9ab43825fc..3d908583e199610eb48aad5ce83126bf957a9ca8 100644
--- a/app/code/Magento/Bundle/view/frontend/templates/sales/order/creditmemo/items/renderer.phtml
+++ b/app/code/Magento/Bundle/view/frontend/templates/sales/order/creditmemo/items/renderer.phtml
@@ -19,7 +19,7 @@
 
 <?php foreach ($items as $_item): ?>
 
-    <?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
+    <?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
         <?php $_showlastRow = true ?>
     <?php else: ?>
         <?php $_showlastRow = false ?>
diff --git a/app/code/Magento/Bundle/view/frontend/templates/sales/order/invoice/items/renderer.phtml b/app/code/Magento/Bundle/view/frontend/templates/sales/order/invoice/items/renderer.phtml
index ce6c827ab2475925de00c0d711b814175ba93fce..c7f4dd44bc08b82634ec14cbc2753806cb1fae3b 100644
--- a/app/code/Magento/Bundle/view/frontend/templates/sales/order/invoice/items/renderer.phtml
+++ b/app/code/Magento/Bundle/view/frontend/templates/sales/order/invoice/items/renderer.phtml
@@ -18,7 +18,7 @@
 <?php $_prevOptionId = '' ?>
 <?php foreach ($items as $_item): ?>
 
-    <?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
+    <?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
         <?php $_showlastRow = true ?>
     <?php else: ?>
         <?php $_showlastRow = false ?>
diff --git a/app/code/Magento/Bundle/view/frontend/templates/sales/order/items/renderer.phtml b/app/code/Magento/Bundle/view/frontend/templates/sales/order/items/renderer.phtml
index b4276aeaa7ba38fc5c5fe72c6fe3622a2f243a55..c50b8cfdac980447385bf4367eb3dfddbf07c789 100644
--- a/app/code/Magento/Bundle/view/frontend/templates/sales/order/items/renderer.phtml
+++ b/app/code/Magento/Bundle/view/frontend/templates/sales/order/items/renderer.phtml
@@ -17,7 +17,7 @@
 
 <?php foreach ($items as $_item): ?>
 
-    <?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
+    <?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
         <?php $_showlastRow = true ?>
     <?php else: ?>
         <?php $_showlastRow = false ?>
diff --git a/app/code/Magento/Bundle/view/frontend/templates/sales/order/shipment/items/renderer.phtml b/app/code/Magento/Bundle/view/frontend/templates/sales/order/shipment/items/renderer.phtml
index 1e02e1b887ad8f29e744f362cbad49440888fe75..15406932c1c3e8706afa0c13b58c5c717ddb3dca 100644
--- a/app/code/Magento/Bundle/view/frontend/templates/sales/order/shipment/items/renderer.phtml
+++ b/app/code/Magento/Bundle/view/frontend/templates/sales/order/shipment/items/renderer.phtml
@@ -17,7 +17,7 @@
 
 <?php foreach ($items as $_item): ?>
 
-    <?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
+    <?php if ($block->getItemOptions() || $parentItem->getDescription() || $this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $parentItem) && $parentItem->getGiftMessageId()): ?>
         <?php $_showlastRow = true ?>
     <?php else: ?>
         <?php $_showlastRow = false ?>
diff --git a/app/code/Magento/Catalog/etc/webapi.xml b/app/code/Magento/Catalog/etc/webapi.xml
index a4fb44c7eae061b3547fee1c93d61889dd923b7a..88bc0f93a6ec32002356446962220f48422f1fce 100644
--- a/app/code/Magento/Catalog/etc/webapi.xml
+++ b/app/code/Magento/Catalog/etc/webapi.xml
@@ -82,7 +82,7 @@
             <resource ref="Magento_Catalog::attributes_attributes" />
         </resources>
     </route>
-    <route url="/V1/products/attributes/:attributeId" method="PUT">
+    <route url="/V1/products/attributes/:attributeCode" method="PUT">
         <service class="Magento\Catalog\Api\ProductAttributeRepositoryInterface" method="save"/>
         <resources>
             <resource ref="Magento_Catalog::attributes_attributes" />
diff --git a/app/code/Magento/Email/Model/Template.php b/app/code/Magento/Email/Model/Template.php
index 5a331546d5831ca7bfafa0a00b84a85b342c5c91..8287fa82aca1e61954395a4611c788bc18c9410b 100644
--- a/app/code/Magento/Email/Model/Template.php
+++ b/app/code/Magento/Email/Model/Template.php
@@ -8,6 +8,7 @@ namespace Magento\Email\Model;
 use Magento\Email\Model\Template\Filter;
 use Magento\Framework\App\Filesystem\DirectoryList;
 use Magento\Framework\Filter\Template as FilterTemplate;
+use Magento\Store\Model\ScopeInterface;
 use Magento\Store\Model\StoreManagerInterface;
 
 /**
@@ -213,7 +214,7 @@ class Template extends \Magento\Email\Model\AbstractTemplate implements \Magento
         $store = $this->_storeManager->getStore($store);
         $fileName = $this->_scopeConfig->getValue(
             self::XML_PATH_DESIGN_EMAIL_LOGO,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+            ScopeInterface::SCOPE_STORE,
             $store
         );
         if ($fileName) {
@@ -252,7 +253,7 @@ class Template extends \Magento\Email\Model\AbstractTemplate implements \Magento
         $store = $this->_storeManager->getStore($store);
         $alt = $this->_scopeConfig->getValue(
             self::XML_PATH_DESIGN_EMAIL_LOGO_ALT,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+            ScopeInterface::SCOPE_STORE,
             $store
         );
         if ($alt) {
@@ -379,7 +380,7 @@ class Template extends \Magento\Email\Model\AbstractTemplate implements \Magento
     /**
      * Return true if this template can be used for sending queue as main template
      *
-     * @return boolean
+     * @return bool
      */
     public function isValidForSend()
     {
@@ -480,6 +481,7 @@ class Template extends \Magento\Email\Model\AbstractTemplate implements \Magento
      * Get exception, generated during send() method
      *
      * @return \Exception|null
+     * @codeCoverageIgnore
      */
     public function getSendingException()
     {
@@ -520,6 +522,7 @@ class Template extends \Magento\Email\Model\AbstractTemplate implements \Magento
      *
      * @param string|array $bcc
      * @return $this
+     * @codeCoverageIgnore
      */
     public function addBcc($bcc)
     {
@@ -532,6 +535,7 @@ class Template extends \Magento\Email\Model\AbstractTemplate implements \Magento
      *
      * @param string $email
      * @return $this
+     * @codeCoverageIgnore
      */
     public function setReturnPath($email)
     {
@@ -544,6 +548,7 @@ class Template extends \Magento\Email\Model\AbstractTemplate implements \Magento
      *
      * @param string $email
      * @return $this
+     * @codeCoverageIgnore
      */
     public function setReplyTo($email)
     {
diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Edit/FormTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Edit/FormTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c5d1fefa9c28797f686e8247f61d1e696fbf3454
--- /dev/null
+++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Edit/FormTest.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Email\Test\Unit\Block\Adminhtml\Template\Edit;
+
+/**
+ * @covers \Magento\Email\Block\Adminhtml\Template\Edit\Form
+ */
+class FormTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Email\Block\Adminhtml\Template\Edit\Form */
+    protected $form;
+
+    /** @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject */
+    protected $registryMock;
+
+    /** @var \Magento\Email\Model\Source\Variables|\PHPUnit_Framework_MockObject_MockObject */
+    protected $variablesMock;
+
+    /** @var \Magento\Variable\Model\VariableFactory|\PHPUnit_Framework_MockObject_MockObject */
+    protected $variableFactoryMock;
+
+    /** @var \Magento\Variable\Model\Variable|\PHPUnit_Framework_MockObject_MockObject */
+    protected $variableMock;
+
+    /** @var \Magento\Email\Model\Template|\PHPUnit_Framework_MockObject_MockObject */
+    protected $templateMock;
+
+    public function setUp()
+    {
+        $this->registryMock = $this->getMockBuilder('Magento\Framework\Registry')
+            ->disableOriginalConstructor()
+            ->setMethods(['registry'])
+            ->getMock();
+        $this->variablesMock = $this->getMockBuilder('Magento\Email\Model\Source\Variables')
+            ->disableOriginalConstructor()
+            ->setMethods(['toOptionArray'])
+            ->getMock();
+        $this->variableFactoryMock = $this->getMockBuilder('Magento\Variable\Model\VariableFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $this->variableMock = $this->getMockBuilder('Magento\Variable\Model\Variable')
+            ->disableOriginalConstructor()
+            ->setMethods(['getVariablesOptionArray'])
+            ->getMock();
+        $this->templateMock = $this->getMockBuilder('Magento\Email\Model\Template')
+            ->disableOriginalConstructor()
+            ->setMethods(['getId', 'getVariablesOptionArray'])
+            ->getMock();
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->form = $objectManager->getObject(
+            'Magento\Email\Block\Adminhtml\Template\Edit\Form',
+            [
+                'registry' => $this->registryMock,
+                'variableFactory' => $this->variableFactoryMock,
+                'variables' => $this->variablesMock
+            ]
+        );
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Edit\Form::getVariables
+     */
+    public function testGetVariables()
+    {
+        $this->variablesMock->expects($this->once())
+            ->method('toOptionArray')
+            ->willReturn(['var1', 'var2', 'var3']);
+        $this->variableFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($this->variableMock);
+        $this->variableMock->expects($this->once())
+            ->method('getVariablesOptionArray')
+            ->willReturn(['custom var 1', 'custom var 2']);
+        $this->registryMock->expects($this->once())
+            ->method('registry')
+            ->willReturn($this->templateMock);
+        $this->templateMock->expects($this->once())
+            ->method('getId')
+            ->willReturn(1);
+        $this->templateMock->expects($this->once())
+            ->method('getVariablesOptionArray')
+            ->willReturn(['template var 1', 'template var 2']);
+        $this->assertEquals(
+            [['var1', 'var2', 'var3'], ['custom var 1', 'custom var 2'], ['template var 1', 'template var 2']],
+            $this->form->getVariables()
+        );
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Edit\Form::getEmailTemplate
+     */
+    public function testGetEmailTemplate()
+    {
+        $this->registryMock->expects($this->once())
+            ->method('registry')
+            ->with('current_email_template');
+        $this->form->getEmailTemplate();
+    }
+}
diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Grid/Renderer/ActionTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Grid/Renderer/ActionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..fc41f9ff4aaf2b88e3227ac0f0ab9bb4f876a1c8
--- /dev/null
+++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Grid/Renderer/ActionTest.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Email\Test\Unit\Block\Adminhtml\Template\Grid\Renderer;
+
+/**
+ * @covers Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Action
+ */
+class ActionTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Action
+     */
+    protected $action;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $columnMock;
+
+    protected function setUp()
+    {
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->columnMock = $this->getMockBuilder('Magento\Backend\Block\Widget\Grid\Column')
+            ->disableOriginalConstructor()
+            ->setMethods(['setActions', 'getActions'])
+            ->getMock();
+        $this->action = $objectManager->getObject('Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Action');
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Action::render
+     */
+    public function testRenderNoActions()
+    {
+        $this->columnMock->expects($this->once())
+            ->method('setActions');
+        $this->columnMock->expects($this->once())
+            ->method('getActions')
+            ->willReturn('');
+        $this->action->setColumn($this->columnMock);
+        $row = new \Magento\Framework\Object();
+        $this->assertEquals('&nbsp;', $this->action->render($row));
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Action::render
+     */
+    public function testRender()
+    {
+        $this->columnMock->expects($this->once())
+            ->method('setActions');
+        $this->columnMock->expects($this->once())
+            ->method('getActions')
+            ->willReturn(['url', 'popup', 'caption']);
+        $this->action->setColumn($this->columnMock);
+        $row = new \Magento\Framework\Object();
+        $row->setId(1);
+        $this->assertContains('action-select', $this->action->render($row));
+    }
+}
diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Grid/Renderer/SenderTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Grid/Renderer/SenderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..572b341759f50c4a7a92daf40444bdd028a05078
--- /dev/null
+++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Grid/Renderer/SenderTest.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Email\Test\Unit\Block\Adminhtml\Template\Grid\Renderer;
+
+/**
+ * @covers Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Sender
+ */
+class SenderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Sender
+     */
+    protected $sender;
+
+    protected function setUp()
+    {
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->sender = $objectManager->getObject('Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Sender');
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Sender::render
+     */
+    public function testRenderName()
+    {
+        $row = new \Magento\Framework\Object();
+        $row->setTemplateSenderName('Sender Name');
+        $this->assertEquals('Sender Name ', $this->sender->render($row));
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Sender::render
+     */
+    public function testRenderEmail()
+    {
+        $row = new \Magento\Framework\Object();
+        $row->setTemplateSenderEmail('Sender Email');
+        $this->assertEquals('[Sender Email]', $this->sender->render($row));
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Sender::render
+     */
+    public function testRenderNameAndEmail()
+    {
+        $row = new \Magento\Framework\Object();
+        $row->setTemplateSenderName('Sender Name');
+        $row->setTemplateSenderEmail('Sender Email');
+        $this->assertEquals('Sender Name [Sender Email]', $this->sender->render($row));
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Sender::render
+     */
+    public function testRenderEmpty()
+    {
+        $row = new \Magento\Framework\Object();
+        $this->assertEquals('---', $this->sender->render($row));
+    }
+}
diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Grid/Renderer/TypeTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Grid/Renderer/TypeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0e91708653a13afadd0af9a44dc282e5a0b83210
--- /dev/null
+++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/Template/Grid/Renderer/TypeTest.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Email\Test\Unit\Block\Adminhtml\Template\Grid\Renderer;
+
+/**
+ * @covers Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Type
+ */
+class TypeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Type
+     */
+    protected $type;
+
+    protected function setUp()
+    {
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->type = $objectManager->getObject('Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Type');
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Type::render
+     */
+    public function testRenderHtml()
+    {
+        $row = new \Magento\Framework\Object();
+        $row->setTemplateType(\Magento\Framework\App\TemplateTypesInterface::TYPE_HTML);
+        $this->assertEquals('HTML', $this->type->render($row));
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Type::render
+     */
+    public function testRenderText()
+    {
+        $row = new \Magento\Framework\Object();
+        $row->setTemplateType(\Magento\Framework\App\TemplateTypesInterface::TYPE_TEXT);
+        $this->assertEquals('Text', $this->type->render($row));
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Grid\Renderer\Type::render
+     */
+    public function testRenderUnknown()
+    {
+        $row = new \Magento\Framework\Object();
+        $row->setTemplateType('xx');
+        $this->assertEquals('Unknown', $this->type->render($row));
+    }
+}
diff --git a/app/code/Magento/Email/Test/Unit/Block/Adminhtml/TemplateTest.php b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/TemplateTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..57cb9a6392f52fa592190c66b367c7af2f24c862
--- /dev/null
+++ b/app/code/Magento/Email/Test/Unit/Block/Adminhtml/TemplateTest.php
@@ -0,0 +1,121 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Email\Test\Unit\Block\Adminhtml;
+
+/**
+ * @covers Magento\Email\Block\Adminhtml\Template
+ */
+class TemplateTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Email\Block\Adminhtml\Template */
+    protected $template;
+
+    /** @var \Magento\Backend\Block\Template\Context */
+    protected $context;
+
+    /** @var \Magento\Framework\UrlInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $urlBuilderMock;
+
+    /** @var \Magento\Backend\Block\Widget\Button\ItemFactory|\PHPUnit_Framework_MockObject_MockObject */
+    protected $itemFactoryMock;
+
+    /** @var \Magento\Backend\Block\Widget\Button\ButtonList */
+    protected $buttonList;
+
+    /** @var \Magento\Backend\Block\Widget\Button\Item|\PHPUnit_Framework_MockObject_MockObject */
+    protected $buttonMock;
+
+    /** @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager */
+    protected $objectManager;
+
+    protected function setUp()
+    {
+        $this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->itemFactoryMock = $this->getMockBuilder('Magento\Backend\Block\Widget\Button\ItemFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $this->buttonMock = $this->getMockBuilder('Magento\Backend\Block\Widget\Button\Item')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->itemFactoryMock->expects($this->any())
+            ->method('create')
+            ->willReturn($this->buttonMock);
+        $this->buttonList = $this->objectManager->getObject(
+            'Magento\Backend\Block\Widget\Button\ButtonList',
+            [ 'itemFactory' => $this->itemFactoryMock]
+        );
+        $this->urlBuilderMock = $this->getMockForAbstractClass(
+            'Magento\Framework\UrlInterface',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['getUrl']
+        );
+        $this->context = $this->objectManager->getObject(
+            'Magento\Backend\Block\Template\Context',
+            [
+                'urlBuilder' => $this->urlBuilderMock
+            ]
+        );
+        $this->template = $this->objectManager->getObject(
+            'Magento\Email\Block\Adminhtml\Template',
+            [
+                'context' => $this->context,
+                'buttonList' => $this->buttonList
+            ]
+        );
+    }
+
+    public function testAddButton()
+    {
+        $this->template->addButton('1', ['title' => 'My Button']);
+        $buttons = $this->buttonList->getItems()[0];
+        $this->assertContains('1', array_keys($buttons));
+    }
+
+    public function testUpdateButton()
+    {
+        $this->testAddButton();
+        $this->buttonMock->expects($this->once())
+            ->method('setData')
+            ->with('title', 'Updated Button')
+            ->willReturnSelf();
+        $result = $this->template->updateButton('1', 'title', 'Updated Button');
+        $this->assertSame($this->template, $result);
+    }
+
+    public function testRemoveButton()
+    {
+        $this->testAddButton();
+        $this->template->removeButton('1');
+        $buttons = $this->buttonList->getItems()[0];
+        $this->assertNotContains('1', array_keys($buttons));
+    }
+
+    public function testGetCreateUrl()
+    {
+        $this->urlBuilderMock->expects($this->once())
+            ->method('getUrl')
+            ->with('adminhtml/*/new', []);
+        $this->template->getCreateUrl();
+    }
+
+    public function testGetHeaderText()
+    {
+        $this->assertEquals('Transactional Emails', $this->template->getHeaderText());
+    }
+
+    public function testCanRender()
+    {
+        $this->buttonMock->expects($this->once())
+            ->method('isDeleted')
+            ->willReturn(false);
+        $this->assertTrue($this->template->canRender($this->buttonMock));
+    }
+}
diff --git a/app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/EditTest.php b/app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/EditTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..905318c274a3901b8f43cfc3f8afed87b4e04bdc
--- /dev/null
+++ b/app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/EditTest.php
@@ -0,0 +1,259 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Email\Test\Unit\Controller\Adminhtml\Email\Template;
+
+/**
+ * @covers \Magento\Email\Controller\Adminhtml\Email\Template\Edit
+ */
+class EditTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Email\Controller\Adminhtml\Email\Template\Edit
+     */
+    protected $editController;
+
+    /**
+     * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $registryMock;
+
+    /**
+     * @var \Magento\Backend\App\Action\Context
+     */
+    protected $context;
+
+    /**
+     * @var \Magento\Framework\App\Request|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $requestMock;
+
+    /**
+     * @var \Magento\Framework\App\View|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $viewMock;
+
+    /**
+     * @var \Magento\Framework\View\Layout|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $layoutMock;
+
+    /**
+     * @var \Magento\Backend\Block\Menu|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $menuBlockMock;
+
+    /**
+     * @var \Magento\Backend\Block\Widget\Breadcrumbs|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $breadcrumbsBlockMock;
+
+    /**
+     * @var \Magento\Backend\Block\Widget\Breadcrumbs|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $editBlockMock;
+
+    /**
+     * @var \Magento\Framework\View\Result\Page|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultPageMock;
+
+    /**
+     * @var \Magento\Framework\View\Page\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $pageConfigMock;
+
+    /**
+     * @var \Magento\Framework\View\Page\Title|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $pageTitleMock;
+
+    /**
+     * @return void
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    protected function setUp()
+    {
+        $this->registryMock = $this->getMockBuilder('Magento\Framework\Registry')
+            ->disableOriginalConstructor()
+            ->setMethods(['registry', 'register'])
+            ->getMock();
+        $this->requestMock = $this->getMockBuilder('Magento\Framework\App\Request\Http')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->viewMock = $this->getMockBuilder('Magento\Framework\App\View')
+            ->disableOriginalConstructor()
+            ->setMethods(['loadLayout', 'getLayout', 'getPage', 'renderLayout'])
+            ->getMock();
+        $this->layoutMock = $this->getMockBuilder('Magento\Framework\View\Layout')
+            ->disableOriginalConstructor()
+            ->setMethods(['getBlock', 'createBlock', 'setChild'])
+            ->getMock();
+        $this->menuBlockMock = $this->getMockBuilder('\Magento\Backend\Block\Menu')
+            ->disableOriginalConstructor()
+            ->setMethods(['setActive', 'getMenuModel', 'getParentItems'])
+            ->getMock();
+        $this->breadcrumbsBlockMock = $this->getMockBuilder('\Magento\Backend\Block\Widget\Breadcrumbs')
+            ->disableOriginalConstructor()
+            ->setMethods(['addLink'])
+            ->getMock();
+        $this->editBlockMock = $this->getMockBuilder('\Magento\Backend\Block\Widget\Breadcrumbs')
+            ->disableOriginalConstructor()
+            ->setMethods(['setEditMode'])
+            ->getMock();
+        $this->resultPageMock = $this->getMockBuilder('Magento\Framework\View\Result\Page')
+            ->disableOriginalConstructor()
+            ->setMethods(['setActiveMenu', 'getConfig', 'addBreadcrumb'])
+            ->getMock();
+        $this->pageConfigMock = $this->getMockBuilder('Magento\Framework\View\Page\Config')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->pageTitleMock = $this->getMockBuilder('Magento\Framework\View\Page\Title')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->viewMock->expects($this->atLeastOnce())
+            ->method('getLayout')
+            ->willReturn($this->layoutMock);
+        $this->layoutMock->expects($this->any())
+            ->method('getBlock')
+            ->willReturnMap(
+                [
+                    ['menu', $this->menuBlockMock],
+                    ['breadcrumbs', $this->breadcrumbsBlockMock],
+                    ['edit', $this->editBlockMock]
+                ]
+            );
+        $this->menuBlockMock->expects($this->any())
+            ->method('getMenuModel')
+            ->will($this->returnSelf());
+        $this->menuBlockMock->expects($this->any())
+            ->method('getParentItems')
+            ->will($this->returnValue([]));
+        $this->viewMock->expects($this->any())
+            ->method('getPage')
+            ->willReturn($this->resultPageMock);
+        $this->resultPageMock->expects($this->any())
+            ->method('getConfig')
+            ->willReturn($this->pageConfigMock);
+        $this->pageConfigMock->expects($this->any())
+            ->method('getTitle')
+            ->willReturn($this->pageTitleMock);
+        $this->layoutMock->expects($this->once())
+            ->method('createBlock')
+            ->with('Magento\Email\Block\Adminhtml\Template\Edit', 'template_edit', [])
+            ->willReturn($this->editBlockMock);
+        $this->editBlockMock->expects($this->once())
+            ->method('setEditMode')
+            ->willReturnSelf();
+
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $templateMock = $this->getMockBuilder('Magento\Email\Model\Template')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $templateMock->expects($this->once())
+            ->method('getId')
+            ->willReturn(1);
+        $templateMock->expects($this->any())
+            ->method('getTemplateCode')
+            ->willReturn('My Template');
+        $objectManagerMock = $this->getMockBuilder('Magento\Framework\App\ObjectManager')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $objectManagerMock->expects($this->once())
+            ->method('create')
+            ->with('Magento\Email\Model\BackendTemplate')
+            ->willReturn($templateMock);
+        $this->context = $objectManager->getObject(
+            'Magento\Backend\App\Action\Context',
+            [
+                'request' => $this->requestMock,
+                'objectManager' => $objectManagerMock,
+                'view' => $this->viewMock
+            ]
+        );
+        $this->editController = $objectManager->getObject(
+            'Magento\Email\Controller\Adminhtml\Email\Template\Edit',
+            [
+                'context' => $this->context,
+                'coreRegistry' => $this->registryMock
+            ]
+        );
+    }
+
+    /**
+     * @covers \Magento\Email\Controller\Adminhtml\Email\Template\Edit::execute
+     */
+    public function testExecuteNewTemplate()
+    {
+        $this->requestMock->expects($this->any())
+            ->method('getParam')
+            ->with('id')
+            ->willReturn(0);
+        $this->registryMock->expects($this->atLeastOnce())
+            ->method('registry')
+            ->willReturnMap(
+                [
+                    ['email_template', true],
+                    ['current_email_template', true]
+                ]
+            );
+        $this->pageTitleMock->expects($this->any())
+            ->method('prepend')
+            ->willReturnMap(
+                [
+                    ['Email Templates', $this->returnSelf()],
+                    ['New Template', $this->returnSelf()]
+                ]
+            );
+        $this->breadcrumbsBlockMock->expects($this->any())
+            ->method('addLink')
+            ->willReturnMap(
+                [
+                    ['Transactional Emails', 'Transactional Emails', null, $this->returnSelf()],
+                    ['New Template', 'New System Template', null, $this->returnSelf()]
+                ]
+            );
+
+        $this->assertNull($this->editController->execute());
+    }
+
+    /**
+     * @covers \Magento\Email\Controller\Adminhtml\Email\Template\Edit::execute
+     */
+    public function testExecuteEdit()
+    {
+        $this->requestMock->expects($this->any())
+            ->method('getParam')
+            ->with('id')
+            ->willReturn(1);
+        $this->registryMock->expects($this->atLeastOnce())
+            ->method('registry')
+            ->willReturnMap(
+                [
+                    ['email_template', false],
+                    ['current_email_template', false]
+                ]
+            );
+        $this->pageTitleMock->expects($this->any())
+            ->method('prepend')
+            ->willReturnMap(
+                [
+                    ['Email Templates', $this->returnSelf()],
+                    ['My Template', $this->returnSelf()]
+                ]
+            );
+        $this->breadcrumbsBlockMock->expects($this->any())
+            ->method('addLink')
+            ->willReturnMap(
+                [
+                    ['Transactional Emails', 'Transactional Emails', null, $this->returnSelf()],
+                    ['Edit Template', 'Edit System Template', null, $this->returnSelf()]
+                ]
+            );
+
+        $this->assertNull($this->editController->execute());
+    }
+}
diff --git a/app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/IndexTest.php b/app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/IndexTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c5ada6573f6b86c0c52a99a850944c56aacfc26b
--- /dev/null
+++ b/app/code/Magento/Email/Test/Unit/Controller/Adminhtml/Email/Template/IndexTest.php
@@ -0,0 +1,192 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Email\Test\Unit\Controller\Adminhtml\Email\Template;
+
+/**
+ * @covers \Magento\Email\Controller\Adminhtml\Email\Template\Index
+ */
+class IndexTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Email\Controller\Adminhtml\Email\Template\Index
+     */
+    protected $indexController;
+
+    /**
+     * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $registryMock;
+
+    /**
+     * @var \Magento\Backend\App\Action\Context
+     */
+    protected $context;
+
+    /**
+     * @var \Magento\Framework\App\Request|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $requestMock;
+
+    /**
+     * @var \Magento\Framework\App\View|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $viewMock;
+
+    /**
+     * @var \Magento\Framework\View\Layout|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $layoutMock;
+
+    /**
+     * @var \Magento\Backend\Block\Menu|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $menuBlockMock;
+
+    /**
+     * @var \Magento\Backend\Block\Widget\Breadcrumbs|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $breadcrumbsBlockMock;
+
+    /**
+     * @var \Magento\Framework\View\Result\Page|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultPageMock;
+
+    /**
+     * @var \Magento\Framework\View\Page\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $pageConfigMock;
+
+    /**
+     * @var \Magento\Framework\View\Page\Title|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $pageTitleMock;
+
+    protected function setUp()
+    {
+        $this->registryMock = $this->getMockBuilder('Magento\Framework\Registry')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->requestMock = $this->getMockBuilder('Magento\Framework\App\Request\Http')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->viewMock = $this->getMockBuilder('Magento\Framework\App\View')
+            ->disableOriginalConstructor()
+            ->setMethods(['loadLayout', 'getLayout', 'getPage', 'renderLayout'])
+            ->getMock();
+        $this->layoutMock = $this->getMockBuilder('Magento\Framework\View\Layout')
+            ->disableOriginalConstructor()
+            ->setMethods(['getBlock'])
+            ->getMock();
+        $this->menuBlockMock = $this->getMockBuilder('\Magento\Backend\Block\Menu')
+            ->disableOriginalConstructor()
+            ->setMethods(['setActive', 'getMenuModel', 'getParentItems'])
+            ->getMock();
+        $this->breadcrumbsBlockMock = $this->getMockBuilder('\Magento\Backend\Block\Widget\Breadcrumbs')
+            ->disableOriginalConstructor()
+            ->setMethods(['addLink'])
+            ->getMock();
+        $this->resultPageMock = $this->getMockBuilder('Magento\Framework\View\Result\Page')
+            ->disableOriginalConstructor()
+            ->setMethods(['setActiveMenu', 'getConfig', 'addBreadcrumb'])
+            ->getMock();
+        $this->pageConfigMock = $this->getMockBuilder('Magento\Framework\View\Page\Config')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->pageTitleMock = $this->getMockBuilder('Magento\Framework\View\Page\Title')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->context = $objectManager->getObject(
+            'Magento\Backend\App\Action\Context',
+            [
+                'request' => $this->requestMock,
+                'view' => $this->viewMock
+            ]
+        );
+        $this->indexController = $objectManager->getObject(
+            'Magento\Email\Controller\Adminhtml\Email\Template\Index',
+            [
+                'context' => $this->context,
+                'coreRegistry' => $this->registryMock
+            ]
+        );
+    }
+
+    /**
+     * @covers \Magento\Email\Controller\Adminhtml\Email\Template\Index::execute
+     */
+    public function testExecute()
+    {
+        $this->prepareExecute();
+
+        $this->viewMock->expects($this->atLeastOnce())
+            ->method('getLayout')
+            ->willReturn($this->layoutMock);
+        $this->layoutMock->expects($this->at(0))
+            ->method('getBlock')
+            ->with('menu')
+            ->will($this->returnValue($this->menuBlockMock));
+        $this->menuBlockMock->expects($this->any())
+            ->method('getMenuModel')
+            ->will($this->returnSelf());
+        $this->menuBlockMock->expects($this->any())
+            ->method('getParentItems')
+            ->will($this->returnValue([]));
+        $this->viewMock->expects($this->once())
+            ->method('getPage')
+            ->willReturn($this->resultPageMock);
+        $this->resultPageMock->expects($this->once())
+            ->method('getConfig')
+            ->willReturn($this->pageConfigMock);
+        $this->pageConfigMock->expects($this->once())
+            ->method('getTitle')
+            ->willReturn($this->pageTitleMock);
+        $this->pageTitleMock->expects($this->once())
+            ->method('prepend')
+            ->with('Email Templates');
+        $this->layoutMock->expects($this->at(1))
+            ->method('getBlock')
+            ->with('breadcrumbs')
+            ->will($this->returnValue($this->breadcrumbsBlockMock));
+        $this->breadcrumbsBlockMock->expects($this->any())
+            ->method('addLink')
+            ->willReturnSelf();
+
+        $this->assertNull($this->indexController->execute());
+    }
+
+    /**
+     * @covers \Magento\Email\Controller\Adminhtml\Email\Template\Index::execute
+     */
+    public function testExecuteAjax()
+    {
+        $this->prepareExecute(true);
+        $indexController = $this->getMockBuilder('Magento\Email\Controller\Adminhtml\Email\Template\Index')
+            ->setMethods(['getRequest', '_forward'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $indexController->expects($this->once())
+            ->method('getRequest')
+            ->will($this->returnValue($this->requestMock));
+        $indexController->expects($this->once())
+            ->method('_forward')
+            ->with('grid');
+        $this->assertNull($indexController->execute());
+    }
+
+    /**
+     * @param bool $ajax
+     */
+    protected function prepareExecute($ajax = false)
+    {
+        $this->requestMock->expects($this->once())
+            ->method('getQuery')
+            ->with('ajax')
+            ->willReturn($ajax);
+    }
+}
diff --git a/app/code/Magento/Email/Test/Unit/Model/Source/VariablesTest.php b/app/code/Magento/Email/Test/Unit/Model/Source/VariablesTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e74ee0d625c59904e80c1e974f5edff2314be4c4
--- /dev/null
+++ b/app/code/Magento/Email/Test/Unit/Model/Source/VariablesTest.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Email\Test\Unit\Model\Source;
+
+use Magento\Store\Model\Store;
+
+/**
+ * Unit test for Magento\Email\Model\Source\Variables
+ */
+class VariablesTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * Variables model
+     *
+     * @var \Magento\Email\Model\Source\Variables
+     */
+    protected $model;
+
+    /**
+     * Config variables
+     *
+     * @var array
+     */
+    protected $configVariables;
+
+    protected function setup()
+    {
+        $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->model = $helper->getObject('Magento\Email\Model\Source\Variables');
+        $this->configVariables = [
+            [
+                'value' => Store::XML_PATH_UNSECURE_BASE_URL,
+                'label' => __('Base Unsecure URL'),
+            ],
+            ['value' => Store::XML_PATH_SECURE_BASE_URL, 'label' => __('Base Secure URL')],
+            ['value' => 'trans_email/ident_general/name', 'label' => __('General Contact Name')],
+            ['value' => 'trans_email/ident_general/email', 'label' => __('General Contact Email')],
+            ['value' => 'trans_email/ident_sales/name', 'label' => __('Sales Representative Contact Name')],
+            ['value' => 'trans_email/ident_sales/email', 'label' => __('Sales Representative Contact Email')],
+            ['value' => 'trans_email/ident_custom1/name', 'label' => __('Custom1 Contact Name')],
+            ['value' => 'trans_email/ident_custom1/email', 'label' => __('Custom1 Contact Email')],
+            ['value' => 'trans_email/ident_custom2/name', 'label' => __('Custom2 Contact Name')],
+            ['value' => 'trans_email/ident_custom2/email', 'label' => __('Custom2 Contact Email')],
+            ['value' => 'general/store_information/name', 'label' => __('Store Name')],
+            ['value' => 'general/store_information/phone', 'label' => __('Store Phone Number')],
+            ['value' => 'general/store_information/country_id', 'label' => __('Country')],
+            ['value' => 'general/store_information/region_id', 'label' => __('Region/State')],
+            ['value' => 'general/store_information/postcode', 'label' => __('Zip/Postal Code')],
+            ['value' => 'general/store_information/city', 'label' => __('City')],
+            ['value' => 'general/store_information/street_line1', 'label' => __('Street Address 1')],
+            ['value' => 'general/store_information/street_line2', 'label' => __('Street Address 2')],
+        ];
+    }
+
+    public function testToOptionArrayWithoutGroup()
+    {
+        $optionArray = $this->model->toOptionArray();
+        $this->assertEquals(count($this->configVariables), count($optionArray));
+
+        $index = 0;
+        foreach ($optionArray as $variable) {
+            $expectedValue = '{{config path="' . $this->configVariables[$index]['value'] . '"}}';
+            $expectedLabel = $this->configVariables[$index]['label'];
+            $this->assertEquals($expectedValue, $variable['value']);
+            $this->assertEquals($expectedLabel, $variable['label']->getText());
+            $index++;
+        }
+    }
+
+    public function testToOptionArrayWithGroup()
+    {
+        $optionArray = $this->model->toOptionArray(true);
+        $this->assertEquals('Store Contact Information', $optionArray['label']->getText());
+
+        $optionArrayValues = $optionArray['value'];
+        $this->assertEquals(count($this->configVariables), count($optionArrayValues));
+
+        $index = 0;
+        foreach ($optionArrayValues as $variable) {
+            $expectedValue = '{{config path="' . $this->configVariables[$index]['value'] . '"}}';
+            $expectedLabel = $this->configVariables[$index]['label'];
+            $this->assertEquals($expectedValue, $variable['value']);
+            $this->assertEquals($expectedLabel, $variable['label']->getText());
+            $index++;
+        }
+    }
+}
diff --git a/app/code/Magento/Email/Test/Unit/Model/TemplateTest.php b/app/code/Magento/Email/Test/Unit/Model/TemplateTest.php
index 304621aa78b5ee06d108e5a8ddb4f83c448e2ef1..c18cab16cf5844c798af57c0bc12b19711802c76 100644
--- a/app/code/Magento/Email/Test/Unit/Model/TemplateTest.php
+++ b/app/code/Magento/Email/Test/Unit/Model/TemplateTest.php
@@ -5,8 +5,737 @@
  */
 namespace Magento\Email\Test\Unit\Model;
 
+use Magento\Email\Model\Template\Filter;
+use Magento\Framework\App\Filesystem\DirectoryList;
+use Magento\Framework\Filter\Template as FilterTemplate;
+
+/**
+ * Covers \Magento\Email\Model\Template
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class TemplateTest extends \PHPUnit_Framework_TestCase
 {
+    /**
+     * @var \Magento\Framework\Model\Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $context;
+
+    /**
+     * @var \Magento\Framework\View\DesignInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $design;
+
+    /**
+     * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $registry;
+
+    /**
+     * @var \Magento\Store\Model\App\Emulation|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $appEmulation;
+
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $storeManager;
+
+    /**
+     * @var \Magento\Framework\Filesystem|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $filesystem;
+
+    /**
+     * @var \Magento\Framework\View\Asset\Repository|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $assetRepo;
+
+    /**
+     * @var \Magento\Framework\View\FileSystem|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $viewFileSystem;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $scopeConfig;
+
+    /**
+     * @var \Magento\Email\Model\Template\FilterFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $emailFilterFactory;
+
+    /**
+     * @var \Magento\Email\Model\Template\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $emailConfig;
+
+    public function setUp()
+    {
+        $this->context = $this->getMockBuilder('Magento\Framework\Model\Context')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->design = $this->getMockBuilder('Magento\Framework\View\DesignInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->registry = $this->getMockBuilder('Magento\Framework\Registry')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->appEmulation = $this->getMockBuilder('Magento\Store\Model\App\Emulation')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->storeManager = $this->getMockBuilder('Magento\Store\Model\StoreManagerInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->filesystem = $this->getMockBuilder('Magento\Framework\Filesystem')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->assetRepo = $this->getMockBuilder('Magento\Framework\View\Asset\Repository')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->viewFileSystem = $this->getMockBuilder('Magento\Framework\View\FileSystem')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->scopeConfig = $this->getMockBuilder('Magento\Framework\App\Config\ScopeConfigInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->emailFilterFactory = $this->getMockBuilder('Magento\Email\Model\Template\FilterFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->emailConfig = $this->getMockBuilder('Magento\Email\Model\Template\Config')
+            ->disableOriginalConstructor()
+            ->getMock();
+    }
+
+    /**
+     * Return the model under test with additional methods mocked.
+     *
+     * @param $mockedMethods array
+     * @return \Magento\Email\Model\Template|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function getModelMock(array $mockedMethods = [])
+    {
+        return $this->getMockBuilder('Magento\Email\Model\Template')
+            ->setMethods(array_merge($mockedMethods, ['__wakeup', '__sleep', '_init']))
+            ->setConstructorArgs(
+                [
+                    $this->context,
+                    $this->design,
+                    $this->registry,
+                    $this->appEmulation,
+                    $this->storeManager,
+                    $this->filesystem,
+                    $this->assetRepo,
+                    $this->viewFileSystem,
+                    $this->scopeConfig,
+                    $this->emailFilterFactory,
+                    $this->emailConfig
+                ]
+            )
+            ->getMock();
+    }
+
+    public function testGetDefaultEmailLogo()
+    {
+        $model = $this->getModelMock();
+        $value = 'urlWithParamsValue';
+        $this->assetRepo->method('getUrlWithParams')
+            ->with('Magento_Email::logo_email.png', ['area' => \Magento\Framework\App\Area::AREA_FRONTEND])
+            ->will($this->returnValue($value));
+        $this->assertEquals($value, $model->getDefaultEmailLogo());
+    }
+
+    public function testSetAndGetTemplateFilter()
+    {
+        $model = $this->getModelMock();
+        $filterTemplate = $this->getMockBuilder('Magento\Framework\Filter\Template')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $model->setTemplateFilter($filterTemplate);
+        $this->assertSame($filterTemplate, $model->getTemplateFilter());
+    }
+
+    public function testGetTemplateFilterWithEmptyValue()
+    {
+        $filterTemplate = $this->getMockBuilder('Magento\Framework\Filter\Template')
+            ->setMethods(['setUseAbsoluteLinks', 'setStoreId'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $filterTemplate->expects($this->once())
+            ->method('setUseAbsoluteLinks')
+            ->will($this->returnSelf());
+        $filterTemplate->expects($this->once())
+            ->method('setStoreId')
+            ->will($this->returnSelf());
+        $this->emailFilterFactory->method('create')
+            ->will($this->returnValue($filterTemplate));
+        $designConfig = $this->getMockBuilder('Magento\Framework\Object')
+            ->setMethods(['getStore'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $model = $this->getModelMock(['getUseAbsoluteLinks', 'getDesignConfig']);
+        $model->expects($this->once())
+            ->method('getDesignConfig')
+            ->will($this->returnValue($designConfig));
+
+        $this->assertSame($filterTemplate, $model->getTemplateFilter());
+    }
+
+    /**
+     * @param $templateType string
+     * @param $templateText string
+     * @param $parsedTemplateText string
+     * @param $expectedTemplateSubject string|null
+     * @param $expectedOrigTemplateVariables array|null
+     * @param $expectedTemplateStyles string|null
+     * @dataProvider loadDefaultDataProvider
+     */
+    public function testLoadDefault(
+        $templateType,
+        $templateText,
+        $parsedTemplateText,
+        $expectedTemplateSubject,
+        $expectedOrigTemplateVariables,
+        $expectedTemplateStyles
+    ) {
+        $model = $this->getModelMock();
+
+        $templateId = 'templateId';
+
+        $templateFile = 'templateFile';
+        $this->emailConfig->expects($this->once())
+            ->method('getTemplateFilename')
+            ->with($templateId)
+            ->will($this->returnValue($templateFile));
+        $this->emailConfig->expects($this->once())
+            ->method('getTemplateType')
+            ->with($templateId)
+            ->will($this->returnValue($templateType));
+
+        $modulesDir = $this->getMockBuilder('Magento\Framework\Filesystem\Directory\ReadInterface')
+            ->setMethods(['readFile', 'getRelativePath'])
+            ->getMockForAbstractClass();
+
+        $relativePath = 'relativePath';
+        $modulesDir->expects($this->once())
+            ->method('getRelativePath')
+            ->with($templateFile)
+            ->will($this->returnValue($relativePath));
+        $modulesDir->expects($this->once())
+            ->method('readFile')
+            ->will($this->returnValue($templateText));
+
+        $this->filesystem->expects($this->once())
+            ->method('getDirectoryRead')
+            ->with(\Magento\Framework\App\Filesystem\DirectoryList::MODULES)
+            ->will($this->returnValue($modulesDir));
+
+        $model->loadDefault($templateId);
+
+        if ($templateType === 'html') {
+            $this->assertEquals(\Magento\Email\Model\Template::TYPE_HTML, $model->getTemplateType());
+        } else {
+            $this->assertEquals(\Magento\Email\Model\Template::TYPE_TEXT, $model->getTemplateType());
+        }
+        $this->assertEquals($templateId, $model->getId());
+        $this->assertEquals($parsedTemplateText, $model->getTemplateText());
+        $this->assertEquals($expectedTemplateSubject, $model->getTemplateSubject());
+        $this->assertEquals($expectedOrigTemplateVariables, $model->getData('orig_template_variables'));
+        $this->assertEquals($expectedTemplateStyles, $model->getTemplateStyles());
+    }
+
+    public function loadDefaultDataProvider()
+    {
+        return [
+            'empty' => [
+                'templateType' => 'html',
+                'templateText' => '',
+                'parsedTemplateText' => '',
+                'expectedTemplateSubject' => null,
+                'expectedOrigTemplateVariables' => null,
+                'expectedTemplateStyles' => null,
+            ],
+            'copyright in Plain Text Removed' => [
+                'templateType' => 'text',
+                'templateText' => '<!-- Copyright © 2015 Magento. All rights reserved. -->',
+                'parsedTemplateText' => '',
+                'expectedTemplateSubject' => null,
+                'expectedOrigTemplateVariables' => null,
+                'expectedTemplateStyles' => null,
+            ],
+            'copyright in HTML Remains' => [
+                'templateType' => 'html',
+                'templateText' => '<!-- Copyright © 2015 Magento. All rights reserved. -->',
+                'parsedTemplateText' => '<!-- Copyright © 2015 Magento. All rights reserved. -->',
+                'expectedTemplateSubject' => null,
+                'expectedOrigTemplateVariables' => null,
+                'expectedTemplateStyles' => null,
+            ],
+            'subject set' => [
+                'templateType' => 'html',
+                'templateText' => '<!--@subject Email Subject @-->',
+                'parsedTemplateText' => '',
+                'expectedTemplateSubject' => 'Email Subject',
+                'expectedOrigTemplateVariables' => null,
+                'expectedTemplateStyles' => null,
+            ],
+            'orig_template_variables set' => [
+                'templateType' => 'html',
+                'templateText' => '<!--@vars {"store url=\"\"":"Store Url"} @-->Some Other Text',
+                'parsedTemplateText' => 'Some Other Text',
+                'expectedTemplateSubject' => null,
+                'expectedOrigTemplateVariables' => '{"store url=\"\"":"Store Url"}',
+                'expectedTemplateStyles' => null,
+            ],
+            'styles' => [
+                'templateType' => 'html',
+                'templateText' => '<!--@vars {"store url=\"\"":"Store Url"} @-->Some Other Text',
+                'parsedTemplateText' => 'Some Other Text',
+                'expectedTemplateSubject' => null,
+                'expectedOrigTemplateVariables' => '{"store url=\"\"":"Store Url"}',
+                'expectedTemplateStyles' => null,
+            ],
+        ];
+    }
+
+    public function testLoadByCode()
+    {
+        $templateCode = 'templateCode';
+        $templateData = ['templateData'];
+        $resource = $this->getMockBuilder('Magento\Email\Model\Resource\Template')
+            ->setMethods(['loadByCode'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $resource->expects($this->once())
+            ->method('loadByCode')
+            ->with($templateCode)
+            ->will($this->returnValue($templateData));
+        $model = $this->getModelMock(['addData', 'getResource']);
+        $model->expects($this->once())
+            ->method('getResource')
+            ->will($this->returnValue($resource));
+        $model->expects($this->once())
+            ->method('addData')
+            ->with($templateData);
+        $this->assertEquals($model, $model->loadByCode($templateCode));
+    }
+
+    public function testGetAndSetId()
+    {
+        $model = $this->getModelMock();
+        $templateId = 'templateId';
+        $this->assertEquals($model, $model->setId($templateId));
+        $this->assertEquals($templateId, $model->getId());
+    }
+
+    /**
+     * @param $isSMTPDisabled bool
+     * @param $senderName string
+     * @param $senderEmail string
+     * @param $templateSubject string
+     * @dataProvider isValidForSendDataProvider
+     */
+    public function testIsValidForSend($isSMTPDisabled, $senderName, $senderEmail, $templateSubject, $expectedValue)
+    {
+        $this->scopeConfig->expects($this->once())
+            ->method('isSetFlag')
+            ->with('system/smtp/disable', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue($isSMTPDisabled));
+        $model = $this->getModelMock(['getSenderName', 'getSenderEmail', 'getTemplateSubject']);
+        $model->expects($this->any())
+            ->method('getSenderName')
+            ->will($this->returnValue($senderName));
+        $model->expects($this->any())
+            ->method('getSenderEmail')
+            ->will($this->returnValue($senderEmail));
+        $model->expects($this->any())
+            ->method('getTemplateSubject')
+            ->will($this->returnValue($templateSubject));
+        $this->assertEquals($expectedValue, $model->isValidForSend());
+    }
+
+    public function isValidForSendDataProvider()
+    {
+        return [
+            'should be valid' => [
+                'isSMTPDisabled' => false,
+                'senderName' => 'sender name',
+                'senderEmail' => 'email@example.com',
+                'templateSubject' => 'template subject',
+                'expectedValue' => true
+            ],
+            'no smtp so not valid' => [
+                'isSMTPDisabled' => true,
+                'senderName' => 'sender name',
+                'senderEmail' => 'email@example.com',
+                'templateSubject' => 'template subject',
+                'expectedValue' => false
+            ],
+            'no sender name so not valid' => [
+                'isSMTPDisabled' => false,
+                'senderName' => '',
+                'senderEmail' => 'email@example.com',
+                'templateSubject' => 'template subject',
+                'expectedValue' => false
+            ],
+            'no sender email so not valid' => [
+                'isSMTPDisabled' => false,
+                'senderName' => 'sender name',
+                'senderEmail' => '',
+                'templateSubject' => 'template subject',
+                'expectedValue' => false
+            ],
+            'no subject so not valid' => [
+                'isSMTPDisabled' => false,
+                'senderName' => 'sender name',
+                'senderEmail' => 'email@example.com',
+                'templateSubject' => '',
+                'expectedValue' => false
+            ],
+        ];
+    }
+
+    /**
+     * @param $variables array
+     * @param $templateType string
+     * @param $storeId int
+     * @param $expectedVariables array
+     * @param $expectedResult string
+     * @dataProvider getProcessedTemplateProvider
+     */
+    public function testGetProcessedTemplate($variables, $templateType, $storeId, $expectedVariables, $expectedResult)
+    {
+        $filterTemplate = $this->getMockBuilder('Magento\Framework\Filter\Template')
+            ->setMethods([
+                'setUseSessionInUrl',
+                'setPlainTemplateMode',
+                'setVariables',
+                'setStoreId',
+                'filter',
+                'getStoreId',
+            ])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $filterTemplate->expects($this->once())
+            ->method('setUseSessionInUrl')
+            ->with(false)
+            ->will($this->returnSelf());
+        $filterTemplate->expects($this->once())
+            ->method('setPlainTemplateMode')
+            ->with($templateType === \Magento\Framework\App\TemplateTypesInterface::TYPE_TEXT)
+            ->will($this->returnSelf());
+        $filterTemplate->expects($this->any())
+            ->method('setStoreId')
+            ->will($this->returnSelf());
+        $filterTemplate->expects($this->any())
+            ->method('getStoreId')
+            ->will($this->returnValue($storeId));
+
+        $store = $this->getMockBuilder('Magento\Store\Model\Store')
+            ->setMethods(['getFrontendName'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $store->expects($this->any())
+            ->method('getFrontendName')
+            ->will($this->returnValue('frontendName'));
+        $this->storeManager->expects($this->any())
+            ->method('getStore')
+            ->will($this->returnValue($store));
+
+        $model = $this->getModelMock(['getDesignConfig', '_applyDesignConfig', 'getPreparedTemplateText']);
+        $model->setTemplateFilter($filterTemplate);
+        $model->setTemplateType($templateType);
+
+        $designConfig = $this->getMockBuilder('Magento\Framework\Object')
+            ->setMethods(['getStore'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $storeId = 'storeId';
+        $designConfig->expects($this->once())
+            ->method('getStore')
+            ->will($this->returnValue($storeId));
+        $model->expects($this->once())
+            ->method('getDesignConfig')
+            ->will($this->returnValue($designConfig));
+        $filterTemplate->expects($this->once())
+            ->method('setVariables')
+            ->with(array_merge([ 'this' => $model], $expectedVariables));
+
+        $preparedTemplateText = 'prepared text';
+        $model->expects($this->once())
+            ->method('getPreparedTemplateText')
+            ->will($this->returnValue($preparedTemplateText));
+        $filterTemplate->expects($this->once())
+            ->method('filter')
+            ->with($preparedTemplateText)
+            ->will($this->returnValue($expectedResult));
+
+        $this->assertEquals($expectedResult, $model->getProcessedTemplate($variables));
+    }
+
+    /**
+     * @return array
+     */
+    public function getProcessedTemplateProvider()
+    {
+        return [
+            'default' => [
+                'variables' => [],
+                'templateType' => \Magento\Framework\App\TemplateTypesInterface::TYPE_TEXT,
+                'storeId' => 1,
+                'expectedVariables' => [
+                    'logo_url' => null,
+                    'logo_alt' => 'frontendName',
+                ],
+                'expectedResult' => 'expected result',
+            ],
+            'logo variables set' => [
+                'variables' => [
+                    'logo_url' => 'http://example.com/logo',
+                    'logo_alt' => 'Logo Alt',
+                ],
+                'templateType' => \Magento\Framework\App\TemplateTypesInterface::TYPE_HTML,
+                'storeId' => 1,
+                'expectedVariables' => [
+                    'logo_url' => 'http://example.com/logo',
+                    'logo_alt' => 'Logo Alt',
+                ],
+                'expectedResult' => 'expected result',
+            ],
+        ];
+    }
+
+    /**
+     * @param $templateType string
+     * @param $templateStyles string
+     * @param $templateText string
+     * @param $expectedResult string
+     * @dataProvider getPreparedTemplateTextProvider
+     */
+    public function testGetPreparedTemplateText($templateType, $templateStyles, $templateText, $expectedResult)
+    {
+        $model = $this->getModelMock();
+        $model->setTemplateType($templateType);
+        $model->setTemplateStyles($templateStyles);
+        $model->setTemplateText($templateText);
+        $this->assertEquals($expectedResult, $model->getPreparedTemplateText());
+    }
+
+    public function getPreparedTemplateTextProvider()
+    {
+        return [
+            'plain text' => [
+                'templateType' => \Magento\Framework\App\TemplateTypesInterface::TYPE_TEXT,
+                'templateStyles' => '<style>',
+                'templateText' => 'template text',
+                'expectedResult' => 'template text',
+            ],
+            'html no style' => [
+                'templateType' => \Magento\Framework\App\TemplateTypesInterface::TYPE_HTML,
+                'templateStyles' => '',
+                'templateText' => 'template text',
+                'expectedResult' => 'template text',
+            ],
+            'html with style' => [
+                'templateType' => \Magento\Framework\App\TemplateTypesInterface::TYPE_HTML,
+                'templateStyles' => '.body { color: orange }',
+                'templateText' => 'template text',
+                'expectedResult' =>
+                    '<style type="text/css">' . "\n.body { color: orange }\n</style>\n" . 'template text',
+            ],
+        ];
+    }
+
+    public function testGetProcessedTemplateSubject()
+    {
+        $model = $this->getModelMock(['getTemplateFilter', 'getDesignConfig', '_applyDesignConfig']);
+
+        $templateSubject = 'templateSubject';
+        $model->setTemplateSubject($templateSubject);
+
+        $filterTemplate = $this->getMockBuilder('Magento\Framework\Filter\Template')
+            ->setMethods(['setVariables', 'setStoreId', 'filter'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $model->expects($this->once())
+            ->method('getTemplateFilter')
+            ->will($this->returnValue($filterTemplate));
+
+        $model->expects($this->once())
+            ->method('_applyDesignConfig');
+
+        $designConfig = $this->getMockBuilder('Magento\Framework\Object')
+            ->setMethods(['getStore'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $storeId = 'storeId';
+        $designConfig->expects($this->once())
+            ->method('getStore')
+            ->will($this->returnValue($storeId));
+        $model->expects($this->once())
+            ->method('getDesignConfig')
+            ->will($this->returnValue($designConfig));
+
+        $filterTemplate->expects($this->once())
+            ->method('setStoreId')
+            ->with($storeId)
+            ->will($this->returnSelf());
+        $expectedResult = 'expected';
+        $filterTemplate->expects($this->once())
+            ->method('filter')
+            ->with($templateSubject)
+            ->will($this->returnValue($expectedResult));
+
+        $variables = [ 'key' => 'value' ];
+        $filterTemplate->expects($this->once())
+            ->method('setVariables')
+            ->with(array_merge($variables, ['this' => $model]));
+        $this->assertEquals($expectedResult, $model->getProcessedTemplateSubject($variables));
+    }
+
+    /**
+     * @param $withGroup bool
+     * @param $templateVariables string
+     * @param $expectedResult array
+     * @dataProvider getVariablesOptionArrayDataProvider
+     */
+    public function testGetVariablesOptionArray($withGroup, $templateVariables, $expectedResult)
+    {
+        $model = $this->getModelMock();
+        $model->setData('orig_template_variables', $templateVariables);
+        $this->assertEquals($expectedResult, $model->getVariablesOptionArray($withGroup));
+    }
+
+    public function getVariablesOptionArrayDataProvider()
+    {
+        return [
+            'empty variables' => [
+                'withGroup' => false,
+                'templateVariables' => '',
+                'expectedResult' => [],
+            ],
+            'empty variables with grouped option' => [
+                'withGroup' => true,
+                'templateVariables' => '',
+                'expectedResult' => [],
+            ],
+            'customer account new variables' => [
+                'withGroup' => false,
+                'templateVariables' => '{"store url=\"\"":"Store Url","var logo_url":"Email Logo Image Url",'
+                . '"escapehtml var=$customer.name":"Customer Name"}',
+                'expectedResult' => [
+                    [
+                        'value' => '{{store url=""}}',
+                        'label' => __('%1', 'Store Url'),
+                    ],
+                    [
+                        'value' => '{{var logo_url}}',
+                        'label' => __('%1', 'Email Logo Image Url'),
+                    ],
+                    [
+                        'value' => '{{escapehtml var=$customer.name}}',
+                        'label' => __('%1', 'Customer Name'),
+                    ],
+                ],
+            ],
+            'customer account new variables with grouped option' => [
+                'withGroup' => true,
+                'templateVariables' => '{"store url=\"\"":"Store Url","var logo_url":"Email Logo Image Url",'
+                . '"escapehtml var=$customer.name":"Customer Name"}',
+                'expectedResult' => [
+                    'label' => __('Template Variables'),
+                    'value' => [
+                        [
+                            'value' => '{{store url=""}}',
+                            'label' => __('%1', 'Store Url'),
+                        ],
+                        [
+                            'value' => '{{var logo_url}}',
+                            'label' => __('%1', 'Email Logo Image Url'),
+                        ],
+                        [
+                            'value' => '{{escapehtml var=$customer.name}}',
+                            'label' => __('%1', 'Customer Name'),
+                        ],
+                    ],
+                ],
+            ],
+        ];
+    }
+
+    /**
+     * @param $templateId string|int
+     * @param $expectedResult string
+     * @dataProvider processTemplateVariable
+     */
+    public function testProcessTemplate($templateId, $expectedResult)
+    {
+        $model = $this->getModelMock([
+            'load',
+            'loadDefault',
+            'getProcessedTemplate'
+        ]);
+        $model->setId($templateId);
+        if (is_numeric($templateId)) {
+            $model->expects($this->once())
+                ->method('load')
+                ->with($templateId);
+        } else {
+            $model->expects($this->once())
+                ->method('loadDefault')
+                ->with($templateId);
+        }
+
+        $vars = [ 'key' => 'value' ];
+        $model->setVars($vars);
+        $model->expects($this->once())
+            ->method('getProcessedTemplate')
+            ->with($vars, true)
+            ->will($this->returnValue($expectedResult));
+
+        $this->assertEquals($expectedResult, $model->processTemplate());
+        $this->assertTrue($model->getUseAbsoluteLinks());
+    }
+
+    public function processTemplateVariable()
+    {
+        return [
+            'numeric id' => [
+                'templateId' => 1,
+                'expectedResult' => 'expected result',
+            ],
+            'string id' => [
+                'templateId' => 'my id',
+                'expectedResult' => 'expected result',
+            ],
+        ];
+    }
+
+    public function testGetSubject()
+    {
+        $variables = [ 'key' => 'value' ];
+        $model = $this->getModelMock(['getProcessedTemplateSubject']);
+        $model->setVars($variables);
+        $expectedResult = 'result';
+        $model->expects($this->once())
+            ->method('getProcessedTemplateSubject')
+            ->with($variables)
+            ->will($this->returnValue($expectedResult));
+        $this->assertEquals($expectedResult, $model->getSubject());
+    }
+
+    public function testSetOptions()
+    {
+        $options = ['someOption' => 'someValue'];
+        $model = $this->getModelMock(['setDesignConfig']);
+        $model->expects($this->once())
+            ->method('setDesignConfig')
+            ->with($options);
+        $model->setOptions($options);
+    }
+
     /**
      * @dataProvider getTypeDataProvider
      * @param string $templateType
diff --git a/app/code/Magento/GiftMessage/Api/CartRepositoryInterface.php b/app/code/Magento/GiftMessage/Api/CartRepositoryInterface.php
index 62a7916c14ca9479e2a9feefa458aa2c8aacf5ed..7e34c18ed0d6531fef0ce82b093e9b0551aa549f 100644
--- a/app/code/Magento/GiftMessage/Api/CartRepositoryInterface.php
+++ b/app/code/Magento/GiftMessage/Api/CartRepositoryInterface.php
@@ -8,7 +8,7 @@ namespace Magento\GiftMessage\Api;
 interface CartRepositoryInterface
 {
     /**
-     * Returns the gift message for a specified order.
+     * Return the gift message for a specified order.
      *
      * @param int $cartId The shopping cart ID.
      * @return \Magento\GiftMessage\Api\Data\MessageInterface Gift message.
@@ -16,7 +16,7 @@ interface CartRepositoryInterface
     public function get($cartId);
 
     /**
-     * Sets the gift message for an entire order.
+     * Set the gift message for an entire order.
      *
      * @param int $cartId The cart ID.
      * @param \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage The gift message.
diff --git a/app/code/Magento/GiftMessage/Api/Data/MessageInterface.php b/app/code/Magento/GiftMessage/Api/Data/MessageInterface.php
index a044e7c0ab0c72253dc3b375c1ed2677fb47c389..5faf04f77045c257707bc84fd3e9466380aa6349 100644
--- a/app/code/Magento/GiftMessage/Api/Data/MessageInterface.php
+++ b/app/code/Magento/GiftMessage/Api/Data/MessageInterface.php
@@ -18,14 +18,14 @@ interface MessageInterface extends \Magento\Framework\Api\ExtensibleDataInterfac
     /**#@-*/
 
     /**
-     * Returns the gift message ID.
+     * Return the gift message ID.
      *
      * @return int|null Gift message ID. Otherwise, null.
      */
     public function getGiftMessageId();
 
     /**
-     * Sets the gift message ID.
+     * Set the gift message ID.
      *
      * @param int|null $id
      * @return $this
@@ -33,14 +33,14 @@ interface MessageInterface extends \Magento\Framework\Api\ExtensibleDataInterfac
     public function setGiftMessageId($id);
 
     /**
-     * Returns the customer ID.
+     * Return the customer ID.
      *
      * @return int|null Customer ID. Otherwise, null.
      */
     public function getCustomerId();
 
     /**
-     * Sets the customer ID.
+     * Set the customer ID.
      *
      * @param int|null $id
      * @return $this
@@ -48,14 +48,14 @@ interface MessageInterface extends \Magento\Framework\Api\ExtensibleDataInterfac
     public function setCustomerId($id);
 
     /**
-     * Returns the sender name.
+     * Return the sender name.
      *
      * @return string Sender name.
      */
     public function getSender();
 
     /**
-     * Sets the sender name.
+     * Set the sender name.
      *
      * @param string $sender
      * @return $this
@@ -63,14 +63,14 @@ interface MessageInterface extends \Magento\Framework\Api\ExtensibleDataInterfac
     public function setSender($sender);
 
     /**
-     * Returns the recipient name.
+     * Return the recipient name.
      *
      * @return string Recipient name.
      */
     public function getRecipient();
 
     /**
-     * Gets the recipient name.
+     * Get the recipient name.
      *
      * @param string $recipient
      * @return $this
@@ -78,14 +78,14 @@ interface MessageInterface extends \Magento\Framework\Api\ExtensibleDataInterfac
     public function setRecipient($recipient);
 
     /**
-     * Returns the message text.
+     * Return the message text.
      *
      * @return string Message text.
      */
     public function getMessage();
 
     /**
-     * Sets the message text.
+     * Set the message text.
      *
      * @param string $message
      * @return $this
diff --git a/app/code/Magento/GiftMessage/Api/ItemRepositoryInterface.php b/app/code/Magento/GiftMessage/Api/ItemRepositoryInterface.php
index f0141740b3ed9b34f40822415c3d301e16e27876..3e2f771fad1337908d2fa1759d8760911c7b0bf7 100644
--- a/app/code/Magento/GiftMessage/Api/ItemRepositoryInterface.php
+++ b/app/code/Magento/GiftMessage/Api/ItemRepositoryInterface.php
@@ -8,7 +8,7 @@ namespace Magento\GiftMessage\Api;
 interface ItemRepositoryInterface
 {
     /**
-     * Returns the gift message for a specified item in a specified shopping cart.
+     * Return the gift message for a specified item in a specified shopping cart.
      *
      * @param int $cartId The shopping cart ID.
      * @param int $itemId The item ID.
@@ -18,7 +18,7 @@ interface ItemRepositoryInterface
     public function get($cartId, $itemId);
 
     /**
-     * Sets the gift message for a specified item in a specified shopping cart.
+     * Set the gift message for a specified item in a specified shopping cart.
      *
      * @param int $cartId The cart ID.
      * @param \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage The gift message.
diff --git a/app/code/Magento/GiftMessage/Api/OrderItemRepositoryInterface.php b/app/code/Magento/GiftMessage/Api/OrderItemRepositoryInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..4b94af3ce5f6155fb451021ed6ae1b581b9fbf8f
--- /dev/null
+++ b/app/code/Magento/GiftMessage/Api/OrderItemRepositoryInterface.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\GiftMessage\Api;
+
+interface OrderItemRepositoryInterface
+{
+    /**
+     * Return the gift message for a specified item in a specified order.
+     *
+     * @param int $orderId The order ID.
+     * @param int $orderItemId The item ID.
+     * @return \Magento\GiftMessage\Api\Data\MessageInterface Gift message.
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     */
+    public function get($orderId, $orderItemId);
+
+    /**
+     * Set the gift message for a specified item in a specified order.
+     *
+     * @param int $orderId The order ID.
+     * @param int $orderItemId The item ID.
+     * @param \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage The gift message.
+     * @return bool
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     * @throws \Magento\Framework\Exception\State\InvalidTransitionException
+     * @throws \Magento\Framework\Exception\CouldNotSaveException
+     */
+    public function save($orderId, $orderItemId, \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage);
+}
diff --git a/app/code/Magento/GiftMessage/Api/OrderRepositoryInterface.php b/app/code/Magento/GiftMessage/Api/OrderRepositoryInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..28f5b54dde526722c322f5c319cfb8c48b1c943e
--- /dev/null
+++ b/app/code/Magento/GiftMessage/Api/OrderRepositoryInterface.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\GiftMessage\Api;
+
+interface OrderRepositoryInterface
+{
+    /**
+     * Return the gift message for a specified order.
+     *
+     * @param int $orderId The order ID.
+     * @return \Magento\GiftMessage\Api\Data\MessageInterface Gift message.
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     */
+    public function get($orderId);
+
+    /**
+     * Set the gift message for an entire order.
+     *
+     * @param int $orderId The order ID.
+     * @param \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage The gift message.
+     * @return bool
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     * @throws \Magento\Framework\Exception\InputException
+     * @throws \Magento\Framework\Exception\CouldNotSaveException
+     * @throws \Magento\Framework\Exception\State\InvalidTransitionException
+     */
+    public function save($orderId, \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage);
+}
diff --git a/app/code/Magento/GiftMessage/Block/Adminhtml/Sales/Order/Create/Form.php b/app/code/Magento/GiftMessage/Block/Adminhtml/Sales/Order/Create/Form.php
index 44933c3de7c0ce179be214e10f64ec62bc047491..c5d2d46cccfb1f1904b25be12d0a83610de04f2b 100644
--- a/app/code/Magento/GiftMessage/Block/Adminhtml/Sales/Order/Create/Form.php
+++ b/app/code/Magento/GiftMessage/Block/Adminhtml/Sales/Order/Create/Form.php
@@ -47,6 +47,6 @@ class Form extends \Magento\Backend\Block\Template
     public function canDisplayGiftmessageForm()
     {
         $quote = $this->_sessionQuote->getQuote();
-        return $this->_messageHelper->getIsMessagesAvailable('items', $quote, $quote->getStore());
+        return $this->_messageHelper->isMessagesAllowed('items', $quote, $quote->getStore());
     }
 }
diff --git a/app/code/Magento/GiftMessage/Block/Adminhtml/Sales/Order/Create/Items.php b/app/code/Magento/GiftMessage/Block/Adminhtml/Sales/Order/Create/Items.php
index ebd3613070da152027828aa917a87d1514f9e2a5..f343fce19c7d8d64243d6806bb1bb42784af755e 100644
--- a/app/code/Magento/GiftMessage/Block/Adminhtml/Sales/Order/Create/Items.php
+++ b/app/code/Magento/GiftMessage/Block/Adminhtml/Sales/Order/Create/Items.php
@@ -52,7 +52,7 @@ class Items extends \Magento\Backend\Block\Template
         if (!$item) {
             return false;
         }
-        return $this->_messageHelper->getIsMessagesAvailable('item', $item, $item->getStoreId());
+        return $this->_messageHelper->isMessagesAllowed('item', $item, $item->getStoreId());
     }
 
     /**
diff --git a/app/code/Magento/GiftMessage/Block/Message/Inline.php b/app/code/Magento/GiftMessage/Block/Message/Inline.php
index 71edfa4fe880d23684edf68185276ec1c6d2677f..4a7640f3aa7814cbdfb04a47430d3905d7236065 100644
--- a/app/code/Magento/GiftMessage/Block/Message/Inline.php
+++ b/app/code/Magento/GiftMessage/Block/Message/Inline.php
@@ -317,7 +317,7 @@ class Inline extends \Magento\Framework\View\Element\Template
      */
     public function isMessagesAvailable()
     {
-        return $this->_giftMessageMessage->isMessagesAvailable('quote', $this->getEntity());
+        return $this->_giftMessageMessage->isMessagesAllowed('quote', $this->getEntity());
     }
 
     /**
@@ -329,7 +329,7 @@ class Inline extends \Magento\Framework\View\Element\Template
     public function isItemMessagesAvailable($item)
     {
         $type = substr($this->getType(), 0, 5) == 'multi' ? 'address_item' : 'item';
-        return $this->_giftMessageMessage->isMessagesAvailable($type, $item);
+        return $this->_giftMessageMessage->isMessagesAllowed($type, $item);
     }
 
     /**
diff --git a/app/code/Magento/GiftMessage/Helper/Message.php b/app/code/Magento/GiftMessage/Helper/Message.php
index a54b8c5db8c53d005aa7c6968e8ac4c4767d3594..e2ab3e3eefa6fcce05032ef3437ee17b771616b4 100644
--- a/app/code/Magento/GiftMessage/Helper/Message.php
+++ b/app/code/Magento/GiftMessage/Helper/Message.php
@@ -109,7 +109,7 @@ class Message extends \Magento\Framework\App\Helper\AbstractHelper
      */
     public function getInline($type, \Magento\Framework\Object $entity, $dontDisplayContainer = false)
     {
-        if (!$this->skipPage($type) && !$this->isMessagesAvailable($type, $entity)) {
+        if (!$this->skipPage($type) && !$this->isMessagesAllowed($type, $entity)) {
             return '';
         }
         return $this->_layoutFactory->create()->createBlock('Magento\GiftMessage\Block\Message\Inline')
@@ -129,7 +129,7 @@ class Message extends \Magento\Framework\App\Helper\AbstractHelper
     }
 
     /**
-     * Check availability of giftmessages for specified entity.
+     * Check if giftmessages is allowed for specified entity.
      *
      * @param string $type
      * @param \Magento\Framework\Object $entity
@@ -137,12 +137,16 @@ class Message extends \Magento\Framework\App\Helper\AbstractHelper
      * @return bool|string|null
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      */
-    public function isMessagesAvailable($type, \Magento\Framework\Object $entity, $store = null)
+    public function isMessagesAllowed($type, \Magento\Framework\Object $entity, $store = null)
     {
         if ($type == 'items') {
             $items = $entity->getAllItems();
             if (!is_array($items) || empty($items)) {
-                return $this->scopeConfig->getValue(self::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ITEMS, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store);
+                return $this->scopeConfig->getValue(
+                    self::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ITEMS,
+                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+                    $store
+                );
             }
             if ($entity instanceof \Magento\Quote\Model\Quote) {
                 $_type = $entity->getIsMultiShipping() ? 'address_item' : 'item';
@@ -153,7 +157,7 @@ class Message extends \Magento\Framework\App\Helper\AbstractHelper
                 if ($item->getParentItem()) {
                     continue;
                 }
-                if ($this->isMessagesAvailable($_type, $item, $store)) {
+                if ($this->isMessagesAllowed($_type, $item, $store)) {
                     return true;
                 }
             }
@@ -177,7 +181,11 @@ class Message extends \Magento\Framework\App\Helper\AbstractHelper
                 $store
             );
         } else {
-            return $this->scopeConfig->getValue(self::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ORDER, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store);
+            return $this->scopeConfig->getValue(
+                self::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ORDER,
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+                $store
+            );
         }
         return false;
     }
@@ -191,7 +199,10 @@ class Message extends \Magento\Framework\App\Helper\AbstractHelper
      */
     protected function _getDependenceFromStoreConfig($productGiftMessageAllow, $store = null)
     {
-        $result = $this->scopeConfig->getValue(self::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ITEMS, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store);
+        $result = $this->scopeConfig->getValue(
+            self::XPATH_CONFIG_GIFT_MESSAGE_ALLOW_ITEMS,
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store
+        );
         if ($productGiftMessageAllow === '' || is_null($productGiftMessageAllow)) {
             return $result;
         } else {
@@ -199,19 +210,6 @@ class Message extends \Magento\Framework\App\Helper\AbstractHelper
         }
     }
 
-    /**
-     * Alias for isMessagesAvailable(...)
-     *
-     * @param string $type
-     * @param \Magento\Framework\Object $entity
-     * @param \Magento\Store\Model\Store|int|null $store
-     * @return bool|null|string
-     */
-    public function getIsMessagesAvailable($type, \Magento\Framework\Object $entity, $store = null)
-    {
-        return $this->isMessagesAvailable($type, $entity, $store);
-    }
-
     /**
      * Retrieve escaped and preformated gift message text for specified entity
      *
@@ -293,7 +291,7 @@ class Message extends \Magento\Framework\App\Helper\AbstractHelper
     public function getAvailableForQuoteItems($quote, $store = null)
     {
         foreach ($quote->getAllItems() as $item) {
-            if ($this->isMessagesAvailable('item', $item, $store)) {
+            if ($this->isMessagesAllowed('item', $item, $store)) {
                 return true;
             }
         }
@@ -311,7 +309,7 @@ class Message extends \Magento\Framework\App\Helper\AbstractHelper
     public function getAvailableForAddressItems($items, $store = null)
     {
         foreach ($items as $item) {
-            if ($this->isMessagesAvailable('address_item', $item, $store)) {
+            if ($this->isMessagesAllowed('address_item', $item, $store)) {
                 return true;
             }
         }
diff --git a/app/code/Magento/GiftMessage/Model/CartRepository.php b/app/code/Magento/GiftMessage/Model/CartRepository.php
index bb1b66db7d20d0f5b42e2321eaf354030e4661f9..4fe6b988236c6258fc0d7f7068a72f803468debb 100644
--- a/app/code/Magento/GiftMessage/Model/CartRepository.php
+++ b/app/code/Magento/GiftMessage/Model/CartRepository.php
@@ -107,7 +107,7 @@ class CartRepository implements \Magento\GiftMessage\Api\CartRepositoryInterface
         if ($quote->isVirtual()) {
             throw new InvalidTransitionException(__('Gift Messages is not applicable for virtual products'));
         }
-        if (!$this->helper->getIsMessagesAvailable('quote', $quote, $this->storeManager->getStore())) {
+        if (!$this->helper->isMessagesAllowed('quote', $quote, $this->storeManager->getStore())) {
             throw new CouldNotSaveException(__('Gift Message is not available'));
         }
         $this->giftMessageManager->setMessage($quote, 'quote', $giftMessage);
diff --git a/app/code/Magento/GiftMessage/Model/ItemRepository.php b/app/code/Magento/GiftMessage/Model/ItemRepository.php
index 16d442a769240fef8fb93ced6c29ea8fc479d022..d7220d2516f7a2b934d9365a83c481f13249b1c2 100644
--- a/app/code/Magento/GiftMessage/Model/ItemRepository.php
+++ b/app/code/Magento/GiftMessage/Model/ItemRepository.php
@@ -121,7 +121,7 @@ class ItemRepository implements \Magento\GiftMessage\Api\ItemRepositoryInterface
         if ($item->getIsVirtual()) {
             throw new InvalidTransitionException(__('Gift Messages is not applicable for virtual products'));
         }
-        if (!$this->helper->getIsMessagesAvailable('items', $quote, $this->storeManager->getStore())) {
+        if (!$this->helper->isMessagesAllowed('items', $quote, $this->storeManager->getStore())) {
             throw new CouldNotSaveException(__('Gift Message is not available'));
         }
         $this->giftMessageManager->setMessage($quote, 'quote_item', $giftMessage, $itemId);
diff --git a/app/code/Magento/GiftMessage/Model/Observer.php b/app/code/Magento/GiftMessage/Model/Observer.php
index 696b4f38f5f6ae96d869838106d96d524bafeb81..342bc8cb133106011900935328a3d356036a47c4 100644
--- a/app/code/Magento/GiftMessage/Model/Observer.php
+++ b/app/code/Magento/GiftMessage/Model/Observer.php
@@ -74,7 +74,7 @@ class Observer extends \Magento\Framework\Object
             return $this;
         }
 
-        if (!$this->_giftMessageMessage->isMessagesAvailable('order', $order, $order->getStore())) {
+        if (!$this->_giftMessageMessage->isMessagesAllowed('order', $order, $order->getStore())) {
             return $this;
         }
         $giftMessageId = $order->getGiftMessageId();
@@ -102,7 +102,7 @@ class Observer extends \Magento\Framework\Object
             return $this;
         }
 
-        $isAvailable = $this->_giftMessageMessage->isMessagesAvailable(
+        $isAvailable = $this->_giftMessageMessage->isMessagesAllowed(
             'order_item',
             $orderItem,
             $orderItem->getStoreId()
diff --git a/app/code/Magento/GiftMessage/Model/OrderItemRepository.php b/app/code/Magento/GiftMessage/Model/OrderItemRepository.php
new file mode 100644
index 0000000000000000000000000000000000000000..4c71f599f0b1fe88dba1c1a4948c1b7db8db07a4
--- /dev/null
+++ b/app/code/Magento/GiftMessage/Model/OrderItemRepository.php
@@ -0,0 +1,155 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\GiftMessage\Model;
+
+use Magento\Framework\Exception\CouldNotSaveException;
+use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Framework\Exception\State\InvalidTransitionException;
+
+/**
+ * Order item gift message repository object.
+ */
+class OrderItemRepository implements \Magento\GiftMessage\Api\OrderItemRepositoryInterface
+{
+    /**
+     * Order factory.
+     *
+     * @var \Magento\Sales\Model\OrderFactory
+     */
+    protected $orderFactory;
+
+    /**
+     * Store manager interface.
+     *
+     * @var \Magento\Store\Model\StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * Gift message save model.
+     *
+     * @var \Magento\GiftMessage\Model\Save
+     */
+    protected $giftMessageSaveModel;
+
+    /**
+     * Message helper.
+     *
+     * @var \Magento\GiftMessage\Helper\Message
+     */
+    protected $helper;
+
+    /**
+     * Message factory.
+     *
+     * @var \Magento\GiftMessage\Model\MessageFactory
+     */
+    protected $messageFactory;
+
+    /**
+     * @param \Magento\Sales\Model\OrderFactory $orderFactory
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     * @param \Magento\GiftMessage\Model\Save $giftMessageSaveModel
+     * @param \Magento\GiftMessage\Helper\Message $helper
+     * @param MessageFactory $messageFactory
+     */
+    public function __construct(
+        \Magento\Sales\Model\OrderFactory $orderFactory,
+        \Magento\Store\Model\StoreManagerInterface $storeManager,
+        \Magento\GiftMessage\Model\Save $giftMessageSaveModel,
+        \Magento\GiftMessage\Helper\Message $helper,
+        \Magento\GiftMessage\Model\MessageFactory $messageFactory
+    ) {
+        $this->orderFactory = $orderFactory;
+        $this->giftMessageSaveModel = $giftMessageSaveModel;
+        $this->storeManager = $storeManager;
+        $this->helper = $helper;
+        $this->messageFactory = $messageFactory;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function get($orderId, $orderItemId)
+    {
+        /** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+        if (!$orderItem = $this->getItemById($orderId, $orderItemId)) {
+            throw new NoSuchEntityException(__('There is no item with provided id in the order'));
+        };
+
+        if (!$this->helper->isMessagesAllowed('order_item', $orderItem, $this->storeManager->getStore())) {
+            throw new NoSuchEntityException(
+                __('There is no item with provided id in the order or gift message isn\'t allowed')
+            );
+        }
+
+        $messageId = $orderItem->getGiftMessageId();
+        if (!$messageId) {
+            throw new NoSuchEntityException(__('There is no item with provided id in the order'));
+        }
+
+        return $this->messageFactory->create()->load($messageId);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function save($orderId, $orderItemId, \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage)
+    {
+        /** @var \Magento\Sales\Api\Data\OrderInterface $order */
+        $order = $this->orderFactory->create()->load($orderId);
+
+        /** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+        if (!$orderItem = $this->getItemById($orderId, $orderItemId)) {
+            throw new NoSuchEntityException(__('There is no item with provided id in the order'));
+        };
+
+        if ($order->getIsVirtual()) {
+            throw new InvalidTransitionException(__('Gift Messages is not applicable for virtual products'));
+        }
+        if (!$this->helper->isMessagesAllowed('order_item', $orderItem, $this->storeManager->getStore())) {
+            throw new CouldNotSaveException(__('Gift Message is not available'));
+        }
+
+        $message = [];
+        $message[$orderItemId] = [
+            'type' => 'order_item',
+            'sender' => $giftMessage->getSender(),
+            'recipient' => $giftMessage->getRecipient(),
+            'message' => $giftMessage->getMessage(),
+        ];
+
+        $this->giftMessageSaveModel->setGiftmessages($message);
+        try {
+            $this->giftMessageSaveModel->saveAllInOrder();
+        } catch (\Exception $e) {
+            throw new CouldNotSaveException(__('Could not add gift message to order: "%1"', $e->getMessage()), $e);
+        }
+        return true;
+    }
+
+    /**
+     * Get order item by id
+     *
+     * @param int $orderId
+     * @param int $orderItemId
+     * @return \Magento\Sales\Api\Data\OrderItemInterface|bool
+     */
+    protected function getItemById($orderId, $orderItemId)
+    {
+        /** @var \Magento\Sales\Api\Data\OrderInterface $order */
+        $order = $this->orderFactory->create()->load($orderId);
+        /** @var \Magento\Sales\Api\Data\OrderItemInterface $item */
+        foreach ($order->getItems() as $item) {
+            if ($item->getItemId() === $orderItemId) {
+                return $item;
+            }
+        }
+        return false;
+    }
+}
diff --git a/app/code/Magento/GiftMessage/Model/OrderRepository.php b/app/code/Magento/GiftMessage/Model/OrderRepository.php
new file mode 100644
index 0000000000000000000000000000000000000000..5bbff94c44bf9cb0d26b84683964dfc051ed1a17
--- /dev/null
+++ b/app/code/Magento/GiftMessage/Model/OrderRepository.php
@@ -0,0 +1,137 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\GiftMessage\Model;
+
+use Magento\Framework\Exception\CouldNotSaveException;
+use Magento\Framework\Exception\InputException;
+use Magento\Framework\Exception\State\InvalidTransitionException;
+use Magento\Framework\Exception\NoSuchEntityException;
+
+/**
+ * Order gift message repository object.
+ */
+class OrderRepository implements \Magento\GiftMessage\Api\OrderRepositoryInterface
+{
+    /**
+     * Order factory.
+     *
+     * @var \Magento\Sales\Model\OrderFactory
+     */
+    protected $orderFactory;
+
+    /**
+     * Store manager interface.
+     *
+     * @var \Magento\Store\Model\StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * Gift message save model.
+     *
+     * @var \Magento\GiftMessage\Model\Save
+     */
+    protected $giftMessageSaveModel;
+
+    /**
+     * Message helper.
+     *
+     * @var \Magento\GiftMessage\Helper\Message
+     */
+    protected $helper;
+
+    /**
+     * Message factory.
+     *
+     * @var \Magento\GiftMessage\Model\MessageFactory
+     */
+    protected $messageFactory;
+
+    /**
+     * @param \Magento\Sales\Model\OrderFactory $orderFactory
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     * @param \Magento\GiftMessage\Model\Save $giftMessageSaveModel
+     * @param \Magento\GiftMessage\Helper\Message $helper
+     * @param MessageFactory $messageFactory
+     */
+    public function __construct(
+        \Magento\Sales\Model\OrderFactory $orderFactory,
+        \Magento\Store\Model\StoreManagerInterface $storeManager,
+        \Magento\GiftMessage\Model\Save $giftMessageSaveModel,
+        \Magento\GiftMessage\Helper\Message $helper,
+        \Magento\GiftMessage\Model\MessageFactory $messageFactory
+    ) {
+        $this->orderFactory = $orderFactory;
+        $this->giftMessageSaveModel = $giftMessageSaveModel;
+        $this->storeManager = $storeManager;
+        $this->helper = $helper;
+        $this->messageFactory = $messageFactory;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function get($orderId)
+    {
+        /** @var \Magento\Sales\Api\Data\OrderInterface $order */
+        $order = $this->orderFactory->create()->load($orderId);
+
+        if (!$this->helper->isMessagesAllowed('order', $order, $this->storeManager->getStore())) {
+            throw new NoSuchEntityException(
+                __('There is no order with provided id or gift message isn\'t allowed')
+            );
+        }
+
+        $messageId = $order->getGiftMessageId();
+        if (!$messageId) {
+            throw new NoSuchEntityException(__('There is no item with provided id in the order'));
+        }
+
+        return $this->messageFactory->create()->load($messageId);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function save($orderId, \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage)
+    {
+        /** @var \Magento\Sales\Api\Data\OrderInterface $order */
+        $order = $this->orderFactory->create()->load($orderId);
+        if (!$order->getEntityId()) {
+            throw new NoSuchEntityException(__('There is no order with provided id'));
+        };
+
+        if (0 == $order->getTotalItemCount()) {
+            throw new InputException(__('Gift Messages is not applicable for empty order'));
+        }
+
+        if ($order->getIsVirtual()) {
+            throw new InvalidTransitionException(__('Gift Messages is not applicable for virtual products'));
+        }
+        if (!$this->helper->isMessagesAllowed('order', $order, $this->storeManager->getStore())) {
+            throw new CouldNotSaveException(__('Gift Message is not available'));
+        }
+
+        $message = [];
+        $message[$orderId] = [
+            'type' => 'order',
+            $giftMessage::CUSTOMER_ID => $giftMessage->getCustomerId(),
+            $giftMessage::SENDER => $giftMessage->getSender(),
+            $giftMessage::RECIPIENT => $giftMessage->getRecipient(),
+            $giftMessage::MESSAGE => $giftMessage->getMessage(),
+        ];
+
+        $this->giftMessageSaveModel->setGiftmessages($message);
+        try {
+            $this->giftMessageSaveModel->saveAllInOrder();
+        } catch (\Exception $e) {
+            throw new CouldNotSaveException(__('Could not add gift message to order: "%1"', $e->getMessage()), $e);
+        }
+        return true;
+    }
+}
diff --git a/app/code/Magento/GiftMessage/Model/Plugin/OrderGet.php b/app/code/Magento/GiftMessage/Model/Plugin/OrderGet.php
new file mode 100644
index 0000000000000000000000000000000000000000..c63a726d8e8449e3ebe709aac5828803a12961de
--- /dev/null
+++ b/app/code/Magento/GiftMessage/Model/Plugin/OrderGet.php
@@ -0,0 +1,129 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\GiftMessage\Model\Plugin;
+
+use Magento\Framework\Exception\NoSuchEntityException;
+
+class OrderGet
+{
+    /** @var \Magento\GiftMessage\Api\OrderRepositoryInterface */
+    protected $giftMessageOrderRepository;
+
+    /** @var \Magento\GiftMessage\Api\OrderItemRepositoryInterface */
+    protected $giftMessageOrderItemRepository;
+
+    /** @var \Magento\Sales\Api\Data\OrderExtensionFactory */
+    protected $orderExtensionFactory;
+
+    /** @var \Magento\Sales\Api\Data\OrderItemExtensionFactory */
+    protected $orderItemExtensionFactory;
+
+    /**
+     * Init plugin
+     *
+     * @param \Magento\GiftMessage\Api\OrderRepositoryInterface $giftMessageOrderRepository
+     * @param \Magento\GiftMessage\Api\OrderItemRepositoryInterface $giftMessageOrderItemRepository
+     * @param \Magento\Sales\Api\Data\OrderExtensionFactory $orderExtensionFactory
+     * @param \Magento\Sales\Api\Data\OrderItemExtensionFactory $orderItemExtensionFactory
+     */
+    public function __construct(
+        \Magento\GiftMessage\Api\OrderRepositoryInterface $giftMessageOrderRepository,
+        \Magento\GiftMessage\Api\OrderItemRepositoryInterface $giftMessageOrderItemRepository,
+        \Magento\Sales\Api\Data\OrderExtensionFactory $orderExtensionFactory,
+        \Magento\Sales\Api\Data\OrderItemExtensionFactory $orderItemExtensionFactory
+    ) {
+        $this->giftMessageOrderRepository = $giftMessageOrderRepository;
+        $this->giftMessageOrderItemRepository = $giftMessageOrderItemRepository;
+        $this->orderExtensionFactory = $orderExtensionFactory;
+        $this->orderItemExtensionFactory = $orderItemExtensionFactory;
+    }
+
+    /**
+     * Get gift message
+     *
+     * @param \Magento\Sales\Api\OrderRepositoryInterface $subject
+     * @param callable $proceed
+     * @param int $orderId
+     * @return \Magento\Sales\Api\Data\OrderInterface
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function aroundGet(
+        \Magento\Sales\Api\OrderRepositoryInterface $subject,
+        \Closure $proceed,
+        $orderId
+    ) {
+        /** @var \Magento\Sales\Api\Data\OrderInterface $resultOrder */
+        $resultOrder = $proceed($orderId);
+
+        $resultOrder = $this->getOrderGiftMessage($resultOrder);
+        $resultOrder = $this->getOrderItemGiftMessage($resultOrder);
+
+        return $resultOrder;
+    }
+
+    /**
+     * Get gift message for order
+     *
+     * @param \Magento\Sales\Api\Data\OrderInterface $order
+     * @return \Magento\Sales\Api\Data\OrderInterface
+     */
+    protected function getOrderGiftMessage(\Magento\Sales\Api\Data\OrderInterface $order)
+    {
+        if ($order->getExtensionAttributes() && $order->getExtensionAttributes()->getGiftMessage()) {
+            return $order;
+        }
+
+        try {
+            /** @var \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage */
+            $giftMessage = $this->giftMessageOrderRepository->get($order->getEntityId());
+        } catch (NoSuchEntityException $e) {
+            return $order;
+        }
+
+        /** @var \Magento\Sales\Api\Data\OrderExtension $orderExtension */
+        $orderExtension = $this->orderExtensionFactory->create();
+        $orderExtension->setGiftMessage($giftMessage);
+        $order->setExtensionAttributes($orderExtension);
+
+        return $order;
+    }
+
+    /**
+     * Get gift message for items of order
+     *
+     * @param \Magento\Sales\Api\Data\OrderInterface $order
+     * @return \Magento\Sales\Api\Data\OrderInterface
+     */
+    protected function getOrderItemGiftMessage(\Magento\Sales\Api\Data\OrderInterface $order)
+    {
+        if (null !== $order->getItems()) {
+            /** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+            foreach ($order->getItems() as $orderItem) {
+                if ($orderItem->getExtensionAttributes() && $orderItem->getExtensionAttributes()->getGiftMessage()) {
+                    continue;
+                }
+
+                try {
+                    /* @var \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage */
+                    $giftMessage = $this->giftMessageOrderItemRepository->get(
+                        $order->getEntityId(),
+                        $orderItem->getItemId()
+                    );
+                } catch (NoSuchEntityException $e) {
+                    continue;
+                }
+
+                /** @var \Magento\Sales\Api\Data\OrderItemExtension $orderItemExtension */
+                $orderItemExtension = $this->orderItemExtensionFactory->create();
+                $orderItemExtension->setGiftMessage($giftMessage);
+                $orderItem->setExtensionAttributes($orderItemExtension);
+            }
+        }
+        return $order;
+    }
+}
diff --git a/app/code/Magento/GiftMessage/Model/Plugin/OrderSave.php b/app/code/Magento/GiftMessage/Model/Plugin/OrderSave.php
new file mode 100644
index 0000000000000000000000000000000000000000..8acac4ecd67e230d8e0dc7c75ff7e0daee0301d9
--- /dev/null
+++ b/app/code/Magento/GiftMessage/Model/Plugin/OrderSave.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\GiftMessage\Model\Plugin;
+
+use Magento\Framework\Exception\CouldNotSaveException;
+
+class OrderSave
+{
+    /** @var \Magento\GiftMessage\Api\OrderRepositoryInterface */
+    protected $giftMessageOrderRepository;
+
+    /** @var \Magento\GiftMessage\Api\OrderItemRepositoryInterface */
+    protected $giftMessageOrderItemRepository;
+
+    /**
+     * Init plugin
+     *
+     * @param \Magento\GiftMessage\Api\OrderRepositoryInterface $giftMessageOrderRepository
+     * @param \Magento\GiftMessage\Api\OrderItemRepositoryInterface $giftMessageOrderItemRepository
+     */
+    public function __construct(
+        \Magento\GiftMessage\Api\OrderRepositoryInterface $giftMessageOrderRepository,
+        \Magento\GiftMessage\Api\OrderItemRepositoryInterface $giftMessageOrderItemRepository
+    ) {
+        $this->giftMessageOrderRepository = $giftMessageOrderRepository;
+        $this->giftMessageOrderItemRepository = $giftMessageOrderItemRepository;
+    }
+
+    /**
+     * Save gift message
+     *
+     * @param \Magento\Sales\Api\OrderRepositoryInterface $subject
+     * @param callable $proceed
+     * @param \Magento\Sales\Api\Data\OrderInterface $order
+     * @return \Magento\Sales\Api\Data\OrderInterface
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function aroundSave(
+        \Magento\Sales\Api\OrderRepositoryInterface $subject,
+        \Closure $proceed,
+        \Magento\Sales\Api\Data\OrderInterface $order
+    ) {
+        /** @var \Magento\Sales\Api\Data\OrderInterface $resultOrder */
+        $resultOrder = $proceed($order);
+        $resultOrder = $this->saveOrderGiftMessage($resultOrder);
+        $resultOrder = $this->saveOrderItemGiftMessage($resultOrder);
+
+        return $resultOrder;
+    }
+
+    /**
+     * Save gift message for order
+     *
+     * @param \Magento\Sales\Api\Data\OrderInterface $order
+     * @return \Magento\Sales\Api\Data\OrderInterface
+     */
+    protected function saveOrderGiftMessage(\Magento\Sales\Api\Data\OrderInterface $order)
+    {
+        if (
+            null !== $order->getExtensionAttributes() &&
+            null !== $order->getExtensionAttributes()->getGiftMessage()
+        ) {
+            /* @var \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage */
+            $giftMessage = $order->getExtensionAttributes()->getGiftMessage();
+            if (null !== $giftMessage) {
+                try {
+                    $this->giftMessageOrderRepository->save($order->getEntityId(), $giftMessage);
+                } catch (\Exception $e) {
+                    throw new CouldNotSaveException(
+                        __('Could not add gift message to order: "%1"', $e->getMessage()),
+                        $e
+                    );
+                }
+            }
+        }
+        return $order;
+    }
+
+    /**
+     * Save gift message for items of order
+     *
+     * @param \Magento\Sales\Api\Data\OrderInterface $order
+     * @return \Magento\Sales\Api\Data\OrderInterface
+     */
+    protected function saveOrderItemGiftMessage(\Magento\Sales\Api\Data\OrderInterface $order)
+    {
+        if (null !== $order->getItems()) {
+            /** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+            foreach ($order->getItems() as $orderItem) {
+                if (
+                    null !== $orderItem->getExtensionAttributes() &&
+                    null !== $orderItem->getExtensionAttributes()->getGiftMessage()
+                ) {
+                    /* @var \Magento\GiftMessage\Api\Data\MessageInterface $giftMessage */
+                    $giftMessage = $orderItem->getExtensionAttributes()->getGiftMessage();
+                    try {
+                        $this->giftMessageOrderItemRepository->save(
+                            $order->getEntityId(),
+                            $orderItem->getItemId(),
+                            $giftMessage
+                        );
+                    } catch (\Exception $e) {
+                        throw new CouldNotSaveException(
+                            __('Could not add gift message to order\'s item: "%1"', $e->getMessage()),
+                            $e
+                        );
+                    }
+                }
+            }
+        }
+        return $order;
+    }
+}
diff --git a/app/code/Magento/GiftMessage/Model/Plugin/QuoteItem.php b/app/code/Magento/GiftMessage/Model/Plugin/QuoteItem.php
index f2538b84b6a2353b25108cb1ad2162ad0784519e..9889f7261d2310678930b16aced1e23bec09d08b 100644
--- a/app/code/Magento/GiftMessage/Model/Plugin/QuoteItem.php
+++ b/app/code/Magento/GiftMessage/Model/Plugin/QuoteItem.php
@@ -39,7 +39,7 @@ class QuoteItem
     ) {
         /** @var $orderItem Item */
         $orderItem = $proceed($item, $additional);
-        $isAvailable = $this->_helper->isMessagesAvailable('item', $item, $item->getStoreId());
+        $isAvailable = $this->_helper->isMessagesAllowed('item', $item, $item->getStoreId());
 
         $orderItem->setGiftMessageId($item->getGiftMessageId());
         $orderItem->setGiftMessageAvailable($isAvailable);
diff --git a/app/code/Magento/GiftMessage/Model/Save.php b/app/code/Magento/GiftMessage/Model/Save.php
index 131624415b58208aa61e1fce40f4e8e69cba396f..7841e2f37867c7395203ef3ec4d90f273a79e6b2 100644
--- a/app/code/Magento/GiftMessage/Model/Save.php
+++ b/app/code/Magento/GiftMessage/Model/Save.php
@@ -265,7 +265,7 @@ class Save extends \Magento\Framework\Object
      */
     public function isGiftMessagesAvailable($item)
     {
-        return $this->_giftMessageMessage->getIsMessagesAvailable('item', $item, $item->getStore());
+        return $this->_giftMessageMessage->isMessagesAllowed('item', $item, $item->getStore());
     }
 
     /**
diff --git a/app/code/Magento/GiftMessage/Test/Unit/Helper/MessageTest.php b/app/code/Magento/GiftMessage/Test/Unit/Helper/MessageTest.php
index 3821d4f05b760a9dc1d6542e08fbcdd10c4a9451..9b1748b1052c1a4cfbdcfb8dad31d19e62a3b78a 100644
--- a/app/code/Magento/GiftMessage/Test/Unit/Helper/MessageTest.php
+++ b/app/code/Magento/GiftMessage/Test/Unit/Helper/MessageTest.php
@@ -29,7 +29,7 @@ class MessageTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * Make sure that isMessagesAvailable is not called
+     * Make sure that isMessagesAllowed is not called
      */
     public function testGetInlineForCheckout()
     {
diff --git a/app/code/Magento/GiftMessage/Test/Unit/Model/CartRepositoryTest.php b/app/code/Magento/GiftMessage/Test/Unit/Model/CartRepositoryTest.php
index c510e993f35c3355f96eda09fa189a6fb5e56924..6974c1f131cda2f511408dde59205c496619a7a1 100644
--- a/app/code/Magento/GiftMessage/Test/Unit/Model/CartRepositoryTest.php
+++ b/app/code/Magento/GiftMessage/Test/Unit/Model/CartRepositoryTest.php
@@ -163,7 +163,6 @@ class CartRepositoryTest extends \PHPUnit_Framework_TestCase
     {
         $this->quoteMock->expects($this->once())->method('getItemsCount')->will($this->returnValue(1));
         $this->quoteMock->expects($this->once())->method('isVirtual')->will($this->returnValue(true));
-
         $this->cartRepository->save($this->cartId, $this->messageMock);
     }
 
@@ -173,7 +172,7 @@ class CartRepositoryTest extends \PHPUnit_Framework_TestCase
         $this->quoteMock->expects($this->once())->method('getItemsCount')->will($this->returnValue(1));
         $this->storeManagerMock->expects($this->once())->method('getStore')->will($this->returnValue($this->storeMock));
         $this->helperMock->expects($this->once())
-            ->method('getIsMessagesAvailable')
+            ->method('isMessagesAllowed')
             ->with('quote', $this->quoteMock, $this->storeMock)
             ->will($this->returnValue(true));
         $this->giftMessageManagerMock->expects($this->once())
diff --git a/app/code/Magento/GiftMessage/Test/Unit/Model/ItemRepositoryTest.php b/app/code/Magento/GiftMessage/Test/Unit/Model/ItemRepositoryTest.php
index a97f5f9bd380007f3a0e238a3d940cf1c30ba2d5..5caa71f1b2bd2a492dc92b99c63c92970169d1bf 100644
--- a/app/code/Magento/GiftMessage/Test/Unit/Model/ItemRepositoryTest.php
+++ b/app/code/Magento/GiftMessage/Test/Unit/Model/ItemRepositoryTest.php
@@ -211,7 +211,7 @@ class ItemRepositoryTest extends \PHPUnit_Framework_TestCase
         $quoteItem->expects($this->once())->method('getIsVirtual')->will($this->returnValue(0));
         $this->storeManagerMock->expects($this->once())->method('getStore')->will($this->returnValue($this->storeMock));
         $this->helperMock->expects($this->once())
-            ->method('getIsMessagesAvailable')
+            ->method('isMessagesAllowed')
             ->with('items', $this->quoteMock, $this->storeMock)
             ->will($this->returnValue(true));
         $this->giftMessageManagerMock->expects($this->once())
diff --git a/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/QuoteItemTest.php b/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/QuoteItemTest.php
index 61afb0c179fc69e84d8b16316dbd57ff5982a23d..b748345a177d1cf92bf81258c5b0c5bebdb1f329 100644
--- a/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/QuoteItemTest.php
+++ b/app/code/Magento/GiftMessage/Test/Unit/Model/Plugin/QuoteItemTest.php
@@ -60,7 +60,7 @@ class QuoteItemTest extends \PHPUnit_Framework_TestCase
         $this->subjectMock = $this->getMock('Magento\Quote\Model\Quote\Item\ToOrderItem', [], [], '', false);
         $this->helperMock = $this->getMock(
             'Magento\GiftMessage\Helper\Message',
-            ['setGiftMessageId', 'isMessagesAvailable'],
+            ['setGiftMessageId', 'isMessagesAllowed'],
             [],
             '',
             false
@@ -86,7 +86,7 @@ class QuoteItemTest extends \PHPUnit_Framework_TestCase
         $this->helperMock->expects(
             $this->once()
         )->method(
-            'isMessagesAvailable'
+            'isMessagesAllowed'
         )->with(
             'item',
             $this->quoteItemMock,
diff --git a/app/code/Magento/GiftMessage/etc/adminhtml/di.xml b/app/code/Magento/GiftMessage/etc/adminhtml/di.xml
deleted file mode 100644
index 961c8c6ff61369d74a53d6a9a943c067933e6345..0000000000000000000000000000000000000000
--- a/app/code/Magento/GiftMessage/etc/adminhtml/di.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0"?>
-<!--
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
--->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
-    <type name="Magento\GiftMessage\Model\Plugin\QuoteItem" shared="false" />
-    <type name="Magento\Quote\Model\Quote\Item\ToOrderItem">
-        <plugin name="gift_message_quote_item_conversion" type="Magento\GiftMessage\Model\Plugin\QuoteItem"/>
-    </type>
-</config>
diff --git a/app/code/Magento/GiftMessage/etc/data_object.xml b/app/code/Magento/GiftMessage/etc/data_object.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a1255cc8a161a5a8d28090697088a87ede8920e7
--- /dev/null
+++ b/app/code/Magento/GiftMessage/etc/data_object.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<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\Sales\Api\Data\OrderInterface">
+        <attribute code="gift_message" type="Magento\GiftMessage\Api\Data\MessageInterface" />
+    </custom_attributes>
+    <custom_attributes for="Magento\Sales\Api\Data\OrderItemInterface">
+        <attribute code="gift_message" type="Magento\GiftMessage\Api\Data\MessageInterface" />
+    </custom_attributes>
+</config>
diff --git a/app/code/Magento/GiftMessage/etc/di.xml b/app/code/Magento/GiftMessage/etc/di.xml
index 2c674334652effc113de85057424dc8be4f74d73..d8ea087e62d735c09063af6d8f3cf518179df33f 100644
--- a/app/code/Magento/GiftMessage/etc/di.xml
+++ b/app/code/Magento/GiftMessage/etc/di.xml
@@ -15,5 +15,15 @@
     </type>
     <preference for="Magento\GiftMessage\Api\CartRepositoryInterface" type="Magento\GiftMessage\Model\CartRepository"/>
     <preference for="Magento\GiftMessage\Api\ItemRepositoryInterface" type="Magento\GiftMessage\Model\ItemRepository"/>
+    <preference for="Magento\GiftMessage\Api\OrderRepositoryInterface" type="Magento\GiftMessage\Model\OrderRepository"/>
+    <preference for="Magento\GiftMessage\Api\OrderItemRepositoryInterface" type="Magento\GiftMessage\Model\OrderItemRepository"/>
     <preference for="Magento\GiftMessage\Api\Data\MessageInterface" type="Magento\GiftMessage\Model\Message"/>
+    <type name="Magento\GiftMessage\Model\Plugin\QuoteItem" shared="false" />
+    <type name="Magento\Quote\Model\Quote\Item\ToOrderItem">
+        <plugin name="gift_message_quote_item_conversion" type="Magento\GiftMessage\Model\Plugin\QuoteItem"/>
+    </type>
+    <type name="Magento\Sales\Api\OrderRepositoryInterface">
+        <plugin name="save_gift_message" type="Magento\GiftMessage\Model\Plugin\OrderSave"/>
+        <plugin name="get_gift_message" type="Magento\GiftMessage\Model\Plugin\OrderGet"/>
+    </type>
 </config>
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Giftmessage.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Giftmessage.php
index f5f53b3f736c8c754b79c56ac89a81ce005010bf..52cc36384d6367e90a2ffb300629f43b8fd993ca 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Giftmessage.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Giftmessage.php
@@ -84,7 +84,7 @@ class Giftmessage extends \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCr
         foreach ($allItems as $item) {
             if ($this->_getGiftmessageSaveModel()->getIsAllowedQuoteItem(
                 $item
-            ) && $this->_messageHelper->getIsMessagesAvailable(
+            ) && $this->_messageHelper->isMessagesAllowed(
                 'item',
                 $item,
                 $this->getStore()
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Items/Grid.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Items/Grid.php
index 86fcf0a4ee35338465e2da808978bb9d46128852..fe33696ba778625a5c27be6b4bf8b43f7fcfd75e 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Items/Grid.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Items/Grid.php
@@ -232,9 +232,9 @@ class Grid extends \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate
     public function isGiftMessagesAvailable($item = null)
     {
         if ($item === null) {
-            return $this->_messageHelper->getIsMessagesAvailable('items', $this->getQuote(), $this->getStore());
+            return $this->_messageHelper->isMessagesAllowed('items', $this->getQuote(), $this->getStore());
         }
-        return $this->_messageHelper->getIsMessagesAvailable('item', $item, $this->getStore());
+        return $this->_messageHelper->isMessagesAllowed('item', $item, $this->getStore());
     }
 
     /**
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Giftmessage.php b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Giftmessage.php
index 546a3e5682549e3431f7b0dbcac1df1631c32990..2f70036c540aa9eb25c9cabe74b542e91451aa81 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Giftmessage.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Giftmessage.php
@@ -290,7 +290,7 @@ class Giftmessage extends \Magento\Backend\Block\Widget
      */
     public function canDisplayGiftmessage()
     {
-        return $this->_messageHelper->getIsMessagesAvailable(
+        return $this->_messageHelper->isMessagesAllowed(
             'order',
             $this->getEntity(),
             $this->getEntity()->getStoreId()
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Items/Renderer/DefaultRenderer.php b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Items/Renderer/DefaultRenderer.php
index 22ca91855bedc6b0d921ffb9afd26464a2ab990d..92cc81fa6f2a8c54deebcec06b1190d71a205308 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/View/Items/Renderer/DefaultRenderer.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/View/Items/Renderer/DefaultRenderer.php
@@ -220,7 +220,7 @@ class DefaultRenderer extends \Magento\Sales\Block\Adminhtml\Items\Renderer\Defa
      */
     public function canDisplayGiftmessage()
     {
-        return $this->_messageHelper->getIsMessagesAvailable(
+        return $this->_messageHelper->isMessagesAllowed(
             'order_item',
             $this->getItem(),
             $this->getItem()->getOrder()->getStoreId()
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/create/giftmessage.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/create/giftmessage.phtml
index 44b97e5d55ea6a7ffcd17a97a5e25ffd05cfc083..846caa0fd3951dd5d83be7d148a8ca942d1fd3ae 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/create/giftmessage.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/create/giftmessage.phtml
@@ -7,13 +7,13 @@
 // @codingStandardsIgnoreFile
 
 ?>
-<?php if ($this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('main', $block->getQuote(), $block->getStoreId())): ?>
+<?php if ($this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('main', $block->getQuote(), $block->getStoreId())): ?>
 <?php $_items = $block->getItems(); ?>
 <div id="order-giftmessage" class="giftmessage-order-create box-left">
     <fieldset>
         <legend><?php echo __('Gift Message for the Entire Order') ?></legend>
         <br />
-        <?php if ($this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('main', $block->getQuote(), $block->getStoreId())): ?>
+        <?php if ($this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('main', $block->getQuote(), $block->getStoreId())): ?>
             <div class="giftmessage-entire-order">
                 <p><?php echo __('If you don\'t want to leave a gift message for the entire order, leave this box blank.') ?></p>
                 <?php echo $block->getFormHtml($block->getQuote(), 'main') ?>
diff --git a/app/code/Magento/Sales/view/frontend/templates/email/items.phtml b/app/code/Magento/Sales/view/frontend/templates/email/items.phtml
index 2f57c23485c3d0ab4b97dd809315683c921f51cb..b8a15bcbb3707819001b5ab6016a5ba635b3dbe7 100644
--- a/app/code/Magento/Sales/view/frontend/templates/email/items.phtml
+++ b/app/code/Magento/Sales/view/frontend/templates/email/items.phtml
@@ -34,7 +34,7 @@
         <?php echo $block->getChildHtml('order_totals') ?>
     </tbody>
 </table>
-<?php if ($this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAvailable('order', $_order, $_order->getStore()) && $_order->getGiftMessageId()): ?>
+<?php if ($this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order', $_order, $_order->getStore()) && $_order->getGiftMessageId()): ?>
     <?php $_giftMessage = $this->helper('Magento\GiftMessage\Helper\Message')->getGiftMessage($_order->getGiftMessageId()); ?>
     <?php if ($_giftMessage): ?>
 <br />
diff --git a/app/code/Magento/Sales/view/frontend/templates/order/items.phtml b/app/code/Magento/Sales/view/frontend/templates/order/items.phtml
index 166366a05d870573701a66f9951aa656bc4c4a8e..f5c27e01af6f791aa3c0cfb267142cc1441a8776 100644
--- a/app/code/Magento/Sales/view/frontend/templates/order/items.phtml
+++ b/app/code/Magento/Sales/view/frontend/templates/order/items.phtml
@@ -31,7 +31,7 @@
 } ?>
             <tbody>
                 <?php echo $block->getItemHtml($_item) ?>
-                <?php if ($this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order_item', $_item) && $_item->getGiftMessageId()): ?>
+                <?php if ($this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order_item', $_item) && $_item->getGiftMessageId()): ?>
                     <?php $_giftMessage = $this->helper('Magento\GiftMessage\Helper\Message')->getGiftMessageForEntity($_item); ?>
                     <tr>
                         <td class="col options" colspan="5">
diff --git a/app/code/Magento/Sales/view/frontend/templates/order/view.phtml b/app/code/Magento/Sales/view/frontend/templates/order/view.phtml
index 1106464712cfa2fbe9c9baf2cd684411c4682e76..64b84dacb490f9d1206af264e370052d3241c2c2 100644
--- a/app/code/Magento/Sales/view/frontend/templates/order/view.phtml
+++ b/app/code/Magento/Sales/view/frontend/templates/order/view.phtml
@@ -20,7 +20,7 @@
 
     <?php echo $block->getChildHtml('order_items') ?>
 
-    <?php if ($this->helper('Magento\GiftMessage\Helper\Message')->getIsMessagesAvailable('order', $_order) && $_order->getGiftMessageId()): ?>
+    <?php if ($this->helper('Magento\GiftMessage\Helper\Message')->isMessagesAllowed('order', $_order) && $_order->getGiftMessageId()): ?>
     <div class="block block-order-details-gift-message">
         <div class="block-title"><strong><?php echo __('Gift Message for This Order') ?></strong></div>
         <?php $_giftMessage = $this->helper('Magento\GiftMessage\Helper\Message')->getGiftMessageForEntity($_order); ?>
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Save.php b/app/code/Magento/User/Controller/Adminhtml/User/Save.php
index 204b188822dbf8935ba57ccdacd7d8438deaf8be..45a960f72e2d48d3accf7931163c206768cd4723 100644
--- a/app/code/Magento/User/Controller/Adminhtml/User/Save.php
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Save.php
@@ -83,7 +83,7 @@ class Save extends \Magento\User\Controller\Adminhtml\User
     {
         $this->_getSession()->setUserData($data);
         $arguments = $model->getId() ? ['user_id' => $model->getId()] : [];
-        $arguments = array_merge($arguments, ['_current' => true]);
+        $arguments = array_merge($arguments, ['_current' => true, 'active_tab' => '']);
         $this->_redirect('adminhtml/*/edit', $arguments);
     }
 }
diff --git a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php
index 7bb1fccd68818c9804f508c9c9f4a445527c9257..c57d73035b1a5f558741437393832e9d26f77348 100644
--- a/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Catalog/Api/ProductAttributeRepositoryTest.php
@@ -111,7 +111,7 @@ class ProductAttributeRepositoryTest extends \Magento\TestFramework\TestCase\Web
 
         $attributeData = [
             'attribute' => [
-                'attribute_code' => $attributeCode,
+                'attribute_id' => $attribute['attribute_id'],
                 'frontend_labels' => [
                     ['store_id' => 0, 'label' => 'front_lbl_new'],
                 ],
@@ -123,7 +123,7 @@ class ProductAttributeRepositoryTest extends \Magento\TestFramework\TestCase\Web
 
         $serviceInfo = [
             'rest' => [
-                'resourcePath' => self::RESOURCE_PATH . '/' . $attribute['attribute_id'],
+                'resourcePath' => self::RESOURCE_PATH . '/' . $attributeCode,
                 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_PUT,
             ],
             'soap' => [
@@ -134,7 +134,7 @@ class ProductAttributeRepositoryTest extends \Magento\TestFramework\TestCase\Web
         ];
 
         if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
-            $attributeData['attribute']['attributeId'] = $attribute['attribute_id'];
+            $attributeData['attribute']['attributeCode'] = $attributeCode;
         }
         $result = $this->_webApiCall($serviceInfo, $attributeData);
 
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Model/AuthTest.php b/dev/tests/integration/testsuite/Magento/Backend/Model/AuthTest.php
index 762fcf94aa70576a4cc04f3b6f16b1015885ba69..3f0e20d8a744b52b81313fb8e2a38c57af8d1a0c 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Model/AuthTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Model/AuthTest.php
@@ -30,11 +30,22 @@ class AuthTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
+     * @dataProvider getLoginDataProvider
+     * @param string $userName
+     * @param string $password
      * @expectedException \Magento\Framework\Exception\AuthenticationException
      */
-    public function testLoginFailed()
+    public function testLoginFailed($userName, $password)
     {
-        $this->_model->login('not_exists', 'not_exists');
+        $this->_model->login($userName, $password);
+    }
+
+    public function getLoginDataProvider()
+    {
+        return [
+            'Invalid credentials' => ['not_exists', 'not_exists'],
+            'Empty credentials' => ['', 'not_exists']
+        ];
     }
 
     public function testSetGetAuthStorage()
@@ -77,17 +88,13 @@ class AuthTest extends \PHPUnit_Framework_TestCase
      */
     public function testLogout()
     {
-        $this->markTestIncomplete('MAGETWO-17021');
         $this->_model->login(
             \Magento\TestFramework\Bootstrap::ADMIN_NAME,
             \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD
         );
         $this->assertNotEmpty($this->_model->getAuthStorage()->getData());
-        $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());
-        $this->assertEmpty($cookie->get($this->_model->getAuthStorage()->getName()));
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Model/Search/CustomerTest.php b/dev/tests/integration/testsuite/Magento/Backend/Model/Search/CustomerTest.php
index fb4b79dfe54a16bcb4738af561ea64ad253c455a..e17b5accf97dd08dc234b90e73192bb51a573bd7 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Model/Search/CustomerTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Model/Search/CustomerTest.php
@@ -10,12 +10,12 @@ use Magento\TestFramework\Helper\Bootstrap;
 
 /**
  * @magentoAppArea adminhtml
+ * @magentoDataFixture Magento/Customer/_files/three_customers.php
+ * @magentoDataFixture Magento/Customer/_files/customer_address.php
  */
 class CustomerTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @magentoDataFixture Magento/Customer/_files/three_customers.php
-     * @magentoDataFixture Magento/Customer/_files/customer_address.php
      * @dataProvider loadDataProvider
      */
     public function testLoad($query, $limit, $start, $expectedResult)
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Model/Search/OrderTest.php b/dev/tests/integration/testsuite/Magento/Backend/Model/Search/OrderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..759951c785d8590a1e9651a68f7a3ceeffae6371
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Backend/Model/Search/OrderTest.php
@@ -0,0 +1,135 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Backend\Model\Search;
+
+use Magento\TestFramework\Helper\Bootstrap;
+
+/**
+ * @magentoAppArea adminhtml
+ * @magentoDataFixture Magento/Sales/_files/order.php
+ * @magentoDataFixture Magento/Sales/_files/order_shipping_address_different_to_billing.php
+ */
+class OrderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider loadDataProvider
+     */
+    public function testLoad($query, $limit, $start, $expectedResult)
+    {
+        /** @var $order \Magento\Sales\Model\Order */
+        $order = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Sales\Model\Order');
+        $orderIdByIncrementId = [];
+        foreach (['100000001', '100000002', '100000003'] as $incrementId) {
+            $orderIdByIncrementId[$incrementId] = $order->loadByIncrementId($incrementId)->getId();
+        }
+
+        /** Preconditions */
+        $objectManager = Bootstrap::getObjectManager();
+        /** @var \Magento\Backend\Model\Search\Order $orderSearch */
+        $orderSearch = $objectManager->create('Magento\Backend\Model\Search\Order');
+        $orderSearch->setQuery($query);
+        $orderSearch->setLimit($limit);
+        $orderSearch->setStart($start);
+        $orderSearch->load();
+
+        /** SUT Execution */
+        $searchResults = $orderSearch->getResults();
+
+        /** Ensure that search results are correct */
+        $this->assertCount(count($expectedResult), $searchResults, 'Quantity of search result items is invalid.');
+        foreach ($expectedResult as $itemIndex => $expectedItem) {
+            /** Validate URL to item */
+            $orderIncrementId = substr($expectedItem['id'], strlen('order/1/#'));
+            $this->assertContains(
+                "order/view/order_id/{$orderIdByIncrementId[$orderIncrementId]}",
+                $searchResults[$itemIndex]['url'],
+                'Item URL is invalid.'
+            );
+            $expectedItem['id'] = 'order/1/' . $orderIdByIncrementId[$orderIncrementId];
+            unset($searchResults[$itemIndex]['url']);
+
+            /** Validate other item data */
+            foreach ($expectedItem as $field => $value) {
+                $this->assertEquals(
+                    $value,
+                    (string)$searchResults[$itemIndex][$field],
+                    "Data of item #$itemIndex is invalid."
+                );
+            }
+        }
+    }
+
+    public static function loadDataProvider()
+    {
+        return [
+            'All items, first page' => [
+                '10000000',
+                2, // Items on page
+                1, // Page number
+                [
+                    [
+                        'id' => 'order/1/#100000001',
+                        'type' => 'Order',
+                        'name' => 'Order #100000001',
+                        'description' => 'firstname lastname',
+                    ],
+                    [
+                        'id' => 'order/1/#100000002',
+                        'type' => 'Order',
+                        'name' => 'Order #100000002',
+                        'description' => 'guest guest'
+                    ]
+                ],
+            ],
+            'All items, second page' => [
+                '10000000',
+                2, // Items on page
+                2, // Page number
+                [
+                    [
+                        'id' => 'order/1/#100000003',
+                        'type' => 'Order',
+                        'name' => 'Order #100000003',
+                        'description' => 'guest guest',
+                    ]
+                ],
+            ],
+            'Search by first name, first item only' => [
+                'First',
+                10, // Items on page
+                1, // Page number
+                [
+                    [
+                        'id' => 'order/1/#100000001',
+                        'type' => 'Order',
+                        'name' => 'Order #100000001',
+                        'description' => 'firstname lastname',
+                    ]
+                ],
+            ],
+            'No results' => [
+                'NotExistingOrder',
+                10, // Items on page
+                1, // Page number
+                [],
+            ],
+            'Search by last name, first item only' => [
+                'last',
+                10, // Items on page
+                1, // Page number
+                [
+                    [
+                        'id' => 'order/1/#100000001',
+                        'type' => 'Order',
+                        'name' => 'Order #100000001',
+                        'description' => 'firstname lastname',
+                    ]
+                ],
+            ],
+        ];
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Email/Block/Adminhtml/Template/Edit/FormTest.php b/dev/tests/integration/testsuite/Magento/Email/Block/Adminhtml/Template/Edit/FormTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..035efbb3bb89879982b67db8f958456ad61b84c2
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Email/Block/Adminhtml/Template/Edit/FormTest.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Email\Block\Adminhtml\Template\Edit;
+
+/**
+ * Test class for \Magento\Email\Block\Adminhtml\Template\Edit\Form
+ * @magentoAppArea adminhtml
+ * @magentoAppIsolation enabled
+ */
+class FormTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var string[] */
+    protected $expectedFields;
+
+    /** @var Magento\Email\Model\Template */
+    protected $template;
+
+    /** @var Magento\Framework\TestFramework\Unit\Helper\ObjectManager */
+    protected $objectManager;
+
+    /** @var \Magento\Framework\Registry */
+    protected $registry;
+
+    /** @var \Magento\Email\Block\Adminhtml\Template\Edit\Form */
+    protected $block;
+
+    /** @var \ReflectionMethod */
+    protected $prepareFormMethod;
+
+    public function setUp()
+    {
+        $this->expectedFields = [
+            'base_fieldset',
+            'template_code',
+            'template_subject',
+            'orig_template_variables',
+            'variables',
+            'template_variables',
+            'insert_variable',
+            'template_text',
+            'template_styles'
+        ];
+
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->template = $this->objectManager->get('Magento\Email\Model\Template')
+            ->setId(1)
+            ->setTemplateType(\Magento\Framework\App\TemplateTypesInterface::TYPE_HTML);
+        $this->registry = $this->objectManager->get('Magento\Framework\Registry');
+        if ($this->registry->registry('current_email_template') == null) {
+            $this->registry->register('current_email_template', $this->template);
+        }
+        $this->block = $this->objectManager->create('Magento\Email\Block\Adminhtml\Template\Edit\Form');
+        $this->prepareFormMethod = new \ReflectionMethod(
+            'Magento\Email\Block\Adminhtml\Template\Edit\Form',
+            '_prepareForm'
+        );
+        $this->prepareFormMethod->setAccessible(true);
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Edit\Form::_prepareForm
+     */
+    public function testPrepareFormWithTemplateId()
+    {
+        $this->expectedFields[] = 'used_currently_for';
+        $this->runTest();
+    }
+
+    /**
+     * @covers \Magento\Email\Block\Adminhtml\Template\Edit\Form::_prepareForm
+     */
+    public function testPrepareFormWithoutTemplateId()
+    {
+        $this->template->setId(null);
+        $this->expectedFields[] = 'used_default_for';
+        $this->runTest();
+    }
+
+    protected function runTest()
+    {
+        $this->prepareFormMethod->invoke($this->block);
+        $form = $this->block->getForm();
+        foreach ($this->expectedFields as $key) {
+            $this->assertNotNull($form->getElement($key));
+        }
+        $this->assertGreaterThan(0, strpos($form->getElement('insert_variable')->getData('text'), 'Insert Variable'));
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Email/Model/TemplateTest.php b/dev/tests/integration/testsuite/Magento/Email/Model/TemplateTest.php
index 72cbb8f071d6f7b0a8cdd2574bc3ccb6005eabe1..f7c9bcc53653adc6854ac860d56bab6bf17a6da3 100644
--- a/dev/tests/integration/testsuite/Magento/Email/Model/TemplateTest.php
+++ b/dev/tests/integration/testsuite/Magento/Email/Model/TemplateTest.php
@@ -201,4 +201,104 @@ class TemplateTest extends \PHPUnit_Framework_TestCase
             [['store' => $storeId]],
         ];
     }
+
+    public function testSetAndGetId()
+    {
+        $testId = 9999;
+        $this->_model->setId($testId);
+        $this->assertEquals($testId, $this->_model->getId());
+    }
+
+    public function testIsValidForSend()
+    {
+        $this->assertTrue($this->_model->isValidForSend());
+    }
+
+    /**
+     * @expectedException \UnexpectedValueException
+     * @expectedExceptionMessage Email template 'foo' is not defined.
+     */
+    public function testGetTypeNonExistentType()
+    {
+        $this->_model->setId('foo');
+        $this->_model->getType();
+    }
+
+    public function testGetTypeHtml()
+    {
+        $this->_model->setId('customer_create_account_email_template');
+        $this->assertEquals(\Magento\Framework\App\TemplateTypesInterface::TYPE_HTML, $this->_model->getType());
+    }
+
+    public function testGetType()
+    {
+        $templateTypeId = 'test_template';
+        $this->_model->setTemplateType($templateTypeId);
+        $this->assertEquals($templateTypeId, $this->_model->getType());
+    }
+
+    public function testGetPreparedTemplateText()
+    {
+        $this->_model->loadDefault('customer_create_account_email_template');
+        $this->assertContains('<body style', $this->_model->getPreparedTemplateText());
+    }
+
+    public function testGetSendingException()
+    {
+        $this->assertNull($this->_model->getSendingException());
+    }
+
+    public function testGetVariablesOptionArray()
+    {
+        $testTemplateVariables = '{"var data.name":"Sender Name","var data.email":"Sender Email"}';
+        $this->_model->setOrigTemplateVariables($testTemplateVariables);
+        $variablesOptionArray = $this->_model->getVariablesOptionArray();
+        $this->assertEquals('{{var data.name}}', $variablesOptionArray[0]['value']);
+        $this->assertEquals('Sender Name', $variablesOptionArray[0]['label']->getArguments()[0]);
+        $this->assertEquals('{{var data.email}}', $variablesOptionArray[1]['value']);
+        $this->assertEquals('Sender Email', $variablesOptionArray[1]['label']->getArguments()[0]);
+    }
+
+    public function testGetVariablesOptionArrayInGroup()
+    {
+        $testTemplateVariables = '{"var data.name":"Sender Name","var data.email":"Sender Email"}';
+        $this->_model->setOrigTemplateVariables($testTemplateVariables);
+        $variablesOptionArray = $this->_model->getVariablesOptionArray(true);
+        $this->assertEquals('Template Variables', $variablesOptionArray['label']->getText());
+        $this->assertEquals($this->_model->getVariablesOptionArray(), $variablesOptionArray['value']);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Mail\Exception
+     * @expectedExceptionMessage The template Name must not be empty.
+     */
+    public function testBeforeSaveEmptyTemplateCode()
+    {
+        $this->_model->beforeSave();
+    }
+
+    public function testBeforeSave()
+    {
+        $this->_model->setTemplateCode('test template code');
+        $this->_model->beforeSave();
+    }
+
+    public function testProcessTemplate()
+    {
+        $this->_model->setId('customer_create_account_email_template');
+        $this->assertContains('<body style', $this->_model->processTemplate());
+    }
+
+    public function testGetSubject()
+    {
+        $this->_model->setVars(['foo', 'bar', 'baz']);
+        $this->assertEquals('Subject', $this->_model->getSubject());
+    }
+
+    public function testSetOptions()
+    {
+        $options = ['area' => 'test area', 'store' => 1];
+        $this->_model->setOptions($options);
+        $this->assertEquals($options, $this->_model->getDesignConfig()->getData());
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/GiftMessage/Model/OrderItemRepositoryTest.php b/dev/tests/integration/testsuite/Magento/GiftMessage/Model/OrderItemRepositoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..18532c48952e48d2f1abd65f62514eeb45c7acbf
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/GiftMessage/Model/OrderItemRepositoryTest.php
@@ -0,0 +1,163 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\GiftMessage\Model;
+
+class OrderItemRepositoryTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Framework\ObjectManagerInterface */
+    protected $objectManager;
+
+    /** @var \Magento\GiftMessage\Model\Message */
+    protected $message;
+
+    /** @var \Magento\GiftMessage\Model\OrderItemRepository */
+    protected $giftMessageOrderItemRepository;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+        $this->message = $this->objectManager->create('Magento\GiftMessage\Model\Message');
+        $this->message->setSender('Romeo');
+        $this->message->setRecipient('Mercutio');
+        $this->message->setMessage('I thought all for the best.');
+
+        $this->giftMessageOrderItemRepository = $this->objectManager->create(
+            'Magento\GiftMessage\Model\OrderItemRepository'
+        );
+
+    }
+
+    protected function tearDown()
+    {
+        unset($this->objectManager);
+        unset($this->message);
+        unset($this->giftMessageOrderItemRepository);
+    }
+
+    /**
+     * @magentoDataFixture Magento/GiftMessage/_files/order_with_message.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_items 1
+     */
+    public function testGet()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+        /** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+        $orderItem = $order->getItems();
+        $orderItem = array_shift($orderItem);
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $message = $this->giftMessageOrderItemRepository->get($order->getEntityId(), $orderItem->getItemId());
+        $this->assertEquals('Romeo', $message->getSender());
+        $this->assertEquals('Mercutio', $message->getRecipient());
+        $this->assertEquals('I thought all for the best.', $message->getMessage());
+    }
+
+    /**
+     * @magentoDataFixture Magento/GiftMessage/_files/order_with_message.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_items 1
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage There is no item with provided id in the order
+     */
+    public function testGetNoProvidedItemId()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+        /** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+        $orderItem = $order->getItems();
+        $orderItem = array_shift($orderItem);
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $this->giftMessageOrderItemRepository->get($order->getEntityId(), $orderItem->getItemId() * 10);
+    }
+
+    /**
+     * @magentoDataFixture Magento/Sales/_files/order.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_items 1
+     */
+    public function testSave()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+        /** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+        $orderItem = $order->getItems();
+        $orderItem = array_shift($orderItem);
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $result = $this->giftMessageOrderItemRepository->save(
+            $order->getEntityId(),
+            $orderItem->getItemId(),
+            $this->message
+        );
+
+        $message = $this->giftMessageOrderItemRepository->get($order->getEntityId(), $orderItem->getItemId());
+
+        $this->assertTrue($result);
+        $this->assertEquals('Romeo', $message->getSender());
+        $this->assertEquals('Mercutio', $message->getRecipient());
+        $this->assertEquals('I thought all for the best.', $message->getMessage());
+    }
+
+
+    /**
+     * @magentoDataFixture Magento/Sales/_files/order.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_items 0
+     * @expectedException \Magento\Framework\Exception\CouldNotSaveException
+     * @expectedExceptionMessage Gift Message is not available
+     */
+    public function testSaveMessageIsNotAvailable()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+        /** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+        $orderItem = $order->getItems();
+        $orderItem = array_shift($orderItem);
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $this->giftMessageOrderItemRepository->save($order->getEntityId(), $orderItem->getItemId(), $this->message);
+    }
+
+    /**
+     * @magentoDataFixture Magento/GiftMessage/_files/virtual_order.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_items 1
+     * @expectedException \Magento\Framework\Exception\State\InvalidTransitionException
+     * @expectedExceptionMessage Gift Messages is not applicable for virtual products
+     */
+    public function testSaveMessageIsVirtual()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+        /** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+        $orderItem = $order->getItems();
+        $orderItem = array_shift($orderItem);
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $this->giftMessageOrderItemRepository->save($order->getEntityId(), $orderItem->getItemId(), $this->message);
+    }
+
+    /**
+     * @magentoDataFixture Magento/GiftMessage/_files/empty_order.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_items 1
+     * @expectedException  \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage There is no item with provided id in the order
+     */
+    public function testSaveMessageNoProvidedItemId()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+        /** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+        $orderItem = $order->getItems();
+        $orderItem = array_shift($orderItem);
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $this->giftMessageOrderItemRepository->save(
+            $order->getEntityId(),
+            $orderItem->getItemId() * 10,
+            $this->message
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/GiftMessage/Model/OrderRepositoryTest.php b/dev/tests/integration/testsuite/Magento/GiftMessage/Model/OrderRepositoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f47174a49cf265d42dd203ad3d758b605606d552
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/GiftMessage/Model/OrderRepositoryTest.php
@@ -0,0 +1,133 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\GiftMessage\Model;
+
+class OrderRepositoryTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Framework\ObjectManagerInterface */
+    protected $objectManager;
+
+    /** @var \Magento\GiftMessage\Model\Message */
+    protected $message;
+
+    /** @var \Magento\GiftMessage\Model\OrderRepository */
+    protected $giftMessageOrderRepository;
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+        $this->message = $this->objectManager->create('Magento\GiftMessage\Model\Message');
+        $this->message->setSender('Romeo');
+        $this->message->setRecipient('Mercutio');
+        $this->message->setMessage('I thought all for the best.');
+
+        $this->giftMessageOrderRepository = $this->objectManager->create('Magento\GiftMessage\Model\OrderRepository');
+    }
+
+    protected function tearDown()
+    {
+        unset($this->objectManager);
+        unset($this->message);
+        unset($this->giftMessageOrderRepository);
+    }
+
+    /**
+     * @magentoDataFixture Magento/GiftMessage/_files/order_with_message.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_order 1
+     */
+    public function testGet()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $message = $this->giftMessageOrderRepository->get($order->getEntityId());
+        $this->assertEquals('Romeo', $message->getSender());
+        $this->assertEquals('Mercutio', $message->getRecipient());
+        $this->assertEquals('I thought all for the best.', $message->getMessage());
+    }
+
+    /**
+     * @magentoDataFixture Magento/Sales/_files/order.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_order 1
+     */
+    public function testSave()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $result = $this->giftMessageOrderRepository->save($order->getEntityId(), $this->message);
+
+        $message = $this->giftMessageOrderRepository->get($order->getEntityId());
+
+        $this->assertTrue($result);
+        $this->assertEquals('Romeo', $message->getSender());
+        $this->assertEquals('Mercutio', $message->getRecipient());
+        $this->assertEquals('I thought all for the best.', $message->getMessage());
+    }
+
+    /**
+     * @magentoDataFixture Magento/Sales/_files/order.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_order 0
+     * @expectedException \Magento\Framework\Exception\CouldNotSaveException
+     * @expectedExceptionMessage Gift Message is not available
+     */
+    public function testSaveMessageIsNotAvailable()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $this->giftMessageOrderRepository->save($order->getEntityId(), $this->message);
+    }
+
+    /**
+     * @magentoDataFixture Magento/GiftMessage/_files/virtual_order.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_order 1
+     * @expectedException \Magento\Framework\Exception\State\InvalidTransitionException
+     * @expectedExceptionMessage Gift Messages is not applicable for virtual products
+     */
+    public function testSaveMessageIsVirtual()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $this->giftMessageOrderRepository->save($order->getEntityId(), $this->message);
+    }
+
+    /**
+     * @magentoDataFixture Magento/GiftMessage/_files/empty_order.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_order 1
+     * @expectedException \Magento\Framework\Exception\InputException
+     * @expectedExceptionMessage Gift Messages is not applicable for empty order
+     */
+    public function testSaveMessageIsEmpty()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $this->giftMessageOrderRepository->save($order->getEntityId(), $this->message);
+    }
+
+    /**
+     * @magentoDataFixture Magento/GiftMessage/_files/empty_order.php
+     * @magentoConfigFixture default_store sales/gift_options/allow_order 1
+     * @expectedException  \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage There is no order with provided id
+     */
+    public function testSaveMessageNoProvidedItemId()
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $this->objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+
+        /** @var \Magento\GiftMessage\Api\Data\MessageInterface $message */
+        $this->giftMessageOrderRepository->save($order->getEntityId() * 10, $this->message);
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/empty_order.php b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/empty_order.php
new file mode 100644
index 0000000000000000000000000000000000000000..40a28f6d051f7f6b53e491ceaa44a195d15d56f4
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/empty_order.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+require __DIR__ . '/../../../Magento/Sales/_files/order.php';
+/** @var \Magento\Sales\Model\Order $order */
+
+$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+$order = $objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+$order->setItems([])->setTotalItemCount(0)->save();
diff --git a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/order_with_message.php b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/order_with_message.php
new file mode 100644
index 0000000000000000000000000000000000000000..b99eddea282846771d77bfc51cf101789e191b52
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/order_with_message.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+require __DIR__ . '/../../../Magento/Sales/_files/order.php';
+
+$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+/** @var \Magento\GiftMessage\Model\Message $message */
+$message = $objectManager->create('Magento\GiftMessage\Model\Message');
+$message->setSender('Romeo');
+$message->setRecipient('Mercutio');
+$message->setMessage('I thought all for the best.');
+$message->save();
+
+/** @var \Magento\Sales\Model\Order $order */
+$order = $objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+
+/** @var \Magento\Sales\Api\Data\OrderItemInterface $orderItem */
+$orderItem = $order->getItems();
+$orderItem = array_shift($orderItem);
+$orderItem->setGiftMessageId($message->getId());
+
+$order->setItems([$orderItem])->setGiftMessageId($message->getId());
+$order->save();
diff --git a/dev/tests/integration/testsuite/Magento/GiftMessage/_files/virtual_order.php b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/virtual_order.php
new file mode 100644
index 0000000000000000000000000000000000000000..1e33aba1663cb9c01beb1cbf0d53c0cd61e3ca8b
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/GiftMessage/_files/virtual_order.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+require __DIR__ . '/../../../Magento/Sales/_files/order.php';
+/** @var \Magento\Sales\Model\Order $order */
+
+$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+
+$order = $objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId('100000001');
+$order->setIsVirtual(1)->save();
diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php
index d53554db1622aaf000606fd11378630584e89d7a..ab65efa40a0ec16a5e87507b90e0cde8139b8377 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php
@@ -83,7 +83,7 @@ class CreateTest extends \PHPUnit_Framework_TestCase
 
         /** @var $order \Magento\Sales\Model\Order */
         $order = $objectManager->create('Magento\Sales\Model\Order');
-        $order->loadByIncrementId('100000001');
+        $order->loadByIncrementId('100000002');
 
         $this->assertNull($order->getShippingAddress()->getSameAsBilling());
 
diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_shipping_address_different_to_billing.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_shipping_address_different_to_billing.php
index d46172f603d9538db67d078db203080b47664b6a..9a4f95e5fbf0199ea442e40f1c18152d08cf7d82 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/_files/order_shipping_address_different_to_billing.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/_files/order_shipping_address_different_to_billing.php
@@ -30,13 +30,21 @@ $shippingAddress->setId(null)->setPostcode('2')->setAddressType('shipping');
 $order = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Sales\Model\Order');
 $order->loadByIncrementId('100000001');
 $clonedOrder = clone $order;
-$order->setIncrementId('100000002');
-$order->save();
 
 /** @var $payment \Magento\Sales\Model\Order\Payment */
 $payment = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Sales\Model\Order\Payment');
 $payment->setMethod('checkmo');
+$clonedOrder->setIncrementId('100000002')
+    ->setId(null)
+    ->setBillingAddress($billingAddress)
+    ->setShippingAddress($shippingAddress)
+    ->setPayment($payment);
+$clonedOrder->save();
 
-$order = $clonedOrder;
-$order->setId(null)->setBillingAddress($billingAddress)->setShippingAddress($shippingAddress)->setPayment($payment);
-$order->save();
+$secondClonedOrder = clone $order;
+$secondClonedOrder->setIncrementId('100000003')
+    ->setId(null)
+    ->setBillingAddress($billingAddress->setId(null))
+    ->setShippingAddress($shippingAddress->setId(null))
+    ->setPayment($payment->setId(null));
+$secondClonedOrder->save();
diff --git a/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/UserTest.php b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/UserTest.php
index 0fa5bfb6712bbf3d47504100f45b355cc980f4da..f7de99380e8423f158736487530959823e2fb917 100644
--- a/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/UserTest.php
+++ b/dev/tests/integration/testsuite/Magento/User/Controller/Adminhtml/UserTest.php
@@ -95,6 +95,32 @@ class UserTest extends \Magento\Backend\Utility\Controller
         $this->assertRedirect($this->stringContains('backend/admin/user/index/'));
     }
 
+    /**
+     * @magentoDbIsolation enabled
+     * @magentoDataFixture Magento/User/_files/user_with_role.php
+     */
+    public function testSaveActionDuplicateUser()
+    {
+        $this->getRequest()->setPostValue(
+            [
+                'username' => 'adminUser',
+                'email' => 'adminUser@example.com',
+                'firstname' => 'John',
+                'lastname' => 'Doe',
+                'password' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD,
+                'password_confirmation' => \Magento\TestFramework\Bootstrap::ADMIN_PASSWORD,
+                \Magento\User\Block\User\Edit\Tab\Main::CURRENT_USER_PASSWORD_FIELD => Bootstrap::ADMIN_PASSWORD,
+            ]
+        );
+        $this->dispatch('backend/admin/user/save/active_tab/main_section');
+        $this->assertSessionMessages(
+            $this->equalTo(['A user with the same user name or email already exists.']),
+            \Magento\Framework\Message\MessageInterface::TYPE_ERROR
+        );
+        $this->assertRedirect($this->stringContains('backend/admin/user/edit/'));
+        $this->assertRedirect($this->matchesRegularExpression('/^((?!active_tab).)*$/'));
+    }
+
     /**
      * @magentoDbIsolation enabled
      * @dataProvider resetPasswordDataProvider
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 21ff60a356b59dbd10c2c7bcc2d9c5cc21c57bd4..7baeb9bac60b7ecbb782de7407a87d7033367831 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
@@ -338,6 +338,11 @@ return [
     ['_getItemPosition', 'Magento\Catalog\Block\Navigation'],
     ['_renderCategoryMenuItemHtml', 'Magento\Catalog\Block\Navigation'],
     ['getCurrentCategoryPath', 'Magento\Catalog\Block\Navigation'],
+    [
+        'getIsMessagesAvailable',
+        'Magento\GiftMessage\Helper\Message',
+        'Magento\GiftMessage\Helper\Message::isMessagesAllowed'
+    ],
     ['drawOpenCategoryItem', 'Magento\Catalog\Block\Navigation'],
     ['renderCategoriesMenuHtml', 'Magento\Catalog\Block\Navigation'],
     ['dropKey', 'Magento\Framework\DB\Adapter\Pdo\Mysql'],
diff --git a/dev/tests/unit/phpunit.xml.dist b/dev/tests/unit/phpunit.xml.dist
index da22efa001e62023edca737d21fce161a764a665..5c785e252e48aa8c82aa8bcfe817c761b38ecc23 100644
--- a/dev/tests/unit/phpunit.xml.dist
+++ b/dev/tests/unit/phpunit.xml.dist
@@ -44,5 +44,8 @@
         <!--coverage_clover_placeholder
             <log type="coverage-clover" target="{{coverage_dir}}/test-reports/phpunit.coverage.xml"/>
         coverage_clover_placeholder-->
+        <!--coverage_crap4j_placeholder
+            <log type="coverage-crap4j" target="{{coverage_dir}}/test-reports/phpunit.crap4j.xml"/>
+        coverage_crap4j_placeholder-->
     </logging>
 </phpunit>
diff --git a/dev/tools/Magento/Tools/Di/compiler.php b/dev/tools/Magento/Tools/Di/compiler.php
index fca4673dd90fdf85f5feb74bfd3257d99a83e78b..ced28772e7c6108f8f1a033617cf4af379687195 100644
--- a/dev/tools/Magento/Tools/Di/compiler.php
+++ b/dev/tools/Magento/Tools/Di/compiler.php
@@ -247,11 +247,6 @@ try {
         . ' in the "var" directory. For instance, if you run the Magento application using Apache,'
         . ' the owner of the files in the "var" directory should be the Apache user (example command:'
         . ' "chown -R www-data:www-data <MAGENTO_ROOT>/var" where MAGENTO_ROOT is the Magento root directory).' . "\n";
-    /** TODO: Temporary solution before having necessary changes on bamboo to overcome issue described above */
-    $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($rootDir . '/var'));
-    foreach ($iterator as $item) {
-        chmod($item, 0777);
-    }
 
 } catch (Zend_Console_Getopt_Exception $e) {
     echo $e->getUsageMessage();