function startIndexing($verbose = true, $extConf, $mode = '')
 {
     // write starting timestamp into registry
     // this is a helper to delete all records which are older than starting timestamp in registry
     // this also prevents starting the indexer twice
     if ($this->registry->get('tx_kesearch', 'startTimeOfIndexer') === null) {
         $this->registry->set('tx_kesearch', 'startTimeOfIndexer', time());
     } else {
         // check lock time
         $lockTime = $this->registry->get('tx_kesearch', 'startTimeOfIndexer');
         $compareTime = time() - 60 * 60 * 12;
         if ($lockTime < $compareTime) {
             // lock is older than 12 hours - remove
             $this->registry->removeAllByNamespace('tx_kesearch');
             $this->registry->set('tx_kesearch', 'startTimeOfIndexer', time());
         } else {
             return 'You can\'t start the indexer twice. Please wait while first indexer process is currently running';
         }
     }
     // set indexing start time
     $this->startTime = time();
     // get configurations
     $configurations = $this->getConfigurations();
     // number of records that should be written to the database in one action
     $this->amountOfRecordsToSaveInMem = 500;
     // register additional fields which should be written to DB
     if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['registerAdditionalFields'])) {
         foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['registerAdditionalFields'] as $_classRef) {
             if (TYPO3_VERSION_INTEGER >= 7000000) {
                 $_procObj =& TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj($_classRef);
             } else {
                 $_procObj =& t3lib_div::getUserObj($_classRef);
             }
             $_procObj->registerAdditionalFields($this->additionalFields);
         }
     }
     // set some prepare statements
     $this->prepareStatements();
     foreach ($configurations as $indexerConfig) {
         $this->indexerConfig = $indexerConfig;
         // run default indexers shipped with ke_search
         if (in_array($this->indexerConfig['type'], $this->defaultIndexerTypes)) {
             if (TYPO3_VERSION_INTEGER < 6002000) {
                 $path = t3lib_extMgm::extPath('ke_search') . 'Classes/indexer/types/class.tx_kesearch_indexer_types_' . $this->indexerConfig['type'] . '.php';
             } else {
                 $path = TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('ke_search') . 'Classes/indexer/types/class.tx_kesearch_indexer_types_' . $this->indexerConfig['type'] . '.php';
             }
             if (is_file($path)) {
                 require_once $path;
                 if (TYPO3_VERSION_INTEGER >= 6002000) {
                     $searchObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('tx_kesearch_indexer_types_' . $this->indexerConfig['type'], $this);
                 } else {
                     $searchObj = t3lib_div::makeInstance('tx_kesearch_indexer_types_' . $this->indexerConfig['type'], $this);
                 }
                 $content .= $searchObj->startIndexing();
             } else {
                 $content = '<div class="error"> Could not find file ' . $path . '</div>' . "\n";
             }
         }
         // hook for custom indexer
         if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['customIndexer'])) {
             foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['customIndexer'] as $_classRef) {
                 if (TYPO3_VERSION_INTEGER >= 7000000) {
                     $_procObj =& TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj($_classRef);
                 } else {
                     $_procObj =& t3lib_div::getUserObj($_classRef);
                 }
                 $content .= $_procObj->customIndexer($indexerConfig, $this);
             }
         }
         // In most cases there are some records waiting in ram to be written to db
         $this->storeTempRecordsToIndex('both');
     }
     // process index cleanup
     $content .= $this->cleanUpIndex();
     // count index records
     $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('*', 'tx_kesearch_index');
     $content .= '<p><b>Index contains ' . $count . ' entries.</b></p>';
     // clean up process after indezing to free memory
     $this->cleanUpProcessAfterIndexing();
     // print indexing errors
     if (sizeof($this->indexingErrors)) {
         $content .= "\n\n" . '<br /><br /><br /><b>INDEXING ERRORS (' . sizeof($this->indexingErrors) . ')<br /><br />' . CHR(10);
         foreach ($this->indexingErrors as $error) {
             $content .= $error . '<br />' . CHR(10);
         }
     }
     // create plaintext report
     $plaintextReport = $this->createPlaintextReport($content);
     // send notification in CLI mode
     if ($mode == 'CLI') {
         // send finishNotification
         if (TYPO3_VERSION_INTEGER >= 7000000) {
             $isValidEmail = TYPO3\CMS\Core\Utility\GeneralUtility::validEmail($extConf['notificationRecipient']);
         } else {
             $isValidEmail = t3lib_div::validEmail($extConf['notificationRecipient']);
         }
         if ($extConf['finishNotification'] && $isValidEmail) {
             // send the notification message
             // use swiftmailer in 4.5 and above
             if (TYPO3_VERSION_INTEGER >= 4005000) {
                 if (TYPO3_VERSION_INTEGER >= 7000000) {
                     $mail = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Mail\\MailMessage');
                 } else {
                     if (TYPO3_VERSION_INTEGER >= 6002000) {
                         $mail = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('t3lib_mail_Message');
                     } else {
                         $mail = t3lib_div::makeInstance('t3lib_mail_Message');
                     }
                 }
                 $mail->setFrom(array($extConf['notificationSender']));
                 $mail->setTo(array($extConf['notificationRecipient']));
                 $mail->setSubject($extConf['notificationSubject']);
                 $mail->setBody($plaintextReport);
                 $mail->send();
             } else {
                 mail($extConf['notificationRecipient'], $subject, $plaintextReport);
             }
         }
     }
     // log report to sys_log
     $GLOBALS['BE_USER']->simplelog($plaintextReport, 'ke_search');
     // verbose or quiet output? as set in function call!
     if ($verbose) {
         return $content;
     }
 }