diff --git a/core/core.services.yml b/core/core.services.yml
index 66bc3f2bebc30790dc09360630dfd0f5a46be830..be51f0345a7f24ad5cdd1ce2d8ecfac31803c2f4 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -579,6 +579,7 @@ services:
     arguments: ['@csrf_token']
   maintenance_mode_subscriber:
     class: Drupal\Core\EventSubscriber\MaintenanceModeSubscriber
+    arguments: ['@state', '@config.factory', '@string_translation', '@url_generator', '@current_user']
     tags:
       - { name: event_subscriber }
   path_subscriber:
diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index 27fb20cb15f0f3847d5dd0bdbef6aaa06fc8b9e3..46de223e32b706fd8226772e2bd1fdb8cc3a9921 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -102,26 +102,6 @@
  * add more with menu_link_save().
  */
 
-/**
- * @defgroup menu_status_codes Menu status codes
- * @{
- * Status codes for menu callbacks.
- */
-
-/**
- * Internal menu status code -- Menu item inaccessible because site is offline.
- */
-const MENU_SITE_OFFLINE = 4;
-
-/**
- * Internal menu status code -- Everything is working fine.
- */
-const MENU_SITE_ONLINE = 5;
-
-/**
- * @} End of "defgroup menu_status_codes".
- */
-
 /**
  * @defgroup menu_tree_parameters Menu tree parameters
  * @{
@@ -965,47 +945,6 @@ function _menu_set_expanded_menus() {
   \Drupal::state()->set('menu_expanded', $names);
 }
 
-
-/**
- * Checks whether the site is in maintenance mode.
- *
- * This function will log the current user out and redirect to front page
- * if the current user has no 'access site in maintenance mode' permission.
- *
- * @param $check_only
- *   If this is set to TRUE, the function will perform the access checks and
- *   return the site offline status, but not log the user out or display any
- *   messages.
- *
- * @return
- *   FALSE if the site is not in maintenance mode, the user login page is
- *   displayed, or the user has the 'access site in maintenance mode'
- *   permission. TRUE for anonymous users not being on the login page when the
- *   site is in maintenance mode.
- */
-function _menu_site_is_offline($check_only = FALSE) {
-  // Check if site is in maintenance mode.
-  if (\Drupal::state()->get('system.maintenance_mode')) {
-    if (user_access('access site in maintenance mode')) {
-      // Ensure that the maintenance mode message is displayed only once
-      // (allowing for page redirects) and specifically suppress its display on
-      // the maintenance mode settings page.
-      if (!$check_only && current_path() != 'admin/config/development/maintenance') {
-        if (user_access('administer site configuration')) {
-          drupal_set_message(t('Operating in maintenance mode. <a href="@url">Go online.</a>', array('@url' => url('admin/config/development/maintenance'))), 'status', FALSE);
-        }
-        else {
-          drupal_set_message(t('Operating in maintenance mode.'), 'status', FALSE);
-        }
-      }
-    }
-    else {
-      return TRUE;
-    }
-  }
-  return FALSE;
-}
-
 /**
  * @} End of "defgroup menu".
  */
diff --git a/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php
index 8c75e7b0c4e8d41f83ac4e9fd814360e0ea524a0..1b665f333432322bb68576a54c5a2d6afac04622 100644
--- a/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php
@@ -9,18 +9,97 @@
 
 use Drupal\Component\Utility\String;
 use Drupal\Component\Utility\Xss;
+use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Page\DefaultHtmlPageRenderer;
+use Drupal\Core\Routing\UrlGeneratorInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\State\StateInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\Core\StringTranslation\TranslationInterface;
+use Symfony\Cmf\Component\Routing\RouteObjectInterface;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\HttpKernel\KernelEvents;
 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
-use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpKernel\KernelEvents;
 
 /**
  * Maintenance mode subscriber for controller requests.
  */
 class MaintenanceModeSubscriber implements EventSubscriberInterface {
 
+  use StringTranslationTrait;
+
+  /**
+   * The current account.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $account;
+
+  /**
+   * The state.
+   *
+   * @var \Drupal\Core\State\StateInterface
+   */
+  protected $state;
+
+  /**
+   * The config factory.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $config;
+
+  /**
+   * The url generator.
+   *
+   * @var \Drupal\Core\Routing\UrlGeneratorInterface
+   */
+  protected $urlGenerator;
+
+  /**
+   * @defgroup menu_status_codes Menu status codes
+   * @{
+   * Status codes to be used to check the maintenance code.
+   */
+
+  /**
+   * Internal menu status code -- Menu item inaccessible because site is offline.
+   */
+  const SITE_OFFLINE = 4;
+
+  /**
+   * Internal menu status code -- Everything is working fine.
+   */
+  const SITE_ONLINE = 5;
+
+  /**
+   * @} End of "defgroup menu_status_codes".
+   */
+
+  /**
+   * Constructs a new MaintenanceModeSubscriber.
+   *
+   * @param \Drupal\Core\State\StateInterface $state
+   *   The state.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The config factory.
+   * @param \Drupal\Core\StringTranslation\TranslationInterface $translation
+   *   The string translation.
+   * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
+   *   The url generator.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The current user.
+   */
+  public function __construct(StateInterface $state, ConfigFactoryInterface $config_factory, TranslationInterface $translation, UrlGeneratorInterface $url_generator, AccountInterface $account) {
+    $this->state = $state;
+    $this->config = $config_factory;
+    $this->stringTranslation = $translation;
+    $this->urlGenerator = $url_generator;
+    $this->account = $account;
+  }
+
   /**
    * Determine whether the page is configured to be offline.
    *
@@ -30,7 +109,7 @@ class MaintenanceModeSubscriber implements EventSubscriberInterface {
   public function onKernelRequestDetermineSiteStatus(GetResponseEvent $event) {
     // Check if the site is offline.
     $request = $event->getRequest();
-    $is_offline = _menu_site_is_offline() ? MENU_SITE_OFFLINE : MENU_SITE_ONLINE;
+    $is_offline = $this->isSiteInMaintenance($request) ? static::SITE_OFFLINE : static::SITE_ONLINE;
     $request->attributes->set('_maintenance', $is_offline);
   }
 
@@ -44,17 +123,55 @@ public function onKernelRequestMaintenance(GetResponseEvent $event) {
     $request = $event->getRequest();
     $response = $event->getResponse();
     // Continue if the site is online and the response is not a redirection.
-    if ($request->attributes->get('_maintenance') != MENU_SITE_ONLINE && !($response instanceof RedirectResponse)) {
+    if ($request->attributes->get('_maintenance') != static::SITE_ONLINE && !($response instanceof RedirectResponse)) {
       // Deliver the 503 page.
       drupal_maintenance_theme();
-      $content = Xss::filterAdmin(String::format(\Drupal::config('system.maintenance')->get('message'), array(
-        '@site' => \Drupal::config('system.site')->get('name'),
+      $content = Xss::filterAdmin(String::format($this->config->get('system.maintenance')->get('message'), array(
+        '@site' => $this->config->get('system.site')->get('name'),
       )));
       $content = DefaultHtmlPageRenderer::renderPage($content, t('Site under maintenance'));
       $response = new Response('Service unavailable', 503);
       $response->setContent($content);
       $event->setResponse($response);
     }
+
+    $can_access_maintenance = $this->account->hasPermission('access site in maintenance mode');
+    $is_maintenance = $this->state->get('system.maintenance_mode');
+    // Ensure that the maintenance mode message is displayed only once
+    // (allowing for page redirects) and specifically suppress its display on
+    // the maintenance mode settings page.
+    $is_maintenance_route = $request->attributes->get(RouteObjectInterface::ROUTE_NAME) == 'system.site_maintenance_mode';
+    if ($is_maintenance && $can_access_maintenance && !$is_maintenance_route) {
+      if ($this->account->hasPermission('administer site configuration')) {
+        $this->drupalSetMessage($this->t('Operating in maintenance mode. <a href="@url">Go online.</a>', array('@url' => $this->urlGenerator->generate('system.site_maintenance_mode'))), 'status', FALSE);
+      }
+      else {
+        $this->drupalSetMessage($this->t('Operating in maintenance mode.'), 'status', FALSE);
+      }
+    }
+  }
+
+  /**
+   * Checks whether the site is in maintenance mode.
+   *
+   * @return bool
+   *   FALSE if the site is not in maintenance mode
+   */
+  protected function isSiteInMaintenance() {
+    // Check if site is in maintenance mode.
+    if ($this->state->get('system.maintenance_mode')) {
+      if (!$this->account->hasPermission('access site in maintenance mode')) {
+        return TRUE;
+      }
+    }
+    return FALSE;
+  }
+
+  /**
+   * Wraps the drupal_set_message function.
+   */
+  protected function drupalSetMessage($message = NULL, $type = 'status', $repeat = FALSE) {
+    return drupal_set_message($message, $type, $repeat);
   }
 
   /**
@@ -67,4 +184,5 @@ static function getSubscribedEvents() {
     $events[KernelEvents::REQUEST][] = array('onKernelRequestMaintenance', 30);
     return $events;
   }
+
 }
diff --git a/core/modules/system/tests/modules/menu_test/src/EventSubscriber/MaintenanceModeSubscriber.php b/core/modules/system/tests/modules/menu_test/src/EventSubscriber/MaintenanceModeSubscriber.php
index 2071a375a4bc90cbcf861144f9f0e27b8717e854..0b6ae6171fab166757c8732bbb026e81861d0d69 100644
--- a/core/modules/system/tests/modules/menu_test/src/EventSubscriber/MaintenanceModeSubscriber.php
+++ b/core/modules/system/tests/modules/menu_test/src/EventSubscriber/MaintenanceModeSubscriber.php
@@ -10,6 +10,8 @@
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
 use Symfony\Component\HttpKernel\KernelEvents;
+use Drupal\Core\EventSubscriber\MaintenanceModeSubscriber as CoreMaintenanceModeSubscriber;
+
 
 /**
  * Maintenance mode subscriber to set site online on a test.
@@ -25,8 +27,8 @@ class MaintenanceModeSubscriber implements EventSubscriberInterface {
   public function onKernelRequestMaintenance(GetResponseEvent $event) {
     $request = $event->getRequest();
     // Allow access to menu_login_callback even if in maintenance mode.
-    if ($request->attributes->get('_maintenance') == MENU_SITE_OFFLINE && $request->attributes->get('_system_path') == 'menu_login_callback') {
-      $request->attributes->set('_maintenance', MENU_SITE_ONLINE);
+    if ($request->attributes->get('_maintenance') == CoreMaintenanceModeSubscriber::SITE_OFFLINE && $request->attributes->get('_system_path') == 'menu_login_callback') {
+      $request->attributes->set('_maintenance', CoreMaintenanceModeSubscriber::SITE_ONLINE);
     }
   }
 
diff --git a/core/modules/user/src/EventSubscriber/MaintenanceModeSubscriber.php b/core/modules/user/src/EventSubscriber/MaintenanceModeSubscriber.php
index 3c478f7b6075cdc1c5a7941f217b71c37cb02dc4..1e8d114dcff20ee53a39692f2d5abd9dcc28986a 100644
--- a/core/modules/user/src/EventSubscriber/MaintenanceModeSubscriber.php
+++ b/core/modules/user/src/EventSubscriber/MaintenanceModeSubscriber.php
@@ -11,6 +11,7 @@
 use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
 use Symfony\Component\HttpKernel\KernelEvents;
+use Drupal\Core\EventSubscriber\MaintenanceModeSubscriber as CoreMaintenanceModeSubscriber;
 
 /**
  * Maintenance mode subscriber to logout users.
@@ -28,7 +29,7 @@ public function onKernelRequestMaintenance(GetResponseEvent $event) {
     $request = $event->getRequest();
     $site_status = $request->attributes->get('_maintenance');
     $path = $request->attributes->get('_system_path');
-    if ($site_status == MENU_SITE_OFFLINE) {
+    if ($site_status == CoreMaintenanceModeSubscriber::SITE_OFFLINE) {
       // If the site is offline, log out unprivileged users.
       if ($user->isAuthenticated() && !$user->hasPermission('access site in maintenance mode')) {
         user_logout();
@@ -46,12 +47,12 @@ public function onKernelRequestMaintenance(GetResponseEvent $event) {
           case 'user/login':
           case 'user/password':
             // Disable offline mode.
-            $request->attributes->set('_maintenance', MENU_SITE_ONLINE);
+            $request->attributes->set('_maintenance', CoreMaintenanceModeSubscriber::SITE_ONLINE);
             break;
           default:
             if (strpos($path, 'user/reset/') === 0) {
               // Disable offline mode.
-              $request->attributes->set('_maintenance', MENU_SITE_ONLINE);
+              $request->attributes->set('_maintenance', CoreMaintenanceModeSubscriber::SITE_ONLINE);
             }
             break;
         }