diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index e6810b8..c7f81d0 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -1623,6 +1623,9 @@ function theme_menu_link(array $variables) {
  */
 function theme_menu_local_task($variables) {
   $link = $variables['element']['#link'];
+  $link += array(
+    'localized_options' => array(),
+  );
   $link_text = $link['title'];
 
   if (!empty($variables['element']['#active'])) {
@@ -1855,21 +1858,20 @@ function menu_navigation_links($menu_name, $level = 0) {
  *
  * @return
  *   An array containing
- *   - tabs: Local tasks for the requested level:
- *     - count: The number of local tasks.
- *     - output: The themed output of local tasks.
- *   - actions: Action links for the requested level:
- *     - count: The number of action links.
- *     - output: The themed output of action links.
+ *   - tabs: Local tasks for the requested level.
+ *   - actions: Action links for the requested level.
  *   - root_path: The router path for the current page. If the current page is
  *     a default local task, then this corresponds to the parent tab.
+ *
+ * @see hook_menu_local_tasks()
+ * @see hook_menu_local_tasks_alter()
  */
 function menu_local_tasks($level = 0) {
   $data = &drupal_static(__FUNCTION__);
   $root_path = &drupal_static(__FUNCTION__ . ':root_path', '');
   $empty = array(
-    'tabs' => array('count' => 0, 'output' => array()),
-    'actions' => array('count' => 0, 'output' => array()),
+    'tabs' => array(),
+    'actions' => array(),
     'root_path' => &$root_path,
   );
 
@@ -1921,8 +1923,7 @@ function menu_local_tasks($level = 0) {
     // Tab parenting may skip levels, so the number of parts in the path may not
     // equal the depth. Thus we use the $depth counter (offset by 1000 for ksort).
     $depth = 1001;
-    $actions['count'] = 0;
-    $actions['output'] = array();
+    $actions = array();
     while (isset($children[$path])) {
       $tabs_current = array();
       $actions_current = array();
@@ -1955,10 +1956,11 @@ function menu_local_tasks($level = 0) {
             if ($link['href'] != current_path()) {
               $link['localized_options']['attributes']['class'][] = 'active';
             }
-            $tabs_current[] = array(
+            $tabs_current[$link['href']] = array(
               '#theme' => 'menu_local_task',
               '#link' => $link,
               '#active' => TRUE,
+              '#weight' => isset($link['weight']) ? $link['weight'] : NULL,
             );
             $next_path = $item['path'];
             $tab_count++;
@@ -1968,17 +1970,19 @@ function menu_local_tasks($level = 0) {
             // MENU_IS_LOCAL_ACTION before checking.
             if (($item['type'] & MENU_IS_LOCAL_ACTION) == MENU_IS_LOCAL_ACTION) {
               // The item is an action, display it as such.
-              $actions_current[] = array(
+              $actions_current[$link['href']] = array(
                 '#theme' => 'menu_local_action',
                 '#link' => $link,
+                '#weight' => isset($link['weight']) ? $link['weight'] : NULL,
               );
               $action_count++;
             }
             else {
               // Otherwise, it's a normal tab.
-              $tabs_current[] = array(
+              $tabs_current[$link['href']] = array(
                 '#theme' => 'menu_local_task',
                 '#link' => $link,
+                '#weight' => isset($link['weight']) ? $link['weight'] : NULL,
               );
               $tab_count++;
             }
@@ -1986,10 +1990,8 @@ function menu_local_tasks($level = 0) {
         }
       }
       $path = $next_path;
-      $tabs[$depth]['count'] = $tab_count;
-      $tabs[$depth]['output'] = $tabs_current;
-      $actions['count'] += $action_count;
-      $actions['output'] = array_merge($actions['output'], $actions_current);
+      $tabs[$depth] = $tabs_current;
+      $actions = array_merge($actions, $actions_current);
       $depth++;
     }
     $data['actions'] = $actions;
@@ -2031,10 +2033,11 @@ function menu_local_tasks($level = 0) {
             if ($link['href'] != current_path()) {
               $link['localized_options']['attributes']['class'][] = 'active';
             }
-            $tabs_current[] = array(
+            $tabs_current[$link['href']] = array(
               '#theme' => 'menu_local_task',
               '#link' => $link,
               '#active' => TRUE,
+              '#weight' => isset($link['weight']) ? $link['weight'] : NULL,
             );
             $next_path = $item['tab_parent'];
             if (isset($tasks[$next_path])) {
@@ -2042,17 +2045,17 @@ function menu_local_tasks($level = 0) {
             }
           }
           else {
-            $tabs_current[] = array(
+            $tabs_current[$link['href']] = array(
               '#theme' => 'menu_local_task',
               '#link' => $link,
+              '#weight' => isset($link['weight']) ? $link['weight'] : NULL,
             );
           }
         }
       }
       $path = $next_path;
       $parent = $next_parent;
-      $tabs[$depth]['count'] = $count;
-      $tabs[$depth]['output'] = $tabs_current;
+      $tabs[$depth] = $tabs_current;
       $depth--;
     }
     // Sort by depth.
@@ -2061,7 +2064,12 @@ function menu_local_tasks($level = 0) {
     $tabs = array_values($tabs);
     $data['tabs'] = $tabs;
 
-    // Allow modules to alter local tasks or dynamically append further tasks.
+    // Allow modules to dynamically add further tasks.
+    foreach (module_implements('menu_local_tasks') as $module) {
+      $function = $module . '_menu_local_tasks';
+      $function($data, $router_item, $root_path);
+    }
+    // Allow modules to alter local tasks.
     drupal_alter('menu_local_tasks', $data, $router_item, $root_path);
   }
 
@@ -2072,9 +2080,7 @@ function menu_local_tasks($level = 0) {
       'root_path' => $root_path,
     );
   }
-  // @todo If there are no tabs, then there still can be actions; for example,
-  //   when added via hook_menu_local_tasks_alter().
-  elseif (!empty($data['actions']['output'])) {
+  elseif (!empty($data['actions'])) {
     return array('actions' => $data['actions']) + $empty;
   }
   return $empty;
@@ -2187,7 +2193,7 @@ function menu_contextual_links($module, $parent_path, $args) {
 function menu_primary_local_tasks() {
   $links = menu_local_tasks(0);
   // Do not display single tabs.
-  return ($links['tabs']['count'] > 1 ? $links['tabs']['output'] : '');
+  return count(element_get_visible_children($links['tabs'])) > 1 ? $links['tabs'] : '';
 }
 
 /**
@@ -2196,7 +2202,7 @@ function menu_primary_local_tasks() {
 function menu_secondary_local_tasks() {
   $links = menu_local_tasks(1);
   // Do not display single tabs.
-  return ($links['tabs']['count'] > 1 ? $links['tabs']['output'] : '');
+  return count(element_get_visible_children($links['tabs'])) > 1 ? $links['tabs'] : '';
 }
 
 /**
@@ -2204,7 +2210,7 @@ function menu_secondary_local_tasks() {
  */
 function menu_local_actions() {
   $links = menu_local_tasks();
-  return $links['actions']['output'];
+  return $links['actions'];
 }
 
 /**
@@ -2219,11 +2225,12 @@ function menu_tab_root_path() {
  * Returns a renderable element for the primary and secondary tabs.
  */
 function menu_local_tabs() {
-  return array(
+  $build = array(
     '#theme' => 'menu_local_tasks',
     '#primary' => menu_primary_local_tasks(),
     '#secondary' => menu_secondary_local_tasks(),
   );
+  return !empty($build['#primary']) || !empty($build['#secondary']) ? $build : array();
 }
 
 /**
@@ -3566,7 +3573,6 @@ function _menu_router_build($callbacks) {
     $item['to_arg_functions'] = empty($to_arg_functions) ? '' : serialize($to_arg_functions);
     $item += array(
       'title' => '',
-      'weight' => 0,
       'type' => MENU_NORMAL_ITEM,
       'module' => '',
       '_number_parts' => $number_parts,
@@ -3574,6 +3580,9 @@ function _menu_router_build($callbacks) {
       '_fit' => $fit,
     );
     $item += array(
+      // Default MENU_DEFAULT_LOCAL_TASKs to a weight of -10, so they appear as
+      // first tab by default.
+      'weight' => ($item['type'] & MENU_DEFAULT_LOCAL_TASK) == MENU_DEFAULT_LOCAL_TASK ? -10 : 0,
       '_visible' => (bool) ($item['type'] & MENU_VISIBLE_IN_BREADCRUMB),
       '_tab' => (bool) ($item['type'] & MENU_IS_LOCAL_TASK),
     );
diff --git a/core/modules/action/action.module b/core/modules/action/action.module
index 6ebf1fb..6396caf 100644
--- a/core/modules/action/action.module
+++ b/core/modules/action/action.module
@@ -69,7 +69,6 @@ function action_menu() {
     'description' => 'Manage the actions defined for your site.',
     'page callback' => 'action_admin_manage',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -2,
     'file' => 'action.admin.inc',
   );
   $items['admin/config/system/actions/configure'] = array(
diff --git a/core/modules/aggregator/aggregator.module b/core/modules/aggregator/aggregator.module
index 35cdc19..e250509 100644
--- a/core/modules/aggregator/aggregator.module
+++ b/core/modules/aggregator/aggregator.module
@@ -146,7 +146,6 @@ function aggregator_menu() {
   $items['admin/config/services/aggregator/list'] = array(
     'title' => 'List',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
   $items['admin/config/services/aggregator/settings'] = array(
     'title' => 'Settings',
@@ -155,6 +154,7 @@ function aggregator_menu() {
     'page arguments' => array('aggregator_admin_form'),
     'access arguments' => array('administer news feeds'),
     'type' => MENU_LOCAL_TASK,
+    'weight' => 100,
     'file' => 'aggregator.admin.inc',
   );
   $items['aggregator'] = array(
@@ -201,7 +201,6 @@ function aggregator_menu() {
   $items['aggregator/categories/%aggregator_category/view'] = array(
     'title' => 'View',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
   $items['aggregator/categories/%aggregator_category/categorize'] = array(
     'title' => 'Categorize',
@@ -217,7 +216,7 @@ function aggregator_menu() {
     'page arguments' => array('aggregator_form_category', 2),
     'access arguments' => array('administer news feeds'),
     'type' => MENU_LOCAL_TASK,
-    'weight' => 1,
+    'weight' => 10,
     'file' => 'aggregator.admin.inc',
   );
   $items['aggregator/sources/%aggregator_feed'] = array(
@@ -229,7 +228,6 @@ function aggregator_menu() {
   $items['aggregator/sources/%aggregator_feed/view'] = array(
     'title' => 'View',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
   $items['aggregator/sources/%aggregator_feed/categorize'] = array(
     'title' => 'Categorize',
@@ -245,7 +243,7 @@ function aggregator_menu() {
     'page arguments' => array('aggregator_form_feed', 2),
     'access arguments' => array('administer news feeds'),
     'type' => MENU_LOCAL_TASK,
-    'weight' => 1,
+    'weight' => 10,
     'file' => 'aggregator.admin.inc',
   );
   $items['admin/config/services/aggregator/edit/feed/%aggregator_feed'] = array(
diff --git a/core/modules/block/block.module b/core/modules/block/block.module
index d9155c3..ea3b5c4 100644
--- a/core/modules/block/block.module
+++ b/core/modules/block/block.module
@@ -153,7 +153,6 @@ function block_menu() {
         'title' => check_plain($theme->info['name']),
         'page arguments' => array($key),
         'type' => $key == $default_theme ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
-        'weight' => $key == $default_theme ? -10 : 0,
         'access callback' => '_block_themes_access',
         'access arguments' => array($key),
         'file' => 'block.admin.inc',
diff --git a/core/modules/book/book.module b/core/modules/book/book.module
index 99edfc5..3e5bf7d 100644
--- a/core/modules/book/book.module
+++ b/core/modules/book/book.module
@@ -147,7 +147,7 @@ function book_menu() {
     'page arguments' => array('book_admin_settings'),
     'access arguments' => array('administer site configuration'),
     'type' => MENU_LOCAL_TASK,
-    'weight' => 8,
+    'weight' => 100,
     'file' => 'book.admin.inc',
   );
   $items['admin/content/book/%node'] = array(
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 7ebef3e..df19952 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -222,7 +222,6 @@ function comment_menu() {
   $items['admin/content/comment/new'] = array(
     'title' => 'Published comments',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
   $items['admin/content/comment/approval'] = array(
     'title' => 'Unapproved comments',
@@ -240,7 +239,6 @@ function comment_menu() {
   $items['comment/%/view'] = array(
     'title' => 'View comment',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
   // Every other comment path uses %, but this one loads the comment directly,
   // so we don't end up loading it twice (in the page and access callback).
@@ -251,7 +249,6 @@ function comment_menu() {
     'access callback' => 'comment_access',
     'access arguments' => array('edit', 1),
     'type' => MENU_LOCAL_TASK,
-    'weight' => 0,
   );
   $items['comment/%/approve'] = array(
     'title' => 'Approve',
@@ -259,7 +256,7 @@ function comment_menu() {
     'page arguments' => array(1),
     'access arguments' => array('administer comments'),
     'file' => 'comment.pages.inc',
-    'weight' => 1,
+    'weight' => 10,
   );
   $items['comment/%/delete'] = array(
     'title' => 'Delete',
@@ -268,7 +265,7 @@ function comment_menu() {
     'access arguments' => array('administer comments'),
     'type' => MENU_LOCAL_TASK,
     'file' => 'comment.admin.inc',
-    'weight' => 2,
+    'weight' => 20,
   );
   $items['comment/reply/%node'] = array(
     'title' => 'Add new comment',
diff --git a/core/modules/config/config.module b/core/modules/config/config.module
index a41fc09..f8a1874 100644
--- a/core/modules/config/config.module
+++ b/core/modules/config/config.module
@@ -51,7 +51,6 @@ function config_menu() {
   $items['admin/config/development/sync/import'] = array(
     'title' => 'Import',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
   return $items;
 }
diff --git a/core/modules/config/tests/config_test/config_test.module b/core/modules/config/tests/config_test/config_test.module
index 5dbcb92..42996f5 100644
--- a/core/modules/config/tests/config_test/config_test.module
+++ b/core/modules/config/tests/config_test/config_test.module
@@ -45,7 +45,6 @@ function config_test_menu() {
   $items['admin/structure/config_test/manage/%config_test/edit'] = array(
     'title' => 'Edit',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
   $items['admin/structure/config_test/manage/%config_test/delete'] = array(
     'title' => 'Delete',
diff --git a/core/modules/contact/contact.module b/core/modules/contact/contact.module
index 44a6f5a..4939ecf 100644
--- a/core/modules/contact/contact.module
+++ b/core/modules/contact/contact.module
@@ -84,7 +84,6 @@ function contact_menu() {
   $items['admin/structure/contact/manage/%contact_category/edit'] = array(
     'title' => 'Edit',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
   $items['admin/structure/contact/manage/%contact_category/delete'] = array(
     'title' => 'Delete',
diff --git a/core/modules/field_ui/field_ui.module b/core/modules/field_ui/field_ui.module
index dd2a1cc..b2e23a0 100644
--- a/core/modules/field_ui/field_ui.module
+++ b/core/modules/field_ui/field_ui.module
@@ -67,6 +67,10 @@ function field_ui_menu() {
     'type' => MENU_NORMAL_ITEM,
     'file' => 'field_ui.admin.inc',
   );
+  $items['admin/reports/fields/list'] = array(
+    'title' => 'Entities',
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+  );
 
   // Create tabs for all possible bundles.
   foreach (entity_get_info() as $entity_type => $entity_info) {
@@ -181,9 +185,11 @@ function field_ui_menu() {
               'access callback' => '_field_ui_view_mode_menu_access',
               'access arguments' => array_merge(array($entity_type, $bundle_arg, $view_mode, $access['access callback']), $access['access arguments']),
               'type' => ($view_mode == 'default' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK),
-              'weight' => ($view_mode == 'default' ? -10 : $weight++),
               'file' => 'field_ui.admin.inc',
             );
+            if ($view_mode != 'default') {
+              $items["$path/display/$view_mode"]['weight'] = $weight++;
+            }
           }
         }
       }
diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module
index c4b596a..5ea0f32 100644
--- a/core/modules/filter/filter.module
+++ b/core/modules/filter/filter.module
@@ -147,7 +147,6 @@ function filter_menu() {
     'page callback' => 'filter_admin_format_page',
     'access arguments' => array('administer filters'),
     'type' => MENU_LOCAL_ACTION,
-    'weight' => 1,
     'file' => 'filter.admin.inc',
   );
   $items['admin/config/content/formats/%filter_format'] = array(
diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module
index fbe06a0..392768c 100644
--- a/core/modules/forum/forum.module
+++ b/core/modules/forum/forum.module
@@ -116,7 +116,6 @@ function forum_menu() {
   $items['admin/structure/forum/list'] = array(
     'title' => 'List',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
   $items['admin/structure/forum/add/container'] = array(
     'title' => 'Add container',
@@ -141,7 +140,7 @@ function forum_menu() {
     'page callback' => 'drupal_get_form',
     'page arguments' => array('forum_admin_settings'),
     'access arguments' => array('administer forums'),
-    'weight' => 5,
+    'weight' => 100,
     'type' => MENU_LOCAL_TASK,
     'parent' => 'admin/structure/forum',
     'file' => 'forum.admin.inc',
@@ -164,9 +163,9 @@ function forum_menu() {
 }
 
 /**
- * Implements hook_menu_local_tasks_alter().
+ * Implements hook_menu_local_tasks().
  */
-function forum_menu_local_tasks_alter(&$data, $router_item, $root_path) {
+function forum_menu_local_tasks(&$data, $router_item, $root_path) {
   global $user;
 
   // Add action link to 'node/add/forum' on 'forum' sub-pages.
@@ -211,7 +210,7 @@ function forum_menu_local_tasks_alter(&$data, $router_item, $root_path) {
           );
         }
       }
-      $data['actions']['output'] = array_merge($data['actions']['output'], $links);
+      $data['actions'] += $links;
     }
   }
 }
diff --git a/core/modules/image/image.module b/core/modules/image/image.module
index b9ad53c..f1af8f9 100644
--- a/core/modules/image/image.module
+++ b/core/modules/image/image.module
@@ -121,7 +121,6 @@ function image_menu() {
     'page callback' => 'image_style_list',
     'access arguments' => array('administer image styles'),
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => 1,
     'file' => 'image.admin.inc',
   );
   $items['admin/config/media/image-styles/add'] = array(
diff --git a/core/modules/language/language.module b/core/modules/language/language.module
index c2356be..98930a5 100644
--- a/core/modules/language/language.module
+++ b/core/modules/language/language.module
@@ -74,7 +74,6 @@ function language_menu() {
   );
   $items['admin/config/regional/language/list'] = array(
     'title' => 'List',
-    'weight' => 0,
     'type' => MENU_DEFAULT_LOCAL_TASK,
   );
   $items['admin/config/regional/language/add'] = array(
@@ -82,7 +81,6 @@ function language_menu() {
     'page callback' => 'drupal_get_form',
     'page arguments' => array('language_admin_add_form'),
     'access arguments' => array('administer languages'),
-    'weight' => 5,
     'type' => MENU_LOCAL_ACTION,
     'file' => 'language.admin.inc',
   );
diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module
index 5ba05d2..4823b0b 100644
--- a/core/modules/locale/locale.module
+++ b/core/modules/locale/locale.module
@@ -193,7 +193,6 @@ function locale_menu() {
   );
   $items['admin/config/regional/translate/translate'] = array(
     'title' => 'Translate',
-    'weight' => -10,
     'type' => MENU_DEFAULT_LOCAL_TASK,
   );
   $items['admin/config/regional/translate/import'] = array(
@@ -219,7 +218,7 @@ function locale_menu() {
     'page callback' => 'drupal_get_form',
     'page arguments' => array('locale_translate_settings'),
     'access arguments' => array('translate interface'),
-    'weight' => 40,
+    'weight' => 100,
     'type' => MENU_LOCAL_TASK,
     'file' => 'locale.pages.inc',
   );
diff --git a/core/modules/menu/menu.module b/core/modules/menu/menu.module
index 3d4a360..5f12c22 100644
--- a/core/modules/menu/menu.module
+++ b/core/modules/menu/menu.module
@@ -79,7 +79,6 @@ function menu_menu() {
   $items['admin/structure/menu/list'] = array(
     'title' => 'List menus',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
   $items['admin/structure/menu/add'] = array(
     'title' => 'Add menu',
@@ -94,7 +93,7 @@ function menu_menu() {
     'page arguments' => array('menu_configure'),
     'access arguments' => array('administer menu'),
     'type' => MENU_LOCAL_TASK,
-    'weight' => 5,
+    'weight' => 100,
     'file' => 'menu.admin.inc',
   );
   $items['admin/structure/menu/manage/%menu'] = array(
@@ -108,7 +107,6 @@ function menu_menu() {
   );
   $items['admin/structure/menu/manage/%menu/list'] = array(
     'title' => 'List links',
-    'weight' => -10,
     'type' => MENU_DEFAULT_LOCAL_TASK,
     'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
   );
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 9e8fbd3..12302c4 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -1640,7 +1640,6 @@ function node_menu() {
   $items['admin/content/node'] = array(
     'title' => 'Content',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
 
   $items['admin/reports/status/rebuild'] = array(
@@ -1664,7 +1663,6 @@ function node_menu() {
   $items['admin/structure/types/list'] = array(
     'title' => 'List',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
   $items['admin/structure/types/add'] = array(
     'title' => 'Add content type',
@@ -1739,7 +1737,6 @@ function node_menu() {
   $items['node/%node/view'] = array(
     'title' => 'View',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
   $items['node/%node/edit'] = array(
     'title' => 'Edit',
@@ -1747,7 +1744,6 @@ function node_menu() {
     'page arguments' => array(1),
     'access callback' => 'node_access',
     'access arguments' => array('update', 1),
-    'weight' => 0,
     'type' => MENU_LOCAL_TASK,
     'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
     'file' => 'node.pages.inc',
@@ -1758,7 +1754,7 @@ function node_menu() {
     'page arguments' => array('node_delete_confirm', 1),
     'access callback' => 'node_access',
     'access arguments' => array('delete', 1),
-    'weight' => 1,
+    'weight' => 10,
     'type' => MENU_LOCAL_TASK,
     'context' => MENU_CONTEXT_INLINE,
     'file' => 'node.pages.inc',
@@ -1769,7 +1765,7 @@ function node_menu() {
     'page arguments' => array(1),
     'access callback' => '_node_revision_access',
     'access arguments' => array(1),
-    'weight' => 2,
+    'weight' => 20,
     'type' => MENU_LOCAL_TASK,
     'file' => 'node.pages.inc',
   );
@@ -1800,14 +1796,14 @@ function node_menu() {
 }
 
 /**
- * Implements hook_menu_local_tasks_alter().
+ * Implements hook_menu_local_tasks().
  */
-function node_menu_local_tasks_alter(&$data, $router_item, $root_path) {
+function node_menu_local_tasks(&$data, $router_item, $root_path) {
   // Add action link to 'node/add' on 'admin/content' page.
   if ($root_path == 'admin/content') {
     $item = menu_get_item('node/add');
     if ($item['access']) {
-      $data['actions']['output'][] = array(
+      $data['actions'][] = array(
         '#theme' => 'menu_local_action',
         '#link' => $item,
       );
diff --git a/core/modules/path/path.module b/core/modules/path/path.module
index 63e5c6c..3a468a0 100644
--- a/core/modules/path/path.module
+++ b/core/modules/path/path.module
@@ -64,6 +64,10 @@ function path_menu() {
     'weight' => -5,
     'file' => 'path.admin.inc',
   );
+  $items['admin/config/search/path/list'] = array(
+    'title' => 'List',
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+  );
   $items['admin/config/search/path/edit/%path'] = array(
     'title' => 'Edit alias',
     'page callback' => 'path_admin_edit',
@@ -78,11 +82,6 @@ function path_menu() {
     'access arguments' => array('administer url aliases'),
     'file' => 'path.admin.inc',
   );
-  $items['admin/config/search/path/list'] = array(
-    'title' => 'List',
-    'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
-  );
   $items['admin/config/search/path/add'] = array(
     'title' => 'Add alias',
     'page callback' => 'path_admin_edit',
diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module
index d7adb65..760947f 100644
--- a/core/modules/simpletest/simpletest.module
+++ b/core/modules/simpletest/simpletest.module
@@ -50,6 +50,7 @@ function simpletest_menu() {
     'page arguments' => array('simpletest_settings_form'),
     'access arguments' => array('administer unit tests'),
     'type' => MENU_LOCAL_TASK,
+    'weight' => 100,
     'file' => 'simpletest.pages.inc',
   );
   $items['admin/config/development/testing/results/%'] = array(
diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/LocalTasksTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/LocalTasksTest.php
new file mode 100644
index 0000000..5f695c0
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Menu/LocalTasksTest.php
@@ -0,0 +1,143 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\system\Tests\Menu\LocalTasksTest.
+ */
+
+namespace Drupal\system\Tests\Menu;
+
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Tests local tasks derived from router and added/altered via hooks.
+ */
+class LocalTasksTest extends WebTestBase {
+
+  public static $modules = array('menu_test');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Local tasks',
+      'description' => 'Tests local tasks derived from router and added/altered via hooks.',
+      'group' => 'Menu',
+    );
+  }
+
+  /**
+   * Tests appearance of local tasks.
+   *
+   * @see menu_test_menu()
+   * @see menu_test_menu_local_tasks()
+   * @see menu_test_menu_local_tasks_alter()
+   */
+  function testLocalTasks() {
+    // Verify that there is no local tasks markup if none are defined in the
+    // router and no module adds any dynamically.
+    $this->drupalGet('menu-test/tasks/empty');
+    $this->assertNoRaw('tabs');
+    $this->drupalGet('menu-test/tasks/default');
+    $this->assertNoRaw('tabs');
+
+    // Verify that local tasks appear as defined in the router.
+    $this->drupalGet('menu-test/tasks/tasks');
+    $this->assertLocalTasks(array(
+      // MENU_DEFAULT_LOCAL_TASK is expected to get a default weight of -10
+      // (without having to define it manually), so it should appear first,
+      // despite that its label is "View".
+      'menu-test/tasks/tasks',
+      'menu-test/tasks/tasks/edit',
+      'menu-test/tasks/tasks/settings',
+    ));
+
+    // Enable addition of tasks in menu_test_menu_local_tasks().
+    config('menu_test.settings')->set('tasks.add', TRUE)->save();
+
+    // Verify that the added tasks appear even if there are no tasks normally.
+    $this->drupalGet('menu-test/tasks/empty');
+    $this->assertLocalTasks(array(
+      'task/foo',
+      'task/bar',
+    ));
+
+    // Verify that the default local task appears before the added tasks.
+    $this->drupalGet('menu-test/tasks/default');
+    $this->assertLocalTasks(array(
+      'menu-test/tasks/default',
+      'task/foo',
+      'task/bar',
+    ));
+
+    // Verify that the added tasks appear within normal tasks.
+    $this->drupalGet('menu-test/tasks/tasks');
+    $this->assertLocalTasks(array(
+      'menu-test/tasks/tasks',
+      // The Edit task defines no weight, which is expected to sort as 0.
+      'menu-test/tasks/tasks/edit',
+      'task/foo',
+      'task/bar',
+      'menu-test/tasks/tasks/settings',
+    ));
+
+    // Enable manipulation of tasks in menu_test_menu_local_tasks_alter().
+    config('menu_test.settings')->set('tasks.alter', TRUE)->save();
+
+    // Verify that the added tasks appear even if there are no tasks normally.
+    $this->drupalGet('menu-test/tasks/empty');
+    $this->assertLocalTasks(array(
+      'task/bar',
+      'task/foo',
+    ));
+    $this->assertNoText('Show it');
+    $this->assertText('Advanced settings');
+
+    // Verify that the default local task appears before the added tasks.
+    $this->drupalGet('menu-test/tasks/default');
+    $this->assertLocalTasks(array(
+      'menu-test/tasks/default',
+      'task/bar',
+      'task/foo',
+    ));
+    $this->assertText('Show it');
+    $this->assertText('Advanced settings');
+
+    // Verify that the added tasks appear within normal tasks.
+    $this->drupalGet('menu-test/tasks/tasks');
+    $this->assertLocalTasks(array(
+      'menu-test/tasks/tasks',
+      'menu-test/tasks/tasks/edit',
+      'task/bar',
+      'menu-test/tasks/tasks/settings',
+      'task/foo',
+    ));
+    $this->assertText('Show it');
+    $this->assertText('Advanced settings');
+  }
+
+  /**
+   * Asserts local tasks in the page output.
+   *
+   * @param array $hrefs
+   *   A list of expected link hrefs of local tasks to assert on the page (in
+   *   the given order).
+   * @param int $level
+   *   (optional) The local tasks level to assert; 0 for primary, 1 for
+   *   secondary. Defaults to 0.
+   */
+  protected function assertLocalTasks(array $hrefs, $level = 0) {
+    $elements = $this->xpath('//*[contains(@class, :class)]//a', array(
+      ':class' => $level == 0 ? 'tabs primary' : 'tabs secondary',
+    ));
+    $this->assertTrue(count($elements), 'Local tasks found.');
+    foreach ($hrefs as $index => $element) {
+      $expected = url($hrefs[$index]);
+      $method = ($elements[$index]['href'] == $expected ? 'pass' : 'fail');
+      $this->{$method}(format_string('Task @number href @value equals @expected.', array(
+        '@number' => $index + 1,
+        '@value' => (string) $elements[$index]['href'],
+        '@expected' => $expected,
+      )));
+    }
+  }
+
+}
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index 7e95a03..0371830 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -1041,8 +1041,7 @@ function hook_menu_link_delete($link) {
  * Alter tabs and actions displayed on the page before they are rendered.
  *
  * This hook is invoked by menu_local_tasks(). The system-determined tabs and
- * actions are passed in by reference. Additional tabs or actions may be added,
- * or existing items altered.
+ * actions are passed in by reference. Additional tabs or actions may be added.
  *
  * Each tab or action is an associative array containing:
  * - #theme: The theme function to use to render.
@@ -1050,30 +1049,24 @@ function hook_menu_link_delete($link) {
  *   - title: The localized title of the link.
  *   - href: The system path to link to.
  *   - localized_options: An array of options to pass to l().
+ * - #weight: The link's weight compared to other links.
  * - #active: Whether the link should be marked as 'active'.
  *
- * @param $data
+ * @param array $data
  *   An associative array containing:
- *   - actions: An associative array containing:
- *     - count: The amount of actions determined by the menu system, which can
- *       be ignored.
- *     - output: A list of of actions, each one being an associative array
- *       as described above.
- *   - tabs: An indexed array (list) of tab levels (up to 2 levels), each
- *     containing an associative array:
- *     - count: The amount of tabs determined by the menu system. This value
- *       does not need to be altered if there is more than one tab.
- *     - output: A list of of tabs, each one being an associative array as
- *       described above.
- * @param $router_item
+ *   - actions: A list of of actions keyed by their href, each one being an
+ *     associative array as described above.
+ *   - tabs: A list of (up to 2) tab levels that contain a list of of tabs keyed
+ *     by their href, each one being an associative array as described above.
+ * @param array $router_item
  *   The menu system router item of the page.
- * @param $root_path
+ * @param string $root_path
  *   The path to the root item for this set of tabs.
  */
-function hook_menu_local_tasks_alter(&$data, $router_item, $root_path) {
+function hook_menu_local_tasks(&$data, $router_item, $root_path) {
   // Add an action linking to node/add to all pages.
-  $data['actions']['output'][] = array(
-    '#theme' => 'menu_local_task',
+  $data['actions']['node/add'] = array(
+    '#theme' => 'menu_local_action',
     '#link' => array(
       'title' => t('Add new content'),
       'href' => 'node/add',
@@ -1086,7 +1079,7 @@ function hook_menu_local_tasks_alter(&$data, $router_item, $root_path) {
   );
 
   // Add a tab linking to node/add to all pages.
-  $data['tabs'][0]['output'][] = array(
+  $data['tabs'][0]['node/add'] = array(
     '#theme' => 'menu_local_task',
     '#link' => array(
       'title' => t('Example tab'),
@@ -1097,14 +1090,31 @@ function hook_menu_local_tasks_alter(&$data, $router_item, $root_path) {
         ),
       ),
     ),
-    // Define whether this link is active. This can be omitted for
-    // implementations that add links to pages outside of the current page
-    // context.
+    // Define whether this link is active. This can usually be omitted.
     '#active' => ($router_item['path'] == $root_path),
   );
 }
 
 /**
+ * Alter tabs and actions displayed on the page before they are rendered.
+ *
+ * This hook is invoked by menu_local_tasks(). The system-determined tabs and
+ * actions are passed in by reference. Existing tabs or actions may be altered.
+ *
+ * @param array $data
+ *   An associative array containing tabs and actions. See
+ *   hook_menu_local_tasks() for details.
+ * @param array $router_item
+ *   The menu system router item of the page.
+ * @param string $root_path
+ *   The path to the root item for this set of tabs.
+ *
+ * @see hook_menu_local_tasks()
+ */
+function hook_menu_local_tasks_alter(&$data, $router_item, $root_path) {
+}
+
+/**
  * Alter links in the active trail before it is rendered as the breadcrumb.
  *
  * This hook is invoked by menu_get_active_breadcrumb() and allows alteration
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 2d665bb..55a9d94 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -692,7 +692,6 @@ function system_menu() {
     'title' => 'List',
     'description' => 'Select and configure your theme',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -1,
     'file' => 'system.admin.inc',
   );
   $items['admin/appearance/enable'] = array(
@@ -724,13 +723,12 @@ function system_menu() {
     'access arguments' => array('administer themes'),
     'type' => MENU_LOCAL_TASK,
     'file' => 'system.admin.inc',
-    'weight' => 20,
+    'weight' => 100,
   );
   // Theme configuration subtabs.
   $items['admin/appearance/settings/global'] = array(
     'title' => 'Global settings',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -1,
   );
 
   foreach (list_themes() as $key => $theme) {
diff --git a/core/modules/system/tests/modules/design_test/design_test.module b/core/modules/system/tests/modules/design_test/design_test.module
index b8a1a80..9771ba4 100644
--- a/core/modules/system/tests/modules/design_test/design_test.module
+++ b/core/modules/system/tests/modules/design_test/design_test.module
@@ -75,7 +75,6 @@ function design_test_menu() {
   $items['design_test/list'] = array(
     'title' => 'List',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
   // Lastly, add the category containers.
   foreach ($categories as $category) {
diff --git a/core/modules/system/tests/modules/menu_test/menu_test.module b/core/modules/system/tests/modules/menu_test/menu_test.module
index 36cef57..1b0ada5 100644
--- a/core/modules/system/tests/modules/menu_test/menu_test.module
+++ b/core/modules/system/tests/modules/menu_test/menu_test.module
@@ -124,7 +124,6 @@ function menu_test_menu() {
   $items['menu-test/hidden/menu/list'] = array(
     'title' => 'List menus',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
   $items['menu-test/hidden/menu/add'] = array(
     'title' => 'Add menu',
@@ -146,7 +145,6 @@ function menu_test_menu() {
   );
   $items['menu-test/hidden/menu/manage/%menu/list'] = array(
     'title' => 'List links',
-    'weight' => -10,
     'type' => MENU_DEFAULT_LOCAL_TASK,
     'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
   );
@@ -178,7 +176,6 @@ function menu_test_menu() {
   $items['menu-test/hidden/block/list'] = array(
     'title' => 'List',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
   $items['menu-test/hidden/block/add'] = array(
     'title' => 'Add block',
@@ -239,6 +236,38 @@ function menu_test_menu() {
     'type' => MENU_LOCAL_TASK,
   ) + $base;
 
+  // Menu local tasks tests.
+  // @see Drupal\system\Tests\Menu\LocalTasksTest
+  $items['menu-test/tasks'] = array(
+    'title' => 'Local tasks',
+  ) + $base;
+  $items['menu-test/tasks/empty'] = array(
+    'title' => 'Empty',
+  ) + $base;
+  $items['menu-test/tasks/default'] = array(
+    'title' => 'Default only',
+  ) + $base;
+  $items['menu-test/tasks/default/view'] = array(
+    'title' => 'View',
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+  ) + $base;
+  $items['menu-test/tasks/tasks'] = array(
+    'title' => 'With tasks',
+  ) + $base;
+  $items['menu-test/tasks/tasks/view'] = array(
+    'title' => 'View',
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+  ) + $base;
+  $items['menu-test/tasks/tasks/edit'] = array(
+    'title' => 'Edit',
+    'type' => MENU_LOCAL_TASK,
+  ) + $base;
+  $items['menu-test/tasks/tasks/settings'] = array(
+    'title' => 'Settings',
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 100,
+  ) + $base;
+
   // Menu trail tests.
   // @see MenuTrailTestCase
   $items['menu-test/menu-trail'] = array(
@@ -367,6 +396,56 @@ function menu_test_menu() {
 }
 
 /**
+ * Implements hook_menu_local_tasks().
+ */
+function menu_test_menu_local_tasks(&$data, $router_item, $root_path) {
+  if (!config('menu_test.settings')->get('tasks.add')) {
+    return;
+  }
+  if (strpos($router_item['tab_root'], 'menu-test/tasks/') === 0) {
+    $data['tabs'][0]['foo'] = array(
+      '#theme' => 'menu_local_task',
+      '#link' => array(
+        'title' => 'Task 1',
+        'href' => 'task/foo',
+      ),
+      '#weight' => 10,
+    );
+    $data['tabs'][0]['bar'] = array(
+      '#theme' => 'menu_local_task',
+      '#link' => array(
+        'title' => 'Task 2',
+        'href' => 'task/bar',
+      ),
+      '#weight' => 20,
+    );
+  }
+}
+
+/**
+ * Implements hook_menu_local_tasks_alter().
+ */
+function menu_test_menu_local_tasks_alter(&$data, $router_item, $root_path) {
+  if (!config('menu_test.settings')->get('tasks.alter')) {
+    return;
+  }
+  if (strpos($router_item['tab_root'], 'menu-test/tasks/') === 0) {
+    // Rename the default local task from 'View' to 'Show'.
+    // $data['tabs'] is expected to be keyed by link hrefs.
+    // The default local task always links to its parent path, which means that
+    // if the tab root path appears as key in $data['tabs'], then that key is
+    // the default local task.
+    $key = $router_item['tab_root'];
+    if (isset($data['tabs'][0][$key])) {
+      $data['tabs'][0][$key]['#link']['title'] = 'Show it';
+    }
+    // Rename the 'foo' task to "Advanced settings" and put it last.
+    $data['tabs'][0]['foo']['#link']['title'] = 'Advanced settings';
+    $data['tabs'][0]['foo']['#weight'] = 110;
+  }
+}
+
+/**
  * Dummy argument loader for hook_menu() to point to.
  */
 function menu_test_argument_load($arg1) {
diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module
index a15874e..4756a06 100644
--- a/core/modules/taxonomy/taxonomy.module
+++ b/core/modules/taxonomy/taxonomy.module
@@ -253,7 +253,6 @@ function taxonomy_menu() {
   $items['admin/structure/taxonomy/list'] = array(
     'title' => 'List',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
   $items['admin/structure/taxonomy/add'] = array(
     'title' => 'Add vocabulary',
@@ -295,7 +294,7 @@ function taxonomy_menu() {
     'access callback' => 'taxonomy_term_access',
     'access arguments' => array('delete', 2),
     'type' => MENU_LOCAL_TASK,
-    'weight' => 11,
+    'weight' => 20,
     'file' => 'taxonomy.admin.inc',
   );
   $items['taxonomy/term/%taxonomy_term/feed'] = array(
@@ -328,7 +327,6 @@ function taxonomy_menu() {
   $items['admin/structure/taxonomy/%taxonomy_vocabulary/list'] = array(
     'title' => 'List',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -20,
   );
   $items['admin/structure/taxonomy/%taxonomy_vocabulary/edit'] = array(
     'title' => 'Edit',
@@ -336,7 +334,6 @@ function taxonomy_menu() {
     'page arguments' => array(3),
     'access arguments' => array('administer taxonomy'),
     'type' => MENU_LOCAL_TASK,
-    'weight' => -10,
     'file' => 'taxonomy.admin.inc',
   );
 
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 02f5072..f6d80e0 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -909,7 +909,6 @@ function user_menu() {
   $items['user/login/default'] = array(
     'title' => 'Username and password',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
 
   $items['user/register'] = array(
@@ -966,7 +965,6 @@ function user_menu() {
     'description' => 'Find and manage people interacting with your site.',
     'access arguments' => array('administer users'),
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
     'file' => 'user.admin.inc',
   );
 
@@ -1033,7 +1031,6 @@ function user_menu() {
   $items['admin/config/people/accounts/settings'] = array(
     'title' => 'Settings',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
 
   $items['user/%user'] = array(
@@ -1045,13 +1042,10 @@ function user_menu() {
     'access callback' => 'user_view_access',
     'access arguments' => array(1),
   );
-
   $items['user/%user/view'] = array(
     'title' => 'View',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
   );
-
   $items['user/%user/cancel'] = array(
     'title' => 'Cancel account',
     'page callback' => 'drupal_get_form',
@@ -1060,7 +1054,6 @@ function user_menu() {
     'access arguments' => array(1),
     'file' => 'user.pages.inc',
   );
-
   $items['user/%user/cancel/confirm/%/%'] = array(
     'title' => 'Confirm account cancellation',
     'page callback' => 'user_cancel_confirm',
@@ -1069,7 +1062,6 @@ function user_menu() {
     'access arguments' => array(1),
     'file' => 'user.pages.inc',
   );
-
   $items['user/%user/edit'] = array(
     'title' => 'Edit',
     'page callback' => 'entity_get_form',
diff --git a/core/modules/views/views_ui/views_ui.module b/core/modules/views/views_ui/views_ui.module
index 7552f63..fbb5dd5 100644
--- a/core/modules/views/views_ui/views_ui.module
+++ b/core/modules/views/views_ui/views_ui.module
@@ -46,7 +46,6 @@ function views_ui_menu() {
 
   $items['admin/structure/views/list'] = array(
     'title' => 'List',
-    'weight' => -10,
     'type' => MENU_DEFAULT_LOCAL_TASK,
   ) + $base;
 
@@ -103,7 +102,6 @@ function views_ui_menu() {
     'title' => 'Edit view',
     'type' => MENU_DEFAULT_LOCAL_TASK,
     'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
-    'weight' => -10,
     'theme callback' => 'ajax_base_page_theme',
   ) + $base;
   $items['admin/structure/views/view/%views_ui_cache/edit/%/ajax'] = array(
@@ -170,17 +168,11 @@ function views_ui_menu() {
   ) + $base;
 
   // A page in the Reports section to show usage of fields in all views
-  $items['admin/reports/fields/list'] = array(
-    'title' => 'List',
-    'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
-  );
   $items['admin/reports/fields/views-fields'] = array(
     'title' => 'Used in views',
     'description' => 'Overview of fields used in all views.',
     'page callback' => 'views_ui_field_list',
     'type' => MENU_LOCAL_TASK,
-    'weight' => 0,
   ) + $base;
 
   // A page in the Reports section to show usage of plugins in all views.
diff --git a/core/themes/seven/template.php b/core/themes/seven/template.php
index d679369..8ffe462 100644
--- a/core/themes/seven/template.php
+++ b/core/themes/seven/template.php
@@ -34,7 +34,7 @@ function seven_preprocess_page(&$vars) {
   unset($vars['primary_local_tasks']['#secondary']);
   $vars['secondary_local_tasks'] = array(
     '#theme' => 'menu_local_tasks',
-    '#secondary' => $vars['tabs']['#secondary'],
+    '#secondary' => isset($vars['tabs']['#secondary']) ? $vars['tabs']['#secondary'] : '',
   );
 }
 
