diff --git a/index.php b/index.php
index fcacf5da0d77eb9670d0bfcb263b5b6bab208366..e24c525274fe1a28b73888f6f16b552aa1683a26 100644
--- a/index.php
+++ b/index.php
@@ -30,11 +30,4 @@ if (version_compare(PHP_VERSION, '5.5.0', '<')) {
 define('TYPO3_MODE', 'FE');
 
 require __DIR__ . '/typo3/sysext/core/Classes/Core/Bootstrap.php';
-\TYPO3\CMS\Core\Core\Bootstrap::getInstance()
-	->baseSetup('')
-	->redirectToInstallerIfEssentialConfigurationDoesNotExist()
-	->startOutputBuffering()
-	->loadConfigurationAndInitialize();
-
-$frontendRequestHandler = new \TYPO3\CMS\Frontend\FrontendRequestHandler();
-$frontendRequestHandler->handleRequest();
+\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->run()->shutdown();
diff --git a/typo3/ajax.php b/typo3/ajax.php
index 98503819b4eb2f15de3817d22a8a129bd4040b46..fbe1263e02bfc6ef17da97bf666b09609fca643a 100644
--- a/typo3/ajax.php
+++ b/typo3/ajax.php
@@ -14,77 +14,12 @@
 
 /**
  * AJAX dispatcher
- *
- * @author Benjamin Mack <mack@xnos.org>
+ * main entry point for AJAX calls in the TYPO3 Backend. Based on $TYPO3_AJAX the Bootstrap let's the request
+ * handled by TYPO3\CMS\Backend\AjaxRequestHandler and AjaxController.
+ * See $TYPO3_CONF_VARS['BE']['AJAX'] and the Core APIs on how to register an AJAX call in the TYPO3 Backend.
  */
-
 $TYPO3_AJAX = TRUE;
+define('TYPO3_MODE', 'BE');
 
-// This is a list of requests that don't necessarily need a valid BE user
-$noUserAjaxIDs = array(
-	'BackendLogin::login',
-	'BackendLogin::logout',
-	'BackendLogin::refreshLogin',
-	'BackendLogin::isTimedOut',
-	'BackendLogin::getChallenge',
-	'BackendLogin::getRsaPublicKey',
-);
-
-// First get the ajaxID
-$ajaxID = isset($_POST['ajaxID']) ? $_POST['ajaxID'] : $_GET['ajaxID'];
-if (isset($ajaxID)) {
-	$ajaxID = (string)stripslashes($ajaxID);
-}
-
-// If we're trying to do an ajax login, don't require a user.
-if (in_array($ajaxID, $noUserAjaxIDs)) {
-	define('TYPO3_PROCEED_IF_NO_USER', 2);
-}
-
-require __DIR__ . '/init.php';
-
-// Finding the script path from the registry
-$ajaxRegistryEntry = isset($GLOBALS['TYPO3_CONF_VARS']['BE']['AJAX'][$ajaxID]) ? $GLOBALS['TYPO3_CONF_VARS']['BE']['AJAX'][$ajaxID] : NULL;
-$ajaxScript = NULL;
-$csrfTokenCheck = FALSE;
-if ($ajaxRegistryEntry !== NULL) {
-	if (is_array($ajaxRegistryEntry)) {
-		if (isset($ajaxRegistryEntry['callbackMethod'])) {
-			$ajaxScript = $ajaxRegistryEntry['callbackMethod'];
-			$csrfTokenCheck = $ajaxRegistryEntry['csrfTokenCheck'];
-		}
-	} else {
-		// @Deprecated since 6.2 will be removed two versions later
-		$ajaxScript = $ajaxRegistryEntry;
-	}
-}
-
-// Instantiating the AJAX object
-$ajaxObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Http\AjaxRequestHandler::class, $ajaxID);
-$ajaxParams = array();
-
-// Evaluating the arguments and calling the AJAX method/function
-if (empty($ajaxID)) {
-	$ajaxObj->setError('No valid ajaxID parameter given.');
-} elseif (empty($ajaxScript)) {
-	$ajaxObj->setError('No backend function registered for ajaxID "' . $ajaxID . '".');
-} else {
-	$success = TRUE;
-	$tokenIsValid = TRUE;
-	if ($csrfTokenCheck) {
-		$tokenIsValid = \TYPO3\CMS\Core\FormProtection\FormProtectionFactory::get()->validateToken(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('ajaxToken'), 'ajaxCall', $ajaxID);
-	}
-	if ($tokenIsValid) {
-		// Cleanup global variable space
-		unset($csrfTokenCheck, $ajaxRegistryEntry, $tokenIsValid, $success);
-		$success = \TYPO3\CMS\Core\Utility\GeneralUtility::callUserFunction($ajaxScript, $ajaxParams, $ajaxObj, FALSE, TRUE);
-	} else {
-		$ajaxObj->setError('Invalid CSRF token detected for ajaxID "' . $ajaxID . '"!');
-	}
-	if ($success === FALSE) {
-		$ajaxObj->setError('Registered backend function for ajaxID "' . $ajaxID . '" was not found.');
-	}
-}
-
-// Outputting the content (and setting the X-JSON-Header)
-$ajaxObj->render();
+require __DIR__ . '/sysext/core/Classes/Core/Bootstrap.php';
+\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->run('typo3/')->shutdown();
diff --git a/typo3/cli_dispatch.phpsh b/typo3/cli_dispatch.phpsh
index 3eaf59e57f59a83b4d3d6daaa72b7cb2c43b028e..1bc8ed2ec924bac7d23bc0f440ac394243f5fe1d 100755
--- a/typo3/cli_dispatch.phpsh
+++ b/typo3/cli_dispatch.phpsh
@@ -30,29 +30,4 @@ require __DIR__ . '/sysext/core/Classes/Core/CliBootstrap.php';
 \TYPO3\CMS\Core\Core\CliBootstrap::checkEnvironmentOrDie();
 
 require __DIR__ . '/sysext/core/Classes/Core/Bootstrap.php';
-\TYPO3\CMS\Core\Core\Bootstrap::getInstance()
-	->baseSetup('typo3/')
-	->loadConfigurationAndInitialize()
-	->loadTypo3LoadedExtAndExtLocalconf(TRUE)
-	->applyAdditionalConfigurationSettings()
-	->initializeTypo3DbGlobal();
-
-\TYPO3\CMS\Core\Core\CliBootstrap::initializeCliKeyOrDie();
-
-\TYPO3\CMS\Core\Core\Bootstrap::getInstance()
-	->loadExtensionTables(TRUE)
-	->initializeBackendUser()
-	->initializeBackendAuthentication()
-	->initializeLanguageObject();
-
-	// Make sure output is not buffered, so command-line output and interaction can take place
-\TYPO3\CMS\Core\Utility\GeneralUtility::flushOutputBuffers();
-
-try {
-	include(TYPO3_cliInclude);
-} catch (\Exception $e) {
-	fwrite(STDERR, $e->getMessage() . LF);
-	exit(99);
-}
-
-\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->shutdown();
+\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->run('typo3/')->shutdown();
diff --git a/typo3/init.php b/typo3/init.php
index 49d6ced88cbb674426fd6e3eba8635b6612bc36d..235b9c8f92bd2fe96d59903f8770f1cd649bfda9 100644
--- a/typo3/init.php
+++ b/typo3/init.php
@@ -35,30 +35,12 @@
  * For a detailed description of this script, the scope of constants and variables in it,
  * please refer to the document "Inside TYPO3"
  *
+ * Please note that this file might be removed in the future in favor of adding these lines to all entry
+ * scripts as well.
+ *
  * @author Kasper Skårhøj <kasperYYYY@typo3.com>
  */
 define('TYPO3_MODE', 'BE');
 
 require __DIR__ . '/sysext/core/Classes/Core/Bootstrap.php';
