diff --git a/includes/wizard.menu.inc b/includes/wizard.menu.inc
new file mode 100644
index 0000000..fe42d7e
--- /dev/null
+++ b/includes/wizard.menu.inc
@@ -0,0 +1,69 @@
+<?php
+
+/**
+ * @file
+ * Contains menu item registration for the wizard plugin.
+ */
+
+function ctools_wizard_menu(&$items) {
+  ctools_include('wizard');
+  // page for wizard demo page
+  $base = array(
+    'access callback' => TRUE,
+    'page callback' => 'ctools_wizard_demo_page',
+    'file' => 'includes/wizard.menu.inc',
+    'file path' => drupal_get_path('module', 'ctools'),
+  );
+  $items['ctools_wizard_demo_page'] = array(
+    'title' => 'Chaos Tools Wizard Plugin Demo',
+    'type' => MENU_NORMAL_ITEM,
+  ) + $base;
+  // provide reasonable defaults, menu access and page callbacks, etc. for
+  // individual wizards
+  $defaults = array(
+    'page callback' => 'ctools_wizard_page',
+    'file' => 'includes/wizard.inc',
+  ) + $base;
+  foreach (ctools_get_wizards() as $wizard) {
+    if (array_key_exists('access', $wizard)) {
+      $defaults['access callback'] = $wizard['access'];
+      if (array_key_exists('access arguments', $wizard)) {
+        if (!is_array($wizard['access arguments'])) {
+          $defaults['access arguments'] = array($wizard['access arguments']);
+        }
+        else {
+          $defaults['access arguments'] = $wizard['access arguments'];
+        }
+      }
+    }
+    $items[$wizard['wizard path']] = array(
+      'title' => $wizard['title'],
+      'description' => $wizard['description'],
+      'page arguments' => array($wizard),
+      'type' => $wizard['type'],
+    ) + $defaults;
+  }
+}
+
+// -------------------------------------------------------------------------
+// Page callbacks
+
+/**
+ * Page callback to display links and render a container for wizard demo
+ * stuff.
+ */
+function ctools_wizard_demo_page() {
+  global $user;
+
+  // Create a list of clickable links.
+  $links = array();
+
+  // Two ways to do our wizard plugin example.
+  $links[] = l(t('Wizard-Plugin Example'), 'ctools-example/wizard-plugin');
+  $links[] = l(t('Paged Wizard-Plugin Example'), 'ctools-example/paged-wizard-plugin');
+
+  $output = theme('item_list', array('items' => $links, 'title' => t('Actions')));
+
+  return array('markup' => array('#markup' => $output));
+}
+
diff --git a/includes/wizard.plugin-type.inc b/includes/wizard.plugin-type.inc
new file mode 100644
index 0000000..aba854c
--- /dev/null
+++ b/includes/wizard.plugin-type.inc
@@ -0,0 +1,17 @@
+<?php
+
+/**
+ * @file
+ * Contains plugin type registration information for the wizard plugin tool.
+ */
+
+function ctools_wizard_plugin_type(&$items) {
+  $items['wizard'] = array(
+    'process' => array(
+      'function' => 'ctools_wizard_process',
+      'file' => 'wizard.inc',
+      'path' => drupal_get_path('module', 'ctools') . '/includes',
+    ),
+    'classes' => array('handler'),
+  );
+}
diff --git a/plugins/wizard/base/ctools_wizard.class.php b/plugins/wizard/base/ctools_wizard.class.php
new file mode 100644
index 0000000..776e719
--- /dev/null
+++ b/plugins/wizard/base/ctools_wizard.class.php
@@ -0,0 +1,113 @@
+<?php
+
+/**
+ * ctools_wizard is a base class for all other wizards to build upon.
+ */
+class ctools_wizard {
+  // The active plugin that invoked this class is passed into it.
+  var $plugin;
+
+  /**
+   * Initialization method for the class.
+   *
+   * @param $plugin
+   *  The fully loaded plugin array for future reference.
+   */
+  function init($plugin) {
+    $this->plugin = $plugin;
+  }
+
+  /**
+   * A seeding function for the form_state of our wizard.
+   *
+   * @param $key
+   *  A unique key to identify the values for this wizard instance to be
+   *  retrieved from the object-cache.
+   *
+   * @return
+   *  A form_state array ready for use within ctools_wizard_multistep_form().
+   */
+  function form_state_seed($key) {
+    $form_state = array(
+      $this->plugin['form_state_key'] => ctools_wizard_object_cache('get', $key),
+      'unique key' => $key,
+      'object' => $this,
+    );
+    if (isset($this->plugin['form_state_seed'])) {
+      $form_state += $this->plugin['form_state_seed'];
+    }
+    return $form_state;
+  }
+
+  /**
+   * A form_info creation function for use in our wizard.
+   *
+   * @return
+   *  A form_info array ready for use within ctools_wizard_multistep_form().
+   */
+  function form_info() {
+    $plugin = $this->plugin;
+    $form_info = array(
+      'id' => $plugin['id'],
+      'path' => $plugin['wizard path'] . "/%step",
+      'show trail' => $plugin['show trail'],
+      'show back' => $plugin['show back'],
+      'show return' => $plugin['show return'],
+      'next callback' => $plugin['next callback'],
+      'finish callback' => $plugin['finish callback'],
+      'return callback' => $plugin['return callback'],
+      'cancel callback' => $plugin['cancel callback'],
+      'order' => $plugin['order'],
+      'forms' => $plugin['forms'],
+    );
+    return $form_info;
+  }
+
+  /**
+   * Invokes the actual ctools wizard callbacks properly.
+   *
+   * @param $step
+   *  The current step of the wizard instance.
+   * @param $key
+   *  The unique key for object-cache values identification.
+   *
+   * @return
+   *  Returns the form of the current step in our wizard.
+   */
+  function wizard($step, $key) {
+    ctools_include('wizard');
+    $output = ctools_wizard_multistep_form($this->form_info(), $step, $this->form_state_seed($key));
+    return $output;
+  }
+
+  /**
+   * Generic "next callback" method for our wizard.
+   *
+   * @see ctools_wizard_wizard_next()
+   */
+  function wizard_next(&$form_state) {
+    ctools_wizard_object_cache('set', $form_state['unique key'], $form_state[$this->plugin['form_state_key']]);
+  }
+
+  /**
+   * Generic "finish callback" method for our wizard.
+   *
+   * @see ctools_wizard_wizard_finish()
+   */
+  function wizard_finish(&$form_state) {
+    if ($callback = ctools_plugin_get_function($this->plugin, 'wizard finish')) {
+      $callback($form_state[$this->plugin['form_state_key']]);
+    }
+    ctools_wizard_object_cache('clear', $form_state['unique key']);
+    $form_state['redirect'] = $this->plugin['redirect'];
+  }
+
+  /**
+   * Generic "cancel callback" method for our wizard.
+   *
+   * @see ctools_wizard_wizard_cancel()
+   */
+  function wizard_cancel($form_state) {
+    ctools_wizard_object_cache('clear', $form_state['unique key']);
+  }
+}
diff --git a/plugins/wizard/base/wizard.inc b/plugins/wizard/base/wizard.inc
new file mode 100644
index 0000000..cc12bc7
--- /dev/null
+++ b/plugins/wizard/base/wizard.inc
@@ -0,0 +1,143 @@
+<?php
+
+/**
+ * @file
+ * CTools' multi-step form wizard plugin type.
+ *
+ * This plugin demostrates the necessary components for building a ctools
+ * style wizard through the simple use of a plugin. This plugin utilizes the
+ * ctools_wizard class, in this same directory, and simply specifies a handful
+ * of settings, and form validate and submit handlers for each step. It then
+ * specifies a 'wizard finish' callback for what to do with the final values
+ * set in the wizard itself.
+ *
+ * Please note in the submit handlers how all values are passed to
+ * $form_state['wizard']. This is our 'form_state_key' which could be renamed
+ * by setting a 'form_state_key' in the $plugin array. Validate/Submit handlers
+ * assume the plugin creator will know what 'form_state_key' is being used for
+ * this plugin. If not set (as is the case in this plugin) 'form_state_key'
+ * will default to 'wizard'.
+ *
+ * Many other defaults are set as well, for a more detailed look of settings
+ * that are available within the $plugin array look at ctools_wizard_process().
+ *
+ * @see ctools_wizard_process()
+ */
+
+/**
+ * An example ctools wizard plugin.
+ */
+$plugin = array(
+  'title' => 'Wizard Plugin',
+  'description' => 'An example plugin for ctools wizard plugins.',
+  'id' => 'ctools_wizard_plugin_example',
+  'type' => MENU_CALLBACK,
+  'handler' => array(
+    'class' => 'ctools_wizard',
+  ),
+  'wizard path' => 'ctools-example/wizard-plugin',
+  'first step' => 'page1',
+  'order' => array(
+    'page1' => t('Page 1'),
+    'page2' => t('Page 2'),
+    'page3' => t('Page 3'),
+  ),
+  'forms' => array(
+    'page1' => array(
+      'form id' => 'ctools_wizard_example_page1'
+    ),
+    'page2' => array(
+      'form id' => 'ctools_wizard_example_page2'
+    ),
+    'page3' => array(
+      'form id' => 'ctools_wizard_example_page3'
+    ),
+  ),
+  'wizard finish' => 'ctools_wizard_example_finish',
+);
+
+/**
+ * A simple textfield for gathering a numeric value.
+ */
+function ctools_wizard_example_page1($form, $form_state) {
+  $form['example_1'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Example Field 1'),
+    '#description' => t('Fill this field with a numeric value.'),
+    '#required' => TRUE,
+    '#default_value' => isset($form_state['wizard']['example_1']) ? $form_state['wizard']['example_1'] : '',
+  );
+  return $form;
+}
+
+/**
+ * Check the value of our form element to see that it is numeric.
+ */
+function ctools_wizard_example_page1_validate(&$form, &$form_state) {
+  if (!is_numeric($form_state['values']['example_1'])) {
+    form_set_error('example_1', t('This field must be numeric.'));
+  }
+}
+
+/**
+ * Place our value in the 'form_state_key' defined section of our form_state.
+ * This section is saved to the object-cache on each next callback invocation.
+ */
+function ctools_wizard_example_page1_submit($form, &$form_state) {
+  $form_state['wizard']['example_1'] = $form_state['values']['example_1'];
+}
+
+/**
+ * A simple textfield for gathering a second numeric value.
+ */
+function ctools_wizard_example_page2($form, $form_state) {
+  $form['example_2'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Example Field 2'),
+    '#description' => t('This field must be the same value as the previous field to pass validation.'),
+    '#required' => TRUE,
+    '#default_value' => isset($form_state['wizard']['example_2']) ? $form_state['wizard']['example_2'] : '',
+  );
+  return $form;
+}
+
+/**
+ * Demonstrates cross form validation with previous values. Requires the second
+ * value to be equal to the orginal value.
+ */
+function ctools_wizard_example_page2_validate(&$form, &$form_state) {
+  if ($form_state['values']['example_2'] != $form_state['wizard']['example_1']) {
+    form_set_error('example_2', t('This field must be equal to your example 1 answer.'));
+  }
+}
+
+/**
+ * Again, place our value in the 'form_state_key' defined section of our
+ * form_state to guarantee the values are saved.
+ */
+function ctools_wizard_example_page2_submit($form, &$form_state) {
+  $form_state['wizard']['example_2'] = $form_state['values']['example_2'];
+}
+
+/**
+ * A simple form that just display the previously submitted values.
+ */
+function ctools_wizard_example_page3($form, $form_state) {
+  $header = array(t('Labels'), t('Values'));
+  $rows = array(
+    array(t('Example Field 1'), $form_state['wizard']['example_1']),
+    array(t('Example Field 2'), $form_state['wizard']['example_2']),
+  );
+  $form['results']['#markup'] = theme('table', array('header' => $header, 'rows' => $rows));
+  return $form;
+}
+
+/**
+ * Prove that our values were in the object cache, and do something with them
+ * before the object cache is cleared. This is the last function to fire before
+ * the values are lost, so if you are going to save them, now is the time to do
+ * it.
+ */
+function ctools_wizard_example_finish($values) {
+  drupal_set_message('<pre>' . var_export($values, TRUE) . '</pre>');
+}
diff --git a/plugins/wizard/paged/paged-1.inc b/plugins/wizard/paged/paged-1.inc
new file mode 100644
index 0000000..045cf1c
--- /dev/null
+++ b/plugins/wizard/paged/paged-1.inc
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * A simple textfield for gathering a numeric value.
+ */
+function ctools_wizard_plugin_paged_example_paged_1($form, $form_state) {
+  $form['example_1'] = array(
+    '#type' => 'select',
+    '#options' => array(
+      'happy' => 'happy',
+      'angry' => 'angry',
+      'bored' => 'bored',
+      'sad' => 'sad',
+    ),
+    '#title' => t('Example Emotion 1'),
+    '#description' => t('Select an emotion, (but not angry).'),
+    '#required' => TRUE,
+    '#default_value' => isset($form_state['wizard']['example_1']) ? $form_state['wizard']['example_1'] : '',
+  );  
+  return $form;
+}
+
+/**
+ * Check the value of our form element to see that it is numeric.
+ */
+function ctools_wizard_plugin_paged_example_paged_1_validate(&$form, &$form_state) {
+  if ('angry' == $form_state['values']['example_1']) {
+    form_set_error('example_1', t('Angry emotions not allowed.'));
+  }
+}
+
+/**
+ * Place our value in the 'form_state_key' defined section of our form_state.
+ * This section is saved to the object-cache on each next callback invocation.
+ */
+function ctools_wizard_plugin_paged_example_paged_1_submit($form, &$form_state) {
+  $form_state['wizard']['example_1'] = $form_state['values']['example_1'];
+}
+
+
diff --git a/plugins/wizard/paged/paged-2.inc b/plugins/wizard/paged/paged-2.inc
new file mode 100644
index 0000000..2bd81bc
--- /dev/null
+++ b/plugins/wizard/paged/paged-2.inc
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * A simple textfield for gathering a numeric value.
+ */
+function ctools_wizard_plugin_paged_example_paged_2($form, $form_state) {
+  $form['show_example_1'] = array(
+    '#type' => 'item',
+    '#title' => t('Emotion from page 1'),
+    '#markup' => isset($form_state['wizard']['example_1']) ? $form_state['wizard']['example_1'] : '',
+  );  
+  $form['example_2'] = array(
+    '#type' => 'select',
+    '#options' => array(
+      'happy' => 'happy',
+      'angry' => 'angry',
+      'bored' => 'bored',
+      'sad' => 'sad',
+    ),
+    '#title' => t('Example Emotion 2'),
+    '#description' => t('This field must be the same value as the previous field (%em1) to pass validation.', array('%em1' => $form_state['wizard']['example_1'])),
+    '#required' => TRUE,
+    '#default_value' => isset($form_state['wizard']['example_2']) ? $form_state['wizard']['example_2'] : '',
+  );
+  return $form;
+}
+
+/**
+ * Demonstrates cross form validation with previous values. Requires the 
+ * second value to be equal to the orginal value.
+ */
+function ctools_wizard_plugin_paged_example_paged_2_validate(&$form, &$form_state) {
+  if ($form_state['values']['example_2'] != $form_state['wizard']['example_1']) {
+    form_set_error('example_2', t('This field must be equal to your example 1 answer.'));
+  }
+}
+
+/**
+ * Again, place our value in the 'form_state_key' defined section of our
+ * form_state to guarantee the values are saved.
+ */
+function ctools_wizard_plugin_paged_example_paged_2_submit($form, &$form_state) {
+  $form_state['wizard']['example_2'] = $form_state['values']['example_2'];
+}
+
+
diff --git a/plugins/wizard/paged/paged-3.inc b/plugins/wizard/paged/paged-3.inc
new file mode 100644
index 0000000..cd0f35b
--- /dev/null
+++ b/plugins/wizard/paged/paged-3.inc
@@ -0,0 +1,15 @@
+<?php
+
+/**
+ * A simple textfield for gathering a numeric value.
+ */
+function ctools_wizard_plugin_paged_example_paged_3($form, $form_state) {
+  $header = array(t('Labels'), t('Values'));
+  $rows = array(
+    array(t('Example Emotion 1'), $form_state['wizard']['example_1']),
+    array(t('Example Emotion 2'), $form_state['wizard']['example_2']),
+  );
+  $form['results']['#markup'] = theme('table', array('header' => $header, 'rows' => $rows));
+  return $form;
+}
+
diff --git a/plugins/wizard/paged/paged_wizard.inc b/plugins/wizard/paged/paged_wizard.inc
new file mode 100644
index 0000000..72ac0a1
--- /dev/null
+++ b/plugins/wizard/paged/paged_wizard.inc
@@ -0,0 +1,79 @@
+<?php
+
+/**
+ * @file
+ * CTools' file-paged multi-step form wizard plugin type.
+ *
+ * This plugin demostrates the necessary components for building a ctools
+ * style wizard through the simple use of the plugin with the added benefit
+ * of pages being stored in seperate files. This plugin utilizes the
+ * ctools_wizard class, in sibling 'base' directory, and simply specifies a
+ * handful of settings. because it set 'wizard paged' as true, the init from
+ * the ctools_wizard class will construct the 'form' array, and include the
+ * form, validate and submit handlers for each step (Each in it's own file).
+ * This $plugin (in this file) then specifies a 'wizard finish' callback for
+ * what to do with the final values set in the wizard itself.
+ *
+ * The difference between this and the base version is that this version
+ * demonstrates the one file per wizard page.  A feature that will make 
+ * larger wizard forms more manageable.  In escense, the difference is 
+ * adding a 'wizard paged' entry in $plugins, and removing the 'forms' entry
+ * which will be built by the process method from the 'order' sub-array, so
+ * that each step in 'order' array, represented by the keys in that array,
+ * become the files from which the forms and callbacks for the step are 
+ * loaded.  
+ *
+ * Please note in the submit handlers how all values are passed to
+ * $form_state['wizard']. This is our 'form_state_key' which could be 
+ * renamed by setting a 'form_state_key' in the $plugin array.
+ * Validate/Submit handlers assume the plugin creator will know what
+ * 'form_state_key' is being used for this plugin. If not set (as is the
+ * case in this plugin) 'form_state_key' will default to 'wizard'.
+ *
+ * 'order' => array(
+ *   'paged-1' => t('Paged File 1'),
+ *   ...
+ *
+ * And 'paged-1' is converted to 'paged-1.inc and sets a new 'forms' entry
+ * for the page's form function by composing the 'id' from $plugins with a
+ * massaged step name, where 'paged-1' becomes 'paged_1' via
+ * ctools_cleanstring.  So here, in example, with an 'id' of 
+ * 'ctools_wizard_plugin_paged_example', then the system will attempt to 
+ * open the file 'paged-1.inc' in this directory, searching for a function:
+ * 'ctools_wizard_plugin_paged_example_paged_1()' If found then that name
+ * is installed in the 'forms' array for the wizard-page step.
+ *
+ * @see ctools_wizard::process()
+ */
+
+/**
+ * An example ctools wizard file-paged plugin.
+ */
+$plugin = array(
+  'title' => 'Wizard Paged Plugin',
+  'description' => 'An example plugin for ctools wizard plugins with automatical pages (as seperate files).',
+  'id' => 'ctools_wizard_plugin_paged_example',
+  'type' => MENU_CALLBACK,
+  'wizard path' => 'ctools-example/paged-wizard-plugin',
+  'wizard paged' => TRUE,
+  'first step' => 'paged-1',
+  // each entry in order will load a page to get the forms entry and the
+  // functions asscociated with them.
+  'order' => array(
+    'paged-1' => t('Paged File 1'),
+    'paged-2' => t('Paged File 2'),
+    'paged-3' => t('Paged File 3'),
+  ),
+  'wizard finish' => 'ctools_paged_wizard_example_finish',
+);
+
+/**
+ * Prove that our values were in the object cache, and do something with 
+ * them before the object cache is cleared. This is the last function to
+ * fire before the values are lost, so if you are going to save them, now is
+ * the time to do it.
+*/   
+function ctools_paged_wizard_example_finish($values) {
+  drupal_set_message('<pre>' . var_export($values, TRUE) . '</pre>');
+} 
+
