diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php
index 08e75ceebecc6160825bc12b0380a03b4a1af0ab..337134c9453c01dad20e4581e4d82019aa956b6d 100644
--- a/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php
+++ b/app/code/Magento/CatalogSearch/Model/Indexer/Fulltext.php
@@ -6,11 +6,16 @@
 namespace Magento\CatalogSearch\Model\Indexer;
 
 use Magento\CatalogSearch\Model\Indexer\Fulltext\Action\FullFactory;
+use Magento\CatalogSearch\Model\Indexer\Scope\State;
 use Magento\CatalogSearch\Model\ResourceModel\Fulltext as FulltextResource;
-use \Magento\Framework\Search\Request\Config as SearchRequestConfig;
+use Magento\Framework\App\ObjectManager;
+use Magento\Framework\Search\Request\Config as SearchRequestConfig;
 use Magento\Framework\Search\Request\DimensionFactory;
 use Magento\Store\Model\StoreManagerInterface;
 
+/**
+ * Provide functionality for Fulltext Search indexing
+ */
 class Fulltext implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface
 {
     /**
@@ -18,34 +23,51 @@ class Fulltext implements \Magento\Framework\Indexer\ActionInterface, \Magento\F
      */
     const INDEXER_ID = 'catalogsearch_fulltext';
 
-    /** @var array index structure */
+    /**
+     * @var array index structure
+     */
     protected $data;
 
     /**
      * @var IndexerHandlerFactory
      */
     private $indexerHandlerFactory;
+
     /**
      * @var StoreManagerInterface
      */
     private $storeManager;
+
     /**
-     * @var DimensionFactory
+     * @var \Magento\Framework\Search\Request\DimensionFactory
      */
     private $dimensionFactory;
+
     /**
-     * @var Full
+     * @var \Magento\CatalogSearch\Model\Indexer\Fulltext\Action\Full
      */
     private $fullAction;
+
     /**
      * @var FulltextResource
      */
     private $fulltextResource;
+
     /**
-     * @var SearchRequestConfig
+     * @var \Magento\Framework\Search\Request\Config
      */
     private $searchRequestConfig;
 
+    /**
+     * @var IndexSwitcherInterface
+     */
+    private $indexSwitcher;
+
+    /**
+     * @var \Magento\CatalogSearch\Model\Indexer\Scope\State
+     */
+    private $indexScopeState;
+
     /**
      * @param FullFactory $fullActionFactory
      * @param IndexerHandlerFactory $indexerHandlerFactory
@@ -54,6 +76,8 @@ class Fulltext implements \Magento\Framework\Indexer\ActionInterface, \Magento\F
      * @param FulltextResource $fulltextResource
      * @param SearchRequestConfig $searchRequestConfig
      * @param array $data
+     * @param IndexSwitcherInterface $indexSwitcher
+     * @param Scope\State $indexScopeState
      */
     public function __construct(
         FullFactory $fullActionFactory,
@@ -62,7 +86,9 @@ class Fulltext implements \Magento\Framework\Indexer\ActionInterface, \Magento\F
         DimensionFactory $dimensionFactory,
         FulltextResource $fulltextResource,
         SearchRequestConfig $searchRequestConfig,
-        array $data
+        array $data,
+        IndexSwitcherInterface $indexSwitcher = null,
+        State $indexScopeState = null
     ) {
         $this->fullAction = $fullActionFactory->create(['data' => $data]);
         $this->indexerHandlerFactory = $indexerHandlerFactory;
@@ -71,6 +97,14 @@ class Fulltext implements \Magento\Framework\Indexer\ActionInterface, \Magento\F
         $this->fulltextResource = $fulltextResource;
         $this->searchRequestConfig = $searchRequestConfig;
         $this->data = $data;
+        if (null === $indexSwitcher) {
+            $indexSwitcher = ObjectManager::getInstance()->get(IndexSwitcherInterface::class);
+        }
+        if (null === $indexScopeState) {
+            $indexScopeState = ObjectManager::getInstance()->get(State::class);
+        }
+        $this->indexSwitcher = $indexSwitcher;
+        $this->indexScopeState = $indexScopeState;
     }
 
     /**
@@ -106,10 +140,14 @@ class Fulltext implements \Magento\Framework\Indexer\ActionInterface, \Magento\F
             'data' => $this->data
         ]);
         foreach ($storeIds as $storeId) {
-            $dimension = $this->dimensionFactory->create(['name' => 'scope', 'value' => $storeId]);
-            $saveHandler->cleanIndex([$dimension]);
-            $saveHandler->saveIndex([$dimension], $this->fullAction->rebuildStoreIndex($storeId));
+            $dimensions = [$this->dimensionFactory->create(['name' => 'scope', 'value' => $storeId])];
+            $this->indexScopeState->useTemporaryIndex();
+
+            $saveHandler->cleanIndex($dimensions);
+            $saveHandler->saveIndex($dimensions, $this->fullAction->rebuildStoreIndex($storeId));
 
+            $this->indexSwitcher->switchIndex($dimensions);
+            $this->indexScopeState->useRegularIndex();
         }
         $this->fulltextResource->resetSearchResults();
         $this->searchRequestConfig->reset();
diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php
index 9a2bb76c04ce76ccfa60e757c2075120ef2d09e2..d2d76bc71ccbf4223036f59e8eebc65fcbd94c4c 100644
--- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php
+++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexStructure.php
@@ -12,6 +12,7 @@ use Magento\Framework\DB\Ddl\Table;
 use Magento\Framework\Search\Request\Dimension;
 use Magento\Framework\Indexer\IndexStructureInterface;
 use Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver;
+use Magento\Framework\Search\Request\IndexScopeResolverInterface;
 
 class IndexStructure implements IndexStructureInterface
 {
@@ -19,6 +20,7 @@ class IndexStructure implements IndexStructureInterface
      * @var Resource
      */
     private $resource;
+
     /**
      * @var IndexScopeResolver
      */
@@ -26,11 +28,11 @@ class IndexStructure implements IndexStructureInterface
 
     /**
      * @param ResourceConnection $resource
-     * @param IndexScopeResolver $indexScopeResolver
+     * @param IndexScopeResolverInterface $indexScopeResolver
      */
     public function __construct(
         ResourceConnection $resource,
-        IndexScopeResolver $indexScopeResolver
+        IndexScopeResolverInterface $indexScopeResolver
     ) {
         $this->resource = $resource;
         $this->indexScopeResolver = $indexScopeResolver;
diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherInterface.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..ba5fb461dde35aa0a6cdfebc1520b8d1091d841b
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherInterface.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogSearch\Model\Indexer;
+
+/**
+ * Provides a functionality to replace main index with its temporary representation
+ */
+interface IndexSwitcherInterface
+{
+    /**
+     * Switch current index with temporary index
+     *
+     * It will drop current index table and rename temporary index table to the current index table.
+     *
+     * @param array $dimensions
+     * @return void
+     */
+    public function switchIndex(array $dimensions);
+}
diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherProxy.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherProxy.php
new file mode 100644
index 0000000000000000000000000000000000000000..2ce093ed99e3a48aebadc2a02c788fd9de018591
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexSwitcherProxy.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Model\Indexer;
+
+use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Framework\ObjectManagerInterface;
+use Magento\Store\Model\ScopeInterface;
+
+/**
+ * Proxy for adapter-specific index switcher
+ */
+class IndexSwitcherProxy implements IndexSwitcherInterface
+{
+    /**
+     * Object Manager instance
+     *
+     * @var ObjectManagerInterface
+     */
+    private $objectManager = null;
+
+    /**
+     * Instance name to create
+     *
+     * @var string
+     */
+    private $handlers;
+
+    /**
+     * @var ScopeConfigInterface
+     */
+    private $scopeConfig;
+
+    /**
+     * Configuration path by which current indexer handler stored
+     *
+     * @var string
+     */
+    private $configPath;
+
+    /**
+     * Factory constructor
+     *
+     * @param ObjectManagerInterface $objectManager
+     * @param ScopeConfigInterface $scopeConfig
+     * @param string $configPath
+     * @param string[] $handlers
+     */
+    public function __construct(
+        ObjectManagerInterface $objectManager,
+        ScopeConfigInterface $scopeConfig,
+        $configPath,
+        array $handlers = []
+    ) {
+        $this->objectManager = $objectManager;
+        $this->scopeConfig = $scopeConfig;
+        $this->configPath = $configPath;
+        $this->handlers = $handlers;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * As index switcher is an optional part of the search SPI, it may be not defined by a search engine.
+     * It is especially reasonable for search engines with pre-defined indexes declaration (like old SOLR and Sphinx)
+     * which cannot create temporary indexes on the fly.
+     * That's the reason why this method do nothing for the case
+     * when switcher is not defined for a specific search engine.
+     */
+    public function switchIndex(array $dimensions)
+    {
+        $currentHandler = $this->scopeConfig->getValue($this->configPath, ScopeInterface::SCOPE_STORE);
+        if (!isset($this->handlers[$currentHandler])) {
+            return;
+        }
+        $this->create($currentHandler)->switchIndex($dimensions);
+    }
+
+    /**
+     * Create indexer handler
+     *
+     * @param string $handler
+     * @return IndexSwitcherInterface
+     */
+    private function create($handler)
+    {
+        $indexSwitcher = $this->objectManager->create($this->handlers[$handler]);
+
+        if (!$indexSwitcher instanceof IndexSwitcherInterface) {
+            throw new \InvalidArgumentException(
+                $handler . ' index switcher doesn\'t implement ' . IndexSwitcherInterface::class
+            );
+        }
+
+        return $indexSwitcher;
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandler.php b/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandler.php
index 8d99cd4492bf59cd4c98439cc402ec36d93744f6..2aa9a418bd7258f9046ebdf889f7b69f8a0c8d31 100644
--- a/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandler.php
+++ b/app/code/Magento/CatalogSearch/Model/Indexer/IndexerHandler.php
@@ -7,13 +7,11 @@ namespace Magento\CatalogSearch\Model\Indexer;
 
 use Magento\Eav\Model\Config;
 use Magento\Framework\App\ResourceConnection;
-use Magento\Framework\DB\Adapter\AdapterInterface;
 use Magento\Framework\Indexer\SaveHandler\IndexerInterface;
 use Magento\Framework\Indexer\IndexStructureInterface;
 use Magento\Framework\Search\Request\Dimension;
 use Magento\Framework\Search\Request\IndexScopeResolverInterface;
 use Magento\Framework\Indexer\SaveHandler\Batch;
-use Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver;
 
 class IndexerHandler implements IndexerInterface
 {
@@ -62,7 +60,7 @@ class IndexerHandler implements IndexerInterface
      * @param ResourceConnection $resource
      * @param Config $eavConfig
      * @param Batch $batch
-     * @param \Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver $indexScopeResolver
+     * @param IndexScopeResolverInterface $indexScopeResolver
      * @param array $data
      * @param int $batchSize
      */
@@ -71,7 +69,7 @@ class IndexerHandler implements IndexerInterface
         ResourceConnection $resource,
         Config $eavConfig,
         Batch $batch,
-        IndexScopeResolver $indexScopeResolver,
+        IndexScopeResolverInterface $indexScopeResolver,
         array $data,
         $batchSize = 100
     ) {
diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexSwitcher.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexSwitcher.php
new file mode 100644
index 0000000000000000000000000000000000000000..87a7b7110d3aae24999040e62d75bdd01052528e
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexSwitcher.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogSearch\Model\Indexer\Scope;
+
+use Magento\CatalogSearch\Model\Indexer\IndexSwitcherInterface;
+use Magento\Framework\App\ResourceConnection;
+use Magento\Framework\Search\Request\IndexScopeResolverInterface;
+
+/**
+ * Provides a functionality to replace main index with its temporary representation
+ */
+class IndexSwitcher implements IndexSwitcherInterface
+{
+    /**
+     * @var Resource
+     */
+    private $resource;
+
+    /**
+     * @var ScopeProxy
+     */
+    private $resolver;
+
+    /**
+     * @var State
+     */
+    private $state;
+
+    /**
+     * @param ResourceConnection $resource
+     * @param IndexScopeResolverInterface $indexScopeResolver
+     * @param State $state
+     */
+    public function __construct(
+        ResourceConnection $resource,
+        IndexScopeResolverInterface $indexScopeResolver,
+        State $state
+    ) {
+        $this->resource = $resource;
+        $this->resolver = $indexScopeResolver;
+        $this->state = $state;
+    }
+
+    /**
+     * {@inheritdoc}
+     * @throws IndexTableNotExistException
+     */
+    public function switchIndex(array $dimensions)
+    {
+        if (State::USE_TEMPORARY_INDEX === $this->state->getState()) {
+            $index = \Magento\CatalogSearch\Model\Indexer\Fulltext::INDEXER_ID;
+
+            $temporalIndexTable = $this->resolver->resolve($index, $dimensions);
+            if (!$this->resource->getConnection()->isTableExists($temporalIndexTable)) {
+                throw new IndexTableNotExistException(
+                    __(
+                        "Temporary table for index $index doesn't exist,"
+                        . " which is inconsistent with state of scope resolver"
+                    )
+                );
+            }
+
+            $this->state->useRegularIndex();
+            $tableName = $this->resolver->resolve($index, $dimensions);
+            if ($this->resource->getConnection()->isTableExists($tableName)) {
+                $this->resource->getConnection()->dropTable($tableName);
+            }
+
+            $this->resource->getConnection()->renameTable($temporalIndexTable, $tableName);
+            $this->state->useTemporaryIndex();
+        }
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexTableNotExistException.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexTableNotExistException.php
new file mode 100644
index 0000000000000000000000000000000000000000..6974f8c278ab55af0cb41f501124eb3201f5e914
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/IndexTableNotExistException.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Model\Indexer\Scope;
+
+
+use Magento\Framework\Exception\LocalizedException;
+
+/**
+ * Exception which represents situation where temporary index table should be used somewhere,
+ * but it does not exist in a database
+ */
+class IndexTableNotExistException extends LocalizedException
+{
+}
diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php
new file mode 100644
index 0000000000000000000000000000000000000000..14832af303bf4167df380776f28de09482c84e7f
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/ScopeProxy.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Model\Indexer\Scope;
+
+
+use Magento\Framework\Search\Request\Dimension;
+
+/**
+ * Implementation of IndexScopeResolverInterface which resolves index scope dynamically
+ * depending on current scope state
+ */
+class ScopeProxy implements \Magento\Framework\Search\Request\IndexScopeResolverInterface
+{
+    /**
+     * Object Manager instance
+     *
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    private $objectManager;
+
+    /**
+     * @var array
+     */
+    private $states = [];
+
+    /**
+     * @var State
+     */
+    private $scopeState;
+
+    /**
+     * Factory constructor
+     *
+     * @param \Magento\Framework\ObjectManagerInterface $objectManager
+     * @param State $scopeState
+     * @param array $states
+     */
+    public function __construct(
+        \Magento\Framework\ObjectManagerInterface $objectManager,
+        State $scopeState,
+        array $states
+    ) {
+        $this->objectManager = $objectManager;
+        $this->scopeState = $scopeState;
+        $this->states = $states;
+    }
+
+    /**
+     * Creates class instance with specified parameters
+     *
+     * @param string $state
+     * @return \Magento\Framework\Search\Request\IndexScopeResolverInterface
+     * @throws UnknownStateException
+     */
+    private function create($state)
+    {
+        if (!array_key_exists($state, $this->states)) {
+            throw new UnknownStateException(__("Requested resolver for unknown indexer state: $state"));
+        }
+        return $this->objectManager->create($this->states[$state]);
+    }
+
+    /**
+     * @param string $index
+     * @param Dimension[] $dimensions
+     * @return string
+     */
+    public function resolve($index, array $dimensions)
+    {
+        return $this->create($this->scopeState->getState())->resolve($index, $dimensions);
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php
new file mode 100644
index 0000000000000000000000000000000000000000..2bba29ae8d842f963146bef411d3a71023740ae8
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/State.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Model\Indexer\Scope;
+
+
+use Magento\Framework\App\ResourceConnection;
+use Magento\Framework\App\ScopeResolverInterface;
+use Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver;
+use Magento\Framework\Search\Request\Dimension;
+use Magento\Framework\Search\Request\IndexScopeResolverInterface;
+
+/**
+ * This class represents state that defines which table should be used during indexation process
+ *
+ * There are two possible states:
+ *   - use_temporary_table
+ *   - use_main_table
+ *
+ * The 'use_main_table' state means that default indexer table should be used.
+ *
+ * The 'use_temporary_table' state is an opposite for 'use_main_table'
+ *   which means that default indexer table should be left unchanged during indexation
+ *   and temporary table should be used instead.
+ *
+ */
+class State
+{
+    const USE_TEMPORARY_INDEX = 'use_temporary_table';
+    const USE_REGULAR_INDEX = 'use_main_table';
+
+    /**
+     * @var string
+     */
+    private $state = self::USE_REGULAR_INDEX;
+
+    /**
+     * Set the state to use temporary Index
+     * @return void
+     */
+    public function useTemporaryIndex()
+    {
+        $this->state = self::USE_TEMPORARY_INDEX;
+    }
+
+    /**
+     * Set the state to use regular Index
+     * @return void
+     */
+    public function useRegularIndex()
+    {
+        $this->state = self::USE_REGULAR_INDEX;
+    }
+
+    /**
+     * @return string
+     */
+    public function getState()
+    {
+        return $this->state;
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/TemporaryResolver.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/TemporaryResolver.php
new file mode 100644
index 0000000000000000000000000000000000000000..51037eb637cf3c346fdcd7ac64aefc0a50e14949
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/TemporaryResolver.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Model\Indexer\Scope;
+
+
+use Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver;
+use Magento\Framework\Search\Request\Dimension;
+
+/**
+ * Resolves name of a temporary table for indexation
+ */
+class TemporaryResolver implements \Magento\Framework\Search\Request\IndexScopeResolverInterface
+{
+    /**
+     * @var IndexScopeResolver
+     */
+    private $indexScopeResolver;
+
+    /**
+     * @inheritDoc
+     */
+    public function __construct(IndexScopeResolver $indexScopeResolver)
+    {
+        $this->indexScopeResolver = $indexScopeResolver;
+    }
+
+    /**
+     * @param string $index
+     * @param Dimension[] $dimensions
+     * @return string
+     */
+    public function resolve($index, array $dimensions)
+    {
+        $tableName = $this->indexScopeResolver->resolve($index, $dimensions);
+        $tableName .= \Magento\Framework\Indexer\Table\StrategyInterface::TMP_SUFFIX;
+
+        return $tableName;
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Model/Indexer/Scope/UnknownStateException.php b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/UnknownStateException.php
new file mode 100644
index 0000000000000000000000000000000000000000..04803ef27480efd504949ecc43773ebd3db3d2f3
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Model/Indexer/Scope/UnknownStateException.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Model\Indexer\Scope;
+
+
+use Magento\Framework\Exception\LocalizedException;
+
+/**
+ * Exception for situation where used state which is not defined in configuration
+ */
+class UnknownStateException extends LocalizedException
+{
+
+}
diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/FulltextTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/FulltextTest.php
index f4c0437590ed56c72c5e0076f79be93d181e082c..6ef656d566867dec02cf3a157e1b6d0c3cd24826 100644
--- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/FulltextTest.php
+++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/FulltextTest.php
@@ -8,7 +8,13 @@ namespace Magento\CatalogSearch\Test\Unit\Model\Indexer;
 use Magento\CatalogSearch\Model\ResourceModel\Fulltext as FulltextResource;
 use Magento\Framework\Search\Request\Config as SearchRequestConfig;
 use Magento\Framework\Search\Request\DimensionFactory;
+use Magento\Framework\Search\Request\Dimension;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
+use \Magento\CatalogSearch\Model\Indexer\Fulltext\IndexSwitcher;
 
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class FulltextTest extends \PHPUnit_Framework_TestCase
 {
     /**
@@ -26,11 +32,6 @@ class FulltextTest extends \PHPUnit_Framework_TestCase
      */
     protected $storeManager;
 
-    /**
-     * @var \Magento\Framework\Search\Request\Dimension|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $dimension;
-
     /**
      * @var \Magento\CatalogSearch\Model\Indexer\IndexerHandler|\PHPUnit_Framework_MockObject_MockObject
      */
@@ -47,8 +48,15 @@ class FulltextTest extends \PHPUnit_Framework_TestCase
     protected $searchRequestConfig;
 
     /**
-     *
+     * @var \Magento\Framework\Search\Request\DimensionFactory|\PHPUnit_Framework_MockObject_MockObject
      */
+    private $dimensionFactory;
+
+    /**
+     * @var \Magento\CatalogSearch\Model\Indexer\Scope\IndexSwitcher|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $indexSwitcher;
+
     protected function setUp()
     {
         $this->fullAction = $this->getClassMock(\Magento\CatalogSearch\Model\Indexer\Fulltext\Action\Full::class);
@@ -80,27 +88,29 @@ class FulltextTest extends \PHPUnit_Framework_TestCase
             []
         );
 
-        $this->dimension = $this->getClassMock(\Magento\Framework\Search\Request\Dimension::class);
-        $dimensionFactory = $this->getMock(
-            \Magento\Framework\Search\Request\DimensionFactory::class,
-            ['create'],
-            [],
-            '',
-            false
-        );
-        $dimensionFactory->expects($this->any())->method('create')->willReturn($this->dimension);
+        $this->dimensionFactory = $this->getMock(DimensionFactory::class, ['create'], [], '', false);
 
         $this->fulltextResource = $this->getClassMock(\Magento\CatalogSearch\Model\ResourceModel\Fulltext::class);
         $this->searchRequestConfig = $this->getClassMock(\Magento\Framework\Search\Request\Config::class);
 
-        $this->model = new \Magento\CatalogSearch\Model\Indexer\Fulltext(
-            $fullActionFactory,
-            $indexerHandlerFactory,
-            $this->storeManager,
-            $dimensionFactory,
-            $this->fulltextResource,
-            $this->searchRequestConfig,
-            []
+        $this->indexSwitcher = $this->getMockBuilder(\Magento\CatalogSearch\Model\Indexer\Scope\IndexSwitcher::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['switchIndex'])
+            ->getMock();
+
+        $objectManagerHelper = new ObjectManagerHelper($this);
+        $this->model = $objectManagerHelper->getObject(
+            \Magento\CatalogSearch\Model\Indexer\Fulltext::class,
+            [
+                'fullActionFactory' => $fullActionFactory,
+                'indexerHandlerFactory' => $indexerHandlerFactory,
+                'storeManager' => $this->storeManager,
+                'dimensionFactory' => $this->dimensionFactory,
+                'fulltextResource' => $this->fulltextResource,
+                'searchRequestConfig' => $this->searchRequestConfig,
+                'data' => [],
+                'indexSwitcher' => $this->indexSwitcher,
+            ]
         );
     }
 
@@ -131,13 +141,38 @@ class FulltextTest extends \PHPUnit_Framework_TestCase
     public function testExecuteFull()
     {
         $stores = [0 => 'Store 1', 1 => 'Store 2'];
-        $indexData = new \ArrayObject([]);
+        $indexData = new \ArrayObject([new \ArrayObject([]), new \ArrayObject([])]);
         $this->storeManager->expects($this->once())->method('getStores')->willReturn($stores);
-        $this->saveHandler->expects($this->exactly(count($stores)))->method('cleanIndex');
-        $this->saveHandler->expects($this->exactly(2))->method('saveIndex');
+
+        $dimensionScope1 = $this->getMock(Dimension::class, [], ['scope', '1']);
+        $dimensionScope2 = $this->getMock(Dimension::class, [], ['scope', '2']);
+
+        $this->dimensionFactory->expects($this->any())->method('create')->willReturnOnConsecutiveCalls(
+            $dimensionScope1,
+            $dimensionScope2
+        );
+        $this->indexSwitcher->expects($this->exactly(2))->method('switchIndex')
+            ->withConsecutive(
+                [$this->equalTo([$dimensionScope1])],
+                [$this->equalTo([$dimensionScope2])]
+            );
+
+        $this->saveHandler->expects($this->exactly(count($stores)))->method('cleanIndex')
+            ->withConsecutive(
+                [$this->equalTo([$dimensionScope1])],
+                [$this->equalTo([$dimensionScope2])]
+            );
+
+        $this->saveHandler->expects($this->exactly(2))->method('saveIndex')
+            ->withConsecutive(
+                [$this->equalTo([$dimensionScope1]), $this->equalTo($indexData)],
+                [$this->equalTo([$dimensionScope2]), $this->equalTo($indexData)]
+            );
         $this->fullAction->expects($this->exactly(2))
             ->method('rebuildStoreIndex')
-            ->willReturn(new \ArrayObject([$indexData, $indexData]));
+            ->withConsecutive([0], [1])
+            ->willReturn($indexData);
+
         $this->fulltextResource->expects($this->once())->method('resetSearchResults');
         $this->searchRequestConfig->expects($this->once())->method('reset');
 
diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Scope/IndexSwitcherTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Scope/IndexSwitcherTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..31bec5906ae5a37c34f666af0999b1cafe2f0485
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Indexer/Scope/IndexSwitcherTest.php
@@ -0,0 +1,212 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogSearch\Test\Unit\Model\Indexer\Scope;
+
+use Magento\CatalogSearch\Model\Indexer\Scope\IndexSwitcher;
+use Magento\CatalogSearch\Model\Indexer\Scope\State;
+use Magento\Framework\App\ResourceConnection;
+use Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver;
+use Magento\Framework\Indexer\IndexStructureInterface;
+use Magento\Framework\Search\Request\Dimension;
+use Magento\CatalogSearch\Model\Indexer\Fulltext as FulltextIndexer;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
+
+class IndexSwitcherTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\DB\Adapter\AdapterInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $connection;
+
+    /**
+     * @var \Magento\Framework\Search\Request\IndexScopeResolverInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $indexScopeResolver;
+
+    /**
+     * @var State|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $scopeState;
+
+    /**
+     * @var IndexSwitcher
+     */
+    private $indexSwitcher;
+
+    /**
+     * @var ResourceConnection|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $resource;
+
+    protected function setUp()
+    {
+        $this->resource = $this->getMockBuilder(ResourceConnection::class)
+            ->setMethods(['getConnection'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->connection = $this->getMockBuilder(\Magento\Framework\DB\Adapter\AdapterInterface::class)
+            ->setMethods(['isTableExists', 'dropTable', 'renameTable'])
+            ->getMockForAbstractClass();
+        $this->resource->expects($this->any())
+            ->method('getConnection')
+            ->willReturn($this->connection);
+        $this->indexScopeResolver = $this->getMockBuilder(
+            \Magento\Framework\Search\Request\IndexScopeResolverInterface::class
+        )
+            ->setMethods(['resolve'])
+            ->getMockForAbstractClass();
+        $this->scopeState = $this->getMockBuilder(State::class)
+            ->setMethods(['getState', 'useRegularIndex', 'useTemporaryIndex'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $objectManagerHelper = new ObjectManagerHelper($this);
+        $this->indexSwitcher = $objectManagerHelper->getObject(
+            \Magento\CatalogSearch\Model\Indexer\Scope\IndexSwitcher::class,
+            [
+                'resource' => $this->resource,
+                'indexScopeResolver' => $this->indexScopeResolver,
+                'state' => $this->scopeState,
+            ]
+        );
+    }
+
+    public function testSwitchRegularIndex()
+    {
+        $dimensions = [$this->getMockBuilder(Dimension::class)->setConstructorArgs(['scope', '1'])];
+
+        $this->scopeState->expects($this->once())
+            ->method('getState')
+            ->willReturn(State::USE_REGULAR_INDEX);
+
+        $this->indexScopeResolver->expects($this->never())->method('resolve');
+        $this->connection->expects($this->never())->method('renameTable');
+
+        $this->indexSwitcher->switchIndex($dimensions);
+    }
+
+    public function testSwitchIndexWithUnknownState()
+    {
+        $dimensions = [$this->getMockBuilder(Dimension::class)->setConstructorArgs(['scope', '1'])];
+
+        $this->scopeState->expects($this->once())
+            ->method('getState')
+            ->willReturn('unknown_state');
+
+        $this->indexScopeResolver->expects($this->never())->method('resolve');
+        $this->connection->expects($this->never())->method('renameTable');
+
+        $this->indexSwitcher->switchIndex($dimensions);
+    }
+
+    public function testSwitchTemporaryIndexWhenRegularIndexExist()
+    {
+        $dimensions = [$this->getMockBuilder(Dimension::class)->setConstructorArgs(['scope', '1'])];
+
+        $this->scopeState->expects($this->once())
+            ->method('getState')
+            ->willReturn(State::USE_TEMPORARY_INDEX);
+
+        $this->scopeState->expects($this->at(1))->method('useRegularIndex');
+        $this->scopeState->expects($this->at(2))->method('useTemporaryIndex');
+
+        $this->indexScopeResolver->expects($this->exactly(2))->method('resolve')
+            ->withConsecutive(
+                [$this->equalTo(FulltextIndexer::INDEXER_ID), $this->equalTo($dimensions)],
+                [$this->equalTo(FulltextIndexer::INDEXER_ID), $this->equalTo($dimensions)]
+            )
+            ->willReturnOnConsecutiveCalls(
+                'catalogsearch_fulltext_scope1_tmp1',
+                'catalogsearch_fulltext_scope1'
+            );
+
+        $this->connection->expects($this->exactly(2))->method('isTableExists')
+            ->withConsecutive(
+                [$this->equalTo('catalogsearch_fulltext_scope1_tmp1'), $this->equalTo(null)],
+                [$this->equalTo('catalogsearch_fulltext_scope1'), $this->equalTo(null)]
+            )
+            ->willReturnOnConsecutiveCalls(
+                true,
+                true
+            );
+
+        $this->connection->expects($this->once())->method('dropTable')->with('catalogsearch_fulltext_scope1', null);
+        $this->connection->expects($this->once())
+            ->method('renameTable')
+            ->with('catalogsearch_fulltext_scope1_tmp1', 'catalogsearch_fulltext_scope1');
+
+        $this->indexSwitcher->switchIndex($dimensions);
+    }
+
+    public function testSwitchTemporaryIndexWhenRegularIndexNotExist()
+    {
+        $dimensions = [$this->getMockBuilder(Dimension::class)->setConstructorArgs(['scope', '1'])];
+
+        $this->scopeState->expects($this->once())
+            ->method('getState')
+            ->willReturn(State::USE_TEMPORARY_INDEX);
+
+        $this->scopeState->expects($this->at(1))->method('useRegularIndex');
+        $this->scopeState->expects($this->at(2))->method('useTemporaryIndex');
+
+        $this->indexScopeResolver->expects($this->exactly(2))->method('resolve')
+            ->withConsecutive(
+                [$this->equalTo(FulltextIndexer::INDEXER_ID), $this->equalTo($dimensions)],
+                [$this->equalTo(FulltextIndexer::INDEXER_ID), $this->equalTo($dimensions)]
+            )
+            ->willReturnOnConsecutiveCalls(
+                'catalogsearch_fulltext_scope1_tmp1',
+                'catalogsearch_fulltext_scope1'
+            );
+
+        $this->connection->expects($this->exactly(2))->method('isTableExists')
+            ->withConsecutive(
+                [$this->equalTo('catalogsearch_fulltext_scope1_tmp1'), $this->equalTo(null)],
+                [$this->equalTo('catalogsearch_fulltext_scope1'), $this->equalTo(null)]
+            )
+            ->willReturnOnConsecutiveCalls(
+                true,
+                false
+            );
+
+        $this->connection->expects($this->never())->method('dropTable')->with('catalogsearch_fulltext_scope1', null);
+        $this->connection->expects($this->once())
+            ->method('renameTable')
+            ->with('catalogsearch_fulltext_scope1_tmp1', 'catalogsearch_fulltext_scope1');
+
+        $this->indexSwitcher->switchIndex($dimensions);
+    }
+
+    /**
+     * @expectedException \Magento\CatalogSearch\Model\Indexer\Scope\IndexTableNotExistException
+     * @expectedExceptionMessage Temporary table for index catalogsearch_fulltext doesn't exist
+     */
+    public function testSwitchWhenTemporaryIndexNotExist()
+    {
+        $dimensions = [$this->getMockBuilder(Dimension::class)->setConstructorArgs(['scope', '1'])];
+
+        $this->scopeState->expects($this->once())
+            ->method('getState')
+            ->willReturn(State::USE_TEMPORARY_INDEX);
+
+        $this->scopeState->expects($this->never())->method('useRegularIndex');
+        $this->scopeState->expects($this->never())->method('useTemporaryIndex');
+
+        $this->indexScopeResolver->expects($this->once())->method('resolve')
+            ->with(FulltextIndexer::INDEXER_ID, $dimensions)
+            ->willReturn('catalogsearch_fulltext_scope1_tmp1');
+
+        $this->connection->expects($this->once())
+            ->method('isTableExists')
+            ->with('catalogsearch_fulltext_scope1_tmp1', null)
+            ->willReturn(false);
+
+        $this->connection->expects($this->never())->method('dropTable')->with('catalogsearch_fulltext_scope1', null);
+        $this->connection->expects($this->never())->method('renameTable');
+
+        $this->indexSwitcher->switchIndex($dimensions);
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Advanced/CollectionTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Advanced/CollectionTest.php
index 4b04e7d66ab569ab3d2e6219cef4e2b69268d8e0..d44fef54683fc9e3c91c79d8844c2d620c750079 100644
--- a/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Advanced/CollectionTest.php
+++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Advanced/CollectionTest.php
@@ -74,7 +74,10 @@ class CollectionTest extends BaseCollectionTest
         $productLimitationMock = $this->getMock(
             \Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitation::class
         );
-        $productLimitationFactoryMock = $this->getMock(ProductLimitationFactory::class, ['create']);
+        $productLimitationFactoryMock = $this->getMockBuilder(ProductLimitationFactory::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
         $productLimitationFactoryMock->method('create')
             ->willReturn($productLimitationMock);
 
diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Fulltext/CollectionTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Fulltext/CollectionTest.php
index 5e56a253563592a55b80b00d26432028d9f4c5fa..5732ed2c8aee1dfa2429757a9e8f67b1cc324f1f 100644
--- a/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Fulltext/CollectionTest.php
+++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/ResourceModel/Fulltext/CollectionTest.php
@@ -80,7 +80,10 @@ class CollectionTest extends BaseCollectionTest
         $productLimitationMock = $this->getMock(
             \Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitation::class
         );
-        $productLimitationFactoryMock = $this->getMock(ProductLimitationFactory::class, ['create']);
+        $productLimitationFactoryMock = $this->getMockBuilder(ProductLimitationFactory::class)
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
         $productLimitationFactoryMock->method('create')
             ->willReturn($productLimitationMock);
 
diff --git a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/Indexer/IndexStructureTest.php b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/Indexer/IndexStructureTest.php
index 3bb270e990617d3a9e05ca574e788f5bb3f714aa..8f4bb7736cd37b9bf86d5591e792edea8909ef19 100644
--- a/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/Indexer/IndexStructureTest.php
+++ b/app/code/Magento/CatalogSearch/Test/Unit/Model/Search/Indexer/IndexStructureTest.php
@@ -48,9 +48,8 @@ class IndexStructureTest extends \PHPUnit_Framework_TestCase
             ->method('getConnection')
             ->willReturn($this->connection);
         $this->indexScopeResolver = $this->getMockBuilder(
-            \Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver::class
+            \Magento\Framework\Search\Request\IndexScopeResolverInterface::class
         )->setMethods(['resolve'])
-            ->disableOriginalConstructor()
             ->getMock();
 
         $objectManager = new ObjectManager($this);
@@ -64,11 +63,6 @@ class IndexStructureTest extends \PHPUnit_Framework_TestCase
         );
     }
 
-    /**
-     * @param string $table
-     * @param array $dimensions
-     * @param bool $isTableExist
-     */
     public function testDelete()
     {
         $index = 'index_name';
diff --git a/app/code/Magento/CatalogSearch/etc/di.xml b/app/code/Magento/CatalogSearch/etc/di.xml
index 7e9451f9b83e7ada30455509b8fd686a0c251705..7116abf263b0dde081a0a7f42f585e807e47ee85 100644
--- a/app/code/Magento/CatalogSearch/etc/di.xml
+++ b/app/code/Magento/CatalogSearch/etc/di.xml
@@ -12,6 +12,7 @@
     <preference for="Magento\Framework\Search\Dynamic\DataProviderInterface" type="Magento\CatalogSearch\Model\Adapter\Mysql\Dynamic\DataProvider" />
     <preference for="Magento\Framework\Search\Adapter\OptionsInterface" type="Magento\CatalogSearch\Model\Adapter\Options" />
     <preference for="Magento\CatalogSearch\Model\Search\FilterMapper\FilterStrategyInterface" type="Magento\CatalogSearch\Model\Search\FilterMapper\FilterContext"/>
+    <preference for="\Magento\CatalogSearch\Model\Indexer\IndexSwitcherInterface" type="\Magento\CatalogSearch\Model\Indexer\IndexSwitcherProxy"/>
     <type name="Magento\CatalogSearch\Model\Indexer\IndexerHandlerFactory">
         <arguments>
             <argument name="configPath" xsi:type="const">Magento\CatalogSearch\Model\ResourceModel\EngineInterface::CONFIG_ENGINE_PATH</argument>
@@ -20,6 +21,14 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\CatalogSearch\Model\Indexer\IndexSwitcherProxy">
+        <arguments>
+            <argument name="configPath" xsi:type="const">Magento\CatalogSearch\Model\ResourceModel\EngineInterface::CONFIG_ENGINE_PATH</argument>
+            <argument name="handlers" xsi:type="array">
+                <item name="mysql" xsi:type="string">\Magento\CatalogSearch\Model\Indexer\Scope\IndexSwitcher</item>
+            </argument>
+        </arguments>
+    </type>
     <type name="Magento\CatalogSearch\Model\Indexer\IndexStructureFactory">
         <arguments>
             <argument name="configPath" xsi:type="const">Magento\CatalogSearch\Model\ResourceModel\EngineInterface::CONFIG_ENGINE_PATH</argument>
@@ -246,4 +255,27 @@
             </argument>
         </arguments>
     </type>
+    <type name="\Magento\CatalogSearch\Model\Indexer\IndexerHandler">
+        <arguments>
+            <argument name="indexScopeResolver" xsi:type="object">\Magento\CatalogSearch\Model\Indexer\Scope\ScopeProxy</argument>
+        </arguments>
+    </type>
+    <type name="\Magento\CatalogSearch\Model\Indexer\IndexStructure">
+        <arguments>
+            <argument name="indexScopeResolver" xsi:type="object">\Magento\CatalogSearch\Model\Indexer\Scope\ScopeProxy</argument>
+        </arguments>
+    </type>
+    <type name="\Magento\CatalogSearch\Model\Indexer\Scope\IndexSwitcher">
+        <arguments>
+            <argument name="indexScopeResolver" xsi:type="object">\Magento\CatalogSearch\Model\Indexer\Scope\ScopeProxy</argument>
+        </arguments>
+    </type>
+    <type name="\Magento\CatalogSearch\Model\Indexer\Scope\ScopeProxy">
+        <arguments>
+            <argument name="states" xsi:type="array">
+                <item name="use_temporary_table" xsi:type="string">\Magento\CatalogSearch\Model\Indexer\Scope\TemporaryResolver</item>
+                <item name="use_main_table" xsi:type="string">\Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver</item>
+            </argument>
+        </arguments>
+    </type>
 </config>
diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Indexer/IndexSwitcherMock.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Indexer/IndexSwitcherMock.php
new file mode 100644
index 0000000000000000000000000000000000000000..955ccce3bb59e5fc5b23ed57dbf917941ace1eb7
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Indexer/IndexSwitcherMock.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogSearch\Model\Indexer;
+
+
+use Magento\CatalogSearch\Model\Indexer\IndexSwitcherInterface;
+
+/**
+ * The proxy class around index switcher which allows to ensure that the IndexSwitcher was actually used
+ */
+class IndexSwitcherMock extends \PHPUnit_Framework_Assert implements IndexSwitcherInterface
+{
+    private $isSwitched = false;
+
+    /**
+     * @var \Magento\CatalogSearch\Model\Indexer\IndexSwitcherInterface
+     */
+    private $indexSwitcher;
+
+    /**
+     * @param \Magento\CatalogSearch\Model\Indexer\IndexSwitcherInterface $indexSwitcher
+     */
+    public function __construct(
+        IndexSwitcherInterface $indexSwitcher
+    ) {
+        $this->indexSwitcher = $indexSwitcher;
+    }
+
+    /**
+     * Switch current index with temporary index
+     *
+     * It will drop current index table and rename temporary index table to the current index table.
+     *
+     * @param array $dimensions
+     * @return void
+     */
+    public function switchIndex(array $dimensions)
+    {
+        $this->isSwitched |= true;
+        $this->indexSwitcher->switchIndex($dimensions);
+    }
+
+    /**
+     * @return bool
+     */
+    public function isSwitched()
+    {
+        return (bool) $this->isSwitched;
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Indexer/SwitcherUsedInFulltextTest.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Indexer/SwitcherUsedInFulltextTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..afcfef5fc4c8e085549c46568d47aa45041b7a6a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Indexer/SwitcherUsedInFulltextTest.php
@@ -0,0 +1,214 @@
+<?php
+/**
+ * Copyright © 2016 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogSearch\Model\Indexer;
+
+use Magento\Catalog\Model\Product;
+use Magento\CatalogSearch\Model\Indexer\Fulltext;
+use Magento\CatalogSearch\Model\Indexer\IndexSwitcherMock;
+use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection;
+use Magento\TestFramework\Helper\Bootstrap;
+
+/**
+ * @magentoDbIsolation disabled
+ * @magentoDataFixture Magento/CatalogSearch/_files/indexer_fulltext.php
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class SwitcherUsedInFulltextTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var IndexSwitcherInterface
+     */
+    private $indexSwitcher;
+
+    /**
+     * @var \Magento\Framework\Indexer\IndexerInterface
+     */
+    protected $indexer;
+
+    /**
+     * @var \Magento\CatalogSearch\Model\ResourceModel\Engine
+     */
+    protected $engine;
+
+    /**
+     * @var \Magento\CatalogSearch\Model\ResourceModel\Fulltext
+     */
+    protected $resourceFulltext;
+
+    /**
+     * @var \Magento\CatalogSearch\Model\Fulltext
+     */
+    protected $fulltext;
+
+    /**
+     * @var \Magento\Search\Model\QueryFactory
+     */
+    protected $queryFactory;
+
+    /**
+     * @var \Magento\Catalog\Model\Product
+     */
+    protected $productApple;
+
+    /**
+     * @var \Magento\Catalog\Model\Product
+     */
+    protected $productBanana;
+
+    /**
+     * @var \Magento\Catalog\Model\Product
+     */
+    protected $productOrange;
+
+    /**
+     * @var \Magento\Catalog\Model\Product
+     */
+    protected $productPapaya;
+
+    /**
+     * @var \Magento\Catalog\Model\Product
+     */
+    protected $productCherry;
+
+    /**
+     * @var  \Magento\Framework\Search\Request\Dimension
+     */
+    protected $dimension;
+
+    protected function setUp()
+    {
+        $objectManager = Bootstrap::getObjectManager();
+
+        $objectManager->configure(
+            [
+                ltrim(Fulltext::class, '\\') => [
+                    'arguments' => [
+                        'indexSwitcher' => [
+                            'instance' => ltrim(IndexSwitcherMock::class, '\\'),
+                        ],
+                    ],
+                ],
+            ]
+        );
+
+        /** @var \Magento\Framework\Indexer\IndexerInterface indexer */
+        $this->indexer = $objectManager->create(
+            \Magento\Indexer\Model\Indexer::class
+        );
+        $this->indexer->load('catalogsearch_fulltext');
+
+        $this->engine = $objectManager->get(
+            \Magento\CatalogSearch\Model\ResourceModel\Engine::class
+        );
+
+        $this->resourceFulltext = $objectManager->get(
+            \Magento\CatalogSearch\Model\ResourceModel\Fulltext::class
+        );
+
+        $this->queryFactory = $objectManager->get(
+            \Magento\Search\Model\QueryFactory::class
+        );
+
+        $this->dimension = $objectManager->create(
+            \Magento\Framework\Search\Request\Dimension::class,
+            ['name' => 'scope', 'value' => '1']
+        );
+
+        $this->indexSwitcher = Bootstrap::getObjectManager()->get(
+            IndexSwitcherMock::class
+        );
+
+        $this->productApple = $this->getProductBySku('fulltext-1');
+        $this->productBanana = $this->getProductBySku('fulltext-2');
+        $this->productOrange = $this->getProductBySku('fulltext-3');
+        $this->productPapaya = $this->getProductBySku('fulltext-4');
+        $this->productCherry = $this->getProductBySku('fulltext-5');
+    }
+
+    /**
+     * @magentoAppIsolation enabled
+     */
+    public function testReindexAll()
+    {
+        $this->indexer->reindexAll();
+
+        /** @var IndexSwitcherMock $indexSwitcher */
+        $indexSwitcher = Bootstrap::getObjectManager()->get(
+            IndexSwitcherMock::class
+        );
+        $this->assertTrue($indexSwitcher->isSwitched());
+    }
+
+    /**
+     * @magentoAppIsolation enabled
+     */
+    public function testReindexList()
+    {
+        $this->indexer->reindexList([$this->productApple->getId(), $this->productBanana->getId()]);
+
+        /** @var IndexSwitcherMock $indexSwitcher */
+        $indexSwitcher = Bootstrap::getObjectManager()->get(
+            IndexSwitcherMock::class
+        );
+        $this->assertFalse($indexSwitcher->isSwitched());
+    }
+
+    /**
+     * @magentoAppIsolation enabled
+     */
+    public function testReindexRow()
+    {
+        $this->indexer->reindexRow($this->productPapaya->getId());
+
+        /** @var IndexSwitcherMock $indexSwitcher */
+        $indexSwitcher = Bootstrap::getObjectManager()->get(
+            IndexSwitcherMock::class
+        );
+        $this->assertFalse($indexSwitcher->isSwitched());
+    }
+
+    /**
+     * Search the text and return result collection
+     *
+     * @param string $text
+     * @return Product[]
+     */
+    protected function search($text)
+    {
+        $this->resourceFulltext->resetSearchResults();
+        $query = $this->queryFactory->get();
+        $query->unsetData();
+        $query->setQueryText($text);
+        $query->saveIncrementalPopularity();
+        $products = [];
+        $collection = Bootstrap::getObjectManager()->create(
+            Collection::class,
+            [
+                'searchRequestName' => 'quick_search_container'
+            ]
+        );
+        $collection->addSearchFilter($text);
+        foreach ($collection as $product) {
+            $products[] = $product;
+        }
+        return $products;
+    }
+
+    /**
+     * Return product by SKU
+     *
+     * @param string $sku
+     * @return Product
+     */
+    protected function getProductBySku($sku)
+    {
+        /** @var Product $product */
+        $product = Bootstrap::getObjectManager()->get(
+            \Magento\Catalog\Model\Product::class
+        );
+        return $product->loadByAttribute('sku', $sku);
+    }
+}
diff --git a/lib/internal/Magento/Framework/Indexer/ScopeResolver/IndexScopeResolver.php b/lib/internal/Magento/Framework/Indexer/ScopeResolver/IndexScopeResolver.php
index eaab236bbca5bd3dddf6386f7490417bc8be584a..8bcb4acaa11a314e3bd937468cd202fd17ec81b2 100644
--- a/lib/internal/Magento/Framework/Indexer/ScopeResolver/IndexScopeResolver.php
+++ b/lib/internal/Magento/Framework/Indexer/ScopeResolver/IndexScopeResolver.php
@@ -52,6 +52,7 @@ class IndexScopeResolver implements IndexScopeResolverInterface
                     $tableNameParts[] = $dimension->getName() . $dimension->getValue();
             }
         }
+
         return $this->resource->getTableName(implode('_', $tableNameParts));
     }
 
@@ -63,10 +64,12 @@ class IndexScopeResolver implements IndexScopeResolverInterface
      */
     private function getScopeId($dimension)
     {
-        if (is_numeric($dimension->getValue())) {
-            return $dimension->getValue();
-        } else {
-            return $this->scopeResolver->getScope($dimension->getValue())->getId();
+        $scopeId = $dimension->getValue();
+
+        if (!is_numeric($scopeId)) {
+            $scopeId = $this->scopeResolver->getScope($scopeId)->getId();
         }
+
+        return $scopeId;
     }
 }