diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index be9821d..3954352 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -9,12 +9,9 @@
 
 use Drupal\Component\ProxyBuilder\ProxyDumper;
 use Drupal\Component\Utility\Crypt;
-use Drupal\Component\Utility\Timer;
-use Drupal\Component\Utility\Unicode;
 use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Config\BootstrapConfigStorageFactory;
 use Drupal\Core\Config\NullStorage;
-use Drupal\Core\Database\Database;
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\DependencyInjection\ServiceProviderInterface;
 use Drupal\Core\DependencyInjection\YamlFileLoader;
@@ -64,18 +61,14 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
   protected $container;
 
   /**
-   * The environment, e.g. 'testing', 'install'.
-   *
-   * @var string
+   * Holds the Environment object.
    */
   protected $environment;
 
   /**
-   * Whether the kernel has been booted.
-   *
-   * @var bool
+   * Holds the initial request created at script start.
    */
-  protected $booted = FALSE;
+  protected $initialRequest;
 
   /**
    * Whether essential services have been set up properly by preHandle().
@@ -108,13 +101,6 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
   protected $storage;
 
   /**
-   * The classloader object.
-   *
-   * @var \Composer\Autoload\ClassLoader
-   */
-  protected $classLoader;
-
-  /**
    * Config storage object used for reading enabled modules configuration.
    *
    * @var \Drupal\Core\Config\StorageInterface
@@ -169,84 +155,9 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
   protected $serviceProviders;
 
   /**
-   * Whether the PHP environment has been initialized.
-   *
-   * This legacy phase can only be booted once because it sets session INI
-   * settings. If a session has already been started, re-generating these
-   * settings would break the session.
-   *
-   * @var bool
-   */
-  protected static $isEnvironmentInitialized = FALSE;
-
-  /**
-   * The site directory.
-   *
-   * @var string
+   * Reference to ourself for use by static functions.
    */
-  protected $sitePath;
-
-  /**
-   * The app root.
-   *
-   * @var string
-   */
-  protected $root;
-
-  /**
-   * Create a DrupalKernel object from a request.
-   *
-   * @param \Symfony\Component\HttpFoundation\Request $request
-   *   The request.
-   * @param $class_loader
-   *   The class loader. Normally Composer's ClassLoader, as included by the
-   *   front controller, but may also be decorated; e.g.,
-   *   \Symfony\Component\ClassLoader\ApcClassLoader.
-   * @param string $environment
-   *   String indicating the environment, e.g. 'prod' or 'dev'.
-   * @param bool $allow_dumping
-   *   (optional) FALSE to stop the container from being written to or read
-   *   from disk. Defaults to TRUE.
-   *
-   * @return static
-   *
-   * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
-   *   In case the host name in the request is not trusted.
-   */
-  public static function createFromRequest(Request $request, $class_loader, $environment, $allow_dumping = TRUE) {
-    // Include our bootstrap file.
-    $core_root = dirname(dirname(dirname(__DIR__)));
-    require_once $core_root . '/includes/bootstrap.inc';
-
-    $kernel = new static($environment, $class_loader, $allow_dumping);
-
-    // Ensure sane php environment variables..
-    static::bootEnvironment();
-
-    // Get our most basic settings setup.
-    $site_path = static::findSitePath($request);
-    $kernel->setSitePath($site_path);
-    Settings::initialize(dirname($core_root), $site_path, $class_loader);
-
-    // Initialize our list of trusted HTTP Host headers to protect against
-    // header attacks.
-    $host_patterns = Settings::get('trusted_host_patterns', array());
-    if (PHP_SAPI !== 'cli' && !empty($host_patterns)) {
-      if (static::setupTrustedHosts($request, $host_patterns) === FALSE) {
-        throw new BadRequestHttpException('The provided host name is not valid for this server.');
-      }
-    }
-
-    // Redirect the user to the installation script if Drupal has not been
-    // installed yet (i.e., if no $databases array has been defined in the
-    // settings.php file) and we are not already installing.
-    if (!Database::getConnectionInfo() && !drupal_installation_attempted() && PHP_SAPI !== 'cli') {
-      $response = new RedirectResponse($request->getBasePath() . '/core/install.php');
-      $response->prepare($request)->send();
-    }
-
-    return $kernel;
-  }
+  protected static $self;
 
   /**
    * Constructs a DrupalKernel object.
@@ -261,109 +172,31 @@ public static function createFromRequest(Request $request, $class_loader, $envir
    *   (optional) FALSE to stop the container from being written to or read
    *   from disk. Defaults to TRUE.
    */
-  public function __construct($environment, $class_loader, $allow_dumping = TRUE) {
-    $this->environment = $environment;
-    $this->classLoader = $class_loader;
+  public function __construct(Request $request, $environment, $class_loader, $allow_dumping = TRUE) {
     $this->allowDumping = $allow_dumping;
-    $this->root = dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__))));
+    $this->setEnvironment($request, $environment, $class_loader);
+    static::$self = $this;
   }
 
   /**
-   * Returns the appropriate site directory for a request.
-   *
-   * Once the kernel has been created DrupalKernelInterface::getSitePath() is
-   * preferred since it gets the statically cached result of this method.
-   *
-   * Site directories contain all site specific code. This includes settings.php
-   * for bootstrap level configuration, file configuration stores, public file
-   * storage and site specific modules and themes.
-   *
-   * Finds a matching site directory file by stripping the website's hostname
-   * from left to right and pathname from right to left. By default, the
-   * directory must contain a 'settings.php' file for it to match. If the
-   * parameter $require_settings is set to FALSE, then a directory without a
-   * 'settings.php' file will match as well. The first configuration file found
-   * will be used and the remaining ones will be ignored. If no configuration
-   * file is found, returns a default value 'sites/default'. See
-   * default.settings.php for examples on how the URL is converted to a
-   * directory.
-   *
-   * If a file named sites.php is present in the sites directory, it will be
-   * loaded prior to scanning for directories. That file can define aliases in
-   * an associative array named $sites. The array is written in the format
-   * '<port>.<domain>.<path>' => 'directory'. As an example, to create a
-   * directory alias for http://www.drupal.org:8080/mysite/test whose
-   * configuration file is in sites/example.com, the array should be defined as:
-   * @code
-   * $sites = array(
-   *   '8080.www.drupal.org.mysite.test' => 'example.com',
-   * );
-   * @endcode
-   *
-   * @param \Symfony\Component\HttpFoundation\Request $request
-   *   The current request.
-   * @param bool $require_settings
-   *   Only directories with an existing settings.php file will be recognized.
-   *   Defaults to TRUE. During initial installation, this is set to FALSE so
-   *   that Drupal can detect a matching directory, then create a new
-   *   settings.php file in it.
-   *
-   * @return string
-   *   The path of the matching directory.
-   *
-   * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
-   *   In case the host name in the request is invalid.
-   *
-   * @see \Drupal\Core\DrupalKernelInterface::getSitePath()
-   * @see \Drupal\Core\DrupalKernelInterface::setSitePath()
-   * @see default.settings.php
-   * @see example.sites.php
+   * Boots an environment and binds it..
    */