-
-\TYPO3\CMS\Core\Core\Bootstrap::getInstance()
-	->baseSetup('typo3/')
-	->redirectToInstallerIfEssentialConfigurationDoesNotExist('../')
-	->startOutputBuffering()
-	->loadConfigurationAndInitialize()
-	->loadTypo3LoadedExtAndExtLocalconf(TRUE)
-	->applyAdditionalConfigurationSettings()
-	->initializeTypo3DbGlobal()
-	->checkLockedBackendAndRedirectOrDie()
-	->checkBackendIpOrDie()
-	->checkSslBackendAndRedirectIfNeeded()
-	->checkValidBrowserOrDie()
-	->loadExtensionTables(TRUE)
-	->initializeSpriteManager()
-	->initializeBackendUser()
-	->initializeBackendAuthentication()
-	->initializeLanguageObject()
-	->initializeBackendTemplate()
-	->endOutputBufferingAndCleanPreviousOutput()
-	->initializeOutputCompression()
-	->sendHttpHeaders();
+\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->run('typo3/');
diff --git a/typo3/sysext/backend/Classes/AjaxRequestHandler.php b/typo3/sysext/backend/Classes/AjaxRequestHandler.php
new file mode 100644
index 0000000000000000000000000000000000000000..fb96fd3f65e3bd9d69dbc4bdd7cd18770b9046ad
--- /dev/null
+++ b/typo3/sysext/backend/Classes/AjaxRequestHandler.php
@@ -0,0 +1,154 @@
+<?php
+namespace TYPO3\CMS\Backend;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Core\Core\Bootstrap;
+use TYPO3\CMS\Core\Core\RequestHandlerInterface;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * Base class for all AJAX-related calls for the TYPO3 Backend run through typo3/ajax.php.
+ * Before doing the basic BE-related set up of this request (see the additional calls on $this->bootstrap inside
+ * handleRequest()), some AJAX-calls can be made without a valid user, which is determined here.
+ *
+ * Due to legacy reasons, the actual logic is in EXT:core/Http/AjaxRequestHandler which will eventually
+ * be moved into this class.
+ * In the future, the logic for "TYPO3_PROCEED_IF_NO_USER" will be moved in here as well.
+ */
+class AjaxRequestHandler implements RequestHandlerInterface {
+
+	/**
+	 * Instance of the current TYPO3 bootstrap
+	 * @var Bootstrap
+	 */
+	protected $bootstrap;
+
+	/**
+	 * Constructor handing over the bootstrap
+	 *
+	 * @param Bootstrap $bootstrap
+	 */
+	public function __construct(Bootstrap $bootstrap) {
+		$this->bootstrap = $bootstrap;
+	}
+
+	/**
+	 * Handles any AJAX request in the TYPO3 Backend
+	 *
+	 * @return void
+	 */
+	public function handleRequest() {
+
+		// This is a list of requests that don't necessarily need a valid BE user
+		$noUserAjaxIDs = array(
+			'BackendLogin::login',
+			'BackendLogin::logout',
+			'BackendLogin::refreshLogin',
+			'BackendLogin::isTimedOut',
+			'BackendLogin::getChallenge',
+			'BackendLogin::getRsaPublicKey',
+		);
+
+		// First get the ajaxID
+		$ajaxID = isset($_POST['ajaxID']) ? $_POST['ajaxID'] : $_GET['ajaxID'];
+		if (isset($ajaxID)) {
+			$ajaxID = (string)stripslashes($ajaxID);
+		}
+
+		// If we're trying to do an ajax login, don't require a user.
+		if (in_array($ajaxID, $noUserAjaxIDs)) {
+			define('TYPO3_PROCEED_IF_NO_USER', 2);
+		}
+
+		$this->bootstrap
+			->checkLockedBackendAndRedirectOrDie()
+			->checkBackendIpOrDie()
+			->checkSslBackendAndRedirectIfNeeded()
+			->checkValidBrowserOrDie()
+			->loadExtensionTables(TRUE)
+			->initializeSpriteManager()
+			->initializeBackendUser()
+			->initializeBackendAuthentication()
+			->initializeLanguageObject()
+			->initializeBackendTemplate()
+			->endOutputBufferingAndCleanPreviousOutput()
+			->initializeOutputCompression()
+			->sendHttpHeaders();
+
+		// Finding the script path from the registry
+		$ajaxRegistryEntry = isset($GLOBALS['TYPO3_CONF_VARS']['BE']['AJAX'][$ajaxID]) ? $GLOBALS['TYPO3_CONF_VARS']['BE']['AJAX'][$ajaxID] : NULL;
+		$ajaxScript = NULL;
+		$csrfTokenCheck = FALSE;
+		if ($ajaxRegistryEntry !== NULL) {
+			if (is_array($ajaxRegistryEntry)) {
+				if (isset($ajaxRegistryEntry['callbackMethod'])) {
+					$ajaxScript = $ajaxRegistryEntry['callbackMethod'];
+					$csrfTokenCheck = $ajaxRegistryEntry['csrfTokenCheck'];
+				}
+			} else {
+				// @deprecated since 6.2 will be removed two versions later
+				$ajaxScript = $ajaxRegistryEntry;
+			}
+		}
+
+		// Instantiating the AJAX object
+		$ajaxObj = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Http\AjaxRequestHandler::class, $ajaxID);
+		$ajaxParams = array();
+
+		// Evaluating the arguments and calling the AJAX method/function
+		if (empty($ajaxID)) {
+			$ajaxObj->setError('No valid ajaxID parameter given.');
+		} elseif (empty($ajaxScript)) {
+			$ajaxObj->setError('No backend function registered for ajaxID "' . $ajaxID . '".');
+		} else {
+			$success = TRUE;
+			$tokenIsValid = TRUE;
+			if ($csrfTokenCheck) {
+				$tokenIsValid = \TYPO3\CMS\Core\FormProtection\FormProtectionFactory::get()->validateToken(GeneralUtility::_GP('ajaxToken'), 'ajaxCall', $ajaxID);
+			}
+			if ($tokenIsValid) {
+				// Cleanup global variable space
+				unset($csrfTokenCheck, $ajaxRegistryEntry, $tokenIsValid, $success);
+				$success = GeneralUtility::callUserFunction($ajaxScript, $ajaxParams, $ajaxObj, FALSE, TRUE);
+			} else {
+				$ajaxObj->setError('Invalid CSRF token detected for ajaxID "' . $ajaxID . '"!');
+			}
+			if ($success === FALSE) {
+				$ajaxObj->setError('Registered backend function for ajaxID "' . $ajaxID . '" was not found.');
+			}
+		}
+
+		// Outputting the content (and setting the X-JSON-Header)
+		$ajaxObj->render();
+	}
+
+	/**
+	 * This request handler can handle any backend request coming from ajax.php
+	 *
+	 * @return bool If the request is an AJAX backend request, TRUE otherwise FALSE
+	 */
+	public function canHandleRequest() {
+		return TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_AJAX;
+	}
+
+	/**
+	 * Returns the priority - how eager the handler is to actually handle the request.
+	 *
+	 * @return int The priority of the request handler.
+	 */
+	public function getPriority() {
+		return 80;
+	}
+}
diff --git a/typo3/sysext/backend/Classes/CliRequestHandler.php b/typo3/sysext/backend/Classes/CliRequestHandler.php
new file mode 100644
index 0000000000000000000000000000000000000000..fe6f88313ff51ec4a3168805a851897563e4658d
--- /dev/null
+++ b/typo3/sysext/backend/Classes/CliRequestHandler.php
@@ -0,0 +1,140 @@
+<?php
+namespace TYPO3\CMS\Backend;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Core\Core\Bootstrap;
+use TYPO3\CMS\Core\Core\RequestHandlerInterface;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * Command Line Interface Request Handler dealing with "cliKey"-based Commands from the cli_dispatch.phpsh script.
+ * Picks up requests only when coming from the CLI mode.
+ * Resolves the "cliKey" which is registered inside $TYPO3_CONF_VARS[SC_OPTIONS][GLOBAL][cliKeys]
+ * and includes the CLI-based script or exits if no valid "cliKey" is found.
+ */
+class CliRequestHandler implements RequestHandlerInterface {
+
+	/**
+	 * Instance of the current TYPO3 bootstrap
+	 * @var Bootstrap
+	 */
+	protected $bootstrap;
+
+	/**
+	 * Constructor handing over the bootstrap
+	 *
+	 * @param Bootstrap $bootstrap
+	 */
+	public function __construct(Bootstrap $bootstrap) {
+		$this->bootstrap = $bootstrap;
+	}
+
+	/**
+	 * Handles any commandline request
+	 *
+	 * @return void
+	 */
+	public function handleRequest() {
+		$commandLineKey = $this->getCommandLineKeyOrDie();
+		$commandLineScript = $this->getIncludeScriptByCommandLineKey($commandLineKey);
+
+		$this->bootstrap
+			->loadExtensionTables(TRUE)
+			->initializeBackendUser()
+			->initializeBackendAuthentication()
+			->initializeLanguageObject();
+
+		// Make sure output is not buffered, so command-line output and interaction can take place
+		GeneralUtility::flushOutputBuffers();
+
+		try {
+			include($commandLineScript);
+		} catch (\Exception $e) {
+			fwrite(STDERR, $e->getMessage() . LF);
+			exit(99);
+		}
+	}
+
+	/**
+	 * Check CLI parameters.
+	 * First argument is a key that points to the script configuration.
+	 * If it is not set or not valid, the script exits with an error message.
+	 *
+	 * @return string the CLI key in use
+	 */
+	protected function getCommandLineKeyOrDie() {
+		$cliKey = $_SERVER['argv'][1];
+		$errorMessage = '';
+		if (empty($cliKey)) {
+			$errorMessage = 'This script must have a \'cliKey\' as first argument.';
+		} elseif (!is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['cliKeys'][$cliKey])) {
+			$errorMessage = 'The supplied \'cliKey\' is not valid.';
+		}
+
+		// exit with an error message
+		if (!empty($errorMessage)) {
+			$errorMessage .= ' Valid keys are:
+
+';
+			$cliKeys = array_keys($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['cliKeys']);
+			asort($cliKeys);
+			foreach ($cliKeys as $key => $value) {
+				$errorMessage .= '  ' . $value . LF;
+			}
+			fwrite(STDERR, $errorMessage . LF);
+			die(1);
+		}
+
+		return $cliKey;
+	}
+
+	/**
+	 * Define cli-related parameters and return the include script.
+	 *
+	 * @param string $cliKey the CLI key
+	 * @return string the absolute path to the include script
+	 */
+	protected function getIncludeScriptByCommandLineKey($cliKey) {
+		list($commandLineScript, $commandLineName) = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['cliKeys'][$cliKey];
+		$commandLineScript = GeneralUtility::getFileAbsFileName($commandLineScript);
+		// Note: These constants are not in use anymore
+		define('TYPO3_cliKey', $cliKey);
+		define('TYPO3_cliInclude', $commandLineScript);
+		$GLOBALS['MCONF']['name'] = $commandLineName;
+		// This is a compatibility layer: Some cli scripts rely on this, like ext:phpunit cli
+		$GLOBALS['temp_cliScriptPath'] = array_shift($_SERVER['argv']);
+		$GLOBALS['temp_cliKey'] = array_shift($_SERVER['argv']);
+		array_unshift($_SERVER['argv'], $GLOBALS['temp_cliScriptPath']);
+		return $commandLineScript;
+	}
+
+	/**
+	 * This request handler can handle any CLI request .
+	 *
+	 * @return bool If the request is a CLI request, TRUE otherwise FALSE
+	 */
+	public function canHandleRequest() {
+		return defined('TYPO3_cliMode') && (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_BE) && (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI);
+	}
+
+	/**
+	 * Returns the priority - how eager the handler is to actually handle the request.
+	 *
+	 * @return int The priority of the request handler.
+	 */
+	public function getPriority() {
+		return 50;
+	}
+}
diff --git a/typo3/sysext/backend/Classes/RequestHandler.php b/typo3/sysext/backend/Classes/RequestHandler.php
new file mode 100644
index 0000000000000000000000000000000000000000..23be5e2ca6a542a490d6063896cc84c51bc097fa
--- /dev/null
+++ b/typo3/sysext/backend/Classes/RequestHandler.php
@@ -0,0 +1,84 @@
+<?php
+namespace TYPO3\CMS\Backend;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Core\Core\Bootstrap;
+use TYPO3\CMS\Core\Core\RequestHandlerInterface;
+
+/**
+ * General RequestHandler for the TYPO3 Backend. This is used for all Backend requests except for CLI
+ * or AJAX calls. Unlike all other RequestHandlers in the TYPO3 CMS Core, the actual logic for choosing
+ * the controller is still done inside places like mod.php and each single file.
+ * This RequestHandler here serves solely to check and set up all requirements needed for a TYPO3 Backend.
+ * This class might be changed in the future.
+ */
+class RequestHandler implements RequestHandlerInterface {
+
+	/**
+	 * Instance of the current TYPO3 bootstrap
+	 * @var Bootstrap
+	 */
+	protected $bootstrap;
+
+	/**
+	 * Constructor handing over the bootstrap
+	 *
+	 * @param Bootstrap $bootstrap
+	 */
+	public function __construct(Bootstrap $bootstrap) {
+		$this->bootstrap = $bootstrap;
+	}
+
+	/**
+	 * Handles any backend request
+	 *
+	 * @return void
+	 */
+	public function handleRequest() {
+		$this->bootstrap
+			->checkLockedBackendAndRedirectOrDie()
+			->checkBackendIpOrDie()
+			->checkSslBackendAndRedirectIfNeeded()
+			->checkValidBrowserOrDie()
+			->loadExtensionTables(TRUE)
+			->initializeSpriteManager()
+			->initializeBackendUser()
+			->initializeBackendAuthentication()
+			->initializeLanguageObject()
+			->initializeBackendTemplate()
+			->endOutputBufferingAndCleanPreviousOutput()
+			->initializeOutputCompression()
+			->sendHttpHeaders();
+	}
+
+	/**
+	 * This request handler can handle any backend request (but not CLI).
+	 *
+	 * @return bool If the request is not a CLI script, TRUE otherwise FALSE
+	 */
+	public function canHandleRequest() {
+		return (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_BE && !(TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI));
+	}
+
+	/**
+	 * Returns the priority - how eager the handler is to actually handle the
+	 * request.
+	 *
+	 * @return int The priority of the request handler.
+	 */
+	public function getPriority() {
+		return 50;
+	}
+}
diff --git a/typo3/sysext/core/Classes/Core/Bootstrap.php b/typo3/sysext/core/Classes/Core/Bootstrap.php
index b6f35f5155eac83e4b2d0b0f02e803eff7f74ec1..2af75563701e6dd0e3ef35a304c2228fa04c6eed 100644
--- a/typo3/sysext/core/Classes/Core/Bootstrap.php
+++ b/typo3/sysext/core/Classes/Core/Bootstrap.php
@@ -70,6 +70,12 @@ class Bootstrap {
 	 */
 	protected $activeErrorHandlerClassName;
 
+	/**
+	 * registered request handlers
+	 * @var RequestHandlerInterface[]
+	 */
+	protected $availableRequestHandlers = array();
+
 	/**
 	 * @var bool
 	 */
@@ -151,6 +157,45 @@ class Bootstrap {
 		return $this;
 	}
 
+	/**
+	 * Main entry point called at every request usually from Global scope. Checks if everthing is correct,
+	 * and sets up the base request information for a regular request, then
+	 * resolves the RequestHandler which handles the request.
+	 *
+	 * @param string $relativePathPart Relative path of entry script back to document root
+	 * @return Bootstrap
+	 */
+	public function run($relativePathPart = '') {
+		$this->baseSetup($relativePathPart);
+
+		// Failsafe minimal setup mode for the install tool
+		if (defined('TYPO3_enterInstallScript')) {
+			$this->startOutputBuffering()
+				->loadConfigurationAndInitialize(FALSE, \TYPO3\CMS\Core\Package\FailsafePackageManager::class);
+		} elseif (!$this->checkIfEssentialConfigurationExists() && !defined('TYPO3_cliMode')) {
+			// Redirect to install tool if base configuration is not found
+			$backPathToSiteRoot = '';
+			$pathParts = explode('/', $relativePathPart);
+			for ($i = 1; $i <= count($pathParts); $i++) {
+				$backPathToSiteRoot .= '../';
+			}
+			$this->redirectToInstallTool($backPathToSiteRoot);
+		} else {
+			// Regular request (Frontend, AJAX, Backend, CLI)
+			$this->startOutputBuffering()
+				->loadConfigurationAndInitialize()
+				->loadTypo3LoadedExtAndExtLocalconf(TRUE)
+				->applyAdditionalConfigurationSettings()
+				->initializeTypo3DbGlobal();
+		}
+
+		// Resolve request handler that were registered based on TYPO3_MODE
+		$this->registerRequestHandlers();
+		$requestHandler = $this->resolveRequestHandler();
+		$requestHandler->handleRequest();
+		return $this;
+	}
+
 	/**
 	 * Run the base setup that checks server environment, determines pathes,
 	 * populates base files and sets common configuration.
@@ -208,25 +253,86 @@ class Bootstrap {
 		}
 	}
 
+	/**
+	 * checks if LocalConfiguration.php or PackageStates.php is missing,
+	 * used to see if a redirect to the install tool is needed
+	 *
+	 * @return bool TRUE when the essential configuration is available, otherwise FALSE
+	 */
+	protected function checkIfEssentialConfigurationExists() {
+		$configurationManager = new \TYPO3\CMS\Core\Configuration\ConfigurationManager;
+		$this->setEarlyInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class, $configurationManager);
+		return (!file_exists($configurationManager->getLocalConfigurationFileLocation()) || !file_exists(PATH_typo3conf . 'PackageStates.php')) ? FALSE : TRUE;
+	}
+
 	/**
 	 * Redirect to install tool if LocalConfiguration.php is missing.
 	 *
 	 * @param string $pathUpToDocumentRoot Can contain '../' if called from a sub directory
+	 * @internal This is not a public API method, do not use in own extensions
+	 */
+	public function redirectToInstallTool($pathUpToDocumentRoot = '') {
+		define('TYPO3_enterInstallScript', '1');
+		$this->defineTypo3RequestTypes();
+		Utility\HttpUtility::redirect($pathUpToDocumentRoot . 'typo3/sysext/install/Start/Install.php');
+	}
+
+	/**
+	 * Adds available request handlers, which currently hard-coded here based on the TYPO3_MODE. The extensability
+	 * of adding own request handlers would be too complex for now, but can be added later.
+	 *
 	 * @return Bootstrap
 	 * @internal This is not a public API method, do not use in own extensions
 	 */
