diff --git a/core/core.services.yml b/core/core.services.yml
index bbc9e8e..fe0dc21 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -636,6 +636,9 @@ services:
   event_dispatcher:
     class: Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher
     arguments: ['@service_container']
+  app:
+    class: Drupal\Core\App
+    arguments: ['@app.root']
   app.root:
     class: SplString
     factory: app.root.factory:get
@@ -1114,7 +1117,7 @@ services:
       - { name: event_subscriber }
   redirect_response_subscriber:
     class: Drupal\Core\EventSubscriber\RedirectResponseSubscriber
-    arguments: ['@unrouted_url_assembler', '@router.request_context']
+    arguments: ['@unrouted_url_assembler', '@app']
     tags:
       - { name: event_subscriber }
   redirect_leading_slashes_subscriber:
diff --git a/core/includes/common.inc b/core/includes/common.inc
index 5d62aad..3c6f740 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -412,7 +412,7 @@ function drupal_set_time_limit($time_limit) {
  * - http://example.com/drupal/folder returns "/drupal/folder/".
  */
 function base_path() {
-  return $GLOBALS['base_path'];
+  return \Drupal::app()->getBasePath() . '/';
 }
 
 /**
diff --git a/core/includes/file.inc b/core/includes/file.inc
index 3e5eb8c..d915daa 100644
--- a/core/includes/file.inc
+++ b/core/includes/file.inc
@@ -216,7 +216,7 @@ function file_create_url($uri) {
       // If this is not a properly formatted stream, then it is a shipped file.
       // Therefore, return the urlencoded URI with the base URL prepended.
       $options = UrlHelper::parse($uri);
-      $path = $GLOBALS['base_url'] . '/' . UrlHelper::encodePath($options['path']);
+      $path = \Drupal::app()->getBaseUrl() . '/' . UrlHelper::encodePath($options['path']);
       // Append the query.
       if ($options['query']) {
         $path .= '?' . UrlHelper::buildQuery($options['query']);
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index ffe27e0..da9e2d2 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -936,8 +936,7 @@ function install_redirect_url($install_state) {
  * @see install_redirect_url()
  */
 function install_full_redirect_url($install_state) {
-  global $base_url;
-  return $base_url . '/' . install_redirect_url($install_state);
+  return \Drupal::app()->getBaseUrl() . '/' . install_redirect_url($install_state);
 }
 
 /**
@@ -1872,7 +1871,7 @@ function install_check_translations($langcode, $server_pattern) {
       'title'       => t('Translations directory'),
       'value'       => t('The translations directory does not exist.'),
       'severity'    => REQUIREMENT_ERROR,
-      'description' => t('The installer requires that you create a translations directory as part of the installation process. Create the directory %translations_directory . More details about installing Drupal are available in <a href=":install_txt">INSTALL.txt</a>.', array('%translations_directory' => $translations_directory, ':install_txt' => base_path() . 'core/INSTALL.txt')),
+      'description' => t('The installer requires that you create a translations directory as part of the installation process. Create the directory %translations_directory . More details about installing Drupal are available in <a href=":install_txt">INSTALL.txt</a>.', array('%translations_directory' => $translations_directory, ':install_txt' => \Drupal::app()->getBasePath() . 'core/INSTALL.txt')),
     );
   }
   else {
@@ -2065,7 +2064,7 @@ function install_check_requirements($install_state) {
             '@drupal' => drupal_install_profile_distribution_name(),
             '%file' => $file,
             '%default_file' => $default_file,
-            ':install_txt' => base_path() . 'core/INSTALL.txt'
+            ':install_txt' => \Drupal::app()->getBasePath() . 'core/INSTALL.txt'
           )),
       );
     }
@@ -2115,7 +2114,7 @@ function install_check_requirements($install_state) {
               '@drupal' => drupal_install_profile_distribution_name(),
               '%file' => $file,
               '%default_file' => $default_file,
-              ':install_txt' => base_path() . 'core/INSTALL.txt',
+              ':install_txt' => \Drupal::app()->getBasePath() . 'core/INSTALL.txt',
               ':handbook_url' => 'https://www.drupal.org/server-permissions'
             )),
         );
diff --git a/core/includes/install.inc b/core/includes/install.inc
index bae87d7..cecdfb0 100644
--- a/core/includes/install.inc
+++ b/core/includes/install.inc
@@ -841,12 +841,11 @@ function drupal_install_fix_file($file, $mask, $message = TRUE) {
  *   An installer path.
  */
 function install_goto($path) {
-  global $base_url;
   $headers = array(
     // Not a permanent redirect.
     'Cache-Control' => 'no-cache',
   );
-  $response = new RedirectResponse($base_url . '/' . $path, 302, $headers);
+  $response = new RedirectResponse(\Drupal::app()->getBaseUrl() . '/' . $path, 302, $headers);
   $response->send();
 }
 
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 04b41ce..764881f 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -1341,7 +1341,7 @@ function template_preprocess_page(&$variables) {
     }
   }
 
-  $variables['base_path']         = base_path();
+  $variables['base_path']         = \Drupal::app()->getBasePath() . '/';
   $variables['front_page']        = \Drupal::url('<front>');
   $variables['language']          = $language_interface;
 
diff --git a/core/lib/Drupal.php b/core/lib/Drupal.php
index a33c265..87bf43c 100644
--- a/core/lib/Drupal.php
+++ b/core/lib/Drupal.php
@@ -721,4 +721,14 @@ public static function entityDefinitionUpdateManager() {
     return static::getContainer()->get('entity.definition_update_manager');
   }
 
+  /**
+   * Returns the application helper.
+   *
+   * @return \Drupal\Core\App
+   *   The application helper.
+   */
+  public static function app() {
+    return static::getContainer()->get('app');
+  }
+
 }
diff --git a/core/lib/Drupal/Core/App.php b/core/lib/Drupal/Core/App.php
new file mode 100644
index 0000000..2aa4d6b
--- /dev/null
+++ b/core/lib/Drupal/Core/App.php
@@ -0,0 +1,142 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\App.
+ */
+
+namespace Drupal\Core;
+
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Provides the applications base URL in a front controller independent way.
+ */
+class App {
+
+  /**
+   * The current request.
+   *
+   * @var \Symfony\Component\HttpFoundation\Request
+   */
+  protected $request;
+
+  /**
+   * The absolute path to the applications root directory.
+   *
+   * @var string
+   */
+  protected $root;
+
+  /**
+   * The base URL of the application.
+   *
+   * @var string
+   */
+  protected $baseUrl;
+
+  /**
+   * The path part of the base URL.
+   *
+   * @var string
+   */
+  protected $basePath;
+
+  /**
+   * Constructs a new app object.
+   *
+   * @param string $root
+   *   The absolute path to the Drupal root directory.
+   */
+  public function __construct($root) {
+    $this->root = $root;
+  }
+
+  /**
+   * Sets the current request.
+   *
+   * @param \Symfony\Component\HttpFonudation\Request
+   *   The current request.
+   */
+  public function setRequest(Request $request) {
+    if ($request != $this->request) {
+      $this->request = $request;
+      $this->reset();
+    }
+  }
+
+  /**
+   * Returns the base URL of the application.
+   *
+   * @return string
+   *   The base URL of the application.
+   */
+  public function getBaseUrl() {
+    if (!isset($this->baseUrl)) {
+      $this->prepareBaseUrl();
+    }
+
+    return $this->baseUrl;
+  }
+
+  /**
+   * Returns the path part of the base URL.
+   *
+   * @return string
+   *   The path part of the base URL.
+   */
+  public function getBasePath() {
+    if (!isset($this->basePath)) {
+      $this->prepareBasePath();
+    }
+
+    return $this->basePath;
+  }
+
+  /**
+   * Resets internal state.
+   */
+  protected function reset() {
+    $this->baseUrl = NULL;
+    $this->basePath = NULL;
+  }
+
+  /**
+   * Computes the base URL.
+   */
+  protected function prepareBaseUrl() {
+    $this->baseUrl = $this->request->getSchemeAndHttpHost() . $this->getBasePath();
+  }
+
+  /**
+   * Computes the base path.
+   */
+  protected function prepareBasePath() {
+    $this->basePath = $this->request->getBasePath();
+
+    if ($this->basePath) {
+      $script_path = $this->realpath($this->request->server->get('SCRIPT_FILENAME'));
+      // Remove trailing filename from path to front controller.
+      $script_base = substr($script_path, 0, -strlen(basename($script_path)) - 1);
+      // Remove leading document root from path to front controller.
+      $script_subdir = substr($script_base, strlen($this->realpath($this->root)));
+      if ($script_subdir) {
+        // Base path is request basePath - script subdir
+        $this->basePath = substr($this->request->getBasePath(), 0, -strlen($script_subdir));
+      }
+    }
+  }
+
+  /**
+   * Wraps the PHP realpath for testing purposes.
+   *
+   * @param string $path
+   *   The path to be converted.
+   * @return string
+   *   The true path with symlinks, and relative portions, resolved.
+   */
+  protected function realpath($path) {
+    return realpath($path);
+  }
+
+}
diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index 628bba3..a7638f7 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -526,8 +526,14 @@ public function preHandle(Request $request) {
     // Register stream wrappers.
     $this->container->get('stream_wrapper_manager')->register();
 
+    // Initialize application from request.
+    $app = $this->container->get('app');
+    $app->setRequest($request);
+
     // Initialize legacy request globals.
-    $this->initializeRequestGlobals($request);
+    $GLOBALS['base_url'] = $app->getBaseUrl();
+    $GLOBALS['base_path'] = $app->getBasePath() . '/';
+    $GLOBALS['base_root'] = $request->getSchemeAndHttpHost();
 
     // Put the request on the stack.
     $this->container->get('request_stack')->push($request);
@@ -853,6 +859,12 @@ protected function initializeContainer() {
       }
     }
 
