diff -urp --strip-trailing-cr ../category/category.inc ./category.inc
--- ../category/category.inc	2009-08-05 06:52:53.000000000 +0200
+++ ./category.inc	2009-09-29 23:32:28.000000000 +0200
@@ -247,7 +247,7 @@ function category_get_tree($cnid, $paren
 
   // We cache trees, so it's not CPU-intensive to call get_tree() on a category
   // and its children, too.
-  $cache_key = 'cat_get_tree'. $depth .':'. ($distant ? 'd' : 'n');
+  $cache_key = 'cat_get_tree'. ($distant ? 'd' : 'n');
   $data = category_cache_op('get', $cnid, $cache_key);
   if (isset($data)) {
     $children = $data['children'];
@@ -264,7 +264,7 @@ function category_get_tree($cnid, $paren
     $result = db_query(db_rewrite_sql('SELECT c.cid, c.cnid, c.weight, c.depth, h.parent, n.title, cn.admin_title FROM {category} c INNER JOIN {category_hierarchy} h ON c.cid = h.cid INNER JOIN {node} n ON c.cid = n.nid LEFT JOIN {category_cont} cn ON c.cid = cn.cid LEFT JOIN {category} c2 ON h.parent = c2.cid WHERE (c2.cid IS NOT NULL OR h.parent = 0) AND n.status = 1 '. $distant_sql .'ORDER BY c.weight, n.title', 'n', 'nid'), $cnid);
 
     while ($category = db_fetch_object($result)) {
-      if (!$distant && $depth == 0) {
+      if (!$distant) {
         $parent_cat = category_get_category($category->parent);
         if ($parent_cat->cid != $cnid && $parent_cat->cnid != $cnid) {
           $category->parent = $cnid;
diff -urp --strip-trailing-cr ../category/wrappers/taxonomy/taxonomy.module.php ./wrappers/taxonomy/taxonomy.module.php
--- ../category/wrappers/taxonomy/taxonomy.module.php	2009-08-05 06:52:54.000000000 +0200
+++ ./wrappers/taxonomy/taxonomy.module.php	2009-09-29 23:19:21.000000000 +0200
@@ -301,29 +301,36 @@ function taxonomy_del_term($tid, $nodeap
  *   If set, return only those vocabularies associated with this node type.
  */
 function taxonomy_get_vocabularies($type = NULL) {
-  if ($type) {
-    $result = db_query(db_rewrite_sql("SELECT v.vid, v.*, n.type FROM {vocabulary} v LEFT JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE n.type = '%s' ORDER BY v.weight, v.name", 'v', 'vid'), $type);
-  }
-  else {
-    $result = db_query(db_rewrite_sql('SELECT v.*, n.type FROM {vocabulary} v LEFT JOIN {vocabulary_node_types} n ON v.vid = n.vid ORDER BY v.weight, v.name', 'v', 'vid'));
-  }
+  $cache_key = 'tax_get_vocabs'. $type;
+  $vocabularies = category_cache_op('get', 0, $cache_key);
+  if (!isset($vocabularies)) {
 
-  $vocabularies = array();
-  $node_types = array();
-  while ($voc = db_fetch_object($result)) {
-    // If no node types are associated with a vocabulary, the LEFT JOIN will
-    // return a NULL value for type.
-    if (isset($voc->type)) {
-      $node_types[$voc->vid][$voc->type] = $voc->type;
-      unset($voc->type);
-      $voc->nodes = $node_types[$voc->vid];
+    if ($type) {
+      $result = db_query(db_rewrite_sql("SELECT v.vid, v.*, n.type FROM {vocabulary} v LEFT JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE n.type = '%s' ORDER BY v.weight, v.name", 'v', 'vid'), $type);
     }
-    elseif (!isset($voc->nodes)) {
-      $voc->nodes = array();
+    else {
+      $result = db_query(db_rewrite_sql('SELECT v.*, n.type FROM {vocabulary} v LEFT JOIN {vocabulary_node_types} n ON v.vid = n.vid ORDER BY v.weight, v.name', 'v', 'vid'));
     }
-    $vocabularies[$voc->vid] = $voc;
+
+    $vocabularies = array();
+    $node_types = array();
+    while ($voc = db_fetch_object($result)) {
+      // If no node types are associated with a vocabulary, the LEFT JOIN will
+      // return a NULL value for type.
+      if (isset($voc->type)) {
+        $node_types[$voc->vid][$voc->type] = $voc->type;
+        unset($voc->type);
+        $voc->nodes = $node_types[$voc->vid];
+      }
+      elseif (!isset($voc->nodes)) {
+        $voc->nodes = array();
+      }
+      $vocabularies[$voc->vid] = $voc;
+    }
+  category_cache_op('set', 0, $cache_key, $vocabularies);
   }
 
+
   return $vocabularies;
 }
 
@@ -331,10 +338,17 @@ function taxonomy_get_vocabularies($type
  * Find all terms associated with the given node, within one vocabulary.
  */
 function taxonomy_node_get_terms_by_vocabulary($node, $vid, $key = 'tid') {
-  $result = db_query(db_rewrite_sql('SELECT t.tid, t.* FROM {term_data} t INNER JOIN {term_node} r ON r.tid = t.tid WHERE t.vid = %d AND r.vid = %d ORDER BY weight', 't', 'tid'), $vid, $node->vid);
-  $terms = array();
-  while ($term = db_fetch_object($result)) {
-    $terms[$term->$key] = $term;
+  $cache_key = 'tax_node_get_terms_by_voc'. $node->vid .':'. $vid .':'. $key;
+  $terms = category_cache_op('get', $node->nid, $cache_key);
+  if (!isset($terms)) {
+
+    $result = db_query(db_rewrite_sql('SELECT t.tid, t.* FROM {term_data} t INNER JOIN {term_node} r ON r.tid = t.tid WHERE t.vid = %d AND r.vid = %d ORDER BY weight', 't', 'tid'), $vid, $node->vid);
+    $terms = array();
+    while ($term = db_fetch_object($result)) {
+      $terms[$term->$key] = $term;
+    }
+
+    category_cache_op('set', $node->nid, $cache_key, $terms);
   }
   return $terms;
 }
@@ -343,16 +357,20 @@ function taxonomy_node_get_terms_by_voca
  * Find all terms associated with the given node, ordered by vocabulary and term weight.
  */
 function taxonomy_node_get_terms($node, $key = 'tid') {
-  static $terms;
+  $cache_key = 'tax_node_get_terms'. $node->vid .':'. $key;
+  $terms = category_cache_op('get', $node->nid, $cache_key);
+  if (!isset($terms)) {
+
+    $terms = array();
 
-  if (!isset($terms[$node->vid][$key])) {
     $result = db_query(db_rewrite_sql('SELECT t.* FROM {term_node} r INNER JOIN {term_data} t ON r.tid = t.tid INNER JOIN {vocabulary} v ON t.vid = v.vid WHERE r.vid = %d ORDER BY v.weight, t.weight, t.name', 't', 'tid'), $node->vid);
-    $terms[$node->vid][$key] = array();
     while ($term = db_fetch_object($result)) {
-      $terms[$node->vid][$key][$term->$key] = $term;
+      $terms[$term->$key] = $term;
     }
+
+    category_cache_op('set', $node->nid, $cache_key, $terms);
   }
-  return $terms[$node->vid][$key];
+  return $terms;
 }
 
 /**
@@ -451,10 +469,17 @@ function taxonomy_node_type($op, $info) 
  */
 function taxonomy_get_related($tid, $key = 'tid') {
   if ($tid) {
-    $result = db_query('SELECT t.*, tid1, tid2 FROM {term_relation}, {term_data} t WHERE (t.tid = tid1 OR t.tid = tid2) AND (tid1 = %d OR tid2 = %d) AND t.tid != %d ORDER BY weight, name', $tid, $tid, $tid);
-    $related = array();
-    while ($term = db_fetch_object($result)) {
-      $related[$term->$key] = $term;
+    $cache_key = 'tax_get_related'. $key;
+    $related = category_cache_op('get', $tid, $cache_key);
+    if (!isset($related)) {
+
+      $result = db_query('SELECT t.*, tid1, tid2 FROM {term_relation}, {term_data} t WHERE (t.tid = tid1 OR t.tid = tid2) AND (tid1 = %d OR tid2 = %d) AND t.tid != %d ORDER BY weight, name', $tid, $tid, $tid);
+      $related = array();
+      while ($term = db_fetch_object($result)) {
+        $related[$term->$key] = $term;
+      }
+
+      category_cache_op('set', $tid, $cache_key, $related);
     }
     return $related;
   }
@@ -468,10 +493,17 @@ function taxonomy_get_related($tid, $key
  */
 function taxonomy_get_parents($tid, $key = 'tid') {
   if ($tid) {
-    $result = db_query(db_rewrite_sql('SELECT t.tid, t.* FROM {term_data} t INNER JOIN {term_hierarchy} h ON h.parent = t.tid WHERE h.tid = %d ORDER BY weight, name', 't', 'tid'), $tid);
-    $parents = array();
-    while ($parent = db_fetch_object($result)) {
-      $parents[$parent->$key] = $parent;
+    $cache_key = 'tax_get_parents'. $key;
+    $parents = category_cache_op('get', $tid, $cache_key);
+    if (!isset($parents)) {
+
+      $result = db_query(db_rewrite_sql('SELECT t.tid, t.* FROM {term_data} t INNER JOIN {term_hierarchy} h ON h.parent = t.tid WHERE h.tid = %d ORDER BY weight, name', 't', 'tid'), $tid);
+      $parents = array();
+      while ($parent = db_fetch_object($result)) {
+        $parents[$parent->$key] = $parent;
+      }
+
+      category_cache_op('set', $tid, $cache_key, $parents);
     }
     return $parents;
   }
@@ -500,15 +532,22 @@ function taxonomy_get_parents_all($tid) 
  * Find all children of a term ID.
  */
 function taxonomy_get_children($tid, $vid = 0, $key = 'tid') {
-  if ($vid) {
-    $result = db_query(db_rewrite_sql('SELECT t.* FROM {term_data} t INNER JOIN {term_hierarchy} h ON h.tid = t.tid WHERE t.vid = %d AND h.parent = %d ORDER BY weight, name', 't', 'tid'), $vid, $tid);
-  }
-  else {
-    $result = db_query(db_rewrite_sql('SELECT t.* FROM {term_data} t INNER JOIN {term_hierarchy} h ON h.tid = t.tid WHERE parent = %d ORDER BY weight, name', 't', 'tid'), $tid);
-  }
-  $children = array();
-  while ($term = db_fetch_object($result)) {
-    $children[$term->$key] = $term;
+  $cache_key = 'tax_get_children'. $vid .':'. $key;
+  $children = category_cache_op('get', $tid, $cache_key);
+  if (!isset($children)) {
+
+    if ($vid) {
+      $result = db_query(db_rewrite_sql('SELECT t.* FROM {term_data} t INNER JOIN {term_hierarchy} h ON h.tid = t.tid WHERE t.vid = %d AND h.parent = %d ORDER BY weight, name', 't', 'tid'), $vid, $tid);
+    }
+    else {
+      $result = db_query(db_rewrite_sql('SELECT t.* FROM {term_data} t INNER JOIN {term_hierarchy} h ON h.tid = t.tid WHERE parent = %d ORDER BY weight, name', 't', 'tid'), $tid);
+    }
+    $children = array();
+    while ($term = db_fetch_object($result)) {
+      $children[$term->$key] = $term;
+    }
+
+    category_cache_op('set', $tid, $cache_key, $children);
   }
   return $children;
 }
@@ -535,36 +574,45 @@ function taxonomy_get_children($tid, $vi
  *   Results are statically cached.
  */
 function taxonomy_get_tree($vid, $parent = 0, $depth = -1, $max_depth = NULL) {
-  static $children, $parents, $terms;
 
   $depth++;
 
   // We cache trees, so it's not CPU-intensive to call get_tree() on a term
   // and its children, too.
-  if (!isset($children[$vid])) {
-    $children[$vid] = array();
+  $cache_key = 'tax_get_tree';
+  $data = category_cache_op('get', $vid, $cache_key);
+  if (isset($data)) {
+    $children = $data['children'];
+    $terms = $data['terms'];
+    $parents = $data['parents'];
+  }
+  else {
+    $children = array();
+    $terms = array();
+    $parents = array();
 
     $result = db_query(db_rewrite_sql('SELECT t.tid, t.*, parent FROM {term_data} t INNER JOIN {term_hierarchy} h ON t.tid = h.tid WHERE t.vid = %d ORDER BY weight, name', 't', 'tid'), $vid);
     while ($term = db_fetch_object($result)) {
-      $children[$vid][$term->parent][] = $term->tid;
-      $parents[$vid][$term->tid][] = $term->parent;
-      $terms[$vid][$term->tid] = $term;
+      $children[$term->parent][] = $term->tid;
+      $parents[$term->tid][] = $term->parent;
+      $terms[$term->tid] = $term;
     }
+    category_cache_op('set', $vid, $cache_key, array('children' => $children, 'terms' => $terms, 'parents' => $parents));
   }
 
-  $max_depth = (is_null($max_depth)) ? count($children[$vid]) : $max_depth;
+  $max_depth = (is_null($max_depth)) ? count($children) : $max_depth;
   $tree = array();
-  if (!empty($children[$vid][$parent])) {
-    foreach ($children[$vid][$parent] as $child) {
+  if (!empty($children[$parent])) {
+    foreach ($children[$parent] as $child) {
       if ($max_depth > $depth) {
-        $term = drupal_clone($terms[$vid][$child]);
+        $term = drupal_clone($terms[$child]);
         $term->depth = $depth;
         // The "parent" attribute is not useful, as it would show one parent only.
         unset($term->parent);
-        $term->parents = $parents[$vid][$child];
+        $term->parents = $parents[$child];
         $tree[] = $term;
 
-        if (!empty($children[$vid][$child])) {
+        if (!empty($children[$child])) {
           $tree = array_merge($tree, taxonomy_get_tree($vid, $child, $depth, $max_depth));
         }
       }
@@ -579,10 +627,17 @@ function taxonomy_get_tree($vid, $parent
  */
 function taxonomy_get_synonyms($tid) {
   if ($tid) {
-    $synonyms = array();
-    $result = db_query('SELECT name FROM {term_synonym} WHERE tid = %d', $tid);
-    while ($synonym = db_fetch_array($result)) {
-      $synonyms[] = $synonym['name'];
+    $cache_key = 'tax_get_synonyms';
+    $synonyms = category_cache_op('get', $tid, $cache_key);
+    if (!isset($synonyms)) {
+
+      $synonyms = array();
+      $result = db_query('SELECT name FROM {term_synonym} WHERE tid = %d', $tid);
+      while ($synonym = db_fetch_array($result)) {
+        $synonyms[] = $synonym['name'];
+      }
+
+    category_cache_op('set', $tid, $cache_key, $synonyms);
     }
     return $synonyms;
   }
@@ -613,9 +668,10 @@ function taxonomy_get_synonym_root($syno
  *   Results are statically cached.
  */
 function taxonomy_term_count_nodes($tid, $type = 0) {
-  static $count;
+  $cache_key = 'tax_term_count_nodes'. $type;
+  $count = category_cache_op('get', 0, $cache_key);
+  if (!isset($count)) {
 
-  if (!isset($count[$type])) {
     // $type == 0 always evaluates TRUE if $type is a string
     if (is_numeric($type)) {
       $result = db_query(db_rewrite_sql('SELECT t.tid, COUNT(n.nid) AS c FROM {term_node} t INNER JOIN {node} n ON t.vid = n.vid WHERE n.status = 1 GROUP BY t.tid'));
@@ -624,14 +680,17 @@ function taxonomy_term_count_nodes($tid,
       $result = db_query(db_rewrite_sql("SELECT t.tid, COUNT(n.nid) AS c FROM {term_node} t INNER JOIN {node} n ON t.vid = n.vid WHERE n.status = 1 AND n.type = '%s' GROUP BY t.tid"), $type);
     }
     while ($term = db_fetch_object($result)) {
-      $count[$type][$term->tid] = $term->c;
+      $count[$term->tid] = $term->c;
     }
+
+    category_cache_op('set', 0, $cache_key, $count);
   }
+
   $children_count = 0;
   foreach (_taxonomy_term_children($tid) as $c) {
     $children_count += taxonomy_term_count_nodes($c, $type);
   }
-  return $children_count + (isset($count[$type][$tid]) ? $count[$type][$tid] : 0);
+  return $children_count + (isset($count[$tid]) ? $count[$tid] : 0);
 }
 
 /**
@@ -647,13 +706,14 @@ function taxonomy_term_count_nodes($tid,
  *
  */
 function _taxonomy_term_children($tid) {
-  static $children;
-
+  $cache_key = 'tax_term_childr';
+  $children = category_cache_op('get', 0, $cache_key);
   if (!isset($children)) {
     $result = db_query('SELECT tid, parent FROM {term_hierarchy}');
     while ($term = db_fetch_object($result)) {
       $children[$term->parent][] = $term->tid;
     }
+    category_cache_op('set', 0, $cache_key, $children);
   }
   return isset($children[$tid]) ? $children[$tid] : array();
 }
@@ -691,12 +751,13 @@ function taxonomy_get_term_by_name($name
  *   Results are statically cached.
  */
 function taxonomy_vocabulary_load($vid) {
-  static $vocabularies = array();
+  $cache_key = 'tax_vocab_load';
+  $vocab = category_cache_op('get', $vid, $cache_key);
+  if (!isset($vocab)) {
 
-  if (!isset($vocabularies[$vid])) {
     // Initialize so if this vocabulary does not exist, we have
     // that cached, and we will not try to load this later.
-    $vocabularies[$vid] = FALSE;
+    $vocab = FALSE;
     // Try to load the data and fill up the object.
     $result = db_query('SELECT v.*, n.type FROM {vocabulary} v LEFT JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE v.vid = %d', $vid);
     $node_types = array();
@@ -706,12 +767,13 @@ function taxonomy_vocabulary_load($vid) 
       }
       unset($voc->type);
       $voc->nodes = $node_types;
-      $vocabularies[$vid] = $voc;
+      $vocab = $voc;
     }
+    category_cache_op('set', $vid, $cache_key, $vocab);
   }
 
   // Return NULL if this vocabulary does not exist.
-  return !empty($vocabularies[$vid]) ? $vocabularies[$vid] : NULL;
+  return !empty($vocab) ? $vocab : NULL;
 }
 
 /**
@@ -724,13 +786,14 @@ function taxonomy_vocabulary_load($vid) 
  *   A term object. Results are statically cached.
  */
 function taxonomy_get_term($tid) {
-  static $terms = array();
-
-  if (!isset($terms[$tid])) {
-    $terms[$tid] = db_fetch_object(db_query('SELECT * FROM {term_data} WHERE tid = %d', $tid));
+  $cache_key = 'tax_get_term';
+  $term = category_cache_op('get', $tid, $cache_key);
+  if (!isset($term)) {
+    $term = db_fetch_object(db_query('SELECT * FROM {term_data} WHERE tid = %d', $tid));
+    category_cache_op('set', $tid, $cache_key, $term);
   }
 
-  return $terms[$tid];
+  return $term;
 }
 
 /**
