diff --git a/app/code/Magento/Catalog/Block/Product/ProductList/Related.php b/app/code/Magento/Catalog/Block/Product/ProductList/Related.php
index 3a85443d070d402ea9ae86809aa14c7bf57f301f..78a9e8c4594df493fe5c4b4ed5e4e5b8b30dcab2 100644
--- a/app/code/Magento/Catalog/Block/Product/ProductList/Related.php
+++ b/app/code/Magento/Catalog/Block/Product/ProductList/Related.php
@@ -131,4 +131,19 @@ class Related extends \Magento\Catalog\Block\Product\AbstractProduct implements
         }
         return $identities;
     }
+
+    /**
+     * Find out if some products can be easy added to cart
+     *
+     * @return bool
+     */
+    public function canItemsAddToCart()
+    {
+        foreach ($this->getItems() as $item) {
+            if (!$item->isComposite() && $item->isSaleable() && !$item->getRequiredOptions()) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php
index 28e8e25dfaa6b8273b50b984f0d0ec265a21aa34..aa8a3027a9d37115bd1382bc47ddd93d9a33f913 100644
--- a/app/code/Magento/Catalog/Model/ProductRepository.php
+++ b/app/code/Magento/Catalog/Model/ProductRepository.php
@@ -13,7 +13,6 @@ use Magento\Framework\Api\Data\ImageContentInterface;
 use Magento\Framework\Api\Data\ImageContentInterfaceFactory;
 use Magento\Framework\Api\ImageContentValidatorInterface;
 use Magento\Framework\Api\ImageProcessorInterface;
-use Magento\Framework\Api\SearchCriteriaInterface;
 use Magento\Framework\Api\SortOrder;
 use Magento\Framework\Exception\InputException;
 use Magento\Framework\Exception\NoSuchEntityException;
@@ -658,7 +657,7 @@ class ProductRepository implements \Magento\Catalog\Api\ProductRepositoryInterfa
             $field = $sortOrder->getField();
             $collection->addOrder(
                 $field,
-                ($sortOrder->getDirection() == SearchCriteriaInterface::SORT_ASC) ? 'ASC' : 'DESC'
+                ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC'
             );
         }
         $collection->setCurPage($searchCriteria->getCurrentPage());
diff --git a/app/code/Magento/Catalog/Model/Resource/Product/Collection.php b/app/code/Magento/Catalog/Model/Resource/Product/Collection.php
index 96b2597121705d7c66ed647a5cc100f4643f5d02..4ac6244bd11334085b2b903a5e15c11df088ee69 100644
--- a/app/code/Magento/Catalog/Model/Resource/Product/Collection.php
+++ b/app/code/Magento/Catalog/Model/Resource/Product/Collection.php
@@ -1312,7 +1312,7 @@ class Collection extends \Magento\Catalog\Model\Resource\Collection\AbstractColl
         $select = $this->getConnection()
             ->select()
             ->from(['u' => $this->getTable('url_rewrite')], ['u.entity_id', 'u.request_path'])
-            ->where('u.store_id = ?', $this->_storeManager->getStore()->getId())
+            ->where('u.store_id = ?', $this->_storeManager->getStore($this->getStoreId())->getId())
             ->where('u.is_autogenerated = 1')
             ->where('u.entity_type = ?', ProductUrlRewriteGenerator::ENTITY_TYPE)
             ->where('u.entity_id IN(?)', $productIds);
diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/RelatedTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/RelatedTest.php
index cd759fefce044092fa68a8f3bcbe2baa07c81986..414e617530bc9a9de45abd65e50d39c2f77cfc17 100644
--- a/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/RelatedTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Block/Product/ProductList/RelatedTest.php
@@ -41,4 +41,47 @@ class RelatedTest extends \PHPUnit_Framework_TestCase
             $this->block->getIdentities()
         );
     }
+
+    /**
+     * @dataProvider canItemsAddToCartDataProvider
+     * @param bool $isComposite
+     * @param bool $isSaleable
+     * @param bool $hasRequiredOptions
+     * @param bool $canItemsAddToCart
+     */
+    public function testCanItemsAddToCart($isComposite, $isSaleable, $hasRequiredOptions, $canItemsAddToCart)
+    {
+        $product = $this->getMock(
+            'Magento\Catalog\Model\Product',
+            ['isComposite', 'isSaleable', 'getRequiredOptions'],
+            [],
+            '',
+            false
+        );
+        $product->expects($this->any())->method('isComposite')->willReturn($isComposite);
+        $product->expects($this->any())->method('isSaleable')->willReturn($isSaleable);
+        $product->expects($this->any())->method('getRequiredOptions')->willReturn($hasRequiredOptions);
+
+        $itemsCollection = new \ReflectionProperty(
+            'Magento\Catalog\Block\Product\ProductList\Related',
+            '_itemCollection'
+        );
+        $itemsCollection->setAccessible(true);
+        $itemsCollection->setValue($this->block, [$product]);
+
+        $this->assertEquals(
+            $canItemsAddToCart,
+            $this->block->canItemsAddToCart()
+        );
+    }
+
+    public function canItemsAddToCartDataProvider()
+    {
+        return [
+            [false, true, false, true],
+            [false, false, false, false],
+            [true, false, false, false],
+            [true, false, true, false],
+        ];
+    }
 }
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php
index ad8341e86cfdd703d5379a82366c40fd386afef0..87aef1de10e46c80aea5b1e1dc08ac04b4f3a34b 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php
@@ -11,6 +11,7 @@ namespace Magento\Catalog\Test\Unit\Model;
 
 use Magento\Catalog\Model\Layer\Filter\Dynamic\AlgorithmFactory;
 use Magento\Framework\Api\Data\ImageContentInterface;
+use Magento\Framework\Api\SortOrder;
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
 use Magento\Store\Model\ScopeInterface;
 
@@ -602,7 +603,7 @@ class ProductRepositoryTest extends \PHPUnit_Framework_TestCase
         $searchCriteriaMock->expects($this->once())->method('getSortOrders')->willReturn([$sortOrderMock]);
         $sortOrderMock->expects($this->once())->method('getField')->willReturn('field');
         $sortOrderMock->expects($this->once())->method('getDirection')
-            ->willReturn(\Magento\Framework\Api\SearchCriteriaInterface::SORT_ASC);
+            ->willReturn(SortOrder::SORT_ASC);
         $collectionMock->expects($this->once())->method('addOrder')->with('field', 'ASC');
         $searchCriteriaMock->expects($this->once())->method('getCurrentPage')->willReturn(4);
         $collectionMock->expects($this->once())->method('setCurPage')->with(4);
