diff --git ahah_example/ahah_example.css ahah_example/ahah_example.css
index ff7554e..77d7720 100644
--- ahah_example/ahah_example.css
+++ ahah_example/ahah_example.css
@@ -1,4 +1,11 @@
 /* hide the next button when not degrading to non-javascript browser */
 html.js .next-button { 
   display: none; 
-}
\ No newline at end of file
+}
+
+
+/* Make the next/choose button align to the right of the select control */
+#edit-master-dropdown-wrapper {
+  display: inline-block;
+}
+
diff --git ahah_example/ahah_example.module ahah_example/ahah_example.module
index 870b2c8..4a580c0 100644
--- ahah_example/ahah_example.module
+++ ahah_example/ahah_example.module
@@ -12,70 +12,121 @@ $path = drupal_get_path('module','ahah_example');
 
 /**
  * Implement hook_menu().
+ *
+ * Note that each item has both an entry point to prepare the form, and also
+ * a callback function that provides and AHAH menu callback.
  */
 function ahah_example_menu() {
   $items = array();
 
+  $items['examples/ahah_example'] = array(
+    'title' => 'AHAH Examples',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('ahah_example_simplest'),
+    'access callback' => TRUE,
+    'file' => 'simplest_ahah.inc',
+  );
   // Simple AHAH with its callback.
-  $items['ahah_example/simplest_ahah'] = array(
-    'title' => t('AHAH: Simplest Example'),
+  $items['examples/ahah_example/simplest_ahah'] = array(
+    'title' => 'Simplest',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('ahah_example_simplest'),
     'access callback' => TRUE,
+    'type' => MENU_DEFAULT_LOCAL_TASK,
     'file' => 'simplest_ahah.inc',
+    'weight' => 0,
   );
-  $items['ahah_example/simplest_ahah/callback'] = array(
+  $items['examples/ahah_example/simplest_ahah/callback'] = array(
     'page callback' => 'ahah_example_simplest_callback',
     'access callback' => TRUE,
     'file' => 'simplest_ahah.inc',
-    );
+    'type' => MENU_CALLBACK,
+  );
 
   // Automatically generate checkboxes.
-  $items['ahah_example/autocheckboxes'] = array(
-    'title' => t('AHAH: generate checkboxes'),
+  $items['examples/ahah_example/autocheckboxes'] = array(
+    'title' => 'Generate checkboxes',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('ahah_example_autocheckboxes'),
     'access callback' => TRUE,
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 2,
     'file' => 'autocheckboxes.inc',
   );
-  $items['ahah_example/autocheckboxes/callback'] = array(
-    'type' => MENU_CALLBACK,
+  $items['examples/ahah_example/autocheckboxes/callback'] = array(
     'page callback' => 'ahah_example_autocheckboxes_callback',
     'access callback' => TRUE,
     'file' => 'autocheckboxes.inc',
-    );
+    'type' => MENU_CALLBACK,
+  );
 
     // Automatically generate textfields.
-  $items['ahah_example/autotextfields'] = array(
-    'title' => t('AHAH: generate textfields'),
+  $items['examples/ahah_example/autotextfields'] = array(
+    'title' => 'Generate textfields',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('ahah_example_autotextfields'),
     'access callback' => TRUE,
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 4,
     'file' => 'autotextfields.inc',
   );
-  $items['ahah_example/autotextfields/callback'] = array(
-    'type' => MENU_CALLBACK,
+  $items['examples/ahah_example/autotextfields/callback'] = array(
     'page callback' => 'ahah_example_autotextfields_callback',
     'access callback' => TRUE,
     'file' => 'autotextfields.inc',
+    'type' => MENU_CALLBACK,
     );
     // Automatically generate textfields.
-  $items['ahah_example/dependent_dropdown'] = array(
-    'title' => t('AHAH: dependent dropdown'),
+  $items['examples/ahah_example/dependent_dropdown'] = array(
+    'title' => 'Degrading dependent dropdown',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('ahah_example_dropdown'),
     'access callback' => TRUE,
+    'weight' => 4,
+    'type' => MENU_LOCAL_TASK,
     'file' => 'dependent_dropdown.inc',
   );
-  $items['ahah_example/dependent_dropdown/callback'] = array(
-    'type' => MENU_CALLBACK,
+  $items['examples/ahah_example/dependent_dropdown/callback'] = array(
     'page callback' => 'ahah_example_dropdown_callback',
     'access callback' => TRUE,
     'file' => 'dependent_dropdown.inc',
-    );
+    'type' => MENU_CALLBACK,
+  );
+  $items['examples/ahah_example/simple_validation'] = array(
+    'title' => 'Simple Validation',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('ahah_example_simple_validation'),
+    'access callback' => TRUE,
+    'type' => MENU_LOCAL_TASK,
+    'file' => 'ahah_example_simple_validation.inc',
+    'weight' => 6,
+  );
+  $items['examples/ahah_example/simple_validation/callback'] = array(
+    'page callback' => 'ahah_example_simple_validation_callback',
+    'access callback' => TRUE,
+    'file' => 'ahah_example_simple_validation.inc',
+    'type' => MENU_CALLBACK,
+  );
+
   return $items;
 }
 
+/**
+ * Does the very standard things that must be done in any normal callback.
+ * Used by each callback in this example module.
+ */
+function ahah_example_callback_helper() {
+	$form_state = array('storage' => NULL, 'submitted' => FALSE);
+  $form_build_id = $_POST['form_build_id'];
+  $form = form_get_cache($form_build_id, $form_state);
+  $args = $form['#parameters'];
+  $form_id = array_shift($args);
+  $form_state['post'] = $form['#post'] = $_POST;
+  $form['#programmed'] = $form['#redirect'] = FALSE;
+  drupal_process_form($form_id, $form, $form_state);
+  $form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
+	return $form;
+}
 
 /**
  * Implements hook_init() to add module css.
diff --git ahah_example/ahah_example_simple_validation.inc ahah_example/ahah_example_simple_validation.inc
new file mode 100644
index 0000000..00f2d52
--- /dev/null
+++ ahah_example/ahah_example_simple_validation.inc
@@ -0,0 +1,70 @@
+<?php
+
+/**
+ * @file
+ * Demonstrate validation of a textfield using AHAH.
+ * This approach allows 'live' validation of a field which degrades gracefully
+ * when JavaScript is not available.
+ */
+function ahah_example_simple_validation(&$form_state) {
+
+	// Wrap the dynamic element in a fieldset, as some themes render the throbber
+	// wrong and things appear to jump around on the screen. This can also be
+	// fixed with some CSS.
+	$form['wrapper_fieldset'] = array(
+	 '#type' => 'fieldset',
+	);
+  $form['wrapper_fieldset']['two_words_required'] = array(
+    '#title' => t('At least two words are required in this textfield'),
+    '#type' => 'textfield',
+    '#default_value' => !empty($form_state['values']['two_words_required']) ? $form_state['values']['two_words_required'] : '',
+    '#ahah' => array(
+      'path' => 'examples/ahah_example/simple_validation/callback',
+      'wrapper' => 'two_words_required_wrapper',
+    ),
+    '#prefix' => '<div id="two_words_required_wrapper">',
+    '#suffix' => '</div>',
+  );
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Click Me'),
+  );
+
+  return $form;
+}
+
+/**
+ * Validation function for the form. Requires that two words be entered.
+ */
+function ahah_example_simple_validation_validate(&$form, &$form_state) {
+	$words = explode(' ', $form_state['values']['two_words_required']);
+	if (count($words) < 2) {
+		form_set_error('two_words_required', t('You have to enter at least two words'));
+	}
+}
+/**
+ * Callback for autocheckboxes. Process the form with the number of checkboxes
+ * we want to provide.
+ */
+function ahah_example_simple_validation_callback() {
+  $form = ahah_example_callback_helper();
+  
+  // This section prepares the actual output that will be returned to the 
+  // browser.
+  $selected_portion = $form['wrapper_fieldset']['two_words_required'];
+  
+  // To avoid doubling-up the wrapper, we have to remove it here.
+  unset($selected_portion['#prefix'], $selected_portion['#suffix']);
+  
+  // Now render and output.
+  $output = drupal_render($selected_portion);
+  
+  // Include (optionally) the results of any drupal_set_message() calls that
+  // may have occurred.
+  $output .= theme('status_messages');  
+  
+  // Output the results and exit.
+  print drupal_json(array('status' => TRUE, 'data' => $output));
+  exit();
+}
\ No newline at end of file
diff --git ahah_example/autocheckboxes.inc ahah_example/autocheckboxes.inc
index 3f07cbf..b68647f 100644
--- ahah_example/autocheckboxes.inc
+++ ahah_example/autocheckboxes.inc
@@ -14,7 +14,7 @@ function ahah_example_autocheckboxes(&$form_state) {
     '#options' => array(1=>1, 2=>2, 3=>3, 4=>4),
     '#default_value' => $default,
     '#ahah' => array(
-      'path' => 'ahah_example/autocheckboxes/callback',
+      'path' => 'examples/ahah_example/autocheckboxes/callback',
       'wrapper' => 'checkboxes',
       'effect' => 'fade',
       // 'event' => 'change', // default value: does not need to be set explicitly.
@@ -56,25 +56,15 @@ function ahah_example_autocheckboxes(&$form_state) {
  * we want to provide.
  */
 function ahah_example_autocheckboxes_callback() {
-  $form_state = array('storage' => NULL, 'submitted' => FALSE);
-  $form_build_id = $_POST['form_build_id'];
-  $form = form_get_cache($form_build_id, $form_state);
-
-  $args = $form['#parameters'];
-  $form_id = array_shift($args);
-  $form_state['post'] = $form['#post'] = $_POST;
-  $form['#programmed'] = $form['#redirect'] = FALSE;
-
-  // HACK: Select values changing never get recognized.
-  unset ($form['howmany']['#value']);
-
-  drupal_process_form($form_id, $form, $form_state);
-  $form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
-
+  $form = ahah_example_callback_helper();
+	
   $checkboxes = $form['checkboxes'];
+  // Remove the wrapper so we don't double it up.
+  unset($checkboxes['#prefix'], $checkboxes['#suffix']);
+
   $output = theme('status_messages');  
   $output .= drupal_render($checkboxes);
-
+  
   // Final rendering callback.
   print drupal_json(array('status' => TRUE, 'data' => $output));
   exit();
diff --git ahah_example/autotextfields.inc ahah_example/autotextfields.inc
index 4b1dc56..8d09b69 100644
--- ahah_example/autotextfields.inc
+++ ahah_example/autotextfields.inc
@@ -13,8 +13,8 @@ function ahah_example_autotextfields(&$form_state) {
     '#title' => t('Ask me my first name'),
     '#default_value' => $default_first_name,
     '#ahah' => array(
-      'path' => 'ahah_example/autotextfields/callback',
-      'wrapper' => 'textfields',
+      'path' => 'examples/ahah_example/autotextfields/callback',
+      'wrapper' => 'textfield-wrapper',
       'effect' => 'fade',
     )
   );
@@ -24,8 +24,8 @@ function ahah_example_autotextfields(&$form_state) {
    '#default_value' => $default_last_name,
 
     '#ahah' => array(
-      'path' => 'ahah_example/autotextfields/callback',
-      'wrapper' => 'textfields',
+      'path' => 'examples/ahah_example/autotextfields/callback',
+      'wrapper' => 'textfield-wrapper',
       'effect' => 'fade',
       // 'event' => 'change', // default value: does not need to be set explicitly.
 
@@ -34,7 +34,7 @@ function ahah_example_autotextfields(&$form_state) {
 
   $form['textfields'] = array(
     '#title' => t("Generated text fields for first and last name"),
-    '#prefix' => '<div id="textfields">',
+    '#prefix' => '<div id="textfield-wrapper">',
     '#suffix' => '</div>',
     '#type' => 'fieldset',
     '#description' => t('This is where we put automatically generated textfields'),
@@ -65,19 +65,14 @@ function ahah_example_autotextfields(&$form_state) {
 
 
 function ahah_example_autotextfields_callback() {
-  $form_state = array('storage' => NULL, 'submitted' => FALSE);
-  $form_build_id = $_POST['form_build_id'];
-  $form = form_get_cache($form_build_id, $form_state);
-
-  $args = $form['#parameters'];
-  $form_id = array_shift($args);
-  $form_state['post'] = $form['#post'] = $_POST;
-  $form['#programmed'] = $form['#redirect'] = FALSE;
-
-  drupal_process_form($form_id, $form, $form_state);
-  $form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
-
+  $form = ahah_example_callback_helper();
+	
   $textfields = $form['textfields'];
+  
+  // Remove the prefix/suffix wrapper so we don't double it up.
+  unset($textfields['#prefix'], $textfields['#suffix']);
+  
+  // Render the output.
   $output = theme('status_messages');  
   $output .= drupal_render($textfields);
 
diff --git ahah_example/dependent_dropdown.inc ahah_example/dependent_dropdown.inc
index 18511dc..a6c0114 100644
--- ahah_example/dependent_dropdown.inc
+++ ahah_example/dependent_dropdown.inc
@@ -4,59 +4,65 @@
  * @file
  * Show/hide textfields based on checkbox clicks.
  */
+
+/**
+ * Form builder function to create a form showing dependent dropdowns. The
+ * second dropdown has its values populated based on the first.
+ * @param $form_state
+ * @param $my_values
+ */
 function ahah_example_dropdown(&$form_state, $my_values = array()) {
   $form = array();
-  $form['#cache'] = TRUE;
-  $form['#submit'] = array('ahax_example_dropdown_form_submit');
-  // the contents of $musician will either come from the db or from $form_state
-  if (isset($form_state['my_values'])) {
-    $my_values = $form_state['my_values'] + (array)$my_values;
-  }
-  
+
   // get the list of options to populate the first dropdown
-  $options_first = _ahah_example_get_first_dropdown_options();
+  $initial_options = _ahah_example_get_first_dropdown_options();
 
+  $form['explanation'] = array(
+    '#type' => 'markup',
+    '#value' => '<div>' . t('This is an example of a properly degrading dynamic form. It will work correctly with or without AJAX enabled. However, it has to provide an extra hidden button to change the values in the dependent dropdown.') . '</div>',
+  );
   // if we have a value for the first dropdown from $form_state['values'] we use
   // this both as the default value for the first dropdown and also as a
   // parameter to pass to the function that retrieves the options for the
   // second dropdown.
-  $selected = isset($my_values['dropdown_first']) ? $my_values['dropdown_first'] : key($options_first);
+  $master_selection = !empty($form_state['values']['master_dropdown']) ? $form_state['values']['master_dropdown'] : t('Strings');
 
-  $form['dropdown_first'] = array(
+  $form['master_dropdown'] = array(
     '#type' => 'select',
-    '#title' => 'First Dropdown',
-    '#options' => $options_first,
-    '#default_value' => $selected,
+    '#title' => 'Master Dropdown',
+    '#options' => $initial_options,
+    '#default_value' => $master_selection,
     '#ahah' => array(
-      'path' => 'ahah_example/dependent_dropdown/callback',
-      'wrapper' => 'dropdown-second-replace',
+      'path' => 'examples/ahah_example/dependent_dropdown/callback',
+      'wrapper' => 'dependent-dropdown-wrapper',
       // 'event' => 'change', // default value: does not need to be set explicitly.
     ),
-  );  
+    '#attributes' => array('class' => 'master-dropdown'),
+  );
 
   // The CSS for this module hides this next button if JS is enabled.
-  $form['continue_to_second'] = array(
+  $form['continue_to_dependent_dropdown'] = array(
     '#type' => 'submit',
     '#value' => t('Choose'),
     '#attributes' => array('class' => 'next-button'),
-    '#submit' => array('dropdown_submit_handler'),
+    '#submit' => array('ahah_example_dropdown_continue'),
   );
 
-  $form['dropdown_second_wrapper'] = array(
+  $form['dependent_dropdown_holder'] = array(
     '#tree' => TRUE,
-    '#prefix' => '<div id="dropdown-second-replace">',
+    '#prefix' => '<div id="dependent-dropdown-wrapper">',
     '#suffix' => '</div>',
   );
-  
-  $form['dropdown_second_wrapper']['dropdown_second'] = array(
+
+  $form['dependent_dropdown_holder']['dependent_dropdown'] = array(
     '#type' => 'select',
-    '#title' => 'Second Dropdown',
+    '#title' => t('Dependent Dropdown (changes based on master dropdown)'),
 
     // when the form is rebuilt during processing (either AJAX or multistep),
-    // the $selected variable will now have the new value and so the options
-    // will change.
-    '#options' => _ahah_example_get_second_dropdown_options($selected),
-    '#default_value' => isset($my_values['dropdown_second']) ? $my_values['dropdown_second'] : '',
+    // the $master_selction variable will now have the new value and so the
+    // options will change.
+    '#options' => _ahah_example_get_second_dropdown_options($master_selection),
+    '#default_value' => isset($my_values['dependent_dropdown']) ? $my_values['dependent_dropdown'] : '',
   );
 
 
@@ -65,48 +71,49 @@ function ahah_example_dropdown(&$form_state, $my_values = array()) {
     '#value' => t('Save'),
   );
 
-
   return $form;
 }
 
 /**
-* Submit handler for the second drop down.
-*/
-function dropdown_submit_handler($form, &$form_state) {
-  $values = $form_state['values'];
-  unset($form_state['submit_handlers']);
-  form_execute_handlers('submit', $form, $form_state);
-  $form_state['my_values'] = $values;
-  $form_state['rebuild'] = TRUE;
-}
-
+ * The AHAH callback. It processes the form using ahah_example_callback_helper()
+ * and then
+ */
 function ahah_example_dropdown_callback() {
-  $form_state = array('storage' => NULL, 'submitted' => FALSE);
-  $form_build_id = $_POST['form_build_id'];
-  $form = form_get_cache($form_build_id, $form_state);
+	$form = ahah_example_callback_helper();
+
+  $changed_elements = $form['dependent_dropdown_holder'];
 
-  $args = $form['#parameters'];
-  $form_id = array_shift($args);
-  $form_state['post'] = $form['#post'] = $_POST;
-  $form['#programmed'] = $form['#redirect'] = FALSE;
+  // Prevent duplicate wrappers.
+  unset($changed_elements['#prefix'], $changed_elements['#suffix']);
 
-  drupal_process_form($form_id, $form, $form_state);
-  $form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
+  $output = theme('status_messages') . drupal_render($changed_elements);
 
-  $changed_elements = $form['dropdown_second_wrapper'];
-  unset($changed_elements['#prefix'], $changed_elements['#suffix']); // Prevent duplicate wrappers.
   drupal_json(array(
     'status'   => TRUE,
-    'data'     => theme('status_messages') . drupal_render($changed_elements),
+    'data'     => $output,
   ));
 }
 
+/**
+* Submit handler for 'continue_to_dependent_dropdown'.
+*/
+function ahah_example_dropdown_continue($form, &$form_state) {
+  $values = $form_state['values'];
+  unset($form_state['submit_handlers']);
+  form_execute_handlers('submit', $form, $form_state);
+  $form_state['my_values'] = $values;
+  $form_state['rebuild'] = TRUE;
+}
 
-function ahax_example_dropdown_form_submit($form, &$form_state) {
+/**
+ * Default submit handler for form. This one happens when the main submit
+ * button is pressed.
+ */
+function ahax_example_dropdown_submit($form, &$form_state) {
 
   if ($form_state['clicked_button']['#id'] == 'edit-submit') {
       $form_state['rebuild'] = FALSE;
-      drupal_set_message(t('Your values have been submitted. dropdown_first=@first, dropdown_second=@second', array('@first' => $form_state['values']['dropdown_first'], '@second' => $form_state['values']['dropdown_second_wrapper']['dropdown_second'])));
+      drupal_set_message(t('Your values have been submitted. dropdown_first=@first, dependent_dropdown=@second', array('@first' => $form_state['values']['dropdown_first'], '@second' => $form_state['values']['dependent_dropdown_wrapper']['dependent_dropdown'])));
   }
 
   // edit-next or anything else will cause rebuild.
diff --git ahah_example/simplest_ahah.inc ahah_example/simplest_ahah.inc
index fc42333..f17231f 100644
--- ahah_example/simplest_ahah.inc
+++ ahah_example/simplest_ahah.inc
@@ -4,8 +4,18 @@
  * @file
  * A Hello-world AHAH. Just swaps out a markup section on submit.
  */
-function ahah_example_simplest() {
 
+/**
+ * This trivial form builder function just creates a box as a section on the
+ * page which can be replaced when AHAH-enabled submit element fires.
+ */
+function ahah_example_simplest(&$form_state) {
+
+	$form['explanation'] = array(
+	 '#type' => 'markup',
+	 '#value' => '<div>' . t('This is the very simplest AHAH example, which just replaces the HTML for a div on the page. Notice the more advanced examples in the other tabs.') . '</div>',
+	);
+	
   $initial_markup = '<div style="width: 150px; height: 150px; border: 1px solid black">' . t('This box will be replaced') . '</div>';
 
   $form['box'] = array(
@@ -18,7 +28,7 @@ function ahah_example_simplest() {
   $form['submit'] = array(
     '#type' => 'submit',
     '#ahah' => array(
-      'path' => 'ahah_example/simplest_ahah/callback',
+      'path' => 'examples/ahah_example/simplest_ahah/callback',
       'wrapper' => 'box',
     ),
     '#value' => t('Click Me to change box color'),
@@ -27,6 +37,10 @@ function ahah_example_simplest() {
   return $form;
 }
 
+/**
+ * This callback has nothing to do with the form itself, so just returns a bit
+ * of HTML that will replace the existing markup in $form['box'].
+ */
 function ahah_example_simplest_callback() {
   $colors = preg_split('/[ ,]+/', "aqua, black, blue, fuchsia, gray, green, lime, maroon, navy, olive, purple, red, silver, teal, white, yellow");
   $color = $colors[array_rand($colors)];
