Index: API.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/API.txt,v
retrieving revision 1.51
diff -u -F^f -r1.51 API.txt
--- API.txt	22 Aug 2008 10:54:32 -0000	1.51
+++ API.txt	13 Sep 2008 17:44:08 -0000
@@ -262,6 +262,21 @@
   some magic, and AJAX updates won't work.
 
 
+Why Hierarchical Select can't take advantage of Drupal 6 Form API
+-----------------------------------------------------------------
+There are two main things that make Hierarchical Select's FAPI code very
+complex. But for neither one I can take advantage of Drupal 6's FAPI
+improvements.
+1) Hierarchical Select has its own "light" form cache (only a unique id, the
+   form_id and the parameters that are passed to the form definition function)
+   to make AJAX updates possible (in an AJAX callback only the Hierarchical
+   Select should be re-rendered and returned).
+   One would think he can use Drupal 6's shiny $form_state. But one would be
+   wrong, because Views (the exposed filters form) support is a necessity. And
+   that particular form doesn't work when $form['#cache'] is set.
+2) add child form items based on the user's input
+
+
 Hooks
 -----
 1) hook_hierarchical_select_params();
Index: UPGRADE.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/UPGRADE.txt,v
retrieving revision 1.2
diff -u -F^f -r1.2 UPGRADE.txt
--- UPGRADE.txt	29 Jul 2008 23:22:55 -0000	1.2
+++ UPGRADE.txt	13 Sep 2008 17:44:08 -0000
@@ -1,31 +1,8 @@
 // $Id: UPGRADE.txt,v 1.2 2008/07/29 23:22:55 wimleers Exp $
 
-Upgrading (from Hierarchical Select 2 to 3)
--------------------------------------------
+Upgrading (from Drupal 5 to 6)
+------------------------------
 1) Upgrade this module just like any other: overwrite existing files and run
    update.php.
 
-2) Upgrade to jQuery Update 2.
-
-3) Disable and uninstall the jQuery Interface module. It's no longer necessary
-   and in fact it's even *incompatible*.
-
-4) If you're using Views, update to the Views 5.x-1.x-dev tarball of May 11 or
-   later, or apply this patch:
-   http://drupal.org/files/issues/hs_compatibility.patch
-
-5) All modules that Hierarchical Select integrates with are split out into
-   their own module now! Go to admin/build/modules (Site building -> Modules)
-   and enable all the modules you'd like to use. E.g.:
-   - Taxonomy: enable the Hierarchical Select Taxonomy module
-   - Taxonomy exposed filters in Views: enable the Hierchical Select Taxonomy 
-     Views module
-
-6) One very special case: if you had been using Hierarchical Select for your
-   content_taxonomy CCK fields, you had been told to use the "select" widget,
-   Hierarchical Select would automatically override it. Well, that's no longer
-   the case. Now there's a CCK widget especially for content_taxonomy CCK
-   fields! Go through these steps:
-   - enable the Hierarchical Select Content Taxonomy module
-   - change the widget to "Hierarchical Select" for the fields on which you'd
-     like to use Hierarchical Select
+2) That's it. :)
Index: hierarchical_select-rtl.css
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/hierarchical_select-rtl.css,v
retrieving revision 1.6
diff -u -F^f -r1.6 hierarchical_select-rtl.css
--- hierarchical_select-rtl.css	20 Jul 2008 11:05:14 -0000	1.6
+++ hierarchical_select-rtl.css	13 Sep 2008 17:44:08 -0000
@@ -2,210 +2,28 @@
 
 
 /* The hierarchical select. */
-.hierarchical-select-wrapper {
-  margin: 2px; /* Make sure a Hierarchical Selects is *indistuingishable*
-                  from a normal select with regards to spacing. Firefox seems
-                  to be giving special treatment to select elements though,
-                  because it's not rendering the 2px horizontal margins though
-                  they *are* set. */
-}
-
 .hierarchical-select-wrapper .hierarchical-select select,
 .hierarchical-select-wrapper .hierarchical-select .add-to-dropbox,
 .hierarchical-select-wrapper .hierarchical-select .create-new-item {
-  margin: 0;
-  margin-left: .5em; /* margin-right: .5em; */
-  float: right; /* float: left; */
-}
-
-
-/* The flat select (only used in GET forms). */
-.hierarchical-select-wrapper .flat-select {
-  display: none;
+  margin-left: .5em;
+  float: right;
 }
 
 
 /* The pseudo-modal window for creating a new item or new level. */
-.hierarchical-select-wrapper .hierarchical-select .create-new-item {
-  padding: .7em;
-  border: 2px outset gray;
-}
-
-.hierarchical-select-wrapper .hierarchical-select .create-new-item {
-  width: 11em;
-}
-
 .hierarchical-select-wrapper .hierarchical-select .create-new-item-create,
 .hierarchical-select-wrapper .hierarchical-select .create-new-item-cancel {
-  float: left; /* float: right; */
-  margin: 0;
-  margin-left: .4em;
-  clear: right; /* clear: left; */
+  float: left;
+  clear: right;
 }
 
 .hierarchical-select-wrapper .hierarchical-select .create-new-item-input {
-  width: 10.5em;
-  margin: 0;
-  margin-bottom: 1em;
-  float: right; /* float: left; */
-  float: left; /* clear: right; */
-}
-
-
-/* Level labels styles. */
-.hierarchical-select-level-labels-style-bold .hierarchical-select select option.level-label {
-  font-weight: bold;
-}
-
-.hierarchical-select-level-labels-style-inversed .hierarchical-select select option.level-label {
-  background-color: #000000;
-  color: #FFFFFF;
-}
-
-.hierarchical-select-level-labels-style-underlined .hierarchical-select select option.level-label {
-  text-decoration: underline;
+  float: right;
+  clear: left;
 }
 
 
 /* Dropbox limit warning.*/
 p.hierarchical-select-dropbox-limit-warning {
-  padding: 0;
-  color: #F7A54F;
-  font-size: 110%;
-  padding-left: .5em;
-}
-
-
-/* The dropbox table. */
-.hierarchical-select-wrapper .dropbox-title {
-  font-size: 115%;
-  color: #898989;
-  margin-bottom: 0.2em;
-}
-
-.hierarchical-select-wrapper .dropbox {
-  display: inline-block;
-  margin: .5em 0;
-}
-
-.hierarchical-select-wrapper .dropbox table {
-  margin: 0;  width: auto;
-  max-width: 100%;
-  min-width: 20em;
-  color: gray;
-  font-size: 90%;
-  border: 1px solid gray;
-}
-
-tr.dropbox-entry {
-  line-height: 1.3em;
-  padding: .3em .6em;
-  text-decoration: none;
-}
-
-td.dropbox-remove a:hover {
-  text-decoration: underline;
-}
-
-tr.dropbox-entry.even {
-  background-color: transparent;
-  border-bottom: 1px solid #CCCCCC;
-}
-
-tr.dropbox-entry.odd {
-  background-color: #EDF5FA;
-  border-bottom: 1px solid #CCCCCC;
-}
-
-tr.dropbox-entry.first {
-  border-top: 1px solid gray;
-}
-
-tr.dropbox-entry.last {
-  border-bottom: 1px solid gray;
-}
-
-.dropbox-selected-item {
-  font-weight: bold;
-}
-
-.dropbox-item-separator {
-  padding-left: .5em;
   padding-right: .5em;
 }