diff --git a/app/code/Magento/Catalog/view/frontend/templates/product/list/items.phtml b/app/code/Magento/Catalog/view/frontend/templates/product/list/items.phtml
index 7260913b0c67c1ee6a6dece62025cf06c0d01f6d..65b0f6c600093d6c772f05dbc2a7318756574abb 100644
--- a/app/code/Magento/Catalog/view/frontend/templates/product/list/items.phtml
+++ b/app/code/Magento/Catalog/view/frontend/templates/product/list/items.phtml
@@ -23,6 +23,7 @@ switch ($type = $block->getType()) {
             $items = $block->getAllItems();
             $limit = $block->getPositionLimit();
             $shuffle = (int) $block->isShuffled();
+            $canItemsAddToCart = $block->canItemsAddToCart();
 
             $showWishlist = true;
             $showCompare = true;
@@ -44,6 +45,7 @@ switch ($type = $block->getType()) {
             $items = $block->getItems();
             $limit = 0;
             $shuffle = 0;
+            $canItemsAddToCart = $block->canItemsAddToCart();
 
             $showWishlist = true;
             $showCompare = true;
@@ -70,6 +72,7 @@ switch ($type = $block->getType()) {
             $showCart = false;
             $templateType = null;
             $description = false;
+            $canItemsAddToCart = false;
         }
     break;
 
@@ -91,6 +94,7 @@ switch ($type = $block->getType()) {
             $showCart = false;
             $templateType = null;
             $description = false;
+            $canItemsAddToCart = false;
         }
     break;
 
@@ -110,6 +114,7 @@ switch ($type = $block->getType()) {
             $showCart = true;
             $templateType = \Magento\Catalog\Block\Product\ReviewRendererInterface::SHORT_VIEW;
             $description = false;
+            $canItemsAddToCart = false;
         }
     break;
 
@@ -129,6 +134,7 @@ switch ($type = $block->getType()) {
             $showCart = true;
             $templateType = \Magento\Catalog\Block\Product\ReviewRendererInterface::SHORT_VIEW;
             $description = false;
+            $canItemsAddToCart = false;
         }
     break;
 
@@ -150,6 +156,7 @@ switch ($type = $block->getType()) {
             $showCart = true;
             $templateType = \Magento\Catalog\Block\Product\ReviewRendererInterface::SHORT_VIEW;
             $description = ($mode == 'list') ? true : false;
+            $canItemsAddToCart = false;
         }
     break;
 
@@ -173,7 +180,7 @@ switch ($type = $block->getType()) {
         <strong id="block-<?php echo $class?>-heading" role="heading" aria-level="2"><?php echo $title; ?></strong>
     </div>
     <div class="block-content content" aria-labelledby="block-<?php echo $class?>-heading">
-        <?php if ($type == 'related'): ?>
+        <?php if ($type == 'related' && $canItemsAddToCart): ?>
         <div class="block-actions">
             <?php echo __('Check items to add to the cart or') ?>
             <button type="button" class="action select" role="select-all"><span><?php echo __('select all') ?></span></button>
diff --git a/app/code/Magento/Cms/Model/BlockRepository.php b/app/code/Magento/Cms/Model/BlockRepository.php
index 32c12f0d8dba6d257234ab5af0ed9b71744f88b6..d283374c4206762e4f6be332f8e5fd46edc27e5c 100644
--- a/app/code/Magento/Cms/Model/BlockRepository.php
+++ b/app/code/Magento/Cms/Model/BlockRepository.php
@@ -8,7 +8,7 @@ namespace Magento\Cms\Model;
 use Magento\Cms\Api\Data;
 use Magento\Cms\Api\BlockRepositoryInterface;
 use Magento\Framework\Api\DataObjectHelper;
-use Magento\Framework\Api\SearchCriteriaInterface;
+use Magento\Framework\Api\SortOrder;
 use Magento\Framework\Exception\CouldNotDeleteException;
 use Magento\Framework\Exception\CouldNotSaveException;
 use Magento\Framework\Exception\NoSuchEntityException;
@@ -146,7 +146,7 @@ class BlockRepository implements BlockRepositoryInterface
             foreach ($sortOrders as $sortOrder) {
                 $collection->addOrder(
                     $sortOrder->getField(),
-                    ($sortOrder->getDirection() == SearchCriteriaInterface::SORT_ASC) ? 'ASC' : 'DESC'
+                    ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC'
                 );
             }
         }
diff --git a/app/code/Magento/Cms/Model/PageRepository.php b/app/code/Magento/Cms/Model/PageRepository.php
index b8499344a92e2a02e3926e2bb06510383621053c..c4edabe1ae62083d69f773ca0f4515a5835df341 100644
--- a/app/code/Magento/Cms/Model/PageRepository.php
+++ b/app/code/Magento/Cms/Model/PageRepository.php
@@ -8,7 +8,7 @@ namespace Magento\Cms\Model;
 use Magento\Cms\Api\Data;
 use Magento\Cms\Api\PageRepositoryInterface;
 use Magento\Framework\Api\DataObjectHelper;
-use Magento\Framework\Api\SearchCriteriaInterface;
+use Magento\Framework\Api\SortOrder;
 use Magento\Framework\Exception\CouldNotDeleteException;
 use Magento\Framework\Exception\CouldNotSaveException;
 use Magento\Framework\Exception\NoSuchEntityException;
@@ -143,10 +143,11 @@ class PageRepository implements PageRepositoryInterface
         $searchResults->setTotalCount($collection->getSize());
         $sortOrders = $criteria->getSortOrders();
         if ($sortOrders) {
+            /** @var SortOrder $sortOrder */
             foreach ($sortOrders as $sortOrder) {
                 $collection->addOrder(
                     $sortOrder->getField(),
-                    ($sortOrder->getDirection() == SearchCriteriaInterface::SORT_ASC) ? 'ASC' : 'DESC'
+                    ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC'
                 );
             }
         }
diff --git a/app/code/Magento/Cms/Test/Unit/Model/BlockRepositoryTest.php b/app/code/Magento/Cms/Test/Unit/Model/BlockRepositoryTest.php
index 923efe26c3c1e43bf72588c0b73b5f0df748fc70..f585155396d9f27c311669a7b23bbea5128d8cc8 100644
--- a/app/code/Magento/Cms/Test/Unit/Model/BlockRepositoryTest.php
+++ b/app/code/Magento/Cms/Test/Unit/Model/BlockRepositoryTest.php
@@ -6,7 +6,7 @@
 namespace Magento\Cms\Test\Unit\Model;
 
 use Magento\Cms\Model\BlockRepository;
-use Magento\Framework\Api\SearchCriteriaInterface;
+use Magento\Framework\Api\SortOrder;
 
 /**
  * Test for Magento\Cms\Model\BlockRepository
@@ -236,7 +236,7 @@ class BlockRepositoryTest extends \PHPUnit_Framework_TestCase
         $storeFilter->expects($this->any())->method('getField')->willReturn('store_id');
         $storeFilter->expects($this->once())->method('getValue')->willReturn(1);
         $sortOrder->expects($this->once())->method('getField')->willReturn($sortField);
-        $sortOrder->expects($this->once())->method('getDirection')->willReturn(SearchCriteriaInterface::SORT_DESC);
+        $sortOrder->expects($this->once())->method('getDirection')->willReturn(SortOrder::SORT_DESC);
 
         /** @var \Magento\Framework\Api\SearchCriteriaInterface $criteria */
 
diff --git a/app/code/Magento/Cms/Test/Unit/Model/PageRepositoryTest.php b/app/code/Magento/Cms/Test/Unit/Model/PageRepositoryTest.php
index 79b7b46e4a136e137ef76ab1baf9b990dd780415..64c65fe1f64539572f472ee895c6949cd8c6c10d 100644
--- a/app/code/Magento/Cms/Test/Unit/Model/PageRepositoryTest.php
+++ b/app/code/Magento/Cms/Test/Unit/Model/PageRepositoryTest.php
@@ -6,7 +6,7 @@
 namespace Magento\Cms\Test\Unit\Model;
 
 use Magento\Cms\Model\PageRepository;
-use Magento\Framework\Api\SearchCriteriaInterface;
+use Magento\Framework\Api\SortOrder;
 
 /**
  * Test for Magento\Cms\Model\PageRepository
@@ -236,7 +236,7 @@ class PageRepositoryTest extends \PHPUnit_Framework_TestCase
         $storeFilter->expects($this->any())->method('getField')->willReturn('store_id');
         $storeFilter->expects($this->once())->method('getValue')->willReturn(1);
         $sortOrder->expects($this->once())->method('getField')->willReturn($sortField);
-        $sortOrder->expects($this->once())->method('getDirection')->willReturn(SearchCriteriaInterface::SORT_DESC);
+        $sortOrder->expects($this->once())->method('getDirection')->willReturn(SortOrder::SORT_DESC);
 
         /** @var \Magento\Framework\Api\SearchCriteriaInterface $criteria */
 
diff --git a/app/code/Magento/Customer/Model/Resource/AddressRepository.php b/app/code/Magento/Customer/Model/Resource/AddressRepository.php
index 833cf68fd70b8250e0e0a717d349f43b045620ac..beee1746318b13a9fe1b898c5a43bf2489828177 100644
--- a/app/code/Magento/Customer/Model/Resource/AddressRepository.php
+++ b/app/code/Magento/Customer/Model/Resource/AddressRepository.php
@@ -165,7 +165,7 @@ class AddressRepository implements \Magento\Customer\Api\AddressRepositoryInterf
             $field = $sortOrder->getField();
             $collection->addOrder(
                 $field,
-                ($sortOrder->getDirection() == SearchCriteriaInterface::SORT_ASC) ? 'ASC' : 'DESC'
+                ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC'
             );
         }
         $collection->setCurPage($searchCriteria->getCurrentPage());
diff --git a/app/code/Magento/Customer/Model/Resource/CustomerRepository.php b/app/code/Magento/Customer/Model/Resource/CustomerRepository.php
index bd3064d2f9317d00d62c974f03a899588b4ff180..a0c696bf7b5889d96f625fd622e938e63f756842 100644
--- a/app/code/Magento/Customer/Model/Resource/CustomerRepository.php
+++ b/app/code/Magento/Customer/Model/Resource/CustomerRepository.php
@@ -11,6 +11,7 @@ use Magento\Customer\Model\Data\CustomerSecure;
 use Magento\Framework\Api\DataObjectHelper;
 use Magento\Framework\Api\ImageProcessorInterface;
 use Magento\Framework\Api\SearchCriteriaInterface;
+use Magento\Framework\Api\SortOrder;
 use Magento\Framework\Exception\InputException;
 use Magento\Framework\Exception\NoSuchEntityException;
 
@@ -270,10 +271,11 @@ class CustomerRepository implements \Magento\Customer\Api\CustomerRepositoryInte
         $searchResults->setTotalCount($collection->getSize());
         $sortOrders = $searchCriteria->getSortOrders();
         if ($sortOrders) {
+            /** @var SortOrder $sortOrder */
             foreach ($searchCriteria->getSortOrders() as $sortOrder) {
                 $collection->addOrder(
                     $sortOrder->getField(),
-                    ($sortOrder->getDirection() == SearchCriteriaInterface::SORT_ASC) ? 'ASC' : 'DESC'
+                    ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC'
                 );
             }
         }
diff --git a/app/code/Magento/Customer/Model/Resource/GroupRepository.php b/app/code/Magento/Customer/Model/Resource/GroupRepository.php
index 2b87df95a55bd9454e9c51bf81f013f535335c3c..48c800bf23125ebf7362f8b09b7577880d42305f 100644
--- a/app/code/Magento/Customer/Model/Resource/GroupRepository.php
+++ b/app/code/Magento/Customer/Model/Resource/GroupRepository.php
@@ -10,6 +10,7 @@ use Magento\Customer\Api\Data\GroupInterface;
 use Magento\Customer\Model\Resource\Group\Collection;
 use Magento\Framework\Api\Search\FilterGroup;
 use Magento\Framework\Api\SearchCriteriaInterface;
+use Magento\Framework\Api\SortOrder;
 use Magento\Framework\Exception\InputException;
 use Magento\Framework\Exception\State\InvalidTransitionException;
 use Magento\Tax\Api\Data\TaxClassInterface;
@@ -184,13 +185,13 @@ class GroupRepository implements \Magento\Customer\Api\GroupRepositoryInterface
             $this->addFilterGroupToCollection($group, $collection);
         }
         $sortOrders = $searchCriteria->getSortOrders();