-	public function redirectToInstallerIfEssentialConfigurationDoesNotExist($pathUpToDocumentRoot = '') {
-		$configurationManager = new \TYPO3\CMS\Core\Configuration\ConfigurationManager;
-		$this->setEarlyInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class, $configurationManager);
-		if (!file_exists($configurationManager->getLocalConfigurationFileLocation()) || !file_exists(PATH_typo3conf . 'PackageStates.php')) {
-			define('TYPO3_enterInstallScript', '1');
-			$this->defineTypo3RequestTypes();
-			require_once __DIR__ . '/../Utility/HttpUtility.php';
-			Utility\HttpUtility::redirect($pathUpToDocumentRoot . 'typo3/sysext/install/Start/Install.php');
+	protected function registerRequestHandlers() {
+		// Use the install tool handler if in install tool mode
+		if (!$this->checkIfEssentialConfigurationExists() || (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_INSTALL)) {
+			$this->availableRequestHandlers = array(
+				\TYPO3\CMS\Install\RequestHandler::class
+			);
+		} elseif (TYPO3_MODE == 'BE') {
+			$this->availableRequestHandlers = array(
+				\TYPO3\CMS\Backend\RequestHandler::class,
+				\TYPO3\CMS\Backend\AjaxRequestHandler::class,
+				\TYPO3\CMS\Backend\CliRequestHandler::class
+			);
+		} elseif (TYPO3_MODE == 'FE') {
+			$this->availableRequestHandlers = array(
+				\TYPO3\CMS\Frontend\RequestHandler::class,
+				\TYPO3\CMS\Frontend\EidRequestHandler::class
+			);
 		}
 		return $this;
 	}
 
+	/**
+	 * Fetches the request handler that suits the best based on the priority and the interface
+	 * Be sure to always have the constants that are defined in $this->defineTypo3RequestTypes() are set,
+	 * so most RequestHandlers can check if they can handle the request.
+	 *
+	 * @return RequestHandlerInterface
+	 * @throws \TYPO3\CMS\Core\Exception
+	 * @internal This is not a public API method, do not use in own extensions
+	 */
+	public function resolveRequestHandler() {
+		$suitableRequestHandlers = array();
+		foreach ($this->availableRequestHandlers as $requestHandlerClassName) {
+			$requestHandler = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($requestHandlerClassName, $this);
+			if ($requestHandler->canHandleRequest()) {
+				$priority = $requestHandler->getPriority();
+				if (isset($suitableRequestHandlers[$priority])) {
+					throw new \TYPO3\CMS\Core\Exception('More than one request handler with the same priority can handle the request, but only one handler may be active at a time!', 1176471352);
+				}
+				$suitableRequestHandlers[$priority] = $requestHandler;
+			}
+		}
+		if (count($suitableRequestHandlers) === 0) {
+			throw new \TYPO3\CMS\Core\Exception('No suitable request handler found.', 1225418233);
+		}
+		ksort($suitableRequestHandlers);
+		return array_pop($suitableRequestHandlers);
+	}
+
 	/**
 	 * Registers the instance of the specified object for an early boot stage.
 	 * On finalizing the Object Manager initialization, all those instances will
diff --git a/typo3/sysext/core/Classes/Core/CliBootstrap.php b/typo3/sysext/core/Classes/Core/CliBootstrap.php
index 5f3ced9f1bad656bd80a48a6f4444ccf31e2b967..daedab43b63082f73201925985edd055d2759815 100644
--- a/typo3/sysext/core/Classes/Core/CliBootstrap.php
+++ b/typo3/sysext/core/Classes/Core/CliBootstrap.php
@@ -39,41 +39,6 @@ class CliBootstrap {
 		}
 	}
 
-	/**
-	 * Check and define cli parameters.
-	 * First argument is a key that points to the script configuration.
-	 * If it is not set or not valid, the script exits with an error message.
-	 *
-	 * @return void
-	 * @internal This is not a public API method, do not use in own extensions
-	 */
-	static public function initializeCliKeyOrDie() {
-		if (!isset($_SERVER['argv'][1]) || !is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['cliKeys'][$_SERVER['argv'][1]])) {
-			if (!isset($_SERVER['argv'][1])) {
-				$message = 'This script must have a \'cliKey\' as first argument.';
-			} else {
-				$message = 'The supplied \'cliKey\' is not valid.';
-			}
-			$message .= ' Valid keys are:
-
-';
-			$cliKeys = array_keys($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['cliKeys']);
-			asort($cliKeys);
-			foreach ($cliKeys as $key => $value) {
-				$message .= '  ' . $value . LF;
-			}
-			fwrite(STDERR, $message . LF);
-			die(1);
-		}
-		define('TYPO3_cliKey', $_SERVER['argv'][1]);
-		define('TYPO3_cliInclude', \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['cliKeys'][TYPO3_cliKey][0]));
-		$GLOBALS['MCONF']['name'] = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['cliKeys'][TYPO3_cliKey][1];
-		// This is a compatibility layer: Some cli scripts rely on this, like ext:phpunit cli
-		$GLOBALS['temp_cliScriptPath'] = array_shift($_SERVER['argv']);
-		$GLOBALS['temp_cliKey'] = array_shift($_SERVER['argv']);
-		array_unshift($_SERVER['argv'], $GLOBALS['temp_cliScriptPath']);
-	}
-
 	/**
 	 * Set up cgi sapi as de facto cli, but check no HTTP
 	 * environment variables are set.
diff --git a/typo3/sysext/core/Classes/Core/RequestHandlerInterface.php b/typo3/sysext/core/Classes/Core/RequestHandlerInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..cdddae390b09af1602afd3fee9da3ef858a4904a
--- /dev/null
+++ b/typo3/sysext/core/Classes/Core/RequestHandlerInterface.php
@@ -0,0 +1,50 @@
+<?php
+namespace TYPO3\CMS\Core\Core;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/**
+ * The interface for a request handler
+ * see FrontendRequestHandler
+ *
+ * @api
+ */
+interface RequestHandlerInterface {
+
+	/**
+	 * Handles a raw request
+	 *
+	 * @return void
+	 * @api
+	 */
+	public function handleRequest();
+
+	/**
+	 * Checks if the request handler can handle the current request.
+	 *
+	 * @return bool TRUE if it can handle the request, otherwise FALSE
+	 * @api
+	 */
+	public function canHandleRequest();
+
+	/**
+	 * Returns the priority - how eager the handler is to actually handle the
+	 * request. An integer > 0 means "I want to handle this request" where
+	 * "100" is default. "0" means "I am a fallback solution".
+	 *
+	 * @return int The priority of the request handler
+	 * @api
+	 */
+	public function getPriority();
+}
diff --git a/typo3/sysext/frontend/Classes/EidRequestHandler.php b/typo3/sysext/frontend/Classes/EidRequestHandler.php
new file mode 100644
index 0000000000000000000000000000000000000000..804d768c0260c82de25107f3978fc80505f2f3e6
--- /dev/null
+++ b/typo3/sysext/frontend/Classes/EidRequestHandler.php
@@ -0,0 +1,84 @@
+<?php
+namespace TYPO3\CMS\Frontend;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Core\Core\Bootstrap;
+use TYPO3\CMS\Frontend\Utility\EidUtility;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Core\RequestHandlerInterface;
+
+/**
+ * Lightweight alternative to the regular RequestHandler used when $_GET[eID] is set.
+ * In the future, logic from the EidUtility will be moved to this class.
+ */
+class EidRequestHandler implements RequestHandlerInterface {
+
+	/**
+	 * Instance of the current TYPO3 bootstrap
+	 * @var Bootstrap
+	 */
+	protected $bootstrap;
+
+	/**
+	 * Constructor handing over the bootstrap
+	 *
+	 * @param Bootstrap $bootstrap
+	 */
+	public function __construct(Bootstrap $bootstrap) {
+		$this->bootstrap = $bootstrap;
+	}
+
+	/**
+	 * Handles a frontend request based on the _GP "eID" variable.
+	 *
+	 * @return void
+	 */
+	public function handleRequest() {
+		// Hook to preprocess the current request
+		if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preprocessRequest'])) {
+			foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preprocessRequest'] as $hookFunction) {
+				$hookParameters = array();
+				GeneralUtility::callUserFunction($hookFunction, $hookParameters, $hookParameters);
+			}
+			unset($hookFunction);
+			unset($hookParameters);
+		}
+
+		// Remove any output produced until now
+		$this->bootstrap->endOutputBufferingAndCleanPreviousOutput();
+		require EidUtility::getEidScriptPath();
+		$this->bootstrap->shutdown();
+		exit;
+	}
+
+	/**
+	 * This request handler can handle any frontend request.
+	 *
+	 * @return bool If the request is not an eID request, TRUE otherwise FALSE
+	 */
+	public function canHandleRequest() {
+		return GeneralUtility::_GP('eID') ? TRUE : FALSE;
+	}
+
+	/**
+	 * Returns the priority - how eager the handler is to actually handle the
+	 * request.
+	 *
+	 * @return int The priority of the request handler.
+	 */
+	public function getPriority() {
+		return 80;
+	}
+}
diff --git a/typo3/sysext/frontend/Classes/FrontendRequestHandler.php b/typo3/sysext/frontend/Classes/RequestHandler.php
similarity index 79%
rename from typo3/sysext/frontend/Classes/FrontendRequestHandler.php
rename to typo3/sysext/frontend/Classes/RequestHandler.php
index dd4bcf55632f5149b272ed33901bf3f247c32c51..85d2ea1090543afd7394b6008bb75fef3e9e7e23 100644
--- a/typo3/sysext/frontend/Classes/FrontendRequestHandler.php
+++ b/typo3/sysext/frontend/Classes/RequestHandler.php
@@ -14,17 +14,35 @@ namespace TYPO3\CMS\Frontend;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Frontend\Utility\EidUtility;
+use TYPO3\CMS\Core\Core\Bootstrap;
+use TYPO3\CMS\Core\Core\RequestHandlerInterface;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
- * This is the MAIN DOCUMENT of the TypoScript driven standard front-end
+ * This is the main entry point of the TypoScript driven standard front-end
  *
