diff --git a/facetapi_multiselect.module b/facetapi_multiselect.module
index cbb4c0f..d3e6512 100644
--- a/facetapi_multiselect.module
+++ b/facetapi_multiselect.module
@@ -56,23 +56,83 @@ function facetapi_multiselect_form($form, &$form_state, $widget, $element) {
   // Record this in the form too, in case someone needs to access it there.
   $form['#facetapi_multiselect'] = $form_state['facetapi_multiselect'];
 
+  // Get an array of the facet options
+  $options = $widget->buildOptions($element);
+
+  // Because of an issue with iOS and multiselect fields, we need to add an
+  // empty option. This option must have the `disabled` attribute, so  we'll
+  // handle that in preprocess.
+  // @see http://stackoverflow.com/questions/34985606/ios-9-2-select-list-multiple-incorrectly-firing-change-event-and-setting-valu
+  $options = array('disabled' => '') + $options;
+
   // Build the form.
   $form['facets'] = array(
     '#type' => 'select',
     '#multiple' => TRUE,
-    '#options' => $widget->buildOptions($element),
+    '#options' => $options,
     '#default_value' => $widget->buildDefaultValue($element),
     '#attributes' => array('class' => array('facetapi-multiselect', $form_state['facetapi_multiselect']['facet_class'])),
+    '#post_render' => array('_facetapi_multiselect_disable_options'),
   );
   $form['submit'] = array(
     '#type' => 'submit',
     '#value' => t('Submit'),
   );
 
+  $build = $widget->getBuild();
+  $settings = $build['#settings']->settings;
+
+  if ($settings['auto_submit']) {
+    $form['#attached']['js'][] = drupal_get_path('module', 'facetapi_multiselect') . '/js/facetapi_multiselect_autosubmit.js';
+  }
+
+  if ($settings['placeholder_label']) {
+    $form['facets']['#attributes']['data-placeholder'] = t($settings['placeholder_label']);
+  }
+
   return $form;
 }
 
 /**
+ * Set any option items that have a "disabled" value to be disabled
+ * @param  string $content The rendered HTML for the select item
+ * @param  array $element The Drupal FAPI item
+ * @return string          The updated markeup
+ */
+function _facetapi_multiselect_disable_options($content, $element) {
+  // Check PHP and libxml version.
+  static $new_libxml;
+  if (!isset($new_libxml)) {
+    $new_libxml = version_compare(PHP_VERSION, '5.4', '>=') && defined('LIBXML_HTML_NOIMPLIED') && defined('LIBXML_HTML_NODEFDTD');
+  }
+
+  // Create a new DOMDocument object with our rendered HTML.
+  $select = new DOMDocument;
+  $select->encoding = 'utf-8';
+  if ($new_libxml) {
+    $select->loadHTML(utf8_decode($content), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
+  }
+  else {
+    $select->loadHTML(utf8_decode($content));
+  }
+
+  // Loop over our options list
+  foreach ($select->getElementsByTagName('option') as $option) {
+    if ($option->hasAttribute('value')) {
+      // Get the value and see if it's set to 'disabled'. If not, skip
+      $value = $option->getAttribute('value');
+      if ($value == 'disabled' || strpos($value, ':disabled') !== FALSE) {
+        // Set the disabled attribute, remove the value attribute.
+        $option->setAttribute('disabled', 'disabled');
+        $option->removeAttribute('value');
+      }
+    }
+  }
+
+  return $select->saveHTML();
+}
+
+/**
  * Submit handler for facetapi_multiselect_form().
  */
 function facetapi_multiselect_form_submit($form, &$form_state) {
diff --git a/js/facetapi_multiselect_autosubmit.js b/js/facetapi_multiselect_autosubmit.js
new file mode 100644
index 0000000..8425e0a
--- /dev/null
+++ b/js/facetapi_multiselect_autosubmit.js
@@ -0,0 +1,10 @@
+(function($){
+  Drupal.behaviors.facetapi_multiselect = {
+    attach: function (context, settings) {
+      $('form[id^="facetapi-multiselect-form"] .form-submit', context).hide();
+      $('form[id^="facetapi-multiselect-form"] select', context).change(function () {
+        $(this).closest('form').submit();
+      });
+    }
+  };
+})(jQuery);
diff --git a/plugins/facetapi/facetapi_multiselect.inc b/plugins/facetapi/facetapi_multiselect.inc
index 55e6c12..bb837d2 100644
--- a/plugins/facetapi/facetapi_multiselect.inc
+++ b/plugins/facetapi/facetapi_multiselect.inc
@@ -26,17 +26,43 @@ class FacetapiMultiSelectWidget extends FacetapiWidgetLinks {
   /**
    * Builds an array of #options for our select element.
    */
-  public function buildOptions($element) {
-    $options = array();
+  public function buildOptions($element, $options = array(), $depth = 0) {
+    $settings = $this->settings->settings;
     foreach ($element as $item) {
-      if (empty($item['#item_children'])) {
+      if (empty($item['#item_children']) || !$settings['optgroups']) {
         $key = $this->getOptionKey($item);
-        $options[$key] = $item['#markup'];
+
+        $markup = $item['#markup'];
+
+        if ($settings['add_count']) {
+          if (!$settings['remove_count_on_active'] || ($settings['remove_count_on_active'] && !$item['#active'])) {
+            $markup .= ' (' . $item['#count'] . ')';
+          }
+        }
+
+        $options[$key] = $markup;
+
+        // Prepend the text with a depth indicator.
+        if ($depth > 0) {
+          $options[$key] = str_repeat('-', $depth) . ' ' . $options[$key];
+        }
+        // If the current item is active, but if we have selected the "Remove
+        // selected" option, remove this items from our array, since we want to
+        // hide it.
+        if ($item['#active'] && $settings['remove_selected']) {
+          unset($options[$key]);
+        }
       }
-      else {
-        // Recursively add any children of the item to the #options array (this
-        // will result in them being placed inside optgroups).
-        $options[$item['#markup']] = $this->buildOptions($item['#item_children']);
+      if ($item['#item_children']) {
+        if ($settings['optgroups']) {
+          // Recursively add any children of the item to the #options array (this
+          // will result in them being placed inside optgroups).
+          $options[$item['#markup']] = $this->buildOptions($item['#item_children']);
+        }
+        else {
+          // Not using optgroups, so put all items at the root level.
+          $options = $options + $this->buildOptions($item['#item_children'], $options, $depth + 1);
+        }
       }
     }
     return $options;
@@ -46,16 +72,10 @@ class FacetapiMultiSelectWidget extends FacetapiWidgetLinks {
    * Builds a #default_value array for our select element.
    */
   public function buildDefaultValue($element) {
+    $active_items = $this->facet->getAdapter()->getActiveItems($this->facet->getFacet());
     $default_value = array();
-    foreach ($element as $item) {
-      if ($item['#active']) {
-        $default_value[] = $this->getOptionKey($item);
-        // If the item has children, add their default values to the array
-        // also.
-        if (!empty($item['#item_children'])) {
-          $default_value = array_merge($default_value, $this->buildDefaultValue($item['#item_children']));
-        }
-      }
+    foreach ($active_items as $id => $values) {
+      $default_value[] = rawurlencode($values['field alias']) . ":" . $id;
     }
     return $default_value;
   }
@@ -64,10 +84,128 @@ class FacetapiMultiSelectWidget extends FacetapiWidgetLinks {
    * Gets the key to use for an item in the select element #options array.
    */
   protected function getOptionKey($item) {
+    $settings = $this->settings->settings;
+    if ($settings['act_single'] && isset($item['#query']['f'])) {
+      return implode('&', $item['#query']['f']);
+    }
     // Set the key to the filter that will appear in the URL if this item is
     // selected. We need to do it this way (rather than using $item['#query'])
     // so that multiple selections can be combined together in the form's
-    // submit handler.
-    return $this->facet['field alias'] . ':' . $item['#indexed_value'];
+    // submit handler. ":disabled" is added for facets with 0 items.
+    $facet_url = rawurlencode($this->facet['field alias']) . ':' . $item['#indexed_value'];
+    if (isset($settings['disable_empty']) && $settings['disable_empty'] == 1 && $item['#count'] == 0) {
+      $facet_url .= ':disabled';
+    }
+    return $facet_url;
+  }
+
+  /**
+   * Allows the widget to provide additional settings to the form.
+   */
+  function settingsForm(&$form, &$form_state) {
+    $form['widget']['widget_settings']['links'][$this->id]['add_count'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Add count'),
+      '#description' => t('Add available item count in brackets.'),
+      '#default_value' => $this->settings->settings['add_count'],
+      '#states' => array(
+        'visible' => array(
+          'select[name="widget"]' => array('value' => $this->id),
+        ),
+      ),
+    );
+    $form['widget']['widget_settings']['links'][$this->id]['remove_count_on_active'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Remove parenthetical counts on active items'),
+      '#description' => t('Counts will only appear for unselected items, ideal for Chosen theming.'),
+      '#default_value' => $this->settings->settings['remove_count_on_active'],
+      '#states' => array(
+        'visible' => array(
+          'select[name="widget"]' => array('value' => $this->id),
+          'input[name="add_count"]' => array('checked' => TRUE),
+        ),
+      ),
+    );
+    $form['widget']['widget_settings']['links'][$this->id]['disable_empty'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Show empty facets as disabled'),
+      '#description' => t('When facets have zero items, show them anyway, but disallow selecting them.'),
+      '#default_value' => $this->settings->settings['disable_empty'],
+      '#states' => array(
+        'visible' => array(
+          'select[name="widget"]' => array('value' => $this->id),
+        ),
+      ),
+    );
+    $form['widget']['widget_settings']['links'][$this->id]['remove_selected'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Remove selected'),
+      '#description' => t('Remove selected options from select list.'),
+      '#default_value' => $this->settings->settings['remove_selected'],
+      '#states' => array(
+        'visible' => array(
+          'select[name="widget"]' => array('value' => $this->id),
+        ),
+      ),
+    );
+    $form['widget']['widget_settings']['links'][$this->id]['auto_submit'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Autosubmit'),
+      '#description' => t('Hide submit button and submit selection automatically.'),
+      '#default_value' => $this->settings->settings['auto_submit'],
+      '#states' => array(
+        'visible' => array(
+          'select[name="widget"]' => array('value' => $this->id),
+        ),
+      ),
+    );
+    $form['widget']['widget_settings']['links'][$this->id]['act_single'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Act as single select element'),
+      '#description' => t('Change query path to work with facets from connected fields.'),
+      '#default_value' => $this->settings->settings['act_single'],
+      '#states' => array(
+        'visible' => array(
+          'select[name="widget"]' => array('value' => $this->id),
+        ),
+      ),
+    );
+    $form['widget']['widget_settings']['links'][$this->id]['optgroups'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Nest hierarchical facets in optgroups.'),
+      '#description' => t('Parent facets will be rendered as optgroups in the select element.'),
+      '#default_value' => $this->settings->settings['optgroups'],
+      '#states' => array(
+        'visible' => array(
+          'select[name="widget"]' => array('value' => $this->id),
+        ),
+      ),
+    );
+    $form['widget']['widget_settings']['links'][$this->id]['placeholder_label'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Facet placeholder text'),
+      '#description' => t('The placeholder text will appear before any options are selected.'),
+      '#default_value' => $this->settings->settings['placeholder_label'],
+      '#states' => array(
+        'visible' => array(
+          'select[name="widget"]' => array('value' => $this->id),
+        )
+      )
+    );
+  }
+
+  /**
+   * Returns defaults for the settings this widget provides.
+   */
+  function getDefaultSettings() {
+    return array(
+      'add_count' => 0,
+      'remove_count_on_active' => 0,
+      'remove_selected' => 0,
+      'auto_submit' => 0,
+      'act_single' => 0,
+      'optgroups' => 1,
+      'placeholder_label' => t('Select some options'),
+    );
   }
 }