-        /** @var \Magento\Framework\Api\SortOrder $sortOrder */
+        /** @var SortOrder $sortOrder */
         if ($sortOrders) {
             foreach ($searchCriteria->getSortOrders() as $sortOrder) {
                 $field = $this->translateField($sortOrder->getField());
                 $collection->addOrder(
                     $field,
-                    ($sortOrder->getDirection() == SearchCriteriaInterface::SORT_ASC) ? 'ASC' : 'DESC'
+                    ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC'
                 );
             }
         } else {
diff --git a/app/code/Magento/Customer/Test/Unit/Model/Resource/AddressRepositoryTest.php b/app/code/Magento/Customer/Test/Unit/Model/Resource/AddressRepositoryTest.php
index 2ab811cf660bb812d4dcdc9a02c43ce3eed5ad8e..738f6ba46c772e458fb28d270d70cfb5524a36af 100644
--- a/app/code/Magento/Customer/Test/Unit/Model/Resource/AddressRepositoryTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Model/Resource/AddressRepositoryTest.php
@@ -326,7 +326,7 @@ class AddressRepositoryTest extends \PHPUnit_Framework_TestCase
             ->willReturn('Field');
         $sortOrder->expects($this->once())
             ->method('getDirection')
-            ->willReturn(1);
+            ->willReturn(\Magento\Framework\Api\SortOrder::SORT_ASC);
         $collection->expects($this->once())
             ->method('addOrder')
             ->with('Field', 'ASC');
diff --git a/app/code/Magento/Customer/Test/Unit/Model/Resource/CustomerRepositoryTest.php b/app/code/Magento/Customer/Test/Unit/Model/Resource/CustomerRepositoryTest.php
index b612946db645ccfac51e38ee9306e8a2bcd92fee..98ecda6bc26b2f075035d85472d0e545467316e3 100644
--- a/app/code/Magento/Customer/Test/Unit/Model/Resource/CustomerRepositoryTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Model/Resource/CustomerRepositoryTest.php
@@ -737,7 +737,7 @@ class CustomerRepositoryTest extends \PHPUnit_Framework_TestCase
             ->willReturn('Field');
         $sortOrder->expects($this->once())
             ->method('getDirection')
-            ->willReturn(1);
+            ->willReturn(\Magento\Framework\Api\SortOrder::SORT_ASC);
         $searchCriteria->expects($this->once())
             ->method('getCurrentPage')
             ->willReturn(1);
diff --git a/app/code/Magento/Customer/Test/Unit/Model/Resource/Group/Grid/ServiceCollectionTest.php b/app/code/Magento/Customer/Test/Unit/Model/Resource/Group/Grid/ServiceCollectionTest.php
index e3010d24601b6ea0b56504735fa0996c8a4cec43..88e6ff36f333bd3ac4153be8cf5cf2f50c21f371 100644
--- a/app/code/Magento/Customer/Test/Unit/Model/Resource/Group/Grid/ServiceCollectionTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Model/Resource/Group/Grid/ServiceCollectionTest.php
@@ -8,6 +8,7 @@ namespace Magento\Customer\Test\Unit\Model\Resource\Group\Grid;
 
 use Magento\Framework\Api\SearchCriteria;
 use Magento\Customer\Model\Resource\Group\Grid\ServiceCollection;
+use Magento\Framework\Api\SortOrder;
 
 /**
  * Unit test for \Magento\Customer\Model\Resource\Group\Grid\ServiceCollection
@@ -81,7 +82,7 @@ class ServiceCollectionTest extends \PHPUnit_Framework_TestCase
     {
         $sortOrder = $this->sortOrderBuilder
             ->setField('name')
-            ->setDirection(SearchCriteria::SORT_ASC)
+            ->setDirection(SortOrder::SORT_ASC)
             ->create();
         /** @var SearchCriteria $expectedSearchCriteria */
         $expectedSearchCriteria = $this->searchCriteriaBuilder
@@ -111,7 +112,7 @@ class ServiceCollectionTest extends \PHPUnit_Framework_TestCase
         $value = '35';
         $sortOrder = $this->sortOrderBuilder
             ->setField('name')
-            ->setDirection(SearchCriteria::SORT_ASC)
+            ->setDirection(SortOrder::SORT_ASC)
             ->create();
         /** @var SearchCriteria $expectedSearchCriteria */
         $filter = $this->filterBuilder->setField($field)->setConditionType($conditionType)->setValue($value)->create();
@@ -143,7 +144,7 @@ class ServiceCollectionTest extends \PHPUnit_Framework_TestCase
 
         $sortOrder = $this->sortOrderBuilder
             ->setField('name')
-            ->setDirection(SearchCriteria::SORT_ASC)
+            ->setDirection(SortOrder::SORT_ASC)
             ->create();
         /** @var SearchCriteria $expectedSearchCriteria */
         $expectedSearchCriteria = $this->searchCriteriaBuilder
@@ -179,7 +180,7 @@ class ServiceCollectionTest extends \PHPUnit_Framework_TestCase
 
         $sortOrder = $this->sortOrderBuilder
             ->setField('name')
-            ->setDirection(SearchCriteria::SORT_ASC)
+            ->setDirection(SortOrder::SORT_ASC)
             ->create();
         /** @var SearchCriteria $expectedSearchCriteria */
         $expectedSearchCriteria = $this->searchCriteriaBuilder
diff --git a/app/code/Magento/Customer/Test/Unit/Model/Resource/GroupRepositoryTest.php b/app/code/Magento/Customer/Test/Unit/Model/Resource/GroupRepositoryTest.php
index 4cb9d47d081d02cd1a005a48c4e47f17f1c10544..ff0aa87cead17b7baba65decc1ce0bc458bc1c91 100644
--- a/app/code/Magento/Customer/Test/Unit/Model/Resource/GroupRepositoryTest.php
+++ b/app/code/Magento/Customer/Test/Unit/Model/Resource/GroupRepositoryTest.php
@@ -409,7 +409,7 @@ class GroupRepositoryTest extends \PHPUnit_Framework_TestCase
             ->with('Field', 'ASC');
         $sortOrder->expects($this->once())
             ->method('getDirection')
-            ->willReturn(1);
+            ->willReturn(\Magento\Framework\Api\SortOrder::SORT_ASC);
         $searchCriteria->expects($this->once())
             ->method('getCurrentPage')
             ->willReturn(1);
diff --git a/app/code/Magento/Eav/Model/AttributeRepository.php b/app/code/Magento/Eav/Model/AttributeRepository.php
index e43bc2a42d7c0458d965608b075c4edcc6c8c0b1..8af0743f8376e0f08d153534bd544b8b3ca7ca91 100644
--- a/app/code/Magento/Eav/Model/AttributeRepository.php
+++ b/app/code/Magento/Eav/Model/AttributeRepository.php
@@ -7,7 +7,7 @@
 namespace Magento\Eav\Model;
 
 use Magento\Eav\Model\Resource\Entity\Attribute\Collection;
-use Magento\Framework\Api\SearchCriteriaInterface;
+use Magento\Framework\Api\SortOrder;
 use Magento\Framework\Exception\InputException;
 use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Framework\Exception\StateException;
@@ -118,11 +118,11 @@ class AttributeRepository implements \Magento\Eav\Api\AttributeRepositoryInterfa
         foreach ($searchCriteria->getFilterGroups() as $group) {
             $this->addFilterGroupToCollection($group, $attributeCollection);
         }
-        /** @var \Magento\Framework\Api\SortOrder $sortOrder */
+        /** @var SortOrder $sortOrder */
         foreach ((array)$searchCriteria->getSortOrders() as $sortOrder) {
             $attributeCollection->addOrder(
                 $sortOrder->getField(),
-                ($sortOrder->getDirection() == SearchCriteriaInterface::SORT_ASC) ? 'ASC' : 'DESC'
+                ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC'
             );
         }
 
diff --git a/app/code/Magento/Indexer/Model/Message/Invalid.php b/app/code/Magento/Indexer/Model/Message/Invalid.php
new file mode 100644
index 0000000000000000000000000000000000000000..7eed2246647258ee30760a445b96d936f6711b9c
--- /dev/null
+++ b/app/code/Magento/Indexer/Model/Message/Invalid.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Indexer\Model\Message;
+
+use Magento\Store\Model\Store;
+
+class Invalid implements \Magento\Framework\Notification\MessageInterface
+{
+    /**
+     * @var \Magento\Indexer\Model\Indexer\Collection
+     */
+    protected $collection;
+
+    /**
+     * @param \Magento\Indexer\Model\Indexer\Collection $collection
+     */
+    public function __construct(
+        \Magento\Indexer\Model\Indexer\Collection $collection
+    ) {
+        $this->collection = $collection;
+    }
+
+    /**
+     * Check whether all indices are valid or not
+     *
+     * @return bool
+     */
+    public function isDisplayed()
+    {
+        /** @var \Magento\Indexer\Model\Indexer $indexer */
+        foreach ($this->collection->getItems() as $indexer) {
+            if ($indexer->getStatus() == \Magento\Indexer\Model\Indexer\State::STATUS_INVALID) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    //@codeCoverageIgnoreStart
+    /**
+     * Retrieve unique message identity
+     *
+     * @return string
+     */
+    public function getIdentity()
+    {
+        return md5('INDEX_INVALID');
+    }
+
+    /**
+     * Retrieve message text
+     *
+     * @return \Magento\Framework\Phrase
+     */
+    public function getText()
+    {
+        // @codingStandardsIgnoreStart
+        return __('One or more of the indexers are not valid. Please add Magento cron file to crontab or launch cron.php manually.');
+        // @codingStandardsIgnoreEnd
+    }
+
+    /**
+     * Retrieve message severity
+     *
+     * @return int
+     */
+    public function getSeverity()
+    {
+        return self::SEVERITY_MAJOR;
+    }
+    //@codeCoverageIgnoreEnd
+}
diff --git a/app/code/Magento/Indexer/Test/Unit/Model/Message/InvalidTest.php b/app/code/Magento/Indexer/Test/Unit/Model/Message/InvalidTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b4d8c0152f8bb01ecf8be93e8bc47f017a19babe
--- /dev/null
+++ b/app/code/Magento/Indexer/Test/Unit/Model/Message/InvalidTest.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Indexer\Test\Unit\Model\Message;
+
+class InvalidTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Indexer\Model\Indexer
+     */
+    private $indexerMock = null;
+
+    /**
+     * @var \Magento\Indexer\Model\Message\Invalid
+     */
+    protected $model;
+
+    /**
+     * Set up test
+     */
+    protected function setUp()
+    {
+        $collectionMock = $this->getMock(
+            '\Magento\Indexer\Model\Indexer\Collection',
+            ['getItems'],
+            [],
+            '',
+            false
+        );
+
+        $this->indexerMock = $this->getMock(
+            '\Magento\Indexer\Model\Indexer',
+            ['getStatus'],
+            [],
+            '',
+            false
+        );
+
+        $collectionMock->expects($this->any())->method('getItems')->with()->willReturn([$this->indexerMock]);
+
+        $this->model = new \Magento\Indexer\Model\Message\Invalid(
+            $collectionMock
+        );
+    }
+
+    public function testDisplayMessage()
+    {
+        $this->indexerMock->expects($this->any())->method('getStatus')->with()
+            ->willReturn(\Magento\Indexer\Model\Indexer\State::STATUS_INVALID);
+
+        $this->assertTrue($this->model->isDisplayed());
+    }
+
+    public function testHideMessage()
+    {
+        $this->indexerMock->expects($this->any())->method('getStatus')->with()
+            ->willReturn('Status other than "invalid"');
+
+        $this->assertFalse($this->model->isDisplayed());
+    }
+}
diff --git a/app/code/Magento/Indexer/etc/adminhtml/di.xml b/app/code/Magento/Indexer/etc/adminhtml/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c31dc932055e9c923a6717fdc5a3dd59bbc9e9c0
--- /dev/null
+++ b/app/code/Magento/Indexer/etc/adminhtml/di.xml
@@ -0,0 +1,16 @@
+<?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\Framework\Notification\MessageList">
+        <arguments>
+            <argument name="messages" xsi:type="array">
+                <item name="indexer_invalid_message" xsi:type="string">Magento\Indexer\Model\Message\Invalid</item>
+            </argument>
+        </arguments>
+    </type>
+</config>
diff --git a/app/code/Magento/Indexer/etc/module.xml b/app/code/Magento/Indexer/etc/module.xml
index f03aca19f0cc4ce32b6ce1b4b168d3d1ab391c37..7d12e5d98535c1d04bb5ed7a7c3f8ec6eb779818 100644
--- a/app/code/Magento/Indexer/etc/module.xml
+++ b/app/code/Magento/Indexer/etc/module.xml
@@ -9,6 +9,7 @@
     <module name="Magento_Indexer" setup_version="2.0.0">
         <sequence>
             <module name="Magento_Store"/>
+            <module name="Magento_AdminNotification"/>
         </sequence>
     </module>
 </config>
diff --git a/app/code/Magento/Quote/Model/QuoteRepository.php b/app/code/Magento/Quote/Model/QuoteRepository.php
index 6fa9bca5e4e3323a886ffda19833abf2262c098b..fb0e91591e5a5b01f6f7d0d01277a0e9f826d482 100644
--- a/app/code/Magento/Quote/Model/QuoteRepository.php
+++ b/app/code/Magento/Quote/Model/QuoteRepository.php
@@ -5,15 +5,20 @@
  */
 namespace Magento\Quote\Model;
 
+use Magento\Framework\Api\SortOrder;
 use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Quote\Model\Quote;
 use Magento\Store\Model\StoreManagerInterface;
-use Magento\Framework\Api\SearchCriteria;
 use Magento\Framework\Api\Search\FilterGroup;
 use Magento\Quote\Model\Resource\Quote\Collection as QuoteCollection;
 use Magento\Framework\Exception\InputException;
 use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
 
+/**
+ * Class QuoteRepository
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class QuoteRepository implements \Magento\Quote\Api\CartRepositoryInterface
 {
     /**
@@ -220,10 +225,11 @@ class QuoteRepository implements \Magento\Quote\Api\CartRepositoryInterface
         $searchData->setTotalCount($this->quoteCollection->getSize());
         $sortOrders = $searchCriteria->getSortOrders();
         if ($sortOrders) {
+            /** @var SortOrder $sortOrder */
             foreach ($sortOrders as $sortOrder) {
                 $this->quoteCollection->addOrder(
                     $sortOrder->getField(),
-                    $sortOrder->getDirection() == SearchCriteria::SORT_ASC ? 'ASC' : 'DESC'
+                    $sortOrder->getDirection() == SortOrder::SORT_ASC ? 'ASC' : 'DESC'
                 );
             }
         }
diff --git a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php
index 04e919863d29a21a350fd731ccecfe4ed0db00ed..7955f59ebfca5d91dad96b0befd7ac0de52f73ad 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/QuoteRepositoryTest.php
@@ -9,7 +9,7 @@ namespace Magento\Quote\Test\Unit\Model;
 
 use \Magento\Quote\Model\QuoteRepository;
 
-use Magento\Framework\Api\SearchCriteria;
+use Magento\Framework\Api\SortOrder;
 use Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface;
 
 class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase
@@ -404,8 +404,8 @@ class QuoteRepositoryTest extends \PHPUnit_Framework_TestCase
     public function getListSuccessDataProvider()
     {
         return [
-            'asc' => [SearchCriteria::SORT_ASC, 'ASC'],
-            'desc' => [SearchCriteria::SORT_DESC, 'DESC']
+            'asc' => [SortOrder::SORT_ASC, 'ASC'],
+            'desc' => [SortOrder::SORT_DESC, 'DESC']
         ];
     }
 }
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Sales/Grid/Column/Renderer/Date.php b/app/code/Magento/Reports/Block/Adminhtml/Sales/Grid/Column/Renderer/Date.php
index 8b325bb2a0ad1b0a5695bf54864496effbed60ba..cda443f4c78d9b8ff2edb56bb8a1110bb8eec4f1 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Sales/Grid/Column/Renderer/Date.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Sales/Grid/Column/Renderer/Date.php
@@ -78,7 +78,7 @@ class Date extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\Date
             } else {
                 $date = $this->_localeDate->date(new \DateTime($data), null, false);
             }