-
-td.dropbox-remove *,
-td.dropbox-remove a:link,
-td.dropbox-remove a:visited {
-  margin: 0px;
-  padding: 0px;
-  color: #F7A54F;
-}
-
-tr.dropbox-is-empty {
-  padding: .5em 1em;
-}
-
-
-/* The "Update" button and help text (used when Javascript is disabled). */
-.hierarchical-select-wrapper .nojs .update-button {
-  margin: 0 0 1em;
-}
-
-.hierarchical-select-wrapper .nojs .help-text {
-  font-size: 90%;
-  color: transparent;
-  display: block;
-  border: 1px dotted black;
-  overflow: hidden;
-  width: 34em;
-  height: 1.2em;
-  padding: .6em;
-  line-height: normal;
-}
-
-.hierarchical-select-wrapper .nojs .help-text:hover {
-  height: auto;
-  width: auto;
-  min-width: 25em;
-  max-width: 45em;
-  color: gray;
-}
-
-.hierarchical-select-wrapper .nojs .help-text .ask-to-hover {
-  color: gray;
-  font-style: italic;
-}
-
-.hierarchical-select-wrapper .nojs .help-text:hover .ask-to-hover {
-  display: none;
-}
-  
-.hierarchical-select-wrapper .nojs .help-text .highlight {
-  text-decoration: underline;
-}
-
-.hierarchical-select-wrapper .nojs .help-text .warning {
-  color: red;
-}
-
-.hierarchical-select-wrapper .nojs .help-text .solutions {
-  margin: 0;
-  padding: 0;
-}
-
-
-/* The 'waiting' class is set dynamically, during a callback to the server. */
-.hierarchical-select-wrapper.waiting {
-  opacity: 0.5;
-
-  /* IE doesn't support CSS 2 properly. */
-  zoom: 1;
-  filter: alpha(opacity=50);
-}
-
-
-/* Use a monospace font for the import/export config code text areas. */
-.hierarchical-select-config-code {
-  font-family: 'Monaco', 'Lucida Console', 'Consolas', monospace;
-}
Index: hierarchical_select.admin.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/hierarchical_select.admin.inc,v
retrieving revision 1.13
diff -u -F^f -r1.13 hierarchical_select.admin.inc
--- hierarchical_select.admin.inc	10 Aug 2008 16:16:53 -0000	1.13
+++ hierarchical_select.admin.inc	13 Sep 2008 17:44:08 -0000
@@ -138,6 +138,8 @@ function hierarchical_select_admin_imple
  * Form definition; config export form.
  */
 function hierarchical_select_admin_export($config_id) {
+  require_once(drupal_get_path('module', 'hierarchical_select') .'/includes/common.inc');
+
   $config = hierarchical_select_common_config_get($config_id);
   $code = _hierarchical_select_create_export_code($config);
 
@@ -160,6 +162,8 @@ function hierarchical_select_admin_expor
  * Form definition; config import form.
  */
 function hierarchical_select_admin_import($config_id) {
+  require_once(drupal_get_path('module', 'hierarchical_select') .'/includes/common.inc');
+
   drupal_add_css(drupal_get_path('module', 'hierarchical_select') .'/hierarchical_select.css');
   drupal_add_js('$(document).ready(function() { $(".hierarchical-select-code").focus(); });', 'inline');
 
@@ -187,14 +191,14 @@ function hierarchical_select_admin_impor
 /**
  * Validate callback; config import form.
  */
-function hierarchical_select_admin_import_validate($form_id, $form_values, $form) {
+function hierarchical_select_admin_import_validate($form, &$form_state) {
   ob_start();
-  eval($form_values['config']);
+  eval($form_state['values']['config']);
   ob_end_clean();
 
-  form_set_value($form['interpreted_config'], serialize($config));
+  form_set_value($form['interpreted_config'], serialize($config), $form_state);
 
-  if (empty($form_values['config'])) {
+  if (empty($form_state['values']['config'])) {
     form_error($form['config'], t('You did not enter anything.'));
   }
   elseif ($config == NULL) {
@@ -208,8 +212,8 @@ function hierarchical_select_admin_impor
 /**
  * Submit callback; config import form.
  */
-function hierarchical_select_admin_import_submit($form_id, $form_values) {
-  $config = unserialize($form_values['interpreted_config']);
+function hierarchical_select_admin_import_submit($form, &$form_state) {
+  $config = unserialize($form_state['values']['interpreted_config']);
   $config_id = $config['config_id'];
   hierarchical_select_common_config_set($config_id, $config);
   drupal_set_message(t('Hierarchical Select configuration for %config_id imported!', array('%config_id' => $config_id)));
Index: hierarchical_select.css
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/hierarchical_select.css,v
retrieving revision 1.28
diff -u -F^f -r1.28 hierarchical_select.css
--- hierarchical_select.css	20 Jul 2008 11:05:14 -0000	1.28
+++ hierarchical_select.css	13 Sep 2008 17:44:08 -0000
@@ -86,10 +86,6 @@
 .hierarchical-select-wrapper .dropbox {
   display: inline-block;
   margin: .5em 0;
-}
-
-.hierarchical-select-wrapper .dropbox table {
-  margin: 0;  
   width: auto;
   max-width: 100%;
   min-width: 20em;
Index: hierarchical_select.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/hierarchical_select.info,v
retrieving revision 1.9
diff -u -F^f -r1.9 hierarchical_select.info
--- hierarchical_select.info	28 Apr 2008 17:54:57 -0000	1.9
+++ hierarchical_select.info	13 Sep 2008 17:44:08 -0000
@@ -1,5 +1,5 @@
 ; $Id: hierarchical_select.info,v 1.9 2008/04/28 17:54:57 wimleers Exp $
 name = Hierarchical Select
 description = Simplifies the selection of one or multiple items in a hierarchical tree.
-dependencies = jquery_update
 package = Form Elements
+core = 6.x
Index: hierarchical_select.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/hierarchical_select.module,v
retrieving revision 1.132
diff -u -F^f -r1.132 hierarchical_select.module
--- hierarchical_select.module	29 Aug 2008 18:19:35 -0000	1.132
+++ hierarchical_select.module	13 Sep 2008 17:44:09 -0000
@@ -18,82 +18,70 @@
 /**
  * Implementation of hook_menu().
  */
-function hierarchical_select_menu($may_cache) {
-  if ($may_cache) {
-    $items[] = array(
-      'path'               => 'hierarchical_select_json',
-      'callback'           => 'hierarchical_select_json',
-      'type'               => MENU_CALLBACK,
-      // TODO: Needs improvements. Ideally, this would inherit the permissions
-      // of the form the Hierarchical Select was in.
-      'access'             => TRUE,
-    );
-    $items[] = array(
-      'path'               => 'admin/settings/hierarchical_select',
-      'title'              => t('Hierarchical Select'),
-      'description'        => t('Configure site-wide settings for the Hierarchical Select form element.'),
-      'callback'           => 'drupal_get_form',
-      'callback arguments' => array('hierarchical_select_admin_settings'),
-      'type'               => MENU_NORMAL_ITEM,
-    );
-    $items[] = array(
-      'path'               => 'admin/settings/hierarchical_select/settings',
-      'title'              => t('Site-wide settings'),
-      'weight'             => -10,
-      'type'               => MENU_DEFAULT_LOCAL_TASK,
-    );
-    $items[] = array(
-      'path'               => 'admin/settings/hierarchical_select/configs',
-      'title'              => t('Configurations'),
-      'description'        => t('All available Hierarchical Select configurations.'),
-      'callback'           => 'hierarchical_select_admin_configs',
-      'type'               => MENU_LOCAL_TASK,
-    );
-    $items[] = array(
-      'path'               => 'admin/settings/hierarchical_select/implementations',
-      'title'              => t('Implementations'),
-      'description'        => t('Features of each Hierarchical Select implementation.'),
-      'callback'           => 'hierarchical_select_admin_implementations',
-      'type'               => MENU_LOCAL_TASK,
-    );
-  }
-  else {
-    // Work-around for bug in Drupal 5 (fixed in Drupal 5.8).
-    // See http://drupal.org/node/109459.
-    global $user;
-    if (!isset($user->theme)) {
-      $user->theme = variable_get('theme_default', 'garland');
-    }
-
-    if (arg(0) == 'admin' && arg(1) == 'settings' && arg(2) == 'hierarchical_select') {
-      require_once(drupal_get_path('module', 'hierarchical_select') .'/hierarchical_select.admin.inc');
-
-      if (in_array(arg(3), array('export', 'import'))) {
-        require_once(drupal_get_path('module', 'hierarchical_select') .'/includes/common.inc');
-        $items[] = array(
-          'path'               => 'admin/settings/hierarchical_select/export/'. arg(4),
-          'title'              => t('Export'),
-          'callback'           => 'drupal_get_form',
-          'callback arguments' => array('hierarchical_select_admin_export', arg(4)),
-          'type'               => MENU_LOCAL_TASK,
-        );
-        $items[] = array(
-          'path'               => 'admin/settings/hierarchical_select/import/'. arg(4),
-          'title'              => t('Import'),
-          'callback'           => 'drupal_get_form',
-          'callback arguments' => array('hierarchical_select_admin_import', arg(4)),
-          'type'               => MENU_LOCAL_TASK,
-        );
-      }
-    }
-  }
+function hierarchical_select_menu() {
+  $items['hierarchical_select_json'] = array(
+    'page callback'   => 'hierarchical_select_json',
+    'type'            => MENU_CALLBACK,
+    // TODO: Needs improvements. Ideally, this would inherit the permissions
+    // of the form the Hierarchical Select was in.
+    'access callback' => TRUE,
+  );
+  $items['admin/settings/hierarchical_select'] = array(
+    'title'            => 'Hierarchical Select',
+    'description'      => 'Configure site-wide settings for the Hierarchical Select form element.',
+    'access arguments' => array('administer site configuration'),
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('hierarchical_select_admin_settings'),
+    'type'             => MENU_NORMAL_ITEM,
+    'file'             => 'hierarchical_select.admin.inc',
+  );
+  $items['admin/settings/hierarchical_select/settings'] = array(
+    'title'            => 'Site-wide settings',
+    'access arguments' => array('administer site configuration'),
+    'weight'           => -10,
+    'type'             => MENU_DEFAULT_LOCAL_TASK,
+    'file'             => 'hierarchical_select.admin.inc',
+  );
+  $items['admin/settings/hierarchical_select/configs'] = array(
+    'title'            => 'Configurations',
+    'description'      => 'All available Hierarchical Select configurations.',
+    'access arguments' => array('administer site configuration'),
+    'page callback'    => 'hierarchical_select_admin_configs',
+    'type'             => MENU_LOCAL_TASK,
+    'file'             => 'hierarchical_select.admin.inc',
+  );
+  $items['admin/settings/hierarchical_select/implementations'] = array(
+    'title'            => 'Implementations',
+    'description'      => 'Features of each Hierarchical Select implementation.',
+    'access arguments' => array('administer site configuration'),
+    'page callback'    => 'hierarchical_select_admin_implementations',
+    'type'             => MENU_LOCAL_TASK,
+    'file'             => 'hierarchical_select.admin.inc',
+  );
+  $items['admin/settings/hierarchical_select/export/%hierarchical_select_config_id'] = array(
+    'title'            => 'Export',
+    'access arguments' => array('administer site configuration'),
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('hierarchical_select_admin_export', 4),
+    'type'             => MENU_LOCAL_TASK,
+    'file'             => 'hierarchical_select.admin.inc',
+  );
+  $items['admin/settings/hierarchical_select/import/%hierarchical_select_config_id'] = array(
+    'title'            => 'Import',
+    'access arguments' => array('administer site configuration'),
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('hierarchical_select_admin_import', 4),
+    'type'             => MENU_LOCAL_TASK,
+    'file'             => 'hierarchical_select.admin.inc',
+  );
+
   return $items;
 }
 
 /**
  * Implementation of hook_form_alter().
  */
-function hierarchical_select_form_alter($form_id, &$form) {
+function hierarchical_select_form_alter(&$form, &$form_state, $form_id) {
   if (_hierarchical_select_form_has_hierarchical_select($form)) {
     $form['#after_build'][] = 'hierarchical_select_after_build';
   }
@@ -105,7 +93,7 @@ function hierarchical_select_form_alter(
 function hierarchical_select_elements() {
   $type['hierarchical_select'] = array(
     '#input' => TRUE,
-    '#process' => array('hierarchical_select_process' => array()),
+    '#process' => array('hierarchical_select_process'),
     '#config' => array(
       'module' => 'some_module',
       'params' => array(),
@@ -152,8 +140,7 @@ function hierarchical_select_requirement
     $current = drupal_get_installed_schema_version('hierarchical_select');
 
     $up_to_date = (end($updates) == $current);
-    $jquery_update_v2 = (file_exists(drupal_get_path('module', 'jquery_update') .'/compat.js'));
-    $jquery_interface = module_exists('jquery_interface');
+
     $hierarchical_select_weight = db_result(db_query("SELECT weight FROM {system} WHERE type = 'module' AND name = 'hierarchical_select'"));
     $core_overriding_modules = array('hs_book', 'hs_menu', 'hs_taxonomy');
     $path_errors = array();
@@ -173,41 +160,12 @@ function hierarchical_select_requirement
         $weight_errors[] = t('!module (!weight)', array('!module' => $module_info['name'], '!weight' => $weight));
       }
     }
-    
 
-    if ($up_to_date && $jquery_update_v2 && !$jquery_interface && !count($path_errors) && !count($weight_errors)) {
-      $value = t('All updates installed. jQuery Update 2.x installed. Implementation modules are installed correctly.');
+    if ($up_to_date && !count($path_errors) && !count($weight_errors)) {
+      $value = t('All updates installed. Implementation modules are installed correctly.');
       $description = '';
       $severity = REQUIREMENT_OK;
     }
-    elseif (!$up_to_date) {
-      $value = t('Not all updates installed!');
-      $description = t('Please run update.php to install the latest updates!
-        You have installed update !installed_update, but the latest update is
-        !latest_update!',
-        array(
-          '!installed_update' => $current,
-          '!latest_update' => end($updates),
-        )
-      );
-      $severity = REQUIREMENT_ERROR;
-    }
-    elseif (!$jquery_update_v2) {
-      $value = t('jQuery Update 1.x installed!');
-      $description = t('Please upgrade to jQuery Update 2.x! jQuery Update
-        1.x contains jQuery 1.1.x, which is incompatible with the Javascript
-        code of Hierarchical Select!'
-      );
-      $severity = REQUIREMENT_ERROR;
-    }
-    elseif ($jquery_interface) {
-      $value = t('jQuery Interface installed!');
-      $description = t('Please disable and uninstall jQuery Interface, as it
-        is incompatible with jQuery Update 2. It is very buggy anyway and any
-        module that uses it should upgrade to jQuery UI.'
-      );
-      $severity = REQUIREMENT_ERROR;      
-    }
     elseif ($path_errors) {
       $value = t('Modules incorrectly installed!');
       $description = t(
@@ -228,6 +186,18 @@ function hierarchical_select_requirement
       ) .':'. theme('item_list', $weight_errors);
       $severity = REQUIREMENT_ERROR;
     }
+    else {
+      $value = t('Not all updates installed!');
+      $description = t('Please run update.php to install the latest updates!
+        You have installed update !installed_update, but the latest update is
+        !latest_update!',
+        array(
+          '!installed_update' => $current,
+          '!latest_update' => end($updates),
+        )
+      );
+      $severity = REQUIREMENT_ERROR;
+    }
 
     $requirements['hierarchical_select'] = array(
       'title' => t('Hierarchical Select'),
@@ -240,9 +210,55 @@ function hierarchical_select_requirement
   return $requirements;
 }
 
+/**
+ * Implementation of hook_theme().
+ */
+function hierarchical_select_theme() {
+  return array(
+    'hierarchical_select' => array(
+      'file'      => 'includes/theme.inc',
+      'arguments' => array('element' => NULL),
+    ),
+    'hierarchical_select_select' => array(
+      'file'      => 'includes/theme.inc',
+      'arguments' => array('element' => NULL),
+    ),
+    'hierarchical_select_textfield' => array(
+      'file'      => 'includes/theme.inc',
+      'arguments' => array('element' => NULL),
+    ),
+    'hierarchical_select_dropbox_table' => array(
+      'file'      => 'includes/theme.inc',
+      'arguments' => array('element' => NULL),
+    ),
+    'hierarchical_select_common_config_form_level_labels' => array(
+      'file'      => 'includes/theme.inc',
+      'arguments' => array('form' => NULL),
+    ),
+    'hierarchical_select_common_config_form_editability' => array(
+      'file'      => 'includes/theme.inc',
+      'arguments' => array('form' => NULL),
+    ),
+  );
+}
+
 
 //----------------------------------------------------------------------------
-// Menu callbacks.
+// Menu system callbacks.
+
+/**
+ * Wildcard loader for Hierarchical Select config ID's.
+ */
+function hierarchical_select_config_id_load($config_id) {
+  if (empty($config_id)) {
+    return FALSE;
+  }
+
+  // E.g.: extract "content_taxonomy" from "content-taxonomy_field_somefield".
+  $parts = explode('_', $config_id);
+  $module = str_replace(array('-'), array('_'), $parts[0]);
+  return in_array($config_id, array_keys(module_invoke($module, 'hierarchical_select_config_info')));
+}
 
 /**
  * Menu callback; format=text/json; generates and outputs the appropriate HTML.
@@ -256,7 +272,7 @@ function hierarchical_select_json() {
 
   // Collect all necessary variables.
   $cached = cache_get($hs_form_build_id, 'cache');
-  $storage = unserialize($cached->data);
+  $storage = $cached->data;
 
   // Ensure that the form id in the POST array is the same as the one of the
   // stored parameters of the original form. For 99% of the forms, this step
@@ -271,8 +287,14 @@ function hierarchical_select_json() {
   }
 
   // Retrieve and process the form.
+  $form_state = &$storage['parameters'][1];
+  if (!empty($storage['file'])) {
+    require_once($storage['file']);
+  }
   $form = call_user_func_array('drupal_retrieve_form', $storage['parameters']);
-  drupal_prepare_form($form_id, $form);
+  drupal_prepare_form($form_id, $form, $form_state);
+  $form['#post'] = $_POST;
+  $form = form_builder($form_id, $form, $form_state);
 
   // Render only the relevant part of the form (i.e. the hierarchical_select
   // form item that has triggered this AJAX callback).
@@ -307,7 +329,7 @@ function hierarchical_select_json() {
 /**
  * Hierarchical select form element type #process callback.
  */
-function hierarchical_select_process($element) {
+function hierarchical_select_process($element, $edit, $form_state, $form) {
   static $hsid;
 
   if (!isset($hsid)) {
@@ -573,7 +595,8 @@ function hierarchical_select_process($el
   // is set to 'label_0' after an "Add" operation. When $element['#post'] is
   // NOT unset, the corresponding value in $element['#post'] will be used
   // instead of the default value that was set. This is undesired behavior.
-  unset($element['#post']);
+  // TODO: find a work-around for this in D6.
+//  unset($element['#post']);
 
   // Finally, calculate the return value of this hierarchical_select form
   // element. This will be set in _hierarchical_select_validate(). (If we'd
@@ -583,19 +606,20 @@ function hierarchical_select_process($el
   // Add a validate callback, which will:
   // - validate that the dropbox limit was not exceeded.
   // - set the return value of this form element.
-  $element['#validate'] = array('_hierarchical_select_validate' => array());
+  $element['#element_validate'] = array('_hierarchical_select_validate');
 
   return $element;
 }
 
-/**
- * Hierarchical select form element type #after_build callback.
- */
-function hierarchical_select_after_build($form, $form_values) {
+ /**
+  * Hierarchical select form element type #after_build callback.
+  */
+function hierarchical_select_after_build($form, &$form_state) {
   $names = _hierarchical_select_store_name(NULL, NULL, TRUE);
 
   if (!isset($_POST['hs_form_build_id']) && count($names)) {
     $parameters = (isset($form['#parameters'])) ? $form['#parameters'] : array();
+    $menu_item = menu_get_item();
 
     // Collect information in this array, which will be used in dynamic form
     // updates, to …
@@ -604,6 +628,8 @@ function hierarchical_select_after_build
       'parameters' => $parameters,
       // … determine which part of $form should be rendered.
       '#names'     => $names,
+      // … include the file in which the form function lives.
+      'file'       => $menu_item['file'],
     );
 
     // Store the information needed for dynamic form updates in the cache, so
@@ -611,8 +637,7 @@ function hierarchical_select_after_build
     // render part of the form).
     $expire = max(ini_get('session.cookie_lifetime'), 86400);
     $hs_form_build_id = 'hs_form_'. md5(mt_rand());
-    cache_set($hs_form_build_id, 'cache', serialize($storage), $expire);
-
+    cache_set($hs_form_build_id, $storage, 'cache', $expire);
   }
   elseif (isset($_POST['hs_form_build_id'])) {
     // Don't generate a new hs_form_build_id if this is a re-rendering of the
@@ -629,29 +654,31 @@ function hierarchical_select_after_build
     // form_builder() has all info it needs to generate #name and #id.
     '#parents' => array('hs_form_build_id'),
   );
-  $form['hs_form_build_id'] = form_builder($form['form_id']['#value'], $form_element);
+  $form['hs_form_build_id'] = form_builder($form['form_id']['#value'], $form_element, $form_state);
 
   // Pass the hs_form_build_id to a custom submit function that will clear
   // the associated values from the cache.
-  $form['#submit']['_hierarchical_select_submit'] = array($_POST['hs_form_build_id']);
+  $form_state['hs_form_build_id'] = $_POST['hs_form_build_id'];
+  $form['#submit'][] = '_hierarchical_select_submit';
 
   return $form;
 }
 
 /**
- * Hierarchical select form element #validate callback.
+ * Hierarchical select form element #element_validate callback.
  */
-function _hierarchical_select_validate(&$element) {
+function _hierarchical_select_validate(&$element, &$form_state) {
   // If the dropbox is enabled and a dropbox limit is configured, check if
   // this limit is not exceeded.
   $config = $element['#config'];
   if ($config['dropbox']['status']) {
     if ($config['dropbox']['limit'] > 0) { // Zero as dropbox limit means no limit.
-      // TRICKY: #validate is not called upon the initial rendering (i.e. it
-      // is assumed that the default value is valid). However, Hierarchical
-      // Select's config can influence the validity (i.e. how many selections
-      // may be added to the dropbox). This means it's possible the user has
-      // actually selected too many items without being notified of this.
+      // TRICKY: #element_validate is not called upon the initial rendering
+      // (i.e. it is assumed that the default value is valid). However,
+      // Hierarchical Select's config can influence the validity (i.e. how
+      // many selections may be added to the dropbox). This means it's
+      // possible the user has actually selected too many items without being
+      // notified of this.
       $lineage_count = count($element['#value']['dropbox']['hidden']['lineages_selections']);
       if ($lineage_count > $config['dropbox']['limit']) {
         // TRICKY: this should propagate the error down to the children, but
@@ -680,7 +707,7 @@ function _hierarchical_select_validate(&
   // detects as an empty form value.
   $value = (empty($element['#return_value'])) ? 0 : $element['#return_value'];
   $element['#value'] = $value;
-  form_set_value($element, $value);
+  form_set_value($element, $value, $form_state);
 
   // We have to check again for errors. This line is taken litterally from
   // form.inc, so it works in an identical way.
@@ -692,9 +719,9 @@ function _hierarchical_select_validate(&
 /**
  * Hierarchical select form element #submit callback.
  */
-function _hierarchical_select_submit($form_id, $form_values, $hs_form_build_id) {
+function _hierarchical_select_submit($form, &$form_state) {
   // Delete the stored form information when the form is submitted.
-  cache_clear_all($hs_form_build_id, 'cache');
+  cache_clear_all($form_state['hs_form_build_id'], 'cache');
 }
 
 
@@ -931,9 +958,6 @@ function _hierarchical_select_process_re
       '#type' => 'select',
       '#options' => $hierarchy->levels[$depth],
       '#default_value' => $selected_item,
-      // We need to skip the check of valid options, because they may be
-      // modified after each update.
-      '#DANGEROUS_SKIP_CHECK' => TRUE,
       // Use a #theme callback to prevent the select from being wrapped in a
       // div. This simplifies the CSS and JS code. Also sets a special class
       // on the level label option, if any, to make level label styles
@@ -1929,209 +1953,3 @@ function _hierarchical_select_dropbox_li
 function _hierarchical_select_dropbox_lineage_item_get_value($item) {
   return $item['value'];
 }
-
-/**
- * This is an altered clone of form_select_options(). The reason: I need to be
- * able to set a class on an option element if it contains a level label, to
- * allow for level label styles.
- * Secondly, I need to be able to mark childless items (i.e. "option"
- * elements).
- */
-function _hierarchical_select_options($element) {
-  if (!isset($choices)) {
-    $choices = $element['#options'];
-  }
-  // array_key_exists() accommodates the rare event where $element['#value'] is NULL.
-  // isset() fails in this situation.
-  $value_valid = isset($element['#value']) || array_key_exists('#value', $element);
-  $value_is_array = is_array($element['#value']);
-  $options = '';
-  foreach ($choices as $key => $choice) {
-    $key = (string)$key;
-    if ($value_valid && (!$value_is_array && (string)$element['#value'] === $key || ($value_is_array && in_array($key, $element['#value'])))) {
-      $selected = ' selected="selected"';
-    }
-    else {
-      $selected = '';
-    }
-
-    // If an option DOES NOT have child info, then it's a special option:
-    // - label_\d+ (level label)
-    // - none ("<none>")
-    // - create_new_item ("<create new item>")
-    // Only when it's a level label, we have to add a class to this option.
-    if (!isset($element['#childinfo'][$key])) {
-      $class = (preg_match('/label_\d+/', $key)) ? ' level-label' : '';
-    }
-    else {
-      $class = ($element['#childinfo'][$key] == 0) ? 'has-no-children' : 'has-children';
-    }
-    
-    $options .= '<option value="'. check_plain($key) .'" class="'. $class .'"'. $selected .'>'. check_plain($choice) .'</option>';
-  }
-  return $options;
-}
-
-
-//----------------------------------------------------------------------------
-// Theming callbacks.
-
-/**
- * @ingroup themeable
- * @{
- */
-
-/**
- * Format a hierarchical select.
- *
- * @param $element
- *   An associative array containing the properties of the element.
- * @return
- *   A themed HTML string representing the form element.
- */
-function theme_hierarchical_select($element) {
-  $output = '';
-
-  // Update $element['#attributes']['class'].
-  $hsid = $element['hsid']['#value'];
-  $level_labels_style = variable_get('hierarchical_select_level_labels_style', 'none');
-  $classes = array(
-   'hierarchical-select-wrapper',
-   "hierarchical-select-level-labels-style-$level_labels_style",
-  );
-  $element['#attributes']['class'] .= ' '. implode(' ', $classes);
-  $element['#attributes']['id'] = "hierarchical-select-$hsid-wrapper";
-
-  $output .= theme(
-    'form_element',
-    array(
-      '#title' => $element['#title'],
-      '#description' => $element['#description'],
-      '#id' => $element['#id'],
-      '#required' => $element['#required'],
-      '#error' => $element['#error'],
-    ),
-    '<div '. drupal_attributes($element['#attributes']) .'>'. $element['#children'] .'</div>'
-  );
-
-  return $output;
-}
-
-/**
- * Format a select in the .hierarchial-select div: prevent it from being
- * wrapped in a div. This simplifies the CSS and JS code.
- *
- * @param $element
- *   An associative array containing the properties of the element.
- * @return
- *   A themed HTML string representing the form element.
- */
-function theme_hierarchical_select_select($element) {
-  $select = '';
-  $size = $element['#size'] ? ' size="'. $element['#size'] .'"' : '';
-  _form_set_class($element, array('form-select'));
-  $multiple = isset($element['#multiple']) && $element['#multiple'];
-  return '<select name="'. $element['#name'] .''. ($multiple ? '[]' : '') .'"'. ($multiple ? ' multiple="multiple" ' : '') . drupal_attributes($element['#attributes']) .' id="'. $element['#id'] .'" '. $size .'>'. _hierarchical_select_options($element) .'</select>';
-}
-
-/**
- * Format a textfield in the .hierarchial-select div: prevent it from being
- * wrapped in a div. This simplifies the CSS and JS code.
- *
- * @param $element
- *   An associative array containing the properties of the element.
- * @return
- *   A themed HTML string representing the form element.
- */
-function theme_hierarchical_select_textfield($element) {
-  $size = $element['#size'] ? ' size="'. $element['#size'] .'"' : '';
-  $class = array('form-text');
-  $extra = '';
-  $output = '';
-
-  if ($element['#autocomplete_path']) {
-    drupal_add_js('misc/autocomplete.js');
-    $class[] = 'form-autocomplete';
-    $extra =  '<input class="autocomplete" type="hidden" id="'. $element['#id'] .'-autocomplete" value="'. check_url(url($element['#autocomplete_path'], NULL, NULL, TRUE)) .'" disabled="disabled" />';
-  }
-  _form_set_class($element, $class);
-
-  if (isset($element['#field_prefix'])) {
-    $output .= '<span class="field-prefix">'. $element['#field_prefix'] .'</span> ';
-  }
-
-  $output .= '<input type="text" maxlength="'. $element['#maxlength'] .'" name="'. $element['#name'] .'" id="'. $element['#id'] .'" '. $size .' value="'. check_plain($element['#value']) .'"'. drupal_attributes($element['#attributes']) .' />';
-
-  if (isset($element['#field_suffix'])) {
-    $output .= ' <span class="field-suffix">'. $element['#field_suffix'] .'</span>';
-  }
-
-  return $output . $extra;
-}
-
-/**
- * Forms API theming callback for the dropbox. Renders the dropbox as a table.
- *
- * @param $element
- *   An element for which the #theme property was set to this function.
- * @return
- *   A themed HTML string.
- */
-function theme_hierarchical_select_dropbox_table($element) {
-  $output = '';
-
-
-  $title     = $element['title']['#value'];
-  $separator = $element['separator']['#value'];
-  $is_empty  = $element['is_empty']['#value'];
-
-  $separator_html = '<span class="dropbox-item-separator">'. $separator .'</span>';
-
-  $output .= '<div class="dropbox">';
-  $output .= '<table>';
-  $output .= '<caption class="dropbox-title">'. $title .'</caption>';
-  $output .= '<tbody>';
-
-  if (!$is_empty) {
-    // Each lineage in the dropbox corresponds to an entry in the dropbox table.
-    $lineage_count = count(element_children($element['lineages']));
-    for ($x = 0; $x < $lineage_count; $x++) {
-      $db_entry = $element['lineages'][$x];
-      $zebra = $db_entry['#zebra'];
-      $first = $db_entry['#first'];
-      $last  = $db_entry['#last'];
-      // The deepest level is the number of child levels minus one. This "one"
-      // is the element for the "Remove" checkbox.
-      $deepest_level = count(element_children($db_entry)) - 1;
-
-      $output .= '<tr class="dropbox-entry '. $first .' '. $last .' '. $zebra .'">';
-      $output .= '<td>';
-      // Each item in a lineage is separated by the separator string.
-      for ($depth = 0; $depth < $deepest_level; $depth++) {
-        $output .= drupal_render($db_entry[$depth]);
-
-        if ($depth < $deepest_level - 1) {
-          $output .= $separator_html;
-        }
-      }
-      $output .= '</td>';
-      $output .= '<td class="dropbox-remove">'. drupal_render($db_entry['remove']) .'</td>';
-      $output .= '</tr>';
-    }
-  }
-  else {
-    $output .= '<tr class="dropbox-entry first last dropbox-is-empty"><td>';
-    $output .= t('Nothing has been selected.');
-    $output .= '</td></tr>';
-  }
-
-  $output .= '</tbody>';
-  $output .= '</table>';
-  $output .= '</div>';
-
-  return $output;
-}
-
-/**
- * @} End of "ingroup themeable".
- */
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/includes/common.inc,v
retrieving revision 1.20
diff -u -F^f -r1.20 common.inc
--- includes/common.inc	18 Jul 2008 13:45:47 -0000	1.20
+++ includes/common.inc	13 Sep 2008 17:44:09 -0000
@@ -335,100 +335,10 @@ function hierarchical_select_common_conf
 }
 
 /**
- * Themeing function to render the level_labels settings as a table.
- */
-function theme_hierarchical_select_common_config_form_level_labels($form) {
-  // Recover the stored strings.
-  $strings = $form['#strings'];
-
-  $output = '';
-  $header = array(t('Level'), t('Label'));
-  $rows = array();
-
-  $output .= drupal_render($form['status']);
-
-  $output .= '<div class="level-labels-settings">';
-  if (count(element_children($form['labels']))) {
-    foreach (element_children($form['labels']) as $depth) {
-      $row = array();
-      $row[]['data'] = ($depth == 0) ? t('Root level') : t('Sublevel !depth', array('!depth' => $depth));
-      $row[]['data'] = drupal_render($form['labels'][$depth]);
-      $rows[] = $row;
-    }
-
-    // Render the table.
-    $output .= theme('table', $header, $rows, array('style' => 'width: auto;'));
-  }
-  else {  
-    // No levels exist yet in the hierarchy!
-    $output .= '<p><strong>';
-    $output .= t('There are no levels yet in this !hierarchy!', array('!hierarchy' => $strings['hierarchy']));
-    $output .= '</strong></p>';
-  }
-  $output .= '</div>';
-
-  // Render the remaining form items.
-  $output .= drupal_render($form);
-
-  return $output;
-}
-/**
- * Themeing function to render the per-level editability settings as a table,
- * (these are the item_types and allowed_levels settings).
- */
-function theme_hierarchical_select_common_config_form_editability($form) {
-  // Recover the stored strings.
-  $strings = $form['#strings'];
-
-  $output = '';
-  $header = array(t('Level'), t('Allow'), t('!item_type', array('!item_type' => ucfirst($strings['item_type']))));
-  $rows = array();
-
-  $output .= drupal_render($form['status']);
-
-  $output .= '<div class="editability-per-level-settings">';
-  if (count(element_children($form['item_types']))) {
-    foreach (element_children($form['item_types']) as $depth) {
-      $row = array();
-      $row[]['data'] = ($depth == 0) ? t('Root level') : t('Sublevel !depth', array('!depth' => $depth));
-      $row[]['data'] = drupal_render($form['allowed_levels'][$depth]);
-      $row[]['data'] = drupal_render($form['item_types'][$depth]);
-      $rows[] = $row;
-    }
-
-    // Render the table and description.
-    $output .= theme('table', $header, $rows, array('style' => 'width: auto;'), '<em>'. t('Per-level settings for creating new !items.', array('!items' => $strings['items'])));
-    $output .= '<div class="description">';
-    $output .= t(
-      'The %item_type you enter for each level is what will be used in
-      each level to replace a "&lt;create new item&gt;" option with a
-      "&lt;create new %item_type&gt;" option, which is often more
-      intuitive.',
-      array(
-        '%item_type' => $strings['item_type'],
-      )
-    );
-    $output .= '</div>';
-  }
-  else {  
-    // No levels exist yet in the hierarchy!
-    $output .= '<p><strong>';
-    $output .= t('There are no levels yet in this !hierarchy!', array('!hierarchy' => $strings['hierarchy']));
-    $output .= '</strong></p>';
-  }
-  $output .= '</div>';
-
-  // Render the remaining form items.
-  $output .= drupal_render($form);
-
-  return $output;
-}
-
-/**
  * Submit callback for the hierarchical_select_common_config_form form.
  */
-function hierarchical_select_common_config_form_submit($form_id, $form_values, $parents) {
-  $config = _hierarchical_select_get_form_item_by_parents($form_values, $parents);
+function hierarchical_select_common_config_form_submit($form, &$form_state) {
+  $config = _hierarchical_select_get_form_item_by_parents($form_state['values'], $form['#hs_common_config_form_parents']);
 
   // Don't include the value of the live preview in the config.
   unset($config['live_preview']);
Index: includes/theme.inc
===================================================================
RCS file: includes/theme.inc
diff -N includes/theme.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ includes/theme.inc	13 Sep 2008 17:44:09 -0000
@@ -0,0 +1,309 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * All theme functions for the Hierarchical Select module.
+ */
+
+
+/**
+ * @ingroup themeable
+ * @{
+ */
+
+/**
+* Format a hierarchical select.
+*
+* @param $element
+*   An associative array containing the properties of the element.
+* @return
+*   A themed HTML string representing the form element.
+*/
+function theme_hierarchical_select($element) {
+ $output = '';
+
+ // Update $element['#attributes']['class'].
+ $hsid = $element['hsid']['#value'];
+ $level_labels_style = variable_get('hierarchical_select_level_labels_style', 'none');
+ $classes = array(
+  'hierarchical-select-wrapper',
+  "hierarchical-select-level-labels-style-$level_labels_style",
+ );
+ $element['#attributes']['class'] .= ' '. implode(' ', $classes);
+ $element['#attributes']['id'] = "hierarchical-select-$hsid-wrapper";
+
+ $output .= theme(
+   'form_element',
+   array(
+     '#title' => $element['#title'],
+     '#description' => $element['#description'],
+     '#id' => $element['#id'],
+     '#required' => $element['#required'],
+     '#error' => $element['#error'],
+   ),
+   '<div '. drupal_attributes($element['#attributes']) .'>'. $element['#children'] .'</div>'
+ );
+
+ return $output;
+}
+
+/**
+ * Format a select in the .hierarchial-select div: prevent it from being
+ * wrapped in a div. This simplifies the CSS and JS code.
+ *
+ * @param $element
+ *   An associative array containing the properties of the element.
+ * @return
+ *   A themed HTML string representing the form element.
+ */
+// TODO: check if this has changed in D6.
+function theme_hierarchical_select_select($element) {
+  $select = '';
+  $size = $element['#size'] ? ' size="'. $element['#size'] .'"' : '';
+  _form_set_class($element, array('form-select'));
+  $multiple = isset($element['#multiple']) && $element['#multiple'];
+  return '<select name="'. $element['#name'] .''. ($multiple ? '[]' : '') .'"'. ($multiple ? ' multiple="multiple" ' : '') . drupal_attributes($element['#attributes']) .' id="'. $element['#id'] .'" '. $size .'>'. _hierarchical_select_options($element) .'</select>';
+}
+
+/**
+ * Format a textfield in the .hierarchial-select div: prevent it from being
+ * wrapped in a div. This simplifies the CSS and JS code.
+ *
+ * @param $element
+ *   An associative array containing the properties of the element.
+ * @return
+ *   A themed HTML string representing the form element.
+ */
+// TODO: check if this has changed in D6.
+function theme_hierarchical_select_textfield($element) {
+  $size = $element['#size'] ? ' size="'. $element['#size'] .'"' : '';
+  $class = array('form-text');
+  $extra = '';
+  $output = '';
+
+  if ($element['#autocomplete_path']) {
+    drupal_add_js('misc/autocomplete.js');
+    $class[] = 'form-autocomplete';
+    $extra =  '<input class="autocomplete" type="hidden" id="'. $element['#id'] .'-autocomplete" value="'. check_url(url($element['#autocomplete_path'], NULL, NULL, TRUE)) .'" disabled="disabled" />';
+  }
+  _form_set_class($element, $class);
+
+  if (isset($element['#field_prefix'])) {
+    $output .= '<span class="field-prefix">'. $element['#field_prefix'] .'</span> ';
+  }
+
+  $output .= '<input type="text" maxlength="'. $element['#maxlength'] .'" name="'. $element['#name'] .'" id="'. $element['#id'] .'" '. $size .' value="'. check_plain($element['#value']) .'"'. drupal_attributes($element['#attributes']) .' />';
+
+  if (isset($element['#field_suffix'])) {
+    $output .= ' <span class="field-suffix">'. $element['#field_suffix'] .'</span>';
+  }
+
+  return $output . $extra;
+}
+
+/**
+ * Forms API theming callback for the dropbox. Renders the dropbox as a table.
+ *
+ * @param $element
+ *   An element for which the #theme property was set to this function.
+ * @return
+ *   A themed HTML string.
+ */
+function theme_hierarchical_select_dropbox_table($element) {
+  $output = '';
+
+
+  $title     = $element['title']['#value'];
+  $separator = $element['separator']['#value'];
+  $is_empty  = $element['is_empty']['#value'];
+
+  $separator_html = '<span class="dropbox-item-separator">'. $separator .'</span>';
+
+  $output .= '<div class="dropbox">';
+  $output .= '<table>';
+  $output .= '<caption class="dropbox-title">'. $title .'</caption>';
+  $output .= '<tbody>';
+
+  if (!$is_empty) {
+    // Each lineage in the dropbox corresponds to an entry in the dropbox table.
+    $lineage_count = count(element_children($element['lineages']));
+    for ($x = 0; $x < $lineage_count; $x++) {
+      $db_entry = $element['lineages'][$x];
+      $zebra = $db_entry['#zebra'];
+      $first = $db_entry['#first'];
+      $last  = $db_entry['#last'];
+      // The deepest level is the number of child levels minus one. This "one"
+      // is the element for the "Remove" checkbox.
+      $deepest_level = count(element_children($db_entry)) - 1;
+
+      $output .= '<tr class="dropbox-entry '. $first .' '. $last .' '. $zebra .'">';
+      $output .= '<td>';
+      // Each item in a lineage is separated by the separator string.
+      for ($depth = 0; $depth < $deepest_level; $depth++) {
+        $output .= drupal_render($db_entry[$depth]);
+
+        if ($depth < $deepest_level - 1) {
+          $output .= $separator_html;
+        }
+      }
+      $output .= '</td>';
+      $output .= '<td class="dropbox-remove">'. drupal_render($db_entry['remove']) .'</td>';
+      $output .= '</tr>';
+    }
+  }
+  else {
+    $output .= '<tr class="dropbox-entry first last dropbox-is-empty"><td>';
+    $output .= t('Nothing has been selected.');
+    $output .= '</td></tr>';
+  }
+
+  $output .= '</tbody>';
+  $output .= '</table>';
+  $output .= '</div>';
+
+  return $output;
+}
+
+/**
+ * Themeing function to render the level_labels settings as a table.
+ */
+// TODO: rename $form to $element for consistency (and update hook_theme() after that), make the comment consistent.
+function theme_hierarchical_select_common_config_form_level_labels($form) {
+  // Recover the stored strings.
+  $strings = $form['#strings'];
+
+  $output = '';
+  $header = array(t('Level'), t('Label'));
+  $rows = array();
+
+  $output .= drupal_render($form['status']);
+
+  $output .= '<div class="level-labels-settings">';
+  if (count(element_children($form['labels']))) {
+    foreach (element_children($form['labels']) as $depth) {
+      $row = array();
+      $row[]['data'] = ($depth == 0) ? t('Root level') : t('Sublevel !depth', array('!depth' => $depth));
+      $row[]['data'] = drupal_render($form['labels'][$depth]);
+      $rows[] = $row;
+    }
+
+    // Render the table.
+    $output .= theme('table', $header, $rows, array('style' => 'width: auto;'));
+  }
+  else {  
+    // No levels exist yet in the hierarchy!
+    $output .= '<p><strong>';
+    $output .= t('There are no levels yet in this !hierarchy!', array('!hierarchy' => $strings['hierarchy']));
+    $output .= '</strong></p>';
+  }
+  $output .= '</div>';
+
+  // Render the remaining form items.
+  $output .= drupal_render($form);
+
+  return $output;
+}
+
+/**
+ * Themeing function to render the per-level editability settings as a table,
+ * (these are the item_types and allowed_levels settings).
+ */
+// TODO: rename $form to $element for consistency (and update hook_theme() after that), make the comment consistent.
+function theme_hierarchical_select_common_config_form_editability($form) {
+  // Recover the stored strings.
+  $strings = $form['#strings'];
+
+  $output = '';
+  $header = array(t('Level'), t('Allow'), t('!item_type', array('!item_type' => ucfirst($strings['item_type']))));
+  $rows = array();
+
+  $output .= drupal_render($form['status']);
+
+  $output .= '<div class="editability-per-level-settings">';
+  if (count(element_children($form['item_types']))) {
+    foreach (element_children($form['item_types']) as $depth) {
+      $row = array();
+      $row[]['data'] = ($depth == 0) ? t('Root level') : t('Sublevel !depth', array('!depth' => $depth));
+      $row[]['data'] = drupal_render($form['allowed_levels'][$depth]);
+      $row[]['data'] = drupal_render($form['item_types'][$depth]);
+      $rows[] = $row;
+    }
+
+    // Render the table and description.
+    $output .= theme('table', $header, $rows, array('style' => 'width: auto;'), '<em>'. t('Per-level settings for creating new !items.', array('!items' => $strings['items'])));
+    $output .= '<div class="description">';
+    $output .= t(
+      'The %item_type you enter for each level is what will be used in
+      each level to replace a "&lt;create new item&gt;" option with a
+      "&lt;create new %item_type&gt;" option, which is often more
+      intuitive.',
+      array(
+        '%item_type' => $strings['item_type'],
+      )
+    );
+    $output .= '</div>';
+  }
+  else {  
+    // No levels exist yet in the hierarchy!
+    $output .= '<p><strong>';
+    $output .= t('There are no levels yet in this !hierarchy!', array('!hierarchy' => $strings['hierarchy']));
+    $output .= '</strong></p>';
+  }
+  $output .= '</div>';
+
+  // Render the remaining form items.
+  $output .= drupal_render($form);
+
+  return $output;
+}
+
+/**
+ * @} End of "ingroup themeable".
+ */
+
+
+//----------------------------------------------------------------------------
+// Private functions.
+
+/**
+ * This is an altered clone of form_select_options(). The reason: I need to be
+ * able to set a class on an option element if it contains a level label, to
+ * allow for level label styles.
+ * TODO: rename to _hierarchical_select_select_options().
+ */
+// TODO: check if this has changed in D6.
+function _hierarchical_select_options($element) {
+  if (!isset($choices)) {
+    $choices = $element['#options'];
+  }
+  // array_key_exists() accommodates the rare event where $element['#value'] is NULL.
+  // isset() fails in this situation.
+  $value_valid = isset($element['#value']) || array_key_exists('#value', $element);
+  $value_is_array = is_array($element['#value']);
+  $options = '';
+  foreach ($choices as $key => $choice) {
+    $key = (string)$key;
+    if ($value_valid && (!$value_is_array && (string)$element['#value'] === $key || ($value_is_array && in_array($key, $element['#value'])))) {
+      $selected = ' selected="selected"';
+    }
+    else {
+      $selected = '';
+    }
+
+    // If an option DOES NOT have child info, then it's a special option:
+    // - label_\d+ (level label)
+    // - none ("<none>")
+    // - create_new_item ("<create new item>")
+    // Only when it's a level label, we have to add a class to this option.
+    if (!isset($element['#childinfo'][$key])) {
+      $class = (preg_match('/label_\d+/', $key)) ? ' level-label' : '';
+    }
+    else {
+      $class = ($element['#childinfo'][$key] == 0) ? 'has-no-children' : 'has-children';
+    }
+    
+    $options .= '<option value="'. check_plain($key) .'" class="'. $class .'"'. $selected .'>'. check_plain($choice) .'</option>';
+  }
+  return $options;
+}
Index: modules/hs_content_taxonomy.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/modules/hs_content_taxonomy.module,v
retrieving revision 1.30
diff -u -F^f -r1.30 hs_content_taxonomy.module
--- modules/hs_content_taxonomy.module	10 Aug 2008 16:16:53 -0000	1.30
+++ modules/hs_content_taxonomy.module	13 Sep 2008 17:44:09 -0000
@@ -161,14 +161,14 @@ function hs_content_taxonomy_config_form
 /**
  * Additional submit callback to update the multiple values field setting.
  */
-function hs_content_taxonomy_common_config_form_submit($form_id, $form_values, $content_type_name, $field_name) {
-  $config = $form_values['hierarchical_select_config'];
+function hs_content_taxonomy_common_config_form_submit($form_id, $form_state['values'], $content_type_name, $field_name) {
+  $config = $form_state['values']['hierarchical_select_config'];
   $multiple_values = ($config['save_lineage'] | $config['dropbox']['status']);
 
   $content_type = content_types($content_type_name);
   $field = $content_type['fields'][$field_name];
 
-  $form_values = array(
+  $form_state['values'] = array(
     'widget_type' => 'content_taxonomy_hs',
     'label'       => $field['widget']['label'],
     'weight'      => $field['widget']['weight'],
@@ -188,7 +188,7 @@ function hs_content_taxonomy_common_conf
     'form_id'     => '_content_admin_field',
   );
 
-  drupal_execute('_content_admin_field', $form_values, $field['type_name'], $field_name);
+  drupal_execute('_content_admin_field', $form_state['values'], $field['type_name'], $field_name);
 }
 
 
Index: modules/hs_content_taxonomy_views.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/modules/hs_content_taxonomy_views.module,v
retrieving revision 1.15
diff -u -F^f -r1.15 hs_content_taxonomy_views.module
--- modules/hs_content_taxonomy_views.module	13 Aug 2008 23:19:12 -0000	1.15
+++ modules/hs_content_taxonomy_views.module	13 Sep 2008 17:44:10 -0000
@@ -300,6 +300,11 @@ function hs_content_taxonomy_views_confi
 /**
  * Additional submit callback to redirect the user to the "Edit view" form.
  */
+<<<<<<< hs_content_taxonomy_views.module
+function hs_content_taxonomy_views_common_config_form_submit($form_id, $form_state['values'], $view_name) {
+  if ($form_state['values']['hierarchical_select_config']['save_lineage']) {
+    drupal_set_message(t('You have enabled the <em>Save lineage</em> setting. Please resave this view.'));
+=======
 function hs_content_taxonomy_views_common_config_form_submit($form_id, $form_values, $view_name) {
   if ($form_values['hierarchical_select_config']['save_lineage'] || $form_values['hierarchical_select_config']['dropbox']['status']) {
     if ($form_values['hierarchical_select_config']['save_lineage']) {
@@ -308,6 +313,7 @@ function hs_content_taxonomy_views_commo
     if ($form_values['hierarchical_select_config']['dropbox']['status']) {
       drupal_set_message(t('You have enabled the <em>Dropbox</em> setting. Please resave this view.'));
     }
+>>>>>>> 1.15
     drupal_goto("admin/build/views/$view_name/edit");
   }
 }
Index: modules/hs_flatlist.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/modules/hs_flatlist.info,v
retrieving revision 1.1
diff -u -F^f -r1.1 hs_flatlist.info
--- modules/hs_flatlist.info	3 Jul 2008 23:20:30 -0000	1.1
+++ modules/hs_flatlist.info	13 Sep 2008 17:44:10 -0000
@@ -3,3 +3,4 @@
 description = Allows Hierarchical Select's dropbox to be used for selecting multiple items in a flat list of options.
 dependencies = hierarchical_select
 package = Form Elements
+core = 6.x
Index: modules/hs_menu.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/modules/hs_menu.info,v
retrieving revision 1.1
diff -u -F^f -r1.1 hs_menu.info
--- modules/hs_menu.info	28 Jun 2008 12:24:53 -0000	1.1
+++ modules/hs_menu.info	13 Sep 2008 17:44:10 -0000
@@ -1,5 +1,7 @@
 ; $Id: hs_menu.info,v 1.1 2008/06/28 12:24:53 wimleers Exp $
 name = Hierarchical Select Menu
 description = Use Hierarchical Select for menu parent selection.
-dependencies = hierarchical_select menu
+dependencies[] = hierarchical_select
+dependencies[] = menu
 package = Form Elements
+core = 6.x
Index: modules/hs_menu.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/modules/hs_menu.module,v
retrieving revision 1.4
diff -u -F^f -r1.4 hs_menu.module
--- modules/hs_menu.module	26 Jul 2008 10:40:20 -0000	1.4
+++ modules/hs_menu.module	13 Sep 2008 17:44:10 -0000
@@ -13,17 +13,17 @@
 /**
  * Implementation of hook_form_alter().
  */
-function hs_menu_form_alter($form_id, &$form) {
+function hs_menu_form_alter(&$form, &$form_state, $form_id) {
   if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id) {
-    unset($form['menu']['pid']['#options']);
-    $form['menu']['pid']['#type'] = 'hierarchical_select';
-    _hs_menu_apply($form['menu']['pid'], NULL);
+    unset($form['menu']['parent']['#options']);
+    $form['menu']['parent']['#type'] = 'hierarchical_select';
+    _hs_menu_apply_config($form['menu']['parent'], NULL);
   }
-  
-  if ($form_id == 'menu_edit_item_form') {
-    unset($form['pid']['#options']);
-    $form['pid']['#type'] = 'hierarchical_select';
-    _hs_menu_apply($form['pid'], NULL);
+
+  if ($form_id == 'menu_edit_item') {
+    unset($form['menu']['parent']['#options']);
+    $form['menu']['parent']['#type'] = 'hierarchical_select';
+    _hs_menu_apply_config($form['menu']['parent'], array($form['menu']['#item']['menu_name'], $form['menu']['#item']['mlid']));
   }
 }
 
@@ -36,7 +36,7 @@ function hs_menu_form_alter($form_id, &$
  */
 function hs_menu_hierarchical_select_params() {
   $params = array(
-    'mid', // The mid of the given item. This item and its children will be excluded from the hierarchy.
+    'exclude', // The menu_name and mlid (in an array) of a menu link that should be excluded from the hierarchy.
   );
   return $params;
 }
@@ -45,7 +45,14 @@ function hs_menu_hierarchical_select_par
  * Implementation of hook_hierarchical_select_root_level().
  */
 function hs_menu_hierarchical_select_root_level($params) {
-  return hs_menu_hierarchical_select_children(0, $params);
+  $menus = array();
+
+  $result = db_query("SELECT menu_name, title FROM {menu_custom} ORDER BY title");
+  while ($menu = db_fetch_object($result)) {
+    $menus[$menu->menu_name . ':0'] = $menu->title;
+  }
+
+  return $menus;
 }
 
 /**
@@ -53,34 +60,9 @@ function hs_menu_hierarchical_select_roo
  */
 function hs_menu_hierarchical_select_children($parent, $params) {
   $children = array();
-  $mid = $params['mid'];
-  $pid = $parent;
-
-  if (!($parent_item = menu_get_item($pid))) {
-    return $children;
-  }
-  // Stop processing if there aren't any children.
-  else if (!isset($parent_item['children'])) {
-    return $children;
-  }
-
-  foreach ($parent_item['children'] as $child_mid) {
-    // Don't include the given item in the hierarchy!
-    if ($child_mid == $params['mid']) {
-      continue;
-    }
-
-    $child = menu_get_item($child_mid);
-    if ($child['type'] & (MENU_MODIFIABLE_BY_ADMIN | MENU_IS_ROOT)) {
-      $title = $child['title'];
-      if (!($child['type'] & MENU_VISIBLE_IN_TREE)) {
-        $title .= ' ('. t('disabled') .')';
-      }
-      $children[$child_mid] = $title;
-    }
-  }
-
-  return $children;
+  list($menu_name, $plid) = explode(':', $parent);
+  $tree = menu_tree_all_data($menu_name, NULL);
+  return _hs_menu_children($tree, $menu_name, $plid, $params['exclude']);
 }
 
 /**
@@ -89,15 +71,18 @@ function hs_menu_hierarchical_select_chi
 function hs_menu_hierarchical_select_lineage($item, $params) {
   $lineage = array($item);
 
-  while (TRUE) {
-    $pid = db_result(db_query("SELECT pid FROM {menu} WHERE mid = %d", $item));
-
-    // 0 is the root menu item, so if $pid == 0, the lineage is complete!
-    if ($pid == 0)
-      break;
+  list($menu_name, $mlid) = explode(':', $item);
 
-    array_unshift($lineage, $pid);
-    $item = $pid;
+  // If the initial mlid is zero, then this is the root level, so we don't
+  // have to get the lineage.
+  if ($mlid > 0) {
+    // Prepend each parent mlid (i.e. plid) to the lineage.
+    do {
+      $plid = db_result(db_query("SELECT plid FROM {menu_links} WHERE mlid = %d", $mlid));
+      array_unshift($lineage, "$menu_name:$plid");
+      $mlid = $plid;
+    }
+    while ($plid > 0);
   }
 
   return $lineage;
@@ -107,14 +92,17 @@ function hs_menu_hierarchical_select_lin
  * Implementation of hook_hierarchical_select_valid_item().
  */
 function hs_menu_hierarchical_select_valid_item($item, $params) {
-  if (!is_numeric($item) || $item < 1) {
-    return FALSE;
+  $parts = explode(':', $item);
+
+  $valid = TRUE;
+  for ($i = 1; $i < count($parts); $i++) {
+    $valid = $valid && is_numeric($parts[$i]);
   }
 
-  $type = db_result(db_query("SELECT type FROM {menu} WHERE mid = %d", $item));
+  // Ensure that this isn't the excluded menu link.
+  $valid = $valid && $item != $params['exclude'][0] . $params['exclude'][1];
 
-  // mid 1 corresponds to the hardcoded "Navigation" menu.
-  return (($item == 1) || ($type & (MENU_MODIFIABLE_BY_ADMIN | MENU_IS_ROOT)));
+  return $valid;
 }
 
 /**
@@ -122,9 +110,16 @@ function hs_menu_hierarchical_select_val
  */
 function hs_menu_hierarchical_select_item_get_label($item, $params) {
   static $labels = array();
-
-  if (!isset($labels[$item])) {
-    $labels[$item] = t(db_result(db_query("SELECT title FROM {menu} WHERE mid = %d", $item)));
+  
+  $parts = explode(':', $item);
+  if (count($parts) == 1) { // Get the menu name.
+    $menu_name = $parts[0];
+    $labels[$item] = t(db_result(db_query("SELECT title FROM {menu_custom} WHERE menu_name = '%s'", $menu_name)));
+  }
+  else { // Get the menu link title.
+    $mlid = end($parts);
+    $menu_link = menu_link_load($mlid);
+    $labels[$item] = $menu_link['title'];
   }
 
   return $labels[$item];
@@ -144,11 +139,44 @@ function hs_menu_hierarchical_select_imp
 //----------------------------------------------------------------------------
 // Private functions.
 
-function _hs_menu_apply(&$form, $mid) {
+/**
+ * Recursive helper function for hs_menu_hierarchical_select_children().
+ */
+function _hs_menu_children($tree, $menu_name, $plid = 0, $exclude = FALSE) {
+  global $yar;
+  $children = array();
+
+  foreach ($tree as $data) {
+    if ($data['link']['plid'] == $plid && $data['link']['hidden'] >= 0) {
+      if ($exclude && $data['link']['menu_name'] === $exclude[0] && $data['link']['mlid'] == $exclude[1]) {
+        continue;
+      }
+
+      $title = truncate_utf8($data['link']['title'], 30, TRUE, FALSE);
+      if ($data['link']['hidden']) {
+        $title .= ' ('. t('disabled') .')';
+      }
+      $children[$menu_name .':'. $data['link']['mlid']] = $title;
+      if ($data['below']) {
+        $children += _hs_menu_children($data['below'], $menu_name, $plid, $exclude);
+      }
+    }
+    elseif ($data['below']) {
+      $children += _hs_menu_children($data['below'], $menu_name, $plid, $exclude);
+    }
+  }
+
+  return $children;
+}
+
+/**
+ * Helper function to apply the HS config to a form item.
+ */
+function _hs_menu_apply_config(&$form, $exclude) {
   $form['#config'] = array(
     'module' => 'hs_menu',
     'params' => array(
-      'mid' => $mid,
+      'exclude' => $exclude,
     ),
     'save_lineage'    => 0,
     'enforce_deepest' => 0,
Index: modules/hs_subscriptions_taxonomy.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/modules/hs_subscriptions_taxonomy.module,v
retrieving revision 1.3
diff -u -F^f -r1.3 hs_subscriptions_taxonomy.module
--- modules/hs_subscriptions_taxonomy.module	16 Jul 2008 21:12:23 -0000	1.3
+++ modules/hs_subscriptions_taxonomy.module	13 Sep 2008 17:44:10 -0000
@@ -34,7 +34,7 @@ function hs_subscriptions_taxonomy_form_
 
         // 1) Extract the tids of the selected terms.
         // 2) Make the checkboxes value form elements, to keep the form
-        // structure (and the $form_values structure) the same as the original.
+        // structure (and the $form_state['values'] structure) the same as the original.
         $selected_tids = array();
         foreach ($form[$name]['checkboxes'] as $tid => $element) {
           // Selected?
@@ -90,14 +90,14 @@ function hs_subscriptions_taxonomy_form_
 /**
  * Validate callback; per-user taxonomy subscriptions form.
  */
-function hs_subscriptions_taxonomy_validate($form_id, $form_values, $form) {
+function hs_subscriptions_taxonomy_validate($form_id, $form_state['values'], $form) {
   if ($form_id == 'subscriptions_taxonomy_taxa_form') {
-    foreach ($form_values as $vid => $element) {
+    foreach ($form_state['values'] as $vid => $element) {
       if (is_numeric($vid)) {
 
         // Collect the tids of the selected terms.
         $selected_tids = array();
-        foreach ($form_values[$vid]['select'] as $tid) {
+        foreach ($form_state['values'][$vid]['select'] as $tid) {
           $selected_tids[] = $tid;
         }
 
@@ -105,8 +105,8 @@ function hs_subscriptions_taxonomy_valid
         // - When it's in the set of selected tids, then set it to 1.
         // - When it's *not* in the set of selected tids, and its current value
         //   is 1, then set it to 0.
-        foreach ($form_values[$vid]['checkboxes'] as $tid => $array) {
-          if (!in_array($tid, $selected_tids) && $form_values[$vid]['checkboxes'][$tid][-1] == 1) {
+        foreach ($form_state['values'][$vid]['checkboxes'] as $tid => $array) {
+          if (!in_array($tid, $selected_tids) && $form_state['values'][$vid]['checkboxes'][$tid][-1] == 1) {
             form_set_value($form[$vid]['checkboxes'][$tid][-1], 0);
           }
           else if (in_array($tid, $selected_tids)) {
Index: modules/hs_taxonomy.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/modules/hs_taxonomy.info,v
retrieving revision 1.1
diff -u -F^f -r1.1 hs_taxonomy.info
--- modules/hs_taxonomy.info	28 Jun 2008 18:25:28 -0000	1.1
+++ modules/hs_taxonomy.info	13 Sep 2008 17:44:10 -0000
@@ -1,5 +1,7 @@
-; $I$
+; $Id$
 name = Hierarchical Select Taxonomy
 description = Use Hierarchical Select for Taxonomy.
-dependencies = hierarchical_select taxonomy
+dependencies[] = hierarchical_select
+dependencies[] = taxonomy
 package = Form Elements
+core = 6.x
Index: modules/hs_taxonomy.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/modules/hs_taxonomy.module,v
retrieving revision 1.17
diff -u -F^f -r1.17 hs_taxonomy.module
--- modules/hs_taxonomy.module	29 Aug 2008 23:53:08 -0000	1.17
+++ modules/hs_taxonomy.module	13 Sep 2008 17:44:10 -0000
@@ -13,7 +13,7 @@
 /**
  * Implementation of hook_form_alter().
  */
-function hs_taxonomy_form_alter($form_id, &$form) {
+function hs_taxonomy_form_alter(&$form, &$form_state, $form_id) {
   // Add per-vocabulary settings for Hierarchical Select.
   if ($form_id == 'taxonomy_form_vocabulary') {
     require_once(drupal_get_path('module', 'hierarchical_select') .'/includes/common.inc');
@@ -62,7 +62,7 @@ function hs_taxonomy_form_alter($form_id
       'root_term'   => NULL,
     );
     $config_id = "taxonomy-$vid";
-    $vocabulary = taxonomy_get_vocabulary($vid);
+    $vocabulary = taxonomy_vocabulary_load($vid);
     $defaults = array(
       // Enable the save_lineage setting by default if the multiple parents
       // vocabulary option is enabled.
@@ -99,14 +99,13 @@ function hs_taxonomy_form_alter($form_id
 
     // Add the the submit handler for the Hierarchical Select config form.
     $parents = array('hierarchical_select');
-    $form['#submit']['hierarchical_select_common_config_form_submit'] = array($parents);
+    $form['#submit'][] = 'hierarchical_select_common_config_form_submit';
+    $form['#hs_common_config_form_parents'] = $parents;
 
     // Add a validate callback to override the freetagging and multiple select
     // settings if necessary.
-    if (variable_get("taxonomy_hierarchical_select_$vid", 0)) {
-      $form['#validate']['hierarchical_select_taxonomy_form_vocabulary_validate'] = array();
-      $form['#submit']['hierarchical_select_taxonomy_form_vocabulary_submit'] = array();
-    }
+    $form['#validate'][] = 'hierarchical_select_taxonomy_form_vocabulary_validate';
+    $form['#submit'][]   = 'hierarchical_select_taxonomy_form_vocabulary_submit';
 
     // The original #submit callback(s) has/have to be executed afterwards.
     $form['#submit'] = array_merge($form['#submit'], $second_part['#submit']);
@@ -143,19 +142,47 @@ function hs_taxonomy_form_alter($form_id
 
   // The taxonomy term form.
   else if ($form_id == 'taxonomy_form_term') {
-    unset($form['parent']['#options']);
-    unset($form['parent']['#theme']);
-    $form['parent']['#type'] = 'hierarchical_select';
-    $form['parent']['#config'] = array(
-      'module'          => 'hs_taxonomy',
+    require_once(drupal_get_path('module', 'hierarchical_select') .'/includes/common.inc');
+
+    // Build an appropriate config, that inherits the level_labels settings
+    // from the vocabulary's Hierarchical Select config.
+    $vid = $form['#vocabulary']['vid'];
+    $vocabulary_config = hierarchical_select_common_config_get("taxonomy-$vid");
+    $config = array(
+      'module' => 'hs_taxonomy',
+      'params' => array(
+        'vid'         => $vid,
+        'exclude_tid' => $form['#term']['tid'],
+      ),
       'enforce_deepest' => 0,
       'save_lineage'    => 0,
+      'level_labels' => $vocabulary_config['level_labels'],
+      'dropbox' => array(
+        'status'   => 1,
+      ),
       'params' => array(
         'vid'         => $form['vid']['#value'],
         'exclude_tid' => $form['tid']['#value'],
         'root_term'   => TRUE,
       ),
     );
+
+    // Use Hierarchical Select for selecting the parent term(s).
+    unset($form['advanced']['parent']['#options']);
+    unset($form['advanced']['parent']['#theme']);
+    unset($form['advanced']['parent']['#size']);
+    $form['advanced']['parent']['#type'] = 'hierarchical_select';
+    $form['advanced']['parent']['#config'] = $config;
+    $form['advanced']['parent']['#config']['dropbox']['title'] = t('All parent terms');
+
+    // Use Hierarchical Select for selecting the related term(s).
+    unset($form['advanced']['relations']['#options']);
+    unset($form['advanced']['relations']['#theme']);
+    unset($form['advanced']['relations']['#size']);
+    $form['advanced']['relations']['#type'] = 'hierarchical_select';
+    $form['advanced']['relations']['#config'] = $config;
+    $form['advanced']['relations']['#config']['dropbox']['title'] = t('All related terms');
+
     // When 'multiple parents' are enabled, we should support that as well!
     if ($form['parent']['#multiple']) {
       unset($form['parent']['#size']);
@@ -290,12 +317,12 @@ function hs_taxonomy_hierarchical_select
  * Implementation of hook_hierarchical_select_create_item().
  */
 function hs_taxonomy_hierarchical_select_create_item($label, $parent, $params) {
-  $form_values = array(
+  $form_state['values'] = array(
     'name'   => $label,
     'parent' => $parent,
     'vid'    => $params['vid'],
   );
-  $status = taxonomy_save_term($form_values);
+  $status = taxonomy_save_term($form_state['values']);
 
   if ($status == SAVED_NEW) {
     // Reset the cached tree.
@@ -377,28 +404,28 @@ function hs_taxonomy_hierarchical_select
 /**
  * Additional validate callback for the taxonomy_form_vocabulary form.
  */
-function hierarchical_select_taxonomy_form_vocabulary_validate($form_id, $form_values, $form) {
+function hierarchical_select_taxonomy_form_vocabulary_validate($form, &$form_state) {
   // The "multiple select" setting doesn't exist for the forum vocabulary!
   if (isset($form['multiple'])) {
     // Enable Taxonomy's "multiple select" setting when:
     // - Hierarchical Select's "multiple select" setting is enabled, or:
     // - Hierarchical Select's "save term lineage" setting is enabled
-    $multiple_select_enabled = ($form_values['hierarchical_select']['dropbox']['status'] || $form_values['hierarchical_select']['save_lineage']);
-    form_set_value($form['multiple'], (int) $multiple_select_enabled);
+    $multiple_select_enabled = ($form_state['values']['hierarchical_select']['dropbox']['status'] || $form_state['values']['hierarchical_select']['save_lineage']);
+    form_set_value($form['multiple'], (int) $multiple_select_enabled, $form_state);
   }
 
   // If Hierarchical Select is enabled, disable freetagging.
-  if ($form_values['hierarchical_select']['status']) {
-    form_set_value($form['tags'], 0);
+  if ($form_state['values']['hierarchical_select']['status']) {
+    form_set_value($form['tags'], 0, $form_state);
   }
 }
 
 /**
  * Additional submit callback for the taxonomy_form_vocabulary form.
  */
-function hierarchical_select_taxonomy_form_vocabulary_submit($form_id, $form_values) {
-  $vid = $form_values['vid'];
-  variable_set("taxonomy_hierarchical_select_$vid", $form_values['hierarchical_select_status']);
+function hierarchical_select_taxonomy_form_vocabulary_submit($form, &$form_state) {
+  $vid = $form_state['values']['vid'];
+  variable_set("taxonomy_hierarchical_select_$vid", $form_state['values']['hierarchical_select_status'], $form_state);
 }
 
 
Index: modules/taxonomy.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/modules/Attic/taxonomy.js,v
retrieving revision 1.5
diff -u -F^f -r1.5 taxonomy.js
--- modules/taxonomy.js	6 May 2008 19:07:33 -0000	1.5
+++ modules/taxonomy.js	13 Sep 2008 17:44:10 -0000
@@ -12,7 +12,7 @@
       speed = 200;
     }
 
-    var $affected = $('#edit-tags, #edit-multiple').parent().parent();
+    var $affected = $('#edit-tags-wrapper, #edit-multiple-wrapper');
     if ($HSCheckbox.is(':checked')) {
       $affected.hide(speed);
     }
