diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index d205ac0..8f30ec6 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -854,89 +854,46 @@ function menu_tail_load($arg, &$map, $index) {
  *
  * @param $item
  *   A menu link.
- * @param $translate
- *   (optional) Whether to try to translate a link containing dynamic path
- *   argument placeholders (%) based on the menu router item of the current
- *   path. Defaults to FALSE. Internally used for breadcrumbs.
  *
- * @return
- *   Returns the map of path arguments with objects loaded as defined in the
- *   $item['load_functions'].
  *   $item['access'] becomes TRUE if the item is accessible, FALSE otherwise.
- *   $item['href'] is generated from link_path, possibly by to_arg functions.
+ *   $item['href'] is generated from link_path.
  *   $item['title'] is generated from link_title, and may be localized.
  *   $item['options'] is unserialized; it is also changed within the call here
  *   to $item['localized_options'] by _menu_item_localize().
  */
-function _menu_link_translate(&$item, $translate = FALSE) {
+function _menu_link_translate(&$item) {
   if (!is_array($item['options'])) {
-    $item['options'] = unserialize($item['options']);
+    $item['options'] = (array) unserialize($item['options']);
+  }
+  $item['localized_options'] = $item['options'];
+  if (!is_array($item['route_parameters'])) {
+    $item['route_parameters'] = (array) unserialize($item['route_parameters']);
   }
-  if ($item['external']) {
+  if ($item['external'] || empty($item['route_name'])) {
     $item['access'] = 1;
-    $map = array();
     $item['href'] = $item['link_path'];
     $item['title'] = $item['link_title'];
-    $item['localized_options'] = $item['options'];
   }
   else {
-    // Complete the path of the menu link with elements from the current path,
-    // if it contains dynamic placeholders (%).
-    $map = explode('/', $item['link_path']);
-    if (strpos($item['link_path'], '%') !== FALSE) {
-      // Invoke registered to_arg callbacks.
-      if (!empty($item['to_arg_functions'])) {
-        _menu_link_map_translate($map, $item['to_arg_functions']);
-      }
-      // Or try to derive the path argument map from the current router item,
-      // if this $item's path is within the router item's path. This means
-      // that if we are on the current path 'foo/%/bar/%/baz', then
-      // menu_get_item() will have translated the menu router item for the
-      // current path, and we can take over the argument map for a link like
-      // 'foo/%/bar'. This inheritance is only valid for breadcrumb links.
-      // @see _menu_tree_check_access()
-      // @see menu_get_active_breadcrumb()
-      elseif ($translate && ($current_router_item = menu_get_item())) {
-        // If $translate is TRUE, then this link is in the active trail.
-        // Only translate paths within the current path.
-        if (strpos($current_router_item['path'], $item['link_path']) === 0) {
-          $count = count($map);
-          $map = array_slice($current_router_item['original_map'], 0, $count);
-          $item['original_map'] = $map;
-          if (isset($current_router_item['map'])) {
-            $item['map'] = array_slice($current_router_item['map'], 0, $count);
-          }
-          // Reset access to check it (for the first time).
-          unset($item['access']);
-        }
-      }
-    }
-    $item['href'] = implode('/', $map);
-
-    // Skip links containing untranslated arguments.
-    if (strpos($item['href'], '%') !== FALSE) {
-      $item['access'] = FALSE;
-      return FALSE;
-    }
     // menu_tree_check_access() may set this ahead of time for links to nodes.
     if (!isset($item['access'])) {
-      if ($route = $item->getRoute()) {
-        $item['access'] = menu_item_route_access($route, $item['href'], $map);
-      }
-      elseif (!empty($item['load_functions']) && !_menu_load_objects($item, $map)) {
-        // An error occurred loading an object.
-        $item['access'] = FALSE;
-        return FALSE;
-      }
-      // Apply the access check defined in hook_menu() if there is not route
-      // defined.
-      else {
-        _menu_check_access($item, $map);
-      }
+      $item['access'] = Drupal::getContainer()->get('access_manager')->checkNamedRoute($item['route_name'], $item['route_parameters']);
     }
     // For performance, don't localize a link the user can't access.
     if ($item['access']) {
-      _menu_item_localize($item, $map, TRUE);
+      // @todo - we need a system path to pass to l().  Change to rendering
+      // this later from route name and parameters.
+      $item['href'] = Drupal::urlGenerator()->getPathFromRoute($item['route_name'], $item['route_parameters']);
+      if ($item['machine_name']) {
+        // This link is defined in code and can be localized.
+        $item['title'] = t($item['link_title']);
+        if (!empty($item['localized_options']['attributes']['title'])) {
+          $item['localized_options']['attributes']['title'] = t($item['localized_options']['attributes']['title']);
+        }
+      }
+      else {
+        $item['title'] = $item['link_title'];
+      }
     }
   }
 
@@ -944,10 +901,8 @@ function _menu_link_translate(&$item, $translate = FALSE) {
   // options array. For performance reasons we only invoke this hook if the link
   // has the 'alter' flag set in the options array.
   if (!empty($item['options']['alter'])) {
-    drupal_alter('translated_menu_link', $item, $map);
+    drupal_alter('translated_menu_link', $item);
   }
-
-  return $map;
 }
 
 /**
@@ -1274,13 +1229,13 @@ function menu_tree_page_data($menu_name, $max_depth = NULL, $only_active_trail =
 
   // Check if the active trail has been overridden for this menu tree.
   $active_path = menu_tree_get_path($menu_name);
-  // Load the menu item corresponding to the current page.
-  if ($item = menu_get_item($active_path)) {
+  // Load the system path for the current page.
+  if ($system_path = current_path() || $system_path = '<front>') {
     if (isset($max_depth)) {
       $max_depth = min($max_depth, MENU_MAX_DEPTH);
     }
     // Generate a cache ID (cid) specific for this page.
-    $cid = 'links:' . $menu_name . ':page:' . $item['href'] . ':' . $language_interface->id . ':' . (int) $item['access'] . ':' . (int) $max_depth;
+    $cid = 'links:' . $menu_name . ':page:' . $system_path . ':' . $language_interface->id . ':' . (int) $max_depth;
     // If we are asked for the active trail only, and $menu_name has not been
     // built and cached for this page yet, then this likely means that it
     // won't be built anymore, as this function is invoked from
@@ -1313,7 +1268,9 @@ function menu_tree_page_data($menu_name, $max_depth = NULL, $only_active_trail =
 
         // If the item for the current page is accessible, build the tree
         // parameters accordingly.
-        if ($item['access']) {
+        // @TODO - check the current request or some other place to see if this
+        // page load is a 403.
+        if (TRUE || $item['access']) {
           // Find a menu link corresponding to the current path. If $active_path
           // is NULL, let menu_link_get_preferred() determine the path.
           if ($active_link = menu_link_get_preferred($active_path, $menu_name)) {
@@ -2445,10 +2402,10 @@ function menu_set_active_trail($new_trail = NULL) {
     // Try to retrieve a menu link corresponding to the current path. If more
     // than one exists, the link from the most preferred menu is returned.
     $preferred_link = menu_link_get_preferred();
-    $current_item = menu_get_item();
 
     // There is a link for the current path.
     if ($preferred_link) {
+       _menu_link_translate($preferred_link);
       // Pass TRUE for $only_active_trail to make menu_tree_page_data() build
       // a stripped down menu tree containing the active trail only, in case
       // the given menu has not been built in this request yet.
@@ -2457,7 +2414,6 @@ function menu_set_active_trail($new_trail = NULL) {
     }
     // There is no link for the current path.
     else {
-      $preferred_link = $current_item;
       $curr = FALSE;
     }
 
@@ -2475,7 +2431,7 @@ function menu_set_active_trail($new_trail = NULL) {
           // @see _menu_tree_check_access()
           // @see _menu_link_translate()
           if (strpos($link['href'], '%') !== FALSE) {
-            _menu_link_translate($link, TRUE);
+            _menu_link_translate($link);
           }
           if ($link['access']) {
             $trail[] = $link;
@@ -2530,20 +2486,10 @@ function menu_link_get_preferred($path = NULL, $selected_menu = NULL) {
     // which are ordered by priority (translated hrefs are preferred over
     // untranslated paths). Afterwards, the most relevant path is picked from
     // the menus, ordered by menu preference.
-    $item = menu_get_item($path);
     $path_candidates = array();
     // 1. The current item href.
-    $path_candidates[$item['href']] = $item['href'];
+    $path_candidates[$path] = $path;
     // 2. The tab root href of the current item (if any).
-    if ($item['tab_parent'] && ($tab_root = menu_get_item($item['tab_root_href']))) {
-      $path_candidates[$tab_root['href']] = $tab_root['href'];
-    }
-    // 3. The current item path (with wildcards).
-    $path_candidates[$item['path']] = $item['path'];
-    // 4. The tab root path of the current item (if any).
-    if (!empty($tab_root)) {
-      $path_candidates[$tab_root['path']] = $tab_root['path'];
-    }
 
     // Retrieve a list of menu names, ordered by preference.
     $menu_names = menu_get_active_menu_names();
@@ -2569,9 +2515,9 @@ function menu_link_get_preferred($path = NULL, $selected_menu = NULL) {
         foreach ($menu_names as $menu_name) {
           if (empty($preferred_links[$path][$menu_name]) && isset($candidates[$link_path][$menu_name])) {
             $candidate_item = $candidates[$link_path][$menu_name];
-            $map = explode('/', $path);
-            _menu_translate($candidate_item, $map);
-            if ($candidate_item['access']) {
+            //$map = explode('/', $path);
+            //_menu_translate($candidate_item, $map);
+            if (TRUE || $candidate_item['access']) {
               $preferred_links[$path][$menu_name] = $candidate_item;
               if (empty($preferred_links[$path][MENU_PREFERRED_LINK])) {
                 // Store the most specific link.
@@ -2622,8 +2568,8 @@ function menu_get_active_breadcrumb() {
     return $breadcrumb;
   }
 
-  $item = menu_get_item();
-  if (!empty($item['access'])) {
+  // @todo suppress this for a 403 page.
+  if (TRUE) {
     $active_trail = menu_get_active_trail();
 
     // Allow modules to alter the breadcrumb, if possible, as that is much
@@ -2730,7 +2676,7 @@ function menu_router_rebuild() {
 
   try {
     list($menu, $masks) = menu_router_build(TRUE);
-    _menu_navigation_links_rebuild($menu);
+    menu_default_links_rebuild();
     // Clear the menu, page and block caches.
     menu_cache_clear_all();
     _menu_clear_page_cache();
@@ -2835,11 +2781,34 @@ function menu_get_router() {
 }
 
 /**
- * Builds menu links for the items in the menu router.
- *
- * @todo This function should be removed/refactored.
+ * Recursive helper to save menu links.
  */
-function _menu_navigation_links_rebuild($menu) {
+function _menu_link_save_recursive($controller, $machine_name, &$children, &$links) {
+  $menu_link = $links[$machine_name];
+  if ($menu_link->isNew() || !$menu_link->customized) {
+    if (!isset($menu_link->plid) && !empty($menu_link->parent) && !empty($links[$menu_link->parent])) {
+      $parent = $links[$menu_link->parent];
+      
+      if (empty($menu_link->menu_name) || $parent->menu_name == $menu_link->menu_name) {
+        $menu_link->plid = $parent->id();
+        $menu_link->menu_name = $parent->menu_name;
+      }
+    }
+    $controller->save($menu_link);
+  }
+  if (!empty($children[$machine_name])) {
+    foreach ($children[$machine_name] as $next_name) {
+      _menu_link_save_recursive($controller, $next_name, $children, $links);
+    }
+  }
+  // Remove process links names so we can find stragglers.
+  unset($children[$machine_name]);
+}
+
+/**
+ * Builds menu links for the items returned from hook_default_meanu_links().
+ */
+function menu_default_links_rebuild() {
   if (!module_exists('menu_link')) {
     // The Menu link module may not be available during install, so rebuild
     // when possible.
@@ -2847,90 +2816,95 @@ function _menu_navigation_links_rebuild($menu) {
   }
   $menu_link_controller = Drupal::entityManager()
     ->getStorageController('menu_link');
-
-  // Add normal and suggested items as links.
-  $router_items = array();
-  foreach ($menu as $path => $router_item) {
-    if ($router_item['_visible']) {
-      $router_items[$path] = $router_item;
-      $sort[$path] = $router_item['_number_parts'];
-    }
-  }
-  if ($router_items) {
-    // Keep an array of processed menu links, to allow
-    // Drupal\menu_link\MenuLinkStorageController::save() to check this for
-    // parents instead of querying the database.
-    $parent_candidates = array();
-    // Make sure no child comes before its parent.
-    array_multisort($sort, SORT_NUMERIC, $router_items);
-
-    foreach ($router_items as $key => $router_item) {
+  $links = array();
+  $children = array();
+  $top_links = array();
+  foreach (Drupal::moduleHandler()->getImplementations('default_menu_links') as $module) {
+    $default_links = call_user_func($module . '_default_menu_links');
+    foreach ($default_links as $machine_name => $link) {
+      // Note, we set this as 'system', so that we can be sure to distinguish all
+      // the menu links generated automatically from hook_default_menu_links().
+      $link['machine_name'] = $machine_name;
+      $link['module'] = 'system';
+      $link += array(
+        'type' => MENU_NORMAL_ITEM,
+        'hidden' => 0,
+        'options' => empty($link['description']) ? array() : array('attributes' => array('title' => $link['description'])),
+      );
+      // Suggested items are disabled by default.
+      if ($link['type'] == MENU_SUGGESTED_ITEM) {
+        $link['hidden'] = 1;
+      }
+      // Hide all items that are not visible in the tree.
+      elseif (!($link['type'] & MENU_VISIBLE_IN_TREE)) {
+        $link['hidden'] = -1;
+      }
       // For performance reasons, do a straight query now and convert to a menu
       // link entity later.
       // @todo revisit before release.
       $existing_item = db_select('menu_links')
         ->fields('menu_links')
-        ->condition('link_path', $router_item['path'])
+        ->condition('machine_name', $machine_name)
         ->condition('module', 'system')
-        ->execute()->fetchAll();
+        ->execute()->fetchAssoc();
       if ($existing_item) {
-        $existing_item = reset($existing_item);
-        $existing_item->options = unserialize($existing_item->options);
-
-        $router_item['mlid'] = $existing_item->mlid;
-        $router_item['uuid'] = $existing_item->uuid;
-        // A change in hook_menu may move the link to a different menu
-        if (empty($router_item['menu_name']) || ($router_item['menu_name'] == $existing_item->menu_name)) {
-          $router_item['menu_name'] = $existing_item->menu_name;
-          $router_item['plid'] = $existing_item->plid;
-        }
-        else {
-          // It moved to a new menu.
-          // Let Drupal\menu_link\MenuLinkStorageController::save() try to find
-          // a new parent based on the path.
-          unset($router_item['plid']);
+        $existing_item['options'] = unserialize($existing_item['options']);
+        $existing_item['route_parameters'] = unserialize($existing_item['route_parameters']);
+        $existing_item = $menu_link_controller->create($existing_item);
+        $link['mlid'] = $existing_item->mlid;
+        $link['plid'] = $existing_item->plid;
+        $link['uuid'] = $existing_item->uuid;
+        $link['customized'] = $existing_item->customized;
+        $link['updated'] = $existing_item->updated;
+        $menu_link = $menu_link_controller->create($link);
+        if (!$existing_item->customized) {
+          // A change in hook_default_menu_links may move the link to a
+          // different menu.
+          if (!empty($link['menu_name']) && ($link['menu_name'] != $existing_item->menu_name)) {
+            $menu_link->plid = NULL;
+            $menu_link->menu_name = $link['menu_name'];
+          }
+          $menu_link->original = $existing_item;
         }
-        $router_item['has_children'] = $existing_item->has_children;
-        $router_item['updated'] = $existing_item->updated;
-
-        // Convert the existing item to a typed object.
-        $existing_item = $menu_link_controller->create(get_object_vars($existing_item));
       }
       else {
-        $existing_item = NULL;
+        if (empty($link['route_name']) && empty($link['link_path'])) {
+          $link['route_name'] = '<front>';
+        }
+        $menu_link = $menu_link_controller->create($link);
       }
-
-      if ($existing_item && $existing_item->customized) {
-        $parent_candidates[$existing_item->mlid] = $existing_item;
+      if (!empty($link['parent'])) {
+        $children[$link['parent']][$machine_name] = $machine_name;
+        $menu_link->parent = $link['parent'];
+        if (empty($link['menu_name'])) {
+          // Unset the default menu name so it's populated from the parent.
+          unset($menu_link->menu_name);
+        }
       }
       else {
-        $menu_link = MenuLink::buildFromRouterItem($router_item);
-        $menu_link->original = $existing_item;
-        $menu_link->parentCandidates = $parent_candidates;
-        $menu_link_controller->save($menu_link);
-        $parent_candidates[$menu_link->id()] = $menu_link;
-        unset($router_items[$key]);
+        // A top level link - we need them to root our tree.
+        $top_links[$machine_name] = $machine_name;
+        $menu_link->plid = 0;
       }
+      $links[$machine_name] = $menu_link;
     }
   }
-
-  $paths = array_keys($menu);
-  // Updated and customized items whose router paths are gone need new ones.
-  $menu_links = $menu_link_controller->loadUpdatedCustomized($paths);
-  foreach ($menu_links as $menu_link) {
-    $router_path = _menu_find_router_path($menu_link->link_path);
-    if (!empty($router_path) && ($router_path != $menu_link->router_path || $menu_link->updated)) {
-      // If the router path and the link path matches, it's surely a working
-      // item, so we clear the updated flag.
-      $updated = $menu_link->updated && $router_path != $menu_link->link_path;
-
-      $menu_link->router_path = $router_path;
-      $menu_link->updated = (int) $updated;
-      $menu_link_controller->save($menu_link);
+  foreach ($top_links as $machine_name) {
+    _menu_link_save_recursive($menu_link_controller, $machine_name, $children, $links);
+  }
+  // Handle any children we didn't find starting from top-level links.
+  foreach ($children as $missing_parent => $orphan_links) {
+    foreach ($orphan_links as $machine_name) {
+      // Force it to the top level.
+      $links[$machine_name]->plid = 0;
+      _menu_link_save_recursive($menu_link_controller, $machine_name, $children, $links);
     }
   }
 
-  // Find any item whose router path does not exist any more.
+  // Find any item whose route does not exist any more.
+  return;
+
+  // @todo - load all the route names?
   $query = Drupal::entityQuery('menu_link')
     ->condition('router_path', $paths, 'NOT IN')
     ->condition('external', 0)
diff --git a/core/modules/block/block.module b/core/modules/block/block.module
index a08254a..4324542 100644
--- a/core/modules/block/block.module
+++ b/core/modules/block/block.module
@@ -163,6 +163,20 @@ function block_menu() {
 }
 
 /**
+ * Implements hook_default_menu_links().
+ */
+function block_default_menu_links() {
+  $links['admin.structure.block'] = array(
+    'link_title' => 'Blocks',
+    'parent' => 'admin.structure',
+    'description' => 'Configure what block content appears in your site\'s sidebars and other regions.',
+    'route_name' => 'block_admin_display',
+  );
+
+  return $links;
+}
+
+/**
  * Access callback: Only enabled themes can be accessed.
  *
  * Path:
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index ef12cc1..566e437 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -245,6 +245,20 @@ function comment_menu() {
 }
 
 /**
+ * Implements hook_default_menu_links().
+ */
+function comment_default_menu_links() {
+  $links['admin.content.comment'] = array(
+    'link_title' => 'Comments',
+    'link_path' => 'admin/content/comment',
+    'parent' => 'admin.content',
+    'description' => 'List and edit site comments and the comment approval queue.',
+  );
+
+  return $links;
+}
+
+/**
  * Implements hook_menu_alter().
  */
 function comment_menu_alter(&$items) {
diff --git a/core/modules/contact/contact.module b/core/modules/contact/contact.module
index 2b1d8bf..129fa8d 100644
--- a/core/modules/contact/contact.module
+++ b/core/modules/contact/contact.module
@@ -116,6 +116,26 @@ function contact_menu() {
 }
 
 /**
+ * Implements hook_default_menu_links().
+ */
+function contact_default_menu_links() {
+  $links['admin.structure.contact'] = array(
+    'link_title' => 'Contact form categories',
+    'parent' => 'admin.structure',
+    'description' => 'Create a system contact form and set up categories for the form to use.',
+    'route_name' => 'contact_category_list',
+  );
+
+  $links['contact'] = array(
+    'link_title' => 'Contact',
+    'link_path' => 'contact',
+    'menu_name' => 'footer',
+    'type' => MENU_SUGGESTED_ITEM,
+  );
+  return $links;
+}
+
+/**
  * Access callback: Checks access for a user's personal contact form.
  *
  * @param $account
diff --git a/core/modules/dblog/dblog.module b/core/modules/dblog/dblog.module
index dcef317..3bbf31a 100644
--- a/core/modules/dblog/dblog.module
+++ b/core/modules/dblog/dblog.module
@@ -81,6 +81,42 @@ function dblog_menu() {
 }
 
 /**
+ * Implements hook_default_menu_links().
+ */
+function dblog_default_menu_links() {
+  $links['admin.reports.dblog'] = array(
+    'link_title' => 'Recent log messages',
+    'parent' => 'admin.reports',
+    'description' => 'View events that have recently been logged.',
+    'route_name' => 'dblog_overview',
+    'weight' => -1,
+  );
+  $links['admin.reports.page-not-found'] = array(
+    'link_title' => "Top 'page not found' errors",
+    'link_path' => 'admin/reports/page-not-found',
+    'parent' => 'admin.reports',
+    'description' => "View 'page not found' errors (404s).",
+  );
+  $links['admin.reports.access-denied'] = array(
+    'link_title' => "Top 'access denied' errors",
+    'link_path' => 'admin/reports/access-denied',
+    'description' => "View 'access denied' errors (403s).",
+    'parent' => 'admin.reports',
+  );
+
+  if (module_exists('search')) {
+    $links['admin.reports.search'] = array(
+      'link_title' => 'Top search phrases',
+      'link_path' => 'admin/reports/search',
+      'description' => 'View most popular search phrases.',
+      'parent' => 'admin.reports',
+    );
+  }
+
+  return $links;
+}
+
+/**
  * Implements hook_page_build().
  */
 function dblog_page_build(&$page) {
diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module
index 8b5f3a5..b085dec 100644
--- a/core/modules/filter/filter.module
+++ b/core/modules/filter/filter.module
@@ -157,6 +157,26 @@ function filter_menu() {
 }
 
 /**
+ * Implements hook_default_menu_links().
+ */
+function filter_default_menu_links() {
+  $links['filter.tips'] = array(
+    'link_title' => 'Compose tips',
+    'type' => MENU_SUGGESTED_ITEM,
+    'route_name' => 'filter_tips_all',
+  );
+
+  $links['admin.config.content.formats'] = array(
+    'link_title' => 'Text formats',
+    'parent' => 'admin.config.content',
+    'description' => 'Configure how content input by users is filtered, including allowed HTML tags. Also allows enabling of module-provided filters.',
+    'route_name' => 'filter_admin_overview',
+  );
+
+  return $links;
+}
+
+/**
  * Implements hook_permission().
  */
 function filter_permission() {
diff --git a/core/modules/menu/menu.module b/core/modules/menu/menu.module
index 4906043..3afa8f5 100644
--- a/core/modules/menu/menu.module
+++ b/core/modules/menu/menu.module
@@ -121,6 +121,19 @@ function menu_menu() {
 }
 
 /**
+ * Implements hook_default_menu_links().
+ */
+function menu_default_menu_links() {
+  $links['admin.structure.menu'] = array(
+    'link_title' => 'Menus',
+    'description' => 'Add new menus to your site, edit existing menus, and rename and reorganize menu links.',
+    'route_name' => 'menu_overview_page',
+    'parent' => 'admin.structure',
+  );
+  return $links;
+}
+
+/**
  * Implements hook_entity_info().
  */
 function menu_entity_info(&$entity_info) {
@@ -186,6 +199,9 @@ function menu_enable() {
   menu_router_rebuild();
   $system_link = entity_load_multiple_by_properties('menu_link', array('link_path' => 'admin/structure/menu', 'module' => 'system'));
   $system_link = reset($system_link);
+  if (empty($system_link)) {
+    return;
+  }
 
   $base_link = entity_create('menu_link', array(
     'menu_name' => $system_link->menu_name,
diff --git a/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php b/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php
index d6493f5..6d633f0 100644
--- a/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php
+++ b/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php
@@ -73,6 +73,13 @@ class MenuLink extends Entity implements \ArrayAccess, MenuLinkInterface {
   public $mlid;
 
   /**
+   * An optional machine name if defined via hook_default_menu_links().
+   *
+   * @var string
+   */
+  public $machine_name;
+
+  /**
    * The menu link UUID.
    *
    * @var string
@@ -261,7 +268,7 @@ class MenuLink extends Entity implements \ArrayAccess, MenuLinkInterface {
    *
    * @var array
    */
-  public $route_parameters;
+  public $route_parameters = array();
 
   /**
    * The route object associated with this menu link, if any.
@@ -335,30 +342,6 @@ public function reset() {
   }
 
   /**
-   * {@inheritdoc}
-   */
-  public static function buildFromRouterItem(array $item) {
-    // Suggested items are disabled by default.
-    if ($item['type'] == MENU_SUGGESTED_ITEM) {
-      $item['hidden'] = 1;
-    }
-    // Hide all items that are not visible in the tree.
-    elseif (!($item['type'] & MENU_VISIBLE_IN_TREE)) {
-      $item['hidden'] = -1;
-    }
-    // Note, we set this as 'system', so that we can be sure to distinguish all
-    // the menu links generated automatically from entries in {menu_router}.
-    $item['module'] = 'system';
-    $item += array(
-      'link_title' => $item['title'],
-      'link_path' => $item['path'],
-      'options' => empty($item['description']) ? array() : array('attributes' => array('title' => $item['description'])),
-    );
-    return \Drupal::entityManager()
-      ->getStorageController('menu_link')->create($item);
-  }
-
-  /**
    * Implements ArrayAccess::offsetExists().
    */
   public function offsetExists($offset) {
@@ -439,8 +422,7 @@ public function preSave(EntityStorageControllerInterface $storage_controller) {
     $this->external = (url_is_external($this->link_path) || $this->link_path == '<front>') ? 1 : 0;
 
     // Try to find a parent link. If found, assign it and derive its menu.
-    $parent_candidates = !empty($this->parentCandidates) ? $this->parentCandidates : array();
-    $parent = $this->findParent($storage_controller, $parent_candidates);
+    $parent = $this->findParent($storage_controller);
     if ($parent) {
       $this->plid = $parent->id();
       $this->menu_name = $parent->menu_name;
@@ -479,17 +461,7 @@ public function preSave(EntityStorageControllerInterface $storage_controller) {
     if (isset($this->original) && ($this->plid != $this->original->plid || $this->menu_name != $this->original->menu_name)) {
       $storage_controller->moveChildren($this, $this->original);
     }
-    // Find the router_path.
-    if (empty($this->router_path) || empty($this->original) || (isset($this->original) && $this->original->link_path != $this->link_path)) {
-      if ($this->external) {
-        $this->router_path = '';
-      }
-      else {
-        // Find the router path which will serve this path.
-        $this->parts = explode('/', $this->link_path, MENU_MAX_PARTS);
-        $this->router_path = _menu_find_router_path($this->link_path);
-      }
-    }
+
     // Find the route_name.
     if (!isset($this->route_name)) {
       if ($result = static::findRouteNameParameters($this->link_path)) {
@@ -500,6 +472,9 @@ public function preSave(EntityStorageControllerInterface $storage_controller) {
         $this->route_parameters = array();
       }
     }
+    elseif(empty($this->link_path)) {
+      $this->link_path = \Drupal::urlGenerator()->getPathFromRoute($this->route_name, $this->route_parameters);
+    }
   }
 
   /**
@@ -543,7 +518,7 @@ public static function findRouteNameParameters($link_path) {
   /**
    * {@inheritdoc}
    */
-  public function setParents(EntityInterface $parent) {
+  protected function setParents(MenuLink $parent) {
     $i = 1;
     while ($i < $this->depth) {
       $p = 'p' . $i++;
@@ -561,7 +536,7 @@ public function setParents(EntityInterface $parent) {
   /**
    * {@inheritdoc}
    */
-  public function findParent(EntityStorageControllerInterface $storage_controller, array $parent_candidates = array()) {
+  protected function findParent(EntityStorageControllerInterface $storage_controller) {
     $parent = FALSE;
 
     // This item is explicitely top-level, skip the rest of the parenting.
@@ -584,26 +559,12 @@ public function findParent(EntityStorageControllerInterface $storage_controller,
     }
 
     foreach ($candidates as $mlid) {
-      if (isset($parent_candidates[$mlid])) {
-        $parent = $parent_candidates[$mlid];
-      }
-      else {
-        $parent = $storage_controller->load($mlid);
-      }
+      $parent = $storage_controller->load($mlid);
       if ($parent) {
-        return $parent;
+        break;
       }
     }
-
-    // If everything else failed, try to derive the parent from the path
-    // hierarchy. This only makes sense for links derived from menu router
-    // items (ie. from hook_menu()).
-    if ($this->module == 'system') {
-      $parent = $storage_controller->getParentFromHierarchy($this);
-    }
-
     return $parent;
   }
 
-
 }
diff --git a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkInterface.php b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkInterface.php
index b8e639e..60480cd 100644
--- a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkInterface.php
+++ b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkInterface.php
@@ -9,8 +9,6 @@
 
 use Symfony\Component\Routing\Route;
 use Drupal\Core\Entity\ContentEntityInterface;
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Entity\EntityStorageControllerInterface;
 
 /**
  * Provides an interface defining a menu link entity.
@@ -39,23 +37,12 @@ public function setRouteObject(Route $route);
   /**
    * Resets a system-defined menu link.
    *
-   * @return \Drupal\Core\Entity\EntityInterface
+   * @return \Drupal\menu_link\Entity\MenuLinkInterface
    *   A menu link entity.
    */
   public function reset();
 
   /**
-   * Builds a menu link entity from a router item.
-   *
-   * @param array $item
-   *   A menu router item.
-   *
-   * @return \Drupal\menu_link\MenuLinkInterface
-   *   A menu link entity.
-   */
-  public static function buildFromRouterItem(array $item);
-
-  /**
    * Returns the route_name and route parameters matching a system path.
    *
    * @param string $link_path
@@ -67,33 +54,4 @@ public static function buildFromRouterItem(array $item);
    */
   public static function findRouteNameParameters($link_path);
 
-  /**
-   * Sets the p1 through p9 properties for a menu link entity being saved.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $parent
-   *   A menu link entity.
-   */
-  public function setParents(EntityInterface $parent);
-
-  /**
-   * Finds a possible parent for a given menu link entity.
-   *
-   * Because the parent of a given link might not exist anymore in the database,
-   * we apply a set of heuristics to determine a proper parent:
-   *
-   *  - use the passed parent link if specified and existing.
-   *  - else, use the first existing link down the previous link hierarchy
-   *  - else, for system menu links (derived from hook_menu()), reparent
-   *    based on the path hierarchy.
-   *
-   * @param \Drupal\Core\Entity\EntityStorageControllerInterface $storage_controller
-   *   Storage controller object.
-   * @param array $parent_candidates
-   *   An array of menu link entities keyed by mlid.
-   *
-   * @return \Drupal\Core\Entity\EntityInterface|false
-   *   A menu link entity structure of the possible parent or FALSE if no valid
-   *   parent has been found.
-   */
-  public function findParent(EntityStorageControllerInterface $storage_controller, array $parent_candidates = array());
 }
diff --git a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php
index 31d14f6..bc02919 100644
--- a/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php
+++ b/core/modules/menu_link/lib/Drupal/menu_link/MenuLinkStorageController.php
@@ -30,13 +30,6 @@ class MenuLinkStorageController extends DatabaseStorageController implements Men
   protected $preventReparenting = FALSE;
 
   /**
-   * Holds an array of router item schema fields.
-   *
-   * @var array
-   */
-  protected static $routerItemFields = array();
-
-  /**
    * The route provider service.
    *
    * @var \Symfony\Cmf\Component\Routing\RouteProviderInterface
@@ -59,10 +52,6 @@ public function __construct($entity_type, array $entity_info, Connection $databa
     parent::__construct($entity_type, $entity_info, $database);
 
     $this->routeProvider = $route_provider;
-
-    if (empty(static::$routerItemFields)) {
-      static::$routerItemFields = array_diff(drupal_schema_fields_sql('menu_router'), array('weight'));
-    }
   }
 
   /**
@@ -90,17 +79,6 @@ public static function createInstance(ContainerInterface $container, $entity_typ
   }
 
   /**
-   * Overrides DatabaseStorageController::buildQuery().
-   */
-  protected function buildQuery($ids, $revision_id = FALSE) {
-    $query = parent::buildQuery($ids, $revision_id);
-    // Specify additional fields from the {menu_router} table.
-    $query->leftJoin('menu_router', 'm', 'base.router_path = m.path');
-    $query->fields('m', static::$routerItemFields);
-    return $query;
-  }
-
-  /**
    * Overrides DatabaseStorageController::attachLoad().
    *
    * @todo Don't call parent::attachLoad() at all because we want to be able to
@@ -113,9 +91,6 @@ protected function attachLoad(&$menu_links, $load_revision = FALSE) {
       $menu_link->options = unserialize($menu_link->options);
       $menu_link->route_parameters = unserialize($menu_link->route_parameters);
 
-      // Use the weight property from the menu link.
-      $menu_link->router_item['weight'] = $menu_link->weight;
-
       // By default use the menu_name as type.
       $menu_link->bundle = $menu_link->menu_name;
 
diff --git a/core/modules/menu_link/menu_link.install b/core/modules/menu_link/menu_link.install
index 976653f..c789d34 100644
--- a/core/modules/menu_link/menu_link.install
+++ b/core/modules/menu_link/menu_link.install
@@ -31,6 +31,12 @@ function menu_link_schema() {
         'length' => 128,
         'not null' => FALSE,
       ),
+      'machine_name' => array(
+        'description' => 'Unique machine name: Optional human-readable ID for this link.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => FALSE,
+      ),
       'plid' => array(
         'description' => 'The parent link ID (plid) is the mlid of the link above in the hierarchy, or zero if the link is at the top level in its menu.',
         'type' => 'int',
@@ -45,13 +51,6 @@ function menu_link_schema() {
         'not null' => TRUE,
         'default' => '',
       ),
-      'router_path' => array(
-        'description' => 'For links corresponding to a Drupal path (external = 0), this connects the link to a {menu_router}.path for joins.',
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-      ),
       'langcode' => array(
         'description' => 'The {language}.langcode of this link.',
         'type' => 'varchar',
@@ -60,7 +59,7 @@ function menu_link_schema() {
         'default' => '',
       ),
       'link_title' => array(
-        'description' => 'The text displayed for the link, which may be modified by a title callback stored in {menu_router}.',
+        'description' => 'The text displayed for the link.',
         'type' => 'varchar',
         'length' => 255,
         'not null' => TRUE,
@@ -214,7 +213,6 @@ function menu_link_schema() {
       'path_menu' => array(array('link_path', 128), 'menu_name'),
       'menu_plid_expand_child' => array('menu_name', 'plid', 'expanded', 'has_children'),
       'menu_parents' => array('menu_name', 'p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8', 'p9'),
-      'router_path' => array(array('router_path', 128)),
     ),
     'primary key' => array('mlid'),
   );
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 44f60e7..85fa06a 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -1220,6 +1220,30 @@ function node_menu() {
 }
 
 /**
+ * Implements hook_default_menu_links().
+ */
+function node_default_menu_links() {
+  $links['admin.content'] = array(
+    'link_title' => 'Content',
+    'link_path' => 'admin/content',
+    'parent' => 'admin',
+    'description' => 'Find and manage content.',
+  );
+
+  $links['admin.structure.types'] = array(
+    'link_title' => 'Content types',
+    'parent' => 'admin.structure',
+    'description' => 'Manage content types, including default status, front page promotion, comment settings, etc.',
+    'route_name' => 'node_overview_types',
+  );
+  $links['node.add'] = array(
+    'link_title' => 'Add content',
+    'link_path' => 'node/add',
+  );
+  return $links;
+}
+
+/**
  * Implements hook_menu_local_tasks().
  */
 function node_menu_local_tasks(&$data, $router_item, $root_path) {
diff --git a/core/modules/search/search.module b/core/modules/search/search.module
index fece768..86cbb79 100644
--- a/core/modules/search/search.module
+++ b/core/modules/search/search.module
@@ -146,6 +146,26 @@ function search_preprocess_block(&$variables) {
 }
 
 /**
+ * Implements hook_default_menu_links().
+ */
+function search_default_menu_links() {
+  $links['search'] = array(
+    'link_title' => 'Search',
+    'link_path' => 'search',
+    'type' => MENU_SUGGESTED_ITEM,
+  );
+  $links['admin.config.search.settings'] = array(
+    'link_title' => 'Search settings',
+    'parent' => 'admin.config.search',
+    'description' => 'Configure relevance settings for search and other indexing options.',
+    'route_name' => 'search_settings',
+    'weight' => -10,
+  );
+
+  return $links;
+}
+
+/**
  * Implements hook_menu().
  */
 function search_menu() {
diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index df7ef6f..bcbd498 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -9,6 +9,7 @@
 use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
+use Symfony\Cmf\Component\Routing\RouteObjectInterface;
 
 /**
  * Provide a single block from the administration menu as a page.
@@ -22,8 +23,18 @@
  *   The output HTML.
  */
 function system_admin_menu_block_page() {
-  $item = menu_get_item();
-  if ($content = system_admin_menu_block($item)) {
+  $request = Drupal::request();
+  // Look for a link saved by system_default_menu_links().
+  $properties = array('module' => 'system');
+  if ($route_name = $request->attributes->get(RouteObjectInterface::ROUTE_NAME)) {
+    $properties['route_name'] = $route_name;
+  }
+  else {
+    $properties['link_path'] = current_path();
+  }
+  $menu_links = entity_load_multiple_by_properties('menu_link', $properties);
+  $menu_link = reset($menu_links);
+  if ($content = system_admin_menu_block($menu_link)) {
     $output = theme('admin_block_content', array('content' => $content));
   }
   else {
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 7777e0c..f903cd0 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -2267,6 +2267,23 @@ function system_update_8060() {
 }
 
 /**
+ * Add machine_name column to the menu_links table.
+ */
+function system_update_8061() {
+  $spec = array(
+    'description' => 'Machine name: Optional human-readable ID for this link.',
+    'type' => 'varchar',
+    'length' => 255,
+    'not null' => FALSE,
+  );
+
+  db_add_field('menu_links', 'machine_name', $spec);
+  // Do away with the field that joins to the old {menu_router}.
+  db_drop_index('menu_links', 'router_path');
+  db_drop_field('menu_links', 'router_path');
+}
+
+/**
  * @} End of "defgroup updates-7.x-to-8.x".
  * The next series of updates should start at 9000.
  */
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 94fbd21..f4063e5 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -9,11 +9,13 @@
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Utility\ModuleInfo;
+use \Drupal\menu_link\MenuLinkInterface;
 use Drupal\system\Plugin\Block\SystemMenuBlock;
 use Drupal\user\UserInterface;
 use Symfony\Component\HttpFoundation\JsonResponse;
 use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpFoundation\Request;
 use Guzzle\Http\Exception\BadResponseException;
 use Guzzle\Http\Exception\RequestException;
 
@@ -955,6 +957,208 @@ function system_menu() {
 }
 
 /**
+ * Implements hook_default_menu_links().
+ */
+function system_default_menu_links() {
+
+  $items['admin'] = array(
+    'link_title' => 'Administration',
+    'link_path' => 'admin',
+    'weight' => 9,
+    'menu_name' => 'admin',
+  );
+
+  // Menu items that are basically just menu blocks.
+  $items['admin.structure'] = array(
+    'link_path' => 'admin/structure',
+    'parent' => 'admin',
+    'description' => 'Administer blocks, content types, menus, etc.',
+    'link_title' => 'Structure',
+    'weight' => -8,
+  );
+  // Appearance.
+  $items['admin.appearance'] = array(
+    'link_path' => 'admin/appearance',
+    'link_title' => 'Appearance',
+    'parent' => 'admin',
+    'weight' => -6,
+  );
+  // Modules.
+  $items['admin.modules'] = array(
+    'link_title' => 'Extend',
+    'parent' => 'admin',
+    'route_name' => 'system_modules_list',
+    'weight' => -2,
+  );
+  // Configuration.
+  $items['admin.config'] = array(
+    'link_title' => 'Configuration',
+    'parent' => 'admin',
+    'description' => 'Administer settings.',
+    'route_name' => 'system_admin_config',
+  );
+
+  // Media settings.
+  $items['admin.config.media'] = array(
+    'link_path' => 'admin/config/media',
+    'parent' => 'admin.config',
+    'link_title' => 'Media',
+    'weight' => -10,
+  );
+  $items['admin.config.media.file-system'] = array(
+    'link_title' => 'File system',
+    'description' => 'Tell Drupal where to store uploaded files and how they are accessed.',
+    'parent' => 'admin.config.media',
+    'route_name' => 'system_file_system_settings',
+  );
+  $items['admin.config.media.image-toolkit'] = array(
+    'link_title' => 'Image toolkit',
+    'parent' => 'admin.config.media',
+    'route_name' => 'system_image_toolkit_settings',
+    'description' => 'Choose which image toolkit to use if you have installed optional toolkits.',
+    'weight' => 20,
+  );
+
+  // Service settings.
+  $items['admin.config.services'] = array(
+    'link_title' => 'Web services',
+    'parent' => 'admin.config',
+    'link_path' => 'admin/config/services',
+    'weight' => 0,
+  );
+  $items['admin.config.services.rss-publishing'] = array(
+    'link_title' => 'RSS publishing',
+    'parent' => 'admin.config.services',
+    'description' => 'Configure the site description, the number of items per feed and whether feeds should be titles/teasers/full-text.',
+    'route_name' => 'system_rss_feeds_settings',
+  );
+
+  // Development settings.
+  $items['admin.config.development'] = array(
+    'link_path' => 'admin/config/development',
+    'parent' => 'admin.config',
+    'link_title' => 'Development',
+    'description' => 'Development tools.',
+    'weight' => -10,
+  );
+  $items['admin.config.development.maintenance'] = array(
+    'link_title' => 'Maintenance mode',
+    'parent' => 'admin.config.development',
+    'description' => 'Take the site offline for maintenance or bring it back online.',
+    'route_name' => 'system_site_maintenance_mode',
+    'weight' => -10,
+  );
+  $items['admin.config.development.performance'] = array(
+    'link_title' => 'Performance',
+    'parent' => 'admin.config.development',
+    'description' => 'Enable or disable page caching for anonymous users and set CSS and JS bandwidth optimization options.',
+    'route_name' => 'system_performance_settings',
+    'weight' => -20,
+  );
+  $items['admin.config.development.logging'] = array(
+    'link_title' => 'Logging and errors',
+    'parent' => 'admin.config.development',
+    'description' => "Settings for logging and alerts modules. Various modules can route Drupal's system events to different destinations, such as syslog, database, email, etc.",
+    'route_name' => 'system_logging_settings',
+    'weight' => -15,
+  );
+
+  // Regional and date settings.
+  $items['admin.config.regional'] = array(
+    'link_path' => 'admin/config/regional',
+    'link_title' => 'Regional and language',
+    'parent' => 'admin.config',
+    'description' => 'Regional settings, localization and translation.',
+    'weight' => -5,
+  );
+  $items['admin.config.regional.settings'] = array(
+    'link_title' => 'Regional settings',
+    'parent' => 'admin.config.regional',
+    'description' => "Settings for the site's default time zone and country.",
+    'route_name' => 'system_regional_settings',
+    'weight' => -20,
+  );
+  $items['admin.config.regional.date-time'] = array(
+    'link_title' => 'Date and time formats',
+    'parent' => 'admin.config.regional',
+    'description' => 'Configure display format strings for date and time.',
+    'route_name' => 'date_format_list',
+    'weight' => -9,
+  );
+
+  // Search settings.
+  $items['admin.config.search'] = array(
+    'link_title' => 'Search and metadata',
+    'link_path' => 'admin/config/search',
+    'parent' => 'admin.config',
+    'description' => 'Local site search, metadata and SEO.',
+    'weight' => -10,
+  );
+
+  // System settings.
+  $items['admin.config.system'] = array(
+    'link_title' => 'System',
+    'link_path' => 'admin/config/system',
+    'parent' => 'admin.config',
+    'description' => 'General system related configuration.',
+    'weight' => -20,
+  );
+  $items['admin.config.system.site-information'] = array(
+    'link_title' => 'Site information',
+    'parent' => 'admin.config.system',
+    'description' => 'Change site name, e-mail address, slogan, default front page, and number of posts per page, error pages.',
+    'route_name' => 'system_site_information_settings',
+    'weight' => -20,
+  );
+  $items['admin.config.system.cron'] = array(
+    'link_title' => 'Cron',
+    'parent' => 'admin.config.system',
+    'description' => 'Manage automatic site maintenance tasks.',
+    'route_name' => 'system_cron_settings',
+    'weight' => 20,
+  );
+  // Additional categories
+  $items['admin.config.user-interface'] = array(
+    'link_title' => 'User interface',
+    'link_path' => 'admin/config/user-interface',
+    'parent' => 'admin.config',
+    'description' => 'Tools that enhance the user interface.',
+    'weight' => -15,
+  );
+  $items['admin.config.workflow'] = array(
+    'link_title' => 'Workflow',
+    'link_path' => 'admin/config/workflow',
+    'parent' => 'admin.config',
+    'description' => 'Content workflow, editorial workflow tools.',
+    'weight' => 5,
+  );
+  $items['admin.config.content'] = array(
+    'link_title' => 'Content authoring',
+    'link_path' => 'admin/config/content',
+    'parent' => 'admin.config',
+    'description' => 'Settings related to formatting and authoring content.',
+    'weight' => -15,
+  );
+
+  // Reports.
+  $items['admin.reports'] = array(
+    'link_title' => 'Reports',
+    'link_path' => 'admin/reports',
+    'parent' => 'admin',
+    'description' => 'View reports, updates, and errors.',
+    'weight' => 5,
+  );
+  $items['admin.reports.status'] = array(
+    'link_title' => 'Status report',
+    'parent' => 'admin.reports',
+    'description' => "Get a status report about your site's operation and any detected problems.",
+    'route_name' => 'system_status',
+  );
+
+  return $items;
+}
+
+/**
  * Theme callback for the default batch page.
  */
 function _system_batch_theme() {
@@ -2327,31 +2531,23 @@ function system_preprocess_block(&$variables) {
  * Provide a single block on the administration overview page.
  *
  * @param $item
- *   The menu item to be displayed.
+ *   The route name or path of the menu link to be displayed.
  */
-function system_admin_menu_block($item) {
+function system_admin_menu_block(MenuLinkInterface $menu_link = NULL) {
   $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 (empty($menu_link)) {
+    return;
   }
+  $mlid = $menu_link->id();
+
 
-  if (isset($cache[$item['mlid']])) {
-    return $cache[$item['mlid']];
+  if (isset($cache[$mlid])) {
+    return $cache[$mlid];
   }
 
   $content = array();
-  $menu_links = entity_load_multiple_by_properties('menu_link', array('plid' => $item['mlid'], 'menu_name' => $item['menu_name'], 'hidden' => 0));
+  $menu_links = entity_load_multiple_by_properties('menu_link', array('plid' => $mlid, 'menu_name' => $menu_link->menu_name, 'hidden' => 0));
   foreach ($menu_links as $link) {
     _menu_link_translate($link);
     if ($link['access']) {
@@ -2368,7 +2564,7 @@ function system_admin_menu_block($item) {
     }
   }
   ksort($content);
-  $cache[$item['mlid']] = $content;
+  $cache[$mlid] = $content;
   return $content;
 }
 
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index 306d6d0..8ae8819 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -326,6 +326,20 @@ function taxonomy_menu() {
 }
 
 /**
+ * Implements hook_default_menu_links().
+ */
+function taxonomy_default_menu_links() {
+  $links['admin.structure.taxonomy'] = array(
+    'link_title' => 'Taxonomy',
+    'parent' => 'admin.structure',
+    'description' => 'Manage tagging, categorization, and classification of your content.',
+    'route_name' => 'taxonomy_vocabulary_list',
+  );
+
+  return $links;
+}
+
+/**
  * Implements hook_admin_paths().
  */
 function taxonomy_admin_paths() {
diff --git a/core/modules/tracker/tracker.module b/core/modules/tracker/tracker.module
index c6d2882..8eea989 100644
--- a/core/modules/tracker/tracker.module
+++ b/core/modules/tracker/tracker.module
@@ -72,6 +72,18 @@ function tracker_menu() {
 }
 
 /**
+ * Implements hook_default_menu_links().
+ */
+function tracker_default_menu_links() {
+  $links['tracker'] = array(
+    'link_title' => 'Recent content',
+    'link_path' => 'tracker',
+  );
+
+  return $links;
+}
+
+/**
  * Implements hook_cron().
  *
  * Updates tracking information for any items still to be tracked. The state
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 91e7ee1..4c55444 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -955,6 +955,61 @@ function user_menu() {
 }
 
 /**
+ * Implements hook_default_menu_links().
+ */
+function user_default_menu_links() {
+  // Registration and login pages.
+  $links['user'] = array(
+    'link_title' => 'My account',
+    'weight' => -10,
+    'route_name' => 'user_page',
+    'menu_name' => 'account',
+  );
+
+  $links['user.logout'] = array(
+    'link_title' => 'Log out',
+    'route_name' => 'user_logout',
+    'weight' => 10,
+    'menu_name' => 'account',
+  );
+
+  // User listing pages.
+  $links['admin.people'] = array(
+    'link_title' => 'People',
+    'link_path' => 'admin/people',
+    'description' => 'Manage user accounts, roles, and permissions.',
+    'parent' => 'admin',
+    'weight' => -4,
+  );
+  // Permissions and role forms.
+  $links['admin.people.permissions'] = array(
+    'link_title' => 'Permissions',
+    'parent' => 'admin.people',
+    'description' => 'Determine access to features by selecting permissions for roles.',
+    'route_name' => 'user_admin_permissions',
+  );
+
+  // Administration pages.
+  $links['admin.config.people'] = array(
+   'link_title' => 'People',
+   'link_path' => 'admin/config/people',
+   'parent' => 'admin.config',
+   'description' => 'Configure user accounts.',
+   'weight' => -20,
+  );
+
+  $links['admin.config.people.accounts'] = array(
+    'link_title' => 'Account settings',
+    'parent' => 'admin.config.people',
+    'description' => 'Configure default behavior of users, including registration requirements, e-mails, and fields.',
+    'weight' => -10,
+    'route_name' => 'user_account_settings',
+  );
+
+  return $links;
+}
+
+/**
  * Implements hook_menu_link_presave().
  */
 function user_menu_link_presave(MenuLink $menu_link) {
@@ -962,14 +1017,17 @@ function user_menu_link_presave(MenuLink $menu_link) {
   // for authenticated users. Authenticated users should see "My account", but
   // anonymous users should not see it at all. Therefore, invoke
   // user_menu_link_load() to conditionally hide the link.
-  if ($menu_link->link_path == 'user' && $menu_link->module == 'system') {
+  if ($menu_link->machine_name == 'user' && $menu_link->module == 'system') {
     $menu_link->options['alter'] = TRUE;
   }
+}
 
-  // Force the Logout link to appear on the top-level of 'account' menu by
-  // default (i.e., unless it has been customized).
-  if ($menu_link->link_path == 'user/logout' && $menu_link->module == 'system' && empty($menu_link->customized)) {
-    $menu_link->plid = 0;
+/**
+ * Implements hook_menu_breadcrumb_alter().
+ */
+function user_translated_menu_link_alter(&$link) {
+  if ($link['machine_name'] == 'user' && $GLOBALS['user']->isAnonymous()) {
+    $link['title'] = t('Log in');
   }
 }
 
diff --git a/core/modules/views_ui/views_ui.module b/core/modules/views_ui/views_ui.module
index 7c41565..dd7593d 100644
--- a/core/modules/views_ui/views_ui.module
+++ b/core/modules/views_ui/views_ui.module
@@ -92,6 +92,31 @@ function views_ui_menu() {
 }
 
 /**
+ * Implements hook_default_menu_links().
+ */
+function views_ui_default_menu_links() {
+  $links = array();
+
+  // Top-level Views module pages (not tied to a particular View).
+  $links['admin.structure.views'] = array(
+    'link_title' => 'Views',
+    'parent' => 'admin.structure',
+    'description' => 'Manage customized lists of content.',
+    'route_name' => 'views_ui.list',
+  );
+
+  // A page in the Reports section to show usage of plugins in all views.
+  $links['admin.reports.views-plugins'] = array(
+    'link_title' => 'Views plugins',
+    'parent' => 'admin.reports',
+    'description' => 'Overview of plugins used in all views.',
+    'route_name' => 'views_ui.reports.plugins',
+  );
+
+  return $links;
+}
+
+/**
  * Implements hook_entity_info().
  */
 function views_ui_entity_info(&$entity_info) {