-            return \IntlDateFormatter::formatObject($date, $format);
+            return \IntlDateFormatter::formatObject($date, $format, $this->_localeResolver->getLocale());
         }
         return $this->getColumn()->getDefault();
     }
diff --git a/app/code/Magento/Reports/Test/Unit/Block/Adminhtml/Sales/Grid/Column/Renderer/DateTest.php b/app/code/Magento/Reports/Test/Unit/Block/Adminhtml/Sales/Grid/Column/Renderer/DateTest.php
index 6252d53d0382924f42e5af294791de18e333c88a..1ceb4a5caefde0d1392894fce17f1d28df63bbfd 100644
--- a/app/code/Magento/Reports/Test/Unit/Block/Adminhtml/Sales/Grid/Column/Renderer/DateTest.php
+++ b/app/code/Magento/Reports/Test/Unit/Block/Adminhtml/Sales/Grid/Column/Renderer/DateTest.php
@@ -30,6 +30,44 @@ class DateTest extends \PHPUnit_Framework_TestCase
      */
     protected $localeDate;
 
+    /**
+     * @var string
+     */
+    private $globalStateLocaleBackup;
+
+    /**
+     * @param string $locale
+     */
+    private function mockGridDateRendererBehaviorWithLocale($locale)
+    {
+        $this->resolverMock->expects($this->any())->method('getLocale')->willReturn($locale);
+        $this->localeDate->expects($this->any())->method('getDateFormat')->willReturnCallback(
+            function ($value) use ($locale) {
+                return (new \IntlDateFormatter(
+                    $locale,
+                    $value,
+                    \IntlDateFormatter::NONE
+                ))->getPattern();
+            }
+        );
+    }
+
+    /**
+     * @param string $objectDataIndex
+     * @param string $periodType
+     */
+    private function mockGridDateColumnConfig($objectDataIndex, $periodType)
+    {
+        $columnMock = $this->getMockBuilder('Magento\Backend\Block\Widget\Grid\Column')
+            ->disableOriginalConstructor()
+            ->setMethods(['getIndex', 'getPeriodType'])
+            ->getMock();
+        $columnMock->expects($this->once())->method('getIndex')->willReturn($objectDataIndex);
+        $columnMock->expects($this->atLeastOnce())->method('getPeriodType')->willReturn($periodType);
+
+        $this->date->setColumn($columnMock);
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -41,7 +79,7 @@ class DateTest extends \PHPUnit_Framework_TestCase
         $this->localeDate
             ->expects($this->once())
             ->method('date')
-            ->will($this->returnArgument(0));
+            ->willReturnArgument(0);
 
         $this->contextMock = $this->getMockBuilder('Magento\Backend\Block\Context')
             ->disableOriginalConstructor()
@@ -49,7 +87,7 @@ class DateTest extends \PHPUnit_Framework_TestCase
         $this->contextMock
             ->expects($this->once())
             ->method('getLocaleDate')
-            ->will($this->returnValue($this->localeDate));
+            ->willReturn($this->localeDate);
 
         $this->resolverMock = $this->getMockBuilder('Magento\Framework\Locale\ResolverInterface')
             ->getMock();
@@ -58,43 +96,41 @@ class DateTest extends \PHPUnit_Framework_TestCase
             $this->contextMock,
             $this->resolverMock
         );
+        
+        $this->globalStateLocaleBackup = \Locale::getDefault();
+    }
+
+    protected function tearDown()
+    {
+        $this->restoreTheDefaultLocaleGlobalState();
+    }
+
+    private function restoreTheDefaultLocaleGlobalState()
+    {
+        if (\Locale::getDefault() !== $this->globalStateLocaleBackup) {
+            \Locale::setDefault($this->globalStateLocaleBackup);
+        }
     }
 
     /**
      * @param string $data
-     * @param string $index
      * @param string $locale
+     * @param string $index
      * @param string $period
      * @param string $result
      * @dataProvider datesDataProvider
      * @return void
      */