+    if (($request_stack = $this->container->get('request_stack', ContainerInterface::NULL_ON_INVALID_REFERENCE))) {
+      if ($request = $request_stack->getMasterRequest()) {
+        $this->container->get('app')->setRequest($request);
+      }
+    }
+
     if (!empty($current_user_id)) {
       $this->container->get('current_user')->setInitialAccountId($current_user_id);
     }
@@ -979,46 +991,6 @@ protected function initializeSettings(Request $request) {
   }
 
   /**
-   * Bootstraps the legacy global request variables.
-   *
-   * @param \Symfony\Component\HttpFoundation\Request $request
-   *   The current request.
-   *
-   * @todo D8: Eliminate this entirely in favor of Request object.
-   */
-  protected function initializeRequestGlobals(Request $request) {
-    global $base_url;
-    // Set and derived from $base_url by this function.
-    global $base_path, $base_root;
-    global $base_secure_url, $base_insecure_url;
-
-    // Create base URL.
-    $base_root = $request->getSchemeAndHttpHost();
-    $base_url = $base_root;
-
-    // For a request URI of '/index.php/foo', $_SERVER['SCRIPT_NAME'] is
-    // '/index.php', whereas $_SERVER['PHP_SELF'] is '/index.php/foo'.
-    if ($dir = rtrim(dirname($request->server->get('SCRIPT_NAME')), '\/')) {
-      // Remove "core" directory if present, allowing install.php,
-      // authorize.php, and others to auto-detect a base path.
-      $core_position = strrpos($dir, '/core');
-      if ($core_position !== FALSE && strlen($dir) - 5 == $core_position) {
-        $base_path = substr($dir, 0, $core_position);
-      }
-      else {
-        $base_path = $dir;
-      }
-      $base_url .= $base_path;
-      $base_path .= '/';
-    }
-    else {
-      $base_path = '/';
-    }
-    $base_secure_url = str_replace('http://', 'https://', $base_url);
-    $base_insecure_url = str_replace('https://', 'http://', $base_url);
-  }
-
-  /**
    * Returns service instances to persist from an old container to a new one.
    */
   protected function getServicesToPersist(ContainerInterface $container) {
diff --git a/core/lib/Drupal/Core/EventSubscriber/RedirectResponseSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/RedirectResponseSubscriber.php
index 435246d..63f21a8 100644
--- a/core/lib/Drupal/Core/EventSubscriber/RedirectResponseSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/RedirectResponseSubscriber.php
@@ -9,6 +9,7 @@
 
 use Drupal\Component\HttpFoundation\SecuredRedirectResponse;
 use Drupal\Component\Utility\UrlHelper;
+use Drupal\Core\App;
 use Drupal\Core\Routing\LocalRedirectResponse;
 use Drupal\Core\Routing\RequestContext;
 use Drupal\Core\Utility\UnroutedUrlAssemblerInterface;
@@ -32,16 +33,23 @@ class RedirectResponseSubscriber implements EventSubscriberInterface {
   protected $unroutedUrlAssembler;
 
   /**
+   * The application object.
+   *
+   * @var \Drupal\Core\App
+   */
+  protected $app;
+
+  /**
    * Constructs a RedirectResponseSubscriber object.
    *
    * @param \Drupal\Core\Utility\UnroutedUrlAssemblerInterface $url_assembler
    *   The unrouted URL assembler service.
-   * @param \Drupal\Core\Routing\RequestContext $request_context
-   *   The request context.
+   * @param \Drupal\Core\App $app
+   *   The application object.
    */
   public function __construct(UnroutedUrlAssemblerInterface $url_assembler, RequestContext $request_context) {
     $this->unroutedUrlAssembler = $url_assembler;
-    $this->requestContext = $request_context;
+    $this->app = $app;
   }
 
   /**
@@ -77,7 +85,7 @@ public function checkRedirectUrl(FilterResponseEvent $event) {
           // concrete implementation. Default to LocalRedirectResponse, which
           // considers only redirects to within the same site as safe.
           $safe_response = LocalRedirectResponse::createFromRedirectResponse($response);
-          $safe_response->setRequestContext($this->requestContext);
+          $safe_response->setBaseUrl($this->app->getBaseUrl());
         }
         catch (\InvalidArgumentException $e) {
           // If the above failed, it's because the redirect target wasn't
diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php
index bb7034f..31a1f3f 100644
--- a/core/lib/Drupal/Core/Form/FormBuilder.php
+++ b/core/lib/Drupal/Core/Form/FormBuilder.php
@@ -914,9 +914,8 @@ public function doBuildForm($form_id, &$element, FormStateInterface &$form_state
     // Special handling if we're on the top level form element.
     if (isset($element['#type']) && $element['#type'] == 'form') {
       if (!empty($element['#https']) && !UrlHelper::isExternal($element['#action'])) {
-        global $base_root;
-
         // Not an external URL so ensure that it is secure.
+        $base_root = $this->requestStack->getCurrentRequest()->getSchemeAndHttpHost();
         $element['#action'] = str_replace('http://', 'https://', $base_root) . $element['#action'];
       }
 
diff --git a/core/lib/Drupal/Core/Installer/Exception/AlreadyInstalledException.php b/core/lib/Drupal/Core/Installer/Exception/AlreadyInstalledException.php
index c2b7914..82d2a7d 100644
--- a/core/lib/Drupal/Core/Installer/Exception/AlreadyInstalledException.php
+++ b/core/lib/Drupal/Core/Installer/Exception/AlreadyInstalledException.php
@@ -29,8 +29,8 @@ public function __construct(TranslationInterface $string_translation) {
 <li>To upgrade an existing installation, proceed to the <a href=":update-url">update script</a>.</li>
 <li>View your <a href=":base-url">existing site</a>.</li>
 </ul>', array(
-      ':base-url' => $GLOBALS['base_url'],
-      ':update-url' => $GLOBALS['base_path'] . 'update.php',
+      ':base-url' => \Drupal::app()->getBaseUrl(),
+      ':update-url' => \Drupal::app()->getBasePath() . '/update.php',
     ));
     parent::__construct($message, $title);
   }
diff --git a/core/lib/Drupal/Core/Mail/MailFormatHelper.php b/core/lib/Drupal/Core/Mail/MailFormatHelper.php
index 6ea977f..0cb1397 100644
--- a/core/lib/Drupal/Core/Mail/MailFormatHelper.php
+++ b/core/lib/Drupal/Core/Mail/MailFormatHelper.php
@@ -336,21 +336,18 @@ protected static function wrapMailLine(&$line, $key, $values) {
    * \Drupal\Core\Mail\MailFormatHelper::htmlToText().
    */
   protected static function htmlToMailUrls($match = NULL, $reset = FALSE) {
-    // @todo Use request context instead.
-    global $base_url, $base_path;
-
     if ($reset) {
       // Reset internal URL list.
       static::$urls = array();
     }
     else {
       if (empty(static::$regexp)) {
-        static::$regexp = '@^' . preg_quote($base_path, '@') . '@';
+        static::$regexp = '@^' . preg_quote(\Drupal::app()->getBasePath() . '/', '@') . '@';
       }
       if ($match) {
         list(, , $url, $label) = $match;
         // Ensure all URLs are absolute.
-        static::$urls[] = strpos($url, '://') ? $url : preg_replace(static::$regexp, $base_url . '/', $url);
+        static::$urls[] = strpos($url, '://') ? $url : preg_replace(static::$regexp, \Drupal::app()->getBaseUrl() . '/', $url);
         return $label . ' [' . count(static::$urls) . ']';
       }
     }
diff --git a/core/lib/Drupal/Core/Routing/LocalAwareRedirectResponseTrait.php b/core/lib/Drupal/Core/Routing/LocalAwareRedirectResponseTrait.php
index 8ffa2f6..1aca77e 100644
--- a/core/lib/Drupal/Core/Routing/LocalAwareRedirectResponseTrait.php
+++ b/core/lib/Drupal/Core/Routing/LocalAwareRedirectResponseTrait.php
@@ -15,41 +15,41 @@
 trait LocalAwareRedirectResponseTrait {
 
   /**
-   * The request context.
+   * The base URL of the application.
    *
-   * @var \Drupal\Core\Routing\RequestContext
+   * @var string
    */
-  protected $requestContext;
+  protected $baseUrl;
 
   /**
    * {@inheritdoc}
    */
   protected function isLocal($url) {
-    return !UrlHelper::isExternal($url) || UrlHelper::externalIsLocal($url, $this->getRequestContext()->getCompleteBaseUrl());
+    return !UrlHelper::isExternal($url) || UrlHelper::externalIsLocal($url, $this->getBaseUrl());
   }
 
   /**
-   * Returns the request context.
+   * Returns the base URL.
    *
-   * @return \Drupal\Core\Routing\RequestContext
+   * @return string
    */
-  protected function getRequestContext() {
-    if (!isset($this->requestContext)) {
-      $this->requestContext = \Drupal::service('router.request_context');
+  protected function getBaseUrl() {
+    if (!isset($this->baseUrl)) {
+      $this->baseUrl = \Drupal::app()->getBaseUrl();
     }
-    return $this->requestContext;
+    return $this->baseUrl;
   }
 
   /**
-   * Sets the request context.
+   * Sets the base URL.
    *
-   * @param \Drupal\Core\Routing\RequestContext $request_context
-   *   The request context.
+   * @param string
+   *   The base URL of the application.
    *
    * @return $this
    */
-  public function setRequestContext(RequestContext $request_context) {
-    $this->requestContext = $request_context;
+  public function setBaseUrl($base_url) {
+    $this->baseUrl = $base_url;
 
     return $this;
   }
diff --git a/core/lib/Drupal/Core/Routing/RequestContext.php b/core/lib/Drupal/Core/Routing/RequestContext.php
index 2953251..3c91606 100644
--- a/core/lib/Drupal/Core/Routing/RequestContext.php
+++ b/core/lib/Drupal/Core/Routing/RequestContext.php
@@ -20,13 +20,6 @@
 class RequestContext extends SymfonyRequestContext {
 
   /**
-   * The scheme, host and base path, for example "http://example.com/d8".
-   *
-   * @var string
-   */
-  protected $completeBaseUrl;
-
-  /**
    * Populates the context from the current request from the request stack.
    *
    * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
@@ -36,37 +29,4 @@ public function fromRequestStack(RequestStack $request_stack) {
     $this->fromRequest($request_stack->getCurrentRequest());
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function fromRequest(Request $request) {
-    parent::fromRequest($request);
-
-    // @todo Extract the code in DrupalKernel::initializeRequestGlobals.
-    //   See https://www.drupal.org/node/2404601
-    if (isset($GLOBALS['base_url'])) {
-      $this->setCompleteBaseUrl($GLOBALS['base_url']);
-    }
-  }
-
-  /**
-   * Gets the scheme, host and base path.
-   *
-   * For example, in an installation in a subdirectory "d8", it should be
-   * "https://example.com/d8".
-   */
-  public function getCompleteBaseUrl() {
-    return $this->completeBaseUrl;
-  }
-
-  /**
-   * Sets the complete base URL for the Request context.
-   *
-   * @param string $complete_base_url
-   *   The complete base URL.
-   */
-  public function setCompleteBaseUrl($complete_base_url) {
-    $this->completeBaseUrl = $complete_base_url;
-  }
-
 }
diff --git a/core/lib/Drupal/Core/StreamWrapper/PublicStream.php b/core/lib/Drupal/Core/StreamWrapper/PublicStream.php
index e88eb53..857b6b5 100644
--- a/core/lib/Drupal/Core/StreamWrapper/PublicStream.php
+++ b/core/lib/Drupal/Core/StreamWrapper/PublicStream.php
@@ -53,7 +53,7 @@ public function getDirectoryPath() {
    */
   public function getExternalUrl() {
     $path = str_replace('\\', '/', $this->getTarget());
-    return static::baseUrl() . '/' . UrlHelper::encodePath($path);
+    return \Drupal::app()->getBaseUrl() . '/' . UrlHelper::encodePath($path);
   }
 
   /**
diff --git a/core/modules/book/book.module b/core/modules/book/book.module
index f55f5d6..9baade2 100644
--- a/core/modules/book/book.module
+++ b/core/modules/book/book.module
@@ -467,10 +467,9 @@ function template_preprocess_book_navigation(&$variables) {
  *   - depth: The max depth of the book.
  */
 function template_preprocess_book_export_html(&$variables) {
-  global $base_url;
   $language_interface = \Drupal::languageManager()->getCurrentLanguage();
 
-  $variables['base_url'] = $base_url;
+  $variables['base_url'] = \Drupal::app()->getBaseUrl();
   $variables['language'] = $language_interface;
   $variables['language_rtl'] = ($language_interface->getDirection() == LanguageInterface::DIRECTION_RTL);
 
diff --git a/core/modules/color/color.module b/core/modules/color/color.module
index 055d750..7e7379b 100644
--- a/core/modules/color/color.module
+++ b/core/modules/color/color.module
@@ -485,7 +485,7 @@ function color_scheme_form_submit($form, FormStateInterface $form_state) {
 
       // Return the path to where this CSS file originated from, stripping
       // off the name of the file at the end of the path.
-      $css_optimizer->rewriteFileURIBasePath = base_path() . dirname($paths['source'] . $file) . '/';
+      $css_optimizer->rewriteFileURIBasePath = \Drupal::app()->getBasePath() . dirname($paths['source'] . $file) . '/';
 
       // Prefix all paths within this CSS file, ignoring absolute paths.
       $style = preg_replace_callback('/url\([\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\)/i', array($css_optimizer, 'rewriteFileURI'), $style);
@@ -567,7 +567,7 @@ function _color_rewrite_stylesheet($theme, &$info, &$paths, $palette, $style) {
 
   // Replace paths to images.
   foreach ($paths['map'] as $before => $after) {
-    $before = base_path() . $paths['source'] . $before;
+    $before = \Drupal::app()->getBasePath() . $paths['source'] . $before;
     $before = preg_replace('`(^|/)(?!../)([^/]+)/../`', '$1', $before);
     $output = str_replace($before, $after, $output);
   }
diff --git a/core/modules/comment/src/Plugin/views/row/Rss.php b/core/modules/comment/src/Plugin/views/row/Rss.php
index df7200f..2da2111 100644
--- a/core/modules/comment/src/Plugin/views/row/Rss.php
+++ b/core/modules/comment/src/Plugin/views/row/Rss.php
@@ -65,8 +65,6 @@ public function buildOptionsForm_summary_options() {
   }
 
   public function render($row) {
-    global $base_url;
-
     $cid = $row->{$this->field_alias};
     if (!is_numeric($cid)) {
       return;
@@ -97,7 +95,7 @@ public function render($row) {
       ),
       array(
         'key' => 'guid',
-        'value' => 'comment ' . $comment->id() . ' at ' . $base_url,
+        'value' => 'comment ' . $comment->id() . ' at ' . \Drupal::app()->getBaseUrl(),
         'attributes' => array('isPermaLink' => 'false'),
       ),
     );
diff --git a/core/modules/config_translation/src/Tests/ConfigTranslationUiThemeTest.php b/core/modules/config_translation/src/Tests/ConfigTranslationUiThemeTest.php
index cfb547f..23e53cd 100644
--- a/core/modules/config_translation/src/Tests/ConfigTranslationUiThemeTest.php
+++ b/core/modules/config_translation/src/Tests/ConfigTranslationUiThemeTest.php
@@ -70,7 +70,7 @@ public function testThemeDiscovery() {
       ':label' => 'Install and set as default',
       ':theme' => $theme,
     ]);
-    $this->drupalGet($GLOBALS['base_root'] . $elements[0]['href'], ['external' => TRUE]);
+    $this->drupalGet(\Drupal::request()->getSchemeAndHttpHost() . $elements[0]['href'], ['external' => TRUE]);
 
     $translation_base_url = 'admin/config/development/performance/translate';
     $this->drupalGet($translation_base_url);
diff --git a/core/modules/file/tests/file_test/file_test.module b/core/modules/file/tests/file_test/file_test.module
index 7b25af4..402e1a6 100644
--- a/core/modules/file/tests/file_test/file_test.module
+++ b/core/modules/file/tests/file_test/file_test.module
@@ -260,7 +260,7 @@ function file_test_file_url_alter(&$uri) {
       $path = str_replace('\\', '/', $path);
 
       // Generate a root-relative URL.
-      $uri = base_path() . '/' . $path;
+      $uri = \Drupal::app()->getBasePath() . '/' . $path;
     }
   }
   // Test alteration of file URLs to use protocol-relative URLs.
@@ -283,7 +283,7 @@ function file_test_file_url_alter(&$uri) {
       $path = str_replace('\\', '/', $path);
 
       // Generate a protocol-relative URL.
-      $uri = '/' . base_path() . '/' . $path;
+      $uri = '/' . \Drupal::app()->getBasePath() . '/' . $path;
     }
   }
 }
diff --git a/core/modules/filter/filter.api.php b/core/modules/filter/filter.api.php
index a2ba9b0..ace33da 100644
--- a/core/modules/filter/filter.api.php
+++ b/core/modules/filter/filter.api.php
@@ -35,7 +35,7 @@ function hook_filter_info_alter(&$info) {
  */
 function hook_filter_secure_image_alter(&$image) {
   // Turn an invalid image into an error indicator.
-  $image->setAttribute('src', base_path() . 'core/misc/icons/e32700/error.svg');
+  $image->setAttribute('src', \Drupal::app()->getBasePath() . '/core/misc/icons/ea2800/error.svg');
   $image->setAttribute('alt', t('Image removed.'));
   $image->setAttribute('title', t('This image has been removed. For security reasons, only images from the local domain are allowed.'));
 
diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module
index 46046d1..f9cd0c3 100644
--- a/core/modules/filter/filter.module
+++ b/core/modules/filter/filter.module
@@ -765,7 +765,7 @@ function _filter_html_escape($text) {
  */
 function _filter_html_image_secure_process($text) {
   // Find the path (e.g. '/') to Drupal root.
-  $base_path = base_path();
+  $base_path = \Drupal::app()->getBasePath() . '/';
   $base_path_length = Unicode::strlen($base_path);
 
   // Find the directory on the server where index.php resides.
@@ -813,7 +813,7 @@ function _filter_html_image_secure_process($text) {
  */
 function filter_filter_secure_image_alter(&$image) {
   // Turn an invalid image into an error indicator.
-  $image->setAttribute('src', base_path() . 'core/misc/icons/e32700/error.svg');
+  $image->setAttribute('src', \Drupal::app()->getBasePath() . '/core/misc/icons/ea2800/error.svg');
   $image->setAttribute('alt', t('Image removed.'));
   $image->setAttribute('title', t('This image has been removed. For security reasons, only images from the local domain are allowed.'));
   $image->setAttribute('height', '16');
diff --git a/core/modules/filter/src/Plugin/Filter/FilterHtml.php b/core/modules/filter/src/Plugin/Filter/FilterHtml.php
index 63985ff..ca8e284 100644
--- a/core/modules/filter/src/Plugin/Filter/FilterHtml.php
+++ b/core/modules/filter/src/Plugin/Filter/FilterHtml.php
@@ -335,8 +335,6 @@ public function getHTMLRestrictions() {
    * {@inheritdoc}
    */
   public function tips($long = FALSE) {
-    global $base_url;
-
     if (!($allowed_html = $this->settings['allowed_html'])) {
       return;
     }
@@ -353,7 +351,7 @@ public function tips($long = FALSE) {
     $output .= '<p>' . $this->t('This site allows HTML content. While learning all of HTML may feel intimidating, learning how to use a very small number of the most basic HTML "tags" is very easy. This table provides examples for each tag that is enabled on this site.') . '</p>';
     $output .= '<p>' . $this->t('For more information see W3C\'s <a href=":html-specifications">HTML Specifications</a> or use your favorite search engine to find other sites that explain HTML.', array(':html-specifications' => 'http://www.w3.org/TR/html/')) . '</p>';
     $tips = array(
-      'a' => array($this->t('Anchors are used to make links to other pages.'), '<a href="' . $base_url . '">' . Html::escape(\Drupal::config('system.site')->get('name')) . '</a>'),
+      'a' => array($this->t('Anchors are used to make links to other pages.'), '<a href="' . \Drupal::app()->getBaseUrl() . '">' . Html::escape(\Drupal::config('system.site')->get('name')) . '</a>'),
       'br' => array($this->t('By default line break tags are automatically added, so use this tag to add additional ones. Use of this tag is different because it is not used with an open/close pair like all the others. Use the extra " /" inside the tag to maintain XHTML 1.0 compatibility'), $this->t('Text with <br />line break')),
       'p' => array($this->t('By default paragraph tags are automatically added, so use this tag to add additional ones.'), '<p>' . $this->t('Paragraph one.') . '</p> <p>' . $this->t('Paragraph two.') . '</p>'),
       'strong' => array($this->t('Strong', array(), array('context' => 'Font weight')), '<strong>' . $this->t('Strong', array(), array('context' => 'Font weight')) . '</strong>'),
diff --git a/core/modules/language/src/Form/NegotiationUrlForm.php b/core/modules/language/src/Form/NegotiationUrlForm.php
index f90022f..0714391 100644
--- a/core/modules/language/src/Form/NegotiationUrlForm.php
+++ b/core/modules/language/src/Form/NegotiationUrlForm.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\language\Form;
 
+use Drupal\Core\App;
 use Drupal\Core\Form\ConfigFormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Language\LanguageInterface;
@@ -28,6 +29,13 @@ class NegotiationUrlForm extends ConfigFormBase {
   protected $languageManager;
 
   /**
+   * The application object.
+   *
+   * @var \Drupal\Core\App
+   */
+  protected $app;
+
+  /**
    * Constructs a new LanguageDeleteForm object.
    *
    * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
@@ -35,9 +43,10 @@ class NegotiationUrlForm extends ConfigFormBase {
    * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
    *   The language manager.
    */
-  public function __construct(ConfigFactoryInterface $config_factory, LanguageManagerInterface $language_manager) {
+  public function __construct(ConfigFactoryInterface $config_factory, LanguageManagerInterface $language_manager, App $app) {
     parent::__construct($config_factory);
     $this->languageManager = $language_manager;
+    $this->app = $app;
   }
 
   /**
@@ -46,7 +55,8 @@ public function __construct(ConfigFactoryInterface $config_factory, LanguageMana
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('config.factory'),
-      $container->get('language_manager')
+      $container->get('language_manager'),
+      $container->get('app')
     );
   }
 
@@ -68,7 +78,6 @@ protected function getEditableConfigNames() {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
-    global $base_url;
     $config = $this->config('language.negotiation');
 
     $form['language_negotiation_url_part'] = array(
@@ -120,7 +129,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
         '#title' => $language->isDefault() ? $this->t('%language (%langcode) path prefix (Default language)', $t_args) : $this->t('%language (%langcode) path prefix', $t_args),
         '#maxlength' => 64,
         '#default_value' => isset($prefixes[$langcode]) ? $prefixes[$langcode] : '',
-        '#field_prefix' => $base_url . '/',
+        '#field_prefix' => $this->app->getBaseUrl() . '/',
       );
       $form['domain'][$langcode] = array(
         '#type' => 'textfield',
diff --git a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php
index fc0d9d4..87be3e1 100644
--- a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php
+++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php
@@ -7,13 +7,16 @@
 
 namespace Drupal\language\Plugin\LanguageNegotiation;
 
+use Drupal\Core\App;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
 use Drupal\Core\PathProcessor\OutboundPathProcessorInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Render\BubbleableMetadata;
 use Drupal\Core\Url;
 use Drupal\language\LanguageNegotiationMethodBase;
 use Drupal\language\LanguageSwitcherInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\Request;
 
 /**
@@ -30,7 +33,7 @@
  *   config_route_name = "language.negotiation_url"
  * )
  */
-class LanguageNegotiationUrl extends LanguageNegotiationMethodBase implements InboundPathProcessorInterface, OutboundPathProcessorInterface, LanguageSwitcherInterface {
+class LanguageNegotiationUrl extends LanguageNegotiationMethodBase implements InboundPathProcessorInterface, OutboundPathProcessorInterface, LanguageSwitcherInterface, ContainerFactoryPluginInterface {
 
   /**
    * The language negotiation method id.
@@ -48,6 +51,30 @@ class LanguageNegotiationUrl extends LanguageNegotiationMethodBase implements In
   const CONFIG_DOMAIN = 'domain';
 
   /**
+   * The application object.
+   *
+   * @var \Drupal\Core\App
+   */
+  protected $app;
+
+  /**
+   * Constructs a new language negotiation URL method.
+   *
+   * @param \Drupal\Core\App
+   *   The application object.
+   */
+  public function __construct(App $app) {
+    $this->app = $app;
+  }
+
+  /**
+   * {@inheritdocs}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static($container->get('app'));
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function getLangcode(Request $request = NULL) {
@@ -183,7 +210,7 @@ public function processOutbound($path, &$options = array(), Request $request = N
         }
 
         // Add Drupal's subfolder from the base_path if there is one.
-        $options['base_url'] .= rtrim(base_path(), '/');
+        $options['base_url'] .= $this->app->getBasePath();
         if ($bubbleable_metadata) {
           $bubbleable_metadata->addCacheContexts(['languages:' . LanguageInterface::TYPE_URL, 'url.site']);
         }
diff --git a/core/modules/language/tests/src/Unit/LanguageNegotiationUrlTest.php b/core/modules/language/tests/src/Unit/LanguageNegotiationUrlTest.php
index f1d2914..bfe1726 100644
--- a/core/modules/language/tests/src/Unit/LanguageNegotiationUrlTest.php
+++ b/core/modules/language/tests/src/Unit/LanguageNegotiationUrlTest.php
@@ -5,7 +5,7 @@
  * Contains \Drupal\Tests\language\Unit\LanguageNegotiationUrlTest.
  */
 
-namespace Drupal\Tests\language\Unit {
+namespace Drupal\Tests\language\Unit;
 
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Language\LanguageInterface;
@@ -25,6 +25,13 @@ class LanguageNegotiationUrlTest extends UnitTestCase {
   protected $user;
 
   /**
+   * The application object.
+   *
+   * @var \Drupal\Core\App|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $app;
+
+  /**
    * {@inheritdoc}
    */
   protected function setUp() {
@@ -56,6 +63,14 @@ protected function setUp() {
     $this->user = $this->getMockBuilder('Drupal\Core\Session\AccountInterface')
       ->getMock();
 
+    // Create the app stub.
+    $this->app = $this->getMockBuilder('Drupal\Core\App')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $this->app->expects($this->any())
+      ->method('getBasePath')
+      ->will($this->returnvalue(''));
+
     $cache_contexts_manager = $this->getMockBuilder('Drupal\Core\Cache\Context\CacheContextsManager')
       ->disableOriginalConstructor()
       ->getMock();
@@ -85,7 +100,7 @@ public function testPathPrefix($prefix, $prefixes, $expected_langcode) {
     ]);
 
     $request = Request::create('/' . $prefix . '/foo', 'GET');
-    $method = new LanguageNegotiationUrl();
+    $method = new LanguageNegotiationUrl($this->app);
     $method->setLanguageManager($this->languageManager);
     $method->setConfig($config);
     $method->setCurrentUser($this->user);
@@ -174,7 +189,7 @@ public function testDomain($http_host, $domains, $expected_langcode) {
     ]);
 
     $request = Request::create('', 'GET', array(), array(), array(), array('HTTP_HOST' => $http_host));
-    $method = new LanguageNegotiationUrl();
+    $method = new LanguageNegotiationUrl($this->app);
     $method->setLanguageManager($this->languageManager);
     $method->setConfig($config);
     $method->setCurrentUser($this->user);
@@ -255,14 +270,3 @@ public function providerTestDomain() {
     return $domain_configuration;
   }
 }
-
-}
-
-// @todo Remove as part of https://www.drupal.org/node/2481833.
-namespace {
-  if (!function_exists('base_path')) {
-    function base_path() {
-      return '/';
-    }
-  }
-}
diff --git a/core/modules/node/src/Plugin/views/row/Rss.php b/core/modules/node/src/Plugin/views/row/Rss.php
index 3f2deee..ef6aefb 100644
--- a/core/modules/node/src/Plugin/views/row/Rss.php
+++ b/core/modules/node/src/Plugin/views/row/Rss.php
@@ -89,8 +89,6 @@ public function preRender($values) {
   }
 
   public function render($row) {
-    global $base_url;
-
     $nid = $row->{$this->field_alias};
     if (!is_numeric($nid)) {
       return;
@@ -121,7 +119,7 @@ public function render($row) {
       ),
       array(
         'key' => 'guid',
-        'value' => $node->id() . ' at ' . $base_url,
+        'value' => $node->id() . ' at ' . \Drupal::app()->getBaseUrl(),
         'attributes' => array('isPermaLink' => 'false'),
       ),
     );
diff --git a/core/modules/path/src/Form/PathFormBase.php b/core/modules/path/src/Form/PathFormBase.php
index 8eacb42..98ecf46 100644
--- a/core/modules/path/src/Form/PathFormBase.php
+++ b/core/modules/path/src/Form/PathFormBase.php
@@ -13,7 +13,6 @@
 use Drupal\Core\Path\AliasManagerInterface;
 use Drupal\Core\Path\AliasStorageInterface;
 use Drupal\Core\Path\PathValidatorInterface;
-use Drupal\Core\Routing\RequestContext;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -50,11 +49,11 @@
   protected $pathValidator;
 
   /**
-   * The request context.
+   * The application object.
    *
-   * @var \Drupal\Core\Routing\RequestContext
+   * @var \Drupal\Core\App.
    */
-  protected $requestContext;
+  protected $app;
 
   /**
    * Constructs a new PathController.
@@ -65,14 +64,14 @@
    *   The path alias manager.
    * @param \Drupal\Core\Path\PathValidatorInterface $path_validator
    *   The path validator.
-   * @param \Drupal\Core\Routing\RequestContext $request_context
-   *   The request context.
+   * @param \Drupal\Core\App $app
+   *   The application object.
    */
-  public function __construct(AliasStorageInterface $alias_storage, AliasManagerInterface $alias_manager, PathValidatorInterface $path_validator, RequestContext $request_context) {
+  public function __construct(AliasStorageInterface $alias_storage, AliasManagerInterface $alias_manager, PathValidatorInterface $path_validator, App $app) {
     $this->aliasStorage = $alias_storage;
     $this->aliasManager = $alias_manager;
     $this->pathValidator = $path_validator;
-    $this->requestContext = $request_context;
+    $this->app = $app;
   }
 
   /**
@@ -83,7 +82,7 @@ public static function create(ContainerInterface $container) {
       $container->get('path.alias_storage'),
       $container->get('path.alias_manager'),
       $container->get('path.validator'),
-      $container->get('router.request_context')
+      $container->get('app')
     );
   }
 
@@ -107,7 +106,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $pid = NU
       '#maxlength' => 255,
       '#size' => 45,
       '#description' => $this->t('Specify the existing path you wish to alias. For example: /node/28, /forum/1, /taxonomy/term/1.'),
-      '#field_prefix' => $this->requestContext->getCompleteBaseUrl(),
+      '#field_prefix' => $this->app->getBaseUrl(),
       '#required' => TRUE,
     );
     $form['alias'] = array(
@@ -117,7 +116,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $pid = NU
       '#maxlength' => 255,
       '#size' => 45,
       '#description' => $this->t('Specify an alternative path by which this data can be accessed. For example, type "/about" when writing an about page. Use a relative path with a slash in front.'),
-      '#field_prefix' => $this->requestContext->getCompleteBaseUrl(),
+      '#field_prefix' => $this->app->getBaseUrl(),
       '#required' => TRUE,
     );
 
diff --git a/core/modules/syslog/src/Logger/SysLog.php b/core/modules/syslog/src/Logger/SysLog.php
index a40762b..0aceedc 100644
--- a/core/modules/syslog/src/Logger/SysLog.php
+++ b/core/modules/syslog/src/Logger/SysLog.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\syslog\Logger;
 
+use Drupal\Core\App;
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Logger\LogMessageParserInterface;
 use Drupal\Core\Logger\RfcLoggerTrait;
@@ -33,6 +34,13 @@ class SysLog implements LoggerInterface {
   protected $parser;
 
   /**
+   * The application object.
+   *
+   * @var \Drupal\Core\App
+   */
+  protected $app;
+
+  /**
    * Stores whether there is a system logger connection opened or not.
    *
    * @var bool
@@ -46,10 +54,13 @@ class SysLog implements LoggerInterface {
    *   The configuration factory object.
    * @param \Drupal\Core\Logger\LogMessageParserInterface $parser
    *   The parser to use when extracting message variables.
+   * @param \Drupal\Core\App $app
+   *   The application object.
    */
-  public function __construct(ConfigFactoryInterface $config_factory, LogMessageParserInterface $parser) {
+  public function __construct(ConfigFactoryInterface $config_factory, LogMessageParserInterface $parser, App $app) {
     $this->config = $config_factory->get('syslog.settings');
     $this->parser = $parser;
+    $this->app = $app;
   }
 
   /**
@@ -69,8 +80,6 @@ protected function openConnection() {
    * {@inheritdoc}
    */
   public function log($level, $message, array $context = array()) {
-    global $base_url;
-
     // Ensure we have a connection available.
     $this->openConnection();
 
@@ -79,7 +88,7 @@ public function log($level, $message, array $context = array()) {
     $message = empty($message_placeholders) ? $message : strtr($message, $message_placeholders);
 
     $entry = strtr($this->config->get('format'), array(
-      '!base_url' => $base_url,
+      '!base_url' => $this->app->getBaseUrl(),
       '!timestamp' => $context['timestamp'],
       '!type' => $context['channel'],
       '!ip' => $context['ip'],
diff --git a/core/modules/syslog/syslog.services.yml b/core/modules/syslog/syslog.services.yml
index 78c7d38..e6eae8b 100644
--- a/core/modules/syslog/syslog.services.yml
+++ b/core/modules/syslog/syslog.services.yml
@@ -1,6 +1,6 @@
 services:
   logger.syslog:
     class: Drupal\syslog\Logger\SysLog
-    arguments: ['@config.factory', '@logger.log_message_parser']
+    arguments: ['@config.factory', '@logger.log_message_parser', '@app']
     tags:
       - { name: logger }
diff --git a/core/modules/system/src/Form/SiteInformationForm.php b/core/modules/system/src/Form/SiteInformationForm.php
index 1b1e3a6..2acf37e 100644
--- a/core/modules/system/src/Form/SiteInformationForm.php
+++ b/core/modules/system/src/Form/SiteInformationForm.php
@@ -7,12 +7,12 @@
 
 namespace Drupal\system\Form;
 
+use Drupal\Core\App;
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Path\AliasManagerInterface;
 use Drupal\Core\Form\ConfigFormBase;
 use Drupal\Core\Path\PathValidatorInterface;
-use Drupal\Core\Routing\RequestContext;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -35,11 +35,11 @@ class SiteInformationForm extends ConfigFormBase {
   protected $pathValidator;
 
   /**
-   * The request context.
+   * The application object.
    *
-   * @var \Drupal\Core\Routing\RequestContext
+   * @var \Drupal\Core\App
    */
-  protected $requestContext;
+  protected $app;
 
   /**
    * Constructs a SiteInformationForm object.
@@ -50,15 +50,15 @@ class SiteInformationForm extends ConfigFormBase {
    *   The path alias manager.
    * @param \Drupal\Core\Path\PathValidatorInterface $path_validator
    *   The path validator.
-   * @param \Drupal\Core\Routing\RequestContext $request_context
-   *   The request context.
+   * @param \Drupal\Core\App $app
+   *   The application object.
    */
-  public function __construct(ConfigFactoryInterface $config_factory, AliasManagerInterface $alias_manager, PathValidatorInterface $path_validator, RequestContext $request_context) {
+  public function __construct(ConfigFactoryInterface $config_factory, AliasManagerInterface $alias_manager, PathValidatorInterface $path_validator, App $app) {
     parent::__construct($config_factory);
 
     $this->aliasManager = $alias_manager;
     $this->pathValidator = $path_validator;
-    $this->requestContext = $request_context;
+    $this->app = $app;
   }
 
   /**
@@ -69,7 +69,7 @@ public static function create(ContainerInterface $container) {
       $container->get('config.factory'),
       $container->get('path.alias_manager'),
       $container->get('path.validator'),
-      $container->get('router.request_context')
+      $container->get('app')
     );
   }
 
@@ -133,7 +133,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#default_value' => $front_page,
       '#size' => 40,
       '#description' => t('Optionally, specify a relative URL to display as the front page. Leave blank to display the default front page.'),
-      '#field_prefix' => $this->requestContext->getCompleteBaseUrl(),
+      '#field_prefix' => $this->app->getBaseUrl(),
     );
     $form['error_page'] = array(
       '#type' => 'details',
diff --git a/core/modules/system/src/Tests/File/UrlRewritingTest.php b/core/modules/system/src/Tests/File/UrlRewritingTest.php
index 748e86d..c7fb40d 100644
--- a/core/modules/system/src/Tests/File/UrlRewritingTest.php
+++ b/core/modules/system/src/Tests/File/UrlRewritingTest.php
@@ -23,6 +23,15 @@ class UrlRewritingTest extends FileTestBase {
    */
   public static $modules = array('file_test');
 
+  public function setUp() {
+    parent::setUp();
+
+    // Populate the app object from request globals such that the base URL and
+    // path can be populated from a request containing valid SCRIPT_NAME and
+    // SCRIPT_FILENAME server values.
+    $this->container->get('app')->setRequest(Request::createFromGlobals());
+  }
+
   /**
    * Tests the rewriting of shipped file URLs by hook_file_url_alter().
    */
@@ -43,19 +52,19 @@ function testShippedFileURL()  {
     \Drupal::state()->set('file_test.hook_file_url_alter', 'root-relative');
     $filepath = 'core/assets/vendor/jquery/jquery.min.js';
     $url = file_create_url($filepath);
-    $this->assertEqual(base_path() . '/' . $filepath, $url, 'Correctly generated a root-relative URL for a shipped file.');
+    $this->assertEqual(base_path() . $filepath, $url, 'Correctly generated a root-relative URL for a shipped file.');
     $filepath = 'core/misc/favicon.ico';
     $url = file_create_url($filepath);
-    $this->assertEqual(base_path() . '/' . $filepath, $url, 'Correctly generated a root-relative URL for a shipped file.');
+    $this->assertEqual(base_path() . $filepath, $url, 'Correctly generated a root-relative URL for a shipped file.');
 
     // Test alteration of file URLs to use protocol-relative URLs.
     \Drupal::state()->set('file_test.hook_file_url_alter', 'protocol-relative');
     $filepath = 'core/assets/vendor/jquery/jquery.min.js';
     $url = file_create_url($filepath);
-    $this->assertEqual('/' . base_path() . '/' . $filepath, $url, 'Correctly generated a protocol-relative URL for a shipped file.');
+    $this->assertEqual('/' . base_path() . $filepath, $url, 'Correctly generated a protocol-relative URL for a shipped file.');
     $filepath = 'core/misc/favicon.ico';
     $url = file_create_url($filepath);
-    $this->assertEqual('/' . base_path() . '/' . $filepath, $url, 'Correctly generated a protocol-relative URL for a shipped file.');
+    $this->assertEqual('/' . base_path() . $filepath, $url, 'Correctly generated a protocol-relative URL for a shipped file.');
 
     // Test alteration of file URLs with query strings and/or fragment.
     \Drupal::state()->delete('file_test.hook_file_url_alter');
@@ -87,13 +96,13 @@ function testPublicManagedFileURL() {
     \Drupal::state()->set('file_test.hook_file_url_alter', 'root-relative');
     $uri = $this->createUri();
     $url = file_create_url($uri);
-    $this->assertEqual(base_path() . '/' . $public_directory_path . '/' . drupal_basename($uri), $url, 'Correctly generated a root-relative URL for a created file.');
+    $this->assertEqual(base_path() . $public_directory_path . '/' . drupal_basename($uri), $url, 'Correctly generated a root-relative URL for a created file.');
 
     // Test alteration of file URLs to use a protocol-relative URLs.
     \Drupal::state()->set('file_test.hook_file_url_alter', 'protocol-relative');
     $uri = $this->createUri();
     $url = file_create_url($uri);
-    $this->assertEqual('/' . base_path() . '/' . $public_directory_path . '/' . drupal_basename($uri), $url, 'Correctly generated a protocol-relative URL for a created file.');
+    $this->assertEqual('/' . base_path() . $public_directory_path . '/' . drupal_basename($uri), $url, 'Correctly generated a protocol-relative URL for a created file.');
   }
 
   /**
diff --git a/core/modules/system/src/Tests/Pager/PagerTest.php b/core/modules/system/src/Tests/Pager/PagerTest.php
index 4d7e0a1..ec9a57f 100644
--- a/core/modules/system/src/Tests/Pager/PagerTest.php
+++ b/core/modules/system/src/Tests/Pager/PagerTest.php
@@ -65,7 +65,7 @@ function testActiveClass() {
     $elements = $this->xpath('//li[contains(@class, :class)]/a', array(':class' => 'pager__item--last'));
     preg_match('@page=(\d+)@', $elements[0]['href'], $matches);
     $current_page = (int) $matches[1];
-    $this->drupalGet($GLOBALS['base_root'] . parse_url($this->getUrl())['path'] . $elements[0]['href'], array('external' => TRUE));
+    $this->drupalGet($this->getAbsoluteUrl($elements[0]['href']));
     $this->assertPagerItems($current_page);
   }
 
@@ -89,7 +89,6 @@ protected function testPagerQueryParametersAndCacheContext() {
     // Go back to first page, the count of pager calls need to go to 2.
     $elements = $this->xpath('//li[contains(@class, :class)]/a', array(':class' => 'pager__item--first'));
     $this->drupalGet($this->getAbsoluteUrl($elements[0]['href']));
-    $this->drupalGet($GLOBALS['base_root'] . parse_url($this->getUrl())['path'] . $elements[0]['href'], array('external' => TRUE));
     $this->assertText(t('Pager calls: 2'), 'Second link call to pager shows 2 calls.');
     $this->assertText('[url.query_args.pagers:0]=0.0');
     $this->assertCacheContext('url.query_args');
diff --git a/core/modules/update/src/UpdateProcessor.php b/core/modules/update/src/UpdateProcessor.php
index b5cf745..2d95a47 100644
--- a/core/modules/update/src/UpdateProcessor.php
+++ b/core/modules/update/src/UpdateProcessor.php
@@ -7,6 +7,7 @@
 namespace Drupal\update;
 
 use Drupal\Component\Utility\Crypt;
+use Drupal\Core\App;
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
 use Drupal\Core\State\StateInterface;
@@ -82,6 +83,11 @@ class UpdateProcessor implements UpdateProcessorInterface {
   protected $privateKey;
 
   /**
+   * The application object.
+   */
+  protected $app;
+
+  /**
    * Constructs a UpdateProcessor.
    *
    * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
@@ -98,8 +104,10 @@ class UpdateProcessor implements UpdateProcessorInterface {
    *   The key/value factory.
    * @param \Drupal\Core\KeyValueStore\KeyValueFactoryInterface $key_value_expirable_factory
    *   The expirable key/value factory.
+   * @param \Drupal\Core\App
+   *   The application object.
    */
-  public function __construct(ConfigFactoryInterface $config_factory, QueueFactory $queue_factory, UpdateFetcherInterface $update_fetcher, StateInterface $state_store, PrivateKey $private_key, KeyValueFactoryInterface $key_value_factory, KeyValueFactoryInterface $key_value_expirable_factory) {
+  public function __construct(ConfigFactoryInterface $config_factory, QueueFactory $queue_factory, UpdateFetcherInterface $update_fetcher, StateInterface $state_store, PrivateKey $private_key, KeyValueFactoryInterface $key_value_factory, KeyValueFactoryInterface $key_value_expirable_factory, App $app) {
     $this->updateFetcher = $update_fetcher;
     $this->updateSettings = $config_factory->get('update.settings');
     $this->fetchQueue = $queue_factory->get('update_fetch_tasks');
@@ -108,6 +116,7 @@ public function __construct(ConfigFactoryInterface $config_factory, QueueFactory
     $this->availableReleasesTempStore = $key_value_expirable_factory->get('update_available_releases');
     $this->stateStore = $state_store;
     $this->privateKey = $private_key;
+    $this->app = $app;
     $this->fetchTasks = array();
     $this->failed = array();
   }
@@ -141,8 +150,6 @@ public function fetchData() {
    * {@inheritdoc}
    */
   public function processFetchTask($project) {
-    global $base_url;
-
     // This can be in the middle of a long-running batch, so REQUEST_TIME won't
     // necessarily be valid.
     $request_time_difference = time() - REQUEST_TIME;
@@ -156,7 +163,7 @@ public function processFetchTask($project) {
 
     $success = FALSE;
     $available = array();
-    $site_key = Crypt::hmacBase64($base_url, $this->privateKey->get());
+    $site_key = Crypt::hmacBase64($this->app->getBaseUrl(), $this->privateKey->get());
     $fetch_url_base = $this->updateFetcher->getFetchBaseUrl($project);
     $project_name = $project['name'];
 
diff --git a/core/modules/update/update.services.yml b/core/modules/update/update.services.yml
index fc176d6..c367c8e 100644
--- a/core/modules/update/update.services.yml
+++ b/core/modules/update/update.services.yml
@@ -9,7 +9,7 @@ services:
     arguments: ['@config.factory', '@module_handler', '@update.processor', '@string_translation', '@keyvalue.expirable', '@theme_handler']
   update.processor:
     class: Drupal\update\UpdateProcessor
-    arguments: ['@config.factory', '@queue', '@update.fetcher', '@state', '@private_key', '@keyvalue', '@keyvalue.expirable']
+    arguments: ['@config.factory', '@queue', '@update.fetcher', '@state', '@private_key', '@keyvalue', '@keyvalue.expirable', '@app']
   update.fetcher:
     class: Drupal\update\UpdateFetcher
     arguments: ['@config.factory', '@http_client']
diff --git a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
index e4058ef..6184927 100644
--- a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
+++ b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
@@ -1270,7 +1270,7 @@ public function renderText($alter) {
 
         // Make sure that paths which were run through URL generation work as
         // well.
-        $base_path = base_path();
+        $base_path = \Drupal::app()->getBasePath() . '/';
         // Checks whether the path starts with the base_path.
         if (strpos($more_link_path, $base_path) === 0) {
           $more_link_path = Unicode::substr($more_link_path, Unicode::strlen($base_path));
diff --git a/core/modules/views/views.theme.inc b/core/modules/views/views.theme.inc
index 4ddfc5e..dd406da 100644
--- a/core/modules/views/views.theme.inc
+++ b/core/modules/views/views.theme.inc
@@ -817,7 +817,7 @@ function template_preprocess_views_view_rss(&$variables) {
   $variables['title'] = $title;
 
   // Figure out which display which has a path we're using for this feed. If
-  // there isn't one, use the global $base_url
+  // there isn't one, use the the base URL.
   $link_display_id = $view->display_handler->getLinkDisplay();
   if ($link_display_id && $display = $view->displayHandlers->get($link_display_id)) {
     $url = $view->getUrl(NULL, $link_display_id);
diff --git a/core/tests/Drupal/Tests/Core/AppTest.php b/core/tests/Drupal/Tests/Core/AppTest.php
new file mode 100644
index 0000000..7a9b547
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/AppTest.php
@@ -0,0 +1,173 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\AppTest.
+ */
+
+namespace Drupal\Tests\Core;
+
+use Drupal\Core\App;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Tests the App class.
+ *
+ * @coversDefaultClass \Drupal\Core\App
+ * @group AppTest
+ */
+class AppTest extends \PHPUnit_Framework_TestCase {
+
+  /**
+   * @covers ::getBaseUrl
+   * @covers ::prepareBaseUrl
+   *
+   * @dataProvider providerTestGetBaseUrl
+   */
+  public function testGetBaseUrl($root, $script, $url, $expected_base_url) {
+    $request = Request::create($url, 'GET', [], [], [], [
+      'SCRIPT_FILENAME' => $script,
+      'SCRIPT_NAME' => basename($script),
+    ]);
+    $app = $this->getMock('Drupal\Core\App', ['realpath'], [$root]);
+    $app->expects($this->any())
+      ->method('realpath')
+      ->will($this->returnCallback(function($path) { return $path; }));
+    $app->setRequest($request);
+    $this->assertEquals($expected_base_url, $app->getBaseUrl());
+  }
+
+  /**
+   * Provides test data for testGetBaseUrl().
+   */
+  public function providerTestGetBaseUrl() {
+    return [
+      [
+        '/var/www',
+        '/var/www/index.php',
+        'http://example.com/index.php',
+        'http://example.com',
+      ],
+      [
+        '/var/www',
+        '/var/www/core/install.php',
+        'http://example.com/core/install.php',
+        'http://example.com',
+      ],
+      [
+        '/var/www/drupal',
+        '/var/www/drupal/index.php',
+        'http://example.com/drupal/index.php',
+        'http://example.com/drupal',
+      ],
+      [
+        '/var/www/drupal',
+        '/var/www/drupal/core/install.php',
+        'http://example.com/drupal/core/install.php',
+        'http://example.com/drupal',
+      ],
+
+      [
+        '/var/www',
+        '/var/www/index.php',
+        'https://example.com/index.php',
+        'https://example.com',
+      ],
+      [
+        '/var/www',
+        '/var/www/core/install.php',
+        'https://example.com/core/install.php',
+        'https://example.com',
+      ],
+      [
+        '/var/www/drupal',
+        '/var/www/drupal/index.php',
+        'https://example.com/drupal/index.php',
+        'https://example.com/drupal',
+      ],
+      [
+        '/var/www/drupal',
+        '/var/www/drupal/core/install.php',
+        'https://example.com/drupal/core/install.php',
+        'https://example.com/drupal',
+      ],
+
+      [
+        '/var/www',
+        '/var/www/index.php',
+        'http://example.com:8080/index.php',
+        'http://example.com:8080',
+      ],
+      [
+        '/var/www',
+        '/var/www/core/install.php',
+        'http://example.com:8080/core/install.php',
+        'http://example.com:8080',
+      ],
+      [
+        '/var/www/drupal',
+        '/var/www/drupal/index.php',
+        'http://example.com:8080/drupal/index.php',
+        'http://example.com:8080/drupal',
+      ],
+      [
+        '/var/www/drupal',
+        '/var/www/drupal/core/install.php',
+        'http://example.com:8080/drupal/core/install.php',
+        'http://example.com:8080/drupal',
+      ],
+    ];
+  }
+
+  /**
+   * @covers ::getBasePath
+   * @covers ::prepareBasePath
+   *
+   * @dataProvider providerTestGetBasePath
+   */
+  public function testGetBasePath($root, $script, $url, $expected_base_url) {
+    $request = Request::create($url, 'GET', [], [], [], [
+      'SCRIPT_FILENAME' => $script,
+      'SCRIPT_NAME' => basename($script),
+    ]);
+    $app = $this->getMock('Drupal\Core\App', ['realpath'], [$root]);
+    $app->expects($this->any())
+      ->method('realpath')
+      ->will($this->returnCallback(function($path) { return $path; }));
+    $app->setRequest($request);
+    $this->assertEquals($expected_base_url, $app->getBasePath());
+  }
+
+  /**
+   * Provides test data for testGetBasePath().
+   */
+  public function providerTestGetBasePath() {
+    return [
+      [
+        '/var/www',
+        '/var/www/index.php',
+        'http://example.com/index.php',
+        '',
+      ],
+      [
+        '/var/www',
+        '/var/www/core/install.php',
+        'http://example.com/core/install.php',
+        '',
+      ],
+      [
+        '/var/www/drupal',
+        '/var/www/drupal/index.php',
+        'http://example.com/drupal/index.php',
+        '/drupal',
+      ],
+      [
+        '/var/www/drupal',
+        '/var/www/drupal/core/install.php',
+        'http://example.com/drupal/core/install.php',
+        '/drupal',
+      ],
+    ];
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/EventSubscriber/RedirectResponseSubscriberTest.php b/core/tests/Drupal/Tests/Core/EventSubscriber/RedirectResponseSubscriberTest.php
index 3a0aa79..ce71ca6 100644
--- a/core/tests/Drupal/Tests/Core/EventSubscriber/RedirectResponseSubscriberTest.php
+++ b/core/tests/Drupal/Tests/Core/EventSubscriber/RedirectResponseSubscriberTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Tests\Core\EventSubscriber;
 
+use Drupal\Core\App;
 use Drupal\Core\EventSubscriber\RedirectResponseSubscriber;
 use Drupal\Core\Routing\TrustedRedirectResponse;
 use Drupal\Core\Utility\UnroutedUrlAssemblerInterface;
@@ -27,11 +28,11 @@
 class RedirectResponseSubscriberTest extends UnitTestCase {
 
   /**
-   * The mocked request context.
+   * The mocked app.
    *
-   * @var \Drupal\Core\Routing\RequestContext|\PHPUnit_Framework_MockObject_MockObject
+   * @var \Drupal\Core\App|\PHPUnit_Framework_MockObject_MockObject.
    */
-  protected $requestContext;
+  protected $app;
 
   /**
    * The mocked request context.
@@ -46,11 +47,11 @@ class RedirectResponseSubscriberTest extends UnitTestCase {
   protected function setUp() {
     parent::setUp();
 
-    $this->requestContext = $this->getMockBuilder('Drupal\Core\Routing\RequestContext')
+    $this->app = $this->getMockBuilder('Drupal\Core\App')
       ->disableOriginalConstructor()
       ->getMock();
-    $this->requestContext->expects($this->any())
-      ->method('getCompleteBaseUrl')
+    $this->app->expects($this->any())
+      ->method('getBaseUrl')
       ->willReturn('http://example.com/drupal');
 
     $this->urlAssembler = $this->getMock(UnroutedUrlAssemblerInterface::class);
@@ -65,7 +66,7 @@ protected function setUp() {
       ]);
 
     $container = new Container();
-    $container->set('router.request_context', $this->requestContext);
+    $container->set('app', $this->app);
     \Drupal::setContainer($container);
   }
 
@@ -86,7 +87,7 @@ public function testDestinationRedirect(Request $request, $expected) {
     $response = new RedirectResponse('http://example.com/drupal');
     $request->headers->set('HOST', 'example.com');
 
-    $listener = new RedirectResponseSubscriber($this->urlAssembler, $this->requestContext);
+    $listener = new RedirectResponseSubscriber($this->urlAssembler, $this->app);
     $dispatcher->addListener(KernelEvents::RESPONSE, array($listener, 'checkRedirectUrl'));
     $event = new FilterResponseEvent($kernel, $request, HttpKernelInterface::SUB_REQUEST, $response);
     $dispatcher->dispatch(KernelEvents::RESPONSE, $event);
@@ -128,7 +129,7 @@ public function testDestinationRedirectToExternalUrl($request, $expected) {
     $kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface');
     $response = new RedirectResponse('http://other-example.com');
 
-    $listener = new RedirectResponseSubscriber($this->urlAssembler, $this->requestContext);
+    $listener = new RedirectResponseSubscriber($this->urlAssembler, $this->app);
     $dispatcher->addListener(KernelEvents::RESPONSE, array($listener, 'checkRedirectUrl'));
     $event = new FilterResponseEvent($kernel, $request, HttpKernelInterface::SUB_REQUEST, $response);
     $dispatcher->dispatch(KernelEvents::RESPONSE, $event);
@@ -146,7 +147,7 @@ public function testRedirectWithOptInExternalUrl() {
     $request = Request::create('');
     $request->headers->set('HOST', 'example.com');
 
-    $listener = new RedirectResponseSubscriber($this->urlAssembler, $this->requestContext);
+    $listener = new RedirectResponseSubscriber($this->urlAssembler, $this->app);
     $dispatcher->addListener(KernelEvents::RESPONSE, array($listener, 'checkRedirectUrl'));
     $event = new FilterResponseEvent($kernel, $request, HttpKernelInterface::SUB_REQUEST, $response);
     $dispatcher->dispatch(KernelEvents::RESPONSE, $event);
@@ -179,7 +180,7 @@ public function testDestinationRedirectWithInvalidUrl(Request $request) {
     $kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface');
     $response = new RedirectResponse('http://example.com/drupal');
 
-    $listener = new RedirectResponseSubscriber($this->urlAssembler, $this->requestContext);
+    $listener = new RedirectResponseSubscriber($this->urlAssembler, $this->app);
     $dispatcher->addListener(KernelEvents::RESPONSE, array($listener, 'checkRedirectUrl'));
     $event = new FilterResponseEvent($kernel, $request, HttpKernelInterface::SUB_REQUEST, $response);
     $dispatcher->dispatch(KernelEvents::RESPONSE, $event);
@@ -216,7 +217,7 @@ public function testSanitizeDestinationForGet($input, $output) {
     $request = new Request();
     $request->query->set('destination', $input);
 
-    $listener = new RedirectResponseSubscriber($this->urlAssembler, $this->requestContext);
+    $listener = new RedirectResponseSubscriber($this->urlAssembler, $this->app);
     $kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface');
     $event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
 
@@ -240,7 +241,7 @@ public function testSanitizeDestinationForPost($input, $output) {
     $request = new Request();
     $request->request->set('destination', $input);
 
-    $listener = new RedirectResponseSubscriber($this->urlAssembler, $this->requestContext);
+    $listener = new RedirectResponseSubscriber($this->urlAssembler, $this->app);
     $kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface');
     $event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
 
diff --git a/core/tests/Drupal/Tests/Core/PathProcessor/PathProcessorTest.php b/core/tests/Drupal/Tests/Core/PathProcessor/PathProcessorTest.php
index da61f5f..c065194 100644
--- a/core/tests/Drupal/Tests/Core/PathProcessor/PathProcessorTest.php
+++ b/core/tests/Drupal/Tests/Core/PathProcessor/PathProcessorTest.php
@@ -34,6 +34,13 @@ class PathProcessorTest extends UnitTestCase {
   protected $languages;
 
   /**
+   * The application object.
+   *
+   * @var \Drupal\Core\App|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $app;
+
+  /**
    *  The language manager stub used to construct a PathProcessorLanguage object.
    *
    * @var \Drupal\language\ConfigurableLanguageManagerInterface|\PHPUnit_Framework_MockObject_MockBuilder
@@ -50,13 +57,13 @@ protected function setUp() {
     }
     $this->languages = $languages;
 
-    // Create a stub configuration.
-    $language_prefixes = array_keys($this->languages);
-    $config = array(
-      'url' => array(
-        'prefixes' => array_combine($language_prefixes, $language_prefixes)
-      )
-    );
+    // Create the app stub.
+    $this->app = $this->getMockBuilder('Drupal\Core\App')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $this->app->expects($this->any())
+      ->method('getBasePath')
+      ->will($this->returnvalue(''));
 
     // Create a URL-based language negotiation method definition.
     $method_definitions = array(
@@ -67,7 +74,7 @@ protected function setUp() {
     );
 
     // Create a URL-based language negotiation method.
-    $method_instance = new LanguageNegotiationUrl($config);
+    $method_instance = new LanguageNegotiationUrl($this->app);
 
     // Create a language manager stub.
     $language_manager = $this->getMockBuilder('Drupal\language\ConfigurableLanguageManagerInterface')
@@ -139,7 +146,7 @@ function testProcessInbound() {
         'class' => 'Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl',
         'weight' => 9,
         ))));
-    $method = new LanguageNegotiationUrl();
+    $method = new LanguageNegotiationUrl($this->app);
     $method->setConfig($config_factory_stub);
     $method->setLanguageManager($this->languageManager);
     $negotiator->expects($this->any())
diff --git a/core/tests/Drupal/Tests/Core/Routing/TrustedRedirectResponseTest.php b/core/tests/Drupal/Tests/Core/Routing/TrustedRedirectResponseTest.php
index 2414798..cb9a65f 100644
--- a/core/tests/Drupal/Tests/Core/Routing/TrustedRedirectResponseTest.php
+++ b/core/tests/Drupal/Tests/Core/Routing/TrustedRedirectResponseTest.php
@@ -10,10 +10,10 @@
 use Drupal\Core\Cache\CacheableMetadata;
 use Drupal\Core\Cache\CacheableRedirectResponse;
 use Drupal\Core\Cache\CacheableResponseInterface;
-use Drupal\Core\Routing\RequestContext;
+use Drupal\Core\App;
 use Drupal\Core\Routing\TrustedRedirectResponse;
 use Drupal\Tests\UnitTestCase;
-use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Container;
 use Symfony\Component\HttpFoundation\RedirectResponse;
 
 /**
@@ -37,10 +37,15 @@ public function testSetTargetUrlWithInternalUrl() {
    * @expectedException \InvalidArgumentException
    */
   public function testSetTargetUrlWithUntrustedUrl() {
-    $request_context = new RequestContext();
-    $request_context->setCompleteBaseUrl('https://www.drupal.org');
-    $container = new ContainerBuilder();
-    $container->set('router.request_context', $request_context);
+    $app = $this->getMockBuilder('Drupal\Core\App')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $app->expects($this->any())
+      ->method('getBaseUrl')
+      ->willReturn('http://example.com/drupal');
+
+    $container = new Container();
+    $container->set('app', $app);
     \Drupal::setContainer($container);
 
     $redirect_response = new TrustedRedirectResponse('/example');
