diff --git render_example/render_example.info render_example/render_example.info
new file mode 100644
index 0000000..99da8a8
--- /dev/null
+++ render_example/render_example.info
@@ -0,0 +1,7 @@
+; $Id$
+name = Render example
+description = Demonstrates drupal_render's capabilities and altering render arrays
+core = 7.x
+files[] = render_example.module
+files[] = render_example.test
+dependencies[] = devel
diff --git render_example/render_example.install render_example/render_example.install
new file mode 100644
index 0000000..dec07f7
--- /dev/null
+++ render_example/render_example.install
@@ -0,0 +1,17 @@
+<?php
+// $Id$
+/**
+ * @file render_example.install
+ * Install/uninstall routines for render example.
+ */
+
+/**
+ * Implementation of hook_uninstall().
+ */
+function render_example_uninstall() {
+  variable_del('render_example_show_page');
+  variable_del('render_example_show_block');
+  variable_del('render_example_reverse_sidebar');
+  variable_del('render_example_note_about_render_arrays');
+  variable_del('render_example_move_navigation_menu');
+}
diff --git render_example/render_example.module render_example/render_example.module
new file mode 100644
index 0000000..4e0481e
--- /dev/null
+++ render_example/render_example.module
@@ -0,0 +1,262 @@
+<?php
+// $Id$
+/**
+ * @file render_example.module
+ * Demonstrate how render arrays are arranged and how they can be altered.
+ * This alters forms, blocks, and the page to show the actual render array
+ * that is being used to create each item.
+ */
+
+/**
+ * Implementation of hook_menu().
+ */
+function render_example_menu() {
+  $items['examples/render_example'] = array(
+    'title' => 'Render Array Example',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('render_example_demo_form'),
+    'access arguments' => array('access devel information'),
+  );
+
+  return $items;
+}
+
+
+/**
+ * Builds the form that offers options of what items to show.
+ */
+function render_example_demo_form($form, &$form_state) {
+  $form['description'] = array(
+    '#type' => 'markup',
+    '#markup' => t('This example shows what render arrays look like in the building of a page. It will not work unless the user running it has the "access devel information" privilege. It shows both the actual arrays used to build a page or block and also the capabilities of altering the page late in its lifecycle.'),
+  );
+
+  $form['show_arrays'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Show render arrays'),
+  );
+
+  foreach (array('block', 'page') as $type) {
+    $form['show_arrays']['render_example_show_' . $type] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Show @type render arrays', array('@type' => $type)),
+      '#default_value' => variable_get('render_example_show_' . $type, FALSE),
+    );
+  }
+
+  $form['page_fiddling'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Make changes on page via hook_page_alter()'),
+  );
+  $form['page_fiddling']['render_example_note_about_render_arrays'] = array(
+    '#title' => t('Add a note about render arrays to top of sidebar_first (if it exists)'),
+    '#description' => t('Creates a simple render array that displays the use of #pre_render, #post_render, #theme, and #theme_wrappers.'),
+    '#type' => 'checkbox',
+    '#default_value' => variable_get('render_example_note_about_render_arrays', FALSE),
+  );
+  $form['page_fiddling']['render_example_move_navigation_menu'] = array(
+    '#title' => t('Move the navigation menu to the top of the content area'),
+    '#description' => t('Uses hook_page_alter() to move the navigation menu into another region.'),
+    '#type' => 'checkbox',
+    '#default_value' => variable_get('render_example_move_navigation_menu', FALSE),
+  );
+  $form['page_fiddling']['render_example_reverse_sidebar'] = array(
+    '#title' => t('Reverse ordering of sidebar_first elements (if it exists) - will affect the above'),
+    '#description' => t('Uses hook_page_alter() to reverse the ordering of items in sidebar_first'),
+    '#type' => 'checkbox',
+    '#default_value' => variable_get('render_example_reverse_sidebar', FALSE),
+  );
+
+  return system_settings_form($form);
+}
+
+/**
+ * Alters the page to add to the footer a demonstration of the render
+ * array that built it.
+ */
+function render_example_page_alter(&$page) {
+
+  $original_page = $page;
+
+  // Re-sort the sidebar in reverse order.
+  if (variable_get('render_example_reverse_sidebar', FALSE) && !empty($page['sidebar_first'])) {
+    $page['sidebar_first'] = array_reverse($page['sidebar_first']);
+    foreach(element_children($page['sidebar_first']) as $element) {
+      // Reverse the weights if they exist.
+      if (!empty($page['sidebar_first'][$element]['#weight'])) {
+        $page['sidebar_first'][$element]['#weight'] *= -1;
+      }
+    }
+    $page['sidebar_first']['#sorted'] = FALSE;
+  }
+
+  // Add a list of items to the top of sidebar_first.
+  // This shows how #theme and #theme_wrappers work.
+  if (variable_get('render_example_note_about_render_arrays', FALSE) && !empty($page['sidebar_first'])) {
+    $items = array(
+      t('Render arrays are everywhere in D7'),
+      t('Leave content unrendered as much as possible'),
+      t('This allows rearrangement and alteration very late in page cycle'),
+    );
+
+    $note = array(
+      '#title' => t('Render Array Example'),
+      '#items' => $items,
+
+      // The functions in #pre_render get to alter the actual data before it
+      // gets rendered by the various theme functions.
+      '#pre_render' => array('render_example_change_to_ol'),
+      // The functions in #post_render get both the element and the rendered
+      // data and can add to the rendered data.
+      '#post_render' => array('render_example_add_hr'),
+      // The #theme theme operation gets the first chance at rendering the
+      // element and its children.
+      '#theme' => 'item_list',
+      // Then the theme operations in #theme_wrappers can wrap more around
+      // what #theme left in #chilren.
+      '#theme_wrappers' => array('render_example_add_div', 'render_example_add_notes'),
+      '#weight' => -9999,
+    );
+    $page['sidebar_first']['render_array_note'] = $note;
+    $page['sidebar_first']['#sorted'] = FALSE;
+  }
+
+
+  // Move the navigation menu into the content area.
+  if (variable_get('render_example_move_navigation_menu', FALSE) && !empty($page['sidebar_first']['system_navigation']) && !empty($page['content'])) {
+    $page['content']['system_navigation'] = $page['sidebar_first']['system_navigation'];
+    $page['content']['system_navigation']['#weight'] = -99999;
+    unset($page['content']['#sorted']);
+    unset($page['sidebar_first']['system_navigation']);
+  }
+
+  // Show the render array used to build the page render array display.
+  if (variable_get('render_example_show_page', FALSE)) {
+    $form['render_example_page_fieldset'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Page render array'),
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+    );
+    $form['render_example_page_fieldset']['markup'] = array(
+      '#markup' => kpr($page, TRUE),
+    );
+    $page['content']['page_render_array'] = drupal_get_form('render_example_embedded_form', $form);
+    $page['content']['page_render_array'] = -999999;
+    $page['content']['#sorted'] = FALSE;
+  }
+
+  // Add render array to the bottom of each block
+  if (variable_get('render_example_show_block', FALSE)) {
+    foreach (element_children($page) as $region_name) {
+      foreach (element_children($page[$region_name]) as $block_name) {
+
+        // Push the block down a level so we can add another block after it.
+        $old_block = $page[$region_name][$block_name];
+        $page[$region_name][$block_name] = array(
+          $block_name => $old_block,
+        );
+        $form['render_example_block_fieldset'] = array(
+          '#type' => 'fieldset',
+          '#title' => t('Block render array'),
+          '#collapsible' => TRUE,
+          '#collapsed' => TRUE,
+        );
+
+        $form['render_example_block_fieldset']['markup'] = array(
+          '#type' => 'item',
+          '#title' => t('%blockname block render array', array('%blockname' => $block_name)),
+          '#markup' => kpr($old_block, TRUE),
+        );
+
+        // Add the new block that contains the render array.
+        $page[$region_name][$block_name]['render_example_block_render_array'] =  drupal_get_form('render_example_embedded_form', $form);
+        $page[$region_name][$block_name]['render_example_block_render_array']['#weight'] = 999;
+      }
+    }
+  }
+  $altered_page = $page;
+
+}
+
+/**
+ * Utility function to build a named form given a set of form elements.
+ * This is a standard form builder function that takes an additional array,
+ * which is itself a form.
+ *
+ * @param $form
+ * @param $form_state
+ * @param $form_items
+ *   The form items to be included in this form.
+ */
+function render_example_embedded_form($form, &$form_state, $form_items) {
+  return $form_items;
+}
+
+function render_example_theme() {
+  $items = array(
+    'render_example_add_div' => array(
+      'render element' => 'element',
+    ),
+    'render_example_add_notes' => array(
+      'render element' => 'element',
+    ),
+  );
+  return $items;
+}
+
+/**
+ * Wrap a div around the already-rendered #children.
+ */
+function theme_render_example_add_div($variables) {
+  $element = $variables['element'];
+  $output = '<div class="render-example-wrapper-div">';
+  $output .= $element['#children'];
+  $output .= '</div>';
+  return $output;
+}
+
+/**
+ * Wrap a div and add a little text after the rendered #children.
+ */
+function theme_render_example_add_notes($variables) {
+  $element = $variables['element'];
+  $output = '<div class="render-example-notes-wrapper-div">';
+  $output .= $element['#children'];
+  $output .= '<em>' . t('This is a note added by a #theme_wrapper') . '</em>';
+  $output .= '</div>';
+
+  return $output;
+}
+
+/**
+ * Add a #type to the element before it gets rendered.
+ * In this case, changes from the default 'ul' to 'ol'.
+ * @param $element
+ *   The element to be altered, in this case a list, ready for theme_item_list.
+ *
+ * @return
+ *   The altered list (with '#type')
+ */
+function render_example_change_to_ol($element) {
+  $element['#type'] = 'ol';
+  return $element;
+}
+
+/**
+ * This #post_render function gets to alter the rendered output after all
+ * theme functions have acted on it, and it receives the original data, so
+ * can make decisions based on that. In this example, no use is made of the
+ * passed-in $element.
+ * @param $markup
+ *   The already-rendered data
+ * @param unknown_type $element
+ *   The data element that was rendered
+ *
+ * @return
+ *   The altered data.
+ */
+function render_example_add_hr($markup, $element) {
+  $output = $markup . '<hr />';
+  return $output;
+}
\ No newline at end of file
diff --git render_example/render_example.test render_example/render_example.test
new file mode 100644
index 0000000..7fceb4a
--- /dev/null
+++ render_example/render_example.test
@@ -0,0 +1,64 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Test for the render example module.
+ */
+class RenderExampleTestCase extends DrupalWebTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Render example functionality',
+      'description' => t('Test Render Example'),
+      'group' => 'Examples',
+    );
+  }
+
+  /**
+   * Enable modules and create user with specific permissions.
+   */
+  function setUp() {
+    parent::setUp('devel', 'render_example');
+  }
+
+
+  function checkForRenderFieldset($xpath_array) {
+    foreach($xpath_array as $xpath) {
+      $result = $this->xpath($xpath);
+      $this->assertTrue(!empty($result), t('Found xpath ') . $xpath);
+    }
+  }
+  /**
+   * Login user, create an example node, and test blog functionality through the admin and user interfaces.
+   */
+  function testRenderExampleBasic() {
+
+    // Create a user that can access devel information and log in.
+    $web_user = $this->drupalCreateUser(array('access devel information', 'access content'));
+    $this->drupalLogin($web_user);
+
+    $edit = array(
+      'render_example_show_block' => TRUE,
+    );
+    $this->drupalPost('examples/render_example', $edit, t('Save configuration'));
+
+    $xpath_array = array(
+      '//*[@id="sidebar-first"]//*[@id="block-system-navigation"]//fieldset[contains(@class,"block-render-array")]',
+      '//*[@id="content"]//fieldset[contains(@class,"block-render-array")]',
+    );
+    $this->checkForRenderFieldset($xpath_array);
+
+
+    $edit = array(
+      'render_example_show_page' => TRUE,
+      'render_example_show_block' => FALSE,
+    );
+    $this->drupalPost('examples/render_example', $edit, t('Save configuration'));
+
+    $xpath_array = array(
+      '//*[@id="footer"]//*[@id="block-system-navigation"]//fieldset[contains(@class,"block-render-array")]',
+      '//*[@id="content"]//fieldset[contains(@class,"block-render-array")]',
+    );
+    $this->checkForRenderFieldset($xpath_array);
+  }
+}