-    public function testRender($data, $index, $locale, $period, $result)
+    public function testRender($data, $locale, $index, $period, $result)
     {
-        $this->resolverMock->expects($this->any())->method('getLocale')->will($this->returnValue($locale));
-        $this->localeDate->expects($this->any())->method('getDateFormat')->willReturnCallback(
-            function ($value) use ($locale) {
-                return (new \IntlDateFormatter(
-                    $locale,
-                    $value,
-                    \IntlDateFormatter::NONE
-                ))->getPattern();
-            }
-        );
+        $this->mockGridDateRendererBehaviorWithLocale($locale);
+        $this->mockGridDateColumnConfig($index, $period);
 
         $objectMock = $this->getMockBuilder('Magento\Framework\Object')
             ->setMethods(['getData'])
             ->getMock();
-        $objectMock->expects($this->once())->method('getData')->will($this->returnValue($data));
-
-        $columnMock = $this->getMockBuilder('Magento\Backend\Block\Widget\Grid\Column')
-            ->disableOriginalConstructor()
-            ->setMethods(['getIndex', 'getPeriodType'])
-            ->getMock();
-        $columnMock->expects($this->once())->method('getIndex')->will($this->returnValue($index));
-        $columnMock->expects($this->atLeastOnce())->method('getPeriodType')->will($this->returnValue($period));
+        $objectMock->expects($this->once())->method('getData')->willReturn($data);
 
-        $this->date->setColumn($columnMock);
 
         $this->assertEquals($result, $this->date->render($objectMock));
     }
@@ -107,39 +143,53 @@ class DateTest extends \PHPUnit_Framework_TestCase
         return [
             [
                 'data' => '2000',
-                'index' => 'period',
                 'locale' => 'en_US',
+                'index' => 'period',
                 'period' => 'year',
                 'result' => '2000'
             ],
             [
                 'data' => '2030',
-                'index' => 'period',
                 'locale' => 'en_US',
+                'index' => 'period',
                 'period' => 'year',
                 'result' => '2030'
             ],
             [
                 'data' => '2000-01',
-                'index' => 'period',
                 'locale' => 'en_US',
+                'index' => 'period',
                 'period' => 'month',
                 'result' => '1/2000'
             ],
             [
                 'data' => '2030-12',
-                'index' => 'period',
                 'locale' => 'en_US',
+                'index' => 'period',
                 'period' => 'month',
                 'result' => '12/2030'
             ],
             [
                 'data' => '2014-06-25',
-                'index' => 'period',
                 'locale' => 'en_US',
+                'index' => 'period',
                 'period' => 'day',
                 'result' => 'Jun 25, 2014'
             ]
         ];
     }
+
+    public function testDateIsRenderedIndependentOfSystemDefaultLocale()
+    {
+        \Locale::setDefault('de_DE');
+        $this->mockGridDateRendererBehaviorWithLocale('en_US');
+        $this->mockGridDateColumnConfig('period', 'day');
+
+        $objectMock = $this->getMockBuilder('Magento\Framework\Object')
+            ->setMethods(['getData'])
+            ->getMock();
+        $objectMock->expects($this->any())->method('getData')->willReturn('2014-06-25');
+        
+        $this->assertEquals('Jun 25, 2014', $this->date->render($objectMock));
+    }
 }
diff --git a/app/code/Magento/Tax/Model/Calculation/RateRepository.php b/app/code/Magento/Tax/Model/Calculation/RateRepository.php
index d124469768d16ba5a596c80e87a189f70cb94ce0..c1ac30fd9adadc68528d48df01890ec0f9b6b5ed 100644
--- a/app/code/Magento/Tax/Model/Calculation/RateRepository.php
+++ b/app/code/Magento/Tax/Model/Calculation/RateRepository.php
@@ -10,11 +10,9 @@ namespace Magento\Tax\Model\Calculation;
 use Magento\Directory\Model\CountryFactory;
 use Magento\Directory\Model\RegionFactory;
 use Magento\Framework\Api\Search\FilterGroup;
-use Magento\Framework\Api\SearchCriteria;
 use Magento\Framework\Api\SortOrder;
 use Magento\Framework\Exception\InputException;
 use Magento\Framework\Exception\LocalizedException;
-use Magento\Framework\Exception\AlreadyExistsException;
 use Magento\Tax\Model\Calculation\Rate;
 use Magento\Tax\Model\Calculation\Rate\Converter;
 use Magento\Tax\Model\Resource\Calculation\Rate\Collection;
@@ -168,7 +166,7 @@ class RateRepository implements \Magento\Tax\Api\TaxRateRepositoryInterface
             foreach ($sortOrders as $sortOrder) {
                 $collection->addOrder(
                     $this->translateField($sortOrder->getField()),
-                    ($sortOrder->getDirection() == SearchCriteria::SORT_ASC) ? 'ASC' : 'DESC'
+                    ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC'
                 );
             }
         }
diff --git a/app/code/Magento/Tax/Model/TaxClass/Repository.php b/app/code/Magento/Tax/Model/TaxClass/Repository.php
index 54b92c00c6633d82065d21e342ebe081eba192fc..db2e8812f0ffd9d2a3496774587577c0dbb9a17b 100644
--- a/app/code/Magento/Tax/Model/TaxClass/Repository.php
+++ b/app/code/Magento/Tax/Model/TaxClass/Repository.php
@@ -9,7 +9,6 @@ namespace Magento\Tax\Model\TaxClass;
 
 use Magento\Framework\Api\FilterBuilder;
 use Magento\Framework\Api\Search\FilterGroup;
-use Magento\Framework\Api\SearchCriteria;
 use Magento\Framework\Api\SearchCriteriaBuilder;
 use Magento\Framework\Api\SortOrder;
 use Magento\Framework\Exception\CouldNotDeleteException;
@@ -214,7 +213,7 @@ class Repository implements \Magento\Tax\Api\TaxClassRepositoryInterface
             foreach ($searchCriteria->getSortOrders() as $sortOrder) {
                 $collection->addOrder(
                     $sortOrder->getField(),
-                    ($sortOrder->getDirection() == SearchCriteria::SORT_ASC) ? 'ASC' : 'DESC'
+                    ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC'
                 );
             }
         }
diff --git a/app/code/Magento/Tax/Model/TaxRuleRepository.php b/app/code/Magento/Tax/Model/TaxRuleRepository.php
index 28ff8015b9a66581f310fa30588f5195185fd5a6..fed8cdb44ec6c9f134c1d20252096bc16c16e50f 100644
--- a/app/code/Magento/Tax/Model/TaxRuleRepository.php
+++ b/app/code/Magento/Tax/Model/TaxRuleRepository.php
@@ -7,7 +7,6 @@
 namespace Magento\Tax\Model;
 
 use Magento\Framework\Api\Search\FilterGroup;
-use Magento\Framework\Api\SearchCriteria;
 use Magento\Framework\Api\SortOrder;
 use Magento\Framework\Exception\LocalizedException;
 use Magento\Framework\Exception\CouldNotSaveException;
@@ -163,7 +162,7 @@ class TaxRuleRepository implements TaxRuleRepositoryInterface
             foreach ($sortOrders as $sortOrder) {
                 $collection->addOrder(
                     $this->translateField($sortOrder->getField()),
-                    ($sortOrder->getDirection() == SearchCriteria::SORT_ASC) ? 'ASC' : 'DESC'
+                    ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC'
                 );
             }
         }
diff --git a/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php b/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php
index f2d8b4b17d1646147e9143c797e83f8041f3102b..0a3c7d8f35ec427290b8df206d38caa221124ace 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/Calculation/RateRepositoryTest.php
@@ -5,9 +5,9 @@
  */
 namespace Magento\Tax\Test\Unit\Model\Calculation;
 
+use Magento\Framework\Api\SortOrder;
 use \Magento\Tax\Model\Calculation\RateRepository;
 
-use Magento\Framework\Api\SearchCriteria;
 use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
 use Magento\Framework\Exception\LocalizedException;
 use Magento\Framework\Exception\AlreadyExistsException;
@@ -391,7 +391,7 @@ class RateRepositoryTest extends \PHPUnit_Framework_TestCase
             ->method('getSortOrders')
             ->will($this->returnValue([$sortOrderMock]));
         $sortOrderMock->expects($this->once())->method('getField')->willReturn('field_name');
-        $sortOrderMock->expects($this->once())->method('getDirection')->willReturn(SearchCriteria::SORT_ASC);
+        $sortOrderMock->expects($this->once())->method('getDirection')->willReturn(SortOrder::SORT_ASC);
         $collectionMock->expects($this->once())->method('addOrder')->with('main_table.field_name', 'ASC');
         $currentPage = 1;
         $pageSize = 100;
diff --git a/app/code/Magento/Tax/Test/Unit/Model/TaxClass/RepositoryTest.php b/app/code/Magento/Tax/Test/Unit/Model/TaxClass/RepositoryTest.php
index 277c10f7b2bfc134abe0fc2485c269316831a429..1acb45c2c905ff0af913231431d82dc02e44dce4 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/TaxClass/RepositoryTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/TaxClass/RepositoryTest.php
@@ -6,11 +6,11 @@
 
 namespace Magento\Tax\Test\Unit\Model\TaxClass;
 
+use Magento\Framework\Api\SortOrder;
 use \Magento\Tax\Model\TaxClass\Repository;
 
 use Magento\Framework\Exception\CouldNotDeleteException;
 use Magento\Framework\Exception\LocalizedException;
