diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index dc70185..c52c37c 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -508,7 +508,13 @@ function menu_execute_active_handler($path = NULL, $deliver = TRUE) {
         if ($router_item['include_file']) {
           require_once DRUPAL_ROOT . '/' . $router_item['include_file'];
         }
-        $page_callback_result = call_user_func_array($router_item['page_callback'], $router_item['page_arguments']);
+        if (function_exists($router_item['page_callback'])) {
+          $page_callback_result = call_user_func_array($router_item['page_callback'], $router_item['page_arguments']);
+        }
+        else {
+          debug($router_item['page_callback'] . ' function does not exist.[1]');
+          $page_callback_result = MENU_NOT_FOUND;
+        }
       }
       else {
         $page_callback_result = MENU_ACCESS_DENIED;
@@ -627,7 +633,9 @@ function _menu_check_access(&$item, $map) {
       $item['access'] = (count($arguments) == 1) ? user_access($arguments[0]) : user_access($arguments[0], $arguments[1]);
     }
     else {
-      $item['access'] = call_user_func_array($callback, $arguments);
+      // If the callback function does not exist, do not set $item['access'] to
+      // TRUE.
+      $item['access'] = function_exists($callback) ? call_user_func_array($callback, $arguments) : NULL;
     }
   }
 }
diff --git a/core/modules/menu/menu.admin.inc b/core/modules/menu/menu.admin.inc
index 2e1725d..2f41fa9 100644
--- a/core/modules/menu/menu.admin.inc
+++ b/core/modules/menu/menu.admin.inc
@@ -476,6 +476,32 @@ function menu_edit_menu($form, &$form_state, $type, $menu = array()) {
     '#title' => t('Description'),
     '#default_value' => $menu['description'],
   );
