Index: API.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/API.txt,v
retrieving revision 1.56
diff -u -F^f -r1.56 API.txt
--- API.txt	1 Dec 2008 02:21:17 -0000	1.56
+++ API.txt	28 Mar 2009 11:05:38 -0000
@@ -75,7 +75,7 @@
       // These settings cannot be configured through the UI: they can only be
       // overridden through code.
       'animation_delay'    => 400,
-      'exclusive_lineages' => array(),
+      'special_items'      => array(),
       'render_flat_select' => 0,
     ),
     '#default_value' => '83',
@@ -173,10 +173,35 @@
  - animation_delay (optional, defaults to 400)
    The delay of each animation (the drop in left and right animations), in ms.
 
- - exclusive_lineages (optional, defaults to the empty array)
-   Sometimes, it's desirable to have exclusive lineages. When one of these
-   lineages is selected, the user should not be able to select anything else.
-   e.g. the **ALL** option in Views exposed filters.
+ - special_items (optional, defaults to the empty array)
+   Through this setting, you can mark each item with special properties it
+   possesses. There currently are two special properties: 'exclusive' and
+   'none'.
+   Note: you should include these items in the hierarchy as if it were a
+   normal item and then you can mark them as special through this property.
+   * 'exclusive': Sometimes it's desirable to have exclusive lineages. When
+                  such an option is selected, the user should not be able to
+                  select anything else. This also means that  nothing else in
+                  the dropbox can be selected: if the dropbox contains
+                  anything, it will be reset.
+                  Can be applied to multiple items.
+                  e.g. an 'entire_tree' item:
+                    'special_items' => array(
+                      'entire_tree' => array('exclusive'),
+                    )
+   * 'none': Sometimes you want to replace the default '<none>' option by
+             something else. This replacement should of course also exist in
+             the root level.
+             Can be applied to only one item.
+             e.g. an 'any' item (used in hs_taxonomy_views):
+               'special_items' => array(
+                 'any' => array('none', 'exclusive'),
+               )
+   And a final example for a better overview:
+    'special_items' => array(
+      'entire_tree' => array('exclusive'),
+      'any'         => array('none', 'exclusive'),
+    )
 
  - render_flat_select (optional, defaults to 0)
    Because the hierarchical_select form element consists of multiple form
Index: hierarchical_select.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/hierarchical_select.js,v
retrieving revision 1.92
diff -u -F^f -r1.92 hierarchical_select.js
--- hierarchical_select.js	28 Mar 2009 00:24:50 -0000	1.92
+++ hierarchical_select.js	28 Mar 2009 11:05:39 -0000
@@ -19,6 +19,11 @@
 };
 
 Drupal.HierarchicalSelect.initialize = function(hsid) {
+  // Prevent JS errors when Hierarchical Select is loaded dynamically.
+  if (undefined == Drupal.settings.HierarchicalSelect || undefined == Drupal.settings.HierarchicalSelect.settings[hsid]) {
+    return false;
+  }
+
   // If you set Drupal.settings.HierarchicalSelect.pretendNoJS to *anything*,
   // and as such, Hierarchical Select won't initialize its Javascript! It
   // will seem as if your browser had Javascript disabled.
Index: hierarchical_select.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/hierarchical_select.module,v
retrieving revision 1.160
diff -u -F^f -r1.160 hierarchical_select.module
--- hierarchical_select.module	21 Mar 2009 20:07:46 -0000	1.160
+++ hierarchical_select.module	28 Mar 2009 11:05:40 -0000
@@ -119,7 +119,7 @@ function hierarchical_select_elements() 
         'max_levels'       => 3,
       ),
       'animation_delay'    => variable_get('hierarchical_select_animation_delay', 400),
-      'exclusive_lineages' => array(),
+      'special_items'      => array(),
       'render_flat_select' => 0,
     ),
     '#default_value' => -1,