-  public static function findSitePath(Request $request, $require_settings = TRUE) {
-    if (static::validateHostname($request) === FALSE) {
-      throw new BadRequestHttpException();
+  protected function setEnvironment($request, $environment, $class_loader) {
+    // This check for simpletest requests isn't thorough, it's just enough to
+    // load the correct test profile which in turn will verify.
+    if (isset($_SERVER['HTTP_USER_AGENT']) && stristr($_SERVER['HTTP_USER_AGENT'], 'simpletest')) {
+      $environment .= 'Test';
     }
-
-    // Check for a simpletest override.
-    if ($test_prefix = drupal_valid_test_ua()) {
-      return 'sites/simpletest/' . substr($test_prefix, 10);
-    }
-
-    // Determine whether multi-site functionality is enabled.
-    if (!file_exists(DRUPAL_ROOT . '/sites/sites.php')) {
-      return 'sites/default';
-    }
-
-    // Otherwise, use find the site path using the request.
-    $script_name = $request->server->get('SCRIPT_NAME');
-    if (!$script_name) {
-      $script_name = $request->server->get('SCRIPT_FILENAME');
-    }
-    $http_host = $request->getHost();
-
-    $sites = array();
-    include DRUPAL_ROOT . '/sites/sites.php';
-
-    $uri = explode('/', $script_name);
-    $server = explode('.', implode('.', array_reverse(explode(':', rtrim($http_host, '.')))));
-    for ($i = count($uri) - 1; $i > 0; $i--) {
-      for ($j = count($server); $j > 0; $j--) {
-        $dir = implode('.', array_slice($server, -$j)) . implode('.', array_slice($uri, 0, $i));
-        if (isset($sites[$dir]) && file_exists(DRUPAL_ROOT . '/sites/' . $sites[$dir])) {
-          $dir = $sites[$dir];
-        }
-        if (file_exists(DRUPAL_ROOT . '/sites/' . $dir . '/settings.php') || (!$require_settings && file_exists(DRUPAL_ROOT . '/sites/' . $dir))) {
-          return "sites/$dir";
-        }
-      }
-    }
-    return 'sites/default';
+    $class = '\\Drupal\\Core\\Environment\\' . $environment . 'Environment';
+    $this->environment = new $class($request, $class_loader);
   }
 
+
   /**
    * {@inheritdoc}
    */
   public function setSitePath($path) {
+    throw new Exception('cannot use');
     $this->sitePath = $path;
   }
 
@@ -371,41 +204,23 @@ public function setSitePath($path) {
    * {@inheritdoc}
    */
   public function getSitePath() {
-    return $this->sitePath;
+    return $this->environment->sitePath;
   }
 
   /**
    * {@inheritdoc}
    */
   public function getAppRoot() {
-    return $this->root;
+    return DRUPAL_ROOT;
   }
 
   /**
    * {@inheritdoc}
+   *
+   * BC Wrap. If this object exists all the tasks this function used to do
+   * will have been done.
    */
   public function boot() {
-    if ($this->booted) {
-      return $this;
-    }
-
-    // Start a page timer:
-    Timer::start('page');
-
-    // Ensure that findSitePath is set.
-    if (!$this->sitePath) {
-      throw new \Exception('Kernel does not have site path set before calling boot()');
-    }
-    // Initialize the container.
-    $this->initializeContainer();
-
-    // Ensure mt_rand() is reseeded to prevent random values from one page load
-    // being exploited to predict random values in subsequent page loads.
-    $seed = unpack("L", Crypt::randomBytes(4));
-    mt_srand($seed[1]);
-
-    $this->booted = TRUE;
-
     return $this;
   }
 
@@ -434,19 +249,19 @@ public function getContainer() {
    * {@inheritdoc}
    */
   public function loadLegacyIncludes() {
-    require_once $this->root . '/core/includes/common.inc';
-    require_once $this->root . '/core/includes/database.inc';
-    require_once $this->root . '/core/includes/module.inc';
-    require_once $this->root . '/core/includes/theme.inc';
-    require_once $this->root . '/core/includes/pager.inc';
-    require_once $this->root . '/core/includes/menu.inc';
-    require_once $this->root . '/core/includes/tablesort.inc';
-    require_once $this->root . '/core/includes/file.inc';
-    require_once $this->root . '/core/includes/unicode.inc';
-    require_once $this->root . '/core/includes/form.inc';
-    require_once $this->root . '/core/includes/errors.inc';
-    require_once $this->root . '/core/includes/schema.inc';
-    require_once $this->root . '/core/includes/entity.inc';
+    require_once DRUPAL_ROOT . '/core/includes/common.inc';
+    require_once DRUPAL_ROOT . '/core/includes/database.inc';
+    require_once DRUPAL_ROOT . '/core/includes/module.inc';
+    require_once DRUPAL_ROOT . '/core/includes/theme.inc';
+    require_once DRUPAL_ROOT . '/core/includes/pager.inc';
+    require_once DRUPAL_ROOT . '/core/includes/menu.inc';
+    require_once DRUPAL_ROOT . '/core/includes/tablesort.inc';
+    require_once DRUPAL_ROOT . '/core/includes/file.inc';
+    require_once DRUPAL_ROOT . '/core/includes/unicode.inc';
+    require_once DRUPAL_ROOT . '/core/includes/form.inc';
+    require_once DRUPAL_ROOT . '/core/includes/errors.inc';
+    require_once DRUPAL_ROOT . '/core/includes/schema.inc';
+    require_once DRUPAL_ROOT . '/core/includes/entity.inc';
   }
 
   /**
@@ -561,15 +376,18 @@ public function terminate(Request $request, Response $response) {
    * {@inheritdoc}
    */
   public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) {
-    $this->boot();
-    return $this->getHttpKernel()->handle($request, $type, $catch);
+    $this->initializeContainer();
+
+    return $this->getHttpKernel()
+      ->handle($request, $type, $catch)
+      ->prepare($request);
   }
 
   /**
    * {@inheritdoc}
    */
   public function prepareLegacyRequest(Request $request) {
-    $this->boot();
+    $this->initializeContainer();
     $this->preHandle($request);
     // Setup services which are normally initialized from within stack
     // middleware or during the request kernel event.
@@ -595,7 +413,7 @@ public function prepareLegacyRequest(Request $request) {
   protected function moduleData($module) {
     if (!$this->moduleData) {
       // First, find profiles.
-      $listing = new ExtensionDiscovery($this->root);
+      $listing = new ExtensionDiscovery(DRUPAL_ROOT);
       $listing->setProfileDirectories(array());
       $all_profiles = $listing->scan('profile');
       $profiles = array_intersect_key($all_profiles, $this->moduleList);
@@ -637,7 +455,7 @@ public function updateModules(array $module_list, array $module_filenames = arra
     // list will take effect when boot() is called. If we have already booted,
     // then rebuild the container in order to refresh the serviceProvider list
     // and container.
-    if ($this->booted) {
+    if ($this->environment) {
       $this->initializeContainer(TRUE);
     }
   }
@@ -649,7 +467,7 @@ public function updateModules(array $module_list, array $module_filenames = arra
    *   The class name.
    */
   protected function getClassName() {
-    $parts = array('service_container', $this->environment);
+    $parts = array('service_container', DRUPAL_PROFILE);
     return implode('_', $parts);
   }
 
@@ -660,7 +478,7 @@ protected function getClassName() {
    *   The class name.
    */
   protected function getClassNamespace() {
-    return 'Drupal\\Core\\DependencyInjection\\Container\\' . $this->environment;
+    return 'Drupal\\Core\\DependencyInjection\\Container\\' . DRUPAL_PROFILE;
   }
 
   /**
@@ -670,7 +488,7 @@ protected function getClassNamespace() {
    */
   protected function getKernelParameters() {
     return array(
-      'kernel.environment' => $this->environment,
+      'kernel.environment' => DRUPAL_PROFILE,
     );
   }
 
@@ -752,68 +570,6 @@ protected function initializeContainer($rebuild = FALSE) {
   }
 
   /**
-   * Setup a consistent PHP environment.
-   *
-   * This method sets PHP environment options we want to be sure are set
-   * correctly for security or just saneness.
-   */
-  public static function bootEnvironment() {
-    if (static::$isEnvironmentInitialized) {
-      return;
-    }
-
-    // Enforce E_STRICT, but allow users to set levels not part of E_STRICT.
-    error_reporting(E_STRICT | E_ALL);
-
-    // Override PHP settings required for Drupal to work properly.
-    // sites/default/default.settings.php contains more runtime settings.
-    // The .htaccess file contains settings that cannot be changed at runtime.
-
-    // Use session cookies, not transparent sessions that puts the session id in
-    // the query string.
-    ini_set('session.use_cookies', '1');
-    ini_set('session.use_only_cookies', '1');
-    ini_set('session.use_trans_sid', '0');
-    // Don't send HTTP headers using PHP's session handler.
-    // Send an empty string to disable the cache limiter.
-    ini_set('session.cache_limiter', '');
-    // Use httponly session cookies.
-    ini_set('session.cookie_httponly', '1');
-
-    // Set sane locale settings, to ensure consistent string, dates, times and
-    // numbers handling.
-    setlocale(LC_ALL, 'C');
-
-    // Detect string handling method.
-    Unicode::check();
-
-    // Indicate that code is operating in a test child site.
-    if (!defined('DRUPAL_TEST_IN_CHILD_SITE')) {
-      if ($test_prefix = drupal_valid_test_ua()) {
-        // Only code that interfaces directly with tests should rely on this
-        // constant; e.g., the error/exception handler conditionally adds further
-        // error information into HTTP response headers that are consumed by
-        // Simpletest's internal browser.
-        define('DRUPAL_TEST_IN_CHILD_SITE', TRUE);
-
-        // Log fatal errors to the test site directory.
-        ini_set('log_errors', 1);
-        ini_set('error_log', DRUPAL_ROOT . '/sites/simpletest/' . substr($test_prefix, 10) . '/error.log');
-      }
-      else {
-        // Ensure that no other code defines this.
-        define('DRUPAL_TEST_IN_CHILD_SITE', FALSE);
-      }
-    }
-
-    // Set the Drupal custom error handler.
-    set_error_handler('_drupal_error_handler');
-    set_exception_handler('_drupal_exception_handler');
-
-    static::$isEnvironmentInitialized = TRUE;
-  }
-
-  /**
    * Bootstraps the legacy global request variables.
    *
    * @param \Symfony\Component\HttpFoundation\Request $request
@@ -929,7 +685,7 @@ protected function attachSynthetic(ContainerInterface $container) {
     $container->set('kernel', $this);
 
     // Set the class loader which was registered as a synthetic service.
-    $container->set('class_loader', $this->classLoader);
+    $container->set('class_loader', $this->environment->classLoader);
     return $container;
   }
 
@@ -958,10 +714,11 @@ protected function compileContainer() {
     // - Element
     // - Entity
     // - Plugin
-    foreach (array('Core', 'Component') as $parent_directory) {
+    foreach (['Core', 'Component'] as $parent_directory) {
       $path = 'core/lib/Drupal/' . $parent_directory;
       $parent_namespace = 'Drupal\\' . $parent_directory;
-      foreach (new \DirectoryIterator($this->root . '/' . $path) as $component) {
+
+      foreach (new \DirectoryIterator(DRUPAL_ROOT . '/' . $path) as $component) {
         /** @var $component \DirectoryIterator */
         $pathname = $component->getPathname();
         if (!$component->isDot() && $component->isDir() && (
@@ -1026,6 +783,7 @@ protected function compileContainer() {
     $container->setParameter('persistIds', $persist_ids);
 
     $container->compile();
+
     return $container;
   }
 
@@ -1119,7 +877,7 @@ protected function getConfigStorage() {
       // The active configuration storage may not exist yet; e.g., in the early
       // installer. Catch the exception thrown by config_get_config_directory().
       try {
-        $this->configStorage = BootstrapConfigStorageFactory::get($this->classLoader);
+        $this->configStorage = BootstrapConfigStorageFactory::get($this->environment->classLoader);
       }
       catch (\Exception $e) {
         $this->configStorage = new NullStorage();
@@ -1195,115 +953,15 @@ protected function classLoaderAddMultiplePsr4(array $namespaces = array()) {
     foreach ($namespaces as $prefix => $paths) {
       if (is_array($paths)) {
         foreach ($paths as $key => $value) {
-          $paths[$key] = $this->root . '/' . $value;
+          $paths[$key] = DRUPAL_ROOT . '/' . $value;
         }
       }
       elseif (is_string($paths)) {
-        $paths = $this->root . '/' . $paths;
-      }
-      $this->classLoader->addPsr4($prefix . '\\', $paths);
-    }
-  }
-
-  /**
-   * Validates a hostname length.
-   *
-   * @param string $host
-   *   A hostname.
-   *
-   * @return bool
-   *   TRUE if the length is appropriate, or FALSE otherwise.
-   */
-  protected static function validateHostnameLength($host) {
-    // Limit the length of the host name to 1000 bytes to prevent DoS attacks
-    // with long host names.
-    return strlen($host) <= 1000
-    // Limit the number of subdomains and port separators to prevent DoS attacks
-    // in findSitePath().
-    && substr_count($host, '.') <= 100
-    && substr_count($host, ':') <= 100;
-  }
 
-  /**
-   * Validates the hostname supplied from the HTTP request.
-   *
-   * @param \Symfony\Component\HttpFoundation\Request $request
-   *   The request object
-   *
-   * @return bool
-   *   TRUE if the hostmame is valid, or FALSE otherwise.
-   *
-   * @todo Adjust per resolution to https://github.com/symfony/symfony/issues/12349
-   */
-  public static function validateHostname(Request $request) {
-    // $request->getHost() can throw an UnexpectedValueException if it
-    // detects a bad hostname, but it does not validate the length.
-    try {
-      $http_host = $request->getHost();
-    }
-    catch (\UnexpectedValueException $e) {
-      return FALSE;
-    }
-
-    if (static::validateHostnameLength($http_host) === FALSE) {
-      return FALSE;
-    }
-
-    return TRUE;
-  }
-
-  /**
-   * Sets up the lists of trusted HTTP Host headers.
-   *
-   * Since the HTTP Host header can be set by the user making the request, it
-   * is possible to create an attack vectors against a site by overriding this.
-   * Symfony provides a mechanism for creating a list of trusted Host values.
-   *
-   * Host patterns (as regular expressions) can be configured throught
-   * settings.php for multisite installations, sites using ServerAlias without
-   * canonical redirection, or configurations where the site responds to default
-   * requests. For example,
-   *
-   * @code
-   * $settings['trusted_host_patterns'] = array(
-   *   '^example\.com$',
-   *   '^*.example\.com$',
-   * );
-   * @endcode
-   *
-   * @param \Symfony\Component\HttpFoundation\Request $request
-   *   The request object.
-   * @param array $host_patterns
-   *   The array of trusted host patterns.
-   *
-   * @return boolean
-   *   TRUE if the Host header is trusted, FALSE otherwise.
-   *
-   * @see https://www.drupal.org/node/1992030
-   * @see \Drupal\Core\Http\TrustedHostsRequestFactory
-   */
-  protected static function setupTrustedHosts(Request $request, $host_patterns) {
-    $request->setTrustedHosts($host_patterns);
-
-    // Get the host, which will validate the current request.
-    try {
-      $host = $request->getHost();
-
-      // Fake requests created through Request::create() without passing in the
-      // server variables from the main request have a default host of
-      // 'localhost'. If 'localhost' does not match any of the trusted host
-      // patterns these fake requests would fail the host verification. Instead,
-      // TrustedHostsRequestFactory makes sure to pass in the server variables
-      // from the main request.
-      $request_factory = new TrustedHostsRequestFactory($host);
-      Request::setFactory([$request_factory, 'createRequest']);
-
-    }
-    catch (\UnexpectedValueException $e) {
-      return FALSE;
+        $paths = DRUPAL_ROOT . '/' . $paths;
+      }
+      $this->environment->classLoader->addPsr4($prefix . '\\', $paths);
     }
-
-    return TRUE;
   }
 
   /**
@@ -1322,4 +980,8 @@ protected function addServiceFiles($service_yamls) {
     }
     return FALSE;
   }
+
+  public static function findSitePath($request, $require_settings) {
+    return static::$self->environment->sitePath;
+  }
 }
diff --git a/core/lib/Drupal/Core/Environment/BaseEnvironment.php b/core/lib/Drupal/Core/Environment/BaseEnvironment.php
new file mode 100644
index 0000000..7e3ebfe
--- /dev/null
+++ b/core/lib/Drupal/Core/Environment/BaseEnvironment.php
@@ -0,0 +1,1522 @@
+<?php
+/**
+ * @file Contains Base Environment and associated global functions.
+ */
+
+/**
+ * Unlike all other files in the system, environment files posess two namespaces
+ * using PHP's rarely used namesapce{} syntax. This allows us to define global
+ * functions along with the environment class. This setup also allows us to
+ * more thoroughly segregate the different Drupal environments from each other
+ * especially those with special needs like the testing environments.
+ *
+ * When extending this class keep in mind the constants that it has already
+ * defined.  Constants that can be overridden are set using the define
+ * statement in the class.
+ *
+ * This file replaces includes/bootstrap.inc
+ */
+
+/**
+ * Define the global constants and functions of the Production profile.
+ */
+namespace {
+  use Drupal\Component\Datetime\DateTimePlus;
+  use Drupal\Component\Utility\Crypt;
+  use Drupal\Component\Utility\Environment;
+  use Drupal\Component\Utility\SafeMarkup;
+  use Drupal\Component\Utility\Unicode;
+  use Drupal\Core\DrupalKernel;
+  use Drupal\Core\Extension\ExtensionDiscovery;
+  use Drupal\Core\Language\LanguageInterface;
+  use Drupal\Core\Logger\RfcLogLevel;
+  use Drupal\Core\Session\AccountInterface;
+  use Drupal\Core\Site\Settings;
+  use Drupal\Core\Utility\Error;
+  use Symfony\Component\ClassLoader\ApcClassLoader;
+  use Symfony\Component\HttpFoundation\Request;
+  use Symfony\Component\HttpFoundation\Response;
+
+  /**
+   * Minimum supported version of PHP.
+   */
+  const DRUPAL_MINIMUM_PHP = '5.4.5';
+
+  /**
+   * Minimum recommended value of PHP memory_limit.
+   *
+   * @todo Reduce the memory required to install on some environments in
+   *   https://www.drupal.org/node/2289201 and then decrease this limit.
+   */
+  const DRUPAL_MINIMUM_PHP_MEMORY_LIMIT = '64M';
+
+  /**
+   * Error reporting level: display no errors.
+   */
+  const ERROR_REPORTING_HIDE = 'hide';
+
+  /**
+   * Error reporting level: display errors and warnings.
+   */
+  const ERROR_REPORTING_DISPLAY_SOME = 'some';
+
+  /**
+   * Error reporting level: display all messages.
+   */
+  const ERROR_REPORTING_DISPLAY_ALL = 'all';
+
+  /**
+   * Error reporting level: display all messages, plus backtrace information.
+   */
+  const ERROR_REPORTING_DISPLAY_VERBOSE = 'verbose';
+
+  /**
+   * Role ID for anonymous users; should match what's in the "role" table.
+   *
+   * @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+   *   Use Drupal\Core\Session\AccountInterface::ANONYMOUS_ROLE or
+   *   \Drupal\user\RoleInterface::ANONYMOUS_ID instead.
+   */
+  const DRUPAL_ANONYMOUS_RID = AccountInterface::ANONYMOUS_ROLE;
+
+  /**
+   * Role ID for authenticated users; should match what's in the "role" table.
+   *
+   * @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
+   *   Use Drupal\Core\Session\AccountInterface::AUTHENTICATED_ROLE or
+   *   \Drupal\user\RoleInterface::AUTHENTICATED_ID instead.
+   */
+  const DRUPAL_AUTHENTICATED_RID = AccountInterface::AUTHENTICATED_ROLE;
+
+  /**
+   * The maximum number of characters in a module or theme name.
+   */
+  const DRUPAL_EXTENSION_NAME_MAX_LENGTH = 50;
+
+  /**
+   * Regular expression to match PHP function names.
+   *
+   * @see http://php.net/manual/language.functions.php
+   */
+  const DRUPAL_PHP_FUNCTION_PATTERN = '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*';
+
+  /**
+   * $config_directories key for active directory.
+   *
+   * @see config_get_config_directory()
+   */
+  const CONFIG_ACTIVE_DIRECTORY = 'active';
+
+  /**
+   * $config_directories key for staging directory.
+   *
+   * @see config_get_config_directory()
+   */
+  const CONFIG_STAGING_DIRECTORY = 'staging';
+
+  /**
+   * Returns the appropriate configuration directory.
+   *
+   * @param bool $require_settings
+   *   Only configuration directories with an existing settings.php file
+   *   will be recognized. Defaults to TRUE. During initial installation,
+   *   this is set to FALSE so that Drupal can detect a matching directory,
+   *   then create a new settings.php file in it.
+   * @param bool $reset
+   *   Force a full search for matching directories even if one had been
+   *   found previously. Defaults to FALSE.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   (optional) The current request. Defaults to \Drupal::request() or a new
+   *   request created from globals.
+   *
+   * @return string
+   *   The path of the matching directory.@see default.settings.php
+   *
+   * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
+   *   Use \Drupal\Core\DrupalKernel::getSitePath() instead. If the kernel is
+   *   unavailable or the site path needs to be recalculated then
+   *   Drupal\Core\DrupalKernel::findSitePath() can be used.
+   */
+  function conf_path($require_settings = TRUE, $reset = FALSE, Request $request = NULL) {
+    if (!isset($request)) {
+      if (\Drupal::hasRequest()) {
+        $request = \Drupal::request();
+      }
+      // @todo Remove once external CLI scripts (Drush) are updated.
+      else {
+        $request = Request::createFromGlobals();
+      }
+    }
+    if (\Drupal::hasService('kernel')) {
+      $site_path = \Drupal::service('kernel')->getSitePath();
+    }
+    if (!isset($site_path) || empty($site_path)) {
+      $site_path = DrupalKernel::findSitePath($request, $require_settings);
+    }
+    return $site_path;
+  }
+
+  /**
+   * Returns the path of a configuration directory.
+   *
+   * @param string $type
+   *   (optional) The type of config directory to return. Drupal core provides
+   *   'active' and 'staging'. Defaults to CONFIG_ACTIVE_DIRECTORY.
+   *
+   * @return string
+   *   The configuration directory path.
+   */
+  function config_get_config_directory($type = CONFIG_ACTIVE_DIRECTORY) {
+    global $config_directories;
+
+    if (!empty($config_directories[$type])) {
+      return $config_directories[$type];
+    }
+    throw new \Exception(format_string('The configuration directory type %type does not exist.', array('%type' => $type)));
+  }
+
+  /**
+   * Returns and optionally sets the filename for a system resource.
+   *
+   * The filename, whether provided, cached, or retrieved from the database, is
+   * only returned if the file exists.
+   *
+   * This function plays a key role in allowing Drupal's resources (modules
+   * and themes) to be located in different places depending on a site's
+   * configuration. For example, a module 'foo' may legally be located
+   * in any of these three places:
+   *
+   * core/modules/foo/foo.info.yml
+   * modules/foo/foo.info.yml
+   * sites/example.com/modules/foo/foo.info.yml
+   *
+   * Calling drupal_get_filename('module', 'foo') will give you one of
+   * the above, depending on where the module is located.
+   *
+   * @param $type
+   *   The type of the item; one of 'core', 'profile', 'module', 'theme', or
+   *   'theme_engine'.
+   * @param $name
+   *   The name of the item for which the filename is requested. Ignored for
+   *   $type 'core'.
+   * @param $filename
+   *   The filename of the item if it is to be set explicitly rather
+   *   than by consulting the database.
+   *
+   * @return
+   *   The filename of the requested item or NULL if the item is not found.
+   */
+  function drupal_get_filename($type, $name, $filename = NULL) {
+    // The location of files will not change during the request, so do not use
+    // drupal_static().
+    static $files = array();
+
+    // Type 'core' only exists to simplify application-level logic; it always maps
+    // to the /core directory, whereas $name is ignored. It is only requested via
+    // drupal_get_path(). /core/core.info.yml does not exist, but is required
+    // since drupal_get_path() returns the dirname() of the returned pathname.
+    if ($type === 'core') {
+      return 'core/core.info.yml';
+    }
+
+    // Profiles are converted into modules in system_rebuild_module_data().
+    // @todo Remove false-exposure of profiles as modules.
+    $original_type = $type;
+    if ($type == 'profile') {
+      $type = 'module';
+    }
+    if (!isset($files[$type])) {
+      $files[$type] = array();
+    }
+
+    if (isset($filename)) {
+      $files[$type][$name] = $filename;
+    }
+    elseif (!isset($files[$type][$name])) {
+      // If the pathname of the requested extension is not known, try to retrieve
+      // the list of extension pathnames from various providers, checking faster
+      // providers first.
+      // Retrieve the current module list (derived from the service container).
+      if ($type == 'module' && \Drupal::hasService('module_handler')) {
+        foreach (\Drupal::moduleHandler()->getModuleList() as $module_name => $module) {
+          $files[$type][$module_name] = $module->getPathname();
+        }
+      }
+      // If still unknown, retrieve the file list prepared in state by
+      // system_rebuild_module_data() and
+      // \Drupal\Core\Extension\ThemeHandlerInterface::rebuildThemeData().
+      if (!isset($files[$type][$name]) && \Drupal::hasService('state')) {
+        $files[$type] += \Drupal::state()->get('system.' . $type . '.files', array());
+      }
+      // If still unknown, perform a filesystem scan.
+      if (!isset($files[$type][$name])) {
+        $listing = new ExtensionDiscovery(DRUPAL_ROOT);
+        // Prevent an infinite recursion by this legacy function.
+        if ($original_type == 'profile') {
+          $listing->setProfileDirectories(array());
+        }
+        foreach ($listing->scan($original_type) as $extension_name => $file) {
+          $files[$type][$extension_name] = $file->getPathname();
+        }
+      }
+    }
+
+    if (isset($files[$type][$name])) {
+      return $files[$type][$name];
+    }
+  }
+
+  /**
+   * Returns the path to a system item (module, theme, etc.).
+   *
+   * @param $type
+   *   The type of the item; one of 'core', 'profile', 'module', 'theme', or
+   *   'theme_engine'.
+   * @param $name
+   *   The name of the item for which the path is requested. Ignored for
+   *   $type 'core'.
+   *
+   * @return
+   *   The path to the requested item or an empty string if the item is not found.
+   */
+  function drupal_get_path($type, $name) {
+    return dirname(drupal_get_filename($type, $name));
+  }
+
+  /**
+   * Sets an HTTP response header for the current page.
+   *
+   * Note: When sending a Content-Type header, always include a 'charset' type,
+   * too. This is necessary to avoid security bugs (e.g. UTF-7 XSS).
+   *
+   * @param $name
+   *   The HTTP header name, or the special 'Status' header name.
+   * @param $value
+   *   The HTTP header value; if equal to FALSE, the specified header is unset.
+   *   If $name is 'Status', this is expected to be a status code followed by a
+   *   reason phrase, e.g. "404 Not Found".
+   * @param $append
+   *   Whether to append the value to an existing header or to replace it.
+   *
+   * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
+   *   Use \Symfony\Component\HttpFoundation\Response->headers->set().
+   *   See https://drupal.org/node/2181523.
+   */
+  function _drupal_add_http_header($name, $value, $append = FALSE) {
+    // The headers as name/value pairs.
+    $headers = &drupal_static('drupal_http_headers', array());
+
+    $name_lower = strtolower($name);
+    _drupal_set_preferred_header_name($name);
+
+    if ($value === FALSE) {
+      $headers[$name_lower] = FALSE;
+    }
+    elseif (isset($headers[$name_lower]) && $append) {
+      // Multiple headers with identical names may be combined using comma (RFC
+      // 2616, section 4.2).
+      $headers[$name_lower] .= ',' . $value;
+    }
+    else {
+      $headers[$name_lower] = $value;
+    }
+  }
+
+  /**
+   * Gets the HTTP response headers for the current page.
+   *
+   * @param $name
+   *   An HTTP header name. If omitted, all headers are returned as name/value
+   *   pairs. If an array value is FALSE, the header has been unset.
+   *
+   * @return
+   *   A string containing the header value, or FALSE if the header has been set,
+   *   or NULL if the header has not been set.
+   *
+   * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
+   *   Use \Symfony\Component\HttpFoundation\Response->headers->get().
+   *   See https://drupal.org/node/2181523.
+   */
+  function drupal_get_http_header($name = NULL) {
+    $headers = &drupal_static('drupal_http_headers', array());
+    if (isset($name)) {
+      $name = strtolower($name);
+      return isset($headers[$name]) ? $headers[$name] : NULL;
+    }
+    else {
+      return $headers;
+    }
+  }
+
+  /**
+   * Sets the preferred name for the HTTP header.
+   *
+   * Header names are case-insensitive, but for maximum compatibility they should
+   * follow "common form" (see RFC 2616, section 4.2).
+   *
+   * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
+   *   See https://drupal.org/node/2181523.
+   */
+  function _drupal_set_preferred_header_name($name = NULL) {
+    static $header_names = array();
+
+    if (!isset($name)) {
+      return $header_names;
+    }
+    $header_names[strtolower($name)] = $name;
+  }
+
+  /**
+   * Translates a string to the current language or to a given language.
+   *
+   * The t() function serves two purposes. First, at run-time it translates
+   * user-visible text into the appropriate language. Second, various mechanisms
+   * that figure out what text needs to be translated work off t() -- the text
+   * inside t() calls is added to the database of strings to be translated.
+   * These strings are expected to be in English, so the first argument should
+   * always be in English. To enable a fully-translatable site, it is important
+   * that all human-readable text that will be displayed on the site or sent to
+   * a user is passed through the t() function, or a related function. See the
+   * @link http://drupal.org/node/322729 Localization API @endlink pages for
+   * more information, including recommendations on how to break up or not
+   * break up strings for translation.
+   *
+   * @section sec_translating_vars Translating Variables
+   * You should never use t() to translate variables, such as calling
+   * @code t($text); @endcode, unless the text that the variable holds has been
+   * passed through t() elsewhere (e.g., $text is one of several translated
+   * literal strings in an array). It is especially important never to call
+   * @code t($user_text); @endcode, where $user_text is some text that a user
+   * entered - doing that can lead to cross-site scripting and other security
+   * problems. However, you can use variable substitution in your string, to put
+   * variable text such as user names or link URLs into translated text. Variable
+   * substitution looks like this:
+   * @code
+   * $text = t("@name's blog", array('@name' => user_format_name($account)));
+   * @endcode
+   * Basically, you can put variables like @name into your string, and t() will
+   * substitute their sanitized values at translation time. (See the
+   * Localization API pages referenced above and the documentation of
+   * format_string() for details about how to define variables in your string.)
+   * Translators can then rearrange the string as necessary for the language
+   * (e.g., in Spanish, it might be "blog de @name").
+   *
+   * @param $string
+   *   A string containing the English string to translate.
+   * @param $args
+   *   An associative array of replacements to make after translation. Based
+   *   on the first character of the key, the value is escaped and/or themed.
+   *   See format_string() for details.
+   * @param $options
+   *   An associative array of additional options, with the following elements:
+   *   - 'langcode' (defaults to the current language): The language code to
+   *     translate to a language other than what is used to display the page.
+   *   - 'context' (defaults to the empty context): The context the source string
+   *     belongs to.
+   *
+   * @return
+   *   The translated string.
+   *
+   * @see format_string()
+   * @ingroup sanitization
+   */
+  function t($string, array $args = array(), array $options = array()) {
+    return \Drupal::translation()->translate($string, $args, $options);
+  }
+
+  /**
+   * Formats a string for HTML display by replacing variable placeholders.
+   *
+   * @see \Drupal\Component\Utility\SafeMarkup::format()
+   * @see t()
+   * @ingroup sanitization
+   */
+  function format_string($string, array $args = array()) {
+    return SafeMarkup::format($string, $args);
+  }
+
+  /**
+   * Checks whether a string is valid UTF-8.
+   *
+   * All functions designed to filter input should use drupal_validate_utf8
+   * to ensure they operate on valid UTF-8 strings to prevent bypass of the
+   * filter.
+   *
+   * When text containing an invalid UTF-8 lead byte (0xC0 - 0xFF) is presented
+   * as UTF-8 to Internet Explorer 6, the program may misinterpret subsequent
+   * bytes. When these subsequent bytes are HTML control characters such as
+   * quotes or angle brackets, parts of the text that were deemed safe by filters
+   * end up in locations that are potentially unsafe; An onerror attribute that
+   * is outside of a tag, and thus deemed safe by a filter, can be interpreted
+   * by the browser as if it were inside the tag.
+   *
+   * The function does not return FALSE for strings containing character codes
+   * above U+10FFFF, even though these are prohibited by RFC 3629.
+   *
+   * @param $text
+   *   The text to check.
+   *
+   * @return
+   *   TRUE if the text is valid UTF-8, FALSE if not.
+   *
+   * @see \Drupal\Component\Utility\Unicode::validateUtf8()
+   */
+  function drupal_validate_utf8($text) {
+    return Unicode::validateUtf8($text);
+  }
+
+  /**
+   * Logs an exception.
+   *
+   * This is a wrapper logging function which automatically decodes an exception.
+   *
+   * @param $type
+   *   The category to which this message belongs.
+   * @param $exception
+   *   The exception that is going to be logged.
+   * @param $message
+   *   The message to store in the log. If empty, a text that contains all useful
+   *   information about the passed-in exception is used.
+   * @param $variables
+   *   Array of variables to replace in the message on display or
+   *   NULL if message is already translated or not possible to
+   *   translate.
+   * @param $severity
+   *   The severity of the message, as per RFC 3164.
+   * @param $link
+   *   A link to associate with the message.
+   *
+   * @see \Drupal\Core\Utility\Error::decodeException()
+   */
+  function watchdog_exception($type, Exception $exception, $message = NULL, $variables = array(), $severity = RfcLogLevel::ERROR, $link = NULL) {
+
+    // Use a default value if $message is not set.
+    if (empty($message)) {
+      // The exception message is run through
+      // \Drupal\Component\Utility\SafeMarkup::checkPlain() by
+      // \Drupal\Core\Utility\Error:decodeException().
+      $message = '%type: !message in %function (line %line of %file).';
+    }
+
+    if ($link) {
+      $variables['link'] = $link;
+    }
+
+    $variables += Error::decodeException($exception);
+
+    \Drupal::logger($type)->log($severity, $message, $variables);
+  }
+
+  /**
+   * Sets a message to display to the user.
+   *
+   * Messages are stored in a session variable and displayed in the page template
+   * via the $messages theme variable.
+   *
+   * Example usage:
+   * @code
+   * drupal_set_message(t('An error occurred and processing did not complete.'), 'error');
+   * @endcode
+   *
+   * @param string $message
+   *   (optional) The translated message to be displayed to the user. For
+   *   consistency with other messages, it should begin with a capital letter and
+   *   end with a period.
+   * @param string $type
+   *   (optional) The message's type. Defaults to 'status'. These values are
+   *   supported:
+   *   - 'status'
+   *   - 'warning'
+   *   - 'error'
+   * @param bool $repeat
+   *   (optional) If this is FALSE and the message is already set, then the
+   *   message won't be repeated. Defaults to FALSE.
+   *
+   * @return array|null
+   *   A multidimensional array with keys corresponding to the set message types.
+   *   The indexed array values of each contain the set messages for that type,
+   *   and each message is an associative array with the following format:
+   *   - safe: Boolean indicating whether the message string has been marked as
+   *     safe. Non-safe strings will be escaped automatically.
+   *   - message: The message string.
+   *   So, the following is an example of the full return array structure:
+   *   @code
+   *     array(
+   *       'status' => array(
+   *         array(
+   *           'safe' => TRUE,
+   *           'message' => 'A <em>safe</em> markup string.',
+   *         ),
+   *         array(
+   *           'safe' => FALSE,
+   *           'message' => "$arbitrary_user_input to escape.",
+   *         ),
+   *       ),
+   *     );
+   *   @endcode
+   *   If there are no messages set, the function returns NULL.
+   *
+   * @see drupal_get_messages()
+   * @see status-messages.html.twig
+   */
+  function drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE) {
+    if (isset($message)) {
+      if (!isset($_SESSION['messages'][$type])) {
+        $_SESSION['messages'][$type] = array();
+      }
+
+      $new = array(
+        'safe' => SafeMarkup::isSafe($message),
+        'message' => $message,
+      );
+      if ($repeat || !in_array($new, $_SESSION['messages'][$type])) {
+        $_SESSION['messages'][$type][] = $new;
+      }
+
+      // Mark this page as being uncacheable.
+      \Drupal::service('page_cache_kill_switch')->trigger();
+    }
+
+    // Messages not set when DB connection fails.
+    return isset($_SESSION['messages']) ? $_SESSION['messages'] : NULL;
+  }
+
+  /**
+   * Returns all messages that have been set with drupal_set_message().
+   *
+   * @param string $type
+   *   (optional) Limit the messages returned by type. Defaults to NULL, meaning
+   *   all types. These values are supported:
+   *   - NULL
+   *   - 'status'
+   *   - 'warning'
+   *   - 'error'
+   * @param bool $clear_queue
+   *   (optional) If this is TRUE, the queue will be cleared of messages of the
+   *   type specified in the $type parameter. Otherwise the queue will be left
+   *   intact. Defaults to TRUE.
+   *
+   * @return array
+   *   An associative, nested array of messages grouped by message type, with
+   *   the top-level keys as the message type. The messages returned are
+   *   limited to the type specified in the $type parameter, if any. If there
+   *   are no messages of the specified type, an empty array is returned. See
+   *   drupal_set_message() for the array structure of individual messages.
+   *
+   * @see drupal_set_message()
+   * @see status-messages.html.twig
+   */
+  function drupal_get_messages($type = NULL, $clear_queue = TRUE) {
+    if ($messages = drupal_set_message()) {
+      foreach ($messages as $message_type => $message_typed_messages) {
+        foreach ($message_typed_messages as $key => $message) {
+          if ($message['safe']) {
+            $message['message'] = SafeMarkup::set($message['message']);
+          }
+          $messages[$message_type][$key] = $message['message'];
+        }
+      }
+      if ($type) {
+        if ($clear_queue) {
+          unset($_SESSION['messages'][$type]);
+        }
+        if (isset($messages[$type])) {
+          return array($type => $messages[$type]);
+        }
+      }
+      else {
+        if ($clear_queue) {
+          unset($_SESSION['messages']);
+        }
+        return $messages;
+      }
+    }
+    return array();
+  }
+
+  /**
+   * Returns the time zone of the current user.
+   */
+  function drupal_get_user_timezone() {
+    $user = \Drupal::currentUser();
+    $config = \Drupal::config('system.date');
+
+    if ($user && $config->get('timezone.user.configurable') && $user->isAuthenticated() && $user->getTimezone()) {
+      return $user->getTimezone();
+    }
+    else {
+      // Ignore PHP strict notice if time zone has not yet been set in the php.ini
+      // configuration.
+      $config_data_default_timezone = $config->get('timezone.default');
+      return !empty($config_data_default_timezone) ? $config_data_default_timezone : @date_default_timezone_get();
+    }
+  }
+
+  /**
+   * Provides custom PHP error handling.
+   *
+   * @param $error_level
+   *   The level of the error raised.
+   * @param $message
+   *   The error message.
+   * @param $filename
+   *   The filename that the error was raised in.
+   * @param $line
+   *   The line number the error was raised at.
+   * @param $context
+   *   An array that points to the active symbol table at the point the error
+   *   occurred.
+   */
+  function _drupal_error_handler($error_level, $message, $filename, $line, $context) {
+    require_once DRUPAL_ROOT . '/core/includes/errors.inc';
+    _drupal_error_handler_real($error_level, $message, $filename, $line, $context);
+  }
+
+  /**
+   * Provides custom PHP exception handling.
+   *
+   * Uncaught exceptions are those not enclosed in a try/catch block. They are
+   * always fatal: the execution of the script will stop as soon as the exception
+   * handler exits.
+   *
+   * @param $exception
+   *   The exception object that was thrown.
+   */
+  function _drupal_exception_handler($exception) {
+    require_once DRUPAL_ROOT . '/core/includes/errors.inc';
+
+    try {
+      // Log the message to the watchdog and return an error page to the user.
+      _drupal_log_error(Error::decodeException($exception), TRUE);
+    }
+    catch (Exception $exception2) {
+      // Another uncaught exception was thrown while handling the first one.
+      // If we are displaying errors, then do so with no possibility of a further uncaught exception being thrown.
+      if (error_displayable()) {
+        print '<h1>Additional uncaught exception thrown while handling exception.</h1>';
+        print '<h2>Original</h2><p>' . Error::renderExceptionSafe($exception) . '</p>';
+        print '<h2>Additional</h2><p>' . Error::renderExceptionSafe($exception2) . '</p><hr />';
+      }
+    }
+  }
+
+  /**
+   * Generates a user agent string with a HMAC and timestamp for simpletest.
+   */
+  function drupal_generate_test_ua($prefix) {
+    static $key, $last_prefix;
+
+    if (!isset($key) || $last_prefix != $prefix) {
+      $last_prefix = $prefix;
+      $key_file = DRUPAL_ROOT . '/sites/simpletest/' . substr($prefix, 10) . '/.htkey';
+      // When issuing an outbound HTTP client request from within an inbound test
+      // request, then the outbound request has to use the same User-Agent header
+      // as the inbound request. A newly generated private key for the same test
+      // prefix would invalidate all subsequent inbound requests.
+      // @see \Drupal\Core\Http\Plugin\SimpletestHttpRequestSubscriber
+      if (DRUPAL_TEST_IN_CHILD_SITE && $parent_prefix = drupal_valid_test_ua()) {
+        if ($parent_prefix != $prefix) {
+          throw new \RuntimeException("Malformed User-Agent: Expected '$parent_prefix' but got '$prefix'.");
+        }
+        // If the file is not readable, a PHP warning is expected in this case.
+        $private_key = file_get_contents($key_file);
+      }
+      else {
+        // Generate and save a new hash salt for a test run.
+        // Consumed by drupal_valid_test_ua() before settings.php is loaded.
+        $private_key = Crypt::randomBytesBase64(55);
+        file_put_contents($key_file, $private_key);
+      }
+      // The file properties add more entropy not easily accessible to others.
+      $key = $private_key . filectime(__FILE__) . fileinode(__FILE__);
+    }
+    // Generate a moderately secure HMAC based on the database credentials.
+    $salt = uniqid('', TRUE);
+    $check_string = $prefix . ';' . time() . ';' . $salt;
+    return $check_string . ';' . Crypt::hmacBase64($check_string, $key);
+  }
+
+  /**
+   * Enables use of the theme system without requiring database access.
+   *
+   * Loads and initializes the theme system for site installs, updates and when
+   * the site is in maintenance mode. This also applies when the database fails.
+   *
+   * @see _drupal_maintenance_theme()
+   */
+  function drupal_maintenance_theme() {
+    require_once __DIR__ . '/theme.maintenance.inc';
+    _drupal_maintenance_theme();
+  }
+
+  /**
+   * Returns TRUE if a Drupal installation is currently being attempted.
+   */
+  function drupal_installation_attempted() {
+    // This cannot rely on the MAINTENANCE_MODE constant, since that would prevent
+    // tests from using the non-interactive installer, in which case Drupal
+    // only happens to be installed within the same request, but subsequently
+    // executed code does not involve the installer at all.
+    // @see install_drupal()
+    return isset($GLOBALS['install_state']) && empty($GLOBALS['install_state']['installation_finished']);
+  }
+
+  /**
+   * Gets the name of the currently active installation profile.
+   *
+   * When this function is called during Drupal's initial installation process,
+   * the name of the profile that's about to be installed is stored in the global
+   * installation state. At all other times, the "install_profile" setting will be
+   * available in settings.php.
+   *
+   * @return string|null $profile
+   *   The name of the installation profile or NULL if no installation profile is
+   *   currently active. This is the case for example during the first steps of
+   *   the installer or during unit tests.
+   */
+  function drupal_get_profile() {
+    global $install_state;
+
+    if (drupal_installation_attempted()) {
+      // If the profile has been selected return it.
+      if (isset($install_state['parameters']['profile'])) {
+        $profile = $install_state['parameters']['profile'];
+      }
+      else {
+        $profile = NULL;
+      }
+    }
+    else {
+      // Fall back to NULL, if there is no 'install_profile' setting.
+      $profile = Settings::get('install_profile');
+    }
+
+    return $profile;
+  }
+
+  /**
+   * Registers an additional namespace.
+   *
+   * @param string $name
+   *   The namespace component to register; e.g., 'node'.
+   * @param string $path
+   *   The relative path to the Drupal component in the filesystem.
+   */
+  function drupal_classloader_register($name, $path) {
+    $loader = \Drupal::service('class_loader');
+    $loader->addPsr4('Drupal\\' . $name . '\\', \Drupal::root() . '/' . $path . '/src');
+  }
+
+  /**
+   * Provides central static variable storage.
+   *
+   * All functions requiring a static variable to persist or cache data within
+   * a single page request are encouraged to use this function unless it is
+   * absolutely certain that the static variable will not need to be reset during
+   * the page request. By centralizing static variable storage through this
+   * function, other functions can rely on a consistent API for resetting any
+   * other function's static variables.
+   *
+   * Example:
+   * @code
+   * function example_list($field = 'default') {
+   *   $examples = &drupal_static(__FUNCTION__);
+   *   if (!isset($examples)) {
+   *     // If this function is being called for the first time after a reset,
+   *     // query the database and execute any other code needed to retrieve
+   *     // information.
+   *     ...
+   *   }
+   *   if (!isset($examples[$field])) {
+   *     // If this function is being called for the first time for a particular
+   *     // index field, then execute code needed to index the information already
+   *     // available in $examples by the desired field.
+   *     ...
+   *   }
+   *   // Subsequent invocations of this function for a particular index field
+   *   // skip the above two code blocks and quickly return the already indexed
+   *   // information.
+   *   return $examples[$field];
+   * }
+   * function examples_admin_overview() {
+   *   // When building the content for the overview page, make sure to get
+   *   // completely fresh information.
+   *   drupal_static_reset('example_list');
+   *   ...
+   * }
+   * @endcode
+   *
+   * In a few cases, a function can have certainty that there is no legitimate
+   * use-case for resetting that function's static variable. This is rare,
+   * because when writing a function, it's hard to forecast all the situations in
+   * which it will be used. A guideline is that if a function's static variable
+   * does not depend on any information outside of the function that might change
+   * during a single page request, then it's ok to use the "static" keyword
+   * instead of the drupal_static() function.
+   *
+   * Example:
+   * @code
+   * function mymodule_log_stream_handle($new_handle = NULL) {
+   *   static $handle;
+   *   if (isset($new_handle)) {
+   *     $handle = $new_handle;
+   *   }
+   *   return $handle;
+   * }
+   * @endcode
+   *
+   * In a few cases, a function needs a resettable static variable, but the
+   * function is called many times (100+) during a single page request, so
+   * every microsecond of execution time that can be removed from the function
+   * counts. These functions can use a more cumbersome, but faster variant of
+   * calling drupal_static(). It works by storing the reference returned by
+   * drupal_static() in the calling function's own static variable, thereby
+   * removing the need to call drupal_static() for each iteration of the function.
+   * Conceptually, it replaces:
+   * @code
+   * $foo = &drupal_static(__FUNCTION__);
+   * @endcode
+   * with:
+   * @code
+   * // Unfortunately, this does not work.
+   * static $foo = &drupal_static(__FUNCTION__);
+   * @endcode
+   * However, the above line of code does not work, because PHP only allows static
+   * variables to be initialized by literal values, and does not allow static
+   * variables to be assigned to references.
+   * - http://php.net/manual/language.variables.scope.php#language.variables.scope.static
+   * - http://php.net/manual/language.variables.scope.php#language.variables.scope.references
+   * The example below shows the syntax needed to work around both limitations.
+   * For benchmarks and more information, see http://drupal.org/node/619666.
+   *
+   * Example:
+   * @code
+   * function example_default_format_type() {
+   *   // Use the advanced drupal_static() pattern, since this is called very often.
+   *   static $drupal_static_fast;
+   *   if (!isset($drupal_static_fast)) {
+   *     $drupal_static_fast['format_type'] = &drupal_static(__FUNCTION__);
+   *   }
+   *   $format_type = &$drupal_static_fast['format_type'];
+   *   ...
+   * }
+   * @endcode
+   *
+   * @param $name
+   *   Globally unique name for the variable. For a function with only one static,
+   *   variable, the function name (e.g. via the PHP magic __FUNCTION__ constant)
+   *   is recommended. For a function with multiple static variables add a
+   *   distinguishing suffix to the function name for each one.
+   * @param $default_value
+   *   Optional default value.
+   * @param $reset
+   *   TRUE to reset one or all variables(s). This parameter is only used
+   *   internally and should not be passed in; use drupal_static_reset() instead.
+   *   (This function's return value should not be used when TRUE is passed in.)
+   *
+   * @return
+   *   Returns a variable by reference.
+   *
+   * @see drupal_static_reset()
+   */
+  function &drupal_static($name, $default_value = NULL, $reset = FALSE) {
+    static $data = array(), $default = array();
+    // First check if dealing with a previously defined static variable.
+    if (isset($data[$name]) || array_key_exists($name, $data)) {
+      // Non-NULL $name and both $data[$name] and $default[$name] statics exist.
+      if ($reset) {
+        // Reset pre-existing static variable to its default value.
+        $data[$name] = $default[$name];
+      }
+      return $data[$name];
+    }
+    // Neither $data[$name] nor $default[$name] static variables exist.
+    if (isset($name)) {
+      if ($reset) {
+        // Reset was called before a default is set and yet a variable must be
+        // returned.
+        return $data;
+      }
+      // First call with new non-NULL $name. Initialize a new static variable.
+      $default[$name] = $data[$name] = $default_value;
+      return $data[$name];
+    }
+    // Reset all: ($name == NULL). This needs to be done one at a time so that
+    // references returned by earlier invocations of drupal_static() also get
+    // reset.
+    foreach ($default as $name => $value) {
+      $data[$name] = $value;
+    }
+    // As the function returns a reference, the return should always be a
+    // variable.
+    return $data;
+  }
+
+  /**
+   * Resets one or all centrally stored static variable(s).
+   *
+   * @param $name
+   *   Name of the static variable to reset. Omit to reset all variables.
+   *   Resetting all variables should only be used, for example, for running
+   *   unit tests with a clean environment.
+   */
+  function drupal_static_reset($name = NULL) {
+    drupal_static($name, NULL, TRUE);
+  }
+
+  /**
+   * Formats text for emphasized display in a placeholder inside a sentence.
+   *
+   * @see \Drupal\Component\Utility\SafeMarkup::placeholder()
+   */
+  function drupal_placeholder($text) {
+    return SafeMarkup::placeholder($text);
+  }
+
+  /**
+   * Registers a function for execution on shutdown.
+   *
+   * Wrapper for register_shutdown_function() that catches thrown exceptions to
+   * avoid "Exception thrown without a stack frame in Unknown".
+   *
+   * @param $callback
+   *   The shutdown function to register.
+   * @param ...
+   *   Additional arguments to pass to the shutdown function.
+   *
+   * @return
+   *   Array of shutdown functions to be executed.
+   *
+   * @see register_shutdown_function()
+   * @ingroup php_wrappers
+   */
+  function &drupal_register_shutdown_function($callback = NULL) {
+    // We cannot use drupal_static() here because the static cache is reset during
+    // batch processing, which breaks batch handling.
+    static $callbacks = array();
+
+    if (isset($callback)) {
+      // Only register the internal shutdown function once.
+      if (empty($callbacks)) {
+        register_shutdown_function('_drupal_shutdown_function');
+      }
+      $args = func_get_args();
+      // Remove $callback from the arguments.
+      unset($args[0]);
+      // Save callback and arguments
+      $callbacks[] = array('callback' => $callback, 'arguments' => $args);
+    }
+    return $callbacks;
+  }
+
+  /**
+   * Executes registered shutdown functions.
+   */
+  function _drupal_shutdown_function() {
+    $callbacks = &drupal_register_shutdown_function();
+
+    // Set the CWD to DRUPAL_ROOT as it is not guaranteed to be the same as it
+    // was in the normal context of execution.
+    chdir(DRUPAL_ROOT);
+
+    try {
+      while (list($key, $callback) = each($callbacks)) {
+        call_user_func_array($callback['callback'], $callback['arguments']);
+      }
+    }
+    catch (Exception $exception) {
+      // If using PHP-FPM then fastcgi_finish_request() will have been fired
+      // preventing further output to the browser.
+      if (!function_exists('fastcgi_finish_request')) {
+        // If we are displaying errors, then do so with no possibility of a
+        // further uncaught exception being thrown.
+        require_once __DIR__ . '/errors.inc';
+        if (error_displayable()) {
+          print '<h1>Uncaught exception thrown in shutdown function.</h1>';
+          print '<p>' . Error::renderExceptionSafe($exception) . '</p><hr />';
+        }
+      }
+      error_log($exception);
+    }
+  }
+
+
+}
+
+/**
+ * And now the Environment namespace where we will define BaseEnvironment.
+ */
+namespace Drupal\Core\Environment {
+
+  use Drupal\Component\Utility\Unicode;
+  use Drupal\Component\Utility\Crypt;
+  use Drupal\Component\Utility\Timer;
+  use Drupal\Core\Site\Settings;
+  use Drupal\Core\Database\Database;
+  use Symfony\Component\HttpFoundation\Request;
+  use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
+
+
+  /**
+   * Drupal Root Enivornment
+   *
+   * During its construction this class sets up the environment needed by
+   * Drupal Kernel and saves several discovered settings. It is highly
+   * modularized allowing each step of the process to be elaborated upon
+   * or overwritten by specific environments.
+   */
+  abstract class BaseEnvironment {
+
+    /**
+     * Site Path.
+     */
+    protected $sitePath = NULL;
+
+    /**
+     * Initial Request.
+     */
+    protected $request = NULL;
+
+    /**
+     * Class Loader
+     */
+    protected $classLoader = NULL;
+
+    /**
+     * Valid Host Patterns.
+     */
+    protected $hostPatterns = NULL;
+
+    /**
+     * Define the current profile.
+     *
+     * STRICT mode prevents us from labelling this as abstract, but ideally
+     * it would be.
+     */
+    protected static function defineProfile() {}
+
+    /**
+     * Return an Environment object.
+     */
+    public function __construct(Request $request, $class_loader) {
+
+      // The very basics - who, where when.
+      $this->defineProfile();
+      $this->defineRoot();
+      $this->defineRequestTime();
+
+      // Fault Management
+      $this->setAssertHandler();
+      $this->setDeprecationErrorHandler();
+      $this->setStrictAndNoticeErrorHandler();
+      $this->setPrimaryErrorHandler();
+      $this->setExceptionHandler();
+
+      // Normally we'd do this assertion at the start, but we needed to set
+      // The handlers first in case we need to handle a raised fail.
+      assert('\\Drupal\\Component\\Fault\\Assertion::validCaller(\'\\Drupal\\Core\\DrupalKernel\')',
+        'Only DrupalKernel should use this object.'
+      );
+
+      // Now the last of the low level settings.
+      $this->setEnvironment();
+      $this->setStringHandling();
+      $this->defineTestState();
+
+      // Attach the request and loader.
+      $this->setRequest($request);
+      $this->setLoader($class_loader);
+
+      // Determine the site.
+      $this->findSitePath();
+      $this->loadSettings();
+
+      // Verify the Host.
+      $this->setHostPatterns();
+      $this->setupTrustedHosts();
+
+      // Get the Database ready.
+      $this->setupDatabase();
+
+      // And now we begin timing the page.  If we need to check the efficiency
+      // of the forgoing process we can check against the
+      // $_SERVER['REQUEST_TIME'].
+      $this->startPageTimer();
+
+    }
+
+    /**
+     * All properties are readable, none are writable.
+     */
+    public function __get($var) {
+      return $this->$var;
+    }
+
+    /**
+     * Set the Request.
+     */
+    protected function setRequest($request) {
+      $this->request = $request;
+    }
+
+    /**
+     * Set the Loader.
+     */
+    protected function setLoader($class_loader) {
+      $this->classLoader = $class_loader;
+    }
+
+    /**
+     * Set the hostPatterns.
+     */
+    protected function setHostPatterns() {
+      $this->hostPatterns = Settings::get('trusted_host_patterns', []);
+    }
+
+    /**
+     * Set up the database. Note that the installation script overrides this
+     * function with an empty function that does nothing.
+     */
+    protected function setupDatabase() {
+
+      // Redirect the user to the installation script if Drupal has not been
+      // installed yet (i.e., if no $databases array has been defined in the
+      // settings.php file) and we are not already installing.
+      if (!Database::getConnectionInfo() && PHP_SAPI !== 'cli') {
+        ( new RedirectResponse($request->getBasePath() . '/core/install.php'))
+          ->prepare($request)
+          ->send();
+      }
+    }
+
+    /**
+     * Load Settings.
+     */
+    protected function loadSettings() {
+      Settings::initialize(DRUPAL_ROOT, $this->sitePath, $this->classLoader);
+    }
+
+    /**
+     * Sets up the lists of trusted HTTP Host headers.
+     *
+     * Since the HTTP Host header can be set by the user making the request, it
+     * is possible to create an attack vectors against a site by overriding this.
+     * Symfony provides a mechanism for creating a list of trusted Host values.
+     *
+     * Host patterns (as regular expressions) can be configured throught
+     * settings.php for multisite installations, sites using ServerAlias without
+     * canonical redirection, or configurations where the site responds to default
+     * requests. For example,
+     *
+     * @code
+     * $settings['trusted_host_patterns'] = array(
+     *   '^example\.com$',
+     *   '^*.example\.com$',
+     * );
+     * @endcode
+     *
+     * @param \Symfony\Component\HttpFoundation\Request $request
+     *   The request object.
+     * @param array $host_patterns
+     *   The array of trusted host patterns.
+     *
+     * @return boolean
+     *   TRUE if the Host header is trusted, FALSE otherwise.
+     *
+     * @see https://www.drupal.org/node/1992030
+     * @see \Drupal\Core\Http\TrustedHostsRequestFactory
+     */
+    protected function setupTrustedHosts() {
+
+      if (PHP_SAPI !== 'cli' && !empty($this->hostPatterns)) {
+        $this->request->setTrustedHosts($this->hostPatterns);
+
+        // Get the host, which will validate the current request.
+        try {
+          $host = $request->getHost();
+
+          // Fake requests created through Request::create() without passing in the
+          // server variables from the main request have a default host of
+          // 'localhost'. If 'localhost' does not match any of the trusted host
+          // patterns these fake requests would fail the host verification. Instead,
+          // TrustedHostsRequestFactory makes sure to pass in the server variables
+          // from the main request.
+          $request_factory = new TrustedHostsRequestFactory($host);
+          Request::setFactory([$request_factory, 'createRequest']);
+        }
+        catch (\UnexpectedValueException $e) {
+          throw new BadRequestHttpException('The provided host name is not valid for this server.');
+        }
+      }
+    }
+
+    /**
+     * Validates a hostname length.
+     *
+     * @param string $host
+     *   A hostname.
+     *
+     * @return bool
+     *   TRUE if the length is appropriate, or FALSE otherwise.
+     */
+    protected function validateHostnameLength($host) {
+      // Limit the length of the host name to 1000 bytes to prevent DoS attacks
+      // with long host names.
+      return strlen($host) <= 1000
+      // Limit the number of subdomains and port separators to prevent DoS attacks
+      // in findSitePath().
+      && substr_count($host, '.') <= 100
+      && substr_count($host, ':') <= 100;
+    }
+
+    /**
+     * Validates the hostname supplied from the HTTP request.
+     *
+     * @param \Symfony\Component\HttpFoundation\Request $request
+     *   The request object
+     *
+     * @return bool
+     *   TRUE if the hostmame is valid, or FALSE otherwise.
+     *
+     * @todo Adjust per resolution to https://github.com/symfony/symfony/issues/12349
+     */
+    public function validateHostname(Request $request) {
+      // $request->getHost() can throw an UnexpectedValueException if it
+      // detects a bad hostname, but it does not validate the length.
+      try {
+        $http_host = $request->getHost();
+      }
+      catch (\UnexpectedValueException $e) {
+        return FALSE;
+      }
+
+      if ($this->validateHostnameLength($http_host) === FALSE) {
+        return FALSE;
+      }
+
+      return TRUE;
+    }
+
+    /**
+     * Returns the appropriate site directory for a request.
+     *
+     * Once the kernel has been created DrupalKernelInterface::getSitePath() is
+     * preferred since it gets the statically cached result of this method.
+     *
+     * Site directories contain all site specific code. This includes settings.php
+     * for bootstrap level configuration, file configuration stores, public file
+     * storage and site specific modules and themes.
+     *
+     * Finds a matching site directory file by stripping the website's hostname
+     * from left to right and pathname from right to left. By default, the
+     * directory must contain a 'settings.php' file for it to match. If the
+     * parameter $require_settings is set to FALSE, then a directory without a
+     * 'settings.php' file will match as well. The first configuration file found
+     * will be used and the remaining ones will be ignored. If no configuration
+     * file is found, returns a default value 'sites/default'. See
+     * default.settings.php for examples on how the URL is converted to a
+     * directory.
+     *
+     * If a file named sites.php is present in the sites directory, it will be
+     * loaded prior to scanning for directories. That file can define aliases in
+     * an associative array named $sites. The array is written in the format
+     * '<port>.<domain>.<path>' => 'directory'. As an example, to create a
+     * directory alias for http://www.drupal.org:8080/mysite/test whose
+     * configuration file is in sites/example.com, the array should be defined as:
+     * @code
+     * $sites = array(
+     *   '8080.www.drupal.org.mysite.test' => 'example.com',
+     * );
+     * @endcode
+     *
+     * @param \Symfony\Component\HttpFoundation\Request $request
+     *   The current request.
+     * @param bool $require_settings
+     *   Only directories with an existing settings.php file will be recognized.
+     *   Defaults to TRUE. During initial installation, this is set to FALSE so
+     *   that Drupal can detect a matching directory, then create a new
+     *   settings.php file in it.
+     *
+     * @return string
+     *   The path of the matching directory.
+     *
+     * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
+     *   In case the host name in the request is invalid.
+     *
+     * @see \Drupal\Core\DrupalKernelInterface::getSitePath()
+     * @see \Drupal\Core\DrupalKernelInterface::setSitePath()
+     * @see default.settings.php
+     * @see example.sites.php
+     */
+    protected function findSitePath() {
+      if ($this->validateHostname($this->request) === FALSE) {
+        throw new BadRequestHttpException();
+      }
+
+      // Determine whether multi-site functionality is enabled.
+      if (!file_exists(DRUPAL_ROOT . '/sites/sites.php')) {
+        $this->sitePath = 'sites/default';
+      }
+      else {
+
+        // Otherwise, use find the site path using the request.
+        $script_name = $request->server->get('SCRIPT_NAME');
+        if (!$script_name) {
+          $script_name = $request->server->get('SCRIPT_FILENAME');
+        }
+        $http_host = $request->getHost();
+
+        $sites = array();
+        include DRUPAL_ROOT . '/sites/sites.php';
+
+        $uri = explode('/', $script_name);
+        $server = explode('.', implode('.', array_reverse(explode(':', rtrim($http_host, '.')))));
+        for ($i = count($uri) - 1; $i > 0; $i--) {
+          for ($j = count($server); $j > 0; $j--) {
+            $dir = implode('.', array_slice($server, -$j)) . implode('.', array_slice($uri, 0, $i));
+            if (isset($sites[$dir]) && file_exists(DRUPAL_ROOT . '/sites/' . $sites[$dir])) {
+              $dir = $sites[$dir];
+            }
+            if (file_exists(DRUPAL_ROOT . '/sites/' . $dir . '/settings.php')) {
+              $this->sitePath = "sites/$dir";
+              break(2);
+            }
+          }
+        }
+
+        $this->sitePath === NULL ? 'sites/default' : $this->sitePath;
+      }
+
+      return $this->sitePath;
+    }
+
+    /**
+     * Start the page timer.
+     */
+    protected static function startPageTimer() {
+      Timer::start('page');
+    }
+
+    /**
+     * Set string handling.
+     */
+    protected static function setStringHandling() {
+      Unicode::check();
+    }
+
+    /**
+     * Set the environment.
+     *
+     * Override PHP settings required for Drupal to work properly.
+     * sites/default/default.settings.php contains more runtime settings.
+     * The .htaccess file contains settings that cannot be changed at runtime.
+     * other than display_errors and assert_active, which are used to configure
+     * the fault system in addition to their effect on PHP.
+     */
+    protected static function setEnvironment() {
+
+      // Error level.
+      error_reporting(E_ALL);
+
+      // Use session cookies, not transparent sessions that puts the session id in
+      // the query string.
+      ini_set('session.use_cookies', '1');
+      ini_set('session.use_only_cookies', '1');
+      ini_set('session.use_trans_sid', '0');
+
+      // Don't send HTTP headers using PHP's session handler.
+      // Send an empty string to disable the cache limiter.
+      ini_set('session.cache_limiter', '');
+
+      // Use httponly session cookies.
+      ini_set('session.cookie_httponly', '1');
+
+      // Set sane locale settings, to ensure consistent string, dates, times and
+      // numbers handling.
+      setlocale(LC_ALL, 'C');
+
+      // Ensure mt_rand() is reseeded to prevent random values from one page load
+      // being exploited to predict random values in subsequent page loads.
+      mt_srand(unpack("L", Crypt::randomBytes(4))[1]);
+    }
+
+    /**
+     * Set the Assertion Handler.
+     */
+    protected function setAssertHandler() {
+      if (assert_options(ASSERT_ACTIVE)) {
+        assert_options(ASSERT_CALLBACK, [__CLASS__, 'handleAssert']);
+        assert_options(ASSERT_WARNING, 0);
+        assert_options(ASSERT_BAIL, 1);
+      }
+    }
+
+    /**
+     * Set the Deprecation Notice Handler.
+     */
+    protected function setDeprecationErrorHandler() {}
+
+    /**
+     * Set the Strict and Notice Handler.
+     */
+    protected function setStrictAndNoticeErrorHandler() {}
+
+    /**
+     * Set the handler for all other errors.
+     */
+    protected function setPrimaryErrorHandler() {
+   //   set_error_handler('_drupal_error_handler');
+    }
+
+    /**
+     * Set the exception handler
+     */
+    protected function setExceptionHandler() {
+   //   set_exception_handler('_drupal_exception_handler');
+    }
+
+    /**
+     * Mark us as being in the non test state. Test Environments must override.
+     */
+    protected function defineTestState() {
+      define('DRUPAL_TEST_IN_CHILD_SITE', FALSE);
+    }
+
+    /**
+     * Assertion Handler.
+     *
+     * @see http://www.php.net/assert
+     * @see http://www.php.net/assert_options
+     */
+    public final static function handleAssert($file, $line, $code, $message = NULL) {
+      (new \Drupal\Component\Fault\AssertionHandler($file, $line, $code, $message, debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT)))
+        ->resolve();
+    }
+
+    /**
+     * Defines the root directory of the Drupal installation.
+     *
+     * This strips two levels of directories off the current directory.
+     */
+    protected static function defineRoot() {
+      define('DRUPAL_ROOT', dirname(dirname(dirname(dirname(dirname(__DIR__))))));
+    }
+
+    /**
+     * Time of the current request in seconds elapsed since the Unix Epoch.
+     *
+     * This differs from $_SERVER['REQUEST_TIME'], which is stored as a float
+     * since PHP 5.4.0. Float timestamps confuse most PHP functions
+     * (including date_create()).
+     *
+     * @see http://php.net/manual/reserved.variables.server.php
+     * @see http://php.net/manual/function.time.php
+     */
+    protected static function defineRequestTime() {
+      define('REQUEST_TIME', (int) $_SERVER['REQUEST_TIME']);
+    }
+
+  }
+
+
+}
diff --git a/core/lib/Drupal/Core/Environment/ProductionEnvironment.php b/core/lib/Drupal/Core/Environment/ProductionEnvironment.php
new file mode 100644
index 0000000..a3454d3
--- /dev/null
+++ b/core/lib/Drupal/Core/Environment/ProductionEnvironment.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * @file Production Boot Profile
+ */
+namespace {
+  /**
+   * BC Wrap.
+   */
+  function drupal_valid_test_ua($new_prefix = NULL) {
+    return NULL;
+  }
+}
+
+
+/**
+ * This will probably grow as I figure out which of the processes in
+ * BaseEnvironment should be unique to production.
+ */
+namespace Drupal\Core\Environment {
+  class ProductionEnvironment extends BaseEnvironment {
+
+    protected static function defineProfile() {
+        define('DRUPAL_PROFILE', 'prod');
+    }
+  }
+}
diff --git a/core/lib/Drupal/Core/Environment/ProductionTestEnvironment.php b/core/lib/Drupal/Core/Environment/ProductionTestEnvironment.php
new file mode 100644
index 0000000..e6627a4
--- /dev/null
+++ b/core/lib/Drupal/Core/Environment/ProductionTestEnvironment.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * @file Defines Production Test Environment
+ */
+
+namespace {
+  function drupal_valid_test_ua($new_prefix = NULL) {
+    return \Drupal\Core\Boot\ProductionTestEnvironment::validateTestUserAgent($new_prefix);
+}
+
+namespace Drupal\Core\Environment {
+  class ProductionTestEnvironment extends BaseEnvironment {
+
+    protected static $testPrefix = NULL;
+
+    public static function run() {
+      parent::run();
+      static::validateTestUserAgent();
+
+
+    }
+
+    protected function findSitePath() {
+      $this->sitePath = 'sites/simpletest/' . substr($this->testPrefix, 10);
+      return $this->sitePath;
+    }
+
+    protected static function defineTestState() {
+      define('DRUPAL_TEST_IN_CHILD_SITE', TRUE);
+    }
+
+   /**
+     * Returns the test prefix if this is an internal request from SimpleTest.
+     *
+     * @param string $new_prefix
+     *   Internal use only. A new prefix to be stored.
+     *
+     * @return string|FALSE
+     *   Either the simpletest prefix (the string "simpletest" followed by any
+     *   number of digits) or FALSE if the user agent does not contain a valid
+     *   HMAC and timestamp.
+     */
+    public static function validateTestUserAgent($test_prefix) {
+
+      // Perform a basic check on the User-Agent HTTP request header first. Any
+      // inbound request that uses the simpletest UA header needs to be validated.
+      if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match("/^(simpletest\d+);(.+);(.+);(.+)$/", $_SERVER['HTTP_USER_AGENT'], $matches)) {
+        list(, $prefix, $time, $salt, $hmac) = $matches;
+        $check_string =  $prefix . ';' . $time . ';' . $salt;
+        // Read the hash salt prepared by drupal_generate_test_ua().
+        // This function is called before settings.php is read and Drupal's error
+        // handlers are set up. While Drupal's error handling may be properly
+        // configured on production sites, the server's PHP error_reporting may not.
+        // Ensure that no information leaks on production sites.
+        $key_file = DRUPAL_ROOT . '/sites/simpletest/' . substr($prefix, 10) . '/.htkey';
+        if (!is_readable($key_file)) {
+          header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');
+          exit;
+        }
+        $private_key = file_get_contents($key_file);
+        // The file properties add more entropy not easily accessible to others.
+        $key = $private_key . filectime(__FILE__) . fileinode(__FILE__);
+        $time_diff = REQUEST_TIME - $time;
+        $test_hmac = Crypt::hmacBase64($check_string, $key);
+        // Since we are making a local request a 5 second time window is allowed,
+        // and the HMAC must match.
+        if ($time_diff >= 0 && $time_diff <= 5 && $hmac === $test_hmac) {
+          $test_prefix = $prefix;
+        }
+      }
+      static::testPrefix = $test_prefix;
+
+      define('DRUPAL_TEST_IN_CHILD_SITE', TRUE);
+      ini_set('log_errors', 1);
+      ini_set('error_log', DRUPAL_ROOT . '/sites/simpletest/' . substr($test_prefix, 10) . '/error.log');
+    }
+
+  }
+
+
+}
diff --git a/index.php b/index.php
index e4de701..acea22d 100644
--- a/index.php
+++ b/index.php
@@ -9,39 +9,15 @@
  */
 
 use Drupal\Core\DrupalKernel;
-use Drupal\Core\Site\Settings;
-use Drupal\Component\Fault\FaultSetup;
-use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
 use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\HttpFoundation\Response;
 
 $autoloader = require_once 'autoload.php';
 
-FaultSetup::start();
+$request = Request::createFromGlobals();
 
-try {
-  $request = Request::createFromGlobals();
-  $kernel = DrupalKernel::createFromRequest($request, $autoloader, 'prod');
-  $response = $kernel
-      ->handle($request)
-      // Handle the response object.
-      ->prepare($request)->send();
-  $kernel->terminate($request, $response);
-}
-catch (HttpExceptionInterface $e) {
-  $response = new Response($e->getMessage(), $e->getStatusCode());
-  $response->prepare($request)->send();
-}
-catch (Exception $e) {
-  $message = 'If you have just changed code (for example deployed a new module or moved an existing one) read <a href="http://drupal.org/documentation/rebuild">http://drupal.org/documentation/rebuild</a>';
-  if (Settings::get('rebuild_access', FALSE)) {
-    $rebuild_path = $GLOBALS['base_url'] . '/rebuild.php';
-    $message .= " or run the <a href=\"$rebuild_path\">rebuild script</a>";
-  }
+$kernel = new DrupalKernel($request, 'Production', $autoloader);
 
-  // Set the response code manually. Otherwise, this response will default to a
-  // 200.
-  http_response_code(500);
-  print $message;
-  throw $e;
-}
+$response = $kernel->handle($request);
+$response->send();
+
+$kernel->terminate($request, $response);