+
+  // Add the option to add custom menus to a content type when creating or
+  // updating a menu.
+  if (module_exists('node')) {
+    $node_types = node_type_get_names();
+    $default_value = array();
+    // Ignore the add form case because there are no default values available.
+    if ($type == 'edit') {
+      // When editing a menu we need to collect all the node types that have
+      // this menu enabled.
+      foreach ($node_types as $node_type => $name) {
+        $menu_options = variable_get('menu_options_' . $node_type, array('main-menu'));
+        if (in_array($menu['menu_name'], $menu_options)) {
+          $default_value[] = $node_type;
+        }
+      }
+    }
+    // Add checkboxes to the form for each content type.
+    $form['menu_node_types'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Available for these content types'),
+      '#default_value' => $default_value,
+      '#options' => $node_types,
+    );
+  }
+
   $form['actions'] = array('#type' => 'actions');
   $form['actions']['submit'] = array(
     '#type' => 'submit',
@@ -580,6 +606,11 @@ function menu_edit_menu_name_exists($value) {
 function menu_edit_menu_submit($form, &$form_state) {
   $menu = $form_state['values'];
   $path = 'admin/structure/menu/manage/';
+  // Abort if menu values do not exist
+  if (!isset($menu['menu_name']) || !isset($menu['title'])) {
+    drupal_set_message(t('There was a problem. Your configuration was not saved.'));
+    $form_state['redirect'] = $path;
+  }
   if ($form['#insert']) {
     // Add 'menu-' to the menu name to help avoid name-space conflicts.
     $menu['menu_name'] = 'menu-' . $menu['menu_name'];
@@ -605,6 +636,23 @@ function menu_edit_menu_submit($form, &$form_state) {
       menu_link_save($link);
     }
   }
+
+  // Add or remove this menu from each available node type.
+  if (isset($menu['menu_node_types'])) {
+    $node_types = $menu['menu_node_types'];
+    foreach ($node_types as $node_type => $value) {
+      $menu_options = variable_get('menu_options_' . $node_type, array('main-menu'));
+      if (empty($value)) {
+        // Remove this menu from the content type.
+        $menu_options = array_diff($menu_options, array($menu['menu_name']));
+      }
+      elseif (!empty($value) && !in_array($menu['menu_name'], $menu_options)) {
+        // Add this menu to the content type.
+        $menu_options[] = $menu['menu_name'];
+      }
+      variable_set('menu_options_' . $node_type, $menu_options);
+    }
+  }
   drupal_set_message(t('Your configuration has been saved.'));
   $form_state['redirect'] = $path . $menu['menu_name'];
 }
diff --git a/core/modules/menu/menu.test b/core/modules/menu/menu.test
index 14fe96b..5227d4e 100644
--- a/core/modules/menu/menu.test
+++ b/core/modules/menu/menu.test
@@ -31,7 +31,8 @@ class MenuTestCase extends WebTestBase {
   }
 
   /**
-   * Login users, add menus and menu links, and test menu functionality through the admin and user interfaces.
+   * Logs in users, adds menus and menu links, and tests menu functionality
+   * through the admin and user interfaces.
    */
   function testMenu() {
     // Login the user.
@@ -49,7 +50,8 @@ class MenuTestCase extends WebTestBase {
     $this->drupalLogin($this->std_user);
     $this->verifyAccess(403);
     foreach ($this->items as $item) {
-      $node = node_load(substr($item['link_path'], 5)); // Paths were set as 'node/$nid'.
+      // Paths were set as 'node/$nid'.
+      $node = node_load(substr($item['link_path'], 5));
       $this->verifyMenuLink($item, $node);
     }
 
@@ -80,7 +82,6 @@ class MenuTestCase extends WebTestBase {
 
   /**
    * Test standard menu functionality using navigation menu.
-   *
    */
   function doStandardMenuTests() {
     $this->doMenuTests();
@@ -89,7 +90,6 @@ class MenuTestCase extends WebTestBase {
 
   /**
    * Test custom menu functionality using navigation menu.
-   *
    */
   function doCustomMenuTests() {
     $this->menu = $this->addCustomMenu();
@@ -129,8 +129,6 @@ class MenuTestCase extends WebTestBase {
    * Add custom menu.
    */
   function addCustomMenu() {
-    // Add custom menu.
-
     // Try adding a menu using a menu_name that is too long.
     $this->drupalGet('admin/structure/menu/add');
     $menu_name = substr(hash('sha256', $this->randomName(16)), 0, MENU_MAX_MENU_NAME_LENGTH_UI + 1);
@@ -142,7 +140,8 @@ class MenuTestCase extends WebTestBase {
     );
     $this->drupalPost('admin/structure/menu/add', $edit, t('Save'));
 
-    // Verify that using a menu_name that is too long results in a validation message.
+    // Verify that using a menu_name that is too long results in a validation
+    // message.
     $this->assertRaw(t('!name cannot be longer than %max characters but is currently %length characters long.', array(
       '!name' => t('Menu name'),
       '%max' => MENU_MAX_MENU_NAME_LENGTH_UI,
@@ -197,7 +196,6 @@ class MenuTestCase extends WebTestBase {
 
   /**
    * Test menu functionality using navigation menu.
-   *
    */
   function doMenuTests($menu_name = 'navigation') {
     // Add nodes to use as links for menu links.
@@ -246,8 +244,8 @@ class MenuTestCase extends WebTestBase {
     $this->disableMenuLink($item1);
     $edit = array();
 
-    // Note in the UI the 'mlid:x[hidden]' form element maps to enabled, or
-    // NOT hidden.
+    // Test a hidden menu link. Note in the UI the 'mlid:x[hidden]' form element
+    // maps to enabled, or NOT hidden.
     $edit['mlid:' . $item1['mlid'] . '[hidden]'] = TRUE;
     $this->drupalPost('admin/structure/menu/manage/' . $item1['menu_name'], $edit, t('Save configuration'));
 
@@ -340,9 +338,9 @@ class MenuTestCase extends WebTestBase {
    * @param array $parent Parent menu link.
    * @param object $parent_node Parent menu link content node.
    */
-  function verifyMenuLink($item, $item_node, $parent = NULL, $parent_node = NULL) {
+  function verifyMenuLink($item, $item_node = NULL, $parent = NULL, $parent_node = NULL) {
     // View home page.
-    $this->drupalGet('');
+    $this->drupalGet('user');
     $this->assertResponse(200);
 
     // Verify parent menu link.
@@ -352,9 +350,11 @@ class MenuTestCase extends WebTestBase {
       $this->assertLink($title, 0, 'Parent menu link was displayed');
 
       // Verify menu link link.
-      $this->clickLink($title);
-      $title = $parent_node->title;
-      $this->assertTitle(t("@title | Drupal", array('@title' => $title)), t('Parent menu link link target was correct'));
+      if (isset($parent_node)) {
+        $this->clickLink($title);
+        $title = $parent_node->title;
+        $this->assertTitle(t("@title | Drupal", array('@title' => $title)), t('Parent menu link link target was correct'));
+      }
     }
 
     // Verify menu link.
@@ -362,9 +362,11 @@ class MenuTestCase extends WebTestBase {
     $this->assertLink($title, 0, 'Menu link was displayed');
 
     // Verify menu link link.
-    $this->clickLink($title);
-    $title = $item_node->title;
-    $this->assertTitle(t("@title | Drupal", array('@title' => $title)), t('Menu link link target was correct'));
+    if (isset($item_node)) {
+      $this->clickLink($title);
+      $title = $item_node->title;
+      $this->assertTitle(t("@title | Drupal", array('@title' => $title)), t('Menu link link target was correct'));
+    }
   }
 
   /**
@@ -419,7 +421,7 @@ class MenuTestCase extends WebTestBase {
     $this->assertRaw(t('The menu link was reset to its default settings.'), t('Menu link was reset'));
 
     // Verify menu link.
-    $this->drupalGet('');
+    $this->drupalGet('user');
     $this->assertNoText($title, 'Menu link was reset');
     $this->assertText($old_title, 'Menu link was reset');
   }
@@ -453,12 +455,12 @@ class MenuTestCase extends WebTestBase {
     $this->disableMenuLink($item);
 
     // Verify menu link is absent.
-    $this->drupalGet('');
+    $this->drupalGet('user');
     $this->assertNoText($item['link_title'], 'Menu link was not displayed');
     $this->enableMenuLink($item);
 
     // Verify menu link is displayed.
-    $this->drupalGet('');
+    $this->drupalGet('user');
     $this->assertText($item['link_title'], 'Menu link was displayed');
   }
 
@@ -521,7 +523,8 @@ class MenuTestCase extends WebTestBase {
    * Get standard menu link.
    */
   private function getStandardMenuLink() {
-    // Retrieve menu link id of the Log out menu link, which will always be on the front page.
+    // Retrieve menu link id of the Log out menu link, which will always be on
+    // the front page.
     $mlid = db_query("SELECT mlid FROM {menu_links} WHERE module = 'system' AND router_path = 'user/logout'")->fetchField();
     $this->assertTrue($mlid > 0, 'Standard menu link id was found');
     // Load menu link.
@@ -580,6 +583,129 @@ class MenuTestCase extends WebTestBase {
       $this->assertText(t('Menus'), t('Add menu node was displayed'));
     }
   }
+
+  /**
+   * With node module disabled, this test logs in users, adds menus and menu
+   * links, and tests menu functionality through the admin and user interfaces.
+   */
+  function testMenuWithoutNode() {
+    // Disable node module to test menus.
+    module_disable(array('node'));
+
+    // Login the user.
+    $this->drupalLogin($this->big_user);
+    $this->items = array();
+
+    // Do standard menu tests.
+    $this->doStandardMenuTestsWithoutNode();
+
+    // Do custom menu tests.
+    $this->doCustomMenuTestsWithoutNode();
+
+    // No standard user tests because there are no accessible menu links to
+    // $std_user.
+
+    // Delete menu links.
+    foreach ($this->items as $item) {
+      $this->deleteMenuLink($item);
+    }
+
+    // Delete custom menu.
+    $this->deleteCustomMenu($this->menu);
+
+    // Modify and reset a standard menu link.
+    $item = $this->getStandardMenuLink();
+    $old_title = $item['link_title'];
+    $this->modifyMenuLink($item);
+    $item = menu_link_load($item['mlid']);
+
+    // Verify that a change to the description is saved.
+    $description = $this->randomName(16);
+    $item['options']['attributes']['title']  = $description;
+    menu_link_save($item);
+    $saved_item = menu_link_load($item['mlid']);
+    $this->assertEqual($description, $saved_item['options']['attributes']['title'], t('Saving an existing link updates the description (title attribute)'));
+    $this->resetMenuLink($item, $old_title);
+  }
+
+  /**
+   * Test standard menu functionality using navigation menu.
+   *
+   */
+  function doStandardMenuTestsWithoutNode() {
+    $this->doMenuTestsWithoutNode();
+    $this->addInvalidMenuLink();
+  }
+
+  /**
+   * Test custom menu functionality using navigation menu.
+   *
+   */
+  function doCustomMenuTestsWithoutNode() {
+    $this->menu = $this->addCustomMenu();
+    $this->doMenuTestsWithoutNode($this->menu['menu_name']);
+    $this->addInvalidMenuLink($this->menu['menu_name']);
+    $this->addCustomMenuCRUD();
+  }
+
+
+  /**
+   * Test menu functionality using navigation menu.
+   *
+   */
+  function doMenuTestsWithoutNode($menu_name = 'navigation') {
+
+    // Add menu links.
+    $item1 = $this->addMenuLink(0, 'admin', $menu_name);
+    $item2 = $this->addMenuLink($item1['mlid'], 'admin/structure', $menu_name);
+    $item3 = $this->addMenuLink($item2['mlid'], 'admin/structure/block', $menu_name);
+    $this->assertMenuLink($item1['mlid'], array('depth' => 1, 'has_children' => 1, 'p1' => $item1['mlid'], 'p2' => 0));
+    $this->assertMenuLink($item2['mlid'], array('depth' => 2, 'has_children' => 1, 'p1' => $item1['mlid'], 'p2' => $item2['mlid'], 'p3' => 0));
+    $this->assertMenuLink($item3['mlid'], array('depth' => 3, 'has_children' => 0, 'p1' => $item1['mlid'], 'p2' => $item2['mlid'], 'p3' => $item3['mlid'], 'p4' => 0));
+
+    // Verify menu links.
+    $this->verifyMenuLink($item1);
+    $this->verifyMenuLink($item2, NULL, $item1, NULL);
+    $this->verifyMenuLink($item3, NULL, $item2, NULL);
+
+    // Add more menu links.
+    $item4 = $this->addMenuLink(0, 'admin/config', $menu_name);
+    $item5 = $this->addMenuLink($item4['mlid'], 'admin/config/system', $menu_name);
+    $this->assertMenuLink($item4['mlid'], array('depth' => 1, 'has_children' => 1, 'p1' => $item4['mlid'], 'p2' => 0));
+    $this->assertMenuLink($item5['mlid'], array('depth' => 2, 'has_children' => 0, 'p1' => $item4['mlid'], 'p2' => $item5['mlid'], 'p3' => 0));
+
+    // Modify menu links.
+    $this->modifyMenuLink($item1);
+    $this->modifyMenuLink($item2);
+
+    // Toggle menu links.
+    $this->toggleMenuLink($item1);
+    $this->toggleMenuLink($item2);
+
+    // Move link and verify that descendants are updated.
+    $this->moveMenuLink($item2, $item5['mlid'], $menu_name);
+    $this->assertMenuLink($item1['mlid'], array('depth' => 1, 'has_children' => 0, 'p1' => $item1['mlid'], 'p2' => 0));
+    $this->assertMenuLink($item4['mlid'], array('depth' => 1, 'has_children' => 1, 'p1' => $item4['mlid'], 'p2' => 0));
+    $this->assertMenuLink($item5['mlid'], array('depth' => 2, 'has_children' => 1, 'p1' => $item4['mlid'], 'p2' => $item5['mlid'], 'p3' => 0));
+    $this->assertMenuLink($item2['mlid'], array('depth' => 3, 'has_children' => 1, 'p1' => $item4['mlid'], 'p2' => $item5['mlid'], 'p3' => $item2['mlid'], 'p4' => 0));
+    $this->assertMenuLink($item3['mlid'], array('depth' => 4, 'has_children' => 0, 'p1' => $item4['mlid'], 'p2' => $item5['mlid'], 'p3' => $item2['mlid'], 'p4' => $item3['mlid'], 'p5' => 0));
+
+    // Enable a link via the overview form.
+    $this->disableMenuLink($item1);
+    $edit = array();
+
+    // Test a hidden menu link. Note in the UI the 'mlid:x[hidden]' form element
+    // maps to enabled, or NOT hidden.
+    $edit['mlid:' . $item1['mlid'] . '[hidden]'] = TRUE;
+    $this->drupalPost('admin/structure/menu/manage/' . $item1['menu_name'], $edit, t('Save configuration'));
+
+    // Verify in the database.
+    $this->assertMenuLink($item1['mlid'], array('hidden' => 0));
+
+    // Save menu links for later tests.
+    $this->items[] = $item1;
+    $this->items[] = $item2;
+  }
 }
 
 /**
@@ -679,7 +805,8 @@ class MenuNodeTestCase extends WebTestBase {
     );
     menu_link_save($item);
 
-    // Assert that disabled Management menu is not shown on the node/$nid/edit page.
+    // Assert that disabled Management menu is not shown on the node/$nid/edit
+    // page.
     $this->drupalGet('node/' . $node->nid . '/edit');
     $this->assertText('Provide a menu link', t('Link in not allowed menu not shown in node edit form'));
     // Assert that the link is still in the management menu after save.
@@ -701,7 +828,8 @@ class MenuNodeTestCase extends WebTestBase {
     menu_link_save($child_item);
     // Edit the first node.
     $this->drupalGet('node/'. $node->nid .'/edit');
-    // Assert that it is not possible to set the parent of the first node to itself or the second node.
+    // Assert that it is not possible to set the parent of the first node to
+    // itself or the second node.
     $this->assertNoOption('edit-menu-parent', 'navigation:'. $item['mlid']);
     $this->assertNoOption('edit-menu-parent', 'navigation:'. $child_item['mlid']);
     // Assert that unallowed Management menu is not available in options.
