From c77851c47358136d0244bbe151cea5c6c4df5e2c Mon Sep 17 00:00:00 2001
From: Dries <dries@buytaert.net>
Date: Wed, 30 Jul 2014 15:54:09 -0400
Subject: [PATCH] Issue #2301319 by pwolanin, effulgentsia: MenuLinkNG part5:
 Remove dead code and party!

---
 core/includes/menu.inc                        | 426 -----------
 core/modules/menu_link/menu_link.api.php      |  42 --
 core/modules/menu_link/menu_link.install      | 221 ------
 core/modules/menu_link/menu_link.module       | 225 ------
 core/modules/menu_link/menu_link.services.yml |   7 -
 .../modules/menu_link/src/Entity/MenuLink.php | 680 ------------------
 .../src/MenuLinkAccessController.php          |  41 --
 core/modules/menu_link/src/MenuLinkForm.php   | 311 --------
 .../menu_link/src/MenuLinkInterface.php       |  45 --
 .../modules/menu_link/src/MenuLinkStorage.php | 319 --------
 .../src/MenuLinkStorageInterface.php          | 110 ---
 core/modules/menu_link/src/MenuTree.php       | 619 ----------------
 .../menu_link/src/MenuTreeInterface.php       | 182 -----
 .../modules/menu_link/src/StaticMenuLinks.php |  76 --
 .../menu_link/tests/src/MenuTreeTest.php      | 539 --------------
 .../src/Plugin/views/sort/MenuHierarchy.php   |  66 --
 16 files changed, 3909 deletions(-)
 delete mode 100644 core/modules/menu_link/menu_link.api.php
 delete mode 100644 core/modules/menu_link/menu_link.install
 delete mode 100644 core/modules/menu_link/menu_link.module
 delete mode 100644 core/modules/menu_link/menu_link.services.yml
 delete mode 100644 core/modules/menu_link/src/Entity/MenuLink.php
 delete mode 100644 core/modules/menu_link/src/MenuLinkAccessController.php
 delete mode 100644 core/modules/menu_link/src/MenuLinkForm.php
 delete mode 100644 core/modules/menu_link/src/MenuLinkInterface.php
 delete mode 100644 core/modules/menu_link/src/MenuLinkStorage.php
 delete mode 100644 core/modules/menu_link/src/MenuLinkStorageInterface.php
 delete mode 100644 core/modules/menu_link/src/MenuTree.php
 delete mode 100644 core/modules/menu_link/src/MenuTreeInterface.php
 delete mode 100644 core/modules/menu_link/src/StaticMenuLinks.php
 delete mode 100644 core/modules/menu_link/tests/src/MenuTreeTest.php
 delete mode 100644 core/modules/views/src/Plugin/views/sort/MenuHierarchy.php

diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index 17c65c171e00..bd387520ea3c 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -255,14 +255,6 @@
  *   documentation here.
  */
 
-/**
- * The maximum depth of a menu links tree - matches the number of p columns.
- *
- * @todo Move this constant to MenuLinkStorage along with all the tree
- * functionality.
- */
-const MENU_MAX_DEPTH = 9;
-
 /**
  * @section Rendering menus
  * Once you have created menus (that contain menu links), you want to render
@@ -315,92 +307,6 @@
  * @endcode
  */
 
-/**
- * Localizes a menu link title using t() if possible.
- *
- * Translate the title and description to allow storage of English title
- * strings in the database, yet display of them in the language required
- * by the current user.
- *
- * @param $item
- *   A menu link entity.
- */
-function _menu_item_localize(&$item) {
-  // Allow default menu links to be translated.
-  $item['localized_options'] = $item['options'];
-  // All 'class' attributes are assumed to be an array during rendering, but
-  // links stored in the database may use an old string value.
-  // @todo In order to remove this code we need to implement a database update
-  //   including unserializing all existing link options and running this code
-  //   on them, as well as adding validation to menu_link_save().
-  if (isset($item['options']['attributes']['class']) && is_string($item['options']['attributes']['class'])) {
-    $item['localized_options']['attributes']['class'] = explode(' ', $item['options']['attributes']['class']);
-  }
-  // If the menu link is defined in code and not customized, we can use t().
-  if (!empty($item['machine_name']) && !$item['customized']) {
-    // @todo Figure out a proper way to support translations of menu links, see
-    //   https://drupal.org/node/2193777.
-    $item['title'] = t($item['link_title']);
-  }
-  else {
-    $item['title'] = $item['link_title'];
-  }
-}
-
-/**
- * Provides menu link unserializing, access control, and argument handling.
- *
- * @param array $item
- *   The passed in item has the following keys:
- *   - access: (optional) Becomes TRUE if the item is accessible, FALSE
- *     otherwise. If the key is not set, the access manager is used to
- *     determine the access.
- *   - options: (required) Is unserialized and copied to $item['localized_options'].
- *   - link_title: (required) The title of the menu link.
- *   - route_name: (required) The route name of the menu link.
- *   - route_parameters: (required) The unserialized route parameters of the menu link.
- *   The passed in item is changed by the following keys:
- *   - href: The actual path to the link. This path is generated from the
- *     link_path of the menu link entity.
- *   - title: The title of the link. This title is generated from the
- *     link_title of the menu link entity.
- */
-function _menu_link_translate(&$item) {
-  if (!is_array($item['options'])) {
-    $item['options'] = (array) unserialize($item['options']);
-  }
-  $item['localized_options'] = $item['options'];
-  $item['title'] = $item['link_title'];
-  if ($item['external'] || empty($item['route_name'])) {
-    $item['access'] = 1;
-    $item['href'] = $item['link_path'];
-    $item['route_parameters'] = array();
-    // Set to NULL so that drupal_pre_render_link() is certain to skip it.
-    $item['route_name'] = NULL;
-  }
-  else {
-    $item['href'] = NULL;
-    if (!is_array($item['route_parameters'])) {
-      $item['route_parameters'] = (array) unserialize($item['route_parameters']);
-    }
-    // menu_tree_check_access() may set this ahead of time for links to nodes.
-    if (!isset($item['access'])) {
-      $item['access'] = \Drupal::getContainer()->get('access_manager')->checkNamedRoute($item['route_name'], $item['route_parameters'], \Drupal::currentUser());
-    }
-    // For performance, don't localize a link the user can't access.
-    if ($item['access']) {
-      _menu_item_localize($item);
-    }
-  }
-
-  // Allow other customizations - e.g. adding a page-specific query string to the
-  // 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::moduleHandler()->alter('translated_menu_link', $item, $map);
-  }
-}
-
 /**
  * Implements template_preprocess_HOOK() for theme_menu_tree().
  */
@@ -764,119 +670,6 @@ function theme_menu_local_tasks(&$variables) {
   return $output;
 }
 
