diff --git a/core/INSTALL.txt b/core/INSTALL.txt
index f985620..080aad1 100644
--- a/core/INSTALL.txt
+++ b/core/INSTALL.txt
@@ -148,40 +148,39 @@ INSTALLATION
    b. Missing settings file.
 
       Drupal will try to automatically create settings.php and services.yml
-      files, which are normally in the directory sites/default (to avoid
+      files, which are normally in the directory settings (to avoid
       problems when upgrading, Drupal is not packaged with this file). If
       auto-creation of either file fails, you will need to create the file
-      yourself. Use the template sites/default/default.settings.php or
-      sites/default/default.services.yml respectively.
+      yourself. Use the template core/default.settings.php or
+      core/default.services.yml respectively.
 
       For example, on a Unix/Linux command line, you can make a copy of the
       default.settings.php and default.services.yml files with the commands:
 
-        cp sites/default/default.settings.php sites/default/settings.php
-        cp sites/default/default.services.yml sites/default/services.yml
+        cp core/default.settings.php settings/settings.php
+        cp core/default.services.yml settings/services.yml
 
       Next, grant write privileges to the file to everyone (including the web
       server) with the command:
 
-        chmod a+w sites/default/settings.php
-        chmod a+w sites/default/services.yml
+        chmod a+w settings/settings.php
+        chmod a+w settings/services.yml
 
       Be sure to set the permissions back after the installation is finished!
       Sample command:
 
-        chmod go-w sites/default/settings.php
-        chmod go-w sites/default/services.yml
+        chmod go-w settings/settings.php
+        chmod go-w settings/services.yml
 
    c. Write permissions after install.
 
-      The install script will attempt to write-protect the settings.php file and
-      the sites/default directory after saving your configuration. If this
-      fails, you will be notified, and you can do it manually. Sample commands
-      from a Unix/Linux command line:
+      The install script will attempt to write-protect the settings.php file
+      after saving your configuration. If this fails, you will be notified, and
+      you can do it manually. Sample commands from a Unix/Linux command line:
 
-        chmod go-w sites/default/settings.php
-        chmod go-w sites/default/services.yml
-        chmod go-w sites/default
+        chmod go-w settings/settings.php
+        chmod go-w settings/services.yml
+        chmod go-w settings
 
 4. Verify that the site is working.
 
@@ -298,9 +297,9 @@ Drupal can be reinstalled without downloading and extracting the Drupal release.
 
 1. Drop all the tables in your database.
 
-2. Remove everything in sites/default/files.
+2. Remove everything in the files directory.
 
-3. Remove sites/default/settings.php.
+3. Remove settings.php.
 
 4. Follow the Installation Instructions above starting from Step 3 (Run the
    install script).
@@ -333,28 +332,28 @@ MULTISITE CONFIGURATION
 A single Drupal installation can host several Drupal-powered sites, each with
 its own individual configuration.
 
-For this to work you need the file sites/sites.php to exist. Make a copy of
-the example.sites.php file:
+For this to work you need to enable the commented out $sites variable in the
+settings.php in Drupal's root directory, like so:
 
-  $ cp sites/example.sites.php sites/sites.php
+  $sites = array();
 
 Additional site configurations are created in subdirectories within the 'sites'
 directory. Each subdirectory must have a 'settings.php' file, which specifies
 the configuration settings. The easiest way to create additional sites is to
-copy file 'default.settings.php' from the 'sites/default' directory into the
-new site directory with file name 'settings.php' and modify as appropriate.
+copy file 'core/default.settings.php' into the new site directory with file name
+'settings.php' and modify as appropriate.
+
 The new directory name is constructed from the site's URL. The configuration
 for www.example.com could be in 'sites/example.com/settings.php' (note that
 'www.' should be omitted if users can access your site at http://example.com/).
 
-  $ cp sites/default/defaults.settings.php sites/example.com/settings.php
+  $ cp core/default.settings.php sites/example.com/settings.php
 
 Sites do not have to have a different domain. You can also use subdomains and
 subdirectories for Drupal sites. For example, example.com, sub.example.com, and
 sub.example.com/site3 can all be defined as independent Drupal sites. The setup
 for a configuration such as this would look like the following:
 
-  sites/default/settings.php
   sites/example.com/settings.php
   sites/sub.example.com/settings.php
   sites/sub.example.com.site3/settings.php
@@ -369,7 +368,7 @@ first configuration it finds:
   sites/www.sub.example.com/settings.php
   sites/sub.example.com/settings.php
   sites/example.com/settings.php
-  sites/default/settings.php
+  settings.php
 
 If you are installing on a non-standard port, the port number is treated as the
 deepest subdomain. For example: http://www.example.com:8080/ could be loaded
diff --git a/core/UPGRADE.txt b/core/UPGRADE.txt
index 420f6ad..a422639 100644
--- a/core/UPGRADE.txt
+++ b/core/UPGRADE.txt
@@ -61,8 +61,8 @@ following the instructions in the INTRODUCTION section at the top of this file:
    If you made modifications to files like .htaccess or robots.txt, you will
    need to re-apply them from your backup, after the new files are in place.
 
-   Sometimes an update includes changes to default.settings.php (this will be
-   noted in the release notes). If that's the case, follow these steps:
+   Sometimes an update includes changes to core/default.settings.php (this will
+   be noted in the release notes). If that's the case, follow these steps:
 
    - Make a backup copy of your settings.php file, with a different file name.
 
diff --git a/sites/default/default.services.yml b/core/default.services.yml
similarity index 100%
copy from sites/default/default.services.yml
copy to core/default.services.yml
diff --git a/sites/default/default.settings.php b/core/default.settings.php
similarity index 77%
copy from sites/default/default.settings.php
copy to core/default.settings.php
index 017fe8a..b6e9144 100644
--- a/sites/default/default.settings.php
+++ b/core/default.settings.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Drupal site-specific configuration file.
+ * Drupal configuration file.
  *
  * IMPORTANT NOTE:
  * This file may have been set to read-only by the Drupal installation program.
@@ -10,10 +10,9 @@
  * your modifications. Failure to remove write permissions to this file is a
  * security risk.
  *
- * In order to use the selection rules below the multisite aliasing file named
- * sites/sites.php must be present. Its optional settings will be loaded, and
- * the aliases in the array $sites will override the default directory rules
- * below. See sites/example.sites.php for more information about aliases.
+ * The configuration file to be loaded is based upon the rules below. However
+ * if the multisite aliasing is enabled, the aliases in the $sites array will
+ * override the default directory rules below.
  *
  * The configuration directory will be discovered by stripping the website's
  * hostname from left to right and pathname from right to left. The first
@@ -46,15 +45,60 @@
  * hostname with that number. For example,
  * http://www.drupal.org:8080/mysite/test/ could be loaded from
  * sites/8080.www.drupal.org.mysite.test/.
+ */
+
+/**
+ * Multi-site functionality and aliases.
+ *
+ * Uncomment the $sites variable below to enable Drupal's multi-site
+ * functionality, which allows to serve multiple different sites from the same
+ * code-base.
+ *
+ * An empty $sites variable just enables the sites directory discovery process.
+ * You can additionally define aliases that map hostnames, ports, and path names
+ * to specific site directories. These aliases are applied prior to scanning for
+ * directories and exempt from the discovery rules.
+ *
+ * Aliases are useful on development servers, where the domain name may not be
+ * the same as the domain of the live server. Since Drupal stores file paths in
+ * the database (files, system table, etc.) this will ensure the paths are
+ * correct when the site is deployed to a live server.
+ *
+ * Aliases are defined in an associative array named $sites. The array is
+ * written in the format: '<port>.<domain>.<path>' => 'directory'. As an
+ * example, to map http://www.drupal.org:8080/mysite/test to the configuration
+ * directory sites/example.com, the array should be defined as:
+ * @code
+ * $sites = array(
+ *   '8080.www.drupal.org.mysite.test' => 'example.com',
+ * );
+ * @endcode
+ * The URL, http://www.drupal.org:8080/mysite/test/, could be a symbolic link or
+ * an Apache Alias directive that points to the Drupal root containing
+ * index.php. An alias could also be created for a subdomain. See the
+ * @link http://drupal.org/documentation/install online Drupal installation guide @endlink
+ * for more information on setting up domains, subdomains, and subdirectories.
+ *
+ * The following examples look for a site configuration in sites/example.com:
+ * @code
+ * URL: http://dev.drupal.org
+ * $sites['dev.drupal.org'] = 'example.com';
  *
- * @see example.sites.php
- * @see conf_path()
+ * URL: http://localhost/example
+ * $sites['localhost.example'] = 'example.com';
  *
- * In addition to customizing application settings through variables in
- * settings.php, you can create a services.yml file in the same directory to
- * register custom, site-specific service definitions and/or swap out default
- * implementations with custom ones.
+ * URL: http://localhost:8080/example
+ * $sites['8080.localhost.example'] = 'example.com';
+ *
+ * URL: http://www.drupal.org:8080/mysite/test/
+ * $sites['8080.www.drupal.org.mysite.test'] = 'example.com';
+ * @endcode
+ *
+ * @see \Drupal\Core\Site\Site::getPath()
+ * @see http://drupal.org/documentation/install/multi-site
  */
+# $sites = array();
+# $sites['localhost.example'] = 'example.com';
 
 /**
  * Database settings:
@@ -98,23 +142,22 @@
  * For each database, you may optionally specify multiple "target" databases.
  * A target database allows Drupal to try to send certain queries to a
  * different database if it can but fall back to the default connection if not.
- * That is useful for primary/replica replication, as Drupal may try to connect
- * to a replica server when appropriate and if one is not available will simply
- * fall back to the single primary server (The terms primary/replica are
- * traditionally referred to as master/slave in database server documentation).
+ * That is useful for master/slave replication, as Drupal may try to connect
+ * to a slave server when appropriate and if one is not available will simply
+ * fall back to the single master server.
  *
  * The general format for the $databases array is as follows:
  * @code
  * $databases['default']['default'] = $info_array;
- * $databases['default']['replica'][] = $info_array;
- * $databases['default']['replica'][] = $info_array;
+ * $databases['default']['slave'][] = $info_array;
+ * $databases['default']['slave'][] = $info_array;
  * $databases['extra']['default'] = $info_array;
  * @endcode
  *
  * In the above example, $info_array is an array of settings described above.
- * The first line sets a "default" database that has one primary database
+ * The first line sets a "default" database that has one master database
  * (the second level default).  The second and third lines create an array
- * of potential replica databases.  Drupal will select one at random for a given
+ * of potential slave databases.  Drupal will select one at random for a given
  * request as needed.  The fourth line creates a new database with a name of
  * "extra".
  *
@@ -222,18 +265,12 @@
 /**
  * Location of the site configuration files.
  *
- * The $config_directories array specifies the location of file system
- * directories used for configuration data. On install, "active" and "staging"
- * directories are created for configuration. The staging directory is used for
- * configuration imports; the active directory is not used by default, since the
- * default storage for active configuration is the database rather than the file
- * system (this can be changed; see "Active configuration settings" below).
+ * By default, Drupal configuration files are stored in a randomly named
+ * directory under the default public files path. On install the
+ * named directory is created in the default files directory. For enhanced
+ * security, you may set this variable to a location outside your docroot.
  *
- * The default location for the active and staging directories is inside a
- * randomly-named directory in the public files path; this setting allows you to
- * override these locations. If you use files for the active configuration, you
- * can enhance security by putting the active configuration outside your
- * document root.
+ * @todo Flesh this out, provide more details, etc.
  *
  * Example:
  * @code
@@ -252,7 +289,7 @@
  * directory and reverse proxy address, and temporary configuration, such as
  * turning on Twig debugging and security overrides.
  *
- * @see \Drupal\Core\Site\Settings::get()
+ * @see \Drupal\Component\Utility\Settings::get()
  */
 
 /**
@@ -263,9 +300,9 @@
  * site is deployed on a cluster of web servers, you must ensure that this
  * variable has the same value on each server.
  *
- * For enhanced security, you may set this variable to the contents of a file
- * outside your document root; you should also ensure that this file is not
- * stored with backups of your database.
+ * For enhanced security, you may set this variable to a value using the
+ * contents of a file outside your docroot that is never saved together
+ * with any backups of your Drupal files and database.
  *
  * Example:
  * @code
@@ -288,6 +325,59 @@
 $settings['update_free_access'] = FALSE;
 
 /**
+ * Twig debugging:
+ *
+ * When debugging is enabled:
+ * - The markup of each Twig template is surrounded by HTML comments that
+ *   contain theming information, such as template file name suggestions.
+ * - Note that this debugging markup will cause automated tests that directly
+ *   check rendered HTML to fail. When running automated tests, 'twig_debug'
+ *   should be set to FALSE.
+ * - The dump() function can be used in Twig templates to output information
+ *   about template variables.
+ * - Twig templates are automatically recompiled whenever the source code
+ *   changes (see twig_auto_reload below).
+ *
+ * Note: changes to this setting will only take effect once the cache is
+ * cleared.
+ *
+ * For more information about debugging Twig templates, see
+ * http://drupal.org/node/1906392.
+ *
+ * Not recommended in production environments (Default: FALSE).
+ */
+# $settings['twig_debug'] = TRUE;
+
+/**
+ * Twig auto-reload:
+ *
+ * Automatically recompile Twig templates whenever the source code changes. If
+ * you don't provide a value for twig_auto_reload, it will be determined based
+ * on the value of twig_debug.
+ *
+ * Note: changes to this setting will only take effect once the cache is
+ * cleared.
+ *
+ * Not recommended in production environments (Default: NULL).
+ */
+# $settings['twig_auto_reload'] = TRUE;
+
+/**
+ * Twig cache:
+ *
+ * By default, Twig templates will be compiled and stored in the filesystem to
+ * increase performance. Disabling the Twig cache will recompile the templates
+ * from source each time they are used. In most cases the twig_auto_reload
+ * setting above should be enabled rather than disabling the Twig cache.
+ *
+ * Note: changes to this setting will only take effect once the cache is
+ * cleared.
+ *
+ * Not recommended in production environments (Default: TRUE).
+ */
+# $settings['twig_cache'] = FALSE;
+
+/**
  * External access proxy settings:
  *
  * If your site must access the Internet via a web proxy then you can enter
@@ -450,7 +540,7 @@
  * Remove the leading hash signs to enable.
  *
  * The "en" part of the variable name, is dynamic and can be any langcode of
- * any added language. (eg locale_custom_strings_de for german).
+ * any enabled language. (eg locale_custom_strings_de for german).
  */
 # $settings['locale_custom_strings_en'][''] = array(
 #   'forum'      => 'Discussion board',
@@ -470,6 +560,16 @@
 # $settings['maintenance_theme'] = 'bartik';
 
 /**
+ * Enable access to rebuild.php.
+ *
+ * This setting can be enabled to allow Drupal's php and database cached
+ * storage to be cleared via the rebuild.php page. Access to this page can also
+ * be gained by generating a query string from rebuild_token_calculator.sh and
+ * using these parameters in a request to rebuild.php.
+ */
+# $settings['rebuild_access'] = TRUE;
+
+/**
  * Base URL (optional).
  *
  * If Drupal is generating incorrect URLs on your site, which could
@@ -497,8 +597,8 @@
  * To see what PHP settings are possible, including whether they can be set at
  * runtime (by using ini_set()), read the PHP documentation:
  * http://php.net/manual/ini.list.php
- * See \Drupal\Core\DrupalKernel::bootEnvironment() for required runtime
- * settings and the .htaccess file for non-runtime settings.
+ * See drupal_environment_initialize() in core/includes/bootstrap.inc for
+ * required runtime settings and the .htaccess file for non-runtime settings.
  * Settings defined there should not be duplicated here so as to avoid conflict
  * issues.
  */
@@ -553,16 +653,14 @@
  * Active configuration settings.
  *
  * By default, the active configuration is stored in the database in the
- * {config} table. To use a different storage mechanism for the active
- * configuration, do the following prior to installing:
- * - Override the 'bootstrap_config_storage' setting here. It must be set to a
- *   callable that returns an object that implements
- *   \Drupal\Core\Config\StorageInterface.
- * - Override the service definition 'config.storage.active'. Put this
- *   override in a services.yml file in the same directory as settings.php
- *   (definitions in this file will override service definition defaults).
+ * {config} table. To install Drupal with a different active configuration
+ * storage, you need to override the setting here, in addition to overriding
+ * the config.storage.active service definition in a module or profile.
+ *
+ * The 'bootstrap_config_storage' setting needs to be a callable that returns
+ * core.services.yml.
  */
-# $settings['bootstrap_config_storage'] = array('Drupal\Core\Config\BootstrapConfigStorageFactory', 'getFileStorage');
+ # $settings['bootstrap_config_storage'] = array('Drupal\Core\Config\BootstrapConfigStorageFactory', 'getFileStorage');
 
 /**
  * Configuration overrides.
@@ -625,11 +723,9 @@
  *
  * Use settings.local.php to override variables on secondary (staging,
  * development, etc) installations of this site. Typically used to disable
- * caching, JavaScript/CSS compression, re-routing of outgoing emails, and
+ * caching, JavaScript/CSS compression, re-routing of outgoing e-mails, and
  * other things that should not happen on development and testing sites.
  *
- * Keep this code block at the end of this file to take full effect.
+ * Keep this include at the end of this file to take full effect.
  */
-# if (file_exists(__DIR__ . '/settings.local.php')) {
-#   include __DIR__ . '/settings.local.php';
-# }
+# include __DIR__ . '/settings.local.php';
diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 27494e7..2389f0f 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -13,6 +13,7 @@
 use Drupal\Core\DrupalKernel;
 use Drupal\Core\Extension\ExtensionDiscovery;
 use Drupal\Core\Site\Settings;
+use Drupal\Core\Site\Site;
 use Drupal\Core\Utility\Error;
 use Symfony\Component\ClassLoader\ApcClassLoader;
 use Symfony\Component\HttpFoundation\Request;
@@ -209,43 +210,22 @@
 /**
  * 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.
+ * Temporary backwards-compatibility layer for Drush.
  *
- * @return string
- *   The path of the matching directory.@see default.settings.php
+ * @deprecated 8.x-dev
+ *   Use \Drupal\Core\Site\Site::getPath() instead.
  *
- * @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);
+ * @internal
+ */
+function conf_path() {
+  if (strpos(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)[1]['function'], 'drush') === FALSE) {
+    throw new \Exception('conf_path() is retained for Drush compatibility only.');
   }
-  return $site_path;
+  // When called from _drush_bootstrap_drupal_site_validate() on testbots, this
+  // function is supposed to return the site path of the parent site, which is
+  // '' (the document root). Ensure that the returned path is relative.
+  // @see https://github.com/drush-ops/drush/blob/master/includes/bootstrap.inc#L782
+  return '.';
 }
 /**
  * Returns the path of a configuration directory.
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 3a877a8..448a5ce 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -16,6 +16,7 @@
 use Drupal\Core\Language\LanguageManager;
 use Drupal\Core\Page\DefaultHtmlPageRenderer;
 use Drupal\Core\Site\Settings;
+use Drupal\Core\Site\Site;
 use Drupal\Core\StringTranslation\Translator\FileTranslation;
 use Drupal\Core\Extension\ExtensionDiscovery;
 use Drupal\Core\DependencyInjection\ContainerBuilder;
@@ -288,6 +289,12 @@ function install_begin_request(&$install_state) {
   $site_path = DrupalKernel::findSitePath($request, FALSE);
   Settings::initialize($site_path);
 
+  // Initialize the site directory.
+  // This primes the site path to be used during installation, to allow an empty
+  // site folder to be prepared in the /sites directory into which Drupal will
+  // be installed.
+  Site::initInstaller(DRUPAL_ROOT);
+
   // Ensure that procedural dependencies are loaded as early as possible,
   // since the error/exception handlers depend on them.
   require_once __DIR__ . '/../modules/system/system.install';
@@ -369,7 +376,7 @@ function install_begin_request(&$install_state) {
     $directory = $GLOBALS['config']['locale.settings']['translation.path'];
   }
   else {
-    $directory = $site_path . '/files/translations';
+    $directory = Site::getPath('files/translations');
   }
   $container->set('string_translator.file_translation', new FileTranslation($directory));
   $container->get('string_translation')
@@ -1007,8 +1014,7 @@ function install_verify_completed_task() {
 function install_verify_database_settings() {
   if ($database = Database::getConnectionInfo()) {
     $database = $database['default'];
-    $settings_file = './' . conf_path(FALSE) . '/settings.php';
-    $errors = install_database_errors($database, $settings_file);
+    $errors = install_database_errors($database);
     if (empty($errors)) {
       return TRUE;
     }
@@ -1019,14 +1025,19 @@ function install_verify_database_settings() {
 /**
  * Checks a database connection and returns any errors.
  */
-function install_database_errors($database, $settings_file) {
+
+function install_database_errors($database) {
   $errors = array();
 
   // Check database type.
   $database_types = drupal_get_database_types();
   $driver = $database['driver'];
   if (!isset($database_types[$driver])) {
-    $errors['driver'] = t("In your %settings_file file you have configured @drupal to use a %driver server, however your PHP installation currently does not support this database type.", array('%settings_file' => $settings_file, '@drupal' => drupal_install_profile_distribution_name(), '%driver' => $driver));
+    $errors['driver'] = t("In your %settings_file file you have configured @drupal to use a %driver server, however your PHP installation currently does not support this database type.", array(
+      '%settings_file' => Site::getPath('settings.php'),
+      '@drupal' => drupal_install_profile_distribution_name(),
+      '%driver' => $driver,
+    ));
   }
   else {
     // Run driver specific validation
@@ -1736,8 +1747,8 @@ function install_check_translations($install_state) {
   $readable = FALSE;
   $writable = FALSE;
   // @todo: Make this configurable.
-  $files_directory = conf_path() . '/files';
-  $translations_directory = conf_path() . '/files/translations';
+  $files_directory = Site::getPath('files');
+  $translations_directory = Site::getPath('files/translations');
   $translations_directory_exists = FALSE;
   $translation_available = FALSE;
   $online = FALSE;
@@ -1913,7 +1924,7 @@ function install_check_requirements($install_state) {
     $writable = FALSE;
     $conf_path = './' . conf_path(FALSE);
     $file = $conf_path . "/{$default_file_info['file']}";
-    $default_file = "./sites/default/{$default_file_info['file_default']}";
+    $default_file = "./core/{$default_file_info['file_default']}";
     $exists = FALSE;
     // Verify that the directory exists.
     if (drupal_verify_install_file($conf_path, FILE_EXIST, 'dir')) {
diff --git a/core/includes/install.inc b/core/includes/install.inc
index d1c1596..9bb949f 100644
--- a/core/includes/install.inc
+++ b/core/includes/install.inc
@@ -11,6 +11,7 @@
 use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Extension\ExtensionDiscovery;
 use Drupal\Core\Site\Settings;
+use Drupal\Core\Site\Site;
 
 /**
  * Requirement severity -- Informational message only.
@@ -195,7 +196,7 @@ function drupal_get_database_types() {
  */
 function drupal_rewrite_settings($settings = array(), $settings_file = NULL) {
   if (!isset($settings_file)) {
-    $settings_file = conf_path(FALSE) . '/settings.php';
+    $settings_file = Site::getPath('settings.php');
   }
   // Build list of setting names and insert the values into the global namespace.
   $variable_names = array();
@@ -468,11 +469,11 @@ function drupal_install_config_directories() {
     $config_directories_hash = Crypt::randomBytesBase64(55);
     $settings['config_directories'] = array(
       CONFIG_ACTIVE_DIRECTORY => (object) array(
-        'value' => conf_path() . '/files/config_' . $config_directories_hash . '/active',
+        'value' => Site::getPath('files/config_' . $config_directories_hash . '/active'),
         'required' => TRUE,
       ),
       CONFIG_STAGING_DIRECTORY => (object) array(
-        'value' => conf_path() . '/files/config_' . $config_directories_hash . '/staging',
+        'value' => Site::getPath('files/config_' . $config_directories_hash . '/staging'),
         'required' => TRUE,
       ),
     );
@@ -680,6 +681,9 @@ function drupal_install_system($install_state) {
  *
  * @return
  *   TRUE on success or FALSE on failure. A message is set for the latter.
+ *
+ * @todo Do not automatically call into drupal_install_fix_file().
+ * @see https://drupal.org/node/1616266
  */
 function drupal_verify_install_file($file, $mask = NULL, $type = 'file') {
   $return = TRUE;
diff --git a/core/includes/update.inc b/core/includes/update.inc
index 945ffe7..abe75ee 100644
--- a/core/includes/update.inc
+++ b/core/includes/update.inc
@@ -14,6 +14,7 @@
 use Drupal\Core\Config\ConfigException;
 use Drupal\Core\DrupalKernel;
 use Drupal\Core\Page\DefaultHtmlPageRenderer;
+use Drupal\Core\Site\Site;
 use Drupal\Core\Utility\Error;
 use Drupal\Component\Uuid\Uuid;
 use Drupal\Component\Utility\NestedArray;
@@ -82,7 +83,7 @@ function update_settings_file_requirements() {
   $requirements = array();
 
   // Check whether settings.php needs to be rewritten.
-  $settings_file = conf_path() . '/settings.php';
+  $settings_file = Site::getPath('settings.php');
   $writable = drupal_verify_install_file($settings_file, FILE_EXIST | FILE_READABLE | FILE_WRITABLE);
   $requirements['settings file']['title'] = 'Settings file';
   if ($writable) {
diff --git a/core/lib/Drupal/Core/Database/Driver/sqlite/Install/Tasks.php b/core/lib/Drupal/Core/Database/Driver/sqlite/Install/Tasks.php
index 97eab54..995f0e6 100644
--- a/core/lib/Drupal/Core/Database/Driver/sqlite/Install/Tasks.php
+++ b/core/lib/Drupal/Core/Database/Driver/sqlite/Install/Tasks.php
@@ -11,6 +11,7 @@
 use Drupal\Core\Database\Driver\sqlite\Connection;
 use Drupal\Core\Database\DatabaseNotFoundException;
 use Drupal\Core\Database\Install\Tasks as InstallTasks;
+use Drupal\Core\Site\Site;
 
 /**
  * Specifies installation tasks for SQLite databases.
@@ -49,7 +50,7 @@ public function getFormOptions(array $database) {
     // Make the text more accurate for SQLite.
     $form['database']['#title'] = t('Database file');
     $form['database']['#description'] = t('The absolute path to the file where @drupal data will be stored. This must be writable by the web server and should exist outside of the web root.', array('@drupal' => drupal_install_profile_distribution_name()));
-    $default_database = conf_path(FALSE) . '/files/.ht.sqlite';
+    $default_database = Site::getPath('files/.ht.sqlite');
     $form['database']['#default_value'] = empty($database['database']) ? $default_database : $database['database'];
     return $form;
   }
diff --git a/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
index f51cbb3..43b31ca 100644
--- a/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
+++ b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Extension\Discovery\RecursiveExtensionFilterIterator;
 use Drupal\Core\Site\Settings;
+use Drupal\Core\Site\Site;
 
 /**
  * Discovers available extensions in the filesystem.
@@ -135,8 +136,10 @@ public function scan($type, $include_tests = NULL) {
       $searchdirs[static::ORIGIN_PARENT_SITE] = $parent_site;
     }
 
-    // Search the site-specific directory.
-    $searchdirs[static::ORIGIN_SITE] = conf_path();
+    // Search the site-specific directory, unless it is the same as ORIGIN_ROOT.
+    if ('' !== $site_path = Site::getPath()) {
+      $searchdirs[static::ORIGIN_SITE] = $site_path;
+    }
 
     // Unless an explicit value has been passed, manually check whether we are
     // in a test environment, in which case test extensions must be included.
diff --git a/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php b/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php
index c8fdd19..adbcec4 100644
--- a/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php
+++ b/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php
@@ -11,6 +11,7 @@
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Locale\CountryManagerInterface;
+use Drupal\Core\Site\Site;
 use Drupal\Core\State\StateInterface;
 use Drupal\user\UserStorageInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -93,8 +94,6 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     $form['#title'] = $this->t('Configure site');
 
     // Warn about settings.php permissions risk
-    $settings_dir = conf_path();
-    $settings_file = $settings_dir . '/settings.php';
     // Check that $_POST is empty so we only show this message when the form is
     // first displayed, not on the next page after it is submitted. (We do not
     // want to repeat it multiple times because it is a general warning that is
@@ -103,8 +102,12 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     // distract from the message that the Drupal installation has completed
     // successfully.)
     $post_params = $this->getRequest()->request->all();
-    if (empty($post_params) && (!drupal_verify_install_file(DRUPAL_ROOT . '/' . $settings_file, FILE_EXIST|FILE_READABLE|FILE_NOT_WRITABLE) || !drupal_verify_install_file(DRUPAL_ROOT . '/' . $settings_dir, FILE_NOT_WRITABLE, 'dir'))) {
-      drupal_set_message(t('All necessary changes to %dir and %file have been made, so you should remove write permissions to them now in order to avoid security risks. If you are unsure how to do so, consult the <a href="@handbook_url">online handbook</a>.', array('%dir' => $settings_dir, '%file' => $settings_file, '@handbook_url' => 'http://drupal.org/server-permissions')), 'warning');
+    if (empty($post_params) && (!drupal_verify_install_file(Site::getAbsolutePath('settings.php'), FILE_EXIST|FILE_READABLE|FILE_NOT_WRITABLE) || is_writable(Site::getAbsolutePath()))) {
+      drupal_set_message(t('All necessary changes to %dir and %file have been made, so you should remove write permissions to them now in order to avoid security risks. If you are unsure how to do so, consult the <a href="@handbook_url">online handbook</a>.', array(
+        '%dir' => Site::getPath() ?: Site::getAbsolutePath(),
+        '%file' => Site::getPath('settings.php'),
+        '@handbook_url' => 'http://drupal.org/server-permissions',
+      )), 'warning');
     }
 
     $form['#attached']['library'][] = 'system/drupal.system';
diff --git a/core/lib/Drupal/Core/Installer/Form/SiteSettingsForm.php b/core/lib/Drupal/Core/Installer/Form/SiteSettingsForm.php
index 48fadf6..803480e 100644
--- a/core/lib/Drupal/Core/Installer/Form/SiteSettingsForm.php
+++ b/core/lib/Drupal/Core/Installer/Form/SiteSettingsForm.php
@@ -28,9 +28,6 @@ public function getFormId() {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
-    $conf_path = './' . conf_path(FALSE);
-    $settings_file = $conf_path . '/settings.php';
-
     $form['#title'] = $this->t('Database configuration');
 
     $drivers = drupal_get_database_types();
@@ -108,7 +105,6 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     );
 
     $form['errors'] = array();
-    $form['settings_file'] = array('#type' => 'value', '#value' => $settings_file);
 
     return $form;
   }
@@ -127,7 +123,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
     $database['driver'] = $driver;
 
     $form_state['storage']['database'] = $database;
-    $errors = install_database_errors($database, $form_state->getValue('settings_file'));
+    $errors = install_database_errors($database);
     foreach ($errors as $name => $message) {
       $form_state->setErrorByName($name, $message);
     }
diff --git a/core/lib/Drupal/Core/Site/Settings.php b/core/lib/Drupal/Core/Site/Settings.php
index e2d57d2..c1cf191 100644
--- a/core/lib/Drupal/Core/Site/Settings.php
+++ b/core/lib/Drupal/Core/Site/Settings.php
@@ -95,9 +95,24 @@ public static function initialize($site_path) {
     $config = array();
     $databases = array();
 
-    // Make conf_path() available as local variable in settings.php.
-    if (is_readable(DRUPAL_ROOT . '/' . $site_path . '/settings.php')) {
-      require DRUPAL_ROOT . '/' . $site_path . '/settings.php';
+    // Read the global /settings/settings.php file.
+    // Allow it to set/override the following variables:
+    $sites = NULL;
+    $conf_path = NULL;
+    // Exclude it for test requests to prevent settings of the test runner from
+    // leaking into the test environment.
+    if (!drupal_valid_test_ua() && is_readable(DRUPAL_ROOT . '/settings/settings.php')) {
+      require DRUPAL_ROOT . '/settings/settings.php';
+    }
+
+    // Discover the site directory.
+    Site::init(DRUPAL_ROOT, $sites, $conf_path);
+
+    // Read settings.php of the actual site, unless it is the root/default site.
+    // Concatenation is safe here, since $conf_path is known to be not empty.
+    $conf_path = Site::getPath();
+    if ($conf_path !== '' && is_readable(DRUPAL_ROOT . '/' . $conf_path . '/settings.php')) {
+      require DRUPAL_ROOT . '/' . $conf_path . '/settings.php';
     }
 
     // Initialize Database.
diff --git a/core/lib/Drupal/Core/Site/Site.php b/core/lib/Drupal/Core/Site/Site.php
new file mode 100644
index 0000000..916abd9
--- /dev/null
+++ b/core/lib/Drupal/Core/Site/Site.php
@@ -0,0 +1,378 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Site\Site.
+ */
+
+namespace Drupal\Core\Site;
+
+/**
+ * A utility class for easy access to the site path.
+ */
+class Site {
+
+  /**
+   * The absolute path to the Drupal root directory.
+   *
+   * @var string
+   */
+  private $root;
+
+  /**
+   * The relative path to the site directory.
+   *
+   * May be an empty string, in case the site directory is the root directory.
+   *
+   * @var string
+   */
+  private $path;
+
+  /**
+   * Whether the Site singleton was instantiated by the installer.
+   *
+   * @var bool
+   */
+  private $isInstaller = FALSE;
+
+  /**
+   * The original Site instance of the test runner during test execution.
+   *
+   * @see \Drupal\Core\Site\Site::setUpTest()
+   * @see \Drupal\Core\Site\Site::tearDownTest()
+   *
+   * @var \Drupal\Core\Site\Site
+   */
+  private static $original;
+
+  /**
+   * The Site singleton instance.
+   *
+   * @var \Drupal\Core\Site\Site
+   */
+  private static $instance;
+
+  /**
+   * Initializes the Site singleton.
+   *
+   * @param string $root_directory
+   *   The root directory to use for absolute paths; i.e., DRUPAL_ROOT.
+   * @param array|null $sites
+   *   (optional) A multi-site mapping, as defined in settings.php. An empty
+   *   array is sufficient to enable discovery of a request-specific site
+   *   directory. If NULL and no $custom_path is passed, the root directory will
+   *   be the site directory.
+   * @param string|null $custom_path
+   *   (optional) An explicit site path to set; skipping site negotiation.
+   *   This can be defined as $conf_path in the root /settings.php file.
+   *
+   * @throws \BadMethodCallException
+   *   If the site path is initialized already.
+   *
+   * @see drupal_settings_initialize()
+   */
+  public static function init($root_directory, array $sites = NULL, $custom_path = NULL) {
+    if (isset(self::$instance)) {
+      // Only the installer environment is allowed to instantiate the Site
+      // singleton prior to drupal_settings_initialize().
+      // @see Site::initInstaller()
+      if (!self::$instance->isInstaller()) {
+        throw new \BadMethodCallException('Site path is initialized already.');
+      }
+    }
+    else {
+      new self($root_directory);
+    }
+    self::$instance->initializePath($sites, $custom_path);
+
+    // Prevent this method from being called more than once.
+    if (self::$instance->isInstaller()) {
+      self::$instance->isInstaller = FALSE;
+    }
+  }
+
+  /**
+   * Initializes the Site singleton in the early installer environment.
+   *
+   * Primes the Site singleton with an installer flag, which allows the
+   * application to be installed into a new and empty site directory, which does
+   * not contain a settings.php yet.
+   *
+   * @param string $root_directory
+   *   The root directory to use for absolute paths; i.e., DRUPAL_ROOT.
+   *
+   * @throws \BadMethodCallException
+   *   If the site path is initialized already.
+   *
+   * @see install_begin_request()
+   */
+  public static function initInstaller($root_directory) {
+    if (isset(self::$instance)) {
+      throw new \BadMethodCallException('Site path is initialized already.');
+    }
+    new self($root_directory);
+    // Denote that we are operating in the special installer environment.
+    self::$instance->isInstaller = TRUE;
+  }
+
+  /**
+   * Constructs the Site singleton.
+   *
+   * @throws \BadMethodCallException
+   *   If the site path is initialized already.
+   */
+  private function __construct($root_directory) {
+    if (isset(self::$instance)) {
+      throw new \BadMethodCallException('Site path is initialized already.');
+    }
+    $this->root = $root_directory;
+    self::$instance = $this;
+  }
+
+  /**
+   * Re-initializes (resets) the Site singleton for a test run.
+   *
+   * @throws \RuntimeException
+   *   If the site path of the test runner is not initialized yet.
+   *
+   * @throws \BadMethodCallException
+   *   If no test is executed currently.
+   *
+   * @see \Drupal\simpletest\TestBase::prepareEnvironment()
+   */
+  public static function setUpTest() {
+    if (!isset(self::$instance)) {
+      throw new \RuntimeException('No original Site to backup. Missing invocation of Site::init()?');
+    }
+    if (!drupal_valid_test_ua()) {
+      throw new \BadMethodCallException('Site is not executing a test.');
+    }
+    self::$original = clone self::$instance;
+    self::$instance = NULL;
+  }
+
+  /**
+   * Reverts the Site singleton to the original after a test run.
+   *
+   * @throws \RuntimeException
+   *   If there is no test runner site path to revert to.
+   *
+   * @throws \BadMethodCallException
+   *   If a test is still being executed currently.
+   *
+   * @see \Drupal\simpletest\TestBase::restoreEnvironment()
+   */
+  public static function tearDownTest() {
+    if (!isset(self::$original)) {
+      throw new \RuntimeException('No original Site to revert to. Missing invocation of Site::setUpTest()?');
+    }
+    // Do not allow to restore original Site singleton in a test environment,
+    // unless we are testing the test environment setup and teardown itself.
+    // @see \Drupal\simpletest\Tests\BrokenSetUpTest
+    if (drupal_valid_test_ua() && !DRUPAL_TEST_IN_CHILD_SITE) {
+      throw new \BadMethodCallException('Unable to revert Site: A test is still being executed.');
+    }
+    self::$instance = clone self::$original;
+    self::$original = NULL;
+  }
+
+  /**
+   * Returns whether the Site singleton was instantiated for the installer.
+   *
+   * @return bool
+   */
+  private function isInstaller() {
+    return $this->isInstaller;
+  }
+
+  /**
+   * Initializes the site path.
+   *
+   * @param array|null $sites
+   *   (optional) A multi-site mapping, as defined in settings.php.
+   * @param string|null $custom_path
+   *   (optional) An explicit site path to set; skipping site negotiation.
+   */
+  private function initializePath(array $sites = NULL, $custom_path = NULL) {
+    // Force-override the site directory in tests.
+    if ($test_prefix = drupal_valid_test_ua()) {
+      $this->path = 'sites/simpletest/' . substr($test_prefix, 10);
+    }
+    // An explicitly defined $conf_path in /settings.php takes precedence.
+    elseif (isset($custom_path)) {
+      $this->path = $custom_path;
+    }
+    // If the multi-site functionality was enabled in /settings.php, discover
+    // the path for the current site.
+    // $sites just needs to be defined; an explicit mapping is not required.
+    elseif (isset($sites)) {
+      $this->path = $this->determinePath($sites, !$this->isInstaller());
+    }
+    // Otherwise, the Drupal root directory is the site directory.
+    else {
+      $this->path = '';
+    }
+  }
+
+  /**
+   * Finds the appropriate configuration directory for a given host and path.
+   *
+   * Finds a matching configuration directory file by stripping the server
+   * hostname from left to right and pathname from right to left.
+   *
+   * By default, the site directory must contain a 'settings.php' file. If the
+   * parameter $require_settings is set to FALSE, then a site directory without
+   * a 'settings.php' file will be valid, too. The first valid site directory
+   * found will be used and less specific options will be ignored.
+   *
+   * The $sites variable can define site directory aliases as an associative
+   * array. For 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['8080.www.drupal.org.mysite.test'] = 'example.com';
+   * @endcode
+   *
+   * @see default.settings.php
+   *
+   * @param array $sites
+   *   A multi-site alias mapping, as defined in settings.php. May be empty.
+   * @param bool $require_settings
+   *   If TRUE, only site directories containing a settings.php file will be
+   *   recognized. During installation, this is set to FALSE, so that Drupal can
+   *   detect a site directory in which to create a new settings.php file.
+   *
+   * @return string
+   *   The relative path of the site directory. May be an empty string, in case
+   *   no site-specific directory matched, in which case the root directory is
+   *   the site directory.
+   */
+  private function determinePath(array $sites, $require_settings) {
+    // The hostname and optional port number, e.g. "www.example.com" or
+    // "www.example.com:8080".
+    $http_host = $_SERVER['HTTP_HOST'];
+    // The part of the URL following the hostname, including the leading slash.
+    $script_name = $_SERVER['SCRIPT_NAME'] ?: $_SERVER['SCRIPT_FILENAME'];
+
+    $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));
+        // Check for an alias in $sites from settings.php.
+        if (isset($sites[$dir])) {
+          $dir = $sites[$dir];
+        }
+        if ($require_settings) {
+          if (file_exists($this->root . '/sites/' . $dir . '/settings.php')) {
+            return "sites/$dir";
+          }
+        }
+        elseif (file_exists($this->root . '/sites/' . $dir)) {
+          return "sites/$dir";
+        }
+      }
+    }
+    return '';
+  }
+
+  /**
+   * Prefixes a given subpathname with the site directory, if any.
+   *
+   * Site::getPath() and this helper method only exists to ensure that a given
+   * subpathname does not result in an absolute filesystem path in case of a
+   * string concatenation like the following:
+   *
+   * @code
+   * // If the sire directory path is empty (root directory), then the resulting
+   * // filesystem path would become absolute; i.e.: "/some/file"
+   * unlink($site_path . '/some/file');
+   * @endcode
+   *
+   * In case the PHP process has write access to the entire filesystem, such a
+   * file operation could succeed and potentially affect arbitrary other files
+   * and directories that happen to exist. That must not happen.
+   *
+   * @param string $subpathname
+   *   The subpathname to prefix.
+   *
+   * @return string
+   *   The prefixed subpathname.
+   *
+   * @throws \RuntimeException
+   *   If the site path is not initialized yet.
+   */
+  private function resolvePath($subpathname) {
+    // Extra safety protection in case a script somehow manages to bypass all
+    // other protections.
+    if (!isset($this->path)) {
+      throw new \RuntimeException('Site path is not initialized yet.');
+    }
+    // A faulty call to Site::getPath() might include a leading slash (/), in
+    // which case the entire site path resolution of this function would be
+    // pointless, because the resulting path would still be absolute. Therefore,
+    // guarantee that even a bogus argument is resolved correctly.
+    $subpathname = ltrim($subpathname, '/');
+
+    if ($this->path !== '') {
+      if ($subpathname !== '') {
+        return $this->path . '/' . $subpathname;
+      }
+      return $this->path;
+    }
+    return $subpathname;
+  }
+
+  /**
+   * Returns the given path relative to the site directory.
+   *
+   * Use this function instead of appending strings to the site path manually,
+   * because the site directory may be the root directory and thus a
+   * concatenated path would result in an absolute filesystem path.
+   *
+   * @param string $subpathname
+   *   (optional) A relative subpathname to append to the site path.
+   *
+   * @return string
+   *   The given $subpathname, potentially prefixed with the site path.
+   *
+   * @throws \RuntimeException
+   *   If the site path is not initialized yet.
+   *
+   * @see \Drupal\Core\Site\Site::getAbsolutePath()
+   */
+  public static function getPath($subpathname = '') {
+    return self::$instance->resolvePath($subpathname);
+  }
+
+  /**
+   * Returns the given path relative to the site directory, as an absolute path.
+   *
+   * Use this function instead of appending strings to the site path manually,
+   * because the site directory may be the root directory and thus a
+   * concatenated path would result in an absolute filesystem path.
+   *
+   * @param string $subpathname
+   *   (optional) A relative subpathname to append to the site path.
+   *
+   * @return string
+   *   The given $subpathname, potentially prefixed with the site path, as an
+   *   absolute filesystem path.
+   *
+   * @throws \RuntimeException
+   *   If the site path is not initialized yet.
+   *
+   * @see \Drupal\Core\Site\Site::getPath()
+   */
+  public static function getAbsolutePath($subpathname = '') {
+    $subpathname = self::$instance->resolvePath($subpathname);
+    if ($subpathname !== '') {
+      return self::$instance->root . '/' . $subpathname;
+    }
+    else {
+      return self::$instance->root;
+    }
+  }
+
+}
diff --git a/core/lib/Drupal/Core/StreamWrapper/PublicStream.php b/core/lib/Drupal/Core/StreamWrapper/PublicStream.php
index 637c9ef..45661a7 100644
--- a/core/lib/Drupal/Core/StreamWrapper/PublicStream.php
+++ b/core/lib/Drupal/Core/StreamWrapper/PublicStream.php
@@ -9,6 +9,7 @@
 
 use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Site\Settings;
+use Drupal\Core\Site\Site;
 
 /**
  * Defines a Drupal public (public://) stream wrapper class.
@@ -40,7 +41,7 @@ public function getExternalUrl() {
    *   The base path for public:// typically sites/default/files.
    */
   public static function basePath() {
-    $base_path = Settings::get('file_public_path', conf_path() . '/files');
+    $base_path = Settings::get('file_public_path', Site::getPath('files'));
     return $base_path;
   }
 
diff --git a/core/modules/file/tests/file_test/src/DummyReadOnlyStreamWrapper.php b/core/modules/file/tests/file_test/src/DummyReadOnlyStreamWrapper.php
index d230bc5..8617566 100644
--- a/core/modules/file/tests/file_test/src/DummyReadOnlyStreamWrapper.php
+++ b/core/modules/file/tests/file_test/src/DummyReadOnlyStreamWrapper.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\file_test;
 
+use Drupal\Core\Site\Site;
 use Drupal\Core\StreamWrapper\LocalReadOnlyStream;
 
 /**
@@ -16,7 +17,7 @@
  */
 class DummyReadOnlyStreamWrapper extends LocalReadOnlyStream {
   function getDirectoryPath() {
-    return conf_path() . '/files';
+    return Site::getPath('files');
   }
 
   /**
diff --git a/core/modules/file/tests/file_test/src/DummyStreamWrapper.php b/core/modules/file/tests/file_test/src/DummyStreamWrapper.php
index cbea40f..dd919c8 100644
--- a/core/modules/file/tests/file_test/src/DummyStreamWrapper.php
+++ b/core/modules/file/tests/file_test/src/DummyStreamWrapper.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\file_test;
 
+use Drupal\Core\Site\Site;
 use Drupal\Core\StreamWrapper\LocalStream;
 
 /**
@@ -16,7 +17,7 @@
  */
 class DummyStreamWrapper extends LocalStream {
   function getDirectoryPath() {
-    return conf_path() . '/files';
+    return Site::getPath('files');
   }
 
   /**
diff --git a/core/modules/locale/locale.install b/core/modules/locale/locale.install
index dd00412..00de29e 100644
--- a/core/modules/locale/locale.install
+++ b/core/modules/locale/locale.install
@@ -6,6 +6,7 @@
  */
 
 use Drupal\Core\Language\Language;
+use Drupal\Core\Site\Site;
 use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationSelected;
 
 /**
@@ -14,7 +15,7 @@
 function locale_install() {
   // Create the interface translations directory and ensure it's writable.
   if (!$directory = \Drupal::config('locale.settings')->get('translation.path')) {
-    $directory = conf_path() . '/files/translations';
+    $directory = Site::getPath('files/translations');
     \Drupal::config('locale.settings')->set('translation.path', $directory)->save();
   }
   file_prepare_directory($directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
diff --git a/core/modules/simpletest/src/TestBase.php b/core/modules/simpletest/src/TestBase.php
index 9819e33..6aea450 100644
--- a/core/modules/simpletest/src/TestBase.php
+++ b/core/modules/simpletest/src/TestBase.php
@@ -20,6 +20,7 @@
 use Drupal\Core\Session\AccountProxy;
 use Drupal\Core\Session\AnonymousUserSession;
 use Drupal\Core\Site\Settings;
+use Drupal\Core\Site\Site;
 use Drupal\Core\StreamWrapper\PublicStream;
 use Drupal\Core\Utility\Error;
 use Symfony\Component\HttpFoundation\Request;
@@ -1002,7 +1003,7 @@ private function prepareEnvironment() {
     }
 
     // Backup current in-memory configuration.
-    $this->originalSite = conf_path();
+    $this->originalSite = Site::getPath();
     $this->originalSettings = Settings::getAll();
     $this->originalConfig = $GLOBALS['config'];
     // @todo Remove all remnants of $GLOBALS['conf'].
@@ -1017,7 +1018,7 @@ private function prepareEnvironment() {
     // Save further contextual information.
     // Use the original files directory to avoid nesting it within an existing
     // simpletest directory if a test is executed within a test.
-    $this->originalFileDirectory = Settings::get('file_public_path', conf_path() . '/files');
+    $this->originalFileDirectory = Settings::get('file_public_path', Site::getPath('files'));
     $this->originalProfile = drupal_get_profile();
     $this->originalUser = isset($user) ? clone $user : NULL;
 
@@ -1090,8 +1091,11 @@ private function prepareEnvironment() {
 
     // After preparing the environment and changing the database prefix, we are
     // in a valid test environment.
+    if (!is_dir(DRUPAL_ROOT . '/' . $this->siteDirectory)) {
+      throw new \RuntimeException("Test site directory '$this->siteDirectory' does not exist.");
+    }
     drupal_valid_test_ua($this->databasePrefix);
-    conf_path(FALSE, TRUE);
+    Site::setUpTest();
 
     // Reset settings.
     new Settings(array(
@@ -1195,7 +1199,7 @@ private function restoreEnvironment() {
     else {
       drupal_valid_test_ua(FALSE);
     }
-    conf_path(TRUE, TRUE);
+    Site::tearDownTest();
 
     // Restore stream wrappers of the test runner.
     file_get_stream_wrappers();
diff --git a/core/modules/simpletest/src/UnitTestBase.php b/core/modules/simpletest/src/UnitTestBase.php
index 9d93fa0..325e87b 100644
--- a/core/modules/simpletest/src/UnitTestBase.php
+++ b/core/modules/simpletest/src/UnitTestBase.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Database\Database;
 use Drupal\Core\Database\ConnectionNotDefinedException;
+use Drupal\Core\Site\Site;
 
 /**
  * Base test case class for unit tests.
@@ -37,6 +38,9 @@ function __construct($test_id = NULL) {
    * setUp() method.
    */
   protected function setUp() {
+    // Initialize the test Site singleton, so that Site::getPath() works.
+    Site::init(DRUPAL_ROOT);
+
     file_prepare_directory($this->public_files_directory, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
     $this->settingsSet('file_public_path', $this->public_files_directory);
   }
diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php
index 05467d2..3ff49e3 100644
--- a/core/modules/simpletest/src/WebTestBase.php
+++ b/core/modules/simpletest/src/WebTestBase.php
@@ -11,6 +11,7 @@
 use Drupal\Component\Serialization\Yaml;
 use Drupal\Component\Utility\Crypt;
 use Drupal\Component\Utility\NestedArray;
+use Drupal\Component\Utility\Settings;
 use Drupal\Component\Utility\String;
 use Drupal\Core\DependencyInjection\YamlFileLoader;
 use Drupal\Core\DrupalKernel;
@@ -813,8 +814,9 @@ protected function setUp() {
     // installation.
     // Not using File API; a potential error must trigger a PHP warning.
     $directory = DRUPAL_ROOT . '/' . $this->siteDirectory;
-    copy(DRUPAL_ROOT . '/sites/default/default.settings.php', $directory . '/settings.php');
-    copy(DRUPAL_ROOT . '/sites/default/default.services.yml', $directory . '/services.yml');
+    copy(DRUPAL_ROOT . '/core/default.settings.php', $directory . '/settings.php');
+    copy(DRUPAL_ROOT . '/core/default.services.yml', $directory . '/services.yml');
+
 
     // All file system paths are created by System module during installation.
     // @see system_requirements()
@@ -833,10 +835,13 @@ protected function setUp() {
     );
     // Add the parent profile's search path to the child site's search paths.
     // @see \Drupal\Core\Extension\ExtensionDiscovery::getProfileDirectories()
-    $settings['conf']['simpletest.settings']['parent_profile'] = (object) array(
+    $settings['config']['simpletest.settings']['parent_profile'] = (object) array(
       'value' => $this->originalProfile,
       'required' => TRUE,
     );
+    // Write a new settings.php for the test site environment.
+    // drupal_rewrite_settings() will reload Settings and update
+    // $GLOBALS['config'] accordingly.
     $this->writeSettings($settings);
     // Allow for test-specific overrides.
     $settings_testing_file = DRUPAL_ROOT . '/' . $this->originalSite . '/settings.testing.php';
@@ -874,7 +879,8 @@ protected function setUp() {
     // directory has to be writable.
     // TestBase::restoreEnvironment() will delete the entire site directory.
     // Not using File API; a potential error must trigger a PHP warning.
-    chmod($directory, 0777);
+    chmod(DRUPAL_ROOT . '/' . $this->siteDirectory, 0777);
+    chmod(DRUPAL_ROOT . '/' . $this->siteDirectory . '/settings.php', 0666);
 
     $request = \Drupal::request();
     $this->kernel = DrupalKernel::createFromRequest($request, drupal_classloader(), 'prod', TRUE);
diff --git a/core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest.php b/core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest.php
index a36adae..59820f9 100644
--- a/core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest.php
+++ b/core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\DrupalKernel;
 use Drupal\Core\Site\Settings;
+use Drupal\Core\Site\Site;
 use Drupal\simpletest\DrupalUnitTestBase;
 use Symfony\Component\HttpFoundation\Request;
 
@@ -25,6 +26,9 @@ class DrupalKernelTest extends DrupalUnitTestBase {
   protected $classloader;
 
   protected function setUp() {
+    // Initialize the test Site singleton, so that Site::getPath() works.
+    Site::init(DRUPAL_ROOT);
+
     // DrupalKernel relies on global $config_directories and requires those
     // directories to exist. Therefore, create the directories, but do not
     // invoke KernelTestBase::setUp(), since that would set up further
diff --git a/core/modules/system/src/Tests/File/DirectoryTest.php b/core/modules/system/src/Tests/File/DirectoryTest.php
index 158be71..ae36102 100644
--- a/core/modules/system/src/Tests/File/DirectoryTest.php
+++ b/core/modules/system/src/Tests/File/DirectoryTest.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\system\Tests\File;
 
+use Drupal\Core\Site\Site;
+
 /**
  * Tests operations dealing with directories.
  *
@@ -17,7 +19,7 @@ class DirectoryTest extends FileTestBase {
    * Test local directory handling functions.
    */
   function testFileCheckLocalDirectoryHandling() {
-    $directory = conf_path() . '/files';
+    $directory = Site::getPath('files');
 
     // Check a new recursively created local directory for correct file system
     // permissions.
diff --git a/core/modules/system/src/Tests/File/ReadOnlyStreamWrapperTest.php b/core/modules/system/src/Tests/File/ReadOnlyStreamWrapperTest.php
index c9cb68b..958dc3c 100644
--- a/core/modules/system/src/Tests/File/ReadOnlyStreamWrapperTest.php
+++ b/core/modules/system/src/Tests/File/ReadOnlyStreamWrapperTest.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\system\Tests\File;
 
+use Drupal\Core\Site\Site;
+
 /**
  * Tests the read-only stream wrapper write functions.
  *
@@ -34,7 +36,7 @@ class ReadOnlyStreamWrapperTest extends FileTestBase {
   function testWriteFunctions() {
     // Generate a test file
     $filename = $this->randomMachineName();
-    $filepath = conf_path() . '/files/' . $filename;
+    $filepath = Site::getPath('files/' . $filename);
     file_put_contents($filepath, $filename);
 
     // Generate a read-only stream wrapper instance
@@ -77,7 +79,9 @@ function testWriteFunctions() {
 
     // Test the mkdir() function by attempting to create a directory.
     $dirname = $this->randomMachineName();
-    $dir = conf_path() . '/files/' . $dirname;
+    $dir = Site::getPath('files/' . $dirname);
+    $dirname = $this->randomName();
+    $dir = Site::getPath('files/' . $dirname);
     $readonlydir = $this->scheme . '://' . $dirname;
     $this->assertFalse(@drupal_mkdir($readonlydir, 0775, 0), 'Unable to create directory with read-only stream wrapper.');
     // Create a temporary directory for testing purposes
diff --git a/core/modules/system/src/Tests/System/SettingsRewriteTest.php b/core/modules/system/src/Tests/System/SettingsRewriteTest.php
index 741f92c..e9aca16 100644
--- a/core/modules/system/src/Tests/System/SettingsRewriteTest.php
+++ b/core/modules/system/src/Tests/System/SettingsRewriteTest.php
@@ -7,8 +7,10 @@
 
 namespace Drupal\system\Tests\System;
 
+<<<<<<< HEAD:core/modules/system/src/Tests/System/SettingsRewriteTest.php
 use Drupal\Core\Site\Settings;
 use Drupal\simpletest\KernelTestBase;
+use Drupal\Core\Site\Site;
 
 /**
  * Tests the drupal_rewrite_settings() function.
@@ -99,7 +101,7 @@ function testDrupalRewriteSettings() {
       ),
     );
     foreach ($tests as $test) {
-      $filename = Settings::get('file_public_path', conf_path() . '/files') . '/mock_settings.php';
+      $filename = Settings::get('file_public_path', Site::getPath('files')) . '/mock_settings.php';
       file_put_contents(DRUPAL_ROOT . '/' . $filename, "<?php\n" . $test['original'] . "\n");
       drupal_rewrite_settings($test['settings'], $filename);
       $this->assertEqual(file_get_contents(DRUPAL_ROOT . '/' . $filename), "<?php\n" . $test['expected'] . "\n");
@@ -117,7 +119,7 @@ function testDrupalRewriteSettings() {
       'expected' => '$no_index = true;'
     );
     // Make an empty file.
-    $filename = Settings::get('file_public_path', conf_path() . '/files') . '/mock_settings.php';
+    $filename = Settings::get('file_public_path', Site::getPath('files')) . '/mock_settings.php';
     file_put_contents(DRUPAL_ROOT . '/' . $filename, "");
 
     // Write the setting to the file.
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 8e7b534..680f19c 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -11,6 +11,7 @@
 use Drupal\Core\Database\Database;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Site\Settings;
+use Drupal\Core\Site\Site;
 use Drupal\Core\StreamWrapper\PublicStream;
 
 /**
@@ -215,14 +216,18 @@ function system_requirements($phase) {
   // Test configuration files and directory for writability.
   if ($phase == 'runtime') {
     $conf_errors = array();
-    $conf_path = conf_path();
-    if (!drupal_verify_install_file($conf_path, FILE_NOT_WRITABLE, 'dir')) {
-      $conf_errors[] = t("The directory %file is not protected from modifications and poses a security risk. You must change the directory's permissions to be non-writable.", array('%file' => $conf_path));
+    if (is_writable(Site::getAbsolutePath())) {
+      $conf_errors[] = t("The directory %file is not protected from modifications and poses a security risk. You must change the directory's permissions to be non-writable.", array(
+        '%file' => Site::getPath() ?: Site::getAbsolutePath(),
+      ));
     }
+<<<<<<< HEAD
     foreach (array('settings.php', 'settings.local.php', 'services.yml') as $conf_file) {
-      $full_path = $conf_path . '/' . $conf_file;
+      $full_path = Site::getAbsolutePath($conf_file);
       if (file_exists($full_path) && !drupal_verify_install_file($full_path, FILE_EXIST|FILE_READABLE|FILE_NOT_WRITABLE)) {
-        $conf_errors[] = t("The file %file is not protected from modifications and poses a security risk. You must change the file's permissions to be non-writable.", array('%file' => $full_path));
+        $conf_errors[] = t("The file %file is not protected from modifications and poses a security risk. You must change the file's permissions to be non-writable.", array(
+          '%file' => Site::getPath($conf_file),
+        ));
       }
     }
     if (!empty($conf_errors)) {
@@ -350,7 +355,7 @@ function system_requirements($phase) {
     else {
       // If we are installing Drupal, the settings.php file might not exist yet
       // in the intended site directory, so don't require it.
-      $directories[] = conf_path(FALSE) . '/files';
+      $directories[] = Site::getPath('files');
     }
     if (!empty($GLOBALS['config']['system.file']['path']['private'])) {
       $directories[] = $GLOBALS['config']['system.file']['path']['private'];
@@ -376,7 +381,7 @@ function system_requirements($phase) {
     $requirements['config directories'] = array(
       'title' => t('Configuration directories'),
       'value' => t('Not present'),
-      'description' => t('Your %file file must define the $config_directories variable as an array containing the name of a directories in which configuration files can be written.', array('%file' => conf_path() . '/settings.php')),
+      'description' => t('Your %file file must define the $config_directories variable as an array containing the name of a directories in which configuration files can be written.', array('%file' => Site::getPath('settings.php'))),
       'severity' => REQUIREMENT_ERROR,
     );
   }
diff --git a/core/modules/update/update.manager.inc b/core/modules/update/update.manager.inc
index 1faf7fd..c2e921f 100644
--- a/core/modules/update/update.manager.inc
+++ b/core/modules/update/update.manager.inc
@@ -36,6 +36,7 @@
  * root.
  */
 
+use Drupal\Core\Site\Site;
 use Symfony\Component\HttpFoundation\RedirectResponse;
 
 /**
@@ -304,7 +305,7 @@ function update_manager_local_transfers_allowed() {
   // the configuration directory to determine if local transfers will be
   // allowed.
   $temporary_file = drupal_tempnam('temporary://', 'update_');
-  $local_transfers_allowed = fileowner($temporary_file) === fileowner(conf_path());
+  $local_transfers_allowed = fileowner($temporary_file) === fileowner(Site::getAbsolutePath());
 
   // Clean up. If this fails, we can ignore it (since this is just a temporary
   // file anyway).
diff --git a/sites/default/default.services.yml b/sites/default/default.services.yml
index 280eb43..792d600 100644
--- a/sites/default/default.services.yml
+++ b/sites/default/default.services.yml
@@ -1,53 +1 @@
-parameters:
-  twig.config:
-    # Twig debugging:
-    #
-    # When debugging is enabled:
-    # - The markup of each Twig template is surrounded by HTML comments that
-    #   contain theming information, such as template file name suggestions.
-    # - Note that this debugging markup will cause automated tests that directly
-    #  check rendered HTML to fail. When running automated tests, 'twig_debug'
-    #   should be set to FALSE.
-    # - The dump() function can be used in Twig templates to output information
-    #   about template variables.
-    # - Twig templates are automatically recompiled whenever the source code
-    #  changes (see twig_auto_reload below).
-    #
-    # For more information about debugging Twig templates, see
-    # http://drupal.org/node/1906392.
-    #
-    # Not recommended in production environments
-    # @default false
-    debug: false
-    # Twig auto-reload:
-    #
-    # Automatically recompile Twig templates whenever the source code changes.
-    # If you don't provide a value for twig_auto_reload, it will be determined
-    # based on the value of twig_debug.
-    #
-    #  Not recommended in production environments
-    # @default null
-    auto_reload: null
-    # Twig cache:
-    #
-    # By default, Twig templates will be compiled and stored in the filesystem
-    # to increase performance. Disabling the Twig cache will recompile the
-    # templates from source each time they are used. In most cases the
-    # twig_auto_reload setting above should be enabled rather than disabling the
-    # Twig cache.
-    #
-    # Not recommended in production environments
-    # @default true
-    cache: true
-  factory.keyvalue:
-    {}
-    # Default key/value storage service to use.
-    # @default keyvalue.database
-    #default: keyvalue.database
-    # Collection-specific overrides.
-    #state: keyvalue.database
-  factory.keyvalue.expirable:
-    {}
-    # Default key/value expirable storage service to use.
-    # @default keyvalue.database.expirable
-    #default: keyvalue.database.expirable
+#
diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php
index 017fe8a..b3d9bbc 100644
--- a/sites/default/default.settings.php
+++ b/sites/default/default.settings.php
@@ -1,635 +1 @@
 <?php
-
-/**
- * @file
- * Drupal site-specific configuration file.
- *
- * IMPORTANT NOTE:
- * This file may have been set to read-only by the Drupal installation program.
- * If you make changes to this file, be sure to protect it again after making
- * your modifications. Failure to remove write permissions to this file is a
- * security risk.
- *
- * In order to use the selection rules below the multisite aliasing file named
- * sites/sites.php must be present. Its optional settings will be loaded, and
- * the aliases in the array $sites will override the default directory rules
- * below. See sites/example.sites.php for more information about aliases.
- *
- * The configuration directory will be discovered by stripping the website's
- * hostname from left to right and pathname from right to left. The first
- * configuration file found will be used and any others will be ignored. If no
- * other configuration file is found then the default configuration file at
- * 'sites/default' will be used.
- *
- * For example, for a fictitious site installed at
- * http://www.drupal.org:8080/mysite/test/, the 'settings.php' file is searched
- * for in the following directories:
- *
- * - sites/8080.www.drupal.org.mysite.test
- * - sites/www.drupal.org.mysite.test
- * - sites/drupal.org.mysite.test
- * - sites/org.mysite.test
- *
- * - sites/8080.www.drupal.org.mysite
- * - sites/www.drupal.org.mysite
- * - sites/drupal.org.mysite
- * - sites/org.mysite
- *
- * - sites/8080.www.drupal.org
- * - sites/www.drupal.org
- * - sites/drupal.org
- * - sites/org
- *
- * - sites/default
- *
- * Note that if you are installing on a non-standard port number, prefix the
- * hostname with that number. For example,
- * http://www.drupal.org:8080/mysite/test/ could be loaded from
- * sites/8080.www.drupal.org.mysite.test/.
- *
- * @see example.sites.php
- * @see conf_path()
- *
- * In addition to customizing application settings through variables in
- * settings.php, you can create a services.yml file in the same directory to
- * register custom, site-specific service definitions and/or swap out default
- * implementations with custom ones.
- */
-
-/**
- * Database settings:
- *
- * The $databases array specifies the database connection or
- * connections that Drupal may use.  Drupal is able to connect
- * to multiple databases, including multiple types of databases,
- * during the same request.
- *
- * Each database connection is specified as an array of settings,
- * similar to the following:
- * @code
- * array(
- *   'driver' => 'mysql',
- *   'database' => 'databasename',
- *   'username' => 'username',
- *   'password' => 'password',
- *   'host' => 'localhost',
- *   'port' => 3306,
- *   'prefix' => 'myprefix_',
- *   'collation' => 'utf8_general_ci',
- * );
- * @endcode
- *
- * The "driver" property indicates what Drupal database driver the
- * connection should use.  This is usually the same as the name of the
- * database type, such as mysql or sqlite, but not always.  The other
- * properties will vary depending on the driver.  For SQLite, you must
- * specify a database file name in a directory that is writable by the
- * webserver.  For most other drivers, you must specify a
- * username, password, host, and database name.
- *
- * Transaction support is enabled by default for all drivers that support it,
- * including MySQL. To explicitly disable it, set the 'transactions' key to
- * FALSE.
- * Note that some configurations of MySQL, such as the MyISAM engine, don't
- * support it and will proceed silently even if enabled. If you experience
- * transaction related crashes with such configuration, set the 'transactions'
- * key to FALSE.
- *
- * For each database, you may optionally specify multiple "target" databases.
- * A target database allows Drupal to try to send certain queries to a
- * different database if it can but fall back to the default connection if not.
- * That is useful for primary/replica replication, as Drupal may try to connect
- * to a replica server when appropriate and if one is not available will simply
- * fall back to the single primary server (The terms primary/replica are
- * traditionally referred to as master/slave in database server documentation).
- *
- * The general format for the $databases array is as follows:
- * @code
- * $databases['default']['default'] = $info_array;
- * $databases['default']['replica'][] = $info_array;
- * $databases['default']['replica'][] = $info_array;
- * $databases['extra']['default'] = $info_array;
- * @endcode
- *
- * In the above example, $info_array is an array of settings described above.
- * The first line sets a "default" database that has one primary database
- * (the second level default).  The second and third lines create an array
- * of potential replica databases.  Drupal will select one at random for a given
- * request as needed.  The fourth line creates a new database with a name of
- * "extra".
- *
- * For a single database configuration, the following is sufficient:
- * @code
- * $databases['default']['default'] = array(
- *   'driver' => 'mysql',
- *   'database' => 'databasename',
- *   'username' => 'username',
- *   'password' => 'password',
- *   'host' => 'localhost',
- *   'prefix' => 'main_',
- *   'collation' => 'utf8_general_ci',
- * );
- * @endcode
- *
- * You can optionally set prefixes for some or all database table names
- * by using the 'prefix' setting. If a prefix is specified, the table
- * name will be prepended with its value. Be sure to use valid database
- * characters only, usually alphanumeric and underscore. If no prefixes
- * are desired, leave it as an empty string ''.
- *
- * To have all database names prefixed, set 'prefix' as a string:
- * @code
- *   'prefix' => 'main_',
- * @endcode
- * To provide prefixes for specific tables, set 'prefix' as an array.
- * The array's keys are the table names and the values are the prefixes.
- * The 'default' element is mandatory and holds the prefix for any tables
- * not specified elsewhere in the array. Example:
- * @code
- *   'prefix' => array(
- *     'default'   => 'main_',
- *     'users'     => 'shared_',
- *     'sessions'  => 'shared_',
- *     'role'      => 'shared_',
- *     'authmap'   => 'shared_',
- *   ),
- * @endcode
- * You can also use a reference to a schema/database as a prefix. This may be
- * useful if your Drupal installation exists in a schema that is not the default
- * or you want to access several databases from the same code base at the same
- * time.
- * Example:
- * @code
- *   'prefix' => array(
- *     'default'   => 'main.',
- *     'users'     => 'shared.',
- *     'sessions'  => 'shared.',
- *     'role'      => 'shared.',
- *     'authmap'   => 'shared.',
- *   );
- * @endcode
- * NOTE: MySQL and SQLite's definition of a schema is a database.
- *
- * Advanced users can add or override initial commands to execute when
- * connecting to the database server, as well as PDO connection settings. For
- * example, to enable MySQL SELECT queries to exceed the max_join_size system
- * variable, and to reduce the database connection timeout to 5 seconds:
- *
- * @code
- * $databases['default']['default'] = array(
- *   'init_commands' => array(
- *     'big_selects' => 'SET SQL_BIG_SELECTS=1',
- *   ),
- *   'pdo' => array(
- *     PDO::ATTR_TIMEOUT => 5,
- *   ),
- * );
- * @endcode
- *
- * WARNING: These defaults are designed for database portability. Changing them
- * may cause unexpected behavior, including potential data loss.
- *
- * @see DatabaseConnection_mysql::__construct
- * @see DatabaseConnection_pgsql::__construct
- * @see DatabaseConnection_sqlite::__construct
- *
- * Database configuration format:
- * @code
- *   $databases['default']['default'] = array(
- *     'driver' => 'mysql',
- *     'database' => 'databasename',
- *     'username' => 'username',
- *     'password' => 'password',
- *     'host' => 'localhost',
- *     'prefix' => '',
- *   );
- *   $databases['default']['default'] = array(
- *     'driver' => 'pgsql',
- *     'database' => 'databasename',
- *     'username' => 'username',
- *     'password' => 'password',
- *     'host' => 'localhost',
- *     'prefix' => '',
- *   );
- *   $databases['default']['default'] = array(
- *     'driver' => 'sqlite',
- *     'database' => '/path/to/databasefilename',
- *   );
- * @endcode
- */
-$databases = array();
-
-/**
- * Location of the site configuration files.
- *
- * The $config_directories array specifies the location of file system
- * directories used for configuration data. On install, "active" and "staging"
- * directories are created for configuration. The staging directory is used for
- * configuration imports; the active directory is not used by default, since the
- * default storage for active configuration is the database rather than the file
- * system (this can be changed; see "Active configuration settings" below).
- *
- * The default location for the active and staging directories is inside a
- * randomly-named directory in the public files path; this setting allows you to
- * override these locations. If you use files for the active configuration, you
- * can enhance security by putting the active configuration outside your
- * document root.
- *
- * Example:
- * @code
- *   $config_directories = array(
- *     CONFIG_ACTIVE_DIRECTORY => '/some/directory/outside/webroot',
- *     CONFIG_STAGING_DIRECTORY => '/another/directory/outside/webroot',
- *   );
- * @endcode
- */
-$config_directories = array();
-
-/**
- * Settings:
- *
- * $settings contains environment-specific configuration, such as the files
- * directory and reverse proxy address, and temporary configuration, such as
- * turning on Twig debugging and security overrides.
- *
- * @see \Drupal\Core\Site\Settings::get()
- */
-
-/**
- * Salt for one-time login links, cancel links, form tokens, etc.
- *
- * This variable will be set to a random value by the installer. All one-time
- * login links will be invalidated if the value is changed. Note that if your
- * site is deployed on a cluster of web servers, you must ensure that this
- * variable has the same value on each server.
- *
- * For enhanced security, you may set this variable to the contents of a file
- * outside your document root; you should also ensure that this file is not
- * stored with backups of your database.
- *
- * Example:
- * @code
- *   $settings['hash_salt'] = file_get_contents('/home/example/salt.txt');
- * @endcode
- */
-$settings['hash_salt'] = '';
-
-/**
- * Access control for update.php script.
- *
- * If you are updating your Drupal installation using the update.php script but
- * are not logged in using either an account with the "Administer software
- * updates" permission or the site maintenance account (the account that was
- * created during installation), you will need to modify the access check
- * statement below. Change the FALSE to a TRUE to disable the access check.
- * After finishing the upgrade, be sure to open this file again and change the
- * TRUE back to a FALSE!
- */
-$settings['update_free_access'] = FALSE;
-
-/**
- * External access proxy settings:
- *
- * If your site must access the Internet via a web proxy then you can enter
- * the proxy settings here. Currently only basic authentication is supported
- * by using the username and password variables. The proxy_user_agent variable
- * can be set to NULL for proxies that require no User-Agent header or to a
- * non-empty string for proxies that limit requests to a specific agent. The
- * proxy_exceptions variable is an array of host names to be accessed directly,
- * not via proxy.
- */
-# $settings['proxy_server'] = '';
-# $settings['proxy_port'] = 8080;
-# $settings['proxy_username'] = '';
-# $settings['proxy_password'] = '';
-# $settings['proxy_user_agent'] = '';
-# $settings['proxy_exceptions'] = array('127.0.0.1', 'localhost');
-
-/**
- * Reverse Proxy Configuration:
- *
- * Reverse proxy servers are often used to enhance the performance
- * of heavily visited sites and may also provide other site caching,
- * security, or encryption benefits. In an environment where Drupal
- * is behind a reverse proxy, the real IP address of the client should
- * be determined such that the correct client IP address is available
- * to Drupal's logging, statistics, and access management systems. In
- * the most simple scenario, the proxy server will add an
- * X-Forwarded-For header to the request that contains the client IP
- * address. However, HTTP headers are vulnerable to spoofing, where a
- * malicious client could bypass restrictions by setting the
- * X-Forwarded-For header directly. Therefore, Drupal's proxy
- * configuration requires the IP addresses of all remote proxies to be
- * specified in $settings['reverse_proxy_addresses'] to work correctly.
- *
- * Enable this setting to get Drupal to determine the client IP from
- * the X-Forwarded-For header (or $settings['reverse_proxy_header'] if set).
- * If you are unsure about this setting, do not have a reverse proxy,
- * or Drupal operates in a shared hosting environment, this setting
- * should remain commented out.
- *
- * In order for this setting to be used you must specify every possible
- * reverse proxy IP address in $settings['reverse_proxy_addresses'].
- * If a complete list of reverse proxies is not available in your
- * environment (for example, if you use a CDN) you may set the
- * $_SERVER['REMOTE_ADDR'] variable directly in settings.php.
- * Be aware, however, that it is likely that this would allow IP
- * address spoofing unless more advanced precautions are taken.
- */
-# $settings['reverse_proxy'] = TRUE;
-
-/**
- * Specify every reverse proxy IP address in your environment.
- * This setting is required if $settings['reverse_proxy'] is TRUE.
- */
-# $settings['reverse_proxy_addresses'] = array('a.b.c.d', ...);
-
-/**
- * Set this value if your proxy server sends the client IP in a header
- * other than X-Forwarded-For.
- */
-# $settings['reverse_proxy_header'] = 'HTTP_X_CLUSTER_CLIENT_IP';
-
-/**
- * Page caching:
- *
- * By default, Drupal sends a "Vary: Cookie" HTTP header for anonymous page
- * views. This tells a HTTP proxy that it may return a page from its local
- * cache without contacting the web server, if the user sends the same Cookie
- * header as the user who originally requested the cached page. Without "Vary:
- * Cookie", authenticated users would also be served the anonymous page from
- * the cache. If the site has mostly anonymous users except a few known
- * editors/administrators, the Vary header can be omitted. This allows for
- * better caching in HTTP proxies (including reverse proxies), i.e. even if
- * clients send different cookies, they still get content served from the cache.
- * However, authenticated users should access the site directly (i.e. not use an
- * HTTP proxy, and bypass the reverse proxy if one is used) in order to avoid
- * getting cached pages from the proxy.
- */
-# $settings['omit_vary_cookie'] = TRUE;
-
-/**
- * Class Loader.
- *
- * By default, Drupal uses Composer's ClassLoader, which is best for
- * development, as it does not break when code is moved on the file
- * system. It is possible, however, to wrap the class loader with a
- * cached class loader solution for better performance, which is
- * recommended for production sites.
- *
- * Examples:
- *   $settings['class_loader'] = 'apc';
- *   $settings['class_loader'] = 'default';
- */
-# $settings['class_loader'] = 'apc';
-
-/**
- * Authorized file system operations:
- *
- * The Update Manager module included with Drupal provides a mechanism for
- * site administrators to securely install missing updates for the site
- * directly through the web user interface. On securely-configured servers,
- * the Update manager will require the administrator to provide SSH or FTP
- * credentials before allowing the installation to proceed; this allows the
- * site to update the new files as the user who owns all the Drupal files,
- * instead of as the user the webserver is running as. On servers where the
- * webserver user is itself the owner of the Drupal files, the administrator
- * will not be prompted for SSH or FTP credentials (note that these server
- * setups are common on shared hosting, but are inherently insecure).
- *
- * Some sites might wish to disable the above functionality, and only update
- * the code directly via SSH or FTP themselves. This setting completely
- * disables all functionality related to these authorized file operations.
- *
- * @see http://drupal.org/node/244924
- *
- * Remove the leading hash signs to disable.
- */
-# $settings['allow_authorize_operations'] = FALSE;
-
-/**
- * Mixed-mode sessions:
- *
- * Set to TRUE to create both secure and insecure sessions when using HTTPS.
- * Defaults to FALSE.
- */
-# $settings['mixed_mode_sessions'] = TRUE;
-
-/**
- * Default mode for for directories and files written by Drupal.
- *
- * Value should be in PHP Octal Notation, with leading zero.
- */
-# $settings['file_chmod_directory'] = 0775;
-# $settings['file_chmod_file'] = 0664;
-
-/**
- * Public file path:
- *
- * A local file system path where public files will be stored. This directory
- * must exist and be writable by Drupal. This directory must be relative to
- * the Drupal installation directory and be accessible over the web.
- */
-# $settings['file_public_path'] = 'sites/default/files';
-
-/**
- * Session write interval:
- *
- * Set the minimum interval between each session write to database.
- * For performance reasons it defaults to 180.
- */
-# $settings['session_write_interval'] = 180;
-
-/**
- * String overrides:
- *
- * To override specific strings on your site with or without enabling the Locale
- * module, add an entry to this list. This functionality allows you to change
- * a small number of your site's default English language interface strings.
- *
- * Remove the leading hash signs to enable.
- *
- * The "en" part of the variable name, is dynamic and can be any langcode of
- * any added language. (eg locale_custom_strings_de for german).
- */
-# $settings['locale_custom_strings_en'][''] = array(
-#   'forum'      => 'Discussion board',
-#   '@count min' => '@count minutes',
-# );
-
-/**
- * A custom theme for the offline page:
- *
- * This applies when the site is explicitly set to maintenance mode through the
- * administration page or when the database is inactive due to an error.
- * The template file should also be copied into the theme. It is located inside
- * 'core/modules/system/templates/maintenance-page.html.twig'.
- *
- * Note: This setting does not apply to installation and update pages.
- */
-# $settings['maintenance_theme'] = 'bartik';
-
-/**
- * Base URL (optional).
- *
- * If Drupal is generating incorrect URLs on your site, which could
- * be in HTML headers (links to CSS and JS files) or visible links on pages
- * (such as in menus), uncomment the Base URL statement below (remove the
- * leading hash sign) and fill in the absolute URL to your Drupal installation.
- *
- * You might also want to force users to use a given domain.
- * See the .htaccess file for more information.
- *
- * Examples:
- *   $base_url = 'http://www.example.com';
- *   $base_url = 'http://www.example.com:8888';
- *   $base_url = 'http://www.example.com/drupal';
- *   $base_url = 'https://www.example.com:8888/drupal';
- *
- * It is not allowed to have a trailing slash; Drupal will add it
- * for you.
- */
-# $base_url = 'http://www.example.com';  // NO trailing slash!
-
-/**
- * PHP settings:
- *
- * To see what PHP settings are possible, including whether they can be set at
- * runtime (by using ini_set()), read the PHP documentation:
- * http://php.net/manual/ini.list.php
- * See \Drupal\Core\DrupalKernel::bootEnvironment() for required runtime
- * settings and the .htaccess file for non-runtime settings.
- * Settings defined there should not be duplicated here so as to avoid conflict
- * issues.
- */
-
-/**
- * Some distributions of Linux (most notably Debian) ship their PHP
- * installations with garbage collection (gc) disabled. Since Drupal depends on
- * PHP's garbage collection for clearing sessions, ensure that garbage
- * collection occurs by using the most common settings.
- */
-ini_set('session.gc_probability', 1);
-ini_set('session.gc_divisor', 100);
-
-/**
- * Set session lifetime (in seconds), i.e. the time from the user's last visit
- * to the active session may be deleted by the session garbage collector. When
- * a session is deleted, authenticated users are logged out, and the contents
- * of the user's $_SESSION variable is discarded.
- */
-ini_set('session.gc_maxlifetime', 200000);
-
-/**
- * Set session cookie lifetime (in seconds), i.e. the time from the session is
- * created to the cookie expires, i.e. when the browser is expected to discard
- * the cookie. The value 0 means "until the browser is closed".
- */
-ini_set('session.cookie_lifetime', 2000000);
-
-/**
- * If you encounter a situation where users post a large amount of text, and
- * the result is stripped out upon viewing but can still be edited, Drupal's
- * output filter may not have sufficient memory to process it.  If you
- * experience this issue, you may wish to uncomment the following two lines
- * and increase the limits of these variables.  For more information, see
- * http://php.net/manual/pcre.configuration.php.
- */
-# ini_set('pcre.backtrack_limit', 200000);
-# ini_set('pcre.recursion_limit', 200000);
-
-/**
- * Drupal automatically generates a unique session cookie name for each site
- * based on its full domain name. If you have multiple domains pointing at the
- * same Drupal site, you can either redirect them all to a single domain (see
- * comment in .htaccess), or uncomment the line below and specify their shared
- * base domain. Doing so assures that users remain logged in as they cross
- * between your various domains. Make sure to always start the $cookie_domain
- * with a leading dot, as per RFC 2109.
- */
-# $cookie_domain = '.example.com';
-
-/**
- * Active configuration settings.
- *
- * By default, the active configuration is stored in the database in the
- * {config} table. To use a different storage mechanism for the active
- * configuration, do the following prior to installing:
- * - Override the 'bootstrap_config_storage' setting here. It must be set to a
- *   callable that returns an object that implements
- *   \Drupal\Core\Config\StorageInterface.
- * - Override the service definition 'config.storage.active'. Put this
- *   override in a services.yml file in the same directory as settings.php
- *   (definitions in this file will override service definition defaults).
- */
-# $settings['bootstrap_config_storage'] = array('Drupal\Core\Config\BootstrapConfigStorageFactory', 'getFileStorage');
-
-/**
- * Configuration overrides.
- *
- * To globally override specific configuration values for this site,
- * set them here. You usually don't need to use this feature. This is
- * useful in a configuration file for a vhost or directory, rather than
- * the default settings.php.
- *
- * Note that any values you provide in these variable overrides will not be
- * modifiable from the Drupal administration interface.
- */
-# $config['system.site']['name'] = 'My Drupal site';
-# $config['system.theme']['default'] = 'stark';
-# $config['user.settings']['anonymous'] = 'Visitor';
-
-/**
- * CSS/JS aggregated file gzip compression:
- *
- * By default, when CSS or JS aggregation and clean URLs are enabled Drupal will
- * store a gzip compressed (.gz) copy of the aggregated files. If this file is
- * available then rewrite rules in the default .htaccess file will serve these
- * files to browsers that accept gzip encoded content. This allows pages to load
- * faster for these users and has minimal impact on server load. If you are
- * using a webserver other than Apache httpd, or a caching reverse proxy that is
- * configured to cache and compress these files itself you may want to uncomment
- * one or both of the below lines, which will prevent gzip files being stored.
- */
-# $config['system.performance']['css']['gzip'] = FALSE;
-# $config['system.performance']['js']['gzip'] = FALSE;
-
-/**
- * Fast 404 pages:
- *
- * Drupal can generate fully themed 404 pages. However, some of these responses
- * are for images or other resource files that are not displayed to the user.
- * This can waste bandwidth, and also generate server load.
- *
- * The options below return a simple, fast 404 page for URLs matching a
- * specific pattern:
- * - $conf['system.performance]['fast_404']['exclude_paths']: A regular
- *   expression to match paths to exclude, such as images generated by image
- *   styles, or dynamically-resized images. If you need to add more paths, you
- *   can add '|path' to the expression.
- * - $conf['system.performance]['fast_404']['paths']: A regular expression to
- *   match paths that should return a simple 404 page, rather than the fully
- *   themed 404 page. If you don't have any aliases ending in htm or html you
- *   can add '|s?html?' to the expression.
- * - $conf['system.performance]['fast_404']['html']: The html to return for
- *   simple 404 pages.
- *
- * Remove the leading hash signs if you would like to alter this functionality.
- */
-# $config['system.performance']['fast_404']['exclude_paths'] = '/\/(?:styles)\//';
-# $config['system.performance']['fast_404']['paths'] = '/\.(?:txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i';
-# $config['system.performance']['fast_404']['html'] = '<!DOCTYPE html><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL "@path" was not found on this server.</p></body></html>';
-
-/**
- * Load local development override configuration, if available.
- *
- * Use settings.local.php to override variables on secondary (staging,
- * development, etc) installations of this site. Typically used to disable
- * caching, JavaScript/CSS compression, re-routing of outgoing emails, and
- * other things that should not happen on development and testing sites.
- *
- * Keep this code block at the end of this file to take full effect.
- */
-# if (file_exists(__DIR__ . '/settings.local.php')) {
-#   include __DIR__ . '/settings.local.php';
-# }
diff --git a/sites/example.sites.php b/sites/example.sites.php
deleted file mode 100644
index 2a813dd..0000000
--- a/sites/example.sites.php
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-
-/**
- * @file
- * Configuration file for multi-site support and directory aliasing feature.
- *
- * This file is required for multi-site support and also allows you to define a
- * set of aliases that map hostnames, ports, and pathnames to configuration
- * directories in the sites directory. These aliases are loaded prior to
- * scanning for directories, and they are exempt from the normal discovery
- * rules. See default.settings.php to view how Drupal discovers the
- * configuration directory when no alias is found.
- *
- * Aliases are useful on development servers, where the domain name may not be
- * the same as the domain of the live server. Since Drupal stores file paths in
- * the database (files, system table, etc.) this will ensure the paths are
- * correct when the site is deployed to a live server.
- *
- * To activate this feature, copy and rename it such that its path plus
- * filename is 'sites/sites.php'.
- *
- * Aliases are defined in an associative array named $sites. The array is
- * written in the format: '<port>.<domain>.<path>' => 'directory'. As an
- * example, to map http://www.drupal.org:8080/mysite/test to the configuration
- * directory sites/example.com, the array should be defined as:
- * @code
- * $sites = array(
- *   '8080.www.drupal.org.mysite.test' => 'example.com',
- * );
- * @endcode
- * The URL, http://www.drupal.org:8080/mysite/test/, could be a symbolic link or
- * an Apache Alias directive that points to the Drupal root containing
- * index.php. An alias could also be created for a subdomain. See the
- * @link http://drupal.org/documentation/install online Drupal installation guide @endlink
- * for more information on setting up domains, subdomains, and subdirectories.
- *
- * The following examples look for a site configuration in sites/example.com:
- * @code
- * URL: http://dev.drupal.org
- * $sites['dev.drupal.org'] = 'example.com';
- *
- * URL: http://localhost/example
- * $sites['localhost.example'] = 'example.com';
- *
- * URL: http://localhost:8080/example
- * $sites['8080.localhost.example'] = 'example.com';
- *
- * URL: http://www.drupal.org:8080/mysite/test/
- * $sites['8080.www.drupal.org.mysite.test'] = 'example.com';
- * @endcode
- *
- * @see default.settings.php
- * @see conf_path()
- * @see http://drupal.org/documentation/install/multi-site
- */
