public function indexQueuedItems()
    {
        $dispatcher = $this->getDispatcher();

        $log = $this->getLogger();
        $context = array('engine' => get_class($this->_searchEngine));
        $log->info('Indexing operation started', $context);

        try {

            // Ensure the schema object is populated. This routine will also
            // throw the SearchEvents::SCHEMA_ALTER event as well as detect
            // incompatible schemata.
            $this->getSchema();

            // Adds the search engine instance  as a subscriber only for the
            // duration of this indexing process.
            $dispatcher->addSubscriber($this->_searchEngine);

            $event = new SearchEngineEvent($this);
            $this->dispatchEvent(SearchEvents::SEARCH_ENGINE_PRE_INDEX, $event);

            // Consume messages from the queue that correspond with items that
            // are scheduled for indexing.
            $consumer = new QueueConsumer($this);
            foreach ($consumer as $message) {
                $context['item'] = $message->getBody();
                $log->debug('Consumed item scheduled for indexing from queue', $context);
                $this->indexQueuedItem($message);
            }

            unset($context['item']); // The item is no longer in context.
            $this->dispatchEvent(SearchEvents::SEARCH_ENGINE_POST_INDEX, $event);

            // The search engine should only listen to events throws during it's
            // own indexing operation.
            $dispatcher->removeSubscriber($this->_searchEngine);

        } catch (Exception $e) {
            // Make sure this service is removed as a subscriber. See above.
            $dispatcher->removeSubscriber($this->_searchEngine);
            throw $e;
        }

        $context['indexed'] = count($consumer);
        $log->info('Indexing operation completed', $context);
    }