diff -urp --strip-trailing-cr ../category/category_display/category_display.module ./category_display/category_display.module
--- ../category/category_display/category_display.module	2009-05-31 11:15:03.000000000 +0200
+++ ./category_display/category_display.module	2009-06-07 22:03:27.000000000 +0200
@@ -69,24 +69,14 @@ function category_display_nodeapi(&$node
 
     case 'prepare':
       $behavior = variable_get('category_behavior_'. $node->type, 0);
-      if (!empty($behavior)) {
-        $links_for_cats = $_POST['category']['menu']['links_for_cats'];
-        $toc_for_cats = $_POST['category']['display']['toc_for_cats'];
-        $show_listing = $_POST['category']['display']['show_listing'];
+      if (!empty($behavior) && $behavior == 'container') {
 
         // Prepare defaults for the add/edit form.
         if (empty($node->category_menu)) {
           $node->category_menu = array();
         }
-
-        if (isset($_POST['category']['menu']['links_for_cats'])) {
-          $node->category_menu['links_for_cats'] = $links_for_cats;
-        }
-        if (isset($_POST['category']['display']['toc_for_cats'])) {
-          $node->category_display['toc_for_cats'] = $toc_for_cats;
-        }
-        if (isset($_POST['category']['display']['show_listing'])) {
-          $node->category_display['show_listing'] = $show_listing;
+        if (empty($node->category_display)) {
+          $node->category_display = _category_display_defaults();
         }
       }
       break;
@@ -94,8 +84,6 @@ function category_display_nodeapi(&$node
     case 'insert':
     case 'update':
       $behavior = variable_get('category_behavior_'. $node->type, 0);
-      _category_display_flatten_values($node);
-
       if (!empty($behavior) && $behavior == 'container') {
         category_display_save_container($node);
       }
@@ -125,6 +113,7 @@ function category_display_form_alter(&$f
 
     if (!empty($behavior) && $behavior == 'container') {
       $form['category']['display'] = _category_display_form_elements($node);
+      $form['#submit'][] = 'category_display_node_form_submit';
     }
   }
 }
@@ -278,6 +267,31 @@ function _category_display_form_elements
 }
 
 /**
+ * Additional form submit handler for node forms.
+ *
+ * Flattens the $form_state['values']['category']['display'] array
+ * on both submits and previews.
+ */
+function category_display_node_form_submit($form, &$form_state) {
+  $fieldsets = array(
+    'display' => TRUE,
+  );
+  if (!empty($form_state['values']['category']) && is_array($form_state['values']['category'])) {
+    foreach ($form_state['values']['category'] as $key => $value) {
+      if (isset($fieldsets[$key]) && is_array($value)) {
+        $fieldset = 'category_'. $key;
+        if (empty($form_state['values'][$fieldset])) {
+          $form_state['values'][$fieldset] = array();
+        }
+        $form_state['values'][$fieldset] = $value + $form_state['values'][$fieldset];
+
+        unset($form_state['values']['category'][$key]);
+      }
+    }
+  }
+}
+
+/**
  * Implementation of hook_category_legacy().
  */
 function category_display_category_legacy($op, &$vocabularies, $edit = NULL) {
@@ -312,6 +326,9 @@ function category_display_get_container(
   if ($container = db_fetch_object($result)) {
     return $container;
   }
+  else {
+    return (object) _category_display_defaults();
+  }
 }
 
 /**
@@ -349,6 +366,21 @@ function category_display_del_container(
 }
 
 /**
+ * Helper function to provide default settings for new containers.
+ */
+function _category_display_defaults() {
+  return array(
+    'navlinks'      => 0,
+    'toc_for_cats'  => 0,
+    'toc_depth'     => 0,
+    'toc_nodecount' => 0,
+    'nodelinks'     => 1,
+    'show_listing'  => 1,
+    'emptymsg'      => 1,
+  );
+}
+
+/**
  * Process variables for category-display-navigation.tpl.php.
  *
  * The $variables array contains the following arguments:
@@ -836,25 +868,3 @@ function theme_category_display_menu_ite
 
   return $output;
 }
-
-/**
- * Helper function to flatten the $node->category['display'] array.
- */
-function _category_display_flatten_values(&$node) {
-  $fieldsets = array(
-    'display' => TRUE,
-  );
-  if (!empty($node->category) && is_array($node->category)) {
-    foreach ($node->category as $key => $value) {
-      if (isset($fieldsets[$key]) && is_array($value)) {
-        $fieldset = 'category_'. $key;
-        if (empty($node->$fieldset)) {
-          $node->$fieldset = array();
-        }
-        $node->$fieldset += $value;
-
-        unset($node->category[$key]);
-      }
-    }
-  }
-}
diff -urp --strip-trailing-cr ../category/category_menu/category_menu.module ./category_menu/category_menu.module
--- ../category/category_menu/category_menu.module	2009-05-31 12:24:23.000000000 +0200
+++ ./category_menu/category_menu.module	2009-06-07 22:33:16.000000000 +0200
@@ -71,42 +71,17 @@ function category_menu_nodeapi(&$node, $
 
     case 'prepare':
       $behavior = variable_get('category_behavior_'. $node->type, 0);
-      if (!empty($behavior)) {
-        $links_for_nodes = $_POST['category']['menu']['links_for_nodes'];
-        $container_has_parent_link = $_POST['category']['menu']['container_has_parent_link'];
-
+      if (!empty($behavior) && $behavior == 'container') {
         // Prepare defaults for the add/edit form.
         if (empty($node->category_menu)) {
           $node->category_menu = array();
         }
-
-        if (!empty($links_for_nodes) && is_array($links_for_nodes)) {
-          $links_for_nodes = array_intersect_key(node_get_types('names'), $links_for_nodes);
-          foreach (array_keys($links_for_nodes) as $node_type) {
-            $links_for_nodes[$node_type] = $node_type;
-          }
-          $node->category_menu['links_for_nodes'] = $links_for_nodes;
-        }
-        if (isset($_POST['category']['menu']['container_has_parent_link'])) {
-          $node->category_menu['container_has_parent_link'] = $container_has_parent_link;
-        }
-
-        if (!isset($node->category_menu['container_has_parent_link'])) {
-          $node->category_menu['container_has_parent_link'] = !empty($node->category_menu['plid_for_container']);
-        }
-        if (!empty($node->category_menu['plid_for_container'])) {
-          $item = db_fetch_array(db_query("SELECT m.*, ml.* FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path WHERE ml.mlid = %d", $node->category_menu['plid_for_container']));
-          $node->category_menu['plid_value_for_container'] = $node->category_menu['plid_for_container'];
-          $node->category_menu['plid_for_container'] = $item['menu_name'] .':'. $node->category_menu['plid_for_container'];
-        }
       }
       break;
 
     case 'insert':
     case 'update':
       $behavior = variable_get('category_behavior_'. $node->type, 0);
-      _category_menu_flatten_values($node);
-
       if (!empty($behavior) && $behavior == 'container') {
         category_menu_save_container($node);
       }
@@ -116,7 +91,6 @@ function category_menu_nodeapi(&$node, $
 
     case 'delete':
       $behavior = variable_get('category_behavior_'. $node->type, 0);
-
       if (!empty($behavior) && $behavior == 'container') {
         category_menu_del_container($node->nid);
       }
@@ -149,6 +123,17 @@ function category_menu_form_alter(&$form
     $behavior = variable_get('category_behavior_'. $node->type, 0);
 
     if (!empty($behavior) && $behavior == 'container') {
+      // Prepare existing settings
+      if (!isset($node->category_menu['container_has_parent_link'])) {
+        $node->category_menu['container_has_parent_link'] = !empty($node->category_menu['plid_for_container']);
+      }
+      if (!empty($node->category_menu['plid_for_container'])) {
+        $item = db_fetch_array(db_query("SELECT m.*, ml.* FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path WHERE ml.mlid = %d", $node->category_menu['plid_for_container']));
+        $node->category_menu['plid_value_for_container'] = $node->category_menu['plid_for_container'];
+        $node->category_menu['plid_for_container'] = $item['menu_name'] .':'. $node->category_menu['plid_for_container'];
+      }
+
+      $form['#submit'][] = 'category_menu_node_form_submit';
       $form['category']['menu'] = array(
         '#type' => 'fieldset',
         '#title' => t('Menu links'),
@@ -197,21 +182,23 @@ function category_menu_form_alter(&$form
 
         $default_options = array();
         $taken_options = array();
-        if (!empty($node->category_menu['links_for_nodes'])) {
-          $default_options = $node->category_menu['links_for_nodes'];
-        }
-        else {
-          foreach (array_keys($nodes_options) as $type) {
-            $type_setting = variable_get('category_menu_links_'. $type, 0);
-            if (!empty($type_setting)) {
-              if ($type_setting == $node->nid) {
+        $is_preset = !empty($node->category_menu['links_for_nodes']);
+        foreach (array_keys($nodes_options) as $type) {
+          $type_setting = variable_get('category_menu_links_'. $type, 0);
+          $was_selected = ($is_preset && !empty($node->category_menu['links_for_nodes'][$type]));
+          if (!empty($type_setting)) {
+            if ($type_setting == $node->nid) {
+              if (!$is_preset || $was_selected) {
                 $default_options[$type] = $type;
               }
-              else {
-                $taken_options[$type] = $type;
-              }
+            }
+            else {
+              $taken_options[$type] = $type;
             }
           }
+          else if ($was_selected) {
+            $default_options[$type] = $type;
+          }
         }
         $category_link['links_for_nodes'] = $nodes_options;
         $category_link['links_selected'] = $default_options;
@@ -304,6 +291,37 @@ function category_menu_form_alter(&$form
 }
 
 /**
+ * Additional form submit handler for node forms.
+ *
+ * Flattens and processes the $form_state['values']['category']['menu']
+ * and ...['menu_map'] arrays on both submits and previews.
+ */
+function category_menu_node_form_submit($form, &$form_state) {
+  $fieldsets = array(
+    'menu' => TRUE,
+    'menu_map' => TRUE,
+  );
+  if (!empty($form_state['values']['category']) && is_array($form_state['values']['category'])) {
+    foreach ($form_state['values']['category'] as $key => $value) {
+      if (isset($fieldsets[$key]) && is_array($value)) {
+        if (isset($value['plid_for_container']) && preg_match('/^[A-Za-z0-9\-_]+:[0-9]+$/', $value['plid_for_container'])) {
+          $value_parts = explode(':', $value['plid_for_container']);
+          $value['plid_for_container'] = $value_parts[1];
+        }
+
+        $fieldset = 'category_'. $key;
+        if (empty($form_state['values'][$fieldset])) {
+          $form_state['values'][$fieldset] = array();
+        }
+        $form_state['values'][$fieldset] = $value + $form_state['values'][$fieldset];
+
+        unset($form_state['values']['category'][$key]);
+      }
+    }
+  }
+}
+
+/**
  * Implementation of hook_node_type().
  */
 function category_menu_node_type($op, $info) {
@@ -512,6 +530,9 @@ function category_menu_get_container($ni
 
     return $container;
   }
+  else {
+    return (object) array();
+  }
 }
 
 /**
@@ -1034,31 +1055,3 @@ function _category_menu_tree_above(&$tre
     }
   }
 }
-
-/**
- * Helper function to flatten the $node->category['menu'] array.
- */
-function _category_menu_flatten_values(&$node) {
-  $fieldsets = array(
-    'menu' => TRUE,
-    'menu_map' => TRUE,
-  );
-  if (!empty($node->category) && is_array($node->category)) {
-    foreach ($node->category as $key => $value) {
-      if (isset($fieldsets[$key]) && is_array($value)) {
-        if (isset($value['plid_for_container']) && preg_match('/^[A-Za-z0-9\-_]+:[0-9]+$/', $value['plid_for_container'])) {
-          $value_parts = explode(':', $value['plid_for_container']);
-          $value['plid_for_container'] = $value_parts[1];
-        }
-
-        $fieldset = 'category_'. $key;
-        if (empty($node->$fieldset)) {
-          $node->$fieldset = array();
-        }
-        $node->$fieldset += $value;
-
-        unset($node->category[$key]);
-      }
-    }
-  }
-}
diff -urp --strip-trailing-cr ../category/category.module ./category.module
--- ../category/category.module	2009-05-31 12:06:26.000000000 +0200
+++ ./category.module	2009-06-07 21:53:44.000000000 +0200
@@ -389,6 +389,7 @@ function category_form_alter(&$form, $fo
         '#weight' => 5,
       );
     }
+    $form['#submit'][] = 'category_node_form_submit';
   }
 
   // Category selection form elements.
@@ -562,6 +563,68 @@ function category_form_alter(&$form, $fo
 }
 
 /**
+ * Additional form submit handler for category/container node forms.
+ *
+ * Flattens and processes the $form_state['values']['category'] array
+ * on both submits and previews. This is needed because
+ * the 'category' fieldset on the node form has to be 'tree = TRUE', but
+ * we don't want to deal with the fieldset hierarchy all the time.
+ */
+function category_node_form_submit($form, &$form_state) {
+  $fieldsets = array(
+    'hierarchy' => TRUE,
+    'advanced' => TRUE,
+    'identification' => TRUE,
+    'content_types' => TRUE,
+    'tagging' => TRUE,
+    'distant' => TRUE,
+  );
+  foreach ($form_state['values']['category'] as $key => $value) {
+    if (isset($fieldsets[$key]) && is_array($value)) {
+      $form_state['values']['category'] += $value;
+      unset($form_state['values']['category'][$key]);
+    }
+  }
+
+  if (!empty($form_state['values']['category']['cid']) && $form_state['values']['category']['cid'] == 'new') {
+    unset($form_state['values']['category']['cid']);
+  }
+
+  // Load the new parent for distant-parent category selection.
+  if (!empty($form_state['values']['op'])) {
+    $containers = category_get_containers($node->type);
+    $is_valid_submission = FALSE;
+    foreach ($containers as $container) {
+      if ($form_state['values']['op'] == t('Update children of @parent', array('@parent' => $container->title))) {
+        $is_valid_submission = TRUE;
+      }
+    }
+
+    if ($is_valid_submission) {
+      foreach ($containers as $container) {
+        if (!empty($form_state['values']['categories'][$container->cid])) {
+          $post_categories = $form_state['values']['categories'][$container->cid];
+          if (!is_array($post_categories)) {
+            if (is_numeric($post_categories)) {
+              $post_categories = (int) $post_categories;
+              $node->categories[$post_categories] = category_get_category($post_categories);
+            }
+          }
+          else {
+            foreach ($post_categories as $post_category) {
+              if (is_numeric($post_category)) {
+                $post_category = (int) $post_category;
+                $node->categories[$post_category] = category_get_category($post_category);
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+/**
  * Generate a form element for selecting categories from a container.
  */
 function category_form($cnid, $value = 0, $help = NULL, $name = 'category',
@@ -826,14 +889,9 @@ function category_nodeapi(&$node, $op, $
     case 'prepare':
       $behavior = variable_get('category_behavior_'. $node->type, 0);
       if (!empty($behavior)) {
-        $container_nid = $_POST['category']['hierarchy']['container'];
-
         // Prepare defaults for the add/edit form.
         if (empty($node->category)) {
           $node->category = array();
-          if (!empty($container_nid) && is_numeric($container_nid)) {
-            $node->category['container'] = $container_nid;
-          }
           if (empty($node->nid) && isset($_GET['parent']) &&
           is_numeric($_GET['parent'])) {
             // Handle "Add child page" links:
@@ -860,10 +918,6 @@ function category_nodeapi(&$node, $op, $
           $node->category += _category_defaults(!empty($node->nid) ? $node->nid : 'new');
         }
         else {
-          _category_flatten_values($node);
-          if (!empty($container_nid) && is_numeric($container_nid)) {
-            $node->category['container'] = $container_nid;
-          }
           $node->category['container'] = empty($node->category['container']) ? $node->category['cnid'] : $node->category['container'];
           if (empty($node->category['container']) && !empty($node->category['parents']) && $behavior == 'container') {
             reset($node->category['parents']);
@@ -879,43 +933,6 @@ function category_nodeapi(&$node, $op, $
           $node->category['parent_depth_limit'] = (MENU_MAX_DEPTH - 1);
         }
         $node->category['behavior'] = $behavior;
-        if (empty($node->category['parents'])) {
-          $node->category['parents'] = array();
-        }
-        $node->category['parents'] = array_keys($node->category['parents']);
-      }
-
-      // Load the new parent for distant-parent category selection.
-      if (!empty($_POST['op'])) {
-        $containers = category_get_containers($node->type);
-        $is_valid_submission = FALSE;
-        foreach ($containers as $container) {
-          if ($_POST['op'] == t('Update children of @parent', array('@parent' => $container->title))) {
-            $is_valid_submission = TRUE;
-          }
-        }
-
-        if ($is_valid_submission) {
-          foreach ($containers as $container) {
-            if (!empty($_POST['categories'][$container->cid])) {
-              $post_categories = $_POST['categories'][$container->cid];
-              if (!is_array($post_categories)) {
-                if (is_numeric($post_categories)) {
-                  $post_categories = (int) $post_categories;
-                  $node->categories[$post_categories] = category_get_category($post_categories);
-                }
-              }
-              else {
-                foreach ($post_categories as $post_category) {
-                  if (is_numeric($post_category)) {
-                    $post_category = (int) $post_category;
-                    $node->categories[$post_category] = category_get_category($post_category);
-                  }
-                }
-              }
-            }
-          }
-        }
       }
       break;
 
@@ -923,7 +940,6 @@ function category_nodeapi(&$node, $op, $
     case 'update':
       $behavior = variable_get('category_behavior_'. $node->type, 0);
       if (!empty($behavior)) {
-        _category_flatten_values($node);
         if ($behavior == 'category') {
           category_save_category($node);
         }
@@ -1345,7 +1361,13 @@ function _category_add_form_elements(&$f
   // Need this for AJAX.
   $form['#cache'] = TRUE;
   drupal_add_js("if (Drupal.jsEnabled) { $(document).ready(function() { $('#edit-category-hierarchy-pick-container').css('display', 'none'); }); }", 'inline');
-  $is_container = ($node->category['behavior'] == 'container');
+  $node->category['behavior'] = variable_get('category_behavior_'. $node->type, 0);
+  $is_container = ($node->category['behavior'] === 'container');
+
+  if (empty($node->category['parents'])) {
+    $node->category['parents'] = array();
+  }
+  $node->category['parents'] = array_keys($node->category['parents']);
 
   $form['category'] = array(
     '#type' => 'fieldset',
@@ -1356,7 +1378,7 @@ function _category_add_form_elements(&$f
     '#tree' => TRUE,
     '#attributes' => array('class' => 'category-form'),
   );
-  foreach (array('cid', 'original_container', 'parent_depth_limit') as $key) {
+  foreach (array('cid', 'original_container', 'parent_depth_limit', 'behavior') as $key) {
     $form['category'][$key] = array(
       '#type' => 'value',
       '#value' => $node->category[$key],
@@ -1861,32 +1883,6 @@ function _category_allowed_containers_op
 }
 
 /**
- * Helper function to flatten the $node->category array. This is needed because
- * the 'category' fieldset on the node form has to be 'tree = TRUE', but
- * we don't want to deal with the fieldset hierarchy all the time.
- */
-function _category_flatten_values(&$node) {
-  $fieldsets = array(
-    'hierarchy' => TRUE,
-    'advanced' => TRUE,
-    'identification' => TRUE,
-    'content_types' => TRUE,
-    'tagging' => TRUE,
-    'distant' => TRUE,
-  );
-  foreach ($node->category as $key => $value) {
-    if (isset($fieldsets[$key]) && is_array($value)) {
-      $node->category += $value;
-      unset($node->category[$key]);
-    }
-  }
-
-  if (!empty($node->category['cid']) && $node->category['cid'] == 'new') {
-    unset($node->category['cid']);
-  }
-}
-
-/**
  * Turns the return value of category_get_parents() into a simple array,
  * where both the keys and the values of each element are the node IDs of
  * the parent categories.
diff -urp --strip-trailing-cr ../category/wrappers/taxonomy/taxonomy.module.php ./wrappers/taxonomy/taxonomy.module.php
--- ../category/wrappers/taxonomy/taxonomy.module.php	2009-05-31 12:12:53.000000000 +0200
+++ ./wrappers/taxonomy/taxonomy.module.php	2009-06-07 20:12:37.000000000 +0200
@@ -828,7 +828,6 @@ function taxonomy_nodeapi($node, $op, $a
     case 'update':
       $behavior = variable_get('category_behavior_'. $node->type, 0);
       if (!empty($behavior) && empty($node->category['is_legacy'])) {
-        _category_flatten_values($node);
         if ($behavior == 'category') {
           taxonomy_save_term(_taxonomy_category_into_term($node), TRUE);
         }
@@ -844,7 +843,6 @@ function taxonomy_nodeapi($node, $op, $a
     case 'delete':
       $behavior = variable_get('category_behavior_'. $node->type, 0);
       if (!empty($behavior) && empty($node->category['is_legacy'])) {
-        _category_flatten_values($node);
         if ($behavior == 'category') {
           taxonomy_del_term($node->nid, TRUE);
         }