-/**
- * Sets (or gets) the active menu for the current page.
- *
- * The active menu for the page determines the active trail.
- *
- * @return
- *   An array of menu machine names, in order of preference. The
- *   'system.menu:active_menus_default' config item may be used to assert a menu
- *   order different from the order of creation, or to prevent a particular menu
- *   from being used at all in the active trail.
- */
-function menu_set_active_menu_names($menu_names = NULL) {
-  $active = &drupal_static(__FUNCTION__);
-
-  if (isset($menu_names) && is_array($menu_names)) {
-    $active = $menu_names;
-  }
-  elseif (!isset($active)) {
-    $config = \Drupal::config('system.menu');
-    $active = $config->get('active_menus_default') ?: array_keys(menu_list_system_menus());
-  }
-  return $active;
-}
-
-/**
- * Gets the active menu for the current page.
- */
-function menu_get_active_menu_names() {
-  return menu_set_active_menu_names();
-}
-
-/**
- * Looks up the preferred menu link for a given system path.
- *
- * @param $path
- *   The path; for example, 'node/5'. The function will find the corresponding
- *   menu link ('node/5' if it exists, or fallback to 'node/%').
- * @param $selected_menu
- *   The name of a menu used to restrict the search for a preferred menu link.
- *   If not specified, all the menus returned by menu_get_active_menu_names()
- *   will be used.
- *
- * @return
- *   A fully translated menu link, or FALSE if no matching menu link was
- *   found. The most specific menu link ('node/5' preferred over 'node/%') in
- *   the most preferred menu (as defined by menu_get_active_menu_names()) is
- *   returned.
- */
-function menu_link_get_preferred($path = NULL, $selected_menu = NULL) {
-  $preferred_links = &drupal_static(__FUNCTION__);
-
-  if (!isset($path)) {
-    $path = current_path();
-  }
-
-  if (empty($selected_menu)) {
-    // Use an illegal menu name as the key for the preferred menu link.
-    $selected_menu = MENU_PREFERRED_LINK;
-  }
-
-  if (!isset($preferred_links[$path])) {
-    // Look for the correct menu link by building a list of candidate paths,
-    // 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.
-    $path_candidates = array();
-    // 1. The current item href.
-    // @todo simplify this code and convert to using route names.
-    // @see https://drupal.org/node/2154949
-    $path_candidates[$path] = $path;
-
-    // Retrieve a list of menu names, ordered by preference.
-    $menu_names = menu_get_active_menu_names();
-    // Put the selected menu at the front of the list.
-    array_unshift($menu_names, $selected_menu);
-
-    $menu_links = entity_load_multiple_by_properties('menu_link', array('link_path' => $path_candidates));
-
-    // Sort candidates by link path and menu name.
-    $candidates = array();
-    foreach ($menu_links as $candidate) {
-      $candidates[$candidate['link_path']][$candidate['menu_name']] = $candidate;
-      // Add any menus not already in the menu name search list.
-      if (!in_array($candidate['menu_name'], $menu_names)) {
-        $menu_names[] = $candidate['menu_name'];
-      }
-    }
-
-    // Store the most specific link for each menu. Also save the most specific
-    // link of the most preferred menu in $preferred_link.
-    foreach ($path_candidates as $link_path) {
-      if (isset($candidates[$link_path])) {
-        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];
-            $candidate_item['access'] = \Drupal::service('access_manager')->checkNamedRoute($candidate_item['route_name'], $candidate_item['route_parameters'], \Drupal::currentUser());
-            if ($candidate_item['access']) {
-              _menu_item_localize($candidate_item);
-              $preferred_links[$path][$menu_name] = $candidate_item;
-              if (empty($preferred_links[$path][MENU_PREFERRED_LINK])) {
-                // Store the most specific link.
-                $preferred_links[$path][MENU_PREFERRED_LINK] = $candidate_item;
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-
-  return isset($preferred_links[$path][$selected_menu]) ? $preferred_links[$path][$selected_menu] : FALSE;
-}
-
 /**
  * Clears all cached menu data.
  *
@@ -887,225 +680,6 @@ function menu_cache_clear_all() {
   \Drupal::cache('menu')->invalidateAll();
 }
 
-/**
- * Saves menu links recursively for menu_links_rebuild_defaults().
- */
-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 processed link names so we can find stragglers.
-  unset($children[$machine_name]);
-}
-
-/**
- * Builds menu links for the items returned from the menu_link.static service.
- */
-function menu_link_rebuild_defaults() {
-  // Ensure that all configuration used to build the menu items are loaded
-  // without overrides.
-  $old_state = \Drupal::configFactory()->getOverrideState();
-  \Drupal::configFactory()->setOverrideState(FALSE);
-  $module_handler = \Drupal::moduleHandler();
-  if (!$module_handler->moduleExists('menu_link')) {
-    // The Menu link module may not be available during install, so rebuild
-    // when possible.
-    return;
-  }
-  /** @var \Drupal\menu_link\MenuLinkStorageInterface $menu_link_storage */
-  $menu_link_storage = \Drupal::entityManager()
-    ->getStorage('menu_link');
-  $links = array();
-  $children = array();
-  $top_links = array();
-  $all_links = \Drupal::service('menu_link.static')->getLinks();
-  if ($all_links) {
-    foreach ($all_links as $machine_name => $link) {
-      // 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('machine_name', $machine_name)
-        ->execute()->fetchObject();
-      if ($existing_item) {
-        $existing_item->options = unserialize($existing_item->options);
-        $existing_item->route_parameters = unserialize($existing_item->route_parameters);
-        $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_storage->createFromDefaultLink($link);
-        // @todo Do not create a new entity in order to update it, see
-        //   https://drupal.org/node/2241865
-        $menu_link->setOriginalId($existing_item->mlid);
-
-        // Convert the existing item to a typed object.
-        /** @var \Drupal\menu_link\MenuLinkInterface $existing_item */
-        $existing_item = $menu_link_storage->create(get_object_vars($existing_item));
-
-        if (!$existing_item->customized) {
-          // A change in the default menu links may move the link to a
-          // different menu or parent.
-          if (!empty($link['menu_name']) && ($link['menu_name'] != $existing_item->menu_name)) {
-            $menu_link->plid = NULL;
-            $menu_link->menu_name = $link['menu_name'];
-          }
-          elseif (!empty($link['parent'])) {
-            $menu_link->plid = NULL;
-          }
-
-          $menu_link->original = $existing_item;
-        }
-      }
-      else {
-        if (empty($link['route_name']) && empty($link['link_path'])) {
-          \Drupal::logger('menu_link')->error('Menu_link %machine_name does neither provide a route_name nor a link_path, so it got skipped.', array('%machine_name' => $machine_name));
-          continue;
-        }
-        $menu_link = $menu_link_storage->createFromDefaultLink($link);
-      }
-      if (!empty($link['parent'])) {
-        $children[$link['parent']][$machine_name] = $machine_name;
-        $menu_link->parent = $link['parent'];
-        if (empty($link['menu_name'])) {
-          // Reset the default menu name so it is populated from the parent.
-          $menu_link->menu_name = NULL;
-        }
-      }
-      else {
-        // 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;
-    }
-  }
-  foreach ($top_links as $machine_name) {
-    _menu_link_save_recursive($menu_link_storage, $machine_name, $children, $links);
-  }
-  // Handle any children we didn't find starting from top-level links.
-  foreach ($children as $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_storage, $machine_name, $children, $links);
-    }
-  }
-
-  // Find any item whose default menu link no longer exists.
-  if ($all_links) {
-    $query = \Drupal::entityQuery('menu_link')
-      ->condition('machine_name', array_keys($all_links), 'NOT IN')
-      ->exists('machine_name')
-      ->condition('external', 0)
-      ->condition('updated', 0)
-      ->condition('customized', 0)
-      ->sort('depth', 'DESC');
-    $result = $query->execute();
-  }
-  else {
-    $result = array();
-  }
-
-  // Remove all such items. Starting from those with the greatest depth will
-  // minimize the amount of re-parenting done by the menu link controller.
-  if ($result) {
-    menu_link_delete_multiple($result, TRUE);
-  }
-  \Drupal::configFactory()->setOverrideState($old_state);
-}
-
-/**
- * Returns an array containing all links for a menu.
- *
- * @param $menu_name
- *   The name of the menu whose links should be returned.
- *
- * @return
- *   An array of menu links.
- */
-function menu_load_links($menu_name) {
-  $links = array();
-
-  $query = \Drupal::entityQuery('menu_link')
-    ->condition('menu_name', $menu_name)
-    // Order by weight so as to be helpful for menus that are only one level
-    // deep.
-    ->sort('weight');
-  $result = $query->execute();
-
-  if (!empty($result)) {
-    $links = menu_link_load_multiple($result);
-  }
-
-  return $links;
-}
-
-/**
- * Deletes all links for a menu.
- *
- * @param $menu_name
- *   The name of the menu whose links will be deleted.
- */
-function menu_delete_links($menu_name) {
-  $links = menu_load_links($menu_name);
-  menu_link_delete_multiple(array_keys($links), FALSE, TRUE);
-}
-
-/**
- * Updates the expanded menu item state at most twice per page load.
- */
-function _menu_update_expanded_menus() {
-  $expanded_menus_updated = &drupal_static(__FUNCTION__, 0);
-
-  // Update the expanded menu item state, but at most twice, including at
-  //  the end of the page load when there are multiple links saved or deleted.
-  if ($expanded_menus_updated == 0) {
-    // Keep track of which menus have expanded items.
-    _menu_set_expanded_menus();
-    $expanded_menus_updated = 1;
-  }
-  elseif ($expanded_menus_updated == 1) {
-    // Keep track of which menus have expanded items.
-    drupal_register_shutdown_function('_menu_set_expanded_menus');
-    $expanded_menus_updated = 2;
-  }
-}
-
-/**
- * Updates a list of menus with expanded items.
- */
-function _menu_set_expanded_menus() {
-  $names = array();
-  $result = Drupal::entityQueryAggregate('menu_link')
-    ->condition('expanded', 0, '<>')
-    ->groupBy('menu_name')
-    ->execute();
-
-  // Flatten the resulting array.
-  foreach($result as $k => $v) {
-    $names[$k] = $v['menu_name'];
-  }
-
-  \Drupal::state()->set('menu_expanded', $names);
-}
-
 /**
  * @} End of "defgroup menu".
  */
diff --git a/core/modules/menu_link/menu_link.api.php b/core/modules/menu_link/menu_link.api.php
deleted file mode 100644
index 470243671874..000000000000
--- a/core/modules/menu_link/menu_link.api.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-
-/**
- * @file
- * Hooks provided by the Menu link module.
- */
-
-/**
- * @addtogroup hooks
- * @{
- */
-
-/**
- * Alter a menu link after it has been translated and before it is rendered.
- *
- * This hook is invoked from _menu_link_translate() after a menu link has been
- * translated; i.e., after the user access to the link's target page has
- * been checked. It is only invoked if $menu_link['options']['alter'] has been
- * set to a non-empty value (e.g. TRUE). This flag should be set using
- * hook_ENTITY_TYPE_presave() for entity 'menu_link'.
- *
- * Implementations of this hook are able to alter any property of the menu link.
- * For example, this hook may be used to add a page-specific query string to all
- * menu links, or hide a certain link by setting:
- * @code
- *   'hidden' => 1,
- * @endcode
- *
- * @param \Drupal\menu_link\Entity\MenuLink $menu_link
- *   A menu link entity.
- *
- * @see hook_menu_link_alter()
- */
-function hook_translated_menu_link_alter(\Drupal\menu_link\Entity\MenuLink &$menu_link, $map) {
-  if ($menu_link->href == 'devel/cache/clear') {
-    $menu_link->localized_options['query'] = drupal_get_destination();
-  }
-}
-
-/**
- * @} End of "addtogroup hooks".
- */
diff --git a/core/modules/menu_link/menu_link.install b/core/modules/menu_link/menu_link.install
deleted file mode 100644
index c789d34ef822..000000000000
--- a/core/modules/menu_link/menu_link.install
+++ /dev/null
@@ -1,221 +0,0 @@
-<?php
-
-/**
- * @file
- * Install, update and uninstall functions for the menu_link module.
- */
-
-/**
- * Implements hook_schema().
- */
-function menu_link_schema() {
-  $schema['menu_links'] = array(
-    'description' => 'Contains the individual links within a menu.',
-    'fields' => array(
-     'menu_name' => array(
-        'description' => "The menu name. All links with the same menu name (such as 'tools') are part of the same menu.",
-        'type' => 'varchar',
-        'length' => 32,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'mlid' => array(
-        'description' => 'The menu link ID (mlid) is the integer primary key.',
-        'type' => 'serial',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-      ),
-      'uuid' => array(
-        'description' => 'Unique Key: Universally unique identifier for this entity.',
-        'type' => 'varchar',
-        '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',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'link_path' => array(
-        'description' => 'The Drupal path or external path this link points to.',
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'langcode' => array(
-        'description' => 'The {language}.langcode of this link.',
-        'type' => 'varchar',
-        'length' => 12,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'link_title' => array(
-        'description' => 'The text displayed for the link.',
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'options' => array(
-        'description' => 'A serialized array of options to be passed to the url() or l() function, such as a query string or HTML attributes.',
-        'type' => 'blob',
-        'not null' => FALSE,
-        'serialize' => TRUE,
-      ),
-      'module' => array(
-        'description' => 'The name of the module that generated this link.',
-        'type' => 'varchar',
-        'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH,
-        'not null' => TRUE,
-        'default' => 'system',
-      ),
-      'hidden' => array(
-        'description' => 'A flag for whether the link should be rendered in menus. (1 = a disabled menu item that may be shown on admin screens, -1 = a menu callback, 0 = a normal, visible link)',
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'small',
-      ),
-      'external' => array(
-        'description' => 'A flag to indicate if the link points to a full URL starting with a protocol, like http:// (1 = external, 0 = internal).',
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'small',
-      ),
-      'has_children' => array(
-        'description' => 'Flag indicating whether any links have this link as a parent (1 = children exist, 0 = no children).',
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'small',
-      ),
-      'expanded' => array(
-        'description' => 'Flag for whether this link should be rendered as expanded in menus - expanded links always have their child links displayed, instead of only when the link is in the active trail (1 = expanded, 0 = not expanded)',
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'small',
-      ),
-      'weight' => array(
-        'description' => 'Link weight among links in the same menu at the same depth.',
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'depth' => array(
-        'description' => 'The depth relative to the top level. A link with plid == 0 will have depth == 1.',
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'small',
-      ),
-      'customized' => array(
-        'description' => 'A flag to indicate that the user has manually created or edited the link (1 = customized, 0 = not customized).',
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'small',
-      ),
-      'p1' => array(
-        'description' => 'The first mlid in the materialized path. If N = depth, then pN must equal the mlid. If depth > 1 then p(N-1) must equal the plid. All pX where X > depth must equal zero. The columns p1 .. p9 are also called the parents.',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'p2' => array(
-        'description' => 'The second mlid in the materialized path. See p1.',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'p3' => array(
-        'description' => 'The third mlid in the materialized path. See p1.',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'p4' => array(
-        'description' => 'The fourth mlid in the materialized path. See p1.',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'p5' => array(
-        'description' => 'The fifth mlid in the materialized path. See p1.',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'p6' => array(
-        'description' => 'The sixth mlid in the materialized path. See p1.',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'p7' => array(
-        'description' => 'The seventh mlid in the materialized path. See p1.',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'p8' => array(
-        'description' => 'The eighth mlid in the materialized path. See p1.',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'p9' => array(
-        'description' => 'The ninth mlid in the materialized path. See p1.',
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'updated' => array(
-        'description' => 'Flag that indicates that this link was generated during the update from Drupal 5.',
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'small',
-      ),
-      'route_name' => array(
-        'description' => 'The machine name of a defined Symfony Route this menu item represents.',
-        'type' => 'varchar',
-        'length' => 255,
-      ),
-      'route_parameters' => array(
-        'description' => 'Serialized array of route parameters of this menu link.',
-        'type' => 'blob',
-        'size' => 'big',
-        'not null' => FALSE,
-        'serialize' => TRUE,
-      ),
-    ),
-    'indexes' => array(
-      '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'),
-    ),
-    'primary key' => array('mlid'),
-  );
-
-  return $schema;
-}
diff --git a/core/modules/menu_link/menu_link.module b/core/modules/menu_link/menu_link.module
deleted file mode 100644
index 8a2ce38c26e4..000000000000
--- a/core/modules/menu_link/menu_link.module
+++ /dev/null
@@ -1,225 +0,0 @@
-<?php
-
-/**
- * @file
- * Enables users to create menu links.
- */
-
-use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\Core\Url;
-use Drupal\menu_link\Entity\MenuLink;
-use Drupal\menu_link\MenuLinkInterface;
-
-function menu_link_help($route_name, RouteMatchInterface $route_match) {
-  switch ($route_name) {
-    case 'help.page.menu_link':
-      $output = '';
-      $output .= '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Menu Link module allows users to create menu links. It is required by the Menu UI module, which provides an interface for managing menus. See the <a href="!menu-help">Menu UI module help page</a> for more information.', array('!menu-help' => \Drupal::url('help.page', array('name' => 'menu_ui')))) . '</p>';
-      return $output;
-  }
-}
-
-/**
- * Entity URI callback.
- *
- * @param \Drupal\menu_link\Entity\MenuLink $menu_link
- *   A menu link entity.
- */
-function menu_link_uri(MenuLink $menu_link) {
-  return new Url($menu_link->route_name, $menu_link->route_parameters);
-}
-
-/**
- * Loads a menu link entity.
- *
- * This function should never be called from within node_load() or any other
- * function used as a menu object load function since an infinite recursion may
- * occur.
- *
- * @param int $mlid
- *   The menu link ID.
- * @param bool $reset
- *   (optional) Whether to reset the menu_link_load_multiple() cache.
- *
- * @return \Drupal\menu_link\Entity\MenuLink|null
- *   A menu link entity, or NULL if there is no entity with the given ID.
- *
- * @deprecated in Drupal 8.x, will be removed before Drupal 9.0.
- *   Use \Drupal\menu_link\Entity\MenuLink::load().
- */
-function menu_link_load($mlid = NULL, $reset = FALSE) {
-  if ($reset) {
-    \Drupal::entityManager()->getStorage('menu_link')->resetCache(array($mlid));
-  }
-  return MenuLink::load($mlid);
-}
-
-/**
- * Loads menu link entities from the database.
- *
- * @param array $mlids
- *   (optional) An array of entity IDs. If omitted, all entities are loaded.
- * @param bool $reset
- *   (optional) Whether to reset the internal cache.
- *
- * @return array<\Drupal\menu_link\Entity\MenuLink>
- *   An array of menu link entities indexed by entity IDs.
- *
- * @see menu_link_load()
- * @see entity_load_multiple()
- *
- * @deprecated in Drupal 8.x, will be removed before Drupal 9.0.
- *   Use \Drupal\menu_link\Entity\MenuLink::loadMultiple().
- */
-function menu_link_load_multiple(array $mlids = NULL, $reset = FALSE) {
-  if ($reset) {
-    \Drupal::entityManager()->getStorage('menu_link')->resetCache($mlids);
-  }
-  return MenuLink::loadMultiple($mlids);
-}
-
-/**
- * Deletes a menu link.
- *
- * @param int $mlid
- *   The menu link ID.
- *
- * @see menu_link_delete_multiple()
- */
-function menu_link_delete($mlid) {
-  menu_link_delete_multiple(array($mlid));
-}
-
-/**
- * Deletes multiple menu links.
- *
- * @param array $mlids
- *   An array of menu link IDs.
- * @param bool $force
- *   (optional) Forces deletion. Internal use only, setting to TRUE is
- *   discouraged. Defaults to FALSE.
- * @param bool $prevent_reparenting
- *   (optional) Disables the re-parenting logic from the deletion process.
- *   Defaults to FALSE.
- */
-function menu_link_delete_multiple(array $mlids, $force = FALSE, $prevent_reparenting = FALSE) {
-  if (!$mlids) {
-    // If no IDs or invalid IDs were passed, do nothing.
-    return;
-  }
-
-  $controller = \Drupal::entityManager()
-    ->getStorage('menu_link');
-  if (!$force) {
-    $entity_query = \Drupal::entityQuery('menu_link');
-    $group = $entity_query->orConditionGroup()
-      ->condition('module', 'system', '<>')
-      ->condition('updated', 0, '<>');
-
-    $entity_query->condition('mlid', $mlids, 'IN');
-    $entity_query->condition($group);
-
-    $result = $entity_query->execute();
-    $entities = $controller->loadMultiple($result);
-  }
-  else {
-    $entities = $controller->loadMultiple($mlids);
-  }
-  $controller->setPreventReparenting($prevent_reparenting);
-  $controller->delete($entities);
-}
-
-/**
- * Saves a menu link.
- *
- * After calling this function, rebuild the menu cache using
- * menu_cache_clear_all().
- *
- * @param \Drupal\menu_link\Entity\MenuLink $menu_link
- *   The menu link entity to be saved.
- *
- * @return int|bool
- *   Returns SAVED_NEW or SAVED_UPDATED if the save operation succeeded, or
- *   FALSE if it failed.
- */
-function menu_link_save(MenuLink $menu_link) {
-  return $menu_link->save();
-}
-
-/**
- * Inserts, updates, enables, disables, or deletes an uncustomized menu link.
- *
- * @param string $module
- *   The name of the module that owns the link.
- * @param string $op
- *   Operation to perform: insert, update, enable, disable, or delete.
- * @param string $link_path
- *   The path this link points to.
- * @param string $link_title
- *   (optional) Title of the link to insert or new title to update the link to.
- *   Unused for delete. Defaults to NULL.
- *
- * @return integer|null
- *   The insert op returns the mlid of the new item. Others op return NULL.
- */
-function menu_link_maintain($module, $op, $link_path, $link_title = NULL) {
-  $menu_link_controller = \Drupal::entityManager()
-    ->getStorage('menu_link');
-  switch ($op) {
-    case 'insert':
-      $menu_link = entity_create('menu_link', array(
-        'link_title' => $link_title,
-        'link_path' => $link_path,
-        'module' => $module,)
-      );
-      return $menu_link->save();
-
-    case 'update':
-      $menu_links = entity_load_multiple_by_properties('menu_link', array('link_path' => $link_path, 'module' => $module, 'customized' => 0));
-      foreach ($menu_links as $menu_link) {
-        $menu_link->original = clone $menu_link;
-        if (isset($link_title)) {
-          $menu_link->link_title = $link_title;
-        }
-        $menu_link_controller->save($menu_link);
-      }
-      break;
-
-    case 'enable':
-    case 'disable':
-      $menu_links = entity_load_multiple_by_properties('menu_link', array('link_path' => $link_path, 'module' => $module, 'customized' => 0));
-      foreach ($menu_links as $menu_link) {
-        $menu_link->original = clone $menu_link;
-        $menu_link->hidden = ($op == 'disable' ? 1 : 0);
-        $menu_link->customized = 1;
-        if (isset($link_title)) {
-          $menu_link->link_title = $link_title;
-        }
-        $menu_link_controller->save($menu_link);
-      }
-      break;
-
-    case 'delete':
-      $result = \Drupal::entityQuery('menu_link')->condition('link_path', $link_path)->execute();
-      if (!empty($result)) {
-        menu_link_delete_multiple($result);
-      }
-      break;
-  }
-}
-
-/**
- * Implements hook_system_breadcrumb_alter().
- */
-function menu_link_system_breadcrumb_alter(array &$breadcrumb, RouteMatchInterface $route_match, array $context) {
-  // Custom breadcrumb behavior for editing menu links, we append a link to
-  // the menu in which the link is found.
-  if (($route_match->getRouteName() == 'menu_ui.link_edit') && $menu_link = $route_match->getParameter('menu_link')) {
-    if (($menu_link instanceof MenuLinkInterface) && !$menu_link->isNew()) {
-      // Add a link to the menu admin screen.
-      $menu = entity_load('menu', $menu_link->menu_name);
-      $breadcrumb[] = Drupal::l($menu->label(), 'menu_ui.menu_edit', array('menu' => $menu->id));
-    }
-  }
-}
diff --git a/core/modules/menu_link/menu_link.services.yml b/core/modules/menu_link/menu_link.services.yml
deleted file mode 100644
index 88f5037de194..000000000000
--- a/core/modules/menu_link/menu_link.services.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-services:
-  menu_link.tree:
-    class: Drupal\menu_link\MenuTree
-    arguments: ['@database', '@cache.data', '@language_manager', '@request_stack', '@entity.manager', '@entity.query', '@state']
-  menu_link.static:
-    class: Drupal\menu_link\StaticMenuLinks
-    arguments: ['@module_handler']
diff --git a/core/modules/menu_link/src/Entity/MenuLink.php b/core/modules/menu_link/src/Entity/MenuLink.php
deleted file mode 100644
index e2215fdbaba8..000000000000
--- a/core/modules/menu_link/src/Entity/MenuLink.php
+++ /dev/null
@@ -1,680 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\menu_link\Entity\MenuLink.
- */
-
-namespace Drupal\menu_link\Entity;
-
-use Drupal\Component\Utility\NestedArray;
-use Drupal\Component\Utility\UrlHelper;
-use Drupal\Core\Cache\Cache;
-use Drupal\Core\Entity\Entity;
-use Drupal\Core\Entity\EntityStorageInterface;
-use Drupal\Core\Url;
-use Drupal\menu_link\MenuLinkInterface;
-use Symfony\Component\Routing\Route;
-
-/**
- * Defines the menu link entity class.
- *
- * @EntityType(
- *   id = "menu_link",
- *   label = @Translation("Menu link"),
- *   controllers = {
- *     "storage" = "Drupal\menu_link\MenuLinkStorage",
- *     "access" = "Drupal\menu_link\MenuLinkAccessController",
- *     "form" = {
- *       "default" = "Drupal\menu_link\MenuLinkForm"
- *     }
- *   },
- *   admin_permission = "administer menu",
- *   static_cache = FALSE,
- *   base_table = "menu_links",
- *   uri_callback = "menu_link_uri",
- *   translatable = TRUE,
- *   entity_keys = {
- *     "id" = "mlid",
- *     "label" = "link_title",
- *     "uuid" = "uuid",
- *     "bundle" = "bundle"
- *   },
- * )
- */
-class MenuLink extends Entity implements \ArrayAccess, MenuLinkInterface {
-
-  /**
-   * The link's menu name.
-   *
-   * @var string
-   */
-  public $menu_name = 'tools';
-
-  /**
-   * The link's bundle.
-   *
-   * @var string
-   */
-  public $bundle = 'tools';
-
-  /**
-   * The menu link ID.
-   *
-   * @var int
-   */
-  public $mlid;
-
-  /**
-   * An optional machine name if defined via the menu_link.static service.
-   *
-   * @var string
-   */
-  public $machine_name;
-
-  /**
-   * The menu link UUID.
-   *
-   * @var string
-   */
-  public $uuid;
-
-  /**
-   * The parent link ID.
-   *
-   * @var int
-   */
-  public $plid;
-
-  /**
-   * The Drupal path or external path this link points to.
-   *
-   * @var string
-   */
-  public $link_path;
-
-  /**
-   * The entity label.
-   *
-   * @var string
-   */
-  public $link_title = '';
-
-  /**
-   * A serialized array of options to be passed to the url() or l() function,
-   * such as a query string or HTML attributes.
-   *
-   * @var array
-   */
-  public $options = array();
-
-  /**
-   * The name of the module that generated this link.
-   *
-   * @var string
-   */
-  public $module = 'menu_ui';
-
-  /**
-   * A flag for whether the link should be rendered in menus.
-   *
-   * @var int
-   */
-  public $hidden = 0;
-
-  /**
-   * A flag to indicate if the link points to a full URL starting with a
-   * protocol, like http:// (1 = external, 0 = internal).
-   *
-   * @var int
-   */
-  public $external;
-
-  /**
-   * Flag indicating whether any links have this link as a parent.
-   *
-   * @var int
-   */
-  public $has_children = 0;
-
-  /**
-   * Flag for whether this link should be rendered as expanded in menus.
-   * Expanded links always have their child links displayed, instead of only
-   * when the link is in the active trail.
-   *
-   * @var int
-   */
-  public $expanded = 0;
-
-  /**
-   * Link weight among links in the same menu at the same depth.
-   *
-   * @var int
-   */
-  public $weight = 0;
-
-  /**
-   * The depth relative to the top level. A link with plid == 0 will have
-   * depth == 1.
-   *
-   * @var int
-   */
-  public $depth;
-
-  /**
-   * A flag to indicate that the user has manually created or edited the link.
-   *
-   * @var int
-   */
-  public $customized = 0;
-
-  /**
-   * The first entity ID in the materialized path.
-   *
-   * @var int
-   *
-   * @todo Investigate whether the p1, p2, .. pX properties can be moved to a
-   * single array property.
-   */
-  public $p1;
-
-  /**
-   * The second entity ID in the materialized path.
-   *
-   * @var int
-   */
-  public $p2;
-
-  /**
-   * The third entity ID in the materialized path.
-   *
-   * @var int
-   */
-  public $p3;
-
-  /**
-   * The fourth entity ID in the materialized path.
-   *
-   * @var int
-   */
-  public $p4;
-
-  /**
-   * The fifth entity ID in the materialized path.
-   *
-   * @var int
-   */
-  public $p5;
-
-  /**
-   * The sixth entity ID in the materialized path.
-   *
-   * @var int
-   */
-  public $p6;
-
-  /**
-   * The seventh entity ID in the materialized path.
-   *
-   * @var int
-   */
-  public $p7;
-
-  /**
-   * The eighth entity ID in the materialized path.
-   *
-   * @var int
-   */
-  public $p8;
-
-  /**
-   * The ninth entity ID in the materialized path.
-   *
-   * @var int
-   */
-  public $p9;
-
-  /**
-   * The menu link modification timestamp.
-   *
-   * @var int
-   */
-  public $updated = 0;
-
-  /**
-   * The name of the route associated with this menu link, if any.
-   *
-   * @var string
-   */
-  public $route_name;
-
-  /**
-   * The parameters of the route associated with this menu link, if any.
-   *
-   * @var array
-   */
-  public $route_parameters = array();
-
-  /**
-   * The route object associated with this menu link, if any.
-   *
-   * @var \Symfony\Component\Routing\Route
-   */
-  protected $routeObject;
-
-  /**
-   * Boolean indicating whether a new revision should be created on save.
-   *
-   * @var bool
-   */
-  protected $newRevision = FALSE;
-
-  /**
-   * Indicates whether this is the default revision.
-   *
-   * @var bool
-   */
-  protected $isDefaultRevision = TRUE;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setNewRevision($value = TRUE) {
-    $this->newRevision = $value;
-  }
-  /**
-   * {@inheritdoc}
-   */
-  public function isNewRevision() {
-    return $this->newRevision || ($this->getEntityType()->hasKey('revision') && !$this->getRevisionId());
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getRevisionId() {
-    return NULL;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isTranslatable() {
-    // @todo Inject the entity manager and retrieve bundle info from it.
-    $bundles = entity_get_bundles($this->entityTypeId);
-    return !empty($bundles[$this->bundle()]['translatable']);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function preSaveRevision(EntityStorageInterface $storage, \stdClass $record) {
-  }
-
-  /**
-   * Overrides Entity::id().
-   */
-  public function id() {
-    return $this->mlid;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function bundle() {
-    return $this->bundle;
-  }
-
-  /**
-   * Overrides Entity::createDuplicate().
-   */
-  public function createDuplicate() {
-    $duplicate = parent::createDuplicate();
-    $duplicate->plid = NULL;
-    return $duplicate;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getRoute() {
-    if (!$this->route_name) {
-      return NULL;
-    }
-    if (!($this->routeObject instanceof Route)) {
-      $route_provider = \Drupal::service('router.route_provider');
-      $this->routeObject = $route_provider->getRouteByName($this->route_name);
-    }
-    return $this->routeObject;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setRouteObject(Route $route) {
-    $this->routeObject = $route;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function reset() {
-    // To reset the link to its original values, we need to retrieve its
-    // definition from the menu_link.static service. Otherwise, for example,
-    // the link's menu would not be reset, because properties like the original
-    // 'menu_name' are not stored anywhere else. Since resetting a link happens
-    // rarely and this is a one-time operation, retrieving the full set of
-    // default menu links does little harm.
-    $all_links = \Drupal::service('menu_link.static')->getLinks();
-    $original = $all_links[$this->machine_name];
-    $original['machine_name'] = $this->machine_name;
-    /** @var \Drupal\menu_link\MenuLinkStorageInterface $storage */
-    $storage = \Drupal::entityManager()->getStorage($this->entityTypeId);
-    // @todo Do not create a new entity in order to update it, see
-    //   https://drupal.org/node/2241865
-    $new_link = $storage->createFromDefaultLink($original);
-    $new_link->setOriginalId($this->id());
-    // Allow the menu to be determined by the parent
-    if (!empty($new_link['parent']) && !empty($all_links[$new_link['parent']])) {
-      // Walk up the tree to find the menu name.
-      $parent = $all_links[$new_link['parent']];
-      $existing_parent = db_select('menu_links')
-        ->fields('menu_links')
-        ->condition('machine_name', $parent['machine_name'])
-        ->execute()->fetchAssoc();
-      if ($existing_parent) {
-        /** @var \Drupal\Core\Entity\EntityInterface $existing_parent */
-        $existing_parent = $storage->create($existing_parent);
-        $new_link->menu_name = $existing_parent->menu_name;
-        $new_link->plid = $existing_parent->id();
-      }
-    }
-    // Merge existing menu link's ID and 'has_children' property.
-    foreach (array('mlid', 'has_children') as $key) {
-      $new_link->{$key} = $this->{$key};
-    }
-    $new_link->save();
-    return $new_link;
-  }
-
-  /**
-   * Implements ArrayAccess::offsetExists().
-   */
-  public function offsetExists($offset) {
-    return isset($this->{$offset});
-  }
-
-  /**
-   * Implements ArrayAccess::offsetGet().
-   */
-  public function &offsetGet($offset) {
-    return $this->{$offset};
-  }
-
-  /**
-   * Implements ArrayAccess::offsetSet().
-   */
-  public function offsetSet($offset, $value) {
-    $this->{$offset} = $value;
-  }
-
-  /**
-   * Implements ArrayAccess::offsetUnset().
-   */
-  public function offsetUnset($offset) {
-    unset($this->{$offset});
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function preDelete(EntityStorageInterface $storage, array $entities) {
-    parent::preDelete($storage, $entities);
-
-    // Nothing to do if we don't want to reparent children.
-    if ($storage->getPreventReparenting()) {
-      return;
-    }
-
-    foreach ($entities as $entity) {
-      // Children get re-attached to the item's parent.
-      if ($entity->has_children) {
-        $children = $storage->loadByProperties(array('plid' => $entity->plid));
-        foreach ($children as $child) {
-          $child->plid = $entity->plid;
-          $storage->save($child);
-        }
-      }
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function postDelete(EntityStorageInterface $storage, array $entities) {
-    parent::postDelete($storage, $entities);
-
-    // Update the has_children status of the parent.
-    foreach ($entities as $entity) {
-      if (!$storage->getPreventReparenting()) {
-        $storage->updateParentalStatus($entity);
-      }
-    }
-
-    // Also clear the menu system static caches.
-    menu_reset_static_cache();
-    _menu_update_expanded_menus();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function preSave(EntityStorageInterface $storage) {
-    parent::preSave($storage);
-
-    // This is the easiest way to handle the unique internal path '<front>',
-    // since a path marked as external does not need to match a route.
-    $this->external = (UrlHelper::isExternal($this->link_path) || $this->link_path == '<front>') ? 1 : 0;
-
-    // Try to find a parent link. If found, assign it and derive its menu.
-    $parent = $this->findParent($storage);
-    if ($parent) {
-      $this->plid = $parent->id();
-      $this->menu_name = $parent->menu_name;
-    }
-    // If no corresponding parent link was found, move the link to the top-level.
-    else {
-      $this->plid = 0;
-    }
-
-    // Directly fill parents for top-level links.
-    if ($this->plid == 0) {
-      $this->p1 = $this->id();
-      for ($i = 2; $i <= MENU_MAX_DEPTH; $i++) {
-        $parent_property = "p$i";
-        $this->{$parent_property} = 0;
-      }
-      $this->depth = 1;
-    }
-    // Otherwise, ensure that this link's depth is not beyond the maximum depth
-    // and fill parents based on the parent link.
-    else {
-      if ($this->has_children && $this->original) {
-        $limit = MENU_MAX_DEPTH - $storage->findChildrenRelativeDepth($this->original) - 1;
-      }
-      else {
-        $limit = MENU_MAX_DEPTH - 1;
-      }
-      if ($parent->depth > $limit) {
-        return FALSE;
-      }
-      $this->depth = $parent->depth + 1;
-      $this->setParents($parent);
-    }
-
-    // Need to check both plid and menu_name, since plid can be 0 in any menu.
-    if (isset($this->original) && ($this->plid != $this->original->plid || $this->menu_name != $this->original->menu_name)) {
-      $storage->moveChildren($this);
-    }
-
-    // Find the route_name.
-    if (!$this->external && !isset($this->route_name)) {
-      $url = Url::createFromPath($this->link_path);
-      $this->route_name = $url->getRouteName();
-      $this->route_parameters = $url->getRouteParameters();
-    }
-    elseif (empty($this->link_path)) {
-      $this->link_path = \Drupal::urlGenerator()->getPathFromRoute($this->route_name, $this->route_parameters);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function postSave(EntityStorageInterface $storage, $update = TRUE) {
-    parent::postSave($storage, $update);
-
-    // Check the has_children status of the parent.
-    $storage->updateParentalStatus($this);
-
-
-    // Entity::postSave() calls Entity::invalidateTagsOnSave(), which only
-    // handles the regular cases. The MenuLink entity has two special cases.
-    $cache_tags = array();
-    // Case 1: a newly created menu link is *also* added to a menu, so we must
-    // invalidate the associated menu's cache tag.
-    if (!$update) {
-      $cache_tags = $this->getCacheTag();
-    }
-    // Case 2: a menu link may be moved from one menu to another; the original
-    // menu's cache tag must also be invalidated.
-    if (isset($this->original) && $this->menu_name != $this->original->menu_name) {
-      $cache_tags = NestedArray::mergeDeep($cache_tags, $this->original->getCacheTag());
-    }
-    Cache::invalidateTags($cache_tags);
-
-    // Also clear the menu system static caches.
-    menu_reset_static_cache();
-
-    // Track which menu items are expanded.
-    _menu_update_expanded_menus();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function postLoad(EntityStorageInterface $storage, array &$entities) {
-    parent::postLoad($storage, $entities);
-
-    $routes = array();
-    foreach ($entities as $menu_link) {
-      $menu_link->options = unserialize($menu_link->options);
-      $menu_link->route_parameters = unserialize($menu_link->route_parameters);
-
-      // By default use the menu_name as type.
-      $menu_link->bundle = $menu_link->menu_name;
-
-      // For all links that have an associated route, load the route object now
-      // and save it on the object. That way we avoid a select N+1 problem later.
-      if ($menu_link->route_name) {
-        $routes[$menu_link->id()] = $menu_link->route_name;
-      }
-    }
-
-    // Now mass-load any routes needed and associate them.
-    if ($routes) {
-      $route_objects = \Drupal::service('router.route_provider')->getRoutesByNames($routes);
-      foreach ($routes as $entity_id => $route) {
-        // Not all stored routes will be valid on load.
-        if (isset($route_objects[$route])) {
-          $entities[$entity_id]->setRouteObject($route_objects[$route]);
-        }
-      }
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setParents(MenuLinkInterface $parent) {
-    $i = 1;
-    while ($i < $this->depth) {
-      $p = 'p' . $i++;
-      $this->{$p} = $parent->{$p};
-    }
-    $p = 'p' . $i++;
-    // The parent (p1 - p9) corresponding to the depth always equals the mlid.
-    $this->{$p} = $this->id();
-    while ($i <= MENU_MAX_DEPTH) {
-      $p = 'p' . $i++;
-      $this->{$p} = 0;
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function findParent(EntityStorageInterface $storage) {
-    $parent = FALSE;
-
-    // This item is explicitly top-level, skip the rest of the parenting.
-    if (isset($this->plid) && empty($this->plid)) {
-      return $parent;
-    }
-
-    // If we have a parent link ID, try to use that.
-    $candidates = array();
-    if (isset($this->plid)) {
-      $candidates[] = $this->plid;
-    }
-
-    // Else, if we have a link hierarchy try to find a valid parent in there.
-    if (!empty($this->depth) && $this->depth > 1) {
-      for ($depth = $this->depth - 1; $depth >= 1; $depth--) {
-        $parent_property = "p$depth";
-        $candidates[] = $this->$parent_property;
-      }
-    }
-
-    foreach ($candidates as $mlid) {
-      $parent = $storage->load($mlid);
-      if ($parent) {
-        break;
-      }
-    }
-    return $parent;
-  }
-
-  /**
-   * Builds and returns the renderable array for this menu link.
-   *
-   * @return array
-   *   A renderable array representing the content of the link.
-   */
-  public function build() {
-    $build = array(
-      '#type' => 'link',
-      '#title' => $this->title,
-      '#href' => $this->href,
-      '#route_name' => $this->route_name ? $this->route_name : NULL,
-      '#route_parameters' => $this->route_parameters,
-      '#options' => !empty($this->localized_options) ? $this->localized_options : array(),
-    );
-    return $build;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getCacheTag() {
-    return entity_load('menu', $this->menu_name)->getCacheTag();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getListCacheTags() {
-    return entity_load('menu', $this->menu_name)->getListCacheTags();
-  }
-
-}
diff --git a/core/modules/menu_link/src/MenuLinkAccessController.php b/core/modules/menu_link/src/MenuLinkAccessController.php
deleted file mode 100644
index c6e6b911036d..000000000000
--- a/core/modules/menu_link/src/MenuLinkAccessController.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\menu_link\MenuLinkAccessController.
- */
-
-namespace Drupal\menu_link;
-
-use Drupal\Core\Entity\EntityAccessController;
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Session\AccountInterface;
-
-/**
- * Defines an access controller for the menu link entity.
- *
- * @see \Drupal\menu_link\Entity\MenuLink
- */
-class MenuLinkAccessController extends EntityAccessController {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
-    $access = $account->hasPermission('administer menu');
-    if ($access) {
-      switch ($operation) {
-        case 'reset':
-          // Reset allowed for items defined via hook_menu() and customized.
-          return !empty($entity->machine_name) && $entity->customized;
-
-        case 'delete':
-          // Only items created by the Menu UI module can be deleted.
-          return $entity->module == 'menu_ui' || $entity->updated == 1;
-
-      }
-    }
-    return $access;
-  }
-
-}
diff --git a/core/modules/menu_link/src/MenuLinkForm.php b/core/modules/menu_link/src/MenuLinkForm.php
deleted file mode 100644
index f5cbca1411c5..000000000000
--- a/core/modules/menu_link/src/MenuLinkForm.php
+++ /dev/null
@@ -1,311 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\menu_link\MenuLinkForm.
- */
-
-namespace Drupal\menu_link;
-
-use Drupal\Component\Utility\UrlHelper;
-use Drupal\Core\Entity\EntityForm;
-use Drupal\Core\Language\LanguageInterface;
-use Drupal\Core\Path\AliasManagerInterface;
-use Drupal\Core\Routing\UrlGenerator;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Form controller for the node edit forms.
- */
-class MenuLinkForm extends EntityForm {
-
-  /**
-   * The menu link storage.
-   *
-   * @var \Drupal\menu_link\MenuLinkStorageInterface
-   */
-  protected $menuLinkStorage;
-
-  /**
-   * The path alias manager.
-   *
-   * @var \Drupal\Core\Path\AliasManagerInterface
-   */
-  protected $pathAliasManager;
-
-  /**
-   * The URL generator.
-   *
-   * @var \Drupal\Core\Routing\UrlGenerator
-   */
-  protected $urlGenerator;
-
-  /**
-   * Constructs a new MenuLinkForm object.
-   *
-   * @param \Drupal\menu_link\MenuLinkStorageInterface $menu_link_storage
-   *   The menu link storage.
-   * @param \Drupal\Core\Path\AliasManagerInterface $path_alias_manager
-   *   The path alias manager.
-   * @param \Drupal\Core\Routing\UrlGenerator $url_generator
-   *   The URL generator.
-   */
-  public function __construct(MenuLinkStorageInterface $menu_link_storage, AliasManagerInterface $path_alias_manager, UrlGenerator $url_generator) {
-    $this->menuLinkStorage = $menu_link_storage;
-    $this->pathAliasManager = $path_alias_manager;
-    $this->urlGenerator = $url_generator;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('entity.manager')->getStorage('menu_link'),
-      $container->get('path.alias_manager'),
-      $container->get('url_generator')
-    );
-  }
-
-  /**
-   * Overrides EntityForm::form().
-   */
-  public function form(array $form, array &$form_state) {
-    $menu_link = $this->entity;
-    // Since menu_link_load() no longer returns a translated and access checked
-    // item, do it here instead.
-    _menu_link_translate($menu_link);
-
-    $form['link_title'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Menu link title'),
-      '#default_value' => $menu_link->link_title,
-      '#description' => t('The text to be used for this link in the menu.'),
-      '#required' => TRUE,
-    );
-    foreach (array('link_path', 'mlid', 'module', 'has_children', 'options') as $key) {
-      $form[$key] = array('#type' => 'value', '#value' => $menu_link->{$key});
-    }
-    // Any item created or edited via this interface is considered "customized".
-    $form['customized'] = array('#type' => 'value', '#value' => 1);
-
-    // We are not using url() when constructing this path because it would add
-    // $base_path.
-    $path = $menu_link->link_path;
-    if (isset($menu_link->options['query'])) {
-      $path .= '?' . $this->urlGenerator->httpBuildQuery($menu_link->options['query']);
-    }
-    if (isset($menu_link->options['fragment'])) {
-      $path .= '#' . $menu_link->options['fragment'];
-    }
-    if ($menu_link->module == 'menu_ui') {
-      $form['link_path'] = array(
-        '#type' => 'textfield',
-        '#title' => t('Path'),
-        '#maxlength' => 255,
-        '#default_value' => $path,
-        '#description' => t('The path for this menu link. This can be an internal Drupal path such as %add-node or an external URL such as %drupal. Enter %front to link to the front page.', array('%front' => '<front>', '%add-node' => 'node/add', '%drupal' => 'http://drupal.org')),
-        '#required' => TRUE,
-      );
-    }
-    else {
-      $form['_path'] = array(
-        '#type' => 'item',
-        '#title' => t('Path'),
-        '#description' => l($menu_link->link_title, $menu_link->href, $menu_link->options),
-      );
-    }
-
-    $form['description'] = array(
-      '#type' => 'textarea',
-      '#title' => t('Description'),
-      '#default_value' => isset($menu_link->options['attributes']['title']) ? $menu_link->options['attributes']['title'] : '',
-      '#rows' => 1,
-      '#description' => t('Shown when hovering over the menu link.'),
-    );
-    $form['enabled'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Enabled'),
-      '#default_value' => !$menu_link->hidden,
-      '#description' => t('Menu links that are not enabled will not be listed in any menu.'),
-    );
-    $form['expanded'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Show as expanded'),
-      '#default_value' => $menu_link->expanded,
-      '#description' => t('If selected and this menu link has children, the menu will always appear expanded.'),
-    );
-
-    // Generate a list of possible parents (not including this link or descendants).
-    $options = menu_ui_parent_options(menu_ui_get_menus(), $menu_link);
-    $default = $menu_link->menu_name . ':' . $menu_link->plid;
-    if (!isset($options[$default])) {
-      $default = 'tools:0';
-    }
-    $form['parent'] = array(
-      '#type' => 'select',
-      '#title' => t('Parent link'),
-      '#default_value' => $default,
-      '#options' => $options,
-      '#description' => t('The maximum depth for a link and all its children is fixed at !maxdepth. Some menu links may not be available as parents if selecting them would exceed this limit.', array('!maxdepth' => MENU_MAX_DEPTH)),
-      '#attributes' => array('class' => array('menu-title-select')),
-    );
-
-    // Get number of items in menu so the weight selector is sized appropriately.
-    $delta = $this->menuLinkStorage->countMenuLinks($menu_link->menu_name);
-    $form['weight'] = array(
-      '#type' => 'weight',
-      '#title' => t('Weight'),
-      // Old hardcoded value.
-      '#delta' => max($delta, 50),
-      '#default_value' => $menu_link->weight,
-      '#description' => t('Optional. In the menu, the heavier links will sink and the lighter links will be positioned nearer the top.'),
-    );
-
-    // Language module allows to configure the menu link language independently
-    // of the menu language. It also allows to optionally show the language
-    // selector on the menu link form so that the language of each menu link can
-    // be configured individually.
-    if ($this->moduleHandler->moduleExists('language')) {
-      $language_configuration = language_get_default_configuration('menu_link', $menu_link->bundle());
-      $default_langcode = ($menu_link->isNew() ? $language_configuration['langcode'] : $menu_link->langcode);
-      $language_show = $language_configuration['language_show'];
-    }
-    // Without Language module menu links inherit the menu language and no
-    // language selector is shown.
-    else {
-      $default_langcode = ($menu_link->isNew() ? entity_load('menu', $menu_link->menu_name)->language()->getId() : $menu_link->langcode);
-      $language_show = FALSE;
-    }
-
-    $form['langcode'] = array(
-      '#type' => 'language_select',
-      '#title' => t('Language'),
-      '#languages' => LanguageInterface::STATE_ALL,
-      '#default_value' => $default_langcode,
-      '#access' => $language_show,
-    );
-
-    return parent::form($form, $form_state, $menu_link);
-  }
-
-  /**
-   * Overrides EntityForm::actions().
-   */
-  protected function actions(array $form, array &$form_state) {
-    $element = parent::actions($form, $form_state);
-    $element['submit']['#button_type'] = 'primary';
-    return $element;
-  }
-
-  /**
-   * Overrides EntityForm::validate().
-   */
-  public function validate(array $form, array &$form_state) {
-    $menu_link = $this->buildEntity($form, $form_state);
-
-    $normal_path = $this->pathAliasManager->getPathByAlias($menu_link->link_path);
-    if ($menu_link->link_path != $normal_path) {
-      drupal_set_message(t('The menu system stores system paths only, but will use the URL alias for display. %link_path has been stored as %normal_path', array('%link_path' => $menu_link->link_path, '%normal_path' => $normal_path)));
-      $menu_link->link_path = $normal_path;
-      $form_state['values']['link_path'] = $normal_path;
-    }
-    if (!UrlHelper::isExternal($menu_link->link_path)) {
-      $parsed_link = parse_url($menu_link->link_path);
-      if (isset($parsed_link['query'])) {
-        $menu_link->options['query'] = array();
-        parse_str($parsed_link['query'], $menu_link->options['query']);
-      }
-      else {
-        // Use unset() rather than setting to empty string
-        // to avoid redundant serialized data being stored.
-        unset($menu_link->options['query']);
-      }
-      if (isset($parsed_link['fragment'])) {
-        $menu_link->options['fragment'] = $parsed_link['fragment'];
-      }
-      else {
-        unset($menu_link->options['fragment']);
-      }
-      if (isset($parsed_link['path']) && $menu_link->link_path != $parsed_link['path']) {
-        $menu_link->link_path = $parsed_link['path'];
-      }
-    }
-    if (!trim($menu_link->link_path) || !drupal_valid_path($menu_link->link_path, TRUE)) {
-      $this->setFormError('link_path', $form_state, $this->t("The path '@link_path' is either invalid or you do not have access to it.", array('@link_path' => $menu_link->link_path)));
-    }
-
-    parent::validate($form, $form_state);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildEntity(array $form, array &$form_state) {
-    // @todo: Remove this when menu links are converted to content entities in
-    //   http://drupal.org/node/1842858.
-    $entity = clone $this->entity;
-    // If you submit a form, the form state comes from caching, which forces
-    // the controller to be the one before caching. Ensure to have the
-    // controller of the current request.
-    $form_state['controller'] = $this;
-
-    // Copy top-level form values to entity properties, without changing
-    // existing entity properties that are not being edited by
-    // this form.
-    foreach ($form_state['values'] as $key => $value) {
-      $entity->$key = $value;
-    }
-
-    // Invoke all specified builders for copying form values to entity properties.
-    if (isset($form['#entity_builders'])) {
-      foreach ($form['#entity_builders'] as $function) {
-        call_user_func_array($function, array($entity->getEntityTypeId(), $entity, &$form, &$form_state));
-      }
-    }
-
-    return $entity;
-  }
-
-  /**
-   * Overrides EntityForm::submit().
-   */
-  public function submit(array $form, array &$form_state) {
-    // Build the menu link object from the submitted values.
-    $menu_link = parent::submit($form, $form_state);
-
-    // The value of "hidden" is the opposite of the value supplied by the
-    // "enabled" checkbox.
-    $menu_link->hidden = (int) !$menu_link->enabled;
-    unset($menu_link->enabled);
-
-    $menu_link->options['attributes']['title'] = $menu_link->description;
-    list($menu_link->menu_name, $menu_link->plid) = explode(':', $menu_link->parent);
-
-    return $menu_link;
-  }
-
-  /**
-   * Overrides EntityForm::save().
-   */
-  public function save(array $form, array &$form_state) {
-    $menu_link = $this->entity;
-
-    $saved = $menu_link->save();
-
-    if ($saved) {
-      drupal_set_message(t('The menu link has been saved.'));
-      $form_state['redirect_route'] = array(
-        'route_name' => 'menu_ui.menu_edit',
-        'route_parameters' => array(
-          'menu' => $menu_link->menu_name,
-        ),
-      );
-    }
-    else {
-      drupal_set_message(t('There was an error saving the menu link.'), 'error');
-      $form_state['rebuild'] = TRUE;
-    }
-  }
-
-}
diff --git a/core/modules/menu_link/src/MenuLinkInterface.php b/core/modules/menu_link/src/MenuLinkInterface.php
deleted file mode 100644
index fdfab6765116..000000000000
--- a/core/modules/menu_link/src/MenuLinkInterface.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\menu_link\MenuLinkInterface.
- */
-
-namespace Drupal\menu_link;
-
-use Drupal\Core\Entity\EntityInterface;
-use Symfony\Component\Routing\Route;
-
-/**
- * Provides an interface defining a menu link entity.
- */
-interface MenuLinkInterface extends EntityInterface {
-
-  /**
-   * Returns the Route object associated with this link, if any.
-   *
-   * @return \Symfony\Component\Routing\Route|null
-   *   The route object for this menu link, or NULL if there isn't one.
-   */
-  public function getRoute();
-
-  /**
-   * Sets the route object for this link.
-   *
-   * This should only be called by MenuLinkStorage when loading
-   * the link object. Calling it at other times could result in unpredictable
-   * behavior.
-   *
-   * @param \Symfony\Component\Routing\Route $route
-   */
-  public function setRouteObject(Route $route);
-
-  /**
-   * Resets a system-defined menu link.
-   *
-   * @return \Drupal\menu_link\MenuLinkInterface
-   *   A menu link entity.
-   */
-  public function reset();
-
-}
diff --git a/core/modules/menu_link/src/MenuLinkStorage.php b/core/modules/menu_link/src/MenuLinkStorage.php
deleted file mode 100644
index 1ece00d171eb..000000000000
--- a/core/modules/menu_link/src/MenuLinkStorage.php
+++ /dev/null
@@ -1,319 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\menu_link\MenuLinkStorage.
- */
-
-namespace Drupal\menu_link;
-
-use Drupal\Core\Entity\EntityDatabaseStorage;
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Entity\EntityStorageException;
-
-/**
- * Controller class for menu links.
- *
- * This extends the Drupal\entity\EntityDatabaseStorage class, adding
- * required special handling for menu_link entities.
- */
-class MenuLinkStorage extends EntityDatabaseStorage implements MenuLinkStorageInterface {
-
-  /**
-   * Indicates whether the delete operation should re-parent children items.
-   *
-   * @var bool
-   */
-  protected $preventReparenting = FALSE;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function create(array $values = array()) {
-    // The bundle of menu links being the menu name is not enforced but is the
-    // default behavior if no bundle is set.
-    if (!isset($values['bundle']) && isset($values['menu_name'])) {
-      $values['bundle'] = $values['menu_name'];
-    }
-    return parent::create($values);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function save(EntityInterface $entity) {
-
-    // We return SAVED_UPDATED by default because the logic below might not
-    // update the entity if its values haven't changed, so returning FALSE
-    // would be confusing in that situation.
-    $return = SAVED_UPDATED;
-
-    $transaction = $this->database->startTransaction();
-    try {
-      // Load the stored entity, if any.
-      if (!$entity->isNew() && !isset($entity->original)) {
-        $id = $entity->id();
-        if ($entity->getOriginalId() !== NULL) {
-          $id = $entity->getOriginalId();
-        }
-        $entity->original = $this->loadUnchanged($id);
-      }
-
-      if ($entity->isNew()) {
-        $entity->mlid = $this->database->insert($this->entityType->getBaseTable())->fields(array('menu_name' => $entity->menu_name))->execute();
-        $entity->enforceIsNew();
-      }
-
-      // Unlike the save() method from EntityDatabaseStorage, we invoke the
-      // 'presave' hook first because we want to allow modules to alter the
-      // entity before all the logic from our preSave() method.
-      $this->invokeHook('presave', $entity);
-      $entity->preSave($this);
-
-      // If every value in $entity->original is the same in the $entity, there
-      // is no reason to run the update queries or clear the caches. We use
-      // array_intersect_key() with the $entity as the first parameter because
-      // $entity may have additional keys left over from building a router entry.
-      // The intersect removes the extra keys, allowing a meaningful comparison.
-      if ($entity->isNew() || (array_intersect_key(get_object_vars($entity), get_object_vars($entity->original)) != get_object_vars($entity->original))) {
-        $return = drupal_write_record($this->entityType->getBaseTable(), $entity, $this->idKey);
-
-        if ($return) {
-          if (!$entity->isNew()) {
-            $this->resetCache(array($entity->{$this->idKey}));
-            $entity->postSave($this, TRUE);
-            $this->invokeHook('update', $entity);
-          }
-          else {
-            $return = SAVED_NEW;
-            $this->resetCache();
-
-            $entity->enforceIsNew(FALSE);
-            $entity->postSave($this, FALSE);
-            $this->invokeHook('insert', $entity);
-          }
-        }
-      }
-
-      // Ignore replica server temporarily.
-      db_ignore_replica();
-      unset($entity->original);
-
-      return $return;
-    }
-    catch (\Exception $e) {
-      $transaction->rollback();
-      watchdog_exception($this->entityTypeId, $e);
-      throw new EntityStorageException($e->getMessage(), $e->getCode(), $e);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setPreventReparenting($value = FALSE) {
-    $this->preventReparenting = $value;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPreventReparenting() {
-    return $this->preventReparenting;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function loadUpdatedCustomized(array $router_paths) {
-    $query = parent::buildQuery(NULL);
-    $query
-      ->condition(db_or()
-      ->condition('updated', 1)
-      ->condition(db_and()
-        ->condition('router_path', $router_paths, 'NOT IN')
-        ->condition('external', 0)
-        ->condition('customized', 1)
-        )
-      );
-    $query_result = $query->execute();
-
-    // We provide the necessary arguments for PDO to create objects of the
-    // specified entity class.
-    // @see \Drupal\Core\Entity\EntityInterface::__construct()
-    $query_result->setFetchMode(\PDO::FETCH_CLASS, $this->entityClass, array(array(), $this->entityTypeId));
-
-    return $query_result->fetchAllAssoc($this->idKey);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function loadModuleAdminTasks() {
-    // @todo - this code will move out of the menu link entity, so we are doing
-    //   a straight SQL query for expediency.
-    $result = $this->database->select('menu_links');
-    $result->condition('machine_name', 'system.admin');
-    $result->addField('menu_links', 'mlid');
-    $plid = $result->execute()->fetchField();
-
-    $query = $this->database->select('menu_links', 'base', array('fetch' => \PDO::FETCH_ASSOC));
-    $query->fields('base');
-    $query
-      ->condition('base.hidden', 0, '>=')
-      ->condition('base.module', '', '>')
-      ->condition('base.machine_name', '', '>')
-      ->condition('base.p1', $plid);
-    $entities = $query->execute()->fetchAll();
-
-    return $entities;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function updateParentalStatus(EntityInterface $entity, $exclude = FALSE) {
-    // If plid == 0, there is nothing to update.
-    if ($entity->plid) {
-      // Check if at least one visible child exists in the table.
-      $query = $this->getQuery();
-      $query
-        ->condition('menu_name', $entity->menu_name)
-        ->condition('hidden', 0)
-        ->condition('plid', $entity->plid)
-        ->count();
-
-      if ($exclude) {
-        $query->condition('mlid', $entity->id(), '<>');
-      }
-
-      $parent_has_children = ((bool) $query->execute()) ? 1 : 0;
-      $this->database->update('menu_links')
-        ->fields(array('has_children' => $parent_has_children))
-        ->condition('mlid', $entity->plid)
-        ->execute();
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function findChildrenRelativeDepth(EntityInterface $entity) {
-    // @todo Since all we need is a specific field from the base table, does it
-    // make sense to convert to EFQ?
-    $query = $this->database->select('menu_links');
-    $query->addField('menu_links', 'depth');
-    $query->condition('menu_name', $entity->menu_name);
-    $query->orderBy('depth', 'DESC');
-    $query->range(0, 1);
-
-    $i = 1;
-    $p = 'p1';
-    while ($i <= MENU_MAX_DEPTH && $entity->{$p}) {
-      $query->condition($p, $entity->{$p});
-      $p = 'p' . ++$i;
-    }
-
-    $max_depth = $query->execute()->fetchField();
-
-    return ($max_depth > $entity->depth) ? $max_depth - $entity->depth : 0;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function moveChildren(EntityInterface $entity) {
-    $query = $this->database->update($this->entityType->getBaseTable());
-
-    $query->fields(array('menu_name' => $entity->menu_name));
-
-    $p = 'p1';
-    $expressions = array();
-    for ($i = 1; $i <= $entity->depth; $p = 'p' . ++$i) {
-      $expressions[] = array($p, ":p_$i", array(":p_$i" => $entity->{$p}));
-    }
-    $j = $entity->original->depth + 1;
-    while ($i <= MENU_MAX_DEPTH && $j <= MENU_MAX_DEPTH) {
-      $expressions[] = array('p' . $i++, 'p' . $j++, array());
-    }
-    while ($i <= MENU_MAX_DEPTH) {
-      $expressions[] = array('p' . $i++, 0, array());
-    }
-
-    $shift = $entity->depth - $entity->original->depth;
-    if ($shift > 0) {
-      // The order of expressions must be reversed so the new values don't
-      // overwrite the old ones before they can be used because "Single-table
-      // UPDATE assignments are generally evaluated from left to right"
-      // @see http://dev.mysql.com/doc/refman/5.0/en/update.html
-      $expressions = array_reverse($expressions);
-    }
-    foreach ($expressions as $expression) {
-      $query->expression($expression[0], $expression[1], $expression[2]);
-    }
-
-    $query->expression('depth', 'depth + :depth', array(':depth' => $shift));
-    $query->condition('menu_name', $entity->original->menu_name);
-    $p = 'p1';
-    for ($i = 1; $i <= MENU_MAX_DEPTH && $entity->original->{$p}; $p = 'p' . ++$i) {
-      $query->condition($p, $entity->original->{$p});
-    }
-
-    $query->execute();
-
-    // Check the has_children status of the parent, while excluding this item.
-    $this->updateParentalStatus($entity->original, TRUE);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function countMenuLinks($menu_name) {
-    $query = $this->getQuery();
-    $query
-      ->condition('menu_name', $menu_name)
-      ->count();
-    return $query->execute();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getParentFromHierarchy(EntityInterface $entity) {
-    $parent_path = $entity->link_path;
-    do {
-      $parent = FALSE;
-      $parent_path = substr($parent_path, 0, strrpos($parent_path, '/'));
-
-      $query = $this->getQuery();
-      $query
-        ->condition('mlid', $entity->id(), '<>')
-        ->condition('module', 'system')
-        // We always respect the link's 'menu_name'; inheritance for router
-        // items is ensured in _menu_router_build().
-        ->condition('menu_name', $entity->menu_name)
-        ->condition('link_path', $parent_path);
-
-      $result = $query->execute();
-      // Only valid if we get a unique result.
-      if (count($result) == 1) {
-        $parent = $this->load(reset($result));
-      }
-    } while ($parent === FALSE && $parent_path);
-
-    return $parent;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function createFromDefaultLink(array $item) {
-    // Suggested items are disabled by default.
-    $item += array(
-      'hidden' => 0,
-      'options' => empty($item['description']) ? array() : array('attributes' => array('title' => $item['description'])),
-    );
-    return $this->create($item);
-  }
-
-}
diff --git a/core/modules/menu_link/src/MenuLinkStorageInterface.php b/core/modules/menu_link/src/MenuLinkStorageInterface.php
deleted file mode 100644
index 3d3fd5d10c51..000000000000
--- a/core/modules/menu_link/src/MenuLinkStorageInterface.php
+++ /dev/null
@@ -1,110 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\menu_link\MenuLinkStorageInterface.
-*/
-
-namespace Drupal\menu_link;
-
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Entity\EntityStorageInterface;
-
-/**
- * Defines a common interface for menu link entity controller classes.
- */
-interface MenuLinkStorageInterface extends EntityStorageInterface {
-
-  /**
-   * Sets an internal flag that allows us to prevent the reparenting operations
-   * executed during deletion.
-   *
-   * @param bool $value
-   *   TRUE if reparenting should be allowed, FALSE if it should be prevented.
-   */
-  public function setPreventReparenting($value = FALSE);
-
-  /**
-   * Gets value of internal flag that allows/prevents reparenting operations
-   * executed during deletion.
-   *
-   * @return bool
-   *   TRUE if reparenting is allowed, FALSE if it is prevented.
-   */
-  public function getPreventReparenting();
-
-  /**
-   * Loads system menu link as needed by system_get_module_admin_tasks().
-   *
-   * @return array
-   *   An array of menu link entities indexed by their IDs.
-   */
-  public function loadModuleAdminTasks();
-
-  /**
-   * Checks and updates the 'has_children' property for the parent of a link.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $entity
-   *   A menu link entity.
-   */
-  public function updateParentalStatus(EntityInterface $entity, $exclude = FALSE);
-
-  /**
-   * Finds the depth of an item's children relative to its depth.
-   *
-   * For example, if the item has a depth of 2 and the maximum of any child in
-   * the menu link tree is 5, the relative depth is 3.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $entity
-   *   A menu link entity.
-   *
-   * @return int
-   *   The relative depth, or zero.
-   */
-  public function findChildrenRelativeDepth(EntityInterface $entity);
-
-  /**
-   * Updates the children of a menu link that is being moved.
-   *
-   * The menu name, parents (p1 - p6), and depth are updated for all children of
-   * the link, and the has_children status of the previous parent is updated.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $entity
-   *   A menu link entity.
-   */
-  public function moveChildren(EntityInterface $entity);
-
-  /**
-   * Returns the number of menu links from a menu.
-   *
-   * @param string $menu_name
-   *   The unique name of a menu.
-   */
-  public function countMenuLinks($menu_name);
-
-  /**
-   * Tries to derive menu link's parent from the path hierarchy.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $entity
-   *   A menu link entity.
-   *
-   * @return \Drupal\Core\Entity\EntityInterface|false
-   *   A menu link entity or FALSE if not valid parent was found.
-   */
-  public function getParentFromHierarchy(EntityInterface $entity);
-
-  /**
-   * Builds a menu link entity from a default item.
-   *
-   * This function should only be called for link data from
-   * the menu_link.static service.
-   *
-   * @param array $item
-   *   An item returned from the menu_link.static service.
-   *
-   * @return \Drupal\menu_link\MenuLinkInterface
-   *   A menu link entity.
-   */
-  public function createFromDefaultLink(array $item);
-
-}
diff --git a/core/modules/menu_link/src/MenuTree.php b/core/modules/menu_link/src/MenuTree.php
deleted file mode 100644
index adbf85d33e38..000000000000
--- a/core/modules/menu_link/src/MenuTree.php
+++ /dev/null
@@ -1,619 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\menu_link\MenuTree.
- */
-
-namespace Drupal\menu_link;
-
-use Drupal\Core\Cache\Cache;
-use Drupal\Core\Cache\CacheBackendInterface;
-use Drupal\Core\Database\Connection;
-use Drupal\Core\Entity\EntityManagerInterface;
-use Drupal\Core\Entity\Query\QueryFactory;
-use Drupal\Core\State\StateInterface;
-use Drupal\Core\Language\LanguageManagerInterface;
-use Symfony\Cmf\Component\Routing\RouteObjectInterface;
-use Symfony\Component\HttpFoundation\RequestStack;
-
-/**
- * Provides the default implementation of a menu tree.
- */
-class MenuTree implements MenuTreeInterface {
-
-  /**
-   * The database connection.
-   *
-   * @var \Drupal\Core\Database\Connection
-   *   The database connection.
-   */
-  protected $database;
-
-  /**
-   * The cache backend.
-   *
-   * @var \Drupal\Core\Cache\CacheBackendInterface
-   */
-  protected $cache;
-
-  /**
-   * The language manager.
-   *
-   * @var \Drupal\Core\Language\LanguageManagerInterface
-   */
-  protected $languageManager;
-
-  /**
-   * The request stack.
-   *
-   * @var \Symfony\Component\HttpFoundation\RequestStack
-   */
-  protected $requestStack;
-
-  /**
-   * The menu link storage.
-   *
-   * @var \Drupal\menu_link\MenuLinkStorageInterface
-   */
-  protected $menuLinkStorage;
-
-  /**
-   * The entity query factory.
-   *
-   * @var \Drupal\Core\Entity\Query\QueryFactory
-   */
-  protected $queryFactory;
-
-  /**
-   * The state.
-   *
-   * @var \Drupal\Core\State\StateInterface
-   */
-  protected $state;
-
-  /**
-   * A list of active trail paths keyed by $menu_name.
-   *
-   * @var array
-   */
-  protected $trailPaths;
-
-  /**
-   * Stores the rendered menu output keyed by $menu_name.
-   *
-   * @var array
-   */
-  protected $menuOutput;
-
-  /**
-   * Stores the menu tree used by the doBuildTree method, keyed by a cache ID.
-   *
-   * This cache ID is built using the $menu_name, the current language and
-   * some parameters passed into an entity query.
-   */
-  protected $menuTree;
-
-  /**
-   * Stores the full menu tree data keyed by a cache ID.
-   *
-   * This variable distinct from static::$menuTree by having also items without
-   * access by the current user.
-   *
-   * This cache ID is built with the menu name, a passed in root link ID, the
-   * current language as well as the maximum depth.
-   *
-   * @var array
-   */
-  protected $menuFullTrees;
-
-  /**
-   * Stores the menu tree data on the current page keyed by a cache ID.
-   *
-   * This contains less information than a tree built with buildAllData.
-   *
-   * @var array
-   */
-  protected $menuPageTrees;
-
-  /**
-   * Constructs a new MenuTree.
-   *
-   * @param \Drupal\Core\Database\Connection $database
-   *   The database connection.
-   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
-   *   The cache backend.
-   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
-   *   The language manager.
-   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
-   *   The request stack.
-   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
-   *   The entity manager.
-   * @param \Drupal\Core\Entity\Query\QueryFactory $entity_query_factory
-   *   The entity query factory.
-   * @param \Drupal\Core\State\StateInterface $state
-   *   The state.
-   */
-  public function __construct(Connection $database, CacheBackendInterface $cache_backend, LanguageManagerInterface $language_manager, RequestStack $request_stack, EntityManagerInterface $entity_manager, QueryFactory $entity_query_factory, StateInterface $state) {
-    $this->database = $database;
-    $this->cache = $cache_backend;
-    $this->languageManager = $language_manager;
-    $this->requestStack = $request_stack;
-    $this->menuLinkStorage = $entity_manager->getStorage('menu_link');
-    $this->queryFactory = $entity_query_factory;
-    $this->state = $state;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildAllData($menu_name, $link = NULL, $max_depth = NULL) {
-    $language_interface = $this->languageManager->getCurrentLanguage();
-
-    // Use $mlid as a flag for whether the data being loaded is for the whole
-    // tree.
-    $mlid = isset($link['mlid']) ? $link['mlid'] : 0;
-    // Generate a cache ID (cid) specific for this $menu_name, $link, $language,
-    // and depth.
-    $cid = 'links:' . $menu_name . ':all:' . $mlid . ':' . $language_interface->id . ':' . (int) $max_depth;
-
-    if (!isset($this->menuFullTrees[$cid])) {
-      // If the static variable doesn't have the data, check {cache_menu}.
-      $cache = $this->cache->get($cid);
-      if ($cache && $cache->data) {
-        // If the cache entry exists, it contains the parameters for
-        // menu_build_tree().
-        $tree_parameters = $cache->data;
-      }
-      // If the tree data was not in the cache, build $tree_parameters.
-      if (!isset($tree_parameters)) {
-        $tree_parameters = array(
-          'min_depth' => 1,
-          'max_depth' => $max_depth,
-        );
-        if ($mlid) {
-          // The tree is for a single item, so we need to match the values in
-          // its p columns and 0 (the top level) with the plid values of other
-          // links.
-          $parents = array(0);
-          for ($i = 1; $i < MENU_MAX_DEPTH; $i++) {
-            if (!empty($link["p$i"])) {
-              $parents[] = $link["p$i"];
-            }
-          }
-          $tree_parameters['expanded'] = $parents;
-          $tree_parameters['active_trail'] = $parents;
-          $tree_parameters['active_trail'][] = $mlid;
-        }
-
-        // Cache the tree building parameters using the page-specific cid.
-        $this->cache->set($cid, $tree_parameters, Cache::PERMANENT, array('menu' => $menu_name));
-      }
-
-      // Build the tree using the parameters; the resulting tree will be cached
-      // by $this->doBuildTree()).
-      $this->menuFullTrees[$cid] = $this->buildTree($menu_name, $tree_parameters);
-    }
-
-    return $this->menuFullTrees[$cid];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildPageData($menu_name, $max_depth = NULL, $only_active_trail = FALSE) {
-    $language_interface = $this->languageManager->getCurrentLanguage();
-
-    // Load the request corresponding to the current page.
-    $request = $this->requestStack->getCurrentRequest();
-    $system_path = NULL;
-    if ($route_name = $request->attributes->get(RouteObjectInterface::ROUTE_NAME)) {
-      // @todo https://drupal.org/node/2068471 is adding support so we can tell
-      // if this is called on a 404/403 page.
-      $system_path = $request->attributes->get('_system_path');
-      $page_not_403 = 1;
-    }
-    if (isset($system_path)) {
-      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:' . $system_path . ':' . $language_interface->id . ':' . $page_not_403 . ':' . (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
-      // template_preprocess_page(). So in order to not build a giant menu tree
-      // that needs to be checked for access on all levels, we simply check
-      // whether we have the menu already in cache, or otherwise, build a
-      // minimum tree containing the active trail only.
-      if (!isset($this->menuPageTrees[$cid]) && $only_active_trail) {
-        $cid .= ':trail';
-      }
-
-      if (!isset($this->menuPageTrees[$cid])) {
-        // If the static variable doesn't have the data, check {cache_menu}.
-        $cache = $this->cache->get($cid);
-        if ($cache && $cache->data) {
-          // If the cache entry exists, it contains the parameters for
-          // menu_build_tree().
-          $tree_parameters = $cache->data;
-        }
-        // If the tree data was not in the cache, build $tree_parameters.
-        if (!isset($tree_parameters)) {
-          $tree_parameters = array(
-            'min_depth' => 1,
-            'max_depth' => $max_depth,
-          );
-          $active_trail = $this->getActiveTrailIds($menu_name);
-
-          // If this page is accessible to the current user, build the tree
-          // parameters accordingly.
-          if ($page_not_403) {
-            // The active trail contains more than only array(0 => 0).
-            if (count($active_trail) > 1) {
-              // If we are asked to build links for the active trail only,skip
-              // the entire 'expanded' handling.
-              if ($only_active_trail) {
-                $tree_parameters['only_active_trail'] = TRUE;
-              }
-            }
-            $parents = $active_trail;
-
-            $expanded = $this->state->get('menu_expanded');
-            // Check whether the current menu has any links set to be expanded.
-            if (!$only_active_trail && $expanded && in_array($menu_name, $expanded)) {
-              // Collect all the links set to be expanded, and then add all of
-              // their children to the list as well.
-              do {
-                $query = $this->queryFactory->get('menu_link')
-                  ->condition('menu_name', $menu_name)
-                  ->condition('expanded', 1)
-                  ->condition('has_children', 1)
-                  ->condition('plid', $parents, 'IN')
-                  ->condition('mlid', $parents, 'NOT IN');
-                $result = $query->execute();
-                $parents += $result;
-              } while (!empty($result));
-            }
-            $tree_parameters['expanded'] = $parents;
-            $tree_parameters['active_trail'] = $active_trail;
-          }
-          // If access is denied, we only show top-level links in menus.
-          else {
-            $tree_parameters['expanded'] = $active_trail;
-            $tree_parameters['active_trail'] = $active_trail;
-          }
-          // Cache the tree building parameters using the page-specific cid.
-          $this->cache->set($cid, $tree_parameters, Cache::PERMANENT, array('menu' => $menu_name));
-        }
-
-        // Build the tree using the parameters; the resulting tree will be
-        // cached by $tihs->buildTree().
-        $this->menuPageTrees[$cid] = $this->buildTree($menu_name, $tree_parameters);
-      }
-      return $this->menuPageTrees[$cid];
-    }
-
-    return array();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getActiveTrailIds($menu_name) {
-    // Parent mlids; used both as key and value to ensure uniqueness.
-    // We always want all the top-level links with plid == 0.
-    $active_trail = array(0 => 0);
-
-    $request = $this->requestStack->getCurrentRequest();
-
-    if ($route_name = $request->attributes->get(RouteObjectInterface::ROUTE_NAME)) {
-      // @todo https://drupal.org/node/2068471 is adding support so we can tell
-      // if this is called on a 404/403 page.
-      // Check if the active trail has been overridden for this menu tree.
-      $active_path = $this->getPath($menu_name);
-      // 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 = $this->menuLinkGetPreferred($menu_name, $active_path)) {
-        if ($active_link['menu_name'] == $menu_name) {
-          // Use all the coordinates, except the last one because
-          // there can be no child beyond the last column.
-          for ($i = 1; $i < MENU_MAX_DEPTH; $i++) {
-            if ($active_link['p' . $i]) {
-              $active_trail[$active_link['p' . $i]] = $active_link['p' . $i];
-            }
-          }
-        }
-      }
-    }
-    return $active_trail;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setPath($menu_name, $path = NULL) {
-    if (isset($path)) {
-      $this->trailPaths[$menu_name] = $path;
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPath($menu_name) {
-    return isset($this->trailPaths[$menu_name]) ? $this->trailPaths[$menu_name] : NULL;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function renderMenu($menu_name) {
-
-    if (!isset($this->menuOutput[$menu_name])) {
-      $tree = $this->buildPageData($menu_name);
-      $this->menuOutput[$menu_name] = $this->renderTree($tree);
-    }
-    return $this->menuOutput[$menu_name];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function renderTree($tree) {
-    $build = array();
-    $items = array();
-    $menu_name = $tree ? end($tree)['link']['menu_name'] : '';
-
-    // Pull out just the menu links we are going to render so that we
-    // get an accurate count for the first/last classes.
-    foreach ($tree as $data) {
-      if ($data['link']['access'] && !$data['link']['hidden']) {
-        $items[] = $data;
-      }
-    }
-
-    foreach ($items as $data) {
-      $class = array();
-      // Set a class for the <li>-tag. Since $data['below'] may contain local
-      // tasks, only set 'expanded' class if the link also has children within
-      // the current menu.
-      if ($data['link']['has_children'] && $data['below']) {
-        $class[] = 'expanded';
-      }
-      elseif ($data['link']['has_children']) {
-        $class[] = 'collapsed';
-      }
-      else {
-        $class[] = 'leaf';
-      }
-      // Set a class if the link is in the active trail.
-      if ($data['link']['in_active_trail']) {
-        $class[] = 'active-trail';
-        $data['link']['localized_options']['attributes']['class'][] = 'active-trail';
-      }
-
-      // Allow menu-specific theme overrides.
-      $element['#theme'] = 'menu_link__' . strtr($data['link']['menu_name'], '-', '_');
-      $element['#attributes']['class'] = $class;
-      $element['#title'] = $data['link']['title'];
-      // @todo Use route name and parameters to generate the link path, unless
-      //    it is external.
-      $element['#href'] = $data['link']['link_path'];
-      $element['#localized_options'] = !empty($data['link']['localized_options']) ? $data['link']['localized_options'] : array();
-      $element['#below'] = $data['below'] ? $this->renderTree($data['below']) : $data['below'];
-      $element['#original_link'] = $data['link'];
-      // Index using the link's unique mlid.
-      $build[$data['link']['mlid']] = $element;
-    }
-    if ($build) {
-      // Make sure drupal_render() does not re-order the links.
-      $build['#sorted'] = TRUE;
-      // Add the theme wrapper for outer markup.
-      // Allow menu-specific theme overrides.
-      $build['#theme_wrappers'][] = 'menu_tree__' . strtr($menu_name, '-', '_');
-      // Set cache tag.
-      $menu_name = $data['link']['menu_name'];
-      $build['#cache']['tags']['menu'][$menu_name] = $menu_name;
-    }
-
-    return $build;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildTree($menu_name, array $parameters = array()) {
-    // Build the menu tree.
-    $tree = $this->doBuildTree($menu_name, $parameters);
-    // Check access for the current user to each item in the tree.
-    $this->checkAccess($tree);
-    return $tree;
-  }
-
-  /**
-   * Builds a menu tree.
-   *
-   * This function may be used build the data for a menu tree only, for example
-   * to further massage the data manually before further processing happens.
-   * MenuTree::checkAccess() needs to be invoked afterwards.
-   *
-   * @param string $menu_name
-   *   The name of the menu.
-   * @param array $parameters
-   *   The parameters passed into static::buildTree()
-   *
-   * @see static::buildTree()
-   */
-  protected function doBuildTree($menu_name, array $parameters = array()) {
-    $language_interface = $this->languageManager->getCurrentLanguage();
-
-    // Build the cache id; sort parents to prevent duplicate storage and remove
-    // default parameter values.
-    if (isset($parameters['expanded'])) {
-      sort($parameters['expanded']);
-    }
-    $tree_cid = 'links:' . $menu_name . ':tree-data:' . $language_interface->id . ':' . hash('sha256', serialize($parameters));
-
-    // If we do not have this tree in the static cache, check {cache_menu}.
-    if (!isset($this->menuTree[$tree_cid])) {
-      $cache = $this->cache->get($tree_cid);
-      if ($cache && $cache->data) {
-        $this->menuTree[$tree_cid] = $cache->data;
-      }
-    }
-
-    if (!isset($this->menuTree[$tree_cid])) {
-      $query = $this->queryFactory->get('menu_link');
-      for ($i = 1; $i <= MENU_MAX_DEPTH; $i++) {
-        $query->sort('p' . $i, 'ASC');
-      }
-      $query->condition('menu_name', $menu_name);
-      if (!empty($parameters['expanded'])) {
-        $query->condition('plid', $parameters['expanded'], 'IN');
-      }
-      elseif (!empty($parameters['only_active_trail'])) {
-        $query->condition('mlid', $parameters['active_trail'], 'IN');
-      }
-      $min_depth = (isset($parameters['min_depth']) ? $parameters['min_depth'] : 1);
-      if ($min_depth != 1) {
-        $query->condition('depth', $min_depth, '>=');
-      }
-      if (isset($parameters['max_depth'])) {
-        $query->condition('depth', $parameters['max_depth'], '<=');
-      }
-      // Add custom query conditions, if any were passed.
-      if (isset($parameters['conditions'])) {
-        foreach ($parameters['conditions'] as $column => $value) {
-          $query->condition($column, $value);
-        }
-      }
-
-      // Build an ordered array of links using the query result object.
-      $links = array();
-      if ($result = $query->execute()) {
-        $links = $this->menuLinkStorage->loadMultiple($result);
-      }
-      $active_trail = (isset($parameters['active_trail']) ? $parameters['active_trail'] : array());
-      $tree = $this->doBuildTreeData($links, $active_trail, $min_depth);
-
-      // Cache the data, if it is not already in the cache.
-      $this->cache->set($tree_cid, $tree, Cache::PERMANENT, array('menu' => $menu_name));
-      $this->menuTree[$tree_cid] = $tree;
-    }
-
-    return $this->menuTree[$tree_cid];
-  }
-
-  /**
-   * Sorts the menu tree and recursively checks access for each item.
-   *
-   * @param array $tree
-   *   The menu tree you wish to operate on.
-   */
-  protected function checkAccess(&$tree) {
-    $new_tree = array();
-    foreach ($tree as $key => $v) {
-      $item = &$tree[$key]['link'];
-      $this->menuLinkTranslate($item);
-      if ($item['access'] || ($item['in_active_trail'] && strpos($item['href'], '%') !== FALSE)) {
-        if ($tree[$key]['below']) {
-          $this->checkAccess($tree[$key]['below']);
-        }
-        // The weights are made a uniform 5 digits by adding 50000 as an offset.
-        // After _menu_link_translate(), $item['title'] has the localized link
-        // title. Adding the mlid to the end of the index insures that it is
-        // unique.
-        $new_tree[(50000 + $item['weight']) . ' ' . $item['title'] . ' ' . $item['mlid']] = $tree[$key];
-      }
-    }
-    // Sort siblings in the tree based on the weights and localized titles.
-    ksort($new_tree);
-    $tree = $new_tree;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildTreeData(array $links, array $parents = array(), $depth = 1) {
-    $tree = $this->doBuildTreeData($links, $parents, $depth);
-    $this->checkAccess($tree);
-    return $tree;
-  }
-
-  /**
-   * Prepares the data for calling $this->treeDataRecursive().
-   */
-  protected function doBuildTreeData(array $links, array $parents = array(), $depth = 1) {
-    // Reverse the array so we can use the more efficient array_pop() function.
-    $links = array_reverse($links);
-    return $this->treeDataRecursive($links, $parents, $depth);
-  }
-
-  /**
-   * Builds the data representing a menu tree.
-   *
-   * The function is a bit complex because the rendering of a link depends on
-   * the next menu link.
-   *
-   * @param array $links
-   *   A flat array of menu links that are part of the menu. Each array element
-   *   is an associative array of information about the menu link, containing
-   *   the fields from the {menu_links} table, and optionally additional
-   *   information from the {menu_router} table, if the menu item appears in
-   *   both tables. This array must be ordered depth-first.
-   *   See _menu_build_tree() for a sample query.
-   * @param array $parents
-   *   An array of the menu link ID values that are in the path from the current
-   *   page to the root of the menu tree.
-   * @param int $depth
-   *   The minimum depth to include in the returned menu tree.
-   *
-   * @return array
-   */
-  protected function treeDataRecursive(&$links, $parents, $depth) {
-    $tree = array();
-    while ($item = array_pop($links)) {
-      // We need to determine if we're on the path to root so we can later build
-      // the correct active trail.
-      $item['in_active_trail'] = in_array($item['mlid'], $parents);
-      // Add the current link to the tree.
-      $tree[$item['mlid']] = array(
-        'link' => $item,
-        'below' => array(),
-      );
-      // Look ahead to the next link, but leave it on the array so it's
-      // available to other recursive function calls if we return or build a
-      // sub-tree.
-      $next = end($links);
-      // Check whether the next link is the first in a new sub-tree.
-      if ($next && $next['depth'] > $depth) {
-        // Recursively call doBuildTreeData to build the sub-tree.
-        $tree[$item['mlid']]['below'] = $this->treeDataRecursive($links, $parents, $next['depth']);
-        // Fetch next link after filling the sub-tree.
-        $next = end($links);
-      }
-      // Determine if we should exit the loop and return.
-      if (!$next || $next['depth'] < $depth) {
-        break;
-      }
-    }
-    return $tree;
-  }
-
-  /**
-   * Wraps menu_link_get_preferred().
-   */
-  protected function menuLinkGetPreferred($menu_name, $active_path) {
-    return menu_link_get_preferred($active_path, $menu_name);
-  }
-
-  /**
-   * Wraps _menu_link_translate().
-   */
-  protected function menuLinkTranslate(&$item) {
-    _menu_link_translate($item);
-  }
-
-}
diff --git a/core/modules/menu_link/src/MenuTreeInterface.php b/core/modules/menu_link/src/MenuTreeInterface.php
deleted file mode 100644
index 418f602570c0..000000000000
--- a/core/modules/menu_link/src/MenuTreeInterface.php
+++ /dev/null
@@ -1,182 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\menu_link\MenuTreeInterface.
- */
-
-namespace Drupal\menu_link;
-
-/**
- * Defines an interface for trees out of menu links.
- */
-interface MenuTreeInterface {
-
-  /**
-   * Returns a rendered menu tree.
-   *
-   * The menu item's LI element is given one of the following classes:
-   * - expanded: The menu item is showing its submenu.
-   * - collapsed: The menu item has a submenu which is not shown.
-   * - leaf: The menu item has no submenu.
-   *
-   * @param array $tree
-   *   A data structure representing the tree as returned from menu_tree_data.
-   *
-   * @return array
-   *   A structured array to be rendered by drupal_render().
-   */
-  public function renderTree($tree);
-
-  /**
-   * Sets the path for determining the active trail of the specified menu tree.
-   *
-   * This path will also affect the breadcrumbs under some circumstances.
-   * Breadcrumbs are built using the preferred link returned by
-   * menu_link_get_preferred(). If the preferred link is inside one of the menus
-   * specified in calls to static::setPath(), the preferred link will be
-   * overridden by the corresponding path returned by static::getPath().
-   *
-   * @param string $menu_name
-   *   The name of the affected menu tree.
-   * @param string $path
-   *   The path to use when finding the active trail.
-   */
-  public function setPath($menu_name, $path = NULL);
-
-  /**
-   * Gets the path for determining the active trail of the specified menu tree.
-   *
-   * @param string $menu_name
-   *   The menu name of the requested tree.
-   *
-   * @return string
-   *   A string containing the path. If no path has been specified with
-   *   static::setPath(), NULL is returned.
-   */
-  public function getPath($menu_name);
-
-  /**
-   * Gets the active trail IDs of the specified menu tree.
-   *
-   * @param string $menu_name
-   *   The menu name of the requested tree.
-   *
-   * @return array
-   *   An array containing the active trail: a list of mlids.
-   */
-  public function getActiveTrailIds($menu_name);
-
-  /**
-   * Sorts and returns the built data representing a menu tree.
-   *
-   * @param array $links
-   *   A flat array of menu links that are part of the menu. Each array element
-   *   is an associative array of information about the menu link, containing
-   *   the fields from the {menu_links} table, and optionally additional
-   *   information from the {menu_router} table, if the menu item appears in
-   *   both tables. This array must be ordered depth-first.
-   *   See _menu_build_tree() for a sample query.
-   * @param array $parents
-   *   An array of the menu link ID values that are in the path from the current
-   *   page to the root of the menu tree.
-   * @param int $depth
-   *   The minimum depth to include in the returned menu tree.
-   *
-   * @return array
-   *   An array of menu links in the form of a tree. Each item in the tree is an
-   *   associative array containing:
-   *   - link: The menu link item from $links, with additional element
-   *     'in_active_trail' (TRUE if the link ID was in $parents).
-   *   - below: An array containing the sub-tree of this item, where each
-   *     element is a tree item array with 'link' and 'below' elements. This
-   *     array will be empty if the menu item has no items in its sub-tree
-   *     having a depth greater than or equal to $depth.
-   */
-  public function buildTreeData(array $links, array $parents = array(), $depth = 1);
-
-  /**
-   * Gets the data structure for a named menu tree, based on the current page.
-   *
-   * The tree order is maintained by storing each parent in an individual
-   * field, see http://drupal.org/node/141866 for more.
-   *
-   * @param string $menu_name
-   *   The named menu links to return.
-   * @param int $max_depth
-   *   (optional) The maximum depth of links to retrieve.
-   * @param bool $only_active_trail
-   *   (optional) Whether to only return the links in the active trail (TRUE)
-   *   instead of all links on every level of the menu link tree (FALSE).
-   *   Defaults to FALSE.
-   *
-   * @return array
-   *   An array of menu links, in the order they should be rendered. The array
-   *   is a list of associative arrays -- these have two keys, link and below.
-   *   link is a menu item, ready for theming as a link. Below represents the
-   *   submenu below the link if there is one, and it is a subtree that has the
-   *   same structure described for the top-level array.
-   */
-  public function buildPageData($menu_name, $max_depth = NULL, $only_active_trail = FALSE);
-
-  /**
-   * Gets the data structure representing a named menu tree.
-   *
-   * Since this can be the full tree including hidden items, the data returned
-   * may be used for generating an an admin interface or a select.
-   *
-   * @param string $menu_name
-   *   The named menu links to return
-   * @param array $link
-   *   A fully loaded menu link, or NULL. If a link is supplied, only the
-   *   path to root will be included in the returned tree - as if this link
-   *   represented the current page in a visible menu.
-   * @param int $max_depth
-   *   Optional maximum depth of links to retrieve. Typically useful if only one
-   *   or two levels of a sub tree are needed in conjunction with a non-NULL
-   *   $link, in which case $max_depth should be greater than $link['depth'].
-   *
-   * @return array
-   *   An tree of menu links in an array, in the order they should be rendered.
-   */
-  public function buildAllData($menu_name, $link = NULL, $max_depth = NULL);
-
-  /**
-   * Renders a menu tree based on the current path.
-   *
-   * @param string $menu_name
-   *   The name of the menu.
-   *
-   * @return array
-   *   A structured array representing the specified menu on the current page,
-   *   to be rendered by drupal_render().
-   */
-  public function renderMenu($menu_name);
-
-  /**
-   * Builds a menu tree, translates links, and checks access.
-   *
-   * @param string $menu_name
-   *   The name of the menu.
-   * @param array $parameters
-   *   (optional) An associative array of build parameters. Possible keys:
-   *   - expanded: An array of parent link ids to return only menu links that
-   *     are children of one of the plids in this list. If empty, the whole menu
-   *     tree is built, unless 'only_active_trail' is TRUE.
-   *   - active_trail: An array of mlids, representing the coordinates of the
-   *     currently active menu link.
-   *   - only_active_trail: Whether to only return links that are in the active
-   *     trail. This option is ignored, if 'expanded' is non-empty.
-   *   - min_depth: The minimum depth of menu links in the resulting tree.
-   *     Defaults to 1, which is the default to build a whole tree for a menu
-   *     (excluding menu container itself).
-   *   - max_depth: The maximum depth of menu links in the resulting tree.
-   *   - conditions: An associative array of custom database select query
-   *     condition key/value pairs; see _menu_build_tree() for the actual query.
-   *
-   * @return array
-   *   A fully built menu tree.
-   */
-  public function buildTree($menu_name, array $parameters = array());
-
-}
diff --git a/core/modules/menu_link/src/StaticMenuLinks.php b/core/modules/menu_link/src/StaticMenuLinks.php
deleted file mode 100644
index d42c5ffbc5d4..000000000000
--- a/core/modules/menu_link/src/StaticMenuLinks.php
+++ /dev/null
@@ -1,76 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Core\Menu\StaticMenuLinks.
- */
-
-namespace Drupal\menu_link;
-
-use Drupal\Component\Discovery\YamlDiscovery;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-
-/**
- * Provides a service which finds and alters default menu links in yml files.
- */
-class StaticMenuLinks {
-
-  /**
-   * The module handler.
-   *
-   * @var \Drupal\Core\Extension\ModuleHandlerInterface
-   */
-  protected $moduleHandler;
-
-  /**
-   * Constructs a new StaticMenuLinks.
-   *
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The module handler.
-   */
-  public function __construct(ModuleHandlerInterface $module_handler) {
-    $this->moduleHandler = $module_handler;
-  }
-
-  /**
-   * Gets the menu links defined in YAML files.
-   *
-   * @return array
-   *   An array of default menu links.
-   */
-  public function getLinks() {
-    $discovery = $this->getDiscovery();
-    foreach ($discovery->findAll() as $module => $menu_links) {
-      foreach ($menu_links as $machine_name => $menu_link) {
-        $all_links[$machine_name] = $menu_link;
-        $all_links[$machine_name]['machine_name'] = $machine_name;
-        $all_links[$machine_name]['module'] = $module;
-      }
-    }
-
-    $this->moduleHandler->alter('menu_link_defaults', $all_links);
-    foreach ($all_links as $machine_name => $menu_link) {
-      // Set the machine_name to the menu links added dynamically.
-      if (!isset($menu_link['machine_name'])) {
-        $all_links[$machine_name]['machine_name'] = $machine_name;
-      }
-      // Change the key to match the DB column for now.
-      $all_links[$machine_name]['link_title'] = $all_links[$machine_name]['title'];
-      unset($all_links[$machine_name]['title']);
-    }
-
-    return $all_links;
-  }
-
-  /**
-   * Creates a YAML discovery for menu links.
-   *
-   * @return \Drupal\Component\Discovery\YamlDiscovery
-   *   An YAML discovery instance.
-   */
-  protected function getDiscovery() {
-    return new YamlDiscovery('links.menu', $this->moduleHandler->getModuleDirectories());
-  }
-
-}
-
diff --git a/core/modules/menu_link/tests/src/MenuTreeTest.php b/core/modules/menu_link/tests/src/MenuTreeTest.php
deleted file mode 100644
index 747335ad4a61..000000000000
--- a/core/modules/menu_link/tests/src/MenuTreeTest.php
+++ /dev/null
@@ -1,539 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\menu_link\Tests\MenuTreeTest.
- */
-
-namespace Drupal\menu_link\Tests {
-
-use Drupal\Core\Cache\Cache;
-use Drupal\Core\Entity\EntityStorageInterface;
-use Drupal\Core\Language\Language;
-use Drupal\menu_link\MenuTree;
-use Drupal\Tests\UnitTestCase;
-use Symfony\Cmf\Component\Routing\RouteObjectInterface;
-use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\HttpFoundation\RequestStack;
-
-if (!defined('MENU_MAX_DEPTH')) {
-  define('MENU_MAX_DEPTH', 9);
-}
-
-/**
- * @coversDefaultClass \Drupal\menu_link\MenuTree
- * @group menu_link
- */
-class MenuTreeTest extends UnitTestCase {
-
-  /**
-   * The tested menu tree.
-   *
-   * @var \Drupal\menu_link\MenuTree|\Drupal\menu_link\Tests\TestMenuTree
-   */
-  protected $menuTree;
-
-  /**
-   * The mocked database connection.
-   *
-   * @var \Drupal\Core\DatabaseConnection|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $connection;
-
-  /**
-   * The mocked cache backend.
-   *
-   * @var \Drupal\Core\Cache\CacheBackendInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $cacheBackend;
-
-  /**
-   * The mocked language manager.
-   *
-   * @var \Drupal\Core\Language\LanguageManagerInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $languageManager;
-
-  /**
-   * The test request stack.
-   *
-   * @var \Symfony\Component\HttpFoundation\RequestStack.
-   */
-  protected $requestStack;
-
-  /**
-   * The mocked entity manager.
-   *
-   * @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $entityManager;
-
-  /**
-   * The mocked entity query factor.y
-   *
-   * @var  \Drupal\Core\Entity\Query\QueryFactory|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $entityQueryFactory;
-
-  /**
-   * The mocked state.
-   *
-   * @var \Drupal\Core\State\StateInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $state;
-
-  /**
-   * Stores some default values for a menu link.
-   *
-   * @var array
-   */
-  protected $defaultMenuLink = array(
-    'menu_name' => 'main-menu',
-    'mlid' => 1,
-    'title' => 'Example 1',
-    'route_name' => 'example1',
-    'link_path' => 'example1',
-    'access' => 1,
-    'hidden' => FALSE,
-    'has_children' => FALSE,
-    'in_active_trail' => TRUE,
-    'localized_options' => array('attributes' => array('title' => '')),
-    'weight' => 0,
-  );
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    $this->connection = $this->getMockBuilder('Drupal\Core\Database\Connection')
-      ->disableOriginalConstructor()
-      ->getMock();
-    $this->cacheBackend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface');
-    $this->languageManager = $this->getMock('Drupal\Core\Language\LanguageManagerInterface');
-    $this->requestStack = new RequestStack();
-    $this->entityManager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
-    $this->entityQueryFactory = $this->getMockBuilder('Drupal\Core\Entity\Query\QueryFactory')
-      ->disableOriginalConstructor()
-      ->getMock();
-    $this->state = $this->getMock('Drupal\Core\State\StateInterface');
-
-    $this->menuTree = new TestMenuTree($this->connection, $this->cacheBackend, $this->languageManager, $this->requestStack, $this->entityManager, $this->entityQueryFactory, $this->state);
-  }
-
-  /**
-   * Tests active paths.
-   *
-   * @covers ::setPath
-   * @covers ::getPath
-   */
-  public function testActivePaths() {
-    $this->assertNull($this->menuTree->getPath('test_menu1'));
-
-    $this->menuTree->setPath('test_menu1', 'example_path1');
-    $this->assertEquals('example_path1', $this->menuTree->getPath('test_menu1'));
-    $this->assertNull($this->menuTree->getPath('test_menu2'));
-
-    $this->menuTree->setPath('test_menu2', 'example_path2');
-    $this->assertEquals('example_path1', $this->menuTree->getPath('test_menu1'));
-    $this->assertEquals('example_path2', $this->menuTree->getPath('test_menu2'));
-  }
-
-  /**
-   * Tests buildTreeData with a single level.
-   *
-   * @covers ::buildTreeData
-   * @covers ::doBuildTreeData
-   */
-  public function testBuildTreeDataWithSingleLevel() {
-    $items = array();
-    $items[] = array(
-      'mlid' => 1,
-      'depth' => 1,
-      'weight' => 0,
-      'title' => '',
-      'route_name' => 'example1',
-      'access' => TRUE,
-    );
-    $items[] = array(
-      'mlid' => 2,
-      'depth' => 1,
-      'weight' => 0,
-      'title' => '',
-      'route_name' => 'example2',
-      'access' => TRUE,
-    );
-
-    $result = $this->menuTree->buildTreeData($items, array(), 1);
-
-    $this->assertCount(2, $result);
-    $result1 = array_shift($result);
-    $this->assertEquals($items[0] + array('in_active_trail' => FALSE), $result1['link']);
-    $result2 = array_shift($result);
-    $this->assertEquals($items[1] + array('in_active_trail' => FALSE), $result2['link']);
-  }
-
-  /**
-   * Tests buildTreeData with a single level and one item being active.
-   *
-   * @covers ::buildTreeData
-   * @covers ::doBuildTreeData
-   */
-  public function testBuildTreeDataWithSingleLevelAndActiveItem() {
-    $items = array();
-    $items[] = array(
-      'mlid' => 1,
-      'depth' => 1,
-      'weight' => 0,
-      'title' => '',
-      'route_name' => 'example1',
-      'access' => TRUE,
-    );
-    $items[] = array(
-      'mlid' => 2,
-      'depth' => 1,
-      'weight' => 0,
-      'title' => '',
-      'route_name' => 'example2',
-      'access' => TRUE,
-    );
-
-    $result = $this->menuTree->buildTreeData($items, array(1), 1);
-
-    $this->assertCount(2, $result);
-    $result1 = array_shift($result);
-    $this->assertEquals($items[0] + array('in_active_trail' => TRUE), $result1['link']);
-    $result2 = array_shift($result);
-    $this->assertEquals($items[1] + array('in_active_trail' => FALSE), $result2['link']);
-  }
-
-  /**
-   * Tests buildTreeData with a single level and none item being active.
-   *
-   * @covers ::buildTreeData
-   * @covers ::doBuildTreeData
-   */
-  public function testBuildTreeDataWithSingleLevelAndNoActiveItem() {
-    $items = array();
-    $items[] = array(
-      'mlid' => 1,
-      'depth' => 1,
-      'weight' => 0,
-      'title' => '',
-      'route_name' => 'example1',
-      'access' => TRUE,
-    );
-    $items[] = array(
-      'mlid' => 2,
-      'depth' => 1,
-      'weight' => 0,
-      'title' => '',
-      'route_name' => 'example2',
-      'access' => TRUE,
-    );
-
-    $result = $this->menuTree->buildTreeData($items, array(3), 1);
-
-    $this->assertCount(2, $result);
-    $result1 = array_shift($result);
-    $this->assertEquals($items[0] + array('in_active_trail' => FALSE), $result1['link']);
-    $result2 = array_shift($result);
-    $this->assertEquals($items[1] + array('in_active_trail' => FALSE), $result2['link']);
-  }
-
-  /**
-   * Tests buildTreeData with a more complex example.
-   *
-   * @covers ::buildTreeData
-   * @covers ::doBuildTreeData
-   */
-  public function testBuildTreeWithComplexData() {
-    $items = array(
-      1 => array('mlid' => 1, 'depth' => 1, 'route_name' => 'example1', 'access' => TRUE, 'weight' => 0, 'title' => ''),
-      2 => array('mlid' => 2, 'depth' => 1, 'route_name' => 'example2', 'access' => TRUE, 'weight' => 0, 'title' => ''),
-      3 => array('mlid' => 3, 'depth' => 2, 'route_name' => 'example3', 'access' => TRUE, 'weight' => 0, 'title' => ''),
-      4 => array('mlid' => 4, 'depth' => 3, 'route_name' => 'example4', 'access' => TRUE, 'weight' => 0, 'title' => ''),
-      5 => array('mlid' => 5, 'depth' => 1, 'route_name' => 'example5', 'access' => TRUE, 'weight' => 0, 'title' => ''),
-    );
-
-    $tree = $this->menuTree->buildTreeData($items);
-
-    // Validate that parent items #1, #2, and #5 exist on the root level.
-    $this->assertEquals($items[1]['mlid'], $tree['50000  1']['link']['mlid']);
-    $this->assertEquals($items[2]['mlid'], $tree['50000  2']['link']['mlid']);
-    $this->assertEquals($items[5]['mlid'], $tree['50000  5']['link']['mlid']);
-
-    // Validate that child item #4 exists at the correct location in the hierarchy.
-    $this->assertEquals($items[4]['mlid'], $tree['50000  2']['below']['50000  3']['below']['50000  4']['link']['mlid']);
-  }
-
-  /**
-   * Tests getActiveTrailIds().
-   *
-   * @covers ::getActiveTrailIds()
-   */
-  public function testGetActiveTrailIds() {
-    $menu_link = array(
-      'mlid' => 10,
-      'route_name' => 'example1',
-      'p1' => 3,
-      'p2' => 2,
-      'p3' => 1,
-      'p4' => 4,
-      'p5' => 9,
-      'p6' => 5,
-      'p7' => 6,
-      'p8' => 7,
-      'p9' => 8,
-      'menu_name' => 'test_menu'
-    );
-    $this->menuTree->setPreferredMenuLink('test_menu', 'test/path', $menu_link);
-    $request = (new Request());
-    $request->attributes->set(RouteObjectInterface::ROUTE_NAME, 'test_route');
-    $this->requestStack->push($request);
-    $this->menuTree->setPath('test_menu', 'test/path');
-
-    $trail = $this->menuTree->getActiveTrailIds('test_menu');
-    $this->assertEquals(array(0 => 0, 3 => 3, 2 => 2, 1 => 1, 4 => 4, 9 => 9, 5 => 5, 6 => 6, 7 => 7), $trail);
-  }
-
-  /**
-   * Tests getActiveTrailIds() without preferred link.
-   *
-   * @covers ::getActiveTrailIds()
-   */
-  public function testGetActiveTrailIdsWithoutPreferredLink() {
-    $request = (new Request());
-    $request->attributes->set(RouteObjectInterface::ROUTE_NAME, 'test_route');
-    $this->requestStack->push($request);
-    $this->menuTree->setPath('test_menu', 'test/path');
-
-    $trail = $this->menuTree->getActiveTrailIds('test_menu');
-    $this->assertEquals(array(0 => 0), $trail);
-  }
-
-
-  /**
-   * Tests buildTree with simple menu_name and no parameters.
-   */
-  public function testBuildTreeWithoutParameters() {
-    $language = new Language(array('id' => 'en'));
-    $this->languageManager->expects($this->any())
-      ->method('getCurrentLanguage')
-      ->will($this->returnValue($language));
-
-    // Setup query and the query result.
-    $query = $this->getMock('Drupal\Core\Entity\Query\QueryInterface');
-    $this->entityQueryFactory->expects($this->once())
-      ->method('get')
-      ->with('menu_link')
-      ->will($this->returnValue($query));
-    $query->expects($this->once())
-      ->method('condition')
-      ->with('menu_name', 'test_menu');
-    $query->expects($this->once())
-      ->method('execute')
-      ->will($this->returnValue(array(1, 2, 3)));
-
-    $storage = $this->getMock('Drupal\Core\Entity\EntityStorageInterface');
-    $base = array(
-      'access' => TRUE,
-      'weight' => 0,
-      'title' => 'title',
-    );
-    $menu_link = $base + array(
-      'mlid' => 1,
-      'p1' => 3,
-      'p2' => 2,
-      'p3' => 1,
-    );
-    $links[1] = $menu_link;
-    $menu_link = $base + array(
-      'mlid' => 3,
-      'p1' => 3,
-      'depth' => 1,
-    );
-    $links[3] = $menu_link;
-    $menu_link = $base + array(
-      'mlid' => 2,
-      'p1' => 3,
-      'p2' => 2,
-      'depth' => 2,
-    );
-    $links[2] = $menu_link;
-    $storage->expects($this->once())
-      ->method('loadMultiple')
-      ->with(array(1, 2, 3))
-      ->will($this->returnValue($links));
-    $this->menuTree->setStorage($storage);
-
-    // Ensure that static/non static caching works.
-    // First setup no working caching.
-    $this->cacheBackend->expects($this->at(0))
-      ->method('get')
-      ->with('links:test_menu:tree-data:en:35786c7117b4e38d0f169239752ce71158266ae2f6e4aa230fbbb87bd699c0e3')
-      ->will($this->returnValue(FALSE));
-    $this->cacheBackend->expects($this->at(1))
-      ->method('set')
-      ->with('links:test_menu:tree-data:en:35786c7117b4e38d0f169239752ce71158266ae2f6e4aa230fbbb87bd699c0e3', $this->anything(), Cache::PERMANENT, array('menu' => 'test_menu'));
-
-    // Ensure that the static caching triggered.
-    $this->cacheBackend->expects($this->exactly(1))
-      ->method('get');
-
-    $this->menuTree->buildTree('test_menu');
-    $this->menuTree->buildTree('test_menu');
-  }
-
-  /**
-   * Tests the output with a single level.
-   *
-   * @covers ::renderTree
-   */
-  public function testOutputWithSingleLevel() {
-    $tree = array(
-      '1' => array(
-        'link' => array('mlid' => 1) + $this->defaultMenuLink,
-        'below' => array(),
-      ),
-      '2' => array(
-        'link' => array('mlid' => 2) + $this->defaultMenuLink,
-        'below' => array(),
-      ),
-    );
-
-    $output = $this->menuTree->renderTree($tree);
-
-    // Validate that the - in main-menu is changed into an underscore
-    $this->assertEquals($output['1']['#theme'], 'menu_link__main_menu', 'Hyphen is changed to an underscore on menu_link');
-    $this->assertEquals($output['2']['#theme'], 'menu_link__main_menu', 'Hyphen is changed to an underscore on menu_link');
-    $this->assertEquals($output['#theme_wrappers'][0], 'menu_tree__main_menu', 'Hyphen is changed to an underscore on menu_tree wrapper');
-  }
-
-  /**
-   * Tests the output method with a complex example.
-   *
-   * @covers ::renderTree
-   */
-  public function testOutputWithComplexData() {
-    $tree = array(
-      '1'=> array(
-        'link' => array('mlid' => 1, 'has_children' => 1, 'title' => 'Item 1', 'link_path' => 'a') + $this->defaultMenuLink,
-        'below' => array(
-          '2' => array('link' => array('mlid' => 2, 'title' => 'Item 2', 'link_path' => 'a/b') + $this->defaultMenuLink,
-            'below' => array(
-              '3' => array('link' => array('mlid' => 3, 'title' => 'Item 3', 'in_active_trail' => 0, 'link_path' => 'a/b/c') + $this->defaultMenuLink,
-                'below' => array()),
-              '4' => array('link' => array('mlid' => 4, 'title' => 'Item 4', 'in_active_trail' => 0, 'link_path' => 'a/b/d') + $this->defaultMenuLink,
-                'below' => array())
-            )
-          )
-        )
-      ),
-      '5' => array('link' => array('mlid' => 5, 'hidden' => 1, 'title' => 'Item 5', 'link_path' => 'e') + $this->defaultMenuLink, 'below' => array()),
-      '6' => array('link' => array('mlid' => 6, 'title' => 'Item 6', 'in_active_trail' => 0, 'access' => 0, 'link_path' => 'f') + $this->defaultMenuLink, 'below' => array()),
-      '7' => array('link' => array('mlid' => 7, 'title' => 'Item 7', 'in_active_trail' => 0, 'link_path' => 'g') + $this->defaultMenuLink, 'below' => array())
-    );
-
-    $output = $this->menuTree->renderTree($tree);
-
-    // Looking for child items in the data
-    $this->assertEquals( $output['1']['#below']['2']['#href'], 'a/b', 'Checking the href on a child item');
-    $this->assertTrue(in_array('active-trail', $output['1']['#below']['2']['#attributes']['class']), 'Checking the active trail class');
-    // Validate that the hidden and no access items are missing
-    $this->assertFalse(isset($output['5']), 'Hidden item should be missing');
-    $this->assertFalse(isset($output['6']), 'False access should be missing');
-    // Item 7 is after a couple hidden items. Just to make sure that 5 and 6 are
-    // skipped and 7 still included.
-    $this->assertTrue(isset($output['7']), 'Item after hidden items is present');
-  }
-
-  /**
-   * Tests menu tree access check with a single level.
-   *
-   * @covers ::checkAccess
-   */
-  public function testCheckAccessWithSingleLevel() {
-    $items = array(
-      array('mlid' => 1, 'route_name' => 'menu_test_1', 'depth' => 1, 'link_path' => 'menu_test/test_1', 'in_active_trail' => FALSE) + $this->defaultMenuLink,
-      array('mlid' => 2, 'route_name' => 'menu_test_2', 'depth' => 1, 'link_path' => 'menu_test/test_2', 'in_active_trail' => FALSE) + $this->defaultMenuLink,
-    );
-
-    // Register a menuLinkTranslate to mock the access.
-    $this->menuTree->menuLinkTranslateCallable = function(&$item) {
-      $item['access'] = $item['mlid'] == 1;
-    };
-
-    // Build the menu tree and check access for all of the items.
-    $tree = $this->menuTree->buildTreeData($items);
-
-    $this->assertCount(1, $tree);
-    $item = reset($tree);
-    $this->assertEquals($items[0], $item['link']);
-  }
-
-}
-
-class TestMenuTree extends MenuTree {
-
-  /**
-   * An alternative callable used for menuLinkTranslate.
-   * @var callable
-   */
-  public $menuLinkTranslateCallable;
-
-  /**
-   * Stores the preferred menu link per menu and path.
-   *
-   * @var array
-   */
-  protected $preferredMenuLink;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function menuLinkTranslate(&$item) {
-    if (isset($this->menuLinkTranslateCallable)) {
-      call_user_func_array($this->menuLinkTranslateCallable, array(&$item));
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function menuLinkGetPreferred($menu_name, $active_path) {
-    return isset($this->preferredMenuLink[$menu_name][$active_path]) ? $this->preferredMenuLink[$menu_name][$active_path] : NULL;
-  }
-
-  /**
-   * Set the storage.
-   *
-   * @param \Drupal\Core\Entity\EntityStorageInterface $storage
-   *   The menu link storage.
-   */
-  public function setStorage(EntityStorageInterface $storage) {
-    $this->menuLinkStorage = $storage;
-  }
-
-  /**
-   * Sets the preferred menu link.
-   *
-   * @param string $menu_name
-   *   The menu name.
-   * @param string $active_path
-   *   The active path.
-   * @param array $menu_link
-   *   The preferred menu link.
-   */
-  public function setPreferredMenuLink($menu_name, $active_path, $menu_link) {
-    $this->preferredMenuLink[$menu_name][$active_path] = $menu_link;
-  }
-
-}
-
-}
-
-namespace {
-  if (!defined('MENU_MAX_DEPTH')) {
-    define('MENU_MAX_DEPTH', 9);
-  }
-}
diff --git a/core/modules/views/src/Plugin/views/sort/MenuHierarchy.php b/core/modules/views/src/Plugin/views/sort/MenuHierarchy.php
deleted file mode 100644
index 2d8a5fc48f9d..000000000000
--- a/core/modules/views/src/Plugin/views/sort/MenuHierarchy.php
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of Drupal\views\Plugin\views\sort\MenuHierarchy.
- */
-
-namespace Drupal\views\Plugin\views\sort;
-
-use Drupal\views\Views;
-
-/**
- * Sort in menu hierarchy order.
- *
- * Given a field name of 'p' this produces an ORDER BY on p1, p2, ..., p9;
- * and optionally injects multiple joins to {menu_links} to sort by weight
- * and title as well.
- *
- * This is only really useful for the {menu_links} table.
- *
- * @ViewsSort("menu_hierarchy")
- */
-class MenuHierarchy extends SortPluginBase {
-
-  protected function defineOptions() {
-    $options = parent::defineOptions();
-    $options['sort_within_level'] = array('default' => FALSE);
-    return $options;
-  }
-
-  public function buildOptionsForm(&$form, &$form_state) {
-    parent::buildOptionsForm($form, $form_state);
-    $form['sort_within_level'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Sort within each hierarchy level'),
-      '#description' => t('Enable this to sort the items within each level of the hierarchy by weight and title.  Warning: this may produce a slow query.'),
-      '#default_value' => $this->options['sort_within_level'],
-    );
-  }
-
-  public function query() {
-    $this->ensureMyTable();
-    $max_depth = isset($this->definition['max depth']) ? $this->definition['max depth'] : MENU_MAX_DEPTH;
-    for ($i = 1; $i <= $max_depth; ++$i) {
-      if ($this->options['sort_within_level']) {
-        $definition = array(
-          'table' => 'menu_links',
-          'field' => 'mlid',
-          'left_table' => $this->tableAlias,
-          'left_field' => $this->field . $i
-        );
-        $join = Views::pluginManager('join')->createInstance('standard', $definition);
-
-        $menu_links = $this->query->addTable('menu_links', NULL, $join);
-        $this->query->addOrderBy($menu_links, 'weight', $this->options['order']);
-        $this->query->addOrderBy($menu_links, 'link_title', $this->options['order']);
-      }
-
-      // We need this even when also sorting by weight and title, to make sure
-      // that children of two parents with the same weight and title are
-      // correctly separated.
-      $this->query->addOrderBy($this->tableAlias, $this->field . $i, $this->options['order']);
-    }
-  }
-
-}
-- 
GitLab