diff --git a/core/lib/Drupal/Core/Routing/Enhancer/AuthenticationEnhancer.php b/core/lib/Drupal/Core/Routing/Enhancer/AuthenticationEnhancer.php
index c2165fa1a55961fde2c2daf14ef81a17e940ef39..a68d83b95bd784247fe7f8351b7f58c42b4b24bf 100644
--- a/core/lib/Drupal/Core/Routing/Enhancer/AuthenticationEnhancer.php
+++ b/core/lib/Drupal/Core/Routing/Enhancer/AuthenticationEnhancer.php
@@ -51,7 +51,13 @@ public function enhance(array $defaults, Request $request) {
       // If the request was authenticated with a non-permitted provider,
       // force the user back to anonymous.
       if (!in_array($auth_provider_triggered, $auth_providers)) {
-        $request->attributes->set('_account', drupal_anonymous_user());
+        $anonymous_user = drupal_anonymous_user();
+        $request->attributes->set('_account', $anonymous_user);
+
+        // The global $user object is included for backward compatibility only
+        // and should be considered deprecated.
+        // @todo Remove this line once global $user is no longer used.
+        $GLOBALS['user'] = $anonymous_user;
       }
     }
     return $defaults;
diff --git a/core/modules/entity/entity.module b/core/modules/entity/entity.module
index a88a10a5a0c845645e859a3d082ac895e17b6648..8b70c47def6cf84486d31828e65466a52ce2df32 100644
--- a/core/modules/entity/entity.module
+++ b/core/modules/entity/entity.module
@@ -30,10 +30,7 @@ function entity_menu() {
   $items['admin/structure/display-modes'] = array(
     'title' => 'Display modes',
     'description' => 'Configure what displays are available for your content and forms.',
-    'page callback' => 'system_admin_menu_block_page',
-    'access arguments' => array('administer display modes'),
-    'file' => 'system.admin.inc',
-    'file path' => drupal_get_path('module', 'system'),
+    'route_name' => 'entity_display_mode',
   );
 
   // View modes.
diff --git a/core/modules/entity/entity.routing.yml b/core/modules/entity/entity.routing.yml
index 05d7092970e18276cd09f4b2f63ee2395b5ddb2c..6ef9fd9bd5b0058d732b114bfc15721ffc41c344 100644
--- a/core/modules/entity/entity.routing.yml
+++ b/core/modules/entity/entity.routing.yml
@@ -1,3 +1,10 @@
+entity_display_mode:
+  pattern: '/admin/structure/display-modes'
+  defaults:
+    _content: '\Drupal\system\Controller\SystemController::systemAdminMenuBlockPage'
+  requirements:
+    _permission: 'administer display modes'
+
 entity_view_mode.list:
   pattern: '/admin/structure/display-modes/view'
   defaults:
diff --git a/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php b/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php
index a4b3e9ee4e6b9bf890c2c924ba9011657abedc66..92c4a413c97570b1736c377a22971dda2eea1a24 100644
--- a/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php
+++ b/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php
@@ -17,7 +17,7 @@ class MenuTest extends MenuWebTestBase {
    *
    * @var array
    */
-  public static $modules = array('block', 'test_page_test', 'contextual', 'path');
+  public static $modules = array('block', 'test_page_test', 'contextual', 'path', 'help');
 
   protected $big_user;
   protected $std_user;
diff --git a/core/modules/rest/lib/Drupal/rest/Tests/AuthTest.php b/core/modules/rest/lib/Drupal/rest/Tests/AuthTest.php
index 6e637c4a57281df0ab93388c156eccd1c87da176..4d1fc8ace003b703623b62a91383af5ea82b37a5 100644
--- a/core/modules/rest/lib/Drupal/rest/Tests/AuthTest.php
+++ b/core/modules/rest/lib/Drupal/rest/Tests/AuthTest.php
@@ -61,8 +61,7 @@ public function testRead() {
     // Try to read the resource with session cookie authentication, which is
     // not enabled and should not work.
     $response = $this->httpRequest('entity/' . $entity_type . '/' . $entity->id(), 'GET', NULL, $this->defaultMimeType);
-    $this->assertResponse('403', 'HTTP response code is 403 when the request is authenticated but not authorized.');
-    $this->drupalLogout();
+    $this->assertResponse('401', 'HTTP response code is 401 when the request is authenticated but not authorized.');
 
     // Now read it with the Basic authentication which is enabled and should
     // work.
diff --git a/core/modules/system/lib/Drupal/system/Controller/SystemController.php b/core/modules/system/lib/Drupal/system/Controller/SystemController.php
index 8403cc45b65d158caa660b3ff16c058c92aaafe7..922d3cedea1d71071c10df959304b7db211b131b 100644
--- a/core/modules/system/lib/Drupal/system/Controller/SystemController.php
+++ b/core/modules/system/lib/Drupal/system/Controller/SystemController.php
@@ -96,11 +96,9 @@ public function overview() {
             unset($item['localized_options']['attributes']['title']);
           }
           $block = $item;
-          // @todo Replace system_admin_menu_block() in
-          //   https://drupal.org/node/1987814.
           $block['content'] = array(
             '#theme' => 'admin_block_content',
-            '#content' => system_admin_menu_block($item),
+            '#content' => $this->systemManager->getAdminBlock($item),
           );
 
           if (!empty($block['content'])) {
@@ -140,4 +138,11 @@ public function compactPage($mode) {
     return $this->redirect('front');
   }
 
+  /**
+   * Provides a single block from the administration menu as a page.
+   */
+  public function systemAdminMenuBlockPage() {
+    return $this->systemManager->getBlockContents();
+  }
+
 }
diff --git a/core/modules/system/lib/Drupal/system/SystemManager.php b/core/modules/system/lib/Drupal/system/SystemManager.php
index 2712169514c00ef5bd3161027e4c51b4c9a5ee6e..619642e37db832593e78b9d3b41f04f571cfe00c 100644
--- a/core/modules/system/lib/Drupal/system/SystemManager.php
+++ b/core/modules/system/lib/Drupal/system/SystemManager.php
@@ -6,6 +6,8 @@
 
 namespace Drupal\system;
 
+use Drupal\Component\Utility\Unicode;
+use Drupal\Core\Entity\EntityManager;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Extension\ModuleHandlerInterface;
@@ -29,6 +31,20 @@ class SystemManager {
    */
   protected $database;
 
+  /**
+   * The menu link storage.
+   *
+   * @var \Drupal\menu_link\MenuLinkStorageControllerInterface
+   */
+  protected $menuLinkStorage;
+
+  /**
+   * A static cache of menu items.
+   *
+   * @var array
+   */
+  protected $menuItems;
+
   /**
    * Requirement severity -- Requirement successfully met.
    */
@@ -46,10 +62,18 @@ class SystemManager {
 
   /**
    * Constructs a SystemManager object.
+   *
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   * @param \Drupal\Core\Database\Connection $database
+   *   The database connection.
+   * @param \Drupal\Core\Entity\EntityManager $entity_manager
+   *   The entity manager.
    */
-  public function __construct(ModuleHandlerInterface $module_handler, Connection $database) {
+  public function __construct(ModuleHandlerInterface $module_handler, Connection $database, EntityManager $entity_manager) {
     $this->moduleHandler = $module_handler;
     $this->database = $database;
+    $this->menuLinkStorage = $entity_manager->getStorageController('menu_link');
   }
 
   /**
@@ -124,4 +148,83 @@ public function getMaxSeverity(&$requirements) {
     return $severity;
   }
 
+  /**
+   * Loads the contents of a menu block.
+   *
+   * This function is often a destination for these blocks.
+   * For example, 'admin/structure/types' needs to have a destination to be
+   * valid in the Drupal menu system, but too much information there might be
+   * hidden, so we supply the contents of the block.
+   *
+   * @return array
+   *   A render array suitable for drupal_render.
+   */
+  public function getBlockContents() {
+    $item = menu_get_item();
+    if ($content = $this->getAdminBlock($item)) {
+      $output = array(
+        '#theme' => 'admin_block_content',
+        '#content' => $content,
+      );
+    }
+    else {
+      $output = array(
+        '#type' => 'markup',
+        '#markup' => t('You do not have any administrative items.'),
+      );
+    }
+    return $output;
+  }
+
+  /**
+   * Provide a single block on the administration overview page.
+   *
+   * @param \Drupal\menu_link\MenuLinkInterface|array $item
+   *   The menu item to be displayed.
+   *
+   * @return array
+   *   An array of menu items, as expected by theme_admin_block_content().
+   */
+  public function getAdminBlock($item) {
+    // If we are calling this function for a menu item that corresponds to a
+    // local task (for example, admin/tasks), then we want to retrieve the
+    // parent item's child links, not this item's (since this item won't have
+    // any).
+    if ($item['tab_root'] != $item['path']) {
+      $item = menu_get_item($item['tab_root_href']);
+    }
+
+    if (!isset($item['mlid'])) {
+      $menu_links = $this->menuLinkStorage->loadByProperties(array('router_path' => $item['path'], 'module' => 'system'));
+      $menu_link = reset($menu_links);
+      $item['mlid'] = $menu_link->id();
+      $item['menu_name'] = $menu_link->menu_name;
+    }
+
+    if (isset($this->menuItems[$item['mlid']])) {
+      return $this->menuItems[$item['mlid']];
+    }
+
+    $content = array();
+    $menu_links = $this->menuLinkStorage->loadByProperties(array('plid' => $item['mlid'], 'menu_name' => $item['menu_name'], 'hidden' => 0));
+    foreach ($menu_links as $link) {
+      _menu_link_translate($link);
+      if ($link['access']) {
+        // The link description, either derived from 'description' in
+        // hook_menu() or customized via menu module is used as title attribute.
+        if (!empty($link['localized_options']['attributes']['title'])) {
+          $link['description'] = $link['localized_options']['attributes']['title'];
+          unset($link['localized_options']['attributes']['title']);
+        }
+        // Prepare for sorting as in function _menu_tree_check_access().
+        // The weight is offset so it is always positive, with a uniform 5-digits.
+        $key = (50000 + $link['weight']) . ' ' . Unicode::strtolower($link['title']) . ' ' . $link['mlid'];
+        $content[$key] = $link;
+      }
+    }
+    ksort($content);
+    $this->menuItems[$item['mlid']] = $content;
+    return $content;
+  }
+
 }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterTest.php
index 0a94658ac6999fdf66e91640415443d83584534b..d1159cb237193c7e4552d3bc51764d16753b8fce 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Menu/MenuRouterTest.php
@@ -136,15 +136,6 @@ function testThemeCallbackInheritance() {
     $this->assertRaw('seven/style.css', "The administrative theme's CSS appears on the page.");
   }
 
-  /**
-   * Test that 'page callback', 'file' and 'file path' keys are properly
-   * inherited from parent menu paths.
-   */
-  function testFileInheritance() {
-    $this->drupalGet('admin/config/development/file-inheritance');
-    $this->assertText('File inheritance test description', 'File inheritance works.');
-  }
-
   /**
    * Test path containing "exotic" characters.
    */
diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index a3235af9c3e47fb27055b0c70f8bfacba14889ee..d3b3a98cce88ca16a642b344322827375b2a116e 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -10,28 +10,6 @@
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
 
-/**
- * Provide a single block from the administration menu as a page.
- *
- * This function is often a destination for these blocks.
- * For example, 'admin/structure/types' needs to have a destination to be valid
- * in the Drupal menu system, but too much information there might be
- * hidden, so we supply the contents of the block.
- *
- * @return
- *   The output HTML.
- */
-function system_admin_menu_block_page() {
-  $item = menu_get_item();
-  if ($content = system_admin_menu_block($item)) {
-    $output = theme('admin_block_content', array('content' => $content));
-  }
-  else {
-    $output = t('You do not have any administrative items.');
-  }
-  return $output;
-}
-
 /**
  * Menu callback; displays a listing of all themes.
  */
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 1fa1400ea4e53bb50560d9097073dc9369fb7778..4f909a3c370537e5d0bef574159b84380ee039fd 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -621,11 +621,9 @@ function system_menu() {
   );
   $items['admin'] = array(
     'title' => 'Administration',
-    'access arguments' => array('access administration pages'),
-    'page callback' => 'system_admin_menu_block_page',
+    'route_name' => 'system_admin',
     'weight' => 9,
     'menu_name' => 'admin',
-    'file' => 'system.admin.inc',
   );
   $items['admin/tasks'] = array(
     'title' => 'Tasks',
@@ -645,9 +643,7 @@ function system_menu() {
     'description' => 'Administer blocks, content types, menus, etc.',
     'position' => 'right',
     'weight' => -8,
-    'page callback' => 'system_admin_menu_block_page',
-    'access arguments' => array('access administration pages'),
-    'file' => 'system.admin.inc',
+    'route_name' => 'system_admin_structure',
   );
   // Appearance.
   $items['admin/appearance'] = array(
@@ -736,9 +732,7 @@ function system_menu() {
     'description' => 'Media tools.',
     'position' => 'left',
     'weight' => -10,
-    'page callback' => 'system_admin_menu_block_page',
-    'access arguments' => array('access administration pages'),
-    'file' => 'system.admin.inc',
+    'route_name' => 'system_admin_config_media',
   );
   $items['admin/config/media/file-system'] = array(
     'title' => 'File system',
@@ -759,9 +753,7 @@ function system_menu() {
     'description' => 'Tools related to web services.',
     'position' => 'right',
     'weight' => 0,
-    'page callback' => 'system_admin_menu_block_page',
-    'access arguments' => array('access administration pages'),
-    'file' => 'system.admin.inc',
+    'route_name' => 'system_admin_config_services',
   );
   $items['admin/config/services/rss-publishing'] = array(
     'title' => 'RSS publishing',
@@ -775,9 +767,7 @@ function system_menu() {
     'description' => 'Development tools.',
     'position' => 'right',
     'weight' => -10,
-    'page callback' => 'system_admin_menu_block_page',
-    'access arguments' => array('access administration pages'),
-    'file' => 'system.admin.inc',
+    'route_name' => 'system_admin_config_development',
   );
   $items['admin/config/development/maintenance'] = array(
     'title' => 'Maintenance mode',
@@ -804,9 +794,7 @@ function system_menu() {
     'description' => 'Regional settings, localization and translation.',
     'position' => 'left',
     'weight' => -5,
-    'page callback' => 'system_admin_menu_block_page',
-    'access arguments' => array('access administration pages'),
-    'file' => 'system.admin.inc',
+    'route_name' => 'system_admin_config_regional',
   );
   $items['admin/config/regional/settings'] = array(
     'title' => 'Regional settings',
@@ -844,9 +832,7 @@ function system_menu() {
     'description' => 'Local site search, metadata and SEO.',
     'position' => 'left',
     'weight' => -10,
-    'page callback' => 'system_admin_menu_block_page',
-    'access arguments' => array('access administration pages'),
-    'file' => 'system.admin.inc',
+    'route_name' => 'system_admin_config_search',
   );
 
   // System settings.
@@ -855,9 +841,7 @@ function system_menu() {
     'description' => 'General system related configuration.',
     'position' => 'right',
     'weight' => -20,
-    'page callback' => 'system_admin_menu_block_page',
-    'access arguments' => array('access administration pages'),
-    'file' => 'system.admin.inc',
+    'route_name' => 'system_admin_config_system',
   );
   $items['admin/config/system/site-information'] = array(
     'title' => 'Site information',
@@ -876,9 +860,7 @@ function system_menu() {
     'title' => 'User interface',
     'description' => 'Tools that enhance the user interface.',
     'position' => 'right',
-    'page callback' => 'system_admin_menu_block_page',
-    'access arguments' => array('access administration pages'),
-    'file' => 'system.admin.inc',
+    'route_name' => 'system_admin_config_ui',
     'weight' => -15,
   );
   $items['admin/config/workflow'] = array(
@@ -886,29 +868,23 @@ function system_menu() {
     'description' => 'Content workflow, editorial workflow tools.',
     'position' => 'right',
     'weight' => 5,
-    'page callback' => 'system_admin_menu_block_page',
-    'access arguments' => array('access administration pages'),
-    'file' => 'system.admin.inc',
+    'route_name' => 'system_admin_config_workflow',
   );
   $items['admin/config/content'] = array(
     'title' => 'Content authoring',
     'description' => 'Settings related to formatting and authoring content.',
     'position' => 'left',
     'weight' => -15,
-    'page callback' => 'system_admin_menu_block_page',
-    'access arguments' => array('access administration pages'),
-    'file' => 'system.admin.inc',
+    'route_name' => 'system_admin_config_content',
   );
 
   // Reports.
   $items['admin/reports'] = array(
     'title' => 'Reports',
     'description' => 'View reports, updates, and errors.',
-    'page callback' => 'system_admin_menu_block_page',
-    'access arguments' => array('access site reports'),
+    'route_name' => 'system_admin_reports',
     'weight' => 5,
     'position' => 'left',
-    'file' => 'system.admin.inc',
   );
   $items['admin/reports/status'] = array(
     'title' => 'Status report',
@@ -2321,55 +2297,6 @@ function system_preprocess_block(&$variables) {
   }
 }
 
-/**
- * Provide a single block on the administration overview page.
- *
- * @param $item
- *   The menu item to be displayed.
- */
-function system_admin_menu_block($item) {
-  $cache = &drupal_static(__FUNCTION__, array());
-  // If we are calling this function for a menu item that corresponds to a
-  // local task (for example, admin/tasks), then we want to retrieve the
-  // parent item's child links, not this item's (since this item won't have
-  // any).
-  if ($item['tab_root'] != $item['path']) {
-    $item = menu_get_item($item['tab_root_href']);
-  }
-
-  if (!isset($item['mlid'])) {
-    $menu_links = entity_load_multiple_by_properties('menu_link', array('router_path' => $item['path'], 'module' => 'system'));
-    $menu_link = reset($menu_links);
-    $item['mlid'] = $menu_link->id();
-    $item['menu_name'] = $menu_link->menu_name;
-  }
-
-  if (isset($cache[$item['mlid']])) {
-    return $cache[$item['mlid']];
-  }
-
-  $content = array();
-  $menu_links = entity_load_multiple_by_properties('menu_link', array('plid' => $item['mlid'], 'menu_name' => $item['menu_name'], 'hidden' => 0));
-  foreach ($menu_links as $link) {
-    _menu_link_translate($link);
-    if ($link['access']) {
-      // The link description, either derived from 'description' in
-      // hook_menu() or customized via menu module is used as title attribute.
-      if (!empty($link['localized_options']['attributes']['title'])) {
-        $link['description'] = $link['localized_options']['attributes']['title'];
-        unset($link['localized_options']['attributes']['title']);
-      }
-      // Prepare for sorting as in function _menu_tree_check_access().
-      // The weight is offset so it is always positive, with a uniform 5-digits.
-      $key = (50000 + $link['weight']) . ' ' . drupal_strtolower($link['title']) . ' ' . $link['mlid'];
-      $content[$key] = $link;
-    }
-  }
-  ksort($content);
-  $cache[$item['mlid']] = $content;
-  return $content;
-}
-
 /**
  * Checks the existence of the directory specified in $form_element.
  *
diff --git a/core/modules/system/system.routing.yml b/core/modules/system/system.routing.yml
index c876fd56c2f08ca65af4f541e957d73ecf2a93ab..a3bf62bd88122c781604cf0e04b6c0e80f843d40 100644
--- a/core/modules/system/system.routing.yml
+++ b/core/modules/system/system.routing.yml
@@ -4,6 +4,91 @@ system.ajax:
     _controller: '\Drupal\system\Controller\FormAjaxController::content'
   requirements:
     _access: 'TRUE'
+
+system_admin:
+  pattern: '/admin'
+  defaults:
+    _content: '\Drupal\system\Controller\SystemController::systemAdminMenuBlockPage'
+  requirements:
+    _permission: 'access administration pages'
+
+system_admin_structure:
+  pattern: '/admin/structure'
+  defaults:
+    _content: '\Drupal\system\Controller\SystemController::systemAdminMenuBlockPage'
+  requirements:
+    _permission: 'access administration pages'
+
+system_admin_reports:
+  pattern: '/admin/reports'
+  defaults:
+    _content: '\Drupal\system\Controller\SystemController::systemAdminMenuBlockPage'
+  requirements:
+    _permission: 'access site reports'
+
+system_admin_config_media:
+  pattern: '/admin/config/media'
+  defaults:
+    _content: '\Drupal\system\Controller\SystemController::systemAdminMenuBlockPage'
+  requirements:
+    _permission: 'access administration pages'
+
+system_admin_config_services:
+  pattern: '/admin/config/services'
+  defaults:
+    _content: '\Drupal\system\Controller\SystemController::systemAdminMenuBlockPage'
+  requirements:
+    _permission: 'access administration pages'
+
+system_admin_config_development:
+  pattern: '/admin/config/development'
+  defaults:
+    _content: '\Drupal\system\Controller\SystemController::systemAdminMenuBlockPage'
+  requirements:
+    _permission: 'access administration pages'
+
+system_admin_config_regional:
+  pattern: '/admin/config/regional'
+  defaults:
+    _content: '\Drupal\system\Controller\SystemController::systemAdminMenuBlockPage'
+  requirements:
+    _permission: 'access administration pages'
+
+system_admin_config_search:
+  pattern: '/admin/config/search'
+  defaults:
+    _content: '\Drupal\system\Controller\SystemController::systemAdminMenuBlockPage'
+  requirements:
+    _permission: 'access administration pages'
+
+system_admin_config_system:
+  pattern: '/admin/config/system'
+  defaults:
+    _content: '\Drupal\system\Controller\SystemController::systemAdminMenuBlockPage'
+  requirements:
+    _permission: 'access administration pages'
+
+system_admin_config_ui:
+  pattern: '/admin/config/user-interface'
+  defaults:
+    _content: '\Drupal\system\Controller\SystemController::systemAdminMenuBlockPage'
+  requirements:
+    _permission: 'access administration pages'
+
+system_admin_config_workflow:
+  pattern: '/admin/config/workflow'
+  defaults:
+    _content: '\Drupal\system\Controller\SystemController::systemAdminMenuBlockPage'
+  requirements:
+    _permission: 'access administration pages'
+
+system_admin_config_content:
+  pattern: '/admin/config/content'
+  defaults:
+    _content: '\Drupal\system\Controller\SystemController::systemAdminMenuBlockPage'
+  requirements:
+    _permission: 'access administration pages'
+
 system.cron:
   pattern: '/cron/{key}'
   defaults:
diff --git a/core/modules/system/system.services.yml b/core/modules/system/system.services.yml
index 08d67adf70bdff20e555d666e729001eb4dd194b..f1838b5549323848fdf176cfc065b50a0d744ed5 100644
--- a/core/modules/system/system.services.yml
+++ b/core/modules/system/system.services.yml
@@ -5,7 +5,7 @@ services:
       - { name: access_check }
   system.manager:
     class: Drupal\system\SystemManager
-    arguments: ['@module_handler', '@database']
+    arguments: ['@module_handler', '@database', '@entity.manager']
   system.breadcrumb.legacy:
     class: Drupal\system\LegacyBreadcrumbBuilder
     tags:
diff --git a/core/modules/system/tests/modules/menu_test/menu_test.module b/core/modules/system/tests/modules/menu_test/menu_test.module
index 02fa65badcc9c168596efa52ff0a2069b64411a6..5315f0060fa330718b03652036282ea85663d5fe 100644
--- a/core/modules/system/tests/modules/menu_test/menu_test.module
+++ b/core/modules/system/tests/modules/menu_test/menu_test.module
@@ -24,14 +24,12 @@ function menu_test_menu() {
     'type' => MENU_CALLBACK,
     'access arguments' => array('access content'),
   );
-  // This item uses system_admin_menu_block_page() to list child items.
+  // This item uses SystemController::systemAdminMenuBlockPage() to list child
+  // items.
   $items['menu_callback_description'] = array(
     'title' => 'Menu item title',
-    'page callback' => 'system_admin_menu_block_page',
     'description' => 'Menu item description parent',
-    'access arguments' => array('access content'),
-    'file' => 'system.admin.inc',
-    'file path' => drupal_get_path('module', 'system'),
+    'route_name' => 'menu_callback_description',
   );
   // This item tests the description key.
   $items['menu_callback_description/description-plain'] = array(
@@ -296,21 +294,6 @@ function menu_test_menu() {
     'access arguments' => array('access content'),
   );
 
-  // File inheritance tests. This menu item should inherit the page callback
-  // system_admin_menu_block_page() and therefore render its children as links
-  // on the page.
-  $items['admin/config/development/file-inheritance'] = array(
-    'title' => 'File inheritance',
-    'description' => 'Test file inheritance',
-    'access arguments' => array('access content'),
-  );
-  $items['admin/config/development/file-inheritance/inherit'] = array(
-    'title' => 'Inherit',
-    'description' => 'File inheritance test description',
-    'page callback' => 'menu_test_callback',
-    'access arguments' => array('access content'),
-  );
-
   // Test the access key.
   $items['menu-title-test/case1'] = array(
    'title' => 'Example title - Case 1',
diff --git a/core/modules/system/tests/modules/menu_test/menu_test.routing.yml b/core/modules/system/tests/modules/menu_test/menu_test.routing.yml
index 2d701dc80ae8a975547371d71794439714e893cb..47d3a8771a707f48993003a6ee7010a095de78c5 100644
--- a/core/modules/system/tests/modules/menu_test/menu_test.routing.yml
+++ b/core/modules/system/tests/modules/menu_test/menu_test.routing.yml
@@ -4,6 +4,14 @@ menu_login_callback:
     _content: '\Drupal\menu_test\TestControllers::testLogin'
   requirements:
     _access: 'TRUE'
+
+menu_callback_description:
+  pattern: 'menu_callback_description'
+  defaults:
+    _content: '\Drupal\system\Controller\SystemController::systemAdminMenuBlockPage'
+  requirements:
+    _permission: 'access content'
+
 menu_router_test1:
   pattern: '/foo/{bar}'
   defaults:
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 4768f937a264133f515df138d9192c3a2ff46900..4392ccdf42b52680c38c9ed2acca31037002e51a 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -880,15 +880,13 @@ function user_menu() {
 
   // Administration pages.
   $items['admin/config/people'] = array(
-   'title' => 'People',
-   'description' => 'Configure user accounts.',
-   'position' => 'left',
-   'weight' => -20,
-   'page callback' => 'system_admin_menu_block_page',
-   'access arguments' => array('access administration pages'),
-   'file' => 'system.admin.inc',
-   'file path' => drupal_get_path('module', 'system'),
+    'title' => 'People',
+    'description' => 'Configure user accounts.',
+    'position' => 'left',
+    'weight' => -20,
+    'route_name' => 'user_admin_index',
   );
+
   $items['admin/config/people/accounts'] = array(
     'title' => 'Account settings',
     'description' => 'Configure default behavior of users, including registration requirements, e-mails, and fields.',
diff --git a/core/modules/user/user.routing.yml b/core/modules/user/user.routing.yml
index 90570ea457388fc9b23ad880994bdc4225ef2978..8bf9b91f3e807c25052784025d6bda69f864b39b 100644
--- a/core/modules/user/user.routing.yml
+++ b/core/modules/user/user.routing.yml
@@ -26,6 +26,13 @@ user_autocomplete_anonymous:
   requirements:
     _permission: 'access user profiles'
 
+user_admin_index:
+  pattern: '/admin/config/people'
+  defaults:
+    _content: '\Drupal\system\Controller\SystemController::systemAdminMenuBlockPage'
+  requirements:
+    _permission: 'access administration pages'
+
 user_account_settings:
   pattern: '/admin/config/people/accounts'
   defaults: