From 91c38c8f983870235a05b2ff492936f0dd17d170 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Mon, 17 Nov 2014 12:20:57 +0000
Subject: [PATCH] Issue #2328111 by dawehner, martin107, neclimdul: Replace
 most instances of the DRUPAL_ROOT constant with the app.root container
 parameter.

---
 core/core.services.yml                        | 24 +++--
 core/includes/batch.inc                       |  4 +-
 core/includes/bootstrap.inc                   |  4 +-
 core/includes/errors.inc                      |  4 +-
 core/includes/install.core.inc                |  6 +-
 core/includes/install.inc                     |  2 +-
 core/includes/module.inc                      |  2 +-
 core/includes/theme.inc                       |  4 +-
 core/lib/Drupal.php                           |  9 ++
 core/lib/Drupal/Core/AppRootFactory.php       | 42 +++++++++
 .../Core/Asset/LibraryDiscoveryParser.php     | 18 +++-
 .../Drupal/Core/Cache/ApcuBackendFactory.php  |  7 +-
 .../lib/Drupal/Core/Config/InstallStorage.php |  2 +-
 core/lib/Drupal/Core/CoreServiceProvider.php  |  2 -
 core/lib/Drupal/Core/DrupalKernel.php         | 70 +++++++-------
 .../lib/Drupal/Core/DrupalKernelInterface.php |  7 ++
 core/lib/Drupal/Core/Extension/Extension.php  | 16 +++-
 .../Core/Extension/ExtensionDiscovery.php     | 25 ++++-
 .../Drupal/Core/Extension/ModuleHandler.php   | 28 ++++--
 .../Drupal/Core/Extension/ThemeHandler.php    | 16 +++-
 .../Form/FileTransferAuthorizeForm.php        | 29 +++++-
 core/lib/Drupal/Core/Form/FormCache.php       | 14 ++-
 .../Core/Installer/Form/SiteConfigureForm.php | 15 ++-
 core/lib/Drupal/Core/Site/Settings.php        |  8 +-
 .../Drupal/Core/Template/TwigEnvironment.php  |  7 +-
 .../lib/Drupal/Core/Test/TestRunnerKernel.php |  4 +-
 core/lib/Drupal/Core/Theme/Registry.php       | 18 +++-
 .../Drupal/Core/Theme/ThemeInitialization.php | 22 +++--
 .../src/Unit/Menu/BlockLocalTasksTest.php     |  1 +
 .../ckeditor/src/Plugin/Editor/CKEditor.php   |  2 +-
 core/modules/color/color.module               |  4 +-
 .../config_test/src/TestInstallStorage.php    |  2 +-
 core/modules/filter/filter.module             |  2 +-
 .../modules/image/src/Tests/ImageItemTest.php |  4 +-
 .../src/Tests/ImageThemeFunctionTest.php      |  2 +-
 .../rdf/src/Tests/StandardProfileTest.php     |  2 +-
 .../search/src/Tests/SearchSimplifyTest.php   |  2 +-
 core/modules/simpletest/simpletest.install    |  6 +-
 core/modules/simpletest/simpletest.module     |  8 +-
 .../simpletest/src/InstallerTestBase.php      |  8 +-
 core/modules/simpletest/src/TestDiscovery.php |  2 +-
 core/modules/simpletest/src/WebTestBase.php   |  4 +-
 .../system/src/Controller/BatchController.php | 32 ++++++-
 .../src/Controller/DbUpdateController.php     | 20 +++-
 .../system/src/Tests/Ajax/FormValuesTest.php  |  2 +-
 .../src/Tests/Common/SystemListingTest.php    |  4 +-
 .../Tests/FileTransfer/FileTransferTest.php   |  4 +-
 .../InstallerLanguageDirectionTest.php        |  4 +-
 .../Installer/InstallerLanguagePageTest.php   |  4 +-
 .../src/Tests/Installer/InstallerTest.php     |  2 +-
 .../Installer/InstallerTranslationTest.php    |  4 +-
 .../InstallerTranslationVersionUnitTest.php   |  2 +-
 .../PhpStorage/PhpStorageFactoryTest.php      |  2 +-
 .../Discovery/AnnotatedClassDiscoveryTest.php |  2 +-
 .../CustomAnnotationClassDiscoveryTest.php    |  2 +-
 ...omDirectoryAnnotatedClassDiscoveryTest.php |  2 +-
 .../src/Tests/Plugin/PluginTestBase.php       |  2 +-
 .../RouteProcessorCurrentIntegrationTest.php  |  8 +-
 .../RouteProcessorNoneIntegrationTest.php     |  8 +-
 .../src/Tests/System/ErrorHandlerTest.php     |  2 +-
 .../system/src/Tests/System/HtaccessTest.php  |  2 +-
 .../System/IgnoreReplicaSubscriberTest.php    |  2 +-
 .../src/Tests/System/SettingsRewriteTest.php  | 10 +-
 .../Tests/System/ShutdownFunctionsTest.php    |  2 +-
 .../Tests/Theme/EntityFilteringThemeTest.php  |  2 +-
 .../src/Tests/Theme/ThemeSettingsTest.php     |  2 +-
 .../src/Tests/TypedData/TypedDataTest.php     |  2 +-
 .../Update/DependencyHookInvocationTest.php   |  2 +-
 .../Tests/Update/DependencyMissingTest.php    |  2 +-
 .../Tests/Update/DependencyOrderingTest.php   |  2 +-
 .../Tests/Update/InvalidUpdateHookTest.php    |  2 +-
 .../src/Tests/Update/UpdatesWith7xTest.php    |  2 +-
 core/modules/system/system.module             |  2 +-
 .../src/Unit/Menu/SystemLocalTasksTest.php    |  2 +-
 .../taxonomy/src/Tests/VocabularyCrudTest.php |  2 +-
 .../update/src/Form/UpdateManagerInstall.php  | 15 ++-
 core/modules/update/src/Form/UpdateReady.php  | 15 ++-
 .../src/Tests/UserAccountFormFieldsTest.php   |  4 +-
 .../tests/src/Unit/PermissionHandlerTest.php  |  4 +-
 core/modules/views/views.module               |  2 +-
 core/rebuild.php                              |  2 +-
 .../Core/Asset/LibraryDiscoveryParserTest.php | 32 ++++---
 .../Core/Extension/DefaultConfigTest.php      |  2 +-
 .../Core/Extension/ModuleHandlerTest.php      | 23 +++--
 .../Tests/Core/Extension/ThemeHandlerTest.php | 94 ++++++++++---------
 .../Drupal/Tests/Core/Form/FormCacheTest.php  |  6 +-
 .../Drupal/Tests/Core/Form/FormTestBase.php   |  1 +
 .../Core/Menu/LocalTaskIntegrationTest.php    |  5 +-
 .../Core/Plugin/DefaultPluginManagerTest.php  |  2 +-
 .../Tests/Core/Routing/UrlGeneratorTest.php   |  2 +-
 .../Drupal/Tests/Core/Theme/RegistryTest.php  |  6 +-
 .../Core/Utility/UnroutedUrlAssemblerTest.php |  2 +-
 core/tests/Drupal/Tests/UnitTestCase.php      |  9 ++
 core/tests/bootstrap.php                      |  1 -
 .../engines/phptemplate/phptemplate.engine    |  2 +-
 95 files changed, 563 insertions(+), 268 deletions(-)
 create mode 100644 core/lib/Drupal/Core/AppRootFactory.php

diff --git a/core/core.services.yml b/core/core.services.yml
index f306a0d976e6..50281cd62303 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -42,6 +42,7 @@ services:
     arguments: ['@database']
   cache.backend.apcu:
     class: Drupal\Core\Cache\ApcuBackendFactory
+    arguments: ['@app.root']
   cache.backend.php:
     class: Drupal\Core\Cache\PhpBackendFactory
   cache.bootstrap:
@@ -182,7 +183,7 @@ services:
     arguments: ['@request_stack', '@url_generator']
   form_cache:
     class: Drupal\Core\Form\FormCache
-    arguments: ['@keyvalue.expirable', '@module_handler', '@current_user', '@csrf_token', '@logger.channel.form', '@config.factory', '@request_stack', '@page_cache_request_policy']
+    arguments: ['@app.root', '@keyvalue.expirable', '@module_handler', '@current_user', '@csrf_token', '@logger.channel.form', '@config.factory', '@request_stack', '@page_cache_request_policy']
     public: false  # Private to form_builder
   keyvalue:
     class: Drupal\Core\KeyValueStore\KeyValueFactory
@@ -287,10 +288,10 @@ services:
     arguments: ['@container.namespaces', '@cache.discovery', '@module_handler']
   module_handler:
     class: Drupal\Core\Extension\ModuleHandler
-    arguments: ['%container.modules%', '@kernel', '@cache.bootstrap']
+    arguments: ['@app.root', '%container.modules%', '@kernel', '@cache.bootstrap']
   theme_handler:
     class: Drupal\Core\Extension\ThemeHandler
-    arguments: ['@config.factory', '@module_handler', '@state', '@info_parser', '@logger.channel.default', '@asset.css.collection_optimizer', '@config.installer', '@config.manager', '@router.builder_indicator']
+    arguments: ['@app.root', '@config.factory', '@module_handler', '@state', '@info_parser', '@logger.channel.default', '@asset.css.collection_optimizer', '@config.installer', '@config.manager', '@router.builder_indicator']
   entity.manager:
     class: Drupal\Core\Entity\EntityManager
     arguments: ['@container.namespaces', '@module_handler', '@cache.discovery', '@language_manager', '@string_translation', '@class_resolver', '@typed_data_manager', '@entity.definitions.installed', '@event_dispatcher']
@@ -382,6 +383,13 @@ services:
   event_dispatcher:
     class: Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher
     arguments: ['@service_container']
+  app.root:
+    class: SplString
+    factory_service: 'app.root.factory'
+    factory_method: 'get'
+  app.root.factory:
+    class: Drupal\Core\AppRootFactory
+    arguments: ['@kernel']
   controller_resolver:
     class: Drupal\Core\Controller\ControllerResolver
     arguments: ['@class_resolver', '@logger.channel.default']
@@ -989,10 +997,10 @@ services:
     arguments: ['@theme.registry', '@theme.negotiator', '@theme.initialization', '@request_stack']
   theme.initialization:
     class: Drupal\Core\Theme\ThemeInitialization
-    arguments: ['@theme_handler', '@state']
+    arguments: ['@app.root', '@theme_handler', '@state']
   theme.registry:
     class: Drupal\Core\Theme\Registry
-    arguments: ['@cache.default', '@lock', '@module_handler']
+    arguments: ['@app.root', '@cache.default', '@lock', '@module_handler']
     tags:
       - { name: needs_destruction }
   authentication:
@@ -1049,12 +1057,12 @@ services:
       - { name: needs_destruction }
   library.discovery.parser:
     class: Drupal\Core\Asset\LibraryDiscoveryParser
-    arguments: ['@module_handler']
+    arguments: ['@app.root', '@module_handler']
   info_parser:
     class: Drupal\Core\Extension\InfoParser
   twig:
     class: Drupal\Core\Template\TwigEnvironment
-    arguments: ['@twig.loader', '@module_handler', '@theme_handler', '%twig.config%']
+    arguments: ['@app.root', '@twig.loader', '@module_handler', '@theme_handler', '%twig.config%']
     tags:
       - { name: service_collector, tag: 'twig.extension', call: addExtension }
   twig.extension:
@@ -1074,7 +1082,7 @@ services:
     alias: twig.loader.filesystem
   twig.loader.filesystem:
     class: Twig_Loader_Filesystem
-    arguments: ['%app.root%']
+    arguments: ['@app.root']
   element_info:
     alias: plugin.manager.element_info
   file.mime_type.guesser:
diff --git a/core/includes/batch.inc b/core/includes/batch.inc
index 4f527b3d2df0..59e152929698 100644
--- a/core/includes/batch.inc
+++ b/core/includes/batch.inc
@@ -235,7 +235,7 @@ function _batch_process() {
     // request, we check if it requires an additional file for functions
     // definitions.
     if ($set_changed && isset($current_set['file']) && is_file($current_set['file'])) {
-      include_once DRUPAL_ROOT . '/' . $current_set['file'];
+      include_once \Drupal::root() . '/' . $current_set['file'];
     }
 
     $task_message = $label = '';
@@ -408,7 +408,7 @@ function _batch_finished() {
     if (isset($batch_set['finished'])) {
       // Check if the set requires an additional file for function definitions.
       if (isset($batch_set['file']) && is_file($batch_set['file'])) {
-        include_once DRUPAL_ROOT . '/' . $batch_set['file'];
+        include_once \Drupal::root() . '/' . $batch_set['file'];
       }
       if (is_callable($batch_set['finished'])) {
         $queue = _batch_queue($batch_set);
diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 5f6c9d4c6aad..43d7368b9f2d 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -277,7 +277,7 @@ function drupal_get_filename($type, $name, $filename = NULL) {
     }
     // If still unknown, perform a filesystem scan.
     if (!isset($files[$type][$name])) {
-      $listing = new ExtensionDiscovery();
+      $listing = new ExtensionDiscovery(DRUPAL_ROOT);
       // Prevent an infinite recursion by this legacy function.
       if ($original_type == 'profile') {
         $listing->setProfileDirectories(array());
@@ -1190,7 +1190,7 @@ function _current_path($path = NULL) {
  */
 function drupal_classloader_register($name, $path) {
   $loader = \Drupal::service('class_loader');
-  $loader->addPsr4('Drupal\\' . $name . '\\', DRUPAL_ROOT . '/' . $path . '/src');
+  $loader->addPsr4('Drupal\\' . $name . '\\', \Drupal::root() . '/' . $path . '/src');
 }
 
 /**
diff --git a/core/includes/errors.inc b/core/includes/errors.inc
index be30937c42a7..a3c356464ee5 100644
--- a/core/includes/errors.inc
+++ b/core/includes/errors.inc
@@ -199,8 +199,8 @@ function _drupal_log_error($error, $fatal = FALSE) {
 
       // Attempt to reduce verbosity by removing DRUPAL_ROOT from the file path
       // in the message. This does not happen for (false) security.
-      $root_length = strlen(DRUPAL_ROOT);
-      if (substr($error['%file'], 0, $root_length) == DRUPAL_ROOT) {
+      $root_length = strlen(\Drupal::root());
+      if (substr($error['%file'], 0, $root_length) == \Drupal::root()) {
         $error['%file'] = substr($error['%file'], $root_length + 1);
       }
       // Should not translate the string to avoid errors producing more errors.
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 2adc5763c267..0899bec2a56c 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -287,7 +287,7 @@ function install_begin_request(&$install_state) {
 
   $site_path = DrupalKernel::findSitePath($request, FALSE);
   $class_loader = require __DIR__ . '/../vendor/autoload.php';
-  Settings::initialize($site_path, $class_loader);
+  Settings::initialize(dirname(dirname(__DIR__)), $site_path, $class_loader);
 
   // Ensure that procedural dependencies are loaded as early as possible,
   // since the error/exception handlers depend on them.
@@ -389,7 +389,7 @@ function install_begin_request(&$install_state) {
   }
 
   // Add list of all available profiles to the installation state.
-  $listing = new ExtensionDiscovery();
+  $listing = new ExtensionDiscovery($container->get('app.root'));
   $listing->setProfileDirectories(array());
   $install_state['profiles'] += $listing->scan('profile');
 
@@ -717,7 +717,7 @@ function install_tasks($install_state) {
     $profile = $install_state['parameters']['profile'];
     $profile_install_file = $install_state['profiles'][$profile]->getPath() . '/' . $profile . '.install';
     if (file_exists($profile_install_file)) {
-      include_once DRUPAL_ROOT . '/' . $profile_install_file;
+      include_once \Drupal::root() . '/' . $profile_install_file;
     }
     $function = $install_state['parameters']['profile'] . '_install_tasks';
     if (function_exists($function)) {
diff --git a/core/includes/install.inc b/core/includes/install.inc
index ec6283b7cac3..cd305b32b217 100644
--- a/core/includes/install.inc
+++ b/core/includes/install.inc
@@ -593,7 +593,7 @@ function drupal_verify_profile($install_state) {
   $info = $install_state['profile_info'];
 
   // Get the list of available modules for the selected installation profile.
-  $listing = new ExtensionDiscovery();
+  $listing = new ExtensionDiscovery(DRUPAL_ROOT);
   $present_modules = array();
   foreach ($listing->scan('module') as $present_module) {
     $present_modules[] = $present_module->getName();
diff --git a/core/includes/module.inc b/core/includes/module.inc
index ac19a621ca94..606d8136892b 100644
--- a/core/includes/module.inc
+++ b/core/includes/module.inc
@@ -179,7 +179,7 @@ function module_uninstall($module_list = array(), $uninstall_dependents = TRUE)
  * Returns an array of modules required by core.
  */
 function drupal_required_modules() {
-  $listing = new ExtensionDiscovery();
+  $listing = new ExtensionDiscovery(\Drupal::root());
   $files = $listing->scan('module');
   $required = array();
 
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 493ceab2c08d..95d9cc09ec3e 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -341,7 +341,7 @@ function _theme($hook, $variables = array()) {
   // elsewhere.
   if (!empty($info['includes'])) {
     foreach ($info['includes'] as $include_file) {
-      include_once DRUPAL_ROOT . '/' . $include_file;
+      include_once \Drupal::root() . '/' . $include_file;
     }
   }
 
@@ -353,7 +353,7 @@ function _theme($hook, $variables = array()) {
     // might reside there.
     if (!empty($base_hook_info['includes'])) {
       foreach ($base_hook_info['includes'] as $include_file) {
-        include_once DRUPAL_ROOT . '/' . $include_file;
+        include_once \Drupal::root() . '/' . $include_file;
       }
     }
     // Replace the preprocess functions with those from the base hook.
diff --git a/core/lib/Drupal.php b/core/lib/Drupal.php
index 363cf129cdb9..141686fda30a 100644
--- a/core/lib/Drupal.php
+++ b/core/lib/Drupal.php
@@ -152,6 +152,15 @@ public static function hasService($id) {
     return static::$container && static::$container->has($id);
   }
 
+  /**
+   * Gets the app root.
+   *
+   * @return string
+   */
+  public static function root() {
+    return static::$container->get('app.root');
+  }
+
   /**
    * Indicates if there is a currently active request object.
    *
diff --git a/core/lib/Drupal/Core/AppRootFactory.php b/core/lib/Drupal/Core/AppRootFactory.php
new file mode 100644
index 000000000000..f57d26262713
--- /dev/null
+++ b/core/lib/Drupal/Core/AppRootFactory.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\AppRootFactory.
+ */
+
+namespace Drupal\Core;
+
+/**
+ * Gets the app root from the kernel.
+ */
+class AppRootFactory {
+
+  /**
+   * The Drupal kernel.
+   *
+   * @var \Drupal\Core\DrupalKernelInterface
+   */
+  protected $drupalKernel;
+
+  /**
+   * Constructs an AppRootFactory instance.
+   *
+   * @param \Drupal\Core\DrupalKernelInterface $drupal_kernel
+   *   The Drupal kernel.
+   */
+  public function __construct(DrupalKernelInterface $drupal_kernel) {
+    $this->drupalKernel = $drupal_kernel;
+  }
+
+  /**
+   * Gets the app root.
+   *
+   * @return string
+   */
+  public function get() {
+    return $this->drupalKernel->getAppRoot();
+  }
+
+}
+
diff --git a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
index bd962bd8e211..a28ca6e8369c 100644
--- a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
+++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
@@ -27,10 +27,22 @@ class LibraryDiscoveryParser {
   protected $moduleHandler;
 
   /**
+   * The app root.
+   *
+   * @var string
+   */
+  protected $root;
+
+  /**
+   * Constructs a new LibraryDiscoveryParser instance.
+   *
+   * @param string $root
+   *   The app root.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler.
    */
-  public function __construct(ModuleHandlerInterface $module_handler) {
+  public function __construct($root, ModuleHandlerInterface $module_handler) {
+    $this->root = $root;
     $this->moduleHandler = $module_handler;
   }
 
@@ -67,7 +79,7 @@ public function buildByExtension($extension) {
 
     $library_file = $path . '/' . $extension . '.libraries.yml';
 
-    if ($library_file && file_exists(DRUPAL_ROOT . '/' . $library_file)) {
+    if ($library_file && file_exists($this->root . '/' . $library_file)) {
       $libraries = $this->parseLibraryInfo($extension, $library_file);
     }
 
@@ -222,7 +234,7 @@ public function buildByExtension($extension) {
    */
   protected function parseLibraryInfo($extension, $library_file) {
     try {
-      $libraries = Yaml::decode(file_get_contents(DRUPAL_ROOT . '/' . $library_file));
+      $libraries = Yaml::decode(file_get_contents($this->root . '/' . $library_file));
     }
     catch (InvalidDataTypeException $e) {
       // Rethrow a more helpful exception to provide context.
diff --git a/core/lib/Drupal/Core/Cache/ApcuBackendFactory.php b/core/lib/Drupal/Core/Cache/ApcuBackendFactory.php
index 341203c4a88c..ffe599387973 100644
--- a/core/lib/Drupal/Core/Cache/ApcuBackendFactory.php
+++ b/core/lib/Drupal/Core/Cache/ApcuBackendFactory.php
@@ -20,9 +20,12 @@ class ApcuBackendFactory implements CacheFactoryInterface {
 
   /**
    * Constructs an ApcuBackendFactory object.
+   *
+   * @param string $root
+   *   The app root.
    */
-  public function __construct() {
-    $this->sitePrefix = Crypt::hashBase64(DRUPAL_ROOT . '/' . conf_path());
+  public function __construct($root) {
+    $this->sitePrefix = Crypt::hashBase64($root . '/' . conf_path());
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Config/InstallStorage.php b/core/lib/Drupal/Core/Config/InstallStorage.php
index e9bd690772f9..d4e7d5c77f84 100644
--- a/core/lib/Drupal/Core/Config/InstallStorage.php
+++ b/core/lib/Drupal/Core/Config/InstallStorage.php
@@ -157,7 +157,7 @@ protected function getAllFolders() {
       if ($profile = drupal_get_profile()) {
         $this->folders += $this->getComponentNames('profile', array($profile));
       }
-      $listing = new ExtensionDiscovery();
+      $listing = new ExtensionDiscovery(DRUPAL_ROOT);
       $this->folders += $this->getComponentNames('module', array_keys($listing->scan('module')));
       $this->folders += $this->getComponentNames('theme', array_keys($listing->scan('theme')));
     }
diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php
index 3767c9f54abd..249944f32a45 100644
--- a/core/lib/Drupal/Core/CoreServiceProvider.php
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php
@@ -41,8 +41,6 @@ class CoreServiceProvider implements ServiceProviderInterface  {
    * {@inheritdoc}
    */
   public function register(ContainerBuilder $container) {
-    $container->setParameter('app.root', DRUPAL_ROOT);
-
     $this->registerUuid($container);
     $this->registerTest($container);
 
diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index 600fd2164b01..9c926ea3357d 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -179,6 +179,13 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
    */
   protected $sitePath;
 
+  /**
+   * The app root.
+   *
+   * @var string
+   */
+  protected $root;
+
   /**
    * Create a DrupalKernel object from a request.
    *
@@ -198,7 +205,8 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
    */
   public static function createFromRequest(Request $request, $class_loader, $environment, $allow_dumping = TRUE) {
     // Include our bootstrap file.
-    require_once dirname(dirname(dirname(__DIR__))) . '/includes/bootstrap.inc';
+    $core_root = dirname(dirname(dirname(__DIR__)));
+    require_once $core_root . '/includes/bootstrap.inc';
 
     $kernel = new static($environment, $class_loader, $allow_dumping);
 
@@ -206,7 +214,9 @@ public static function createFromRequest(Request $request, $class_loader, $envir
     static::bootEnvironment();
 
     // Get our most basic settings setup.
-    $kernel->initializeSettings($request);
+    $site_path = static::findSitePath($request);
+    $kernel->setSitePath($site_path);
+    Settings::initialize(dirname($core_root), $site_path, $class_loader);
 
     // Redirect the user to the installation script if Drupal has not been
     // installed yet (i.e., if no $databases array has been defined in the
@@ -219,18 +229,6 @@ public static function createFromRequest(Request $request, $class_loader, $envir
     return $kernel;
   }
 
-  /**
-   * Initializes the kernel's site path and the Settings singleton.
-   *
-   * @param \Symfony\Component\HttpFoundation\Request $request
-   *   The request that will be used to determine the site path.
-   */
-  protected function initializeSettings(Request $request) {
-    $site_path = static::findSitePath($request);
-    $this->setSitePath($site_path);
-    Settings::initialize($site_path, $this->classLoader);
-  }
-
   /**
    * Constructs a DrupalKernel object.
    *
@@ -248,6 +246,7 @@ public function __construct($environment, $class_loader, $allow_dumping = TRUE)
     $this->environment = $environment;
     $this->classLoader = $class_loader;
     $this->allowDumping = $allow_dumping;
+    $this->root = dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__))));
   }
 
   /**
@@ -349,6 +348,13 @@ public function getSitePath() {
     return $this->sitePath;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getAppRoot() {
+    return $this->root;
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -361,21 +367,21 @@ public function boot() {
     Timer::start('page');
 
     // Load legacy and other functional code.
-    require_once DRUPAL_ROOT . '/core/includes/common.inc';
-    require_once DRUPAL_ROOT . '/core/includes/database.inc';
-    require_once DRUPAL_ROOT . '/core/includes/path.inc';
-    require_once DRUPAL_ROOT . '/core/includes/module.inc';
-    require_once DRUPAL_ROOT . '/core/includes/theme.inc';
-    require_once DRUPAL_ROOT . '/core/includes/pager.inc';
-    require_once DRUPAL_ROOT . '/core/includes/menu.inc';
-    require_once DRUPAL_ROOT . '/core/includes/tablesort.inc';
-    require_once DRUPAL_ROOT . '/core/includes/file.inc';
-    require_once DRUPAL_ROOT . '/core/includes/unicode.inc';
-    require_once DRUPAL_ROOT . '/core/includes/form.inc';
-    require_once DRUPAL_ROOT . '/core/includes/mail.inc';
-    require_once DRUPAL_ROOT . '/core/includes/errors.inc';
-    require_once DRUPAL_ROOT . '/core/includes/schema.inc';
-    require_once DRUPAL_ROOT . '/core/includes/entity.inc';
+    require_once $this->root . '/core/includes/common.inc';
+    require_once $this->root . '/core/includes/database.inc';
+    require_once $this->root . '/core/includes/path.inc';
+    require_once $this->root . '/core/includes/module.inc';
+    require_once $this->root . '/core/includes/theme.inc';
+    require_once $this->root . '/core/includes/pager.inc';
+    require_once $this->root . '/core/includes/menu.inc';
+    require_once $this->root . '/core/includes/tablesort.inc';
+    require_once $this->root . '/core/includes/file.inc';
+    require_once $this->root . '/core/includes/unicode.inc';
+    require_once $this->root . '/core/includes/form.inc';
+    require_once $this->root . '/core/includes/mail.inc';
+    require_once $this->root . '/core/includes/errors.inc';
+    require_once $this->root . '/core/includes/schema.inc';
+    require_once $this->root . '/core/includes/entity.inc';
 
     // Ensure that findSitePath is set.
     if (!$this->sitePath) {
@@ -588,7 +594,7 @@ public function prepareLegacyRequest(Request $request) {
   protected function moduleData($module) {
     if (!$this->moduleData) {
       // First, find profiles.
-      $listing = new ExtensionDiscovery();
+      $listing = new ExtensionDiscovery($this->root);
       $listing->setProfileDirectories(array());
       $all_profiles = $listing->scan('profile');
       $profiles = array_intersect_key($all_profiles, $this->moduleList);
@@ -1017,7 +1023,7 @@ protected function compileContainer() {
     // - Entity
     // - Plugin
     foreach (array('Core', 'Component') as $parent_directory) {
-      $path = DRUPAL_ROOT . '/core/lib/Drupal/' . $parent_directory;
+      $path = $this->root . '/core/lib/Drupal/' . $parent_directory;
       $parent_namespace = 'Drupal\\' . $parent_directory;
       foreach (new \DirectoryIterator($path) as $component) {
         /** @var $component \DirectoryIterator */
@@ -1230,7 +1236,7 @@ protected function getModuleFileNames() {
   protected function getModuleNamespacesPsr4($module_file_names) {
     $namespaces = array();
     foreach ($module_file_names as $module => $filename) {
-      $namespaces["Drupal\\$module"] = DRUPAL_ROOT . '/' . dirname($filename) . '/src';
+      $namespaces["Drupal\\$module"] = $this->root . '/' . dirname($filename) . '/src';
     }
     return $namespaces;
   }
diff --git a/core/lib/Drupal/Core/DrupalKernelInterface.php b/core/lib/Drupal/Core/DrupalKernelInterface.php
index a5eb3b96a727..e7c468fb0506 100644
--- a/core/lib/Drupal/Core/DrupalKernelInterface.php
+++ b/core/lib/Drupal/Core/DrupalKernelInterface.php
@@ -73,6 +73,13 @@ public function setSitePath($path);
    */
   public function getSitePath();
 
+  /**
+   * Gets the app root.
+   *
+   * @return string
+   */
+  public function getAppRoot();
+
   /**
    * Updates the kernel's list of modules to the new list.
    *
diff --git a/core/lib/Drupal/Core/Extension/Extension.php b/core/lib/Drupal/Core/Extension/Extension.php
index b3354950c08d..3c765fe70a29 100644
--- a/core/lib/Drupal/Core/Extension/Extension.php
+++ b/core/lib/Drupal/Core/Extension/Extension.php
@@ -42,9 +42,18 @@ class Extension implements \Serializable {
    */
   protected $splFileInfo;
 
+  /**
+   * The app root.
+   *
+   * @var string
+   */
+  protected $root;
+
   /**
    * Constructs a new Extension object.
    *
+   * @param string $root
+   *   The app root.
    * @param string $type
    *   The type of the extension; e.g., 'module'.
    * @param string $pathname
@@ -53,7 +62,8 @@ class Extension implements \Serializable {
    * @param string $filename
    *   (optional) The filename of the main extension file; e.g., 'node.module'.
    */
-  public function __construct($type, $pathname, $filename = NULL) {
+  public function __construct($root, $type, $pathname, $filename = NULL) {
+    $this->root = $root;
     $this->type = $type;
     $this->pathname = $pathname;
     $this->filename = $filename;
@@ -132,7 +142,7 @@ public function getExtensionFilename() {
    */
   public function load() {
     if ($this->filename) {
-      include_once DRUPAL_ROOT . '/' . $this->getPath() . '/' . $this->filename;
+      include_once $this->root . '/' . $this->getPath() . '/' . $this->filename;
       return TRUE;
     }
     return FALSE;
@@ -157,6 +167,7 @@ public function __call($method, array $args) {
    */
   public function serialize() {
     $data = array(
+      'root' => $this->root,
       'type' => $this->type,
       'pathname' => $this->pathname,
       'filename' => $this->filename,
@@ -177,6 +188,7 @@ public function serialize() {
    */
   public function unserialize($data) {
     $data = unserialize($data);
+    $this->root = $data['root'];
     $this->type = $data['type'];
     $this->pathname = $data['pathname'];
     $this->filename = $data['filename'];
diff --git a/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
index f51cbb3d4deb..968116295f7f 100644
--- a/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
+++ b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
@@ -73,6 +73,23 @@ class ExtensionDiscovery {
    */
   protected $profileDirectories;
 
+  /**
+   * The app root.
+   *
+   * @var string
+   */
+  protected $root;
+
+  /**
+   * Constructs a new ExtensionDiscovery object.
+   *
+   * @param string $root
+   *   The app root.
+   */
+  public function __construct($root) {
+    $this->root = $root;
+  }
+
   /**
    * Discovers available extensions of a given type.
    *
@@ -80,7 +97,7 @@ class ExtensionDiscovery {
    * searches in several locations. For instance, to discover all available
    * modules:
    * @code
-   * $listing = new ExtensionDiscovery();
+   * $listing = new ExtensionDiscovery(\Drupal::root());
    * $modules = $listing->scan('module');
    * @endcode
    *
@@ -304,9 +321,9 @@ protected function scanDirectory($dir, $include_tests) {
     // be used (which also improves performance, since any configured PHP
     // include_paths will not be consulted). Retain the relative originating
     // directory being scanned, so relative paths can be reconstructed below
-    // (all paths are expected to be relative to DRUPAL_ROOT).
+    // (all paths are expected to be relative to $this->root).
     $dir_prefix = ($dir == '' ? '' : "$dir/");
-    $absolute_dir = ($dir == '' ? DRUPAL_ROOT : DRUPAL_ROOT . "/$dir");
+    $absolute_dir = ($dir == '' ? $this->root : $this->root . "/$dir");
 
     if (!is_dir($absolute_dir)) {
       return $files;
@@ -370,7 +387,7 @@ protected function scanDirectory($dir, $include_tests) {
         $filename = NULL;
       }
 
-      $extension = new Extension($type, $pathname, $filename);
+      $extension = new Extension($this->root, $type, $pathname, $filename);
 
       // Track the originating directory for sorting purposes.
       $extension->subpath = $fileinfo->getSubPath();
diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php
index 028d7d43b7ea..12d280507666 100644
--- a/core/lib/Drupal/Core/Extension/ModuleHandler.php
+++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php
@@ -92,9 +92,18 @@ class ModuleHandler implements ModuleHandlerInterface {
    */
   protected $alterFunctions;
 
+  /**
+   * The app root.
+   *
+   * @var string
+   */
+  protected $root;
+
   /**
    * Constructs a ModuleHandler object.
    *
+   * @param string $root
+   *   The app root.
    * @param array $module_list
    *   An associative array whose keys are the names of installed modules and
    *   whose values are Extension class parameters. This is normally the
@@ -107,10 +116,11 @@ class ModuleHandler implements ModuleHandlerInterface {
    * @see \Drupal\Core\DrupalKernel
    * @see \Drupal\Core\CoreServiceProvider
    */
-  public function __construct(array $module_list = array(), DrupalKernelInterface $kernel, CacheBackendInterface $cache_backend) {
+  public function __construct($root, array $module_list = array(), DrupalKernelInterface $kernel, CacheBackendInterface $cache_backend) {
+    $this->root = $root;
     $this->moduleList = array();
     foreach ($module_list as $name => $module) {
-      $this->moduleList[$name] = new Extension($module['type'], $module['pathname'], $module['filename']);
+      $this->moduleList[$name] = new Extension($this->root, $module['type'], $module['pathname'], $module['filename']);
     }
     $this->kernel = $kernel;
     $this->cacheBackend = $cache_backend;
@@ -212,8 +222,8 @@ public function addProfile($name, $path) {
    */
   protected function add($type, $name, $path) {
     $pathname = "$path/$name.info.yml";
-    $filename = file_exists(DRUPAL_ROOT . "/$path/$name.$type") ? "$name.$type" : NULL;
-    $this->moduleList[$name] = new Extension($type, $pathname, $filename);
+    $filename = file_exists($this->root . "/$path/$name.$type") ? "$name.$type" : NULL;
+    $this->moduleList[$name] = new Extension($this->root, $type, $pathname, $filename);
     $this->resetImplementations();
   }
 
@@ -262,12 +272,12 @@ public function loadAllIncludes($type, $name = NULL) {
   public function loadInclude($module, $type, $name = NULL) {
     if ($type == 'install') {
       // Make sure the installation API is available
-      include_once DRUPAL_ROOT . '/core/includes/install.inc';
+      include_once $this->root . '/core/includes/install.inc';
     }
 
     $name = $name ?: $module;
     if (isset($this->moduleList[$module])) {
-      $file = DRUPAL_ROOT . '/' . $this->moduleList[$module]->getPath() . "/$name.$type";
+      $file = $this->root . '/' . $this->moduleList[$module]->getPath() . "/$name.$type";
       if (is_file($file)) {
         require_once $file;
         return $file;
@@ -736,7 +746,7 @@ public function install(array $module_list, $enable_dependencies = TRUE) {
     }
 
     // Required for module installation checks.
-    include_once DRUPAL_ROOT . '/core/includes/install.inc';
+    include_once $this->root . '/core/includes/install.inc';
 
     /** @var \Drupal\Core\Config\ConfigInstaller $config_installer */
     $config_installer = \Drupal::service('config.installer');
@@ -783,7 +793,7 @@ public function install(array $module_list, $enable_dependencies = TRUE) {
             $module_path = drupal_get_path('module', $name);
             $pathname = "$module_path/$name.info.yml";
             $filename = file_exists($module_path . "/$name.module") ? "$name.module" : NULL;
-            $module_filenames[$name] = new Extension('module', $pathname, $filename);
+            $module_filenames[$name] = new Extension($this->root, 'module', $pathname, $filename);
           }
         }
 
@@ -1076,7 +1086,7 @@ protected function removeCacheBins($module) {
   public function getModuleDirectories() {
     $dirs = array();
     foreach ($this->getModuleList() as $name => $module) {
-      $dirs[$name] = DRUPAL_ROOT . '/' . $module->getPath();
+      $dirs[$name] = $this->root . '/' . $module->getPath();
     }
     return $dirs;
   }
diff --git a/core/lib/Drupal/Core/Extension/ThemeHandler.php b/core/lib/Drupal/Core/Extension/ThemeHandler.php
index a316f36e1520..02100fba4f08 100644
--- a/core/lib/Drupal/Core/Extension/ThemeHandler.php
+++ b/core/lib/Drupal/Core/Extension/ThemeHandler.php
@@ -114,9 +114,18 @@ class ThemeHandler implements ThemeHandlerInterface {
    */
   protected $configManager;
 
+  /**
+   * The app root.
+   *
+   * @var string
+   */
+  protected $root;
+
   /**
    * Constructs a new ThemeHandler.
    *
+   * @param string $root
+   *   The app root.
    * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
    *   The config factory to get the installed themes.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
@@ -141,7 +150,8 @@ class ThemeHandler implements ThemeHandlerInterface {
    * @param \Drupal\Core\Extension\ExtensionDiscovery $extension_discovery
    *   (optional) A extension discovery instance (for unit tests).
    */
-  public function __construct(ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, StateInterface $state, InfoParserInterface $info_parser,LoggerInterface $logger, AssetCollectionOptimizerInterface $css_collection_optimizer = NULL, ConfigInstallerInterface $config_installer = NULL, ConfigManagerInterface $config_manager = NULL, RouteBuilderIndicatorInterface $route_builder_indicator = NULL, ExtensionDiscovery $extension_discovery = NULL) {
+  public function __construct($root, ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, StateInterface $state, InfoParserInterface $info_parser,LoggerInterface $logger, AssetCollectionOptimizerInterface $css_collection_optimizer = NULL, ConfigInstallerInterface $config_installer = NULL, ConfigManagerInterface $config_manager = NULL, RouteBuilderIndicatorInterface $route_builder_indicator = NULL, ExtensionDiscovery $extension_discovery = NULL) {
+    $this->root = $root;
     $this->configFactory = $config_factory;
     $this->moduleHandler = $module_handler;
     $this->state = $state;
@@ -639,7 +649,7 @@ protected function doGetBaseThemes(array $themes, $theme, $used_themes = array()
    */
   protected function getExtensionDiscovery() {
     if (!isset($this->extensionDiscovery)) {
-      $this->extensionDiscovery = new ExtensionDiscovery();
+      $this->extensionDiscovery = new ExtensionDiscovery($this->root);
     }
     return $this->extensionDiscovery;
   }
@@ -700,7 +710,7 @@ protected function systemThemeList() {
   public function getThemeDirectories() {
     $dirs = array();
     foreach ($this->listInfo() as $name => $theme) {
-      $dirs[$name] = DRUPAL_ROOT . '/' . $theme->getPath();
+      $dirs[$name] = $this->root . '/' . $theme->getPath();
     }
     return $dirs;
   }
diff --git a/core/lib/Drupal/Core/FileTransfer/Form/FileTransferAuthorizeForm.php b/core/lib/Drupal/Core/FileTransfer/Form/FileTransferAuthorizeForm.php
index e163c043f1d2..12a0572695fa 100644
--- a/core/lib/Drupal/Core/FileTransfer/Form/FileTransferAuthorizeForm.php
+++ b/core/lib/Drupal/Core/FileTransfer/Form/FileTransferAuthorizeForm.php
@@ -10,12 +10,37 @@
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\Element;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Provides the file transfer authorization form.
  */
 class FileTransferAuthorizeForm extends FormBase {
 
+  /**
+   * The app root.
+   *
+   * @var string
+   */
+  protected  $root;
+
+  /**
+   * Constructs a new FileTransferAuthorizeForm object.
+   *
+   * @param string $root
+   *   The app root.
+   */
+  public function __construct($root) {
+    $this->root = $root;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static ($container->get('app.root'));
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -241,7 +266,7 @@ protected function getFiletransfer($backend, $settings = array()) {
     if (!empty($_SESSION['authorize_filetransfer_info'][$backend])) {
       $backend_info = $_SESSION['authorize_filetransfer_info'][$backend];
       if (class_exists($backend_info['class'])) {
-        $filetransfer = $backend_info['class']::factory(DRUPAL_ROOT, $settings);
+        $filetransfer = $backend_info['class']::factory($this->root, $settings);
       }
     }
     return $filetransfer;
@@ -316,7 +341,7 @@ protected function runOperation($filetransfer) {
     $operation = $_SESSION['authorize_operation'];
     unset($_SESSION['authorize_operation']);
 
-    require_once DRUPAL_ROOT . '/' . $operation['file'];
+    require_once $this->root . '/' . $operation['file'];
     call_user_func_array($operation['callback'], array_merge(array($filetransfer), $operation['arguments']));
   }
 
diff --git a/core/lib/Drupal/Core/Form/FormCache.php b/core/lib/Drupal/Core/Form/FormCache.php
index 9eba0426ebf3..ea38fd2c60a3 100644
--- a/core/lib/Drupal/Core/Form/FormCache.php
+++ b/core/lib/Drupal/Core/Form/FormCache.php
@@ -81,9 +81,18 @@ class FormCache implements FormCacheInterface {
    */
   protected $requestPolicy;
 
+  /**
+   * The app root.
+   *
+   * @var string
+   */
+  protected $root;
+
   /**
    * Constructs a new FormCache.
    *
+   * @param string $root
+   *   The app root.
    * @param \Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface $key_value_expirable_factory
    *   The key value expirable factory, used to create key value expirable
    *   stores for the form cache and form state cache.
@@ -102,7 +111,8 @@ class FormCache implements FormCacheInterface {
    * @param \Drupal\Core\PageCache\RequestPolicyInterface $request_policy
    *   A policy rule determining the cacheability of a request.
    */
-  public function __construct(KeyValueExpirableFactoryInterface $key_value_expirable_factory, ModuleHandlerInterface $module_handler, AccountInterface $current_user, CsrfTokenGenerator $csrf_token, LoggerInterface $logger, ConfigFactoryInterface $config_factory, RequestStack $request_stack, RequestPolicyInterface $request_policy) {
+  public function __construct($root, KeyValueExpirableFactoryInterface $key_value_expirable_factory, ModuleHandlerInterface $module_handler, AccountInterface $current_user, CsrfTokenGenerator $csrf_token, LoggerInterface $logger, ConfigFactoryInterface $config_factory, RequestStack $request_stack, RequestPolicyInterface $request_policy) {
+    $this->root = $root;
     $this->keyValueExpirableFactory = $key_value_expirable_factory;
     $this->moduleHandler = $module_handler;
     $this->currentUser = $current_user;
@@ -160,7 +170,7 @@ protected function loadCachedFormState($form_build_id, FormStateInterface $form_
           $this->moduleHandler->loadInclude($file['module'], $file['type'], $file['name']);
         }
         elseif (file_exists($file)) {
-          require_once DRUPAL_ROOT . '/' . $file;
+          require_once $this->root . '/' . $file;
         }
       }
       // Retrieve the list of previously known safe strings and store it for
diff --git a/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php b/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php
index db3fd15ba886..05c9c23f76f3 100644
--- a/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php
+++ b/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php
@@ -48,9 +48,18 @@ class SiteConfigureForm extends FormBase {
    */
   protected $countryManager;
 
+  /**
+   * The app root.
+   *
+   * @var string
+   */
+  protected $root;
+
   /**
    * Constructs a new SiteConfigureForm.
    *
+   * @param string $root
+   *   The app root.
    * @param \Drupal\user\UserStorageInterface $user_storage
    *   The user storage.
    * @param \Drupal\Core\State\StateInterface $state
@@ -60,7 +69,8 @@ class SiteConfigureForm extends FormBase {
    * @param \Drupal\Core\Locale\CountryManagerInterface $country_manager
    *   The country manager.
    */
-  public function __construct(UserStorageInterface $user_storage, StateInterface $state, ModuleHandlerInterface $module_handler, CountryManagerInterface $country_manager) {
+  public function __construct($root, UserStorageInterface $user_storage, StateInterface $state, ModuleHandlerInterface $module_handler, CountryManagerInterface $country_manager) {
+    $this->root = $root;
     $this->userStorage = $user_storage;
     $this->state = $state;
     $this->moduleHandler = $module_handler;
@@ -72,6 +82,7 @@ public function __construct(UserStorageInterface $user_storage, StateInterface $
    */
   public static function create(ContainerInterface $container) {
     return new static(
+      $container->get('app.root'),
       $container->get('entity.manager')->getStorage('user'),
       $container->get('state'),
       $container->get('module_handler'),
@@ -103,7 +114,7 @@ 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'))) {
+    if (empty($post_params) && (!drupal_verify_install_file($this->root . '/' . $settings_file, FILE_EXIST|FILE_READABLE|FILE_NOT_WRITABLE) || !drupal_verify_install_file($this->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');
     }
 
diff --git a/core/lib/Drupal/Core/Site/Settings.php b/core/lib/Drupal/Core/Site/Settings.php
index def307fd0cbe..4fe80b341e6d 100644
--- a/core/lib/Drupal/Core/Site/Settings.php
+++ b/core/lib/Drupal/Core/Site/Settings.php
@@ -85,6 +85,8 @@ public static function getAll() {
   /**
    * Bootstraps settings.php and the Settings singleton.
    *
+   * @param string $app_root
+   *   The app root.
    * @param string $site_path
    *   The current site path.
    * @param \Composer\Autoload\ClassLoader $class_loader
@@ -94,7 +96,7 @@ public static function getAll() {
    *
    * @see default.settings.php
    */
-  public static function initialize($site_path, &$class_loader) {
+  public static function initialize($app_root, $site_path, &$class_loader) {
     // Export these settings.php variables to the global namespace.
     global $base_url, $cookie_domain, $config_directories, $config;
     $settings = array();
@@ -102,8 +104,8 @@ public static function initialize($site_path, &$class_loader) {
     $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';
+    if (is_readable($app_root . '/' . $site_path . '/settings.php')) {
+      require $app_root . '/' . $site_path . '/settings.php';
     }
 
     // Initialize Database.
diff --git a/core/lib/Drupal/Core/Template/TwigEnvironment.php b/core/lib/Drupal/Core/Template/TwigEnvironment.php
index 97341ac597b8..371627706b7f 100644
--- a/core/lib/Drupal/Core/Template/TwigEnvironment.php
+++ b/core/lib/Drupal/Core/Template/TwigEnvironment.php
@@ -33,14 +33,17 @@ class TwigEnvironment extends \Twig_Environment {
   /**
    * Constructs a TwigEnvironment object and stores cache and storage
    * internally.
+   *
+   * @param string $root
+   *   The app root;
    */
-  public function __construct(\Twig_LoaderInterface $loader = NULL, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, $options = array()) {
+  public function __construct($root, \Twig_LoaderInterface $loader = NULL, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, $options = array()) {
     // @todo Pass as arguments from the DIC.
     $this->cache_object = \Drupal::cache();
 
     // Ensure that twig.engine is loaded, given that it is needed to render a
     // template because functions like twig_drupal_escape_filter are called.
-    require_once DRUPAL_ROOT . '/core/themes/engines/twig/twig.engine';
+    require_once $root . '/core/themes/engines/twig/twig.engine';
 
     // Set twig path namespace for themes and modules.
     $namespaces = array();
diff --git a/core/lib/Drupal/Core/Test/TestRunnerKernel.php b/core/lib/Drupal/Core/Test/TestRunnerKernel.php
index 8829113357a2..9fa7430c35ac 100644
--- a/core/lib/Drupal/Core/Test/TestRunnerKernel.php
+++ b/core/lib/Drupal/Core/Test/TestRunnerKernel.php
@@ -42,8 +42,8 @@ public function __construct($environment, $class_loader) {
       'simpletest' => 0,
     );
     $this->moduleData = array(
-      'system' => new Extension('module', 'core/modules/system/system.info.yml', 'system.module'),
-      'simpletest' => new Extension('module', 'core/modules/simpletest/simpletest.info.yml', 'simpletest.module'),
+      'system' => new Extension(DRUPAL_ROOT, 'module', 'core/modules/system/system.info.yml', 'system.module'),
+      'simpletest' => new Extension(DRUPAL_ROOT, 'module', 'core/modules/simpletest/simpletest.info.yml', 'simpletest.module'),
     );
   }
 
diff --git a/core/lib/Drupal/Core/Theme/Registry.php b/core/lib/Drupal/Core/Theme/Registry.php
index 8c9efb30a82a..ff4f678d72df 100644
--- a/core/lib/Drupal/Core/Theme/Registry.php
+++ b/core/lib/Drupal/Core/Theme/Registry.php
@@ -129,9 +129,18 @@ class Registry implements DestructableInterface {
    */
   protected $themeName;
 
+  /**
+   * The app root.
+   *
+   * @var string
+   */
+  protected $root;
+
   /**
    * Constructs a \Drupal\Core\\Theme\Registry object.
    *
+   * @param string $root
+   *   The app root.
    * @param \Drupal\Core\Cache\CacheBackendInterface $cache
    *   The cache backend interface to use for the complete theme registry data.
    * @param \Drupal\Core\Lock\LockBackendInterface $lock
@@ -141,7 +150,8 @@ class Registry implements DestructableInterface {
    * @param string $theme_name
    *   (optional) The name of the theme for which to construct the registry.
    */
-  public function __construct(CacheBackendInterface $cache, LockBackendInterface $lock, ModuleHandlerInterface $module_handler, $theme_name = NULL) {
+  public function __construct($root, CacheBackendInterface $cache, LockBackendInterface $lock, ModuleHandlerInterface $module_handler, $theme_name = NULL) {
+    $this->root = $root;
     $this->cache = $cache;
     $this->lock = $lock;
     $this->moduleHandler = $module_handler;
@@ -180,14 +190,14 @@ protected function init($theme_name = NULL) {
         $ancestor = $themes[$ancestor]->base_theme;
         $this->baseThemes[] = $themes[$ancestor];
         if (!empty($themes[$ancestor]->owner)) {
-          include_once DRUPAL_ROOT . '/' . $themes[$ancestor]->owner;
+          include_once $this->root . '/' . $themes[$ancestor]->owner;
         }
       }
       $this->baseThemes = array_reverse($this->baseThemes);
 
       if (isset($this->theme->engine)) {
         $this->engine = $this->theme->engine;
-        include_once DRUPAL_ROOT . '/' . $this->theme->owner;
+        include_once $this->root . '/' . $this->theme->owner;
         if (function_exists($this->theme->engine . '_init')) {
           foreach ($this->baseThemes as $base) {
             call_user_func($this->theme->engine . '_init', $base);
@@ -444,7 +454,7 @@ protected function processExtension(&$cache, $name, $type, $theme, $path) {
         if (isset($info['file'])) {
           $include_file = isset($info['path']) ? $info['path'] : $path;
           $include_file .= '/' . $info['file'];
-          include_once DRUPAL_ROOT . '/' . $include_file;
+          include_once $this->root . '/' . $include_file;
           $result[$hook]['includes'][] = $include_file;
         }
 
diff --git a/core/lib/Drupal/Core/Theme/ThemeInitialization.php b/core/lib/Drupal/Core/Theme/ThemeInitialization.php
index d4e1d952a238..bbe5cc763610 100644
--- a/core/lib/Drupal/Core/Theme/ThemeInitialization.php
+++ b/core/lib/Drupal/Core/Theme/ThemeInitialization.php
@@ -31,15 +31,25 @@ class ThemeInitialization implements ThemeInitializationInterface {
    */
   protected $state;
 
+  /**
+   * The app root.
+   *
+   * @var string
+   */
+  protected $root;
+
   /**
    * Constructs a new ThemeInitialization object.
    *
+   * @param string $root
+   *   The app root.
    * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
    *   The theme handler.
    * @param \Drupal\Core\State\StateInterface $state
    *   The state.
    */
-  public function __construct(ThemeHandlerInterface $theme_handler, StateInterface $state) {
+  public function __construct($root, ThemeHandlerInterface $theme_handler, StateInterface $state) {
+    $this->root = $root;
     $this->themeHandler = $theme_handler;
     $this->state = $state;
   }
@@ -77,7 +87,7 @@ public function getActiveThemeByName($theme_name) {
       $theme_name = 'core';
       // /core/core.info.yml does not actually exist, but is required because
       // Extension expects a pathname.
-      $active_theme = $this->getActiveTheme(new Extension('theme', 'core/core.info.yml'));
+      $active_theme = $this->getActiveTheme(new Extension($this->root, 'theme', 'core/core.info.yml'));
 
       // Early-return and do not set state, because the initialized $theme_name
       // differs from the original $theme_name.
@@ -105,7 +115,7 @@ public function loadActiveTheme(ActiveTheme $active_theme) {
     // Initialize the theme.
     if ($theme_engine = $active_theme->getEngine()) {
       // Include the engine.
-      include_once DRUPAL_ROOT . '/' . $active_theme->getOwner();
+      include_once $this->root . '/' . $active_theme->getOwner();
 
       if (function_exists($theme_engine . '_init')) {
         foreach ($active_theme->getBaseThemes() as $base) {
@@ -119,17 +129,17 @@ public function loadActiveTheme(ActiveTheme $active_theme) {
       foreach ($active_theme->getBaseThemes() as $base) {
         // Include the theme file or the engine.
         if ($base->getOwner()) {
-          include_once DRUPAL_ROOT . '/' . $base->getOwner();
+          include_once $this->root . '/' . $base->getOwner();
         }
       }
       // and our theme gets one too.
       if ($active_theme->getOwner()) {
-        include_once DRUPAL_ROOT . '/' . $active_theme->getOwner();
+        include_once $this->root . '/' . $active_theme->getOwner();
       }
     }
 
     // Always include Twig as the default theme engine.
-    include_once DRUPAL_ROOT . '/core/themes/engines/twig/twig.engine';
+    include_once $this->root . '/core/themes/engines/twig/twig.engine';
   }
 
   /**
diff --git a/core/modules/block/tests/src/Unit/Menu/BlockLocalTasksTest.php b/core/modules/block/tests/src/Unit/Menu/BlockLocalTasksTest.php
index b1a84a4a41c9..fcfeec8e3fc9 100644
--- a/core/modules/block/tests/src/Unit/Menu/BlockLocalTasksTest.php
+++ b/core/modules/block/tests/src/Unit/Menu/BlockLocalTasksTest.php
@@ -49,6 +49,7 @@ protected function setUp() {
     $container = new ContainerBuilder();
     $container->set('config.factory', $config_factory);
     $container->set('theme_handler', $theme_handler);
+    $container->set('app.root', $this->root);
     \Drupal::setContainer($container);
   }
 
diff --git a/core/modules/ckeditor/src/Plugin/Editor/CKEditor.php b/core/modules/ckeditor/src/Plugin/Editor/CKEditor.php
index 07627286ac96..41259d5bb3f3 100644
--- a/core/modules/ckeditor/src/Plugin/Editor/CKEditor.php
+++ b/core/modules/ckeditor/src/Plugin/Editor/CKEditor.php
@@ -323,7 +323,7 @@ public function getLangcodes() {
     if (empty($langcodes)) {
       $langcodes = array();
       // Collect languages included with CKEditor based on file listing.
-      $ckeditor_languages = new \GlobIterator(DRUPAL_ROOT . '/core/assets/vendor/ckeditor/lang/*.js');
+      $ckeditor_languages = new \GlobIterator(\Drupal::root() . '/core/assets/vendor/ckeditor/lang/*.js');
       foreach ($ckeditor_languages as $language_file) {
         $langcode = $language_file->getBasename('.js');
         $langcodes[$langcode] = $langcode;
diff --git a/core/modules/color/color.module b/core/modules/color/color.module
index 92e21362f271..138385c5ee1d 100644
--- a/core/modules/color/color.module
+++ b/core/modules/color/color.module
@@ -150,7 +150,7 @@ function color_get_info($theme) {
   }
 
   $path = drupal_get_path('theme', $theme);
-  $file = DRUPAL_ROOT . '/' . $path . '/color/color.inc';
+  $file = \Drupal::root() . '/' . $path . '/color/color.inc';
   if ($path && file_exists($file)) {
     include $file;
     // Add in default values.
@@ -308,7 +308,7 @@ function template_preprocess_color_scheme_form(&$variables) {
   $form['scheme']['#attached']['js'][$preview_js_path] = array('weight' => -1);
 
   // Attempt to load preview HTML if the theme provides it.
-  $preview_html_path = DRUPAL_ROOT . '/' . (isset($info['preview_html']) ? drupal_get_path('theme', $theme) . '/' . $info['preview_html'] : drupal_get_path('module', 'color') . '/preview.html');
+  $preview_html_path = \Drupal::root() . '/' . (isset($info['preview_html']) ? drupal_get_path('theme', $theme) . '/' . $info['preview_html'] : drupal_get_path('module', 'color') . '/preview.html');
   $variables['html_preview'] = SafeMarkup::set(file_get_contents($preview_html_path));
 }
 
diff --git a/core/modules/config/tests/config_test/src/TestInstallStorage.php b/core/modules/config/tests/config_test/src/TestInstallStorage.php
index f85de95ba63f..e4b38644ef23 100644
--- a/core/modules/config/tests/config_test/src/TestInstallStorage.php
+++ b/core/modules/config/tests/config_test/src/TestInstallStorage.php
@@ -25,7 +25,7 @@ protected function getAllFolders() {
     if (!isset($this->folders)) {
       $this->folders = $this->getComponentNames('core', array('core'));
       // @todo Refactor getComponentNames() to use the extension list directly.
-      $listing = new ExtensionDiscovery();
+      $listing = new ExtensionDiscovery(\Drupal::root());
       $listing->setProfileDirectories(array());
       $this->folders += $this->getComponentNames('profile', array_keys($listing->scan('profile')));
       $this->folders += $this->getComponentNames('module', array_keys($listing->scan('module')));
diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module
index a14d730ac80a..6d558fee6cd0 100644
--- a/core/modules/filter/filter.module
+++ b/core/modules/filter/filter.module
@@ -787,7 +787,7 @@ function _filter_html_image_secure_process($text) {
   $base_path_length = Unicode::strlen($base_path);
 
   // Find the directory on the server where index.php resides.
-  $local_dir = DRUPAL_ROOT . '/';
+  $local_dir = \Drupal::root() . '/';
 
   $html_dom = Html::load($text);
   $images = $html_dom->getElementsByTagName('img');
diff --git a/core/modules/image/src/Tests/ImageItemTest.php b/core/modules/image/src/Tests/ImageItemTest.php
index e0a3b3678cef..4f7dd155c934 100644
--- a/core/modules/image/src/Tests/ImageItemTest.php
+++ b/core/modules/image/src/Tests/ImageItemTest.php
@@ -55,7 +55,7 @@ protected function setUp() {
       'field_name' => 'image_test',
       'bundle' => 'entity_test',
     ))->save();
-    file_unmanaged_copy(DRUPAL_ROOT . '/core/misc/druplicon.png', 'public://example.jpg');
+    file_unmanaged_copy(\Drupal::root() . '/core/misc/druplicon.png', 'public://example.jpg');
     $this->image = entity_create('file', array(
       'uri' => 'public://example.jpg',
     ));
@@ -88,7 +88,7 @@ public function testImageItem() {
     $this->assertEqual($entity->image_test->entity->uuid(), $this->image->uuid());
 
     // Make sure the computed entity reflects updates to the referenced file.
-    file_unmanaged_copy(DRUPAL_ROOT . '/core/misc/feed.png', 'public://example-2.jpg');
+    file_unmanaged_copy(\Drupal::root() . '/core/misc/feed.png', 'public://example-2.jpg');
     $image2 = entity_create('file', array(
       'uri' => 'public://example-2.jpg',
     ));
diff --git a/core/modules/image/src/Tests/ImageThemeFunctionTest.php b/core/modules/image/src/Tests/ImageThemeFunctionTest.php
index 43a6338621bf..06e9710964eb 100644
--- a/core/modules/image/src/Tests/ImageThemeFunctionTest.php
+++ b/core/modules/image/src/Tests/ImageThemeFunctionTest.php
@@ -50,7 +50,7 @@ protected function setUp() {
       'field_name' => 'image_test',
       'bundle' => 'entity_test',
     ))->save();
-    file_unmanaged_copy(DRUPAL_ROOT . '/core/misc/druplicon.png', 'public://example.jpg');
+    file_unmanaged_copy(\Drupal::root() . '/core/misc/druplicon.png', 'public://example.jpg');
     $this->image = entity_create('file', array(
       'uri' => 'public://example.jpg',
     ));
diff --git a/core/modules/rdf/src/Tests/StandardProfileTest.php b/core/modules/rdf/src/Tests/StandardProfileTest.php
index 29e980445478..05c2fac6b16e 100644
--- a/core/modules/rdf/src/Tests/StandardProfileTest.php
+++ b/core/modules/rdf/src/Tests/StandardProfileTest.php
@@ -131,7 +131,7 @@ protected function setUp() {
     $this->term->save();
 
     // Create image.
-    file_unmanaged_copy(DRUPAL_ROOT . '/core/misc/druplicon.png', 'public://example.jpg');
+    file_unmanaged_copy(\Drupal::root() . '/core/misc/druplicon.png', 'public://example.jpg');
     $this->image = entity_create('file', array('uri' => 'public://example.jpg'));
     $this->image->save();
 
diff --git a/core/modules/search/src/Tests/SearchSimplifyTest.php b/core/modules/search/src/Tests/SearchSimplifyTest.php
index d1c2774233df..45944597ab45 100644
--- a/core/modules/search/src/Tests/SearchSimplifyTest.php
+++ b/core/modules/search/src/Tests/SearchSimplifyTest.php
@@ -25,7 +25,7 @@ function testSearchSimplifyUnicode() {
     // their own lines).  So the even-numbered lines should simplify to nothing,
     // and the odd-numbered lines we need to split into shorter chunks and
     // verify that simplification doesn't lose any characters.
-    $input = file_get_contents(DRUPAL_ROOT . '/core/modules/search/tests/UnicodeTest.txt');
+    $input = file_get_contents(\Drupal::root() . '/core/modules/search/tests/UnicodeTest.txt');
     $basestrings = explode(chr(10), $input);
     $strings = array();
     foreach ($basestrings as $key => $string) {
diff --git a/core/modules/simpletest/simpletest.install b/core/modules/simpletest/simpletest.install
index 4e5e01b5e5b0..9d8e3c76ecba 100644
--- a/core/modules/simpletest/simpletest.install
+++ b/core/modules/simpletest/simpletest.install
@@ -66,17 +66,17 @@ function simpletest_requirements($phase) {
   }
 
   $site_directory = 'sites/simpletest';
-  if (!drupal_verify_install_file(DRUPAL_ROOT . '/' . $site_directory, FILE_EXIST|FILE_READABLE|FILE_WRITABLE|FILE_EXECUTABLE, 'dir')) {
+  if (!drupal_verify_install_file(\Drupal::root() . '/' . $site_directory, FILE_EXIST|FILE_READABLE|FILE_WRITABLE|FILE_EXECUTABLE, 'dir')) {
     $requirements['simpletest_site_directory'] = array(
       'title' => t('Simpletest site directory'),
-      'value' => is_dir(DRUPAL_ROOT . '/' . $site_directory) ? t('Not writable') : t('Missing'),
+      'value' => is_dir(\Drupal::root() . '/' . $site_directory) ? t('Not writable') : t('Missing'),
       'severity' => REQUIREMENT_ERROR,
       'description' => t('The testing framework requires the !sites-simpletest directory to exist and be writable in order to run tests.', array(
         '!sites-simpletest' => '<code>./' . String::checkPlain($site_directory) . '</code>',
       )),
     );
   }
-  elseif (!file_save_htaccess(DRUPAL_ROOT . '/' . $site_directory, FALSE)) {
+  elseif (!file_save_htaccess(\Drupal::root() . '/' . $site_directory, FALSE)) {
     $requirements['simpletest_site_directory'] = array(
       'title' => t('Simpletest site directory'),
       'value' => t('Not protected'),
diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module
index 5471d7e98664..feeffd43dd62 100644
--- a/core/modules/simpletest/simpletest.module
+++ b/core/modules/simpletest/simpletest.module
@@ -221,7 +221,7 @@ function simpletest_phpunit_xml_filepath($test_id) {
  *   The path to core's phpunit.xml.dist configuration file.
  */
 function simpletest_phpunit_configuration_filepath() {
-  return DRUPAL_ROOT . '/core/phpunit.xml.dist';
+  return \Drupal::root() . '/core/phpunit.xml.dist';
 }
 
 /**
@@ -266,7 +266,7 @@ function simpletest_phpunit_run_command(array $unescaped_test_classnames, $phpun
   // Need to change directories before running the command so that we can use
   // relative paths in the configuration file's exclusions.
   $old_cwd = getcwd();
-  chdir(DRUPAL_ROOT . "/core");
+  chdir(\Drupal::root() . "/core");
 
   // exec in a subshell so that the environment is isolated when running tests
   // via the simpletest UI.
@@ -287,10 +287,10 @@ function simpletest_phpunit_command() {
   if (substr(PHP_OS, 0, 3) == 'WIN') {
     $php_executable_finder = new PhpExecutableFinder();
     $php = $php_executable_finder->find();
-    $phpunit_bin = escapeshellarg($php) . " -f " . escapeshellarg(DRUPAL_ROOT . "/core/vendor/phpunit/phpunit/composer/bin/phpunit") . " --";
+    $phpunit_bin = escapeshellarg($php) . " -f " . escapeshellarg(\Drupal::root() . "/core/vendor/phpunit/phpunit/composer/bin/phpunit") . " --";
   }
   else {
-    $phpunit_bin = DRUPAL_ROOT . "/core/vendor/bin/phpunit";
+    $phpunit_bin = \Drupal::root() . "/core/vendor/bin/phpunit";
   }
   return $phpunit_bin;
 }
diff --git a/core/modules/simpletest/src/InstallerTestBase.php b/core/modules/simpletest/src/InstallerTestBase.php
index 90f318bbdd3a..92af365291a3 100644
--- a/core/modules/simpletest/src/InstallerTestBase.php
+++ b/core/modules/simpletest/src/InstallerTestBase.php
@@ -117,6 +117,8 @@ protected function setUp() {
     $this->container
       ->register('string_translation', 'Drupal\Core\StringTranslation\TranslationManager')
       ->addArgument(new Reference('language_manager'));
+    $this->container
+      ->set('app.root', DRUPAL_ROOT);
     \Drupal::setContainer($this->container);
 
     $this->drupalGet($GLOBALS['base_url'] . '/core/install.php');
@@ -138,8 +140,8 @@ protected function setUp() {
 
     // Import new settings.php written by the installer.
     $request = Request::createFromGlobals();
-    $class_loader = require DRUPAL_ROOT . '/core/vendor/autoload.php';
-    Settings::initialize(DrupalKernel::findSitePath($request), $class_loader);
+    $class_loader = require $this->container->get('app.root') . '/core/vendor/autoload.php';
+    Settings::initialize($this->container->get('app.root'), DrupalKernel::findSitePath($request), $class_loader);
     foreach ($GLOBALS['config_directories'] as $type => $path) {
       $this->configDirectories[$type] = $path;
     }
@@ -150,7 +152,7 @@ protected function setUp() {
     // directory has to be writable.
     // WebTestBase::tearDown() will delete the entire test site directory.
     // Not using File API; a potential error must trigger a PHP warning.
-    chmod(DRUPAL_ROOT . '/' . $this->siteDirectory, 0777);
+    chmod($this->container->get('app.root') . '/' . $this->siteDirectory, 0777);
     $this->kernel = DrupalKernel::createFromRequest($request, $class_loader, 'prod', FALSE);
     $this->kernel->prepareLegacyRequest($request);
     $this->container = $this->kernel->getContainer();
diff --git a/core/modules/simpletest/src/TestDiscovery.php b/core/modules/simpletest/src/TestDiscovery.php
index 2c86907a5984..50e19f064252 100644
--- a/core/modules/simpletest/src/TestDiscovery.php
+++ b/core/modules/simpletest/src/TestDiscovery.php
@@ -439,7 +439,7 @@ public static function parseTestClassAnnotations(\ReflectionClass $class) {
    *   An array of Extension objects, keyed by extension name.
    */
   protected function getExtensions() {
-    $listing = new ExtensionDiscovery();
+    $listing = new ExtensionDiscovery(DRUPAL_ROOT);
     // Ensure that tests in all profiles are discovered.
     $listing->setProfileDirectories(array());
     $extensions = $listing->scan('module', TRUE);
diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php
index a8568d698a79..260d983f3a0b 100644
--- a/core/modules/simpletest/src/WebTestBase.php
+++ b/core/modules/simpletest/src/WebTestBase.php
@@ -836,14 +836,14 @@ protected function setUp() {
     // bootstrap into DRUPAL_BOOTSTRAP_CONFIGURATION (again). Hence, we have to
     // reload the newly written custom settings.php manually.
     $class_loader = require DRUPAL_ROOT . '/core/vendor/autoload.php';
-    Settings::initialize($directory, $class_loader);
+    Settings::initialize(DRUPAL_ROOT, $directory, $class_loader);
 
     // Execute the non-interactive installer.
     require_once DRUPAL_ROOT . '/core/includes/install.core.inc';
     install_drupal($parameters);
 
     // Import new settings.php written by the installer.
-    Settings::initialize($directory, $class_loader);
+    Settings::initialize(DRUPAL_ROOT, $directory, $class_loader);
     foreach ($GLOBALS['config_directories'] as $type => $path) {
       $this->configDirectories[$type] = $path;
     }
diff --git a/core/modules/system/src/Controller/BatchController.php b/core/modules/system/src/Controller/BatchController.php
index 31f2b5405ace..ccafd85fd9f6 100644
--- a/core/modules/system/src/Controller/BatchController.php
+++ b/core/modules/system/src/Controller/BatchController.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\system\Controller;
 
+use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
@@ -14,7 +16,33 @@
 /**
  * Controller routines for batch routes.
  */
-class BatchController {
+class BatchController implements ContainerInjectionInterface {
+
+  /**
+   * The app root.
+   *
+   * @var string
+   */
+  protected $root;
+
+  /**
+   * Constructs a new BatchController.
+   *
+   * @param string $root
+   *   The app root.
+   */
+  public function __construct($root) {
+    $this->root = $root;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('app.root')
+    );
+  }
 
   /**
    * Returns a system batch page.
@@ -28,7 +56,7 @@ class BatchController {
    * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
    */
   public function batchPage(Request $request) {
-    require_once DRUPAL_ROOT . '/core/includes/batch.inc';
+    require_once $this->root . '/core/includes/batch.inc';
     $output = _batch_page($request);
 
     if ($output === FALSE) {
diff --git a/core/modules/system/src/Controller/DbUpdateController.php b/core/modules/system/src/Controller/DbUpdateController.php
index 2534301813c1..cfd31dd80065 100644
--- a/core/modules/system/src/Controller/DbUpdateController.php
+++ b/core/modules/system/src/Controller/DbUpdateController.php
@@ -69,15 +69,25 @@ class DbUpdateController extends ControllerBase {
   protected $entityDefinitionUpdateManager;
 
   /**
+<<<<<<< ours
    * The bare HTML page renderer.
    *
    * @var \Drupal\Core\Render\BareHtmlPageRendererInterface
    */
   protected $bareHtmlPageRenderer;
 
+  /**
+   * The app root.
+   *
+   * @var string
+   */
+  protected $root;
+
   /**
    * Constructs a new UpdateController.
    *
+   * @param string $root
+   *   The app root.
    * @param \Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface $key_value_expirable_factory
    *   The keyvalue expirable factory.
    * @param \Drupal\Core\Cache\CacheBackendInterface $cache
@@ -93,7 +103,8 @@ class DbUpdateController extends ControllerBase {
    * @param \Drupal\Core\Render\BareHtmlPageRendererInterface $bare_html_page_renderer
    *   The bare HTML page renderer.
    */
-  public function __construct(KeyValueExpirableFactoryInterface $key_value_expirable_factory, CacheBackendInterface $cache, StateInterface $state, ModuleHandlerInterface $module_handler, AccountInterface $account, EntityDefinitionUpdateManagerInterface $entity_definition_update_manager, BareHtmlPageRendererInterface $bare_html_page_renderer) {
+  public function __construct($root, KeyValueExpirableFactoryInterface $key_value_expirable_factory, CacheBackendInterface $cache, StateInterface $state, ModuleHandlerInterface $module_handler, AccountInterface $account, EntityDefinitionUpdateManagerInterface $entity_definition_update_manager, BareHtmlPageRendererInterface $bare_html_page_renderer) {
+    $this->root = $root;
     $this->keyValueExpirableFactory = $key_value_expirable_factory;
     $this->cache = $cache;
     $this->state = $state;
@@ -108,6 +119,7 @@ public function __construct(KeyValueExpirableFactoryInterface $key_value_expirab
    */
   public static function create(ContainerInterface $container) {
     return new static(
+      $container->get('app.root'),
       $container->get('keyvalue.expirable'),
       $container->get('cache.default'),
       $container->get('state'),
@@ -134,8 +146,8 @@ public static function create(ContainerInterface $container) {
    *   A response object object.
    */
   public function handle($op, Request $request) {
-    require_once DRUPAL_ROOT . '/core/includes/install.inc';
-    require_once DRUPAL_ROOT . '/core/includes/update.inc';
+    require_once $this->root . '/core/includes/install.inc';
+    require_once $this->root . '/core/includes/update.inc';
 
     drupal_load_updates();
     update_fix_compatibility();
@@ -175,7 +187,7 @@ public function handle($op, Request $request) {
 
         // Regular batch ops : defer to batch processing API.
         default:
-          require_once DRUPAL_ROOT . '/core/includes/batch.inc';
+          require_once $this->root . '/core/includes/batch.inc';
           $regions['sidebar_first'] = $this->updateTasksList('run');
           $output = _batch_page($request);
           break;
diff --git a/core/modules/system/src/Tests/Ajax/FormValuesTest.php b/core/modules/system/src/Tests/Ajax/FormValuesTest.php
index c4f1a7c52554..17e74f680f2d 100644
--- a/core/modules/system/src/Tests/Ajax/FormValuesTest.php
+++ b/core/modules/system/src/Tests/Ajax/FormValuesTest.php
@@ -59,6 +59,6 @@ function testSimpleAjaxFormValue() {
     }
     // The exceptions are expected. Do not interpret them as a test failure.
     // Not using File API; a potential error must trigger a PHP warning.
-    unlink(DRUPAL_ROOT . '/' . $this->siteDirectory . '/error.log');
+    unlink(\Drupal::root() . '/' . $this->siteDirectory . '/error.log');
   }
 }
diff --git a/core/modules/system/src/Tests/Common/SystemListingTest.php b/core/modules/system/src/Tests/Common/SystemListingTest.php
index fc1cebf5c818..6b2e1bb318f3 100644
--- a/core/modules/system/src/Tests/Common/SystemListingTest.php
+++ b/core/modules/system/src/Tests/Common/SystemListingTest.php
@@ -37,13 +37,13 @@ function testDirectoryPrecedence() {
     foreach ($expected_directories as $module => $directories) {
       foreach ($directories as $directory) {
         $filename = "$directory/$module/$module.info.yml";
-        $this->assertTrue(file_exists(DRUPAL_ROOT . '/' . $filename), format_string('@filename exists.', array('@filename' => $filename)));
+        $this->assertTrue(file_exists(\Drupal::root() . '/' . $filename), format_string('@filename exists.', array('@filename' => $filename)));
       }
     }
 
     // Now scan the directories and check that the files take precedence as
     // expected.
-    $listing = new ExtensionDiscovery();
+    $listing = new ExtensionDiscovery(\Drupal::root());
     $listing->setProfileDirectories(array('core/profiles/testing'));
     $files = $listing->scan('module');
     foreach ($expected_directories as $module => $directories) {
diff --git a/core/modules/system/src/Tests/FileTransfer/FileTransferTest.php b/core/modules/system/src/Tests/FileTransfer/FileTransferTest.php
index ef7a43a91c56..07ce6add22d2 100644
--- a/core/modules/system/src/Tests/FileTransfer/FileTransferTest.php
+++ b/core/modules/system/src/Tests/FileTransfer/FileTransferTest.php
@@ -25,7 +25,7 @@ class FileTransferTest extends WebTestBase {
 
   protected function setUp() {
     parent::setUp();
-    $this->testConnection = TestFileTransfer::factory(DRUPAL_ROOT, array('hostname' => $this->hostname, 'username' => $this->username, 'password' => $this->password, 'port' => $this->port));
+    $this->testConnection = TestFileTransfer::factory(\Drupal::root(), array('hostname' => $this->hostname, 'username' => $this->username, 'password' => $this->password, 'port' => $this->port));
   }
 
   function _getFakeModuleFiles() {
@@ -87,7 +87,7 @@ function testJail() {
 
     $gotit = TRUE;
     try {
-      $this->testConnection->copyDirectory($source, DRUPAL_ROOT . '/' . PublicStream::basePath());
+      $this->testConnection->copyDirectory($source, \Drupal::root() . '/' . PublicStream::basePath());
     }
     catch (FileTransferException $e) {
       $gotit = FALSE;
diff --git a/core/modules/system/src/Tests/Installer/InstallerLanguageDirectionTest.php b/core/modules/system/src/Tests/Installer/InstallerLanguageDirectionTest.php
index cd7bce5168cc..0c183d88bad7 100644
--- a/core/modules/system/src/Tests/Installer/InstallerLanguageDirectionTest.php
+++ b/core/modules/system/src/Tests/Installer/InstallerLanguageDirectionTest.php
@@ -28,8 +28,8 @@ class InstallerLanguageDirectionTest extends InstallerTestBase {
    */
   protected function setUpLanguage() {
     // Place a custom local translation in the translations directory.
-    mkdir(DRUPAL_ROOT . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
-    file_put_contents(DRUPAL_ROOT . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.ar.po', "msgid \"\"\nmsgstr \"\"\nmsgid \"Save and continue\"\nmsgstr \"Save and continue Arabic\"");
+    mkdir(\Drupal::root() . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
+    file_put_contents(\Drupal::root() . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.ar.po', "msgid \"\"\nmsgstr \"\"\nmsgid \"Save and continue\"\nmsgstr \"Save and continue Arabic\"");
 
     parent::setUpLanguage();
     // After selecting a different language than English, all following screens
diff --git a/core/modules/system/src/Tests/Installer/InstallerLanguagePageTest.php b/core/modules/system/src/Tests/Installer/InstallerLanguagePageTest.php
index 4c74ddcef396..ce573ba6985a 100644
--- a/core/modules/system/src/Tests/Installer/InstallerLanguagePageTest.php
+++ b/core/modules/system/src/Tests/Installer/InstallerLanguagePageTest.php
@@ -21,8 +21,8 @@ class InstallerLanguagePageTest extends InstallerTestBase {
    */
   protected function setUpLanguage() {
     // Place a custom local translation in the translations directory.
-    mkdir(DRUPAL_ROOT . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
-    touch(DRUPAL_ROOT . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.xoxo.po');
+    mkdir(\Drupal::root() . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
+    touch(\Drupal::root() . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.xoxo.po');
 
     // Check that all predefined languages show up with their native names.
     $this->drupalGet($GLOBALS['base_url'] . '/core/install.php');
diff --git a/core/modules/system/src/Tests/Installer/InstallerTest.php b/core/modules/system/src/Tests/Installer/InstallerTest.php
index 760a94270d4d..6d481236e1d8 100644
--- a/core/modules/system/src/Tests/Installer/InstallerTest.php
+++ b/core/modules/system/src/Tests/Installer/InstallerTest.php
@@ -26,7 +26,7 @@ public function testInstaller() {
     $this->assertText($this->root_user->getUsername());
 
     // Verify that the confirmation message appears.
-    require_once DRUPAL_ROOT . '/core/includes/install.inc';
+    require_once \Drupal::root() . '/core/includes/install.inc';
     $this->assertRaw(t('Congratulations, you installed @drupal!', array(
       '@drupal' => drupal_install_profile_distribution_name(),
     )));
diff --git a/core/modules/system/src/Tests/Installer/InstallerTranslationTest.php b/core/modules/system/src/Tests/Installer/InstallerTranslationTest.php
index abecc2a16e17..fb0a23610fd1 100644
--- a/core/modules/system/src/Tests/Installer/InstallerTranslationTest.php
+++ b/core/modules/system/src/Tests/Installer/InstallerTranslationTest.php
@@ -30,8 +30,8 @@ class InstallerTranslationTest extends InstallerTestBase {
    */
   protected function setUpLanguage() {
     // Place a custom local translation in the translations directory.
-    mkdir(DRUPAL_ROOT . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
-    file_put_contents(DRUPAL_ROOT . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.de.po', "msgid \"\"\nmsgstr \"\"\nmsgid \"Save and continue\"\nmsgstr \"Save and continue German\"");
+    mkdir(\Drupal::root() . '/' . $this->siteDirectory . '/files/translations', 0777, TRUE);
+    file_put_contents(\Drupal::root() . '/' . $this->siteDirectory . '/files/translations/drupal-8.0.0.de.po', "msgid \"\"\nmsgstr \"\"\nmsgid \"Save and continue\"\nmsgstr \"Save and continue German\"");
 
     parent::setUpLanguage();
     // After selecting a different language than English, all following screens
diff --git a/core/modules/system/src/Tests/Installer/InstallerTranslationVersionUnitTest.php b/core/modules/system/src/Tests/Installer/InstallerTranslationVersionUnitTest.php
index 882af17f941c..c458716ff137 100644
--- a/core/modules/system/src/Tests/Installer/InstallerTranslationVersionUnitTest.php
+++ b/core/modules/system/src/Tests/Installer/InstallerTranslationVersionUnitTest.php
@@ -19,7 +19,7 @@ class InstallerTranslationVersionUnitTest extends DrupalUnitTestBase {
 
   protected function setUp() {
     parent::setUp();
-    require_once DRUPAL_ROOT . '/core/includes/install.core.inc';
+    require_once \Drupal::root() . '/core/includes/install.core.inc';
   }
 
   /**
diff --git a/core/modules/system/src/Tests/PhpStorage/PhpStorageFactoryTest.php b/core/modules/system/src/Tests/PhpStorage/PhpStorageFactoryTest.php
index 166f3ff67d3f..bad4c2f7e397 100644
--- a/core/modules/system/src/Tests/PhpStorage/PhpStorageFactoryTest.php
+++ b/core/modules/system/src/Tests/PhpStorage/PhpStorageFactoryTest.php
@@ -59,7 +59,7 @@ public function testGetOverride() {
     $this->setSettings('test', array('directory' => NULL));
     $php = PhpStorageFactory::get('test');
     $this->assertTrue($php instanceof MockPhpStorage, 'An MockPhpStorage instance was returned from overridden settings.');
-    $this->assertIdentical(DRUPAL_ROOT . '/' . PublicStream::basePath() . '/php', $php->getConfigurationValue('directory'), 'Default file directory was used.');
+    $this->assertIdentical(\Drupal::root() . '/' . PublicStream::basePath() . '/php', $php->getConfigurationValue('directory'), 'Default file directory was used.');
 
     // Test that a default storage class is set if it's empty.
     $this->setSettings('test', array('class' => NULL));
diff --git a/core/modules/system/src/Tests/Plugin/Discovery/AnnotatedClassDiscoveryTest.php b/core/modules/system/src/Tests/Plugin/Discovery/AnnotatedClassDiscoveryTest.php
index 101dee6ebc10..6cca8f5255a7 100644
--- a/core/modules/system/src/Tests/Plugin/Discovery/AnnotatedClassDiscoveryTest.php
+++ b/core/modules/system/src/Tests/Plugin/Discovery/AnnotatedClassDiscoveryTest.php
@@ -59,7 +59,7 @@ protected function setUp() {
       ),
     );
 
-    $base_directory = DRUPAL_ROOT . '/core/modules/system/tests/modules/plugin_test/src';
+    $base_directory = \Drupal::root() . '/core/modules/system/tests/modules/plugin_test/src';
     $namespaces = new \ArrayObject(array('Drupal\plugin_test' => $base_directory));
 
     $this->discovery = new AnnotatedClassDiscovery('Plugin/plugin_test/fruit', $namespaces);
diff --git a/core/modules/system/src/Tests/Plugin/Discovery/CustomAnnotationClassDiscoveryTest.php b/core/modules/system/src/Tests/Plugin/Discovery/CustomAnnotationClassDiscoveryTest.php
index eb5285eaa0c5..890329cfa0fb 100644
--- a/core/modules/system/src/Tests/Plugin/Discovery/CustomAnnotationClassDiscoveryTest.php
+++ b/core/modules/system/src/Tests/Plugin/Discovery/CustomAnnotationClassDiscoveryTest.php
@@ -35,7 +35,7 @@ protected function setUp() {
       ),
     );
 
-    $base_directory = DRUPAL_ROOT . '/core/modules/system/tests/modules/plugin_test/src';
+    $base_directory = \Drupal::root() . '/core/modules/system/tests/modules/plugin_test/src';
     $root_namespaces = new \ArrayObject(array('Drupal\plugin_test' => $base_directory));
 
     $this->discovery = new AnnotatedClassDiscovery('Plugin/plugin_test/custom_annotation', $root_namespaces, 'Drupal\plugin_test\Plugin\Annotation\PluginExample');
diff --git a/core/modules/system/src/Tests/Plugin/Discovery/CustomDirectoryAnnotatedClassDiscoveryTest.php b/core/modules/system/src/Tests/Plugin/Discovery/CustomDirectoryAnnotatedClassDiscoveryTest.php
index 92a73f3b436a..39e7caf22345 100644
--- a/core/modules/system/src/Tests/Plugin/Discovery/CustomDirectoryAnnotatedClassDiscoveryTest.php
+++ b/core/modules/system/src/Tests/Plugin/Discovery/CustomDirectoryAnnotatedClassDiscoveryTest.php
@@ -73,7 +73,7 @@ protected function setUp() {
       ),
     );
 
-    $base_directory = DRUPAL_ROOT . '/core/modules/system/tests/modules/plugin_test/src';
+    $base_directory = \Drupal::root() . '/core/modules/system/tests/modules/plugin_test/src';
     $namespaces = new \ArrayObject(array('Drupal\plugin_test' => $base_directory));
 
     $this->discovery = new AnnotatedClassDiscovery('', $namespaces);
diff --git a/core/modules/system/src/Tests/Plugin/PluginTestBase.php b/core/modules/system/src/Tests/Plugin/PluginTestBase.php
index 0285312786b1..618c4ef86a81 100644
--- a/core/modules/system/src/Tests/Plugin/PluginTestBase.php
+++ b/core/modules/system/src/Tests/Plugin/PluginTestBase.php
@@ -47,7 +47,7 @@ protected function setUp() {
     //   as derivatives and ReflectionFactory.
     $this->testPluginManager = new TestPluginManager();
     $this->mockBlockManager = new MockBlockManager();
-    $module_handler = new ModuleHandler(array(), $this->container->get('kernel'), new MemoryBackend('plugin'), $this->container->get('event_dispatcher'));
+    $module_handler = new ModuleHandler(\Drupal::root(), array(), $this->container->get('kernel'), new MemoryBackend('plugin'));
     $this->defaultsTestPluginManager = new DefaultsTestPluginManager($module_handler);
 
     // The expected plugin definitions within each manager. Several tests assert
diff --git a/core/modules/system/src/Tests/RouteProcessor/RouteProcessorCurrentIntegrationTest.php b/core/modules/system/src/Tests/RouteProcessor/RouteProcessorCurrentIntegrationTest.php
index 2d530826c30b..f7691bfaec73 100644
--- a/core/modules/system/src/Tests/RouteProcessor/RouteProcessorCurrentIntegrationTest.php
+++ b/core/modules/system/src/Tests/RouteProcessor/RouteProcessorCurrentIntegrationTest.php
@@ -44,7 +44,7 @@ public function testProcessOutbound() {
     // Test request with subdir on homepage.
     $server = [
       'SCRIPT_NAME' => '/subdir/index.php',
-      'SCRIPT_FILENAME' => DRUPAL_ROOT . '/index.php',
+      'SCRIPT_FILENAME' => \Drupal::root() . '/index.php',
       'SERVER_NAME' => 'http://www.example.com',
     ];
     $request = Request::create('/subdir', 'GET', [], [], [], $server);
@@ -58,7 +58,7 @@ public function testProcessOutbound() {
     // Test request with subdir on other page.
     $server = [
       'SCRIPT_NAME' => '/subdir/index.php',
-      'SCRIPT_FILENAME' => DRUPAL_ROOT . '/index.php',
+      'SCRIPT_FILENAME' => \Drupal::root() . '/index.php',
       'SERVER_NAME' => 'http://www.example.com',
     ];
     $request = Request::create('/subdir/node/add', 'GET', [], [], [], $server);
@@ -72,7 +72,7 @@ public function testProcessOutbound() {
     // Test request without subdir on the homepage.
     $server = [
       'SCRIPT_NAME' => '/index.php',
-      'SCRIPT_FILENAME' => DRUPAL_ROOT . '/index.php',
+      'SCRIPT_FILENAME' => \Drupal::root() . '/index.php',
       'SERVER_NAME' => 'http://www.example.com',
     ];
     $request = Request::create('/', 'GET', [], [], [], $server);
@@ -86,7 +86,7 @@ public function testProcessOutbound() {
     // Test request without subdir on other page.
     $server = [
       'SCRIPT_NAME' => '/index.php',
-      'SCRIPT_FILENAME' => DRUPAL_ROOT . '/index.php',
+      'SCRIPT_FILENAME' => \Drupal::root() . '/index.php',
       'SERVER_NAME' => 'http://www.example.com',
     ];
     $request = Request::create('/node/add', 'GET', [], [], [], $server);
diff --git a/core/modules/system/src/Tests/RouteProcessor/RouteProcessorNoneIntegrationTest.php b/core/modules/system/src/Tests/RouteProcessor/RouteProcessorNoneIntegrationTest.php
index 1089498cc297..6a3ca0561764 100644
--- a/core/modules/system/src/Tests/RouteProcessor/RouteProcessorNoneIntegrationTest.php
+++ b/core/modules/system/src/Tests/RouteProcessor/RouteProcessorNoneIntegrationTest.php
@@ -44,7 +44,7 @@ public function testProcessOutbound() {
     // Test request with subdir on homepage.
     $server = [
       'SCRIPT_NAME' => '/subdir/index.php',
-      'SCRIPT_FILENAME' => DRUPAL_ROOT . '/index.php',
+      'SCRIPT_FILENAME' => \Drupal::root() . '/index.php',
       'SERVER_NAME' => 'http://www.example.com',
     ];
     $request = Request::create('/subdir', 'GET', [], [], [], $server);
@@ -59,7 +59,7 @@ public function testProcessOutbound() {
     // Test request with subdir on other page.
     $server = [
       'SCRIPT_NAME' => '/subdir/index.php',
-      'SCRIPT_FILENAME' => DRUPAL_ROOT . '/index.php',
+      'SCRIPT_FILENAME' => \Drupal::root() . '/index.php',
       'SERVER_NAME' => 'http://www.example.com',
     ];
     $request = Request::create('/subdir/node/add', 'GET', [], [], [], $server);
@@ -74,7 +74,7 @@ public function testProcessOutbound() {
     // Test request without subdir on the homepage.
     $server = [
       'SCRIPT_NAME' => '/index.php',
-      'SCRIPT_FILENAME' => DRUPAL_ROOT . '/index.php',
+      'SCRIPT_FILENAME' => \Drupal::root() . '/index.php',
       'SERVER_NAME' => 'http://www.example.com',
     ];
     $request = Request::create('/', 'GET', [], [], [], $server);
@@ -89,7 +89,7 @@ public function testProcessOutbound() {
     // Test request without subdir on other page.
     $server = [
       'SCRIPT_NAME' => '/index.php',
-      'SCRIPT_FILENAME' => DRUPAL_ROOT . '/index.php',
+      'SCRIPT_FILENAME' => \Drupal::root() . '/index.php',
       'SERVER_NAME' => 'http://www.example.com',
     ];
     $request = Request::create('/node/add', 'GET', [], [], [], $server);
diff --git a/core/modules/system/src/Tests/System/ErrorHandlerTest.php b/core/modules/system/src/Tests/System/ErrorHandlerTest.php
index 69f17603f6ff..30a77b8b5ad4 100644
--- a/core/modules/system/src/Tests/System/ErrorHandlerTest.php
+++ b/core/modules/system/src/Tests/System/ErrorHandlerTest.php
@@ -121,7 +121,7 @@ function testExceptionHandler() {
 
     // The exceptions are expected. Do not interpret them as a test failure.
     // Not using File API; a potential error must trigger a PHP warning.
-    unlink(DRUPAL_ROOT . '/' . $this->siteDirectory . '/error.log');
+    unlink(\Drupal::root() . '/' . $this->siteDirectory . '/error.log');
   }
 
   /**
diff --git a/core/modules/system/src/Tests/System/HtaccessTest.php b/core/modules/system/src/Tests/System/HtaccessTest.php
index 29f133d93906..3e8f36d676da 100644
--- a/core/modules/system/src/Tests/System/HtaccessTest.php
+++ b/core/modules/system/src/Tests/System/HtaccessTest.php
@@ -33,7 +33,7 @@ public function testYamlFileAccess() {
    *   Path to file. Without leading slash.
    */
   protected function assertNoFileAccess($path) {
-    $this->assertTrue(file_exists(DRUPAL_ROOT . '/' . $path));
+    $this->assertTrue(file_exists(\Drupal::root() . '/' . $path));
     $this->drupalGet($path);
     $this->assertResponse(403);
   }
diff --git a/core/modules/system/src/Tests/System/IgnoreReplicaSubscriberTest.php b/core/modules/system/src/Tests/System/IgnoreReplicaSubscriberTest.php
index f9ceb3a65089..3615c43a9a7d 100644
--- a/core/modules/system/src/Tests/System/IgnoreReplicaSubscriberTest.php
+++ b/core/modules/system/src/Tests/System/IgnoreReplicaSubscriberTest.php
@@ -32,7 +32,7 @@ function testSystemInitIgnoresSecondaries() {
     Database::addConnectionInfo('default', 'replica', $connection_info['default']);
 
     db_ignore_replica();
-    $class_loader = require DRUPAL_ROOT . '/core/vendor/autoload.php';
+    $class_loader = require \Drupal::root() . '/core/vendor/autoload.php';
     $kernel = new DrupalKernel('testing', $class_loader, FALSE);
     $event = new GetResponseEvent($kernel, Request::create('http://example.com'), HttpKernelInterface::MASTER_REQUEST);
     $subscriber = new ReplicaDatabaseIgnoreSubscriber();
diff --git a/core/modules/system/src/Tests/System/SettingsRewriteTest.php b/core/modules/system/src/Tests/System/SettingsRewriteTest.php
index 741f92cd85b7..70b4043a9299 100644
--- a/core/modules/system/src/Tests/System/SettingsRewriteTest.php
+++ b/core/modules/system/src/Tests/System/SettingsRewriteTest.php
@@ -20,7 +20,7 @@ class SettingsRewriteTest extends KernelTestBase {
    * Tests the drupal_rewrite_settings() function.
    */
   function testDrupalRewriteSettings() {
-    include_once DRUPAL_ROOT . '/core/includes/install.inc';
+    include_once \Drupal::root() . '/core/includes/install.inc';
     $tests = array(
       array(
         'original' => '$no_index_value_scalar = TRUE;',
@@ -100,9 +100,9 @@ function testDrupalRewriteSettings() {
     );
     foreach ($tests as $test) {
       $filename = Settings::get('file_public_path', conf_path() . '/files') . '/mock_settings.php';
-      file_put_contents(DRUPAL_ROOT . '/' . $filename, "<?php\n" . $test['original'] . "\n");
+      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");
+      $this->assertEqual(file_get_contents(\Drupal::root() . '/' . $filename), "<?php\n" . $test['expected'] . "\n");
     }
 
     // Test that <?php gets added to the start of an empty settings file.
@@ -118,12 +118,12 @@ function testDrupalRewriteSettings() {
     );
     // Make an empty file.
     $filename = Settings::get('file_public_path', conf_path() . '/files') . '/mock_settings.php';
-    file_put_contents(DRUPAL_ROOT . '/' . $filename, "");
+    file_put_contents(\Drupal::root() . '/' . $filename, "");
 
     // Write the setting to the file.
     drupal_rewrite_settings($test['settings'], $filename);
 
     // Check that the result is just the php opening tag and the settings.
-    $this->assertEqual(file_get_contents(DRUPAL_ROOT . '/' . $filename), "<?php\n" . $test['expected'] . "\n");
+    $this->assertEqual(file_get_contents(\Drupal::root() . '/' . $filename), "<?php\n" . $test['expected'] . "\n");
   }
 }
diff --git a/core/modules/system/src/Tests/System/ShutdownFunctionsTest.php b/core/modules/system/src/Tests/System/ShutdownFunctionsTest.php
index d32148c1e3cf..b0d72655a61e 100644
--- a/core/modules/system/src/Tests/System/ShutdownFunctionsTest.php
+++ b/core/modules/system/src/Tests/System/ShutdownFunctionsTest.php
@@ -27,7 +27,7 @@ protected function tearDown() {
     // This test intentionally throws an exception in a PHP shutdown function.
     // Prevent it from being interpreted as an actual test failure.
     // Not using File API; a potential error must trigger a PHP warning.
-    unlink(DRUPAL_ROOT . '/' . $this->siteDirectory . '/error.log');
+    unlink(\Drupal::root() . '/' . $this->siteDirectory . '/error.log');
     parent::tearDown();
   }
 
diff --git a/core/modules/system/src/Tests/Theme/EntityFilteringThemeTest.php b/core/modules/system/src/Tests/Theme/EntityFilteringThemeTest.php
index 8454fe99382f..001f65b8475e 100644
--- a/core/modules/system/src/Tests/Theme/EntityFilteringThemeTest.php
+++ b/core/modules/system/src/Tests/Theme/EntityFilteringThemeTest.php
@@ -79,7 +79,7 @@ protected function setUp() {
     parent::setUp();
 
     // Install all available non-testing themes.
-    $listing = new ExtensionDiscovery();
+    $listing = new ExtensionDiscovery(\Drupal::root());
     $this->themes = $listing->scan('theme', FALSE);
     \Drupal::service('theme_handler')->install(array_keys($this->themes));
 
diff --git a/core/modules/system/src/Tests/Theme/ThemeSettingsTest.php b/core/modules/system/src/Tests/Theme/ThemeSettingsTest.php
index 927592246c18..299a96badc51 100644
--- a/core/modules/system/src/Tests/Theme/ThemeSettingsTest.php
+++ b/core/modules/system/src/Tests/Theme/ThemeSettingsTest.php
@@ -38,7 +38,7 @@ protected function setUp() {
     $this->installConfig(array('system'));
 
     if (!isset($this->availableThemes)) {
-      $discovery = new ExtensionDiscovery();
+      $discovery = new ExtensionDiscovery(\Drupal::root());
       $this->availableThemes = $discovery->scan('theme');
     }
   }
diff --git a/core/modules/system/src/Tests/TypedData/TypedDataTest.php b/core/modules/system/src/Tests/TypedData/TypedDataTest.php
index 6d817e6ccd19..61b8cd73b14d 100644
--- a/core/modules/system/src/Tests/TypedData/TypedDataTest.php
+++ b/core/modules/system/src/Tests/TypedData/TypedDataTest.php
@@ -244,7 +244,7 @@ public function testGetAndSet() {
     $files = array();
     for ($i = 0; $i < 3; $i++){
       $path = "public://example_$i.png";
-      file_unmanaged_copy(DRUPAL_ROOT . '/core/misc/druplicon.png', $path);
+      file_unmanaged_copy(\Drupal::root() . '/core/misc/druplicon.png', $path);
       $image = entity_create('file', array('uri' => $path));
       $image->save();
       $files[] = $image;
diff --git a/core/modules/system/src/Tests/Update/DependencyHookInvocationTest.php b/core/modules/system/src/Tests/Update/DependencyHookInvocationTest.php
index f75190a76786..1dd0bef7f071 100644
--- a/core/modules/system/src/Tests/Update/DependencyHookInvocationTest.php
+++ b/core/modules/system/src/Tests/Update/DependencyHookInvocationTest.php
@@ -26,7 +26,7 @@ class DependencyHookInvocationTest extends WebTestBase {
 
   protected function setUp() {
     parent::setUp();
-    require_once DRUPAL_ROOT . '/core/includes/update.inc';
+    require_once \Drupal::root() . '/core/includes/update.inc';
   }
 
   /**
diff --git a/core/modules/system/src/Tests/Update/DependencyMissingTest.php b/core/modules/system/src/Tests/Update/DependencyMissingTest.php
index 7c31851040a8..70cd56b6119e 100644
--- a/core/modules/system/src/Tests/Update/DependencyMissingTest.php
+++ b/core/modules/system/src/Tests/Update/DependencyMissingTest.php
@@ -27,7 +27,7 @@ protected function setUp() {
     // Only install update_test_2.module, even though its updates have a
     // dependency on update_test_3.module.
     parent::setUp();
-    require_once DRUPAL_ROOT . '/core/includes/update.inc';
+    require_once \Drupal::root() . '/core/includes/update.inc';
   }
 
   function testMissingUpdate() {
diff --git a/core/modules/system/src/Tests/Update/DependencyOrderingTest.php b/core/modules/system/src/Tests/Update/DependencyOrderingTest.php
index 4bf270ab37e3..1360c6d72bad 100644
--- a/core/modules/system/src/Tests/Update/DependencyOrderingTest.php
+++ b/core/modules/system/src/Tests/Update/DependencyOrderingTest.php
@@ -25,7 +25,7 @@ class DependencyOrderingTest extends WebTestBase {
 
   protected function setUp() {
     parent::setUp();
-    require_once DRUPAL_ROOT . '/core/includes/update.inc';
+    require_once \Drupal::root() . '/core/includes/update.inc';
   }
 
   /**
diff --git a/core/modules/system/src/Tests/Update/InvalidUpdateHookTest.php b/core/modules/system/src/Tests/Update/InvalidUpdateHookTest.php
index b5ea8fc14bd5..228d62c71d0a 100644
--- a/core/modules/system/src/Tests/Update/InvalidUpdateHookTest.php
+++ b/core/modules/system/src/Tests/Update/InvalidUpdateHookTest.php
@@ -41,7 +41,7 @@ class InvalidUpdateHookTest extends WebTestBase {
 
   protected function setUp() {
     parent::setUp();
-    require_once DRUPAL_ROOT . '/core/includes/update.inc';
+    require_once \Drupal::root() . '/core/includes/update.inc';
 
     $this->update_url = $GLOBALS['base_url'] . '/update.php';
     $this->update_user = $this->drupalCreateUser(array('administer software updates'));
diff --git a/core/modules/system/src/Tests/Update/UpdatesWith7xTest.php b/core/modules/system/src/Tests/Update/UpdatesWith7xTest.php
index b6c215daedc6..09daad3b9b6e 100644
--- a/core/modules/system/src/Tests/Update/UpdatesWith7xTest.php
+++ b/core/modules/system/src/Tests/Update/UpdatesWith7xTest.php
@@ -36,7 +36,7 @@ class UpdatesWith7xTest extends WebTestBase {
 
   protected function setUp() {
     parent::setUp();
-    require_once DRUPAL_ROOT . '/core/includes/update.inc';
+    require_once \Drupal::root() . '/core/includes/update.inc';
     $this->update_url = $GLOBALS['base_url'] . '/update.php';
     $this->update_user = $this->drupalCreateUser(array('administer software updates'));
   }
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 33859e82142d..1632cb8e264d 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -850,7 +850,7 @@ function system_get_info($type, $name = NULL) {
  *   An associative array of module information.
  */
 function _system_rebuild_module_data() {
-  $listing = new ExtensionDiscovery();
+  $listing = new ExtensionDiscovery(\Drupal::root());
   // Find modules
   $modules = $listing->scan('module');
 
diff --git a/core/modules/system/tests/src/Unit/Menu/SystemLocalTasksTest.php b/core/modules/system/tests/src/Unit/Menu/SystemLocalTasksTest.php
index 6d98ebd7ecea..e1b48e95f02a 100644
--- a/core/modules/system/tests/src/Unit/Menu/SystemLocalTasksTest.php
+++ b/core/modules/system/tests/src/Unit/Menu/SystemLocalTasksTest.php
@@ -36,7 +36,7 @@ protected function setUp() {
 
     $this->themeHandler = $this->getMock('Drupal\Core\Extension\ThemeHandlerInterface');
 
-    $theme = new Extension('theme', DRUPAL_ROOT . '/core/themes/bartik', 'bartik.info.yml');
+    $theme = new Extension($this->root, 'theme', '/core/themes/bartik', 'bartik.info.yml');
     $theme->status = 1;
     $theme->info = array('name' => 'bartik');
     $this->themeHandler->expects($this->any())
diff --git a/core/modules/taxonomy/src/Tests/VocabularyCrudTest.php b/core/modules/taxonomy/src/Tests/VocabularyCrudTest.php
index b167840ed2ed..f265ec2161a3 100644
--- a/core/modules/taxonomy/src/Tests/VocabularyCrudTest.php
+++ b/core/modules/taxonomy/src/Tests/VocabularyCrudTest.php
@@ -193,7 +193,7 @@ function testUninstallReinstall() {
     );
     entity_create('field_config', $field_definition)->save();
 
-    require_once DRUPAL_ROOT . '/core/includes/install.inc';
+    require_once \Drupal::root() . '/core/includes/install.inc';
     $this->container->get('module_handler')->uninstall(array('taxonomy'));
     \Drupal::moduleHandler()->install(array('taxonomy'));
 
diff --git a/core/modules/update/src/Form/UpdateManagerInstall.php b/core/modules/update/src/Form/UpdateManagerInstall.php
index 3198a288e4ae..b3e2deb7186c 100644
--- a/core/modules/update/src/Form/UpdateManagerInstall.php
+++ b/core/modules/update/src/Form/UpdateManagerInstall.php
@@ -26,13 +26,23 @@ class UpdateManagerInstall extends FormBase {
    */
   protected $moduleHandler;
 
+  /**
+   * The app root.
+   *
+   * @var string
+   */
+  protected $root;
+
   /**
    * Constructs a new UpdateManagerInstall.
    *
+   * @param string $root
+   *   The app root.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler.
    */
-  public function __construct(ModuleHandlerInterface $module_handler) {
+  public function __construct($root, ModuleHandlerInterface $module_handler) {
+    $this->root = $root;
     $this->moduleHandler = $module_handler;
   }
 
@@ -48,6 +58,7 @@ public function getFormID() {
    */
   public static function create(ContainerInterface $container) {
     return new static(
+      $container->get('app.root'),
       $container->get('module_handler')
     );
   }
@@ -207,7 +218,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     // update_authorize_run_install() directly.
     if (fileowner($project_real_location) == fileowner(conf_path())) {
       $this->moduleHandler->loadInclude('update', 'inc', 'update.authorize');
-      $filetransfer = new Local(DRUPAL_ROOT);
+      $filetransfer = new Local($this->root);
       call_user_func_array('update_authorize_run_install', array_merge(array($filetransfer), $arguments));
     }
 
diff --git a/core/modules/update/src/Form/UpdateReady.php b/core/modules/update/src/Form/UpdateReady.php
index 7f4c5daf09f0..8e106fe491bc 100644
--- a/core/modules/update/src/Form/UpdateReady.php
+++ b/core/modules/update/src/Form/UpdateReady.php
@@ -20,6 +20,13 @@
  */
 class UpdateReady extends FormBase {
 
+  /**
+   * The app root.
+   *
+   * @var string
+   */
+  protected $root;
+
   /**
    * The module handler.
    *
@@ -37,12 +44,15 @@ class UpdateReady extends FormBase {
   /**
    * Constructs a new UpdateReady object.
    *
+   * @param string $root
+   *   The app root.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The object that manages enabled modules in a Drupal installation.
    * @param \Drupal\Core\State\StateInterface $state
    *   The state key value store.
    */
-  public function __construct(ModuleHandlerInterface $module_handler, StateInterface $state) {
+  public function __construct($root, ModuleHandlerInterface $module_handler, StateInterface $state) {
+    $this->root = $root;
     $this->moduleHandler = $module_handler;
     $this->state = $state;
   }
@@ -59,6 +69,7 @@ public function getFormID() {
    */
   public static function create(ContainerInterface $container) {
     return new static(
+      $container->get('app.root'),
       $container->get('module_handler'),
       $container->get('state')
     );
@@ -133,7 +144,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       // and invoke update_authorize_run_update() directly.
       if (fileowner($project_real_location) == fileowner(conf_path())) {
         $this->moduleHandler->loadInclude('update', 'inc', 'update.authorize');
-        $filetransfer = new Local(DRUPAL_ROOT);
+        $filetransfer = new Local($this->root);
         update_authorize_run_update($filetransfer, $updates);
       }
       // Otherwise, go through the regular workflow to prompt for FTP/SSH
diff --git a/core/modules/user/src/Tests/UserAccountFormFieldsTest.php b/core/modules/user/src/Tests/UserAccountFormFieldsTest.php
index ac3651832a8a..747de4bb3a9f 100644
--- a/core/modules/user/src/Tests/UserAccountFormFieldsTest.php
+++ b/core/modules/user/src/Tests/UserAccountFormFieldsTest.php
@@ -29,8 +29,8 @@ class UserAccountFormFieldsTest extends DrupalUnitTestBase {
    * Tests the root user account form section in the "Configure site" form.
    */
   function testInstallConfigureForm() {
-    require_once DRUPAL_ROOT . '/core/includes/install.core.inc';
-    require_once DRUPAL_ROOT . '/core/includes/install.inc';
+    require_once \Drupal::root() . '/core/includes/install.core.inc';
+    require_once \Drupal::root() . '/core/includes/install.inc';
     $install_state = install_state_defaults();
     $form_state = new FormState();
     $form_state->addBuildInfo('args', [&$install_state]);
diff --git a/core/modules/user/tests/src/Unit/PermissionHandlerTest.php b/core/modules/user/tests/src/Unit/PermissionHandlerTest.php
index cbe28dd60c59..118084677129 100644
--- a/core/modules/user/tests/src/Unit/PermissionHandlerTest.php
+++ b/core/modules/user/tests/src/Unit/PermissionHandlerTest.php
@@ -55,6 +55,8 @@ class PermissionHandlerTest extends UnitTestCase {
    * {@inheritdoc}
    */
   protected function setUp() {
+    parent::setUp();
+
     $this->stringTranslation = $this->getStringTranslationStub();
     $this->controllerResolver = $this->getMock('Drupal\Core\Controller\ControllerResolverInterface');
   }
@@ -71,7 +73,7 @@ protected function setUp() {
    *   The extension object.
    */
   protected function mockModuleExtension($module, $name) {
-    $extension = new Extension($module, "modules/$module");
+    $extension = new Extension($this->root, $module, "modules/$module");
     $extension->info['name'] = $name;
     return $extension;
   }
diff --git a/core/modules/views/views.module b/core/modules/views/views.module
index 1c5da7ce2be6..f2a0b376844e 100644
--- a/core/modules/views/views.module
+++ b/core/modules/views/views.module
@@ -181,7 +181,7 @@ function views_theme($existing, $type, $theme, $path) {
       // Whenever we have a theme file, we include it directly so we can
       // auto-detect the theme function.
       if (isset($def['theme_file'])) {
-        $include = DRUPAL_ROOT . '/' . $module_dir . '/' . $def['theme_file'];
+        $include = \Drupal::root() . '/' . $module_dir. '/' . $def['theme_file'];
         if (is_file($include)) {
           require_once $include;
         }
diff --git a/core/rebuild.php b/core/rebuild.php
index c915aff7459e..be3e603b3548 100644
--- a/core/rebuild.php
+++ b/core/rebuild.php
@@ -25,7 +25,7 @@
 // Manually resemble early bootstrap of DrupalKernel::boot().
 require_once __DIR__ . '/includes/bootstrap.inc';
 DrupalKernel::bootEnvironment();
-Settings::initialize(DrupalKernel::findSitePath($request), $autoloader);
+Settings::initialize(dirname(__DIR__), DrupalKernel::findSitePath($request), $autoloader);
 
 if (Settings::get('rebuild_access', FALSE) ||
   ($request->get('token') && $request->get('timestamp') &&
diff --git a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
index f1a71468a441..a912e31119ea 100644
--- a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
+++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryParserTest.php
@@ -62,8 +62,10 @@ class LibraryDiscoveryParserTest extends UnitTestCase {
    * {@inheritdoc}
    */
   protected function setUp() {
+    parent::setUp();
+
     $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
-    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->moduleHandler);
+    $this->libraryDiscoveryParser = new TestLibraryDiscoveryParser($this->root, $this->moduleHandler);
   }
 
   /**
@@ -78,7 +80,7 @@ public function testBuildByExtensionSimple() {
       ->will($this->returnValue(TRUE));
 
     $path = __DIR__ . '/library_test_files';
-    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $path = substr($path, strlen($this->root) + 1);
     $this->libraryDiscoveryParser->setPaths('module', 'example_module', $path);
 
     $libraries = $this->libraryDiscoveryParser->buildByExtension('example_module', 'example');
@@ -105,7 +107,7 @@ public function testBuildByExtensionWithTheme() {
       ->will($this->returnValue(FALSE));
 
     $path = __DIR__ . '/library_test_files';
-    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $path = substr($path, strlen($this->root) + 1);
     $this->libraryDiscoveryParser->setPaths('theme', 'example_theme', $path);
 
     $libraries = $this->libraryDiscoveryParser->buildByExtension('example_theme');
@@ -129,7 +131,7 @@ public function testBuildByExtensionWithMissingLibraryFile() {
       ->will($this->returnValue(TRUE));
 
     $path = __DIR__ . '/library_test_files_not_existing';
-    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $path = substr($path, strlen($this->root) + 1);
     $this->libraryDiscoveryParser->setPaths('module', 'example_module', $path);
 
     $this->assertSame($this->libraryDiscoveryParser->buildByExtension('example_module'), array());
@@ -149,7 +151,7 @@ public function testInvalidLibrariesFile() {
       ->will($this->returnValue(TRUE));
 
     $path = __DIR__ . '/library_test_files';
-    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $path = substr($path, strlen($this->root) + 1);
     $this->libraryDiscoveryParser->setPaths('module', 'invalid_file', $path);
 
     $this->libraryDiscoveryParser->buildByExtension('invalid_file');
@@ -170,7 +172,7 @@ public function testBuildByExtensionWithMissingInformation() {
       ->will($this->returnValue(TRUE));
 
     $path = __DIR__ . '/library_test_files';
-    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $path = substr($path, strlen($this->root) + 1);
     $this->libraryDiscoveryParser->setPaths('module', 'example_module_missing_information', $path);
 
     $this->libraryDiscoveryParser->buildByExtension('example_module_missing_information');
@@ -188,7 +190,7 @@ public function testExternalLibraries() {
       ->will($this->returnValue(TRUE));
 
     $path = __DIR__ . '/library_test_files';
-    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $path = substr($path, strlen($this->root) + 1);
     $this->libraryDiscoveryParser->setPaths('module', 'external', $path);
 
     $libraries = $this->libraryDiscoveryParser->buildByExtension('external', 'example_external');
@@ -210,7 +212,7 @@ public function testDefaultCssWeights() {
       ->will($this->returnValue(TRUE));
 
     $path = __DIR__ . '/library_test_files';
-    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $path = substr($path, strlen($this->root) + 1);
     $this->libraryDiscoveryParser->setPaths('module', 'css_weights', $path);
 
     $libraries = $this->libraryDiscoveryParser->buildByExtension('css_weights');
@@ -250,7 +252,7 @@ public function testJsWithPositiveWeight() {
       ->will($this->returnValue(TRUE));
 
     $path = __DIR__ . '/library_test_files';
-    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $path = substr($path, strlen($this->root) + 1);
     $this->libraryDiscoveryParser->setPaths('module', 'js_positive_weight', $path);
 
     $this->libraryDiscoveryParser->buildByExtension('js_positive_weight');
@@ -268,7 +270,7 @@ public function testLibraryWithCssJsSetting() {
       ->will($this->returnValue(TRUE));
 
     $path = __DIR__ . '/library_test_files';
-    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $path = substr($path, strlen($this->root) + 1);
     $this->libraryDiscoveryParser->setPaths('module', 'css_js_settings', $path);
 
     $libraries = $this->libraryDiscoveryParser->buildByExtension('css_js_settings');
@@ -299,7 +301,7 @@ public function testLibraryWithDependencies() {
       ->will($this->returnValue(TRUE));
 
     $path = __DIR__ . '/library_test_files';
-    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $path = substr($path, strlen($this->root) + 1);
     $this->libraryDiscoveryParser->setPaths('module', 'dependencies', $path);
 
     $libraries = $this->libraryDiscoveryParser->buildByExtension('dependencies');
@@ -322,7 +324,7 @@ public function testLibraryWithDataTypes() {
       ->will($this->returnValue(TRUE));
 
     $path = __DIR__ . '/library_test_files';
-    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $path = substr($path, strlen($this->root) + 1);
     $this->libraryDiscoveryParser->setPaths('module', 'data_types', $path);
 
     $this->libraryDiscoveryParser->setFileValidUri('public://test.css', TRUE);
@@ -354,7 +356,7 @@ public function testLibraryWithJavaScript() {
       ->will($this->returnValue(TRUE));
 
     $path = __DIR__ . '/library_test_files';
-    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $path = substr($path, strlen($this->root) + 1);
     $this->libraryDiscoveryParser->setPaths('module', 'js', $path);
 
     $libraries = $this->libraryDiscoveryParser->buildByExtension('js');
@@ -379,7 +381,7 @@ public function testLibraryThirdPartyWithMissingLicense() {
       ->will($this->returnValue(TRUE));
 
     $path = __DIR__ . '/library_test_files';
-    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $path = substr($path, strlen($this->root) + 1);
     $this->libraryDiscoveryParser->setPaths('module', 'licenses_missing_information', $path);
 
     $this->libraryDiscoveryParser->buildByExtension('licenses_missing_information');
@@ -397,7 +399,7 @@ public function testLibraryWithLicenses() {
       ->will($this->returnValue(TRUE));
 
     $path = __DIR__ . '/library_test_files';
-    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $path = substr($path, strlen($this->root) + 1);
     $this->libraryDiscoveryParser->setPaths('module', 'licenses', $path);
 
     $libraries = $this->libraryDiscoveryParser->buildByExtension('licenses');
diff --git a/core/tests/Drupal/Tests/Core/Extension/DefaultConfigTest.php b/core/tests/Drupal/Tests/Core/Extension/DefaultConfigTest.php
index a4bb8b122434..e65c6517c49d 100644
--- a/core/tests/Drupal/Tests/Core/Extension/DefaultConfigTest.php
+++ b/core/tests/Drupal/Tests/Core/Extension/DefaultConfigTest.php
@@ -28,7 +28,7 @@ class DefaultConfigTest extends UnitTestCase {
    * would not exist. Installation hooks would never be executed.
    */
   public function testConfigIsEmpty() {
-    $config = Yaml::parse(file_get_contents(DRUPAL_ROOT . '/core/config/install/core.extension.yml'));
+    $config = Yaml::parse(file_get_contents($this->root . '/core/config/install/core.extension.yml'));
     $expected = array(
       'module' => array(),
       'theme' => array(),
diff --git a/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerTest.php b/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerTest.php
index 493e2014c2e3..fe5b6e000bac 100644
--- a/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerTest.php
+++ b/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerTest.php
@@ -44,9 +44,12 @@ class ModuleHandlerTest extends UnitTestCase {
    * @covers ::__construct
    */
   protected function setUp() {
+    parent::setUp();
+
     $this->kernel = $this->getMock('Drupal\Core\DrupalKernelInterface');
+
     $this->cacheBackend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface');
-    $this->moduleHandler = new ModuleHandler(array(
+    $this->moduleHandler = new ModuleHandler($this->root, array(
       'module_handler_test' => array(
         'type' => 'module',
         'pathname' => 'core/tests/Drupal/Tests/Core/Extension/modules/module_handler_test/module_handler_test.info.yml',
@@ -97,6 +100,7 @@ public function testLoadAllModules() {
   public function testModuleReloading() {
     $module_handler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandler')
       ->setConstructorArgs(array(
+        $this->root,
         array(
           'module_handler_test' => array(
             'type' => 'module',
@@ -141,7 +145,7 @@ public function testIsLoaded() {
    */
   public function testGetModuleList() {
     $this->assertEquals($this->moduleHandler->getModuleList(), array(
-      'module_handler_test' => new Extension('module', 'core/tests/Drupal/Tests/Core/Extension/modules/module_handler_test/module_handler_test.info.yml', 'module_handler_test.module'),
+      'module_handler_test' => new Extension($this->root, 'module', 'core/tests/Drupal/Tests/Core/Extension/modules/module_handler_test/module_handler_test.info.yml', 'module_handler_test.module'),
     ));
   }
 
@@ -151,7 +155,7 @@ public function testGetModuleList() {
    * @covers ::getModule
    */
   public function testGetModuleWithExistingModule() {
-    $this->assertEquals($this->moduleHandler->getModule('module_handler_test'), new Extension('module', 'core/tests/Drupal/Tests/Core/Extension/modules/module_handler_test/module_handler_test.info.yml', 'module_handler_test.module'));
+    $this->assertEquals($this->moduleHandler->getModule('module_handler_test'), new Extension($this->root, 'module', 'core/tests/Drupal/Tests/Core/Extension/modules/module_handler_test/module_handler_test.info.yml', 'module_handler_test.module'));
   }
 
   /**
@@ -171,7 +175,7 @@ public function testGetModuleWithNonExistingModule() {
   public function testSetModuleList() {
     $module_handler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandler')
       ->setConstructorArgs(array(
-        array(), $this->kernel, $this->cacheBackend
+        $this->root, array(), $this->kernel, $this->cacheBackend
       ))
       ->setMethods(array('resetImplementations'))
       ->getMock();
@@ -199,7 +203,7 @@ public function testAddModule() {
 
     $module_handler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandler')
       ->setConstructorArgs(array(
-        array(), $this->kernel, $this->cacheBackend
+        $this->root, array(), $this->kernel, $this->cacheBackend
       ))
       ->setMethods(array('resetImplementations'))
       ->getMock();
@@ -221,7 +225,7 @@ public function testAddProfile() {
 
     $module_handler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandler')
       ->setConstructorArgs(array(
-        array(), $this->kernel, $this->cacheBackend
+        $this->root, array(), $this->kernel, $this->cacheBackend
       ))
       ->setMethods(array('resetImplementations'))
       ->getMock();
@@ -251,6 +255,7 @@ public function testLoadAllIncludes() {
     $this->assertTrue(true);
     $module_handler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandler')
       ->setConstructorArgs(array(
+        $this->root,
         array(
           'module_handler_test' => array(
             'type' => 'module',
@@ -332,7 +337,7 @@ public function testCachedGetImplementations() {
     // Ensure buildImplementationInfo doesn't get called and that we work off cached results.
     $module_handler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandler')
       ->setConstructorArgs(array(
-        array(
+        $this->root, array(
           'module_handler_test' => array(
             'type' => 'module',
             'pathname' => 'core/tests/Drupal/Tests/Core/Extension/modules/module_handler_test/module_handler_test.info.yml',
@@ -367,7 +372,7 @@ public function testCachedGetImplementationsMissingMethod() {
     // Ensure buildImplementationInfo doesn't get called and that we work off cached results.
     $module_handler = $this->getMockBuilder('Drupal\Core\Extension\ModuleHandler')
       ->setConstructorArgs(array(
-        array(
+        $this->root, array(
           'module_handler_test' => array(
             'type' => 'module',
             'pathname' => 'core/tests/Drupal/Tests/Core/Extension/modules/module_handler_test/module_handler_test.info.yml',
@@ -512,6 +517,6 @@ public function dependencyProvider() {
   public function testGetModuleDirectories() {
     $this->moduleHandler->setModuleList(array());
     $this->moduleHandler->addModule('module', 'place');
-    $this->assertEquals(array('module' => DRUPAL_ROOT . '/place'), $this->moduleHandler->getModuleDirectories());
+    $this->assertEquals(array('module' => $this->root . '/place'), $this->moduleHandler->getModuleDirectories());
   }
 }
diff --git a/core/tests/Drupal/Tests/Core/Extension/ThemeHandlerTest.php b/core/tests/Drupal/Tests/Core/Extension/ThemeHandlerTest.php
index 22b1f2565379..5dba9dbed86e 100644
--- a/core/tests/Drupal/Tests/Core/Extension/ThemeHandlerTest.php
+++ b/core/tests/Drupal/Tests/Core/Extension/ThemeHandlerTest.php
@@ -95,6 +95,8 @@ class ThemeHandlerTest extends UnitTestCase {
    * {@inheritdoc}
    */
   protected function setUp() {
+    parent::setUp();
+
     $this->configFactory = $this->getConfigFactoryStub(array(
       'core.extension' => array(
         'module' => array(),
@@ -117,7 +119,7 @@ protected function setUp() {
       ->disableOriginalConstructor()
       ->getMock();
     $logger = $this->getMock('Psr\Log\LoggerInterface');
-    $this->themeHandler = new TestThemeHandler($this->configFactory, $this->moduleHandler, $this->state, $this->infoParser, $logger, $this->cssCollectionOptimizer, $this->configInstaller, $this->configManager, $this->routeBuilderIndicator, $this->extensionDiscovery);
+    $this->themeHandler = new TestThemeHandler($this->root, $this->configFactory, $this->moduleHandler, $this->state, $this->infoParser, $logger, $this->cssCollectionOptimizer, $this->configInstaller, $this->configManager, $this->routeBuilderIndicator, $this->extensionDiscovery);
 
     $cache_backend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface');
     $this->getContainerWithCacheBins($cache_backend);
@@ -133,17 +135,17 @@ public function testRebuildThemeData() {
       ->method('scan')
       ->with('theme')
       ->will($this->returnValue(array(
-        'seven' => new Extension('theme', DRUPAL_ROOT . '/core/themes/seven/seven.info.yml', 'seven.theme'),
+        'seven' => new Extension($this->root, 'theme', $this->root . '/core/themes/seven/seven.info.yml', 'seven.theme'),
       )));
     $this->extensionDiscovery->expects($this->at(1))
       ->method('scan')
       ->with('theme_engine')
       ->will($this->returnValue(array(
-        'twig' => new Extension('theme_engine', DRUPAL_ROOT . '/core/themes/engines/twig/twig.info.yml', 'twig.engine'),
+        'twig' => new Extension($this->root, 'theme_engine', $this->root . '/core/themes/engines/twig/twig.info.yml', 'twig.engine'),
       )));
     $this->infoParser->expects($this->once())
       ->method('parse')
-      ->with(DRUPAL_ROOT . '/core/themes/seven/seven.info.yml')
+      ->with($this->root . '/core/themes/seven/seven.info.yml')
       ->will($this->returnCallback(function ($file) {
         $info_parser = new InfoParser();
         return $info_parser->parse($file);
@@ -162,9 +164,9 @@ public function testRebuildThemeData() {
     // Ensure some basic properties.
     $this->assertInstanceOf('Drupal\Core\Extension\Extension', $info);
     $this->assertEquals('seven', $info->getName());
-    $this->assertEquals(DRUPAL_ROOT . '/core/themes/seven/seven.info.yml', $info->getPathname());
-    $this->assertEquals(DRUPAL_ROOT . '/core/themes/seven/seven.theme', $info->getExtensionPathname());
-    $this->assertEquals(DRUPAL_ROOT . '/core/themes/engines/twig/twig.engine', $info->owner);
+    $this->assertEquals($this->root . '/core/themes/seven/seven.info.yml', $info->getPathname());
+    $this->assertEquals($this->root . '/core/themes/seven/seven.theme', $info->getExtensionPathname());
+    $this->assertEquals($this->root . '/core/themes/engines/twig/twig.engine', $info->owner);
     $this->assertEquals('twig', $info->prefix);
 
     $this->assertEquals('twig', $info->info['engine']);
@@ -173,40 +175,40 @@ public function testRebuildThemeData() {
     // Ensure that the css paths are set with the proper prefix.
     $this->assertEquals(array(
       'screen' => array(
-        'css/base/elements.css' => DRUPAL_ROOT . '/core/themes/seven/css/base/elements.css',
-        'css/base/typography.css' => DRUPAL_ROOT . '/core/themes/seven/css/base/typography.css',
-        'css/components/admin-list.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/admin-list.css',
-        'css/components/admin-options.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/admin-options.css',
-        'css/components/admin-panel.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/admin-panel.css',
-        'css/components/block-recent-content.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/block-recent-content.css',
-        'css/components/content-header.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/content-header.css',
-        'css/components/breadcrumb.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/breadcrumb.css',
-        'css/components/buttons.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/buttons.css',
-        'css/components/buttons.theme.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/buttons.theme.css',
-        'css/components/comments.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/comments.css',
-        'css/components/messages.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/messages.css',
-        'css/components/dropbutton.component.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/dropbutton.component.css',
-        'css/components/entity-meta.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/entity-meta.css',
-        'css/components/field-ui.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/field-ui.css',
-        'css/components/form.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/form.css',
-        'css/components/help.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/help.css',
-        'css/components/menus-and-lists.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/menus-and-lists.css',
-        'css/components/modules-page.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/modules-page.css',
-        'css/components/node.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/node.css',
-        'css/components/page-title.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/page-title.css',
-        'css/components/pager.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/pager.css',
-        'css/components/skip-link.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/skip-link.css',
-        'css/components/tables.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/tables.css',
-        'css/components/tabs.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/tabs.css',
-        'css/components/tour.theme.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/tour.theme.css',
-        'css/components/update-status.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/update-status.css',
-        'css/components/views-ui.css' => DRUPAL_ROOT . '/core/themes/seven/css/components/views-ui.css',
-        'css/layout/layout.css' => DRUPAL_ROOT . '/core/themes/seven/css/layout/layout.css',
-        'css/layout/node-add.css' => DRUPAL_ROOT . '/core/themes/seven/css/layout/node-add.css',
-        'css/theme/appearance-page.css' => DRUPAL_ROOT . '/core/themes/seven/css/theme/appearance-page.css',
+        'css/base/elements.css' => $this->root . '/core/themes/seven/css/base/elements.css',
+        'css/base/typography.css' => $this->root . '/core/themes/seven/css/base/typography.css',
+        'css/components/admin-list.css' => $this->root . '/core/themes/seven/css/components/admin-list.css',
+        'css/components/admin-options.css' => $this->root . '/core/themes/seven/css/components/admin-options.css',
+        'css/components/admin-panel.css' => $this->root . '/core/themes/seven/css/components/admin-panel.css',
+        'css/components/block-recent-content.css' => $this->root . '/core/themes/seven/css/components/block-recent-content.css',
+        'css/components/content-header.css' => $this->root . '/core/themes/seven/css/components/content-header.css',
+        'css/components/breadcrumb.css' => $this->root . '/core/themes/seven/css/components/breadcrumb.css',
+        'css/components/buttons.css' => $this->root . '/core/themes/seven/css/components/buttons.css',
+        'css/components/buttons.theme.css' => $this->root . '/core/themes/seven/css/components/buttons.theme.css',
+        'css/components/comments.css' => $this->root . '/core/themes/seven/css/components/comments.css',
+        'css/components/messages.css' => $this->root . '/core/themes/seven/css/components/messages.css',
+        'css/components/dropbutton.component.css' => $this->root . '/core/themes/seven/css/components/dropbutton.component.css',
+        'css/components/entity-meta.css' => $this->root . '/core/themes/seven/css/components/entity-meta.css',
+        'css/components/field-ui.css' => $this->root . '/core/themes/seven/css/components/field-ui.css',
+        'css/components/form.css' => $this->root . '/core/themes/seven/css/components/form.css',
+        'css/components/help.css' => $this->root . '/core/themes/seven/css/components/help.css',
+        'css/components/menus-and-lists.css' => $this->root . '/core/themes/seven/css/components/menus-and-lists.css',
+        'css/components/modules-page.css' => $this->root . '/core/themes/seven/css/components/modules-page.css',
+        'css/components/node.css' => $this->root . '/core/themes/seven/css/components/node.css',
+        'css/components/page-title.css' => $this->root . '/core/themes/seven/css/components/page-title.css',
+        'css/components/pager.css' => $this->root . '/core/themes/seven/css/components/pager.css',
+        'css/components/skip-link.css' => $this->root . '/core/themes/seven/css/components/skip-link.css',
+        'css/components/tables.css' => $this->root . '/core/themes/seven/css/components/tables.css',
+        'css/components/tabs.css' => $this->root . '/core/themes/seven/css/components/tabs.css',
+        'css/components/tour.theme.css' => $this->root . '/core/themes/seven/css/components/tour.theme.css',
+        'css/components/update-status.css' => $this->root . '/core/themes/seven/css/components/update-status.css',
+        'css/components/views-ui.css' => $this->root . '/core/themes/seven/css/components/views-ui.css',
+        'css/layout/layout.css' => $this->root . '/core/themes/seven/css/layout/layout.css',
+        'css/layout/node-add.css' => $this->root . '/core/themes/seven/css/layout/node-add.css',
+        'css/theme/appearance-page.css' => $this->root . '/core/themes/seven/css/theme/appearance-page.css',
       ),
     ), $info->info['stylesheets']);
-    $this->assertEquals(DRUPAL_ROOT . '/core/themes/seven/screenshot.png', $info->info['screenshot']);
+    $this->assertEquals($this->root . '/core/themes/seven/screenshot.png', $info->info['screenshot']);
   }
 
   /**
@@ -217,25 +219,25 @@ public function testRebuildThemeDataWithThemeParents() {
       ->method('scan')
       ->with('theme')
       ->will($this->returnValue(array(
-        'test_subtheme' => new Extension('theme', DRUPAL_ROOT . '/core/modules/system/tests/themes/test_subtheme/test_subtheme.info.yml', 'test_subtheme.info.yml'),
-        'test_basetheme' => new Extension('theme', DRUPAL_ROOT . '/core/modules/system/tests/themes/test_basetheme/test_basetheme.info.yml', 'test_basetheme.info.yml'),
+        'test_subtheme' => new Extension($this->root, 'theme', $this->root . '/core/modules/system/tests/themes/test_subtheme/test_subtheme.info.yml', 'test_subtheme.info.yml'),
+        'test_basetheme' => new Extension($this->root, 'theme', $this->root . '/core/modules/system/tests/themes/test_basetheme/test_basetheme.info.yml', 'test_basetheme.info.yml'),
       )));
     $this->extensionDiscovery->expects($this->at(1))
       ->method('scan')
       ->with('theme_engine')
       ->will($this->returnValue(array(
-        'twig' => new Extension('theme_engine', DRUPAL_ROOT . '/core/themes/engines/twig/twig.info.yml', 'twig.engine'),
+        'twig' => new Extension($this->root, 'theme_engine', $this->root . '/core/themes/engines/twig/twig.info.yml', 'twig.engine'),
       )));
     $this->infoParser->expects($this->at(0))
       ->method('parse')
-      ->with(DRUPAL_ROOT . '/core/modules/system/tests/themes/test_subtheme/test_subtheme.info.yml')
+      ->with($this->root . '/core/modules/system/tests/themes/test_subtheme/test_subtheme.info.yml')
       ->will($this->returnCallback(function ($file) {
         $info_parser = new InfoParser();
         return $info_parser->parse($file);
       }));
     $this->infoParser->expects($this->at(1))
       ->method('parse')
-      ->with(DRUPAL_ROOT . '/core/modules/system/tests/themes/test_basetheme/test_basetheme.info.yml')
+      ->with($this->root . '/core/modules/system/tests/themes/test_basetheme/test_basetheme.info.yml')
       ->will($this->returnCallback(function ($file) {
         $info_parser = new InfoParser();
         return $info_parser->parse($file);
@@ -260,9 +262,9 @@ public function testRebuildThemeDataWithThemeParents() {
     $info_subtheme->info['base theme'] = 'test_basetheme';
     $info_basetheme->sub_themes = array('test_subtheme');
 
-    $this->assertEquals(DRUPAL_ROOT . '/core/themes/engines/twig/twig.engine', $info_basetheme->owner);
+    $this->assertEquals($this->root . '/core/themes/engines/twig/twig.engine', $info_basetheme->owner);
     $this->assertEquals('twig', $info_basetheme->prefix);
-    $this->assertEquals(DRUPAL_ROOT . '/core/themes/engines/twig/twig.engine', $info_subtheme->owner);
+    $this->assertEquals($this->root . '/core/themes/engines/twig/twig.engine', $info_subtheme->owner);
     $this->assertEquals('twig', $info_subtheme->prefix);
   }
 
diff --git a/core/tests/Drupal/Tests/Core/Form/FormCacheTest.php b/core/tests/Drupal/Tests/Core/Form/FormCacheTest.php
index 41d76dfa9814..138309e6e9b8 100644
--- a/core/tests/Drupal/Tests/Core/Form/FormCacheTest.php
+++ b/core/tests/Drupal/Tests/Core/Form/FormCacheTest.php
@@ -125,8 +125,7 @@ protected function setUp() {
     $this->requestStack = $this->getMock('\Symfony\Component\HttpFoundation\RequestStack');
     $this->requestPolicy = $this->getMock('\Drupal\Core\PageCache\RequestPolicyInterface');
 
-
-    $this->formCache = new FormCache($this->keyValueExpirableFactory, $this->moduleHandler, $this->account, $this->csrfToken, $this->logger, $this->configFactory, $this->requestStack, $this->requestPolicy);
+    $this->formCache = new FormCache($this->root, $this->keyValueExpirableFactory, $this->moduleHandler, $this->account, $this->csrfToken, $this->logger, $this->configFactory, $this->requestStack, $this->requestPolicy);
   }
 
   /**
@@ -511,8 +510,9 @@ public function testSetCacheImmutableForm() {
     // Rebuild the FormCache with a config factory that will return a config
     // object with the internal page cache enabled.
     $this->configFactory = $this->getConfigFactoryStub(['system.performance' => ['cache.page.use_internal' => TRUE]]);
+    $root = dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__))));
     $this->formCache = $this->getMockBuilder('Drupal\Core\Form\FormCache')
-      ->setConstructorArgs([$this->keyValueExpirableFactory, $this->moduleHandler, $this->account, $this->csrfToken, $this->logger, $this->configFactory, $this->requestStack, $this->requestPolicy])
+      ->setConstructorArgs([$root, $this->keyValueExpirableFactory, $this->moduleHandler, $this->account, $this->csrfToken, $this->logger, $this->configFactory, $this->requestStack, $this->requestPolicy])
       ->setMethods(['isPageCacheable'])
       ->getMock();
 
diff --git a/core/tests/Drupal/Tests/Core/Form/FormTestBase.php b/core/tests/Drupal/Tests/Core/Form/FormTestBase.php
index 13eae9ab82aa..2386eb27031b 100644
--- a/core/tests/Drupal/Tests/Core/Form/FormTestBase.php
+++ b/core/tests/Drupal/Tests/Core/Form/FormTestBase.php
@@ -160,6 +160,7 @@ protected function setUp() {
       ->setConstructorArgs(array($this->requestStack, $this->urlGenerator))
       ->setMethods(array('batchGet', 'drupalInstallationAttempted'))
       ->getMock();
+    $this->root = dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__))));
 
     $this->formBuilder = new TestFormBuilder($this->formValidator, $this->formSubmitter, $this->formCache, $this->moduleHandler, $this->eventDispatcher, $this->requestStack, $this->classResolver, $this->themeManager, $this->csrfToken, $this->kernel);
     $this->formBuilder->setCurrentUser($this->account);
diff --git a/core/tests/Drupal/Tests/Core/Menu/LocalTaskIntegrationTest.php b/core/tests/Drupal/Tests/Core/Menu/LocalTaskIntegrationTest.php
index a295e277ecf5..57148491b764 100644
--- a/core/tests/Drupal/Tests/Core/Menu/LocalTaskIntegrationTest.php
+++ b/core/tests/Drupal/Tests/Core/Menu/LocalTaskIntegrationTest.php
@@ -47,9 +47,12 @@ abstract class LocalTaskIntegrationTest extends UnitTestCase {
    * {@inheritdoc}
    */
   protected function setUp() {
+    parent::setUp();
+
     $container = new ContainerBuilder();
     $config_factory = $this->getConfigFactoryStub(array());
     $container->set('config.factory', $config_factory);
+    $container->set('app.root', $this->root);
     \Drupal::setContainer($container);
     $this->container = $container;
   }
@@ -142,7 +145,7 @@ protected function assertLocalTasks($route_name, $expected_tasks, $route_params
 
     $directory_list = array();
     foreach ($this->directoryList as $key => $value) {
-      $directory_list[$key] = DRUPAL_ROOT . '/' . $value;
+      $directory_list[$key] = $this->root . '/' . $value;
     }
 
     $manager = $this->getLocalTaskManager($directory_list, $route_name, $route_params);
diff --git a/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php b/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
index a4750cace847..7767ff01996a 100644
--- a/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
@@ -55,7 +55,7 @@ protected function setUp() {
     );
 
     $this->namespaces = new \ArrayObject();
-    $this->namespaces['Drupal\plugin_test'] = DRUPAL_ROOT . '/core/modules/system/tests/modules/plugin_test/src';
+    $this->namespaces['Drupal\plugin_test'] = $this->root . '/core/modules/system/tests/modules/plugin_test/src';
   }
 
   /**
diff --git a/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTest.php b/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTest.php
index 740437245dbc..ff14dae1d3b8 100644
--- a/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTest.php
+++ b/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTest.php
@@ -293,7 +293,7 @@ public function testPathBasedURLGeneration() {
         // To reproduce the values install Drupal like that and use a debugger.
         $server = [
           'SCRIPT_NAME' => '/subdir/index.php',
-          'SCRIPT_FILENAME' => DRUPAL_ROOT . '/index.php',
+          'SCRIPT_FILENAME' => $this->root . '/index.php',
           'SERVER_NAME' => 'http://www.example.com',
         ];
         $request = Request::create('/subdir/' . $script_path, 'GET', [], [], [], $server);
diff --git a/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php b/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php
index eb8881d7a9d7..4e2b8cdb5a58 100644
--- a/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php
+++ b/core/tests/Drupal/Tests/Core/Theme/RegistryTest.php
@@ -49,6 +49,8 @@ class RegistryTest extends UnitTestCase {
    * {@inheritdoc}
    */
   protected function setUp() {
+    parent::setUp();
+
     $this->cache = $this->getMock('Drupal\Core\Cache\CacheBackendInterface');
     $this->lock = $this->getMock('Drupal\Core\Lock\LockBackendInterface');
     $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
@@ -65,7 +67,7 @@ public function testGetRegistryForModule() {
     $this->registry->setBaseThemes(array());
 
     // Include the module so that hook_theme can be called.
-    include_once DRUPAL_ROOT . '/core/modules/system/tests/modules/theme_test/theme_test.module';
+    include_once $this->root . '/core/modules/system/tests/modules/theme_test/theme_test.module';
     $this->moduleHandler->expects($this->once())
       ->method('getImplementations')
       ->with('theme')
@@ -96,7 +98,7 @@ public function testGetRegistryForModule() {
   }
 
   protected function setupTheme($theme_name = NULL) {
-    $this->registry = new TestRegistry($this->cache, $this->lock, $this->moduleHandler, $theme_name);
+    $this->registry = new TestRegistry($this->root, $this->cache, $this->lock, $this->moduleHandler, $theme_name);
   }
 
 }
diff --git a/core/tests/Drupal/Tests/Core/Utility/UnroutedUrlAssemblerTest.php b/core/tests/Drupal/Tests/Core/Utility/UnroutedUrlAssemblerTest.php
index 03b33754260d..1790aefe7307 100644
--- a/core/tests/Drupal/Tests/Core/Utility/UnroutedUrlAssemblerTest.php
+++ b/core/tests/Drupal/Tests/Core/Utility/UnroutedUrlAssemblerTest.php
@@ -97,7 +97,7 @@ public function testAssembleWithLocalUri($uri, array $options, $subdir, $expecte
       // To reproduce the values install Drupal like that and use a debugger.
       $server = [
         'SCRIPT_NAME' => '/subdir/index.php',
-        'SCRIPT_FILENAME' => DRUPAL_ROOT . '/index.php',
+        'SCRIPT_FILENAME' => $this->root . '/index.php',
         'SERVER_NAME' => 'http://www.example.com',
       ];
       $request = Request::create('/subdir');
diff --git a/core/tests/Drupal/Tests/UnitTestCase.php b/core/tests/Drupal/Tests/UnitTestCase.php
index d37a04042bfd..43748e8ebe05 100644
--- a/core/tests/Drupal/Tests/UnitTestCase.php
+++ b/core/tests/Drupal/Tests/UnitTestCase.php
@@ -26,6 +26,13 @@ abstract class UnitTestCase extends \PHPUnit_Framework_TestCase {
    */
   protected $randomGenerator;
 
+  /**
+   * The app root.
+   *
+   * @var string
+   */
+  protected $root;
+
   /**
    * {@inheritdoc}
    */
@@ -34,6 +41,8 @@ protected function setUp() {
     // Ensure that an instantiated container in the global state of \Drupal from
     // a previous test does not leak into this test.
     \Drupal::setContainer(NULL);
+
+    $this->root = dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__))));
   }
 
   /**
diff --git a/core/tests/bootstrap.php b/core/tests/bootstrap.php
index e74dc2416ef0..76f745cf8178 100644
--- a/core/tests/bootstrap.php
+++ b/core/tests/bootstrap.php
@@ -83,7 +83,6 @@ function drupal_phpunit_register_extension_dirs(Composer\Autoload\ClassLoader $l
 
 // Look into removing these later.
 define('REQUEST_TIME', (int) $_SERVER['REQUEST_TIME']);
-define('DRUPAL_ROOT', realpath(__DIR__ . '/../../'));
 
 // Set sane locale settings, to ensure consistent string, dates, times and
 // numbers handling.
diff --git a/core/themes/engines/phptemplate/phptemplate.engine b/core/themes/engines/phptemplate/phptemplate.engine
index a4eee497a759..232f78d343ef 100644
--- a/core/themes/engines/phptemplate/phptemplate.engine
+++ b/core/themes/engines/phptemplate/phptemplate.engine
@@ -51,7 +51,7 @@ function phptemplate_render_template($template_file, $variables) {
   ob_start();
 
   // Include the template file
-  include DRUPAL_ROOT . '/' . $template_file;
+  include \Drupal::root() . '/' . $template_file;
 
   // End buffering and return its contents
   return ob_get_clean();
-- 
GitLab