diff --git a/modules/node.module b/modules/node.module
index 4cf89859d4c41e798d5a5374e8129eaa5394ea06..0bc004aca3e021faafcee27484c9c89d4e8bf3aa 100644
--- a/modules/node.module
+++ b/modules/node.module
@@ -744,7 +744,7 @@ function node_search($op = 'search', $keys = null) {
       $form['advanced']['keywords']['negative'] = array('#type' => 'textfield', '#title' => t('Containing none of the words'), '#size' => 30, '#maxlength' => 255);
 
       // Taxonomy box
-      if ($taxonomy = module_invoke('taxonomy', 'form_all')) {
+      if ($taxonomy = module_invoke('taxonomy', 'form_all', 1)) {
         $form['advanced']['category'] = array('#type' => 'select', '#title' => t('Only in the category'), '#prefix' => '<div class="criterium">', '#suffix' => '</div>', '#options' => $taxonomy, '#extra' => 'size="10"', '#multiple' => true);
       }
 
@@ -938,9 +938,9 @@ function node_last_changed($nid) {
   return ($node->changed);
 }
 
-/*
-** Node operations
-*/
+/**
+ * List node administration operations that can be performed.
+ */
 function node_operations() {
   $operations = array(
     'approve' =>   array(t('Approve the selected posts'), 'UPDATE {node} SET status = 1, moderate = 0 WHERE nid = %d'),
@@ -953,70 +953,82 @@ function node_operations() {
   return $operations;
 }
 
-/*
-** Filters
-*/
+/**
+ * List node administration filters that can be applied.
+ */
 function node_filters() {
   // Regular filters
-  $filters = array(
-    'status'   => array('title' => t('status'),
-                        'options' => array('status-1'   => t('published'),     'status-0' => t('not published'),
-                                           'moderate-1' => t('in moderation'), 'moderate-0' => t('not in moderation'),
-                                           'promote-1'  => t('promoted'),      'promote-0' => t('not promoted'),
-                                           'sticky-1'   => t('sticky'),        'sticky-0' => t('not sticky'))),
-    'type'     => array('title' => t('type'), 'where' => "n.type = '%s'",
-                        'options' => node_get_types()));
-  // Merge all vocabularies into one for retrieving $value below
-  if ($taxonomy = module_invoke('taxonomy', 'form_all')) {
-    $terms = array();
-    foreach ($taxonomy as $value) {
-      $terms = $terms + $value;
-    }
-    $filters['category'] = array('title' => t('category'), 'where' => 'tn.tid = %d',
-                                 'options' => $terms, 'join' => 'INNER JOIN {term_node} tn ON n.nid = tn.nid');
-  }
-  if (isset($filters['category'])) {
-    $filters['category']['options'] = $taxonomy;
+  $filters['status'] = array('title' => t('status'),
+    'options' => array('status-1'   => t('published'),     'status-0' => t('not published'),
+                       'moderate-1' => t('in moderation'), 'moderate-0' => t('not in moderation'),
+                       'promote-1'  => t('promoted'),      'promote-0' => t('not promoted'),
+                       'sticky-1'   => t('sticky'),        'sticky-0' => t('not sticky')));
+  $filters['type'] = array('title' => t('type'), 'options' => node_get_types());
+  // The taxonomy filter
+  if ($taxonomy = module_invoke('taxonomy', 'form_all', 1)) {
+    $filters['category'] = array('title' => t('category'), 'options' => $taxonomy);
   }
 
   return $filters;
 }
 
+/**
+ * Build query for node administration filters based on session.
+ */
 function node_build_filter_query() {
   $filters = node_filters();
 
   // Build query
   $where = $args = array();
   $join = '';
-  foreach ($_SESSION['node_overview_filter'] as $filter) {
+  foreach ($_SESSION['node_overview_filter'] as $index => $filter) {
     list($key, $value) = $filter;
-    if ($key == 'status') {
-      // Note: no exploit hole as $value has already been checked
-      list($key, $value) = explode('-', $value, 2);
-      $where[] = 'n.'. $key .' = %d';
-    }
-    else {
-      $where[] = $filters[$key]['where'];
+    switch($key) {
+      case 'status':
+        // Note: no exploitable hole as $key/$value have already been checked when submitted
+        list($key, $value) = explode('-', $value, 2);
+        $where[] = 'n.'. $key .' = %d';
+        break;
+      case 'category':
+        $table = "tn$index";
+        $where[] = "$table.tid = %d";
+        $join .= "INNER JOIN {term_node} $table ON n.nid = $table.nid ";
+        break;
+      case 'type':
+        $where[] = "n.type = '%s'";
     }
     $args[] = $value;
-    $join .= $filters[$key]['join'];
   }
   $where = count($where) ? 'WHERE '. implode(' AND ', $where) : '';
 
   return array('where' => $where, 'join' => $join, 'args' => $args);
 }
 
+/**
+ * Return form for node administration filters.
+ */
 function node_filter_form() {
   $session = &$_SESSION['node_overview_filter'];
   $session = is_array($session) ? $session : array();
   $filters = node_filters();
 
   $i = 0;
-  $form['filters'] = array('#type' => 'fieldset', '#title' => t('Show only items where'), '#theme' => 'node_filters');
+  $form['filters'] = array('#type' => 'fieldset',
+    '#title' => t('Show only items where'),
+    '#theme' => 'node_filters',
+  );
   foreach ($session as $filter) {
     list($type, $value) = $filter;
+    if ($type == 'category') {
+      // Load term name from DB rather than search and parse options array.
+      $value = module_invoke('taxonomy', 'get_term', $value);
+      $value = $value->name;
+    }
+    else {
+      $value = $filters[$type]['options'][$value];
+    }
     $string = ($i++ ? '<em>and</em> where <strong>%a</strong> is <strong>%b</strong>' : '<strong>%a</strong> is <strong>%b</strong>');
-    $form['filters']['current'][] = array('#value' => t($string, array('%a' => $filters[$type]['title'] , '%b' => $filters[$type]['options'][$value])));
+    $form['filters']['current'][] = array('#value' => t($string, array('%a' => $filters[$type]['title'] , '%b' => $value)));
   }
 
   foreach ($filters as $key => $filter) {
@@ -1034,6 +1046,9 @@ function node_filter_form() {
   return drupal_get_form('node_filter_form', $form);
 }
 
+/**
+ * Theme node administration filter form.
+ */
 function theme_node_filter_form(&$form) {
   $output .= '<div id="node-admin-filter">';
   $output .= form_render($form['filters']);
@@ -1042,6 +1057,9 @@ function theme_node_filter_form(&$form) {
   return $output;
 }
 
+/**
+ * Theme node administraton filter selector.
+ */
 function theme_node_filters(&$form) {
   $output .= '<ul>';
   if (sizeof($form['current'])) {
@@ -1051,14 +1069,14 @@ function theme_node_filters(&$form) {
   }
 
   $output .= '<li><dl class="multiselect">' . (sizeof($form['current']) ? '<dt><em>'. t('and') .'</em> '. t('where') .'</dt>' : '') . '<dd class="a">';
-  foreach(element_children($form['filter']) as $key) {
+  foreach (element_children($form['filter']) as $key) {
     $output .= form_render($form['filter'][$key]);
   }
   $output .= '</dd>';
 
   $output .= '<dt>'. t('is') .'</dt>' . '<dd class="b">';
 
-  foreach(element_children($form['status']) as $key) {
+  foreach (element_children($form['status']) as $key) {
     $output .= form_render($form['status'][$key]);
   }
   $output .= '</dd>';
@@ -1070,15 +1088,23 @@ function theme_node_filters(&$form) {
   return $output;
 }
 
+/**
+ * Process result from node administration filter form.
+ */
 function node_filter_form_submit() {
   global $form_values;
   $op = $_POST['op'];
   $filters = node_filters();
   switch ($op) {
-    case t('Filter'): case t('Refine'):
+    case t('Filter'):
+    case t('Refine'):
       if (isset($form_values['filter'])) {
         $filter = $form_values['filter'];
-        if (isset($filters[$filter]['options'][$form_values[$filter]])) {
+
+        // Flatten the options array to accomodate hierarchical/nested options.
+        $flat_options = form_options_flatten($filters[$filter]['options']);
+
+        if (isset($flat_options[$form_values[$filter]])) {
           $_SESSION['node_overview_filter'][] = array($filter, $form_values[$filter]);
         }
       }
@@ -1127,6 +1153,9 @@ function node_admin_nodes_validate($form_id, $edit) {
   }
 }
 
+/**
+ * Menu callback: content administration.
+ */
 function node_admin_nodes() {
   global $form_values;
   $output = node_filter_form();
@@ -1139,9 +1168,10 @@ function node_admin_nodes() {
 
   $result = pager_query('SELECT n.*, u.name, u.uid FROM {node} n '. $filter['join'] .' INNER JOIN {users} u ON n.uid = u.uid '. $filter['where'] .' ORDER BY n.changed DESC', 50, 0, NULL, $filter['args']);
 
-  $form['options'] = array(
-    '#type' => 'fieldset', '#title' => t('Update options'),
-    '#prefix' => "<div class=\"container-inline\">" , '#suffix' => "</div>"
+  $form['options'] = array('#type' => 'fieldset',
+    '#title' => t('Update options'),
+    '#prefix' => '<div class="container-inline">',
+    '#suffix' => '</div>',
   );
   $options = array();
   foreach (node_operations() as $key => $value) {
@@ -1171,6 +1201,9 @@ function node_admin_nodes() {
   return $output;
 }
 
+/**
+ * Theme node administration overview.
+ */
 function theme_node_admin_nodes($form) {
   // Overview table:
   $header = array(NULL, t('Title'), t('Type'), t('Author'), t('Status'), t('Operations'));
@@ -1207,7 +1240,7 @@ function node_multiple_delete_confirm() {
   $edit = $_POST['edit'];
 
   $form['nodes'] = array('#prefix' => '<ul>', '#suffix' => '</ul>', '#tree' => TRUE);
-  // array filter returns only elements with true values
+  // array_filter returns only elements with true values
   foreach (array_filter($edit['nodes']) as $nid => $value) {
     $title = db_result(db_query('SELECT title FROM {node} WHERE nid = %d', $nid));
     $form['nodes'][$nid] = array('#type' => 'hidden', '#value' => $nid, '#prefix' => '<li>', '#suffix' => check_plain($title) ."</li>\n");
@@ -1274,7 +1307,6 @@ function node_revision_overview($node) {
 
   $revisions = node_revision_list($node);
 
-  $i = 0;
   $rows = array();
   $revert_permission = FALSE;
   if ((user_access('revert revisions') || user_access('administer nodes')) && node_access('update', $node)) {
diff --git a/modules/node/node.module b/modules/node/node.module
index 4cf89859d4c41e798d5a5374e8129eaa5394ea06..0bc004aca3e021faafcee27484c9c89d4e8bf3aa 100644
--- a/modules/node/node.module
+++ b/modules/node/node.module
@@ -744,7 +744,7 @@ function node_search($op = 'search', $keys = null) {
       $form['advanced']['keywords']['negative'] = array('#type' => 'textfield', '#title' => t('Containing none of the words'), '#size' => 30, '#maxlength' => 255);
 
       // Taxonomy box
-      if ($taxonomy = module_invoke('taxonomy', 'form_all')) {
+      if ($taxonomy = module_invoke('taxonomy', 'form_all', 1)) {
         $form['advanced']['category'] = array('#type' => 'select', '#title' => t('Only in the category'), '#prefix' => '<div class="criterium">', '#suffix' => '</div>', '#options' => $taxonomy, '#extra' => 'size="10"', '#multiple' => true);
       }
 
@@ -938,9 +938,9 @@ function node_last_changed($nid) {
   return ($node->changed);
 }
 
-/*
-** Node operations
-*/
+/**
+ * List node administration operations that can be performed.
+ */
 function node_operations() {
   $operations = array(
     'approve' =>   array(t('Approve the selected posts'), 'UPDATE {node} SET status = 1, moderate = 0 WHERE nid = %d'),
@@ -953,70 +953,82 @@ function node_operations() {
   return $operations;
 }
 
-/*
-** Filters
-*/
+/**
+ * List node administration filters that can be applied.
+ */
 function node_filters() {
   // Regular filters
-  $filters = array(
-    'status'   => array('title' => t('status'),
-                        'options' => array('status-1'   => t('published'),     'status-0' => t('not published'),
-                                           'moderate-1' => t('in moderation'), 'moderate-0' => t('not in moderation'),
-                                           'promote-1'  => t('promoted'),      'promote-0' => t('not promoted'),
-                                           'sticky-1'   => t('sticky'),        'sticky-0' => t('not sticky'))),
-    'type'     => array('title' => t('type'), 'where' => "n.type = '%s'",
-                        'options' => node_get_types()));
-  // Merge all vocabularies into one for retrieving $value below
-  if ($taxonomy = module_invoke('taxonomy', 'form_all')) {
-    $terms = array();
-    foreach ($taxonomy as $value) {
-      $terms = $terms + $value;
-    }
-    $filters['category'] = array('title' => t('category'), 'where' => 'tn.tid = %d',
-                                 'options' => $terms, 'join' => 'INNER JOIN {term_node} tn ON n.nid = tn.nid');
-  }
-  if (isset($filters['category'])) {
-    $filters['category']['options'] = $taxonomy;
+  $filters['status'] = array('title' => t('status'),
+    'options' => array('status-1'   => t('published'),     'status-0' => t('not published'),
+                       'moderate-1' => t('in moderation'), 'moderate-0' => t('not in moderation'),
+                       'promote-1'  => t('promoted'),      'promote-0' => t('not promoted'),
+                       'sticky-1'   => t('sticky'),        'sticky-0' => t('not sticky')));
+  $filters['type'] = array('title' => t('type'), 'options' => node_get_types());
+  // The taxonomy filter
+  if ($taxonomy = module_invoke('taxonomy', 'form_all', 1)) {
+    $filters['category'] = array('title' => t('category'), 'options' => $taxonomy);
   }
 
   return $filters;
 }
 
+/**
+ * Build query for node administration filters based on session.
+ */
 function node_build_filter_query() {
   $filters = node_filters();
 
   // Build query
   $where = $args = array();
   $join = '';
-  foreach ($_SESSION['node_overview_filter'] as $filter) {
+  foreach ($_SESSION['node_overview_filter'] as $index => $filter) {
     list($key, $value) = $filter;
-    if ($key == 'status') {
-      // Note: no exploit hole as $value has already been checked
-      list($key, $value) = explode('-', $value, 2);
-      $where[] = 'n.'. $key .' = %d';
-    }
-    else {
-      $where[] = $filters[$key]['where'];
+    switch($key) {
+      case 'status':
+        // Note: no exploitable hole as $key/$value have already been checked when submitted
+        list($key, $value) = explode('-', $value, 2);
+        $where[] = 'n.'. $key .' = %d';
+        break;
+      case 'category':
+        $table = "tn$index";
+        $where[] = "$table.tid = %d";
+        $join .= "INNER JOIN {term_node} $table ON n.nid = $table.nid ";
+        break;
+      case 'type':
+        $where[] = "n.type = '%s'";
     }
     $args[] = $value;
-    $join .= $filters[$key]['join'];
   }
   $where = count($where) ? 'WHERE '. implode(' AND ', $where) : '';
 
   return array('where' => $where, 'join' => $join, 'args' => $args);
 }
 
+/**
+ * Return form for node administration filters.
+ */
 function node_filter_form() {
   $session = &$_SESSION['node_overview_filter'];
   $session = is_array($session) ? $session : array();
   $filters = node_filters();
 
   $i = 0;
-  $form['filters'] = array('#type' => 'fieldset', '#title' => t('Show only items where'), '#theme' => 'node_filters');
+  $form['filters'] = array('#type' => 'fieldset',
+    '#title' => t('Show only items where'),
+    '#theme' => 'node_filters',
+  );
   foreach ($session as $filter) {
     list($type, $value) = $filter;
+    if ($type == 'category') {
+      // Load term name from DB rather than search and parse options array.
+      $value = module_invoke('taxonomy', 'get_term', $value);
+      $value = $value->name;
+    }
+    else {
+      $value = $filters[$type]['options'][$value];
+    }
     $string = ($i++ ? '<em>and</em> where <strong>%a</strong> is <strong>%b</strong>' : '<strong>%a</strong> is <strong>%b</strong>');
-    $form['filters']['current'][] = array('#value' => t($string, array('%a' => $filters[$type]['title'] , '%b' => $filters[$type]['options'][$value])));
+    $form['filters']['current'][] = array('#value' => t($string, array('%a' => $filters[$type]['title'] , '%b' => $value)));
   }
 
   foreach ($filters as $key => $filter) {
@@ -1034,6 +1046,9 @@ function node_filter_form() {
   return drupal_get_form('node_filter_form', $form);
 }
 
+/**
+ * Theme node administration filter form.
+ */
 function theme_node_filter_form(&$form) {
   $output .= '<div id="node-admin-filter">';
   $output .= form_render($form['filters']);
@@ -1042,6 +1057,9 @@ function theme_node_filter_form(&$form) {
   return $output;
 }
 
+/**
+ * Theme node administraton filter selector.
+ */
 function theme_node_filters(&$form) {
   $output .= '<ul>';
   if (sizeof($form['current'])) {
@@ -1051,14 +1069,14 @@ function theme_node_filters(&$form) {
   }
 
   $output .= '<li><dl class="multiselect">' . (sizeof($form['current']) ? '<dt><em>'. t('and') .'</em> '. t('where') .'</dt>' : '') . '<dd class="a">';
-  foreach(element_children($form['filter']) as $key) {
+  foreach (element_children($form['filter']) as $key) {
     $output .= form_render($form['filter'][$key]);
   }
   $output .= '</dd>';
 
   $output .= '<dt>'. t('is') .'</dt>' . '<dd class="b">';
 
-  foreach(element_children($form['status']) as $key) {
+  foreach (element_children($form['status']) as $key) {
     $output .= form_render($form['status'][$key]);
   }
   $output .= '</dd>';
@@ -1070,15 +1088,23 @@ function theme_node_filters(&$form) {
   return $output;
 }
 
+/**
+ * Process result from node administration filter form.
+ */
 function node_filter_form_submit() {
   global $form_values;
   $op = $_POST['op'];
   $filters = node_filters();
   switch ($op) {
-    case t('Filter'): case t('Refine'):
+    case t('Filter'):
+    case t('Refine'):
       if (isset($form_values['filter'])) {
         $filter = $form_values['filter'];
-        if (isset($filters[$filter]['options'][$form_values[$filter]])) {
+
+        // Flatten the options array to accomodate hierarchical/nested options.
+        $flat_options = form_options_flatten($filters[$filter]['options']);
+
+        if (isset($flat_options[$form_values[$filter]])) {
           $_SESSION['node_overview_filter'][] = array($filter, $form_values[$filter]);
         }
       }
@@ -1127,6 +1153,9 @@ function node_admin_nodes_validate($form_id, $edit) {
   }
 }
 
+/**
+ * Menu callback: content administration.
+ */
 function node_admin_nodes() {
   global $form_values;
   $output = node_filter_form();
@@ -1139,9 +1168,10 @@ function node_admin_nodes() {
 
   $result = pager_query('SELECT n.*, u.name, u.uid FROM {node} n '. $filter['join'] .' INNER JOIN {users} u ON n.uid = u.uid '. $filter['where'] .' ORDER BY n.changed DESC', 50, 0, NULL, $filter['args']);
 
-  $form['options'] = array(
-    '#type' => 'fieldset', '#title' => t('Update options'),
-    '#prefix' => "<div class=\"container-inline\">" , '#suffix' => "</div>"
+  $form['options'] = array('#type' => 'fieldset',
+    '#title' => t('Update options'),
+    '#prefix' => '<div class="container-inline">',
+    '#suffix' => '</div>',
   );
   $options = array();
   foreach (node_operations() as $key => $value) {
@@ -1171,6 +1201,9 @@ function node_admin_nodes() {
   return $output;
 }
 
+/**
+ * Theme node administration overview.
+ */
 function theme_node_admin_nodes($form) {
   // Overview table:
   $header = array(NULL, t('Title'), t('Type'), t('Author'), t('Status'), t('Operations'));
@@ -1207,7 +1240,7 @@ function node_multiple_delete_confirm() {
   $edit = $_POST['edit'];
 
   $form['nodes'] = array('#prefix' => '<ul>', '#suffix' => '</ul>', '#tree' => TRUE);
-  // array filter returns only elements with true values
+  // array_filter returns only elements with true values
   foreach (array_filter($edit['nodes']) as $nid => $value) {
     $title = db_result(db_query('SELECT title FROM {node} WHERE nid = %d', $nid));
     $form['nodes'][$nid] = array('#type' => 'hidden', '#value' => $nid, '#prefix' => '<li>', '#suffix' => check_plain($title) ."</li>\n");
@@ -1274,7 +1307,6 @@ function node_revision_overview($node) {
 
   $revisions = node_revision_list($node);
 
-  $i = 0;
   $rows = array();
   $revert_permission = FALSE;
   if ((user_access('revert revisions') || user_access('administer nodes')) && node_access('update', $node)) {