diff --git a/modules/search/search.module b/modules/search/search.module
index 62d75ab6c47546e673753cc879f44b6f37779cbd..7c94c0f95d0bbb66b63ef1420ac5c929b00c8456 100644
--- a/modules/search/search.module
+++ b/modules/search/search.module
@@ -246,18 +246,43 @@ function search_menu() {
     'file path' => drupal_get_path('module', 'dblog'),
     'file' => 'dblog.admin.inc',
   );
+
+  // Add paths for searching. We add each module search path twice: once without
+  // and once with %menu_tail appended. The reason for this is that we want to
+  // preserve keywords when switching tabs, and also to have search tabs
+  // highlighted properly. The only way to do that within the Drupal menu
+  // system appears to be having two sets of tabs. See discussion on issue
+  // http://drupal.org/node/245103 for details.
+
   drupal_static_reset('search_get_info');
-  $search_hooks = search_get_info();
-  foreach(variable_get('search_active_modules', array('node', 'user')) as $module) {
-    if (isset($search_hooks[$module])) {
-      $items['search/' . $search_hooks[$module]['path'] . '/%menu_tail'] = array(
-        'title' => $search_hooks[$module]['title'],
+  if ($active = variable_get('search_active_modules', array('node', 'user'))) {
+    foreach (array_intersect_key(search_get_info(), array_flip($active)) as $module => $search_info) {
+      $path = 'search/' . $search_info['path'];
+      $items[$path] = array(
+        'title' => $search_info['title'],
+        'page callback' => 'search_view',
+        'page arguments' => array($module),
+        'access callback' => '_search_menu_access',
+        'access arguments' => array($module),
+        'type' => $module == 'node' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
+        'file' => 'search.pages.inc',
+        'weight' => $module == 'node' ? -10 : 0,
+      );
+      $items["$path/%menu_tail"] = array(
+        'title' => $search_info['title'],
         'page callback' => 'search_view',
         'page arguments' => array($module),
         'access callback' => '_search_menu_access',
         'access arguments' => array($module),
+        // The default local task points to its parent, but this item points to
+        // where it should so it should not be changed.
         'type' => MENU_LOCAL_TASK,
         'file' => 'search.pages.inc',
+        'weight' => 0,
+        // These tabs are not subtabs.
+        'tab_root' => 'search/node/%',
+        // These tabs need to display at the same level.
+        'tab_parent' => 'search',
       );
     }
   }
diff --git a/modules/search/search.pages.inc b/modules/search/search.pages.inc
index 6bbb8894296df4cd38fd5731ed0cab8b7ee630c9..17245cef9a1bb2460cec710414c93d415bbb3476 100644
--- a/modules/search/search.pages.inc
+++ b/modules/search/search.pages.inc
@@ -14,14 +14,14 @@ function search_view($type = 'node') {
   // the search query URL clean as a whistle:
   // search/type/keyword+keyword
   if (!isset($_POST['form_id'])) {
-    if ($type == '') {
-      // Note: search/node can not be a default tab because it would take on the
-      // path of its parent (search). It would prevent remembering keywords when
-      // switching tabs. This is why we drupal_goto to it from the parent instead.
-      drupal_goto('search/node');
+    $keys = search_get_keys();
+    if ($_GET['q'] != 'search' && $type == 'node' && !$keys) {
+      // Due to how search_menu() sets up the tabs, path search/node would
+      // display two sets of tabs. So instead, if there are no keywords and
+      // we're on the node tab, just redirect to the bare 'search' path.
+      drupal_goto('search');
     }
 
-    $keys = search_get_keys();
     // Only perform search if there is non-whitespace search term:
     $results = '';
     if (trim($keys)) {