@@ -282,6 +282,16 @@ function hierarchical_select_json() {
 
   $hs_form_build_id = $_POST['hs_form_build_id'];
 
+  // [VIEWS] TRICKY: If the form is a Views exposed filters form, we stored
+  // the View name in a cache entry (in hierarchical_select_after_build()) so
+  // that we can load the View object here, before retrieving the parameters
+  // of the form - from which this View object is referenced.
+  $cached = cache_get('hs_view_'. $hs_form_build_id);
+  if (isset($cached->data)) {
+    $tmp_view = views_get_view($cached->data);
+    $tmp_view->execute_display();
+  }
+
   // Collect all necessary variables.
   $cached = cache_get($hs_form_build_id, 'cache');
   $storage = $cached->data;
@@ -341,7 +351,7 @@ function hierarchical_select_json() {
 /**
  * Hierarchical select form element type #process callback.
  */
-function hierarchical_select_process($element, $edit, $form_state, $form) {
+function hierarchical_select_process($element, $edit, &$form_state, $form) {
   static $hsid;
 
   if (!isset($hsid)) {
@@ -365,27 +375,35 @@ function hierarchical_select_process($el
   // necessary to find this form item back in an AJAX callback.
   _hierarchical_select_store_name($element, $hsid);
 
+  // Get the config and convert the 'special_items' setting to a more easily
+  // accessible format.
+  $config = $element['#config'];
+  if (isset($config['special_items'])) {
+    $special_items['exclusive'] = array_keys(array_filter($config['special_items'], '_hierarchical_select_special_item_exclusive'));
+    $special_items['none']      = array_keys(array_filter($config['special_items'], '_hierarchical_select_special_item_none'));
+  }
+
   // Set up Javascript and add settings specifically for the current
   // hierarchical select.
   $config = $element['#config'];
-  _hierarchical_select_setup_js();
-  drupal_add_js(
-    array(
-      'HierarchicalSelect' => array(
-        'settings' => array(
-          $hsid => array(
-            'animationDelay'   => ($config['animation_delay'] == 0) ? (int) variable_get('hierarchical_select_animation_delay', 400) : $config['animation_delay'],
-            'cacheId'          => $config['module'] .'_'. implode('_', (is_array($config['params'])) ? $config['params'] : array()),
-            'renderFlatSelect' => (isset($config['render_flat_select'])) ? (int) $config['render_flat_select'] : 0,
-            'createNewItems'   => (isset($config['editability']['status'])) ? (int) $config['editability']['status'] : 0,
-            'createNewLevels'  => (isset($config['editability']['allow_new_levels'])) ? (int) $config['editability']['allow_new_levels'] : 0,
-            'resizable'        => (isset($config['resizable'])) ? (int) $config['resizable'] : 0,
-          ),
+//     if (!isset($_POST['form_build_id'])) {	
+  _hierarchical_select_setup_js($form_state);
+  $settings =  array(
+    'HierarchicalSelect' => array(
+      'settings' => array(
+        $hsid => array(
+          'animationDelay'   => ($config['animation_delay'] == 0) ? (int) variable_get('hierarchical_select_animation_delay', 400) : $config['animation_delay'],
+          'cacheId'          => $config['module'] .'_'. implode('_', (is_array($config['params'])) ? $config['params'] : array()),
+          'renderFlatSelect' => (isset($config['render_flat_select'])) ? (int) $config['render_flat_select'] : 0,
+          'createNewItems'   => (isset($config['editability']['status'])) ? (int) $config['editability']['status'] : 0,
+          'createNewLevels'  => (isset($config['editability']['allow_new_levels'])) ? (int) $config['editability']['allow_new_levels'] : 0,
+          'resizable'        => (isset($config['resizable'])) ? (int) $config['resizable'] : 0,
         ),
-      )
-    ),
-    'setting'
+      ),
+    )
   );
+  _hierarchical_select_add_js_settings($settings, $form_state);
+//}
 
   // Basic config validation and diagnostics.
   if (HS_DEVELOPER_MODE) {
@@ -431,10 +449,12 @@ function hierarchical_select_process($el
     }
   }
 
-  // If the exclusive_lineages setting has been configured, and the dropbox
-  // is enabled, then do the necessary processing to make exclusive lineages
-  // possible.
-  if (count($config['exclusive_lineages']) && $config['dropbox']['status']) {
+  // If:
+  // - the special_items setting has been configured
+  // - at least one special item has the 'exclusive' property
+  // - the dropbox is enabled
+  // then do the necessary processing to make exclusive lineages possible.
+  if (isset($config['special_items']) && count($special_items['exclusive']) && $config['dropbox']['status']) {
     // When the form is first loaded, $db_selection will contain the selection
     // that we should check, but in updates, $hs_selection will.
     $selection = (!empty($hs_selection)) ? $hs_selection : $db_selection;
@@ -442,8 +462,8 @@ function hierarchical_select_process($el
     // If the current selection of the hierarchical select matches one of the
     // configured exclusive items, then disable the dropbox (to ensure an
     // exclusive selection).
-    if (in_array($selection, $config['exclusive_lineages']) // A lineage.
-        || (count($selection) == 1 && in_array($selection[0], $config['exclusive_lineages']))) { // An item at the root level.
+    if (in_array($selection, $special_items['exclusive']) // A lineage.
+        || (count($selection) == 1 && in_array($selection[0], $special_items['exclusive']))) { // An item at the root level.
       // By also updating the configuration stored in $element, we ensure that
       // the validation step, which extracts the configuration again, also gets
       // the updated config.
@@ -631,16 +651,14 @@ function hierarchical_select_process($el
 
   if (HS_DEVELOPER_MODE) {
     $element['log'] = array('#type' => 'value', '#value' => _hierarchical_select_log(NULL, TRUE));
-    drupal_add_js(
-      array(
-        'HierarchicalSelect' => array(
-          'initialLog' => array(
-            $hsid => $element['log']['#value'],
-          ),
+    $settings = array(
+      'HierarchicalSelect' => array(
+        'initialLog' => array(
+          $hsid => $element['log']['#value'],
         ),
       ),
-      'setting'
     );
+    _hierarchical_select_add_js_settings($settings, $form_state);
   }
 
   // If the form item is marked as disabled, disable all child form items as
@@ -656,6 +674,13 @@ function hierarchical_select_process($el
   * Hierarchical select form element type #after_build callback.
   */
 function hierarchical_select_after_build($form, &$form_state) {
+  // TRICKY: Pageroute compatibility: avoid that the body of this #after_build
+  // callback is executed twice.
+  if (isset($form['hs_form_build_id'])) {
+    dpm('hs form build id is already set');
+    return $form;
+  }
+
   $names = _hierarchical_select_store_name(NULL, NULL, TRUE);
 
   if (!isset($_POST['hs_form_build_id']) && count($names)) {
@@ -681,6 +706,14 @@ function hierarchical_select_after_build
     // render part of the form).
     $hs_form_build_id = 'hs_form_'. md5(mt_rand());
     cache_set($hs_form_build_id, $storage, 'cache', time() + $expire);
+
+    // [VIEWS] TRICKY: If the form is a Views exposed filters form, we store
+    // the View name in a cache entry so that we can load the View object
+    // before retrieving the parameters of the form - from which this View
+    // object is referenced - in hierarchical_select_json().
+    if (isset($parameters[1]['view'])) {
+      cache_set('hs_view_'. $hs_form_build_id, $parameters[1]['view']->name, 'cache', time() + $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
@@ -752,15 +785,13 @@ function _hierarchical_select_validate(&
   if ($element['#disabled']) {
     $element['#return_value'] = $element['#default_value'];
   }
-  // If the array is empty, set 0 as the value, which the Forms API
-  // detects as an empty form value.
-  $value = (empty($element['#return_value'])) ? 0 : $element['#return_value'];
-  $element['#value'] = $value;
-  form_set_value($element, $value, $form_state);
+
+  $element['#value'] = $element['#return_value'];
+  form_set_value($element, $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.
-  if ($element['#required'] && empty($element['#value']) && $element['#value'] !== '0') {
+  if ($element['#required'] && (!count($elements['#value']) || (is_string($elements['#value']) && strlen(trim($elements['#value'])) == 0))) {
     form_error($element, t('!name field is required.', array('!name' => $element['#title'])));
   }
 }
@@ -770,7 +801,21 @@ function _hierarchical_select_validate(&
  */
 function _hierarchical_select_submit($form, &$form_state) {
   // Delete the stored form information when the form is submitted.
-  cache_clear_all($form_state['hs_form_build_id'], 'cache');
+  // [VIEWS] TRICKY: when using Views, which uses its own Forms API workflow
+  // instead of core's, whenever the $form_state['rerender'] flag is set, this
+  // #submit callback is called even when there is nothing really there to
+  // submit. So to prevent our cache to be cleared, which would result in
+  // failing AHAH callbacks, we just prevent it from clearing the cache. This
+  // results in cache entries that aren't cleared immediately upon finishing
+  // use of the form, but that's acceptable in the end because the cache will
+  // be cleared anyway at some point.
+  if (isset($form_state['hs_form_build_id']) && !isset($form_state['rerender'])) {
+    //dpm('submit callback');
+    //dpm($form_state);
+    //dpm(debug_backtrace());
+    cache_clear_all($form_state['hs_form_build_id'], 'cache');
+    cache_clear_all('hs_view_'. $form_state['hs_form_build_id'], 'cache');
+  }
 }
 
 
@@ -1140,7 +1185,7 @@ function _hierarchical_select_process_re
     '#type' => 'select',
     '#multiple' => ($config['save_lineage'] || $config['dropbox']['status']),
     '#options' => $options,
-    '#default_value' => array_keys($options),
+    '#value' => array_keys($options),
     // Use a #theme callback to prevent the select from being wrapped in a
     // div. This simplifies the CSS and JS code.
     '#theme' => 'hierarchical_select_select',
@@ -1201,6 +1246,7 @@ function _hierarchical_select_process_ca
     }
     $return_value = array_unique($return_value);
   }
+
   return $return_value;
 }
 
@@ -1210,21 +1256,28 @@ function _hierarchical_select_process_ca
 
 /**
  * Helper function to add the required Javascript files and settings.
+ * @param $form_state
+ *   A form state array. Necessary to set the callback URL for Hierarchical
+ *   Select through _hierarchical_select_add_js_settings().
  */
-function _hierarchical_select_setup_js() {
+function _hierarchical_select_setup_js(&$form_state = NULL) {
   static $ran_once;
+  static $js_settings_added;
 
   $jquery_ui_components = array(
     'effects.core',
     'effects.drop',
   );
 
-  if (!$ran_once) {
-    $ran_once = TRUE;
-
+  if (!$js_settings_added && isset($form_state)) {
     $url = base_path();
     $url .= variable_get('clean_url', 0) ? '' : 'index.php?q=';
     $url .= 'hierarchical_select_json';
+    _hierarchical_select_add_js_settings(array('HierarchicalSelect' => array('url' => $url)), $form_state);
+  }
+
+  if (!$ran_once) {
+    $ran_once = TRUE;
 
     // Add the CSS and JS, set the URL that should be used by all hierarchical
     // selects.
@@ -1247,7 +1300,6 @@ function _hierarchical_select_setup_js()
     else {
       jquery_ui_add($jquery_ui_components);
     }
-    drupal_add_js(array('HierarchicalSelect' => array('url' => $url)), 'setting');
   }
 }
 
@@ -1496,6 +1548,12 @@ function _hierarchical_select_log($item,
 function _hierarchical_select_hierarchy_generate($config, $selection, $required, $dropbox = FALSE) {
   $hierarchy = new stdClass();
 
+  // Convert the 'special_items' setting to a more easily accessible format.
+  if (isset($config['special_items'])) {
+    $special_items['exclusive'] = array_keys(array_filter($config['special_items'], '_hierarchical_select_special_item_exclusive'));
+    $special_items['none']      = array_keys(array_filter($config['special_items'], '_hierarchical_select_special_item_none'));
+  }
+
 
   //
   // Build the lineage.
@@ -1535,7 +1593,7 @@ function _hierarchical_select_hierarchy_
   $selection = _hierarchical_select_hierarchy_validate($selection, $config['module'], $config['params']);
 
   // When nothing is currently selected, set the root level to:
-  // - "<none>" when:
+  // - "<none>" (or its equivalent special item) when:
   //    - enforce_deepest is enabled *and* level labels are enabled *and*
   //      no root level label is set (1), or
   //    - the dropbox is enabled *and* at least one selection has been added
@@ -1543,9 +1601,15 @@ function _hierarchical_select_hierarchy_
   // - "label_0" (the root level label) in all other cases.
   if ($selection == -1) {
     $root_level = module_invoke($config['module'], 'hierarchical_select_root_level', $config['params']);
-
     $first_case  = $config['enforce_deepest'] && $config['level_labels']['status'] && !isset($config['level_labels']['labels'][0]);
     $second_case = $dropbox && count($dropbox->lineages) > 0;
+
+    // If
+    // - the special_items setting has been configured, and
+    // - one special item has the 'none' property
+    // then we'll use the special item instead of the normal "<none>" option.
+    $none_option = (count($special_items['none'])) ? $special_items['none'][0] : 'none';
+    
     $hierarchy->lineage[0] = ($first_case || $second_case) ? 'none' : 'label_0';
   }
   else {
@@ -1608,10 +1672,13 @@ function _hierarchical_select_hierarchy_
   // - enforce_deepest is enabled (2), or
   // - the dropbox is enabled *and* at least one selection has been added to
   //   the dropbox (3)
+  // except when:
+  // - the special_items setting has been configured, and
+  // - one special item has the 'none' property
   $first_case  = !$required;
   $second_case = $config['enforce_deepest'];
   $third_case  = $dropbox && count($dropbox->lineages) > 0;
-  if ($first_case || $second_case || $third_case) {
+  if (($first_case || $second_case || $third_case) && !count($special_items['none'])) {
     $option = theme('hierarchical_select_special_option', t('none'));
     $hierarchy->levels[0] = array('none' => $option) + $hierarchy->levels[0];
   }
@@ -2062,3 +2129,50 @@ function _hierarchical_select_dropbox_li
 function _hierarchical_select_dropbox_lineage_item_get_value($item) {
   return $item['value'];
 }
+
+/**
+ * Helper function needed for the array_filter() call to filter the items
+ * marked with the 'exclusive' property
+ *
+ * @param $item
+ *   An item in the 'special_items' setting.
+ * @return
+ *   TRUE if it's marked with the 'exclusive' property, FALSE otherwise.
+ */
+function _hierarchical_select_special_item_exclusive($item) {
+  return in_array('exclusive', $item);
+}
+
+/**
+ * Helper function needed for the array_filter() call to filter the items
+ * marked with the 'none' property
+ *
+ * @param $item
+ *   An item in the 'special_items' setting.
+ * @return
+ *   TRUE if it's marked with the 'none' property, FALSE otherwise.
+ */
+function _hierarchical_select_special_item_none($item) {
+  return in_array('none', $item);
+}
+
+
+/**
+ * Abstraction around drupal_add_js() and Views' $form_state['js settings'].
+ *
+ * @param $settings
+ *   The JS settings you'd like to add.
+ * @param $form_state
+ *   A form state array.
+ */
+function _hierarchical_select_add_js_settings($settings, &$form_state) {
+  // If we're on a Views-powered form, we must use $form_state['js settings'].
+  if (isset($form_state['view']) && !empty($form_state['ajax'])) {
+    $form_state['js settings'] = (!is_array($form_state['js settings'])) ? array() : $form_state['js settings'];
+    $form_state['js settings'] = array_merge_recursive($form_state['js settings'], $settings);
+  }
+  // Otherwise, use drupal_add_js().
+  else {
+    drupal_add_js($settings, 'setting');
+  }
+}
Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/includes/theme.inc,v
retrieving revision 1.4
diff -u -F^f -r1.4 theme.inc
--- includes/theme.inc	21 Mar 2009 20:07:46 -0000	1.4
+++ includes/theme.inc	28 Mar 2009 11:05:41 -0000
@@ -303,7 +303,6 @@ function theme_hierarchical_select_commo
  * 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'];
Index: includes/views.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/includes/views.js,v
retrieving revision 1.7
diff -u -F^f -r1.7 views.js
--- includes/views.js	5 Aug 2008 21:55:59 -0000	1.7
+++ includes/views.js	28 Mar 2009 11:05:41 -0000
@@ -15,14 +15,14 @@
 
 if (Drupal.jsEnabled) {
   $(document).ready(function(){
-    $('form#views-filters, form#views-filterblock').submit(function() {
+    $('.view-filters form').submit(function() {
       // Remove the Hierarchical Select form build id and the form id, to
       // prevent them from ending up in the GET URL.
-      $('#edit-hs-form-build-id, #edit-views-filters, #edit-views-filterblock').remove();
+      $('#edit-hs-form-build-id').remove();
 
       // Prepare the hierarchical select form elements that are used as
       // exposed filters for a GET submit.
-      $('form#views-filters, form#views-filterblock')
+      $('.view-filters form')
       .find('.hierarchical-select-wrapper')
       .trigger('prepare-GET-submit');
     });
Index: modules/hs_menu.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/modules/hs_menu.module,v
retrieving revision 1.11
diff -u -F^f -r1.11 hs_menu.module
--- modules/hs_menu.module	2 Dec 2008 23:03:48 -0000	1.11
+++ modules/hs_menu.module	28 Mar 2009 11:05:41 -0000
@@ -183,7 +183,6 @@ function hs_menu_hierarchical_select_imp
  * 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) {
Index: modules/hs_taxonomy_views.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/modules/hs_taxonomy_views.info,v
retrieving revision 1.2
diff -u -F^f -r1.2 hs_taxonomy_views.info
--- modules/hs_taxonomy_views.info	28 Jun 2008 18:25:28 -0000	1.2
+++ modules/hs_taxonomy_views.info	28 Mar 2009 11:05:41 -0000
@@ -1,5 +1,8 @@
 ; $Id: hs_taxonomy_views.info,v 1.2 2008/06/28 18:25:28 wimleers Exp $
 name = Hierarchical Select Taxonomy Views
 description = Use Hierarchical Select for Taxonomy exposed filters in Views.
-dependencies = hierarchical_select hs_taxonomy views
+dependencies[] = hierarchical_select
+dependencies[] = hs_taxonomy 
+dependencies[] = views
 package = Form Elements
+core = 6.x
\ No newline at end of file
Index: modules/hs_taxonomy_views.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/hierarchical_select/modules/hs_taxonomy_views.module,v
retrieving revision 1.16
diff -u -F^f -r1.16 hs_taxonomy_views.module
--- modules/hs_taxonomy_views.module	20 Nov 2008 01:04:51 -0000	1.16
+++ modules/hs_taxonomy_views.module	28 Mar 2009 11:05:41 -0000
@@ -7,6 +7,21 @@
  * Views exposed filters.
  */
 
+define('HS_TAXONOMY_VIEWS_ALL_OPTION', 'All');
+/**
+  TODO:
+        - check with multiple selects
+        - force single should set hs multiple setting 
+        - can we cope with the rememeber option in tid filter 
+        - handle multiple displays per view - insert display into hs config id
+        - does cache get cleared? -> See http://drupal.org/node/342991, follow-up #29.
+        - only override what is necessary in hs_taxonomy_views_data_alter()
+        - looks like hs_taxonomy_views_hierarchical_select_entity_count should only count nodes in vid when All selected - not bug in d5, maybe with views2
+  ADDED TO TODO BY WIM:
+        - hook_uninstall() should reset the selection type from 'hierarchical_select' to select
+
+*/
+
 
 //----------------------------------------------------------------------------
 // Core hooks.
@@ -14,214 +29,168 @@
 /**
  * Implementation of hook_menu().
  */
-function hs_taxonomy_views_menu($may_cache) {
+function hs_taxonomy_views_menu() {
   $items = array();
 
-  if (!$may_cache && arg(0) == 'admin' && arg(1) == 'build' && arg(2) == 'views' && is_string(arg(3)) && arg(4) == 'hs_config' && is_numeric(arg(5))) {
-    $view_name = arg(3);
-    $vid = arg(5); // Vocabulary ID, not View ID!
-
-    $items[] = array(
-      'path' => "admin/build/views/$view_name/hs_config/$vid",
-      'title' => t('Hierarchical Select configuration for !view', array('!view' => $view_name)),
-      'callback' => 'drupal_get_form',
-      'callback arguments' => array('hs_taxonomy_views_config_form', $view_name, $vid),
-      'access' => user_access('administer views'),
-      'type' => MENU_NORMAL_ITEM,
-    );
-  }
+  $items["admin/build/views/hs_config/%views_ui_cache/%taxonomy_vocabulary/%"] = array(
+    'title'            => 'Hierarchical Select configuration',
+    'title callback'   => 'hs_taxonomy_views_config_title',
+    'title arguments'  => array(4),
+    'page callback'    => 'drupal_get_form',
+    'page arguments'   => array('hs_taxonomy_views_config_form', 4, 5, 6),
+    'access arguments' => array('administer views'),
+    'type'             => MENU_NORMAL_ITEM,
+  );
+
   return $items;
 }
 
+
+//----------------------------------------------------------------------------
+// Menu system callbacks.
+
 /**
- * Implementation of hook_form_alter().
+ * Title callback; Hierarchical Select configuration form page.
+ *
+ * @param $view
+ *   A view object.
  */
-function hs_taxonomy_views_form_alter($form_id, &$form) {
-  // Change the exposed filters of Views. Only affects hierarchical vocabulary
-  // filters.
-  if (in_array($form_id, array('views_filters', 'views_filterblock'))) {
-    $hs_exposed_filters_found = 0;
-
-    // Find the ids and vocabulary ids of the exposed filters.
-    foreach ($form['view']['#value']->exposed_filter as $id => $filter) {
-      if (preg_match("/term_node_(\d+)\.tid/", $filter['field'], $matches)) {
-        $vid = $matches[1];
-
-        // Only apply Hierarchical Select if it's enabled for this vocabulary.
-        if (variable_get("taxonomy_hierarchical_select_$vid", 0)) {
-          $hs_exposed_filters_found++;
-          $vocabulary = taxonomy_get_vocabulary($vid);
-          $view = $form['view']['#value'];
-
-          // Make it use a hierarchical select.
-          require_once(drupal_get_path('module', 'hierarchical_select') .'/includes/common.inc');
-
-          unset($form["filter$id"]['#options']);
-          unset($form["filter$id"]['#theme']);
-          unset($form["filter$id"]['#size']);
-
-          $form["filter$id"]['#type'] = 'hierarchical_select';
-          $defaults_override = array(
-            'module' => 'hs_taxonomy_views',
-            'params' => array(
-              'optional'    => (bool) $view->exposed_filter[$id]['optional'],
-              'vid'         => $vid,
-              'exclude_tid' => NULL,
-              'root_term'   => NULL,
-            ),
-            // When the **ALL** option is selected, nothing else should be.
-            'exclusive_lineages' => array('**ALL**'),
-            // This is a GET form, so also render the flat select.
-            'render_flat_select' => 1,
-          );
-          hierarchical_select_common_config_apply($form["filter$id"], "taxonomy-views-$view->name-$vid", $defaults_override);
-
-          // Inherit #required from the exposed filter settings.
-          $form["filter$id"]['#required'] = !((bool) $view->exposed_filter[$id]['optional']);
+function hs_taxonomy_views_config_title($view) {
+  return t('Hierarchical Select configuration for !view-name', array('!view-name' => $view->name));
+}
 
-          // Put the altered exposed filters in a separate table row.
-          hierarchical_select_common_views_exposed_filters_reposition();
-        }
-      }
-    }
 
-    if ($hs_exposed_filters_found > 0) {
-      // Views will remove the form_id in views_filters_process(), but we need
-      // it for Hierarchical Select to work, so put it back.
-      $form['copy_of_form_id'] = $form['form_id'] + array('#parents' => array('form_id'));
-    }
-  }
+//----------------------------------------------------------------------------
+// Views hooks.
 
-  // Alter the edit view form: add a link to the Hierarchical Select
-  // configuration when appropriate and to mark which settings are now managed
-  // by the Hierarchical Select configuration.
-  if ($form_id == 'views_edit_view') {
-    foreach ($form['exposed_filter'] as $filter_id => $filter) {
-      if (is_numeric($filter_id)) {
-        $id = $form['exposed_filter'][$filter_id]['id']['#default_value'];
-        if (preg_match("/term_node_(\d+)\.tid/", $id, $matches)) {
-          $vid  = $matches[1];
-          if (variable_get("taxonomy_hierarchical_select_$vid", 0)) {
-            $view = $form['#parameters'][1];
-
-            $link = l(t('Configure Hierarchical Select'), "admin/build/views/$view->name/hs_config/$vid");
-            $form['exposed_filter'][$filter_id]['name']['#value'] .= '<br />'. $link;
-
-            // Alter the form to support the current Hierarchical Select
-            // config.
-            require_once(drupal_get_path('module', 'hierarchical_select') .'/includes/common.inc');
-            $config_id = "taxonomy-views-$view->name-$vid";
-            $config = hierarchical_select_common_config_get($config_id);
-
-            $text = t('This setting is now managed by the<br />Hierarchical Select configuration!');
-            
-            // Exposed filter's "Force single" setting.
-            $form['exposed_filter'][$filter_id]['single']['#description'] = $text;
-
-            // Additional settings when save_lineage is enabled.
-            if ($config['save_lineage']) {
-              // Filter's "Operator" setting.
-              $form['filter'][$filter_id]['operator']['#description'] = $text;
-
-              // Exposed filter's "Lock Operator" setting.
-              $form['exposed_filter'][$filter_id]['operator']['#description'] = $text;
-            }
-          }
-        }
-      }
-    }
-  }
+/**
+ * Implementation of hook_views_api().
+ */
+function hs_taxonomy_views_api() {
+  return array(
+    'api' => 2,
+    'path' => drupal_get_path('module', 'hierarchical_select') .'/modules',
+  );
 }
 
 /**
- * Implementation of hook_requirements().
+ * Implementation of hook_views_handlers().
  */
-function hs_taxonomy_views_requirements($phase) {
-  $requirements = array();
-
-  if ($phase == 'runtime') {
-    $pattern = <<<EOT
-function _views_build_filters_form(\$view) {
-  // When the form is retrieved through an AJAX callback, the cache hasn't
-  // been loaded yet. The cache is necesssary for _views_get_filters().
-  views_load_cache();
-EOT;
-    $views_with_patch_257004 = preg_match('#'. preg_quote($pattern) .'#m', file_get_contents(drupal_get_path('module', 'views') .'/views.module'));
-
-    if ($views_with_patch_257004) {
-      $value = t('The Views module is new enough.');
-      $description = '';
-      $severity = REQUIREMENT_OK;
-    }
-    else {
-      $value = t('The Views module is outdated.');
-      $description = t("The version of Views that you have installed is either
-        older than May 11, 2008, or doesn't have the obligatory patch applied.
-        Please apply the <a href=\"!patch_url\">patch</a> or update to a newer
-        version of the Views module!",
-        array('!patch_url' => 'http://drupal.org/files/issues/hs_compatibility.patch')
-      );
-      $severity = REQUIREMENT_ERROR;
-    }
-
-    $requirements['hs_taxonomy_views'] = array(
-      'title'       => t('Hierarchical Select Views Taxonomy'),
-      'value'       => $value,
-      'description' => $description,
-      'severity'    => $severity,
-    );
-  }
-
-  return $requirements;
+function hs_taxonomy_views_handlers() {
+  return array(
+    'info' => array(
+      'path' => drupal_get_path('module', 'hierarchical_select') .'/modules',
+    ),
+    'handlers' => array(
+      // Filter handlers.
+      'hs_taxonomy_views_handler_filter_term_node_tid' => array(
+        'parent' => 'views_handler_filter_term_node_tid',
+      ),
+    )
+  );
 }
 
+/**
+ * Implementation of hook_views_data_alter().
+ */
+function hs_taxonomy_views_data_alter(&$data) {
+  // tid field
+  $data['term_data']['tid'] = array(
+   'title' => t('Term ID'),
+   'help'  => t('The taxonomy term ID.'),
+   'field' => array(
+     'handler'   => 'views_handler_field_numeric',
+     'skip base' => array('node', 'node_revision'),
+   ),
+   'argument' => array(
+     'handler'   => 'views_handler_argument_numeric',
+     'skip base' => array('node', 'node_revision'),
+   ),
+   'filter' => array(
+     'handler'         => 'hs_taxonomy_views_handler_filter_term_node_tid',
+     'hierarchy table' => 'term_hierarchy',
+     'numeric'         => TRUE,
+     'skip base'       => array('node', 'node_revision'),
+   ),
+  );
 
-//----------------------------------------------------------------------------
-// Forms API callbacks.
+  // tid field
+  $data['term_node']['tid'] = array(
+    'title' => t('Term ID'),
+    'help'  => t('The taxonomy term ID.'),
+    'field' => array(
+      'title'     => t('All terms'),
+      'help'      => t('Display all taxonomy terms associated with a node from specified vocabularies.'),
+      'handler'   => 'views_handler_field_term_node_tid',
+      'skip base' => 'term_data',
+    ),
+    'argument' => array(
+      'handler'          => 'views_handler_argument_term_node_tid',
+      'name table'       => 'term_data',
+      'name field'       => 'name',
+      'empty name field' => t('Uncategorized'),
+      'numeric'          => TRUE,
+      'skip base'        => 'term_data',
+    ),
+    'filter' => array(
+      'title'           => t('Term'),
+      'handler'         => 'hs_taxonomy_views_handler_filter_term_node_tid',
+      'hierarchy table' => 'term_hierarchy',
+      'numeric'         => TRUE,
+      'skip base'       => 'term_data',
+    ),
+  );
+}
 
 /**
  * Form definition; configuration form for Hierarchical Select as the widget
  * for a Taxonomy exposed filter.
  *
- * @param $view_name
- *   Name of a view. Provides necessary context.
- * @param $vid
- *   A vocabulary id. Provides necessary context.
+ * @param $view
+ *   A view object. Provides necessary context.
+ * @param $vocabulary
+ *   A vocabulary object. Provides necessary context.
  */
-function hs_taxonomy_views_config_form($view_name, $vid) {
+function hs_taxonomy_views_config_form($form_state, $view, $vocabulary, $display) {
   require_once(drupal_get_path('module', 'hierarchical_select') .'/includes/common.inc');
+  
+  // TODO: It seems filters are shared by all displays, you can't add any
+  // display-specific filter or display-specific filter settings? If that's
+  // the case, we can remove the $display parameter and always assume the
+  // 'default' display.
+  // I also assumed this behavior (always 'default') in
+  // hs_taxonomy_views_hierarchical_select_config_info(). So if it's a wrong
+  // assumption, change it there too!
+  // [patch-review-by-Wim-Leers]
+  $display = 'default';
 
-  // Find the exposed filter, we need this to set the default value of
-  // $config['dropbox']['status'].
-  $view = views_get_view($view_name);
-  foreach ($view->exposed_filter as $filter) {
-    if ($filter['id'] == "term_node_$vid.tid") {
+  foreach ($view->display[$display]->display_options['filters'] as $filter) {
+    if ($filter['type'] == 'hierarchical_select' && $filter['table'] == 'term_node' && $filter['vid'] == $vocabulary->vid) {
       $exposed_filter = $filter;
       break;
     }
   }
 
+  // Build the config ID.
+  $config_id = "taxonomy-views-$view->name-$vocabulary->vid";
+
   // Add the Hierarchical Select config form.
   $module = 'hs_taxonomy_views';
   $params = array(
-    'optional'    => (bool) $view->exposed_filter[$id]['optional'],
-    'vid'         => $vid,
+    'optional'    => (bool) $exposed_filter['expose']['optional'],
+    'vid'         => $vocabulary->vid,
     'exclude_tid' => NULL,
     'root_term'   => NULL,
   );
-    
-  
-  $config_id = "taxonomy-views-$view_name-$vid";
-  $vocabulary = taxonomy_get_vocabulary($vid);
   $defaults = array(
     // Enable the save_lineage setting by default if the multiple parents
     // vocabulary option is enabled.
     'save_lineage' => (int) ($vocabulary->hierarchy == 2),
     'dropbox' => array(
-      'status' => !$exposed_filter['single'],
+      'status' => !$exposed_filter['expose']['single'],
     ),
     'editability' => array(
-      'max_levels' => _hs_taxonomy_hierarchical_select_get_depth($vid),
+      'max_levels' => _hs_taxonomy_hierarchical_select_get_depth($vocabulary->vid),
     ),
   );
   $strings = array(
@@ -233,8 +202,8 @@ function hs_taxonomy_views_config_form($
     'entity'      => t('node'),
     'entities'    => t('nodes'),
   );
-  $max_hierarchy_depth = _hs_taxonomy_hierarchical_select_get_depth($vid);
-  $preview_is_required = !(bool)$exposed_filter['optional'];
+  $max_hierarchy_depth = _hs_taxonomy_hierarchical_select_get_depth($vocabulary->vid);
+  $preview_is_required = !(bool)$exposed_filter['expose']['optional'];
   $form['hierarchical_select_config'] = hierarchical_select_common_config_form($module, $params, $config_id, $defaults, $strings, $max_hierarchy_depth, $preview_is_required);
   $form['hierarchical_select_config']['save_lineage']['#description'] .= '<br />'. t(
     'When you enable the %save_lineage setting, you will have to resave the
@@ -243,7 +212,7 @@ function hs_taxonomy_views_config_form($
   );
 
   $form['link'] = array(
-    '#value' => l('Back to the view configuration', "admin/build/views/$view_name/edit"),
+    '#value' => l('Back to the view configuration', "admin/build/views/edit/$view->name"),
     '#prefix' => '<div class="hierarchical-select-config-back-link">',
     '#suffix' => '</div>',
     '#weight' => -5,
@@ -256,9 +225,12 @@ function hs_taxonomy_views_config_form($
 
   // Add the the submit handler for the Hierarchical Select config form.
   $parents = array('hierarchical_select_config');
-  $form['#submit']['hierarchical_select_common_config_form_submit'] = array($parents);
 
-  $form['#submit']['hs_taxonomy_views_common_config_form_submit'] = array($view_name, $vid);
+  $form['#submit'][] = 'hierarchical_select_common_config_form_submit';
+  $form['#hs_common_config_form_parents'] = $parents;
+  
+// TODO needs to be D6alised  
+//  $form['#submit']['hs_taxonomy_views_common_config_form_submit'] = array($view->name, $vocabulary->vid);
 
   return $form;
 }
@@ -273,6 +245,7 @@ function hs_taxonomy_views_config_form($
  * @param $vid
  *   A vocabulary id. Provides necessary context.
  */
+ /*
 function hs_taxonomy_views_common_config_form_submit($form_id, $form_values, $view_name, $vid) {
   $view_id = db_result(db_query("SELECT vid FROM {view_view} WHERE name = '%s'", $view_name));
   $field = 'term_node_'. $vid .'.tid';
@@ -312,6 +285,7 @@ function hs_taxonomy_views_common_config
     drupal_set_message(t("Updated the View's exposed filter according to the settings you made."));
   }
 }
+*/
 
 
 //----------------------------------------------------------------------------
@@ -321,14 +295,20 @@ function hs_taxonomy_views_common_config
  * Implementation of hook_hierarchical_select_params().
  */
 function hs_taxonomy_views_hierarchical_select_params() {
-  return array('optional') + hs_taxonomy_hierarchical_select_params();
+  $params = array(
+    'vid',
+    'optional',    // Do we display an "All" option?
+    'exclude_tid', // Allows a term to be excluded (necessary for the taxonomy_form_term form).
+    'root_term',   // Displays a fake "<root>" term in the root level (necessary for the taxonomy_form-term form).
+  );
+  return $params;
 }
 
 /**
  * Implementation of hook_hierarchical_select_root_level().
  */
 function hs_taxonomy_views_hierarchical_select_root_level($params) {
-  $root_level =  ($params['optional']) ? array('**ALL**' => '<'. t('all') .'>') : array();
+  $root_level =  ($params['optional']) ? array(HS_TAXONOMY_VIEWS_ALL_OPTION => '<'. t('Any') .'>') : array();
   $root_level += hs_taxonomy_hierarchical_select_root_level($params);
   return $root_level;
 }
@@ -337,28 +317,28 @@ function hs_taxonomy_views_hierarchical_
  * Implementation of hook_hierarchical_select_children().
  */
 function hs_taxonomy_views_hierarchical_select_children($parent, $params) {
-  return ($parent == '**ALL**') ? array() : hs_taxonomy_hierarchical_select_children($parent, $params);
+  return ($parent == HS_TAXONOMY_VIEWS_ALL_OPTION) ? array() : hs_taxonomy_hierarchical_select_children($parent, $params);
 }
 
 /**
  * Implementation of hook_hierarchical_select_lineage().
  */
 function hs_taxonomy_views_hierarchical_select_lineage($item, $params) {
-  return ($item == '**ALL**') ? array($item) : hs_taxonomy_hierarchical_select_lineage($item, $params);
+  return ($item == HS_TAXONOMY_VIEWS_ALL_OPTION) ? array($item) : hs_taxonomy_hierarchical_select_lineage($item, $params);
 }
 
 /**
  * Implementation of hook_hierarchical_select_valid_item().
  */
 function hs_taxonomy_views_hierarchical_select_valid_item($item, $params) {
-  return ($item == '**ALL**' || hs_taxonomy_hierarchical_select_valid_item($item, $params));
+  return ($item == HS_TAXONOMY_VIEWS_ALL_OPTION || hs_taxonomy_hierarchical_select_valid_item($item, $params));
 }
 
 /**
  * Implementation of hook_hierarchical_select_item_get_label().
  */
 function hs_taxonomy_views_hierarchical_select_item_get_label($item, $params) {
-  return ($item == '**ALL**') ? '<'. t('all') .'>' : hs_taxonomy_hierarchical_select_item_get_label($item, $params);
+  return ($item == HS_TAXONOMY_VIEWS_ALL_OPTION) ? '<'. t('Any') .'>' : hs_taxonomy_hierarchical_select_item_get_label($item, $params);
 }
 
 /**
@@ -372,7 +352,7 @@ function hs_taxonomy_views_hierarchical_
  * Implementation of hook_hierarchical_select_entity_count().
  */
 function hs_taxonomy_views_hierarchical_select_entity_count($item, $params) {
-  if ($item == '**ALL**') {
+  if ($item == HS_TAXONOMY_VIEWS_ALL_OPTION) {
     return db_result(db_query('SELECT COUNT(DISTINCT(t.nid)) FROM {term_node} t INNER JOIN {node} n ON t.nid = n.nid WHERE n.status = 1'));
   }
   else {
@@ -394,22 +374,15 @@ function hs_taxonomy_views_hierarchical_
  * Implementation of hook_hierarchical_select_config_info().
  */
 function hs_taxonomy_views_hierarchical_select_config_info() {
-  static $config_info;
-
-  if (!isset($config_info)) {
-    $config_info = array();
+  $views = views_get_all_views();
 
-    views_load_cache();
-    $result = db_query("SELECT vid, name FROM {view_view} ORDER BY name");
-    while ($view = db_fetch_object($result)) {
-      $view = views_get_view($view->name);
-
-      foreach ($view->exposed_filter as $filter_id => $filter) {
-        $vid = _hs_taxonomy_views_parse_vocabulary_id_from_id($filter['id']);
-        if ($vid) {
-          $vocabulary = taxonomy_get_vocabulary($vid);
+  foreach ($views as $view) {
+    if (count($view->display['default']->display_options['filters'])) {
+      foreach ($view->display['default']->display_options['filters'] as $filter) {
+        if ($filter['type'] == 'hierarchical_select' && $filter['table'] == 'term_node') {
+          $vocabulary = taxonomy_vocabulary_load($filter['vid']);
 
-          $config_id = "taxonomy-views-$view->name-$vid";
+          $config_id = "taxonomy-views-$view->name-$vocabulary->vid";
           $config_info[$config_id] = array(
             'config_id'      => $config_id,
             'hierarchy type' => t('Taxonomy'),
@@ -418,7 +391,7 @@ function hs_taxonomy_views_hierarchical_
             'entity'         => '',
             'context type'   => t('Views exposed filter'),
             'context'        => t($view->name),
-            'edit link'      => "admin/build/views/$view->name/hs_config/$vid",
+            'edit link'      => "admin/build/views/$view->name/hs_config/$vocabulary->vid",
           );
         }
       }
@@ -427,18 +400,3 @@ function hs_taxonomy_views_hierarchical_
 
   return  $config_info;
 }
-
-/**
- * Given an id of the form "term_node_1.tid", with 1 the vid, get the vid.
- *
- * @return
- *   When no valid id was given, FALSE, otherwise the vid.
- */
-function _hs_taxonomy_views_parse_vocabulary_id_from_id($id) {
-  $vid = FALSE;
-
-  if (preg_match("/term_node_(\d+)\.tid/", $id, $matches)) {
-    $vid = $matches[1];
-  }
-  return $vid;
-}
Index: modules/hs_taxonomy_views_handler_filter_term_node_tid.inc
===================================================================
RCS file: modules/hs_taxonomy_views_handler_filter_term_node_tid.inc
diff -N modules/hs_taxonomy_views_handler_filter_term_node_tid.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/hs_taxonomy_views_handler_filter_term_node_tid.inc	28 Mar 2009 11:05:41 -0000
@@ -0,0 +1,159 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * This file defines a new filter handler for using Hierarchical Select in
+ * exposed Taxonomy term filters.
+ */
+
+
+class hs_taxonomy_views_handler_filter_term_node_tid extends views_handler_filter_term_node_tid {
+  function has_extra_options() { return TRUE; }
+
+  function init(&$view, $options) {
+    parent::init($view, $options);
+    _hierarchical_select_setup_js();
+  }
+
+  function value_form(&$form, &$form_state) {
+    $vocabulary = taxonomy_vocabulary_load($this->options['vid']);
+
+    // When not exposed: settings form.
+    if (empty($form_state['exposed'])) {
+      // When the 'Selection type' is:
+      // - 'Autocomplete', or
+      // - 'Dropdown' and 'Show hierarchy in dropdown' is disabled,
+      // show the default form.
+      // Otherwise, generate the form ourselves in a more scalable manner.
+      if ($this->options['type'] == 'textfield' || ($this->options['type'] == 'select' && empty($this->options['hierarchy']))) {
+        parent::value_form($form, $form_state);
+      }
+      else {
+        $form['value'] = array(
+          '#type'          => 'hierarchical_select',
+          '#title'         => t('Select terms from vocabulary @voc', array('@voc' => $vocabulary->name)),
+          '#default_value' => !empty($this->value) ? $this->value : array(),
+          '#config' => array(
+            'module' => 'hs_taxonomy',
+            'params' => array(
+              'vid' => $vocabulary->vid,
+            ),
+            'save_lineage'    => 0,
+            'enforce_deepest' => 0,
+            'entity_count'    => 0,
+            'resizable'       => 1,
+            'level_labels' => array(
+              'status' => 0,
+            ),
+            'dropbox' => array(
+              'status'   => 1,
+              'title'    => t('Terms to filter by'),
+              'limit'    => 0,
+              'reset_hs' => 1,
+            ),
+          ),
+        );
+      }
+      
+    }
+    // Exposed filters form.
+    else {
+      // When the 'Selection type' is 'Hierarchical Select', use our logic,
+      // otherwise, use the logic of the parent class.
+      if ($this->options['type'] == 'hierarchical_select'
+          || // [patch-review-by-Wim-Leers] TEMPORARY HACK BECAUCSE VIEWS IS SO UNSTABLE
+          $this->options['type'] == 'select') {
+        require_once(drupal_get_path('module', 'hierarchical_select') .'/includes/common.inc');
+
+        unset($form["value"]['#options']);
+        unset($form["value"]['#theme']);
+        unset($form["value"]['#size']);
+
+        $form['value']['#type'] = 'hierarchical_select';
+        $defaults_override = array(
+         'module' => 'hs_taxonomy_views',
+         'params' => array(
+           'optional'    => (bool) $this->options['expose']['optional'],
+           'vid'         => $vocabulary->vid,
+           'exclude_tid' => NULL,
+           'root_term'   => NULL,
+         ),
+         // When the 'All' option is selected, nothing else should be and it
+         // should replace the '<none>' option.
+         'special_items' => array(
+           HS_TAXONOMY_VIEWS_ALL_OPTION => array('none', 'exclusive'),
+         ),
+         // This is a GET form, so also render the flat select.
+         'render_flat_select' => 1,
+        );
+        hierarchical_select_common_config_apply($form['value'], "taxonomy-views-{$this->view->name}-$vocabulary->vid", $defaults_override);
+
+        // Inherit #required from the exposed filter settings.
+        $form['value']['#required'] = !((bool) $this->options['expose']['optional']);
+
+        // Ensure that Drupal.HierarchicalSelect.prepareGETSubmit() gets called.
+        hierarchical_select_common_views_exposed_filters_reposition();
+      }
+      else {
+        parent::value_form($form, $form_state);
+      }
+
+      if (!empty($form_state['exposed']) && !isset($form_state['input'][$identifier])) {
+        $form_state['input'][$identifier] = $default_value;
+      }
+    }
+  }
+
+  function expose_form(&$form, &$form_state) {
+    parent::expose_form($form, $form_state);
+
+    if ($this->options['type'] == 'hierarchical_select') {
+      $form['configure_hs'] = array(
+         '#prefix' => '<div class="views-left-50 form-item">',
+         '#value'  => '<p>'. l(t('Configure Hierarchical Select Settings'), 'admin/build/views/hs_config/'. $this->view->name .'/'. $this->options['vid'] .'/'. $this->view->current_display) .'</p>',
+         '#suffix' => '</div>',
+       );
+    }
+  }
+  
+  function expose_form_right(&$form, &$form_state) {
+    parent::expose_form_right($form, $form_state);
+
+/*
+    if ($this->options['type'] == 'hierarchical_select') {
+      $form['expose']['single']['#value'] = 0;
+      $form['expose']['single']['#disabled'] = TRUE;
+    }
+*/
+  }
+
+  function extra_options_form(&$form, &$form_state) {
+    parent::extra_options_form($form, $form_state);
+
+    $form['type'] = array(
+      '#type'    => 'radios',
+      '#title'   => t('Selection type'),
+      '#options' => array(
+        'select'              => t('Dropdown'),
+        'textfield'           => t('Autocomplete'),
+        'hierarchical_select' => t('Hierarchical Select'),
+      ),
+      '#default_value' => $this->options['type'],
+    );
+  }
+
+  // TODO: First this function gets called for validation.
+  function exposed_validate(&$form, &$form_state) {
+//    dpm($form_state);
+    if (empty($this->options['exposed'])) {
+      return;
+    }
+  }
+
+  // TODO: Then we can decide to accept the input or not.
+  function accept_exposed_input($input) {
+//    dpm($input);
+  }
+
+}