- * Basically put this is the script which all requests for TYPO3
- * delivered pages goes to in the frontend (the website). The script configures
- * constants, includes libraries and does a little logic here and there in order
- * to instantiate the right classes to create the webpage.
+ * Basically put, this is the script which all requests for TYPO3 delivered pages goes to in the
+ * frontend (the website). The script instantiates a $TSFE object, includes libraries and does a little logic here
+ * and there in order to instantiate the right classes to create the webpage.
+ * Previously, this was called index_ts.php and also included the logic for the lightweight "eID" concept,
+ * which is now handled in a separate request handler (EidRequestHandler).
  */
-class FrontendRequestHandler {
+class RequestHandler implements RequestHandlerInterface {
+
+	/**
+	 * Instance of the current TYPO3 bootstrap
+	 * @var Bootstrap
+	 */
+	protected $bootstrap;
+
+	/**
+	 * Constructor handing over the bootstrap
+	 *
+	 * @param Bootstrap $bootstrap
+	 */
+	public function __construct(Bootstrap $bootstrap) {
+		$this->bootstrap = $bootstrap;
+	}
 
 	/**
 	 * Handles a frontend request
@@ -32,9 +50,15 @@ class FrontendRequestHandler {
 	 * @return void
 	 */
 	public function handleRequest() {
-		\TYPO3\CMS\Core\Core\Bootstrap::getInstance()
-			->loadTypo3LoadedExtAndExtLocalconf(TRUE)
-			->applyAdditionalConfigurationSettings();
+		// Hook to preprocess the current request:
+		if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preprocessRequest'])) {
+			foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preprocessRequest'] as $hookFunction) {
+				$hookParameters = array();
+				GeneralUtility::callUserFunction($hookFunction, $hookParameters, $hookParameters);
+			}
+			unset($hookFunction);
+			unset($hookParameters);
+		}
 
 		// Timetracking started
 		$configuredCookieName = trim($GLOBALS['TYPO3_CONF_VARS']['BE']['cookieName']);
@@ -49,41 +73,22 @@ class FrontendRequestHandler {
 
 		$GLOBALS['TT']->start();
 
-		\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->initializeTypo3DbGlobal();
-		// Hook to preprocess the current request:
-		if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preprocessRequest'])) {
-			foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preprocessRequest'] as $hookFunction) {
-				$hookParameters = array();
-				\TYPO3\CMS\Core\Utility\GeneralUtility::callUserFunction($hookFunction, $hookParameters, $hookParameters);
-			}
-			unset($hookFunction);
-			unset($hookParameters);
-		}
-		// Look for extension ID which will launch alternative output engine
-		if (EidUtility::isEidRequest()) {
-			// Remove any output produced until now
-			ob_clean();
-			require EidUtility::getEidScriptPath();
-			\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->shutdown();
-			exit;
-		}
-
 		/** @var $GLOBALS['TSFE'] \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController */
-		$GLOBALS['TSFE'] = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
+		$GLOBALS['TSFE'] = GeneralUtility::makeInstance(
 			\TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::class,
 			$GLOBALS['TYPO3_CONF_VARS'],
-			\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('id'),
-			\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('type'),
-			\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('no_cache'),
-			\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('cHash'),
-			\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('jumpurl'),
-			\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('MP'),
-			\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('RDCT')
+			GeneralUtility::_GP('id'),
+			GeneralUtility::_GP('type'),
+			GeneralUtility::_GP('no_cache'),
+			GeneralUtility::_GP('cHash'),
+			GeneralUtility::_GP('jumpurl'),
+			GeneralUtility::_GP('MP'),
+			GeneralUtility::_GP('RDCT')
 		);
 
 		if ($GLOBALS['TYPO3_CONF_VARS']['FE']['pageUnavailable_force']
-			&& !\TYPO3\CMS\Core\Utility\GeneralUtility::cmpIP(
-				\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('REMOTE_ADDR'),
+			&& !GeneralUtility::cmpIP(
+				GeneralUtility::getIndpEnv('REMOTE_ADDR'),
 				$GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask'])
 		) {
 			$GLOBALS['TSFE']->pageUnavailableAndExit('This page is temporarily unavailable.');
@@ -100,7 +105,7 @@ class FrontendRequestHandler {
 				// Prevent errors if ini_set() is unavailable (safe mode)
 				@ini_set('zlib.output_compression_level', $GLOBALS['TYPO3_CONF_VARS']['FE']['compressionLevel']);
 			}
-			ob_start(array(\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\Utility\CompressionUtility::class), 'compressionOutputHandler'));
+			ob_start(array(GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\Utility\CompressionUtility::class), 'compressionOutputHandler'));
 		}
 
 		// FE_USER