-use Magento\Framework\Api\SearchCriteria;
 
 class RepositoryTest extends \PHPUnit_Framework_TestCase
 {
@@ -215,7 +215,7 @@ class RepositoryTest extends \PHPUnit_Framework_TestCase
 
         $searchCriteria->expects($this->exactly(2))->method('getSortOrders')->willReturn([$sortOrder]);
         $sortOrder->expects($this->once())->method('getField')->willReturn('field');
-        $sortOrder->expects($this->once())->method('getDirection')->willReturn(SearchCriteria::SORT_ASC);
+        $sortOrder->expects($this->once())->method('getDirection')->willReturn(SortOrder::SORT_ASC);
         $collection->expects($this->once())->method('addOrder')->with('field', 'ASC');
         $searchCriteria->expects($this->once())->method('getPageSize')->willReturn(20);
         $searchCriteria->expects($this->once())->method('getCurrentPage')->willReturn(0);
diff --git a/app/code/Magento/Tax/Test/Unit/Model/TaxRuleRepositoryTest.php b/app/code/Magento/Tax/Test/Unit/Model/TaxRuleRepositoryTest.php
index 3225be5242f8ace8b4e4bece353df61c02a8bb78..91d6309e8c599873b9f4b4a43765225dc68ff781 100644
--- a/app/code/Magento/Tax/Test/Unit/Model/TaxRuleRepositoryTest.php
+++ b/app/code/Magento/Tax/Test/Unit/Model/TaxRuleRepositoryTest.php
@@ -5,10 +5,9 @@
  */
 namespace Magento\Tax\Test\Unit\Model;
 
+use Magento\Framework\Api\SortOrder;
 use \Magento\Tax\Model\TaxRuleRepository;
 
-use Magento\Framework\Api\SearchCriteria as SearchCriteria;
-
 class TaxRuleRepositoryTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -215,7 +214,7 @@ class TaxRuleRepositoryTest extends \PHPUnit_Framework_TestCase
         $this->searchResultsMock->expects($this->once())->method('setTotalCount')->with($collectionSize);
         $searchCriteriaMock->expects($this->once())->method('getSortOrders')->willReturn([$sortOrderMock]);
         $sortOrderMock->expects($this->once())->method('getField')->willReturn('sort_order');
-        $sortOrderMock->expects($this->once())->method('getDirection')->willReturn(SearchCriteria::SORT_ASC);
+        $sortOrderMock->expects($this->once())->method('getDirection')->willReturn(SortOrder::SORT_ASC);
         $collectionMock->expects($this->once())->method('addOrder')->with('position', 'ASC');
         $searchCriteriaMock->expects($this->once())->method('getCurrentPage')->willReturn($currentPage);
         $collectionMock->expects($this->once())->method('setCurPage')->with($currentPage);
diff --git a/app/code/Magento/Ui/Model/Resource/BookmarkRepository.php b/app/code/Magento/Ui/Model/Resource/BookmarkRepository.php
index 8b20d86baa29da83795e5bf52342707c0f78dd0e..6420a85da9a90448cee78a347ba9ccd143ce524d 100644
--- a/app/code/Magento/Ui/Model/Resource/BookmarkRepository.php
+++ b/app/code/Magento/Ui/Model/Resource/BookmarkRepository.php
@@ -6,6 +6,7 @@
 namespace Magento\Ui\Model\Resource;
 
 use Magento\Framework\Api\SearchCriteriaInterface;
+use Magento\Framework\Api\SortOrder;
 use Magento\Ui\Api\BookmarkRepositoryInterface;
 use Magento\Framework\Api\Search\FilterGroup;
 use Magento\Ui\Api\Data\BookmarkInterface;
@@ -107,11 +108,12 @@ class BookmarkRepository implements BookmarkRepositoryInterface
         $searchResults->setTotalCount($collection->getSize());
         $sortOrders = $searchCriteria->getSortOrders();
         if ($sortOrders) {
+            /** @var SortOrder $sortOrder */
             foreach ($sortOrders as $sortOrder) {
                 $field = $sortOrder->getField();
                 $collection->addOrder(
                     $field,
-                    ($sortOrder->getDirection() == SearchCriteriaInterface::SORT_ASC) ? 'ASC' : 'DESC'
+                    ($sortOrder->getDirection() == SortOrder::SORT_ASC) ? 'ASC' : 'DESC'
                 );
             }
         }
diff --git a/app/design/frontend/Magento/luma/i18n/en_US.csv b/app/design/frontend/Magento/luma/i18n/en_US.csv
index c407d6608c877cd7d8efd758671e14fe2ed2cc34..26d45f7795b93d63ad6db5f250c58300da982781 100644
--- a/app/design/frontend/Magento/luma/i18n/en_US.csv
+++ b/app/design/frontend/Magento/luma/i18n/en_US.csv
@@ -5,8 +5,6 @@
 "Items %1-%2 of %3","%3 items"
 "Regular Price", "was"
 "Shop By","Filter"
-"select all", "Add all"
-"unselect all", "Select none"
 "Remove item", "Remove"
 "Proceed to Checkout", "Go to Checkout"
 "Grand Total", "Estimated Total"
diff --git a/dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerRepositoryTest.php
index 8b357da784ba43f4cba6e2182500ef4e0bee59c6..36af26d2dedbe39b73cb844af0d0301ab937ce62 100644
--- a/dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerRepositoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerRepositoryTest.php
@@ -6,7 +6,7 @@
 namespace Magento\Customer\Api;
 
 use Magento\Customer\Api\Data\CustomerInterface as Customer;
-use Magento\Framework\Api\SearchCriteria;
+use Magento\Framework\Api\SortOrder;
 use Magento\Framework\Exception\InputException;
 use Magento\TestFramework\Helper\Bootstrap;
 use Magento\TestFramework\Helper\Customer as CustomerHelper;
@@ -458,8 +458,8 @@ class CustomerRepositoryTest extends WebapiAbstract
         $sortOrderBuilder = Bootstrap::getObjectManager()->create(
             'Magento\Framework\Api\SortOrderBuilder'
         );
-        /** @var \Magento\Framework\Api\SortOrder $sortOrder */
-        $sortOrder = $sortOrderBuilder->setField(Customer::EMAIL)->setDirection(SearchCriteria::SORT_ASC)->create();
+        /** @var SortOrder $sortOrder */
+        $sortOrder = $sortOrderBuilder->setField(Customer::EMAIL)->setDirection(SortOrder::SORT_ASC)->create();
         $this->searchCriteriaBuilder->setSortOrders([$sortOrder]);
 
         $searchCriteria = $this->searchCriteriaBuilder->create();
@@ -502,7 +502,7 @@ class CustomerRepositoryTest extends WebapiAbstract
             ->create();
         $this->searchCriteriaBuilder->addFilters([$filter1, $filter2]);
         $this->searchCriteriaBuilder->addFilters([$filter3]);
-        $this->searchCriteriaBuilder->setSortOrders([Customer::EMAIL => SearchCriteria::SORT_ASC]);
+        $this->searchCriteriaBuilder->setSortOrders([Customer::EMAIL => SortOrder::SORT_ASC]);
         $searchCriteria = $this->searchCriteriaBuilder->create();
         $searchData = $searchCriteria->__toArray();
         $requestData = ['searchCriteria' => $searchData];
diff --git a/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartRepositoryTest.php
index 7c9661e471e94993b8a4a6db637832b4c4e886a9..cb1e3c50a59d494676b209b10717aaff492dc7c2 100644
--- a/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartRepositoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Quote/Api/CartRepositoryTest.php
@@ -6,7 +6,6 @@
 namespace Magento\Quote\Api;
 
 use Magento\Framework\Api\FilterBuilder;
-use Magento\Framework\Api\SearchCriteria;
 use Magento\Framework\Api\SearchCriteriaBuilder;
 use Magento\Framework\Api\SortOrderBuilder;
 use Magento\Framework\Api\SortOrder;
@@ -178,10 +177,9 @@ class CartRepositoryTest extends WebapiAbstract
         $this->searchCriteriaBuilder->addFilters([$minCreatedAtFilter]);
         $this->searchCriteriaBuilder->addFilters([$maxCreatedAtFilter]);
         /** @var SortOrder $sortOrder */
-        $sortOrder = $this->sortOrderBuilder->setField('subtotal')->setDirection(SearchCriteria::SORT_ASC)->create();
+        $sortOrder = $this->sortOrderBuilder->setField('subtotal')->setDirection(SortOrder::SORT_ASC)->create();
         $this->searchCriteriaBuilder->setSortOrders([$sortOrder]);
         $searchCriteria = $this->searchCriteriaBuilder->create()->__toArray();
-
         $requestData = ['searchCriteria' => $searchCriteria];
         $serviceInfo = [
             'rest' => [
diff --git a/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRateRepositoryTest.php b/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRateRepositoryTest.php
index 5b42630456d992949115670a4ddd17b48c075624..d7c9c9e4260ce8704d9f07ae488b1450a280337f 100644
--- a/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRateRepositoryTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Tax/Api/TaxRateRepositoryTest.php
@@ -7,8 +7,8 @@
 namespace Magento\Tax\Api;
 
 use Magento\Framework\Api\FilterBuilder;
-use Magento\Framework\Api\SearchCriteria;
 use Magento\Framework\Api\SearchCriteriaBuilder;
+use Magento\Framework\Api\SortOrder;
 use Magento\Framework\Api\SortOrderBuilder;
 use Magento\Tax\Model\Calculation\Rate;
 use Magento\TestFramework\Helper\Bootstrap;
@@ -485,7 +485,7 @@ class TaxRateRepositoryTest extends WebapiAbstract
             ->create();
         $sortOrder = $this->sortOrderBuilder
             ->setField(Rate::KEY_POSTCODE)
-            ->setDirection(SearchCriteria::SORT_DESC)
+            ->setDirection(SortOrder::SORT_DESC)
             ->create();
         // Order them by descending postcode (not the default order)
         $this->searchCriteriaBuilder->addFilters([$filter])
diff --git a/dev/tests/api-functional/testsuite/Magento/Webapi/JoinDirectivesTest.php b/dev/tests/api-functional/testsuite/Magento/Webapi/JoinDirectivesTest.php
index 264dad8ab6b66c46a990491398e586cfa4761f0c..74bf7687e0e9ebb5b13c554f0c0f7e1a312e6c19 100644
--- a/dev/tests/api-functional/testsuite/Magento/Webapi/JoinDirectivesTest.php
+++ b/dev/tests/api-functional/testsuite/Magento/Webapi/JoinDirectivesTest.php
@@ -49,7 +49,7 @@ class JoinDirectivesTest extends \Magento\TestFramework\TestCase\WebapiAbstract
     public function testGetList()
     {
         /** @var SortOrder $sortOrder */
-        $sortOrder = $this->sortOrderBuilder->setField('store_id')->setDirection(SearchCriteria::SORT_ASC)->create();
+        $sortOrder = $this->sortOrderBuilder->setField('store_id')->setDirection(SortOrder::SORT_ASC)->create();
         $this->searchBuilder->setSortOrders([$sortOrder]);
         $searchCriteria = $this->searchBuilder->create()->__toArray();
         $requestData = ['searchCriteria' => $searchCriteria];
@@ -87,7 +87,7 @@ class JoinDirectivesTest extends \Magento\TestFramework\TestCase\WebapiAbstract
     {
         $this->getExpectedExtensionAttributes();
         /** @var SortOrder $sortOrder */
-        $sortOrder = $this->sortOrderBuilder->setField('store_id')->setDirection(SearchCriteria::SORT_ASC)->create();
+        $sortOrder = $this->sortOrderBuilder->setField('store_id')->setDirection(SortOrder::SORT_ASC)->create();
         $this->searchBuilder->setSortOrders([$sortOrder]);
         $this->searchBuilder->addFilters([$this->filterBuilder->setField('state')->setValue(2)->create()]);
         $searchCriteria = $this->searchBuilder->create()->__toArray();
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/Dashboard.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/Dashboard.xml
index b7f64e34db13d794af6e7c689ccb905178cf1741..cd846dd75323040300dbfcb94b91e37bc66a8f30 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/Dashboard.xml
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/Dashboard.xml
@@ -14,5 +14,6 @@
         <block name="storeStatsBlock" class="Magento\Backend\Test\Block\Dashboard\StoreStats" locator=".dashboard-store-stats" strategy="css selector" />
         <block name="errorBlock" class="Magento\Backend\Test\Block\Page\Error" locator="[id='page:main-container']" strategy="css selector" />
         <block name="accessDeniedBlock" class="Magento\Backend\Test\Block\Denied" locator="#anchor-content" strategy="css selector" />
+        <block name="systemMessageDialog" class="Magento\AdminNotification\Test\Block\System\Messages" locator='[role="dialog"].ui-popup-message' strategy="css selector" />
     </page>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php
index de73873c4950e1f611ff7ba3e33a72fac1e88f3d..d26b1e05c6ff930debdf451262c190eefd8af4f4 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LoginUserOnBackendStep.php
@@ -9,6 +9,7 @@ namespace Magento\User\Test\TestStep;
 use Magento\Backend\Test\Page\AdminAuthLogin;
 use Magento\Mtf\TestStep\TestStepInterface;
 use Magento\User\Test\Fixture\User;
+use Magento\Backend\Test\Page\Adminhtml\Dashboard;
 
 /**
  * Login user on backend.
@@ -36,20 +37,30 @@ class LoginUserOnBackendStep implements TestStepInterface
      */
     protected $user;
 
+    /**
+     * Dashboard backend page.
+     *
+     * @var Dashboard
+     */
+    protected $dashboard;
+
     /**
      * @constructor
      * @param LogoutUserOnBackendStep $logoutUserOnBackendStep
      * @param AdminAuthLogin $adminAuth
      * @param User $user
+     * @param Dashboard $dashboard
      */
     public function __construct(
         LogoutUserOnBackendStep $logoutUserOnBackendStep,
         AdminAuthLogin $adminAuth,
-        User $user
+        User $user,
+        Dashboard $dashboard
     ) {
         $this->logoutUserOnBackendStep = $logoutUserOnBackendStep;
         $this->adminAuth = $adminAuth;
         $this->user = $user;
+        $this->dashboard = $dashboard;
     }
 
     /**
@@ -65,5 +76,7 @@ class LoginUserOnBackendStep implements TestStepInterface
         $this->adminAuth->getLoginBlock()->fill($this->user);
         $this->adminAuth->getLoginBlock()->submit();
         $this->adminAuth->getLoginBlock()->waitFormNotVisible();
+
+        $this->dashboard->getSystemMessageDialog()->closePopup();
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LogoutUserOnBackendStep.php b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LogoutUserOnBackendStep.php
index cf3227fafecbabb0a89ef565a67aaa430711170c..8b79ba84b485ec46c5785ed66b92a9a38678396e 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LogoutUserOnBackendStep.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestStep/LogoutUserOnBackendStep.php
@@ -48,6 +48,9 @@ class LogoutUserOnBackendStep implements TestStepInterface
     public function run()
     {
         $this->adminAuth->open();
+
+        $this->dashboard->getSystemMessageDialog()->closePopup();
+
         if ($this->dashboard->getAdminPanelHeader()->isVisible()) {
             $this->dashboard->getAdminPanelHeader()->logOut();
         }
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/AddressRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/AddressRepositoryTest.php
index a7fa061cad20519ebaef5b64f6beebe6f9f07ea6..fb917f1aaffc7f4ea5e3b28d1ace94201b2e8621 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/AddressRepositoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/AddressRepositoryTest.php
@@ -7,7 +7,7 @@
 namespace Magento\Customer\Model\Resource;
 
 use Magento\Customer\Api\AddressRepositoryInterface;
-use Magento\Framework\Api\SearchCriteriaInterface;
+use Magento\Framework\Api\SortOrder;
 use Magento\Framework\Exception\InputException;
 use Magento\Framework\Exception\NoSuchEntityException;
 
@@ -375,8 +375,8 @@ class AddressRepositoryTest extends \PHPUnit_Framework_TestCase
                 [$filterBuilder->setField('firstname')->setValue('John')->create()],
                 null,
                 [
-                    $orderBuilder->setField('firstname')->setDirection(SearchCriteriaInterface::SORT_DESC)->create(),
-                    $orderBuilder->setField('city')->setDirection(SearchCriteriaInterface::SORT_ASC)->create(),
+                    $orderBuilder->setField('firstname')->setDirection(SortOrder::SORT_DESC)->create(),
+                    $orderBuilder->setField('city')->setDirection(SortOrder::SORT_ASC)->create(),
                 ],
                 [
                     ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'],
@@ -390,7 +390,7 @@ class AddressRepositoryTest extends \PHPUnit_Framework_TestCase
                     $filterBuilder->setField('postcode')->setValue('47676')->create(),
                 ],
                 [
-                    $orderBuilder->setField('city')->setDirection(SearchCriteriaInterface::SORT_DESC)->create(),
+                    $orderBuilder->setField('city')->setDirection(SortOrder::SORT_DESC)->create(),
                 ],
                 [
                     ['id' => 2, 'city' => 'CityX', 'postcode' => 47676, 'firstname' => 'John'],
@@ -401,8 +401,8 @@ class AddressRepositoryTest extends \PHPUnit_Framework_TestCase
                 [$filterBuilder->setField('postcode')->setValue('0')->setConditionType('gt')->create()],
                 null,
                 [
-                    $orderBuilder->setField('firstname')->setDirection(SearchCriteriaInterface::SORT_ASC)->create(),
-                    $orderBuilder->setField('postcode')->setDirection(SearchCriteriaInterface::SORT_ASC)->create(),
+                    $orderBuilder->setField('firstname')->setDirection(SortOrder::SORT_ASC)->create(),
+                    $orderBuilder->setField('postcode')->setDirection(SortOrder::SORT_ASC)->create(),
                 ],
                 [
                     ['id' => 2, 'city' => 'CityX', 'postcode' => 47676, 'firstname' => 'John'],
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/CustomerRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/CustomerRepositoryTest.php
index e73d1a170b74831ea888eefa3e80550523f62c42..16a007272c94fe8e15144fc9b9c6c504523c5c6a 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/CustomerRepositoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/CustomerRepositoryTest.php
@@ -8,7 +8,7 @@ namespace Magento\Customer\Model\Resource;
 
 use Magento\Customer\Api\AccountManagementInterface;
 use Magento\Customer\Api\CustomerRepositoryInterface;
-use Magento\Framework\Api\SearchCriteriaInterface;
+use Magento\Framework\Api\SortOrder;
 use Magento\TestFramework\Helper\Bootstrap;
 
 /**
@@ -343,7 +343,7 @@ class CustomerRepositoryTest extends \PHPUnit_Framework_TestCase
         $sortOrderBuilder = $objectManager->create('Magento\Framework\Api\SortOrderBuilder');
         $sortOrder = $sortOrderBuilder
             ->setField('lastname')
-            ->setDirection(SearchCriteriaInterface::SORT_ASC)
+            ->setDirection(SortOrder::SORT_ASC)
             ->create();
         $searchBuilder->addSortOrder($sortOrder);
         $searchResults = $this->customerRepository->getList($searchBuilder->create());
@@ -355,7 +355,7 @@ class CustomerRepositoryTest extends \PHPUnit_Framework_TestCase
         // Search descending order
         $sortOrder = $sortOrderBuilder
             ->setField('lastname')
-            ->setDirection(SearchCriteriaInterface::SORT_DESC)
+            ->setDirection(SortOrder::SORT_DESC)
             ->create();
         $searchBuilder->addSortOrder($sortOrder);
         $searchResults = $this->customerRepository->getList($searchBuilder->create());
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/GroupRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/GroupRepositoryTest.php
index 90480ef34222fefeaf654d1e3591a5bea160f142..40e660da0c658cd55196e4be633e0ee56bb059c2 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/GroupRepositoryTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Model/Resource/GroupRepositoryTest.php
@@ -7,7 +7,7 @@
 namespace Magento\Customer\Model\Resource;
 
 use Magento\Customer\Api\Data\GroupInterface;
-use Magento\Framework\Api\SearchCriteria;
+use Magento\Framework\Api\SortOrder;
 
 /**
  * Integration test for \Magento\Customer\Model\Resource\GroupRepository
@@ -23,7 +23,7 @@ class GroupRepositoryTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Framework\ObjectManagerInterface */
     private $objectManager;
 
-    /** @var \Magento\Customer\Model\Data\GroupInterfaceFactory */
+    /** @var \Magento\Customer\Api\Data\GroupInterfaceFactory */
     private $groupFactory;
 
     /** @var  \Magento\Framework\Api\SearchCriteriaBuilder */
@@ -281,9 +281,9 @@ class GroupRepositoryTest extends \PHPUnit_Framework_TestCase
      */
     public function testGetListSortOrder($field, $direction, $methodName, $expectedResult)
     {
-        /** @var \Magento\Framework\Api\SortOrder $sortOrder */
+        /** @var SortOrder $sortOrder */
         /** @var string $direction */
-        $direction = ($direction == 'ASC') ? SearchCriteria::SORT_ASC : SearchCriteria::SORT_DESC;
+        $direction = ($direction == 'ASC') ? SortOrder::SORT_ASC : SortOrder::SORT_DESC;
         $sortOrder = $this->sortOrderBuilder->setField($field)->setDirection($direction)->create();
         $this->searchCriteriaBuilder->addSortOrder($sortOrder);
 
diff --git a/lib/internal/Magento/Framework/Api/AbstractServiceCollection.php b/lib/internal/Magento/Framework/Api/AbstractServiceCollection.php
index 06ebb9d08e76f8867a4c95b8d2e48713080eb070..a834a2151282e11a0544258b39a1ae996a138dff 100644
--- a/lib/internal/Magento/Framework/Api/AbstractServiceCollection.php
+++ b/lib/internal/Magento/Framework/Api/AbstractServiceCollection.php
@@ -137,9 +137,9 @@ abstract class AbstractServiceCollection extends \Magento\Framework\Data\Collect
             $this->searchCriteriaBuilder->addFilters($filterGroup);
         }
         foreach ($this->_orders as $field => $direction) {
-            /** @var \Magento\Framework\Api\SortOrder $sortOrder */
+            /** @var SortOrder $sortOrder */
             /** @var string $direction */
-            $direction = ($direction == 'ASC') ? SearchCriteria::SORT_ASC : SearchCriteria::SORT_DESC;
+            $direction = ($direction == 'ASC') ? SortOrder::SORT_ASC : SortOrder::SORT_DESC;
             $sortOrder = $this->sortOrderBuilder->setField($field)->setDirection($direction)->create();
             $this->searchCriteriaBuilder->addSortOrder($sortOrder);
         }
diff --git a/lib/internal/Magento/Framework/Api/SearchCriteriaInterface.php b/lib/internal/Magento/Framework/Api/SearchCriteriaInterface.php
index 2ab64059748ed7707ba6521117a6c870e5ac8896..e520a58658fb26697e5cc80b68fc11ce70b4d15f 100644
--- a/lib/internal/Magento/Framework/Api/SearchCriteriaInterface.php
+++ b/lib/internal/Magento/Framework/Api/SearchCriteriaInterface.php
@@ -13,9 +13,6 @@ namespace Magento\Framework\Api;
  */
 interface SearchCriteriaInterface
 {
-    const SORT_ASC = 1;
-    const SORT_DESC = -1;
-
     /**
      * Get a list of filter groups.
      *
diff --git a/lib/internal/Magento/Framework/Api/SortOrder.php b/lib/internal/Magento/Framework/Api/SortOrder.php
index f328b93aa176399e1673206e4e58a0935d10d324..209ee8c13e5fd52714d4a39c45c4e8d9badfe131 100644
--- a/lib/internal/Magento/Framework/Api/SortOrder.php
+++ b/lib/internal/Magento/Framework/Api/SortOrder.php
@@ -6,14 +6,32 @@
 
 namespace Magento\Framework\Api;
 
+use Magento\Framework\Exception\InputException;
+use Magento\Framework\Phrase;
+
 /**
  * Data object for sort order.
- * @codeCoverageIgnore
  */
 class SortOrder extends AbstractSimpleObject
 {
     const FIELD = 'field';
     const DIRECTION = 'direction';
+    const SORT_ASC = 'ASC';
+    const SORT_DESC = 'DESC';
+
+    /**
+     * Initialize object and validate sort direction
+     *
+     * @param array $data
+     */
+    public function __construct(array $data = [])
+    {
+        parent::__construct($data);
+        if (null !== $this->getDirection()) {
+            $this->validateDirection($this->getDirection());
+        }
+    }
+
 
     /**
      * Get sorting field.
@@ -54,6 +72,60 @@ class SortOrder extends AbstractSimpleObject
      */
     public function setDirection($direction)
     {
-        return $this->setData(SortOrder::DIRECTION, $direction);
+        $this->validateDirection($direction);
+        return $this->setData(SortOrder::DIRECTION, $this->normalizeDirectionInput($direction));
+    }
+
+    /**
+     * Validate direction argument ASC or DESC
+     * 
+     * @param mixed $direction
+     * @return null
+     * @throws InputException
+     */
+    private function validateDirection($direction)
+    {
+        $this->validateDirectionIsString($direction);
+        $this->validateDirectionIsAscOrDesc($direction);
+    }
+
+    /**
+     * @param string $direction
+     * @throws InputException
+     * @return null
+     */
+    private function validateDirectionIsString($direction)
+    {
+        if (!is_string($direction)) {
+            throw new InputException(new Phrase(
+                'The sort order has to be specified as a string, got %1.',
+                [gettype($direction)]
+            ));
+        }
+    }
+
+    /**
+     * @param string $direction
+     * @throws InputException
+     * @return null
+     */
+    private function validateDirectionIsAscOrDesc($direction)
+    {
+        $normalizedDirection = $this->normalizeDirectionInput($direction);
+        if (!in_array($normalizedDirection, [SortOrder::SORT_ASC, SortOrder::SORT_DESC], true)) {
+            throw new InputException(new Phrase(
+                'The sort order has to be specified as %1 for ascending order or %2 for descending order.',
+                [SortOrder::SORT_ASC, SortOrder::SORT_DESC]
+            ));
+        }
+    }
+
+    /**
+     * @param string $direction
+     * @return string
+     */
+    private function normalizeDirectionInput($direction)
+    {
+        return strtoupper($direction);
     }
 }
diff --git a/lib/internal/Magento/Framework/Api/SortOrderBuilder.php b/lib/internal/Magento/Framework/Api/SortOrderBuilder.php
index 2f02c1c129a3b8c5f330b4e1739194f005f5ca47..8130994135fa80204eb11c9dba4d7c7bd477b9d9 100644
--- a/lib/internal/Magento/Framework/Api/SortOrderBuilder.php
+++ b/lib/internal/Magento/Framework/Api/SortOrderBuilder.php
@@ -36,4 +36,22 @@ class SortOrderBuilder extends AbstractSimpleObjectBuilder
         $this->_set(SortOrder::DIRECTION, $direction);
         return $this;
     }
+
+    /**
+     * @return $this
+     */
+    public function setAscendingDirection()
+    {
+        $this->setDirection(SortOrder::SORT_ASC);
+        return $this;
+    }
+
+    /**
+     * @return $this
+     */
+    public function setDescendingDirection()
+    {
+        $this->setDirection(SortOrder::SORT_DESC);
+        return $this;
+    }
 }
diff --git a/lib/internal/Magento/Framework/Api/Test/Unit/SortOrderTest.php b/lib/internal/Magento/Framework/Api/Test/Unit/SortOrderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2de99040e7d18979efba32d7b0c7598af3acb3f0
--- /dev/null
+++ b/lib/internal/Magento/Framework/Api/Test/Unit/SortOrderTest.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Framework\Api\Test\Unit;
+
+use Magento\Framework\Api\SortOrder;
+
+/**
+ * @covers \Magento\Framework\Api\SortOrder
+ */
+class SortOrderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var SortOrder
+     */
+    private $sortOrder;
+
+    protected function setUp()
+    {
+        $this->sortOrder = new SortOrder();
+    }
+    
+    public function testItReturnsNullIfNoOrderIsSet()
+    {
+        $this->assertNull($this->sortOrder->getDirection());
+    }
+
+    /**
+     * @dataProvider sortOrderDirectionProvider
+     */
+    public function testItReturnsTheCorrectValuesIfSortOrderIsSet($sortOrder)
+    {
+        $this->sortOrder->setDirection($sortOrder);
+        $this->assertSame($sortOrder, $this->sortOrder->getDirection());
+    }
+
+    public function sortOrderDirectionProvider()
+    {
+        return [[SortOrder::SORT_ASC], [SortOrder::SORT_DESC]];
+    }
+    
+    /**
+     * @param mixed $invalidDirection
+     * @dataProvider invalidSortDirectionProvider
+     * @expectedException \Magento\Framework\Exception\InputException
+     */
+    public function testItThrowsAnExceptionIfAnInvalidSortOrderIsSet($invalidDirection)
+    {
+        $this->sortOrder->setDirection($invalidDirection);
+    }
+
+    public function invalidSortDirectionProvider()
+    {
+        return [
+            [-1],
+            [1],
+            [0],
+            [true],
+            [false],
+            [[]],
+        ];
+    }
+
+    public function testTheSortDirectionCanBeSpecifiedCaseInsensitive()
+    {
+        $this->sortOrder->setDirection(strtolower(SortOrder::SORT_ASC));
+        $this->assertSame(SortOrder::SORT_ASC, $this->sortOrder->getDirection());
+        $this->sortOrder->setDirection(strtoupper(SortOrder::SORT_ASC));
+        $this->assertSame(SortOrder::SORT_ASC, $this->sortOrder->getDirection());
+        
+        $this->sortOrder->setDirection(strtolower(SortOrder::SORT_DESC));
+        $this->assertSame(SortOrder::SORT_DESC, $this->sortOrder->getDirection());
+        $this->sortOrder->setDirection(strtoupper(SortOrder::SORT_DESC));
+        $this->assertSame(SortOrder::SORT_DESC, $this->sortOrder->getDirection());
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\InputException
+     */
+    public function testItValidatesADirectionAssignedDuringInstantiation()
+    {
+        $this->sortOrder = new SortOrder([
+            SortOrder::DIRECTION => 'not-asc-or-desc'
+        ]);
+    }
+}