Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.419
diff -u -9 -p -r1.419 form.inc
--- includes/form.inc	14 Dec 2009 13:51:56 -0000	1.419
+++ includes/form.inc	15 Dec 2009 17:56:41 -0000
@@ -2377,27 +2377,39 @@ function theme_tableselect($variables) {
       if (isset($value['#attributes'])) {
         $row += $value['#attributes'];
       }
       // Render the checkbox / radio element.
       $row['data'][] = drupal_render($element[$key]);
 
       // As theme_table only maps header and row columns by order, create the
       // correct order by iterating over the header fields.
       foreach ($element['#header'] as $fieldname => $title) {
-        $row['data'][] = $element['#options'][$key][$fieldname];
+        if (isset($element['#options'][$key][$fieldname])) {
+          $row['data'][] = $element['#options'][$key][$fieldname];
+        }
+        else {
+          $row['data'][] = '';
+        }
       }
       $rows[] = $row;
     }
     // Add an empty header or a "Select all" checkbox to provide room for the
     // checkboxes/radios in the first table column.
     $first_col = $element['#js_select'] ? array(theme('table_select_header_cell')) : array('');
     $header = array_merge($first_col, $header);
   }
+  // A header cell with colspan == 0 is used to name a column following another
+  // header cells with colspan > 1, and should not be displayed.
+  foreach ($header as $fieldname => $title) {
+    if (is_array($header[$fieldname]) && isset($header[$fieldname]['colspan']) && $header[$fieldname]['colspan'] == 0) {
+      unset($header[$fieldname]);
+    }
+  }
   return theme('table', array('header' => $header, 'rows' => $rows, 'empty' => $element['#empty'], 'attributes' => $element['#attributes']));
 }
 
 /**
  * Create the correct amount of checkbox or radio elements to populate the table.
  *
  * @param $element
  *   An associative array containing the properties and children of the
  *   tableselect element.
Index: modules/node/node.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.admin.inc,v
retrieving revision 1.82
diff -u -9 -p -r1.82 node.admin.inc
--- modules/node/node.admin.inc	4 Dec 2009 16:49:46 -0000	1.82
+++ modules/node/node.admin.inc	15 Dec 2009 17:56:41 -0000
@@ -438,19 +438,20 @@ function node_admin_nodes() {
     'title' => array('data' => t('Title'), 'field' => 'n.title'),
     'type' => array('data' => t('Type'), 'field' => 'n.type'),
     'author' => array('data' => t('Author'), 'field' => 'u.name'),
     'status' => array('data' => t('Status'), 'field' => 'n.status'),
     'changed' => array('data' => t('Updated'), 'field' => 'n.changed', 'sort' => 'desc')
   );
   if ($multilanguage) {
     $header['language'] = array('data' => t('Language'), 'field' => 'n.language');
   }
-  $header['operations'] = array('data' => t('Operations'));
+  $header['edit'] = array('data' => t('Operations'), 'colspan' => 2);
+  $header['delete'] = array('colspan' => 0);
 
   $query = db_select('node', 'n')->extend('PagerDefault')->extend('TableSort');
   node_build_filter_query($query);
 
   if (!user_access('bypass node access')) {
     // If the user is able to view their own unpublished nodes, allow them
     // to see these in addition to published nodes. Check that they actually
     // have some unpublished nodes to view before adding the condition.
     if (user_access('view own unpublished content') && $own_unpublished = db_query('SELECT nid FROM {node} WHERE uid = :uid AND status = :status', array(':uid' => $GLOBALS['user']->uid, ':status' => 0))->fetchCol()) {
@@ -490,54 +491,35 @@ function node_admin_nodes() {
       ),
       'type' => check_plain(node_type_get_name($node)),
       'author' => theme('username', array('account' => $node)),
       'status' => $node->status ? t('published') : t('not published'),
       'changed' => format_date($node->changed, 'short'),
     );
     if ($multilanguage) {
       $options[$node->nid]['language'] = $node->language == LANGUAGE_NONE ? t('Language neutral') : t($languages[$node->language]->name);
     }
-    // Build a list of all the accessible operations for the current node.
-    $operations = array();
     if (node_access('update', $node)) {
-      $operations['edit'] = array(
-        'title' => t('edit'),
-        'href' => 'node/' . $node->nid . '/edit',
-        'query' => $destination,
-      );
-    }
-    if (node_access('delete', $node)) {
-      $operations['delete'] = array(
-        'title' => t('delete'),
-        'href' => 'node/' . $node->nid . '/delete',
-        'query' => $destination,
-      );
-    }
-    $options[$node->nid]['operations'] = array();
-    if (count($operations) > 1) {
-      // Render an unordered list of operations links.
-      $options[$node->nid]['operations'] = array(
+      $options[$node->nid]['edit'] = array(
         'data' => array(
-          '#theme' => 'links',
-          '#links' => $operations,
-          '#attributes' => array('class' => array('links', 'inline')),
+          '#type' => 'link',
+          '#title' => t('edit'),
+          '#href' => 'node/' . $node->nid . '/edit',
+          '#options' => array('query' => $destination),
         ),
       );
     }
-    elseif (!empty($operations)) {
-      // Render the first and only operation as a link.
-      $link = reset($operations);
-      $options[$node->nid]['operations'] = array(
+    if (node_access('delete', $node)) {
+      $options[$node->nid]['delete'] = array(
         'data' => array(
           '#type' => 'link',
-          '#title' => $link['title'],
-          '#href' => $link['href'],
-          '#options' => array('query' => $link['query']),
+          '#title' => t('delete'),
+          '#href' => 'node/' . $node->nid . '/delete',
+          '#options' => array('query' => $destination),
         ),
       );
     }
   }
 
   // Only use a tableselect when the current user is able to perform any
   // operations.
   if ($admin_access) {
     $form['nodes'] = array(
Index: modules/system/system.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.admin.inc,v
retrieving revision 1.238
diff -u -9 -p -r1.238 system.admin.inc
--- modules/system/system.admin.inc	15 Dec 2009 08:45:32 -0000	1.238
+++ modules/system/system.admin.inc	15 Dec 2009 17:56:42 -0000
@@ -792,41 +792,41 @@ function system_modules($form, $form_sta
           $extra['requires'][$requires] = t('@module (<span class="admin-disabled">disabled</span>)', array('@module' => $requires_name));
         }
       }
     }
     // Generate link for module's help page, if there is one.
     if ($help_arg && $module->status && in_array($filename, module_implements('help'))) {
       if (module_invoke($filename, 'help', "admin/help#$filename", $help_arg)) {
         $extra['links']['help'] = array(
           '#type' => 'link',
-          '#title' => t('Help'),
+          '#title' => t('help'),
           '#href' => "admin/help/$filename",
           '#options' => array('attributes' => array('class' =>  array('module-link', 'module-link-help'), 'title' => t('Help'))),
         );
       }
     }
     // Generate link for module's permission, if the user has access to it.
     if ($module->status && user_access('administer permissions') && in_array($filename, module_implements('permission'))) {
       $extra['links']['permissions'] = array(
         '#type' => 'link',
-        '#title' => t('Permissions'),
+        '#title' => t('permissions'),
         '#href' => 'admin/config/people/permissions',
         '#options' => array('fragment' => 'module-' . $filename, 'attributes' => array('class' => array('module-link', 'module-link-permissions'), 'title' => t('Configure permissions'))),
       );
     }
     // Generate link for module's configuration page, if the module provides
     // one.
     if ($module->status && isset($module->info['configure'])) {
       $configure_link = menu_get_item($module->info['configure']);
       if ($configure_link['access']) {
         $extra['links']['configure'] = array(
           '#type' => 'link',
-          '#title' => t('Configure'),
+          '#title' => t('configure'),
           '#href' => $configure_link['href'],
           '#options' => array('attributes' => array('class' => array('module-link', 'module-link-configure'), 'title' => $configure_link['description'])),
         );
       }
     }
 
     // Mark dependents disabled so the user cannot remove required modules.
     $dependents = array();
     // If this module is required by other modules, list those, and then make it
@@ -956,19 +956,21 @@ function _system_modules_build_row($info
   else {
     $form['enable'] = array(
       '#markup' =>  theme('image', array('path' => 'misc/watchdog-error.png', 'alt' => t('incompatible'), 'title' => $status_short)),
     );
     $form['description']['#markup'] .= theme('system_modules_incompatible', array('message' => $status_long));
   }
 
   // Build operation links.
   foreach (array('help', 'permissions', 'configure') as $key) {
-    $form['links'][$key] = (isset($extra['links'][$key]) ? $extra['links'][$key] : array());
+    if (isset($extra['links'][$key])) {
+      $form['links'][$key] = $extra['links'][$key];
+    }
   }
 
   return $form;
 }
 
 /**
  * Display confirmation form for required modules.
  *
  * @param $modules