@@ -120,9 +125,9 @@ class FrontendRequestHandler {
 		// Initialize admin panel since simulation settings are required here:
 		if ($GLOBALS['TSFE']->isBackendUserLoggedIn()) {
 			$GLOBALS['BE_USER']->initializeAdminPanel();
-			\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->loadExtensionTables(TRUE);
+			$this->bootstrap->loadExtensionTables(TRUE);
 		} else {
-			\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->loadCachedTca();
+			$this->bootstrap->loadCachedTca();
 		}
 		$GLOBALS['TSFE']->checkAlternativeIdMethods();
 		$GLOBALS['TSFE']->clear_preview();
@@ -133,7 +138,7 @@ class FrontendRequestHandler {
 		// \TYPO3\CMS\Version\Hook\PreviewHook might need to know if a backend user is logged in.
 		if (
 			$GLOBALS['TSFE']->isBackendUserLoggedIn()
-			&& (!$GLOBALS['BE_USER']->extPageReadAccess($GLOBALS['TSFE']->page) || \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('ADMCMD_noBeUser'))
+			&& (!$GLOBALS['BE_USER']->extPageReadAccess($GLOBALS['TSFE']->page) || GeneralUtility::_GP('ADMCMD_noBeUser'))
 		) {
 			// Remove user
 			unset($GLOBALS['BE_USER']);
@@ -151,7 +156,7 @@ class FrontendRequestHandler {
 		if ($GLOBALS['TSFE']->isBackendUserLoggedIn()) {
 			$GLOBALS['BE_USER']->initializeFrontendEdit();
 			if ($GLOBALS['BE_USER']->adminPanel instanceof \TYPO3\CMS\Frontend\View\AdminPanelView) {
-				\TYPO3\CMS\Core\Core\Bootstrap::getInstance()
+				$this->bootstrap
 					->initializeLanguageObject()
 					->initializeSpriteManager();
 			}
@@ -284,9 +289,26 @@ class FrontendRequestHandler {
 			$GLOBALS['error']->debugOutput();
 		}
 		if (TYPO3_DLOG) {
-			\TYPO3\CMS\Core\Utility\GeneralUtility::devLog('END of FRONTEND session', 'cms', 0, array('_FLUSH' => TRUE));
+			GeneralUtility::devLog('END of FRONTEND session', 'cms', 0, array('_FLUSH' => TRUE));
 		}
-		\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->shutdown();
 	}
 
+	/**
+	 * This request handler can handle any frontend request.
+	 *
+	 * @return bool If the request is not an eID request, TRUE otherwise FALSE
+	 */
+	public function canHandleRequest() {
+		return GeneralUtility::_GP('eID') ? FALSE : TRUE;
+	}
+
+	/**
+	 * Returns the priority - how eager the handler is to actually handle the
+	 * request.
+	 *
+	 * @return int The priority of the request handler.
+	 */
+	public function getPriority() {
+		return 50;
+	}
 }
diff --git a/typo3/sysext/install/Classes/RequestHandler.php b/typo3/sysext/install/Classes/RequestHandler.php
new file mode 100644
index 0000000000000000000000000000000000000000..007d51170d5f04a22e8ccfdd5682c5fba1d39c42
--- /dev/null
+++ b/typo3/sysext/install/Classes/RequestHandler.php
@@ -0,0 +1,84 @@
+<?php
+namespace TYPO3\CMS\Install;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Core\Core\Bootstrap;
+use TYPO3\CMS\Core\Core\RequestHandlerInterface;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * Default request handler for all requests inside the TYPO3 Install Tool, which does a simple hardcoded
+ * dispatching to a controller based on the get/post variable.
+ *
+ * @package TYPO3\CMS\Install
+ */
+class RequestHandler implements RequestHandlerInterface {
+
+	/**
+	 * Instance of the current TYPO3 bootstrap
+	 * @var Bootstrap
+	 */
+	protected $bootstrap;
+
+	/**
+	 * Constructor handing over the bootstrap
+	 *
+	 * @param Bootstrap $bootstrap
+	 */
+	public function __construct(Bootstrap $bootstrap) {
+		$this->bootstrap = $bootstrap;
+	}
+
+	/**
+	 * Handles an install tool request
+	 * Execute 'tool' or 'step' controller depending on install[controller] GET/POST parameter
+	 *
+	 * @return void
+	 */
+	public function handleRequest() {
+		$getPost = GeneralUtility::_GP('install');
+		switch ($getPost['controller']) {
+			case 'tool':
+				$controllerClassName = Controller\ToolController::class;
+				break;
+			case 'ajax':
+				$controllerClassName = Controller\AjaxController::class;
+				break;
+			default:
+				$controllerClassName = Controller\StepController::class;
+		}
+		GeneralUtility::makeInstance($controllerClassName)->execute();
+	}
+
+	/**
+	 * This request handler can handle any request when not in CLI mode and the install tool flag is set
+	 * please note that both checks are needed, as when in "failsafe" mode, the TYPO3_REQUESTTYPE is not
+	 * necessarily set at this point.
+	 *
+	 * @return bool Returns TRUE if the request is in Install Tool mode, otherwise FALSE
+	 */
+	public function canHandleRequest() {
+		return defined('TYPO3_enterInstallScript') || (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_INSTALL);
+	}
+
+	/**
+	 * Returns the priority - how eager the handler is to actually handle the request.
+	 *
+	 * @return int The priority of the request handler.
+	 */
+	public function getPriority() {
+		return 20;
+	}
+}
diff --git a/typo3/sysext/install/Resources/Private/PHP/Boot.php b/typo3/sysext/install/Resources/Private/PHP/Boot.php
deleted file mode 100644
index 4029796da2cadda3ce9114c2a9238ea80722cde8..0000000000000000000000000000000000000000
--- a/typo3/sysext/install/Resources/Private/PHP/Boot.php
+++ /dev/null
@@ -1,39 +0,0 @@
-<?php
-namespace TYPO3\CMS\Install;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-defined('TYPO3_MODE') or die();
-
-// Bootstrap bare minimum: class loader, LocalConfiguration, but no extensions and such
-require __DIR__ . '/../../../../core/Classes/Core/Bootstrap.php';
-\TYPO3\CMS\Core\Core\Bootstrap::getInstance()
-	->baseSetup('typo3/sysext/install/Start/')
-	->startOutputBuffering()
-	->loadConfigurationAndInitialize(FALSE, \TYPO3\CMS\Core\Package\FailsafePackageManager::class);
-
-// Execute 'tool' or 'step' controller depending on install[controller] GET/POST parameter
-$getPost = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('install');
-$controllerClassName = \TYPO3\CMS\Install\Controller\StepController::class;
-if (isset($getPost['controller'])) {
-	switch ($getPost['controller']) {
-		case 'tool':
-			$controllerClassName = \TYPO3\CMS\Install\Controller\ToolController::class;
-			break;
-		case 'ajax':
-			$controllerClassName = \TYPO3\CMS\Install\Controller\AjaxController::class;
-			break;
-	}
-}
-\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($controllerClassName)->execute();
\ No newline at end of file
diff --git a/typo3/sysext/install/Start/Install.php b/typo3/sysext/install/Start/Install.php
index a014cfe201f1101542a16f780289ee74794a642b..32eb05dfcf5ef1d93c8203b3f7e739ea5cd4ef24 100644
--- a/typo3/sysext/install/Start/Install.php
+++ b/typo3/sysext/install/Start/Install.php
@@ -105,9 +105,6 @@ if (version_compare(PHP_VERSION, '5.5.0', '<')) {
 define('TYPO3_MODE', 'BE');
 define('TYPO3_enterInstallScript', '1');
 
-/*
- * The following functionality must be required from another file, otherwise a parse error
- * "unexpected 'class'" will be shown on PHP 5.4 instead of the die() from version_compare above.
- */
-require __DIR__ . '/../Resources/Private/PHP/Boot.php';
-
+// Bootstrap bare minimum: class loader, LocalConfiguration, but no extensions and such
+require __DIR__ . '/../../core/Classes/Core/Bootstrap.php';
+\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->run('typo3/sysext/install/Start/')->shutdown();