diff --git action_example/action_example.module action_example/action_example.module
index 31f84b2..0772c75 100644
--- action_example/action_example.module
+++ action_example/action_example.module
@@ -4,10 +4,18 @@
 /**
  * @file
  * Action definition example module.
+ */
+ 
+/**
+ * @defgroup action_example Example: Action
+ * @ingroup examples
+ * @{
+ * Creating actions in Drupal 7
  *
  * Triggers and actions are a matched pair of Drupal features allowing some
  * Drupal programming without using PHP. Using the appropriate action in a
  * specific event, a site administrator can add new functionality.
+ *
  * Examples are:
  *  - Send an email after a node is published or edited.
  *  - Display a message after a user has logged in.
@@ -54,17 +62,10 @@
  * - An action which extends the capabilities of node triggers, but limited
  *   to certain events only, and using a customizable option.
  *
- * See:
- *
- * @todo this is a drupal 6 link
- * @link http://drupal.org/node/172152 Writing Actions @endlink
- *
- * @todo this is a drupal 6 link
- * @link http://drupal.org/node/199254 Triggers and Actions in Drupal 7 @endlink
- *
+ * @see trigger_example
  * @see hook_action_info()
- * In addition, the @link trigger_example.module Trigger Example @endlink
- * provides detailed information on how to create a trigger.
+ * @see @link http://drupal.org/node/172152 Writing Actions in Drupal 6 @endlink
+ * @see @link http://drupal.org/node/199254 Triggers and Actions in Drupal 6 @endlink
  */
 
 /**
@@ -138,7 +139,7 @@
  *       special care in the "presave" hook, in which case a dependent "save"
  *       action should NOT be invoked.
  *
- * See hook_action_info().
+ * @see hook_action_info()
  */
 function action_example_action_info() {
   return array(
@@ -189,45 +190,36 @@ function _action_example_page() {
   return t("The Action Example provides three example actions which can be configured on the <a href='@actions_url'>Actions configuration page</a> and assigned to triggers on the <a href='@triggers_url'>Triggers configuration page</a>.", array('@actions_url' => url('admin/config/system/actions'), '@triggers_url' => url('admin/structure/trigger/node')));
 }
 
-/*
- * Most basic action.
+/**
+ * Action function for action_example_basic_action.
  *
  * This action is not expecting any type of entity object, and can be used with
  * any trigger type or any event.
- */
-
-/**
- * Basic example action.
  *
  * @param $entity
  *   An optional entity object.
  * @param array $context
  *   Array with parameters for this action: depends on the trigger.
- *
- * @ingroup actions
+ * @see action_example_action_info()
  */
 function action_example_basic_action(&$entity, $context = array()) {
   //
   // In this case we are ignoring the entity and the context. This case of
   // action is useful when your action does not depend on the context, and
   // the function must do something regardless the scope of the trigger.
-  // Simply announces that the action was executed using a messages.
+  // Simply announces that the action was executed using a message.
 
   drupal_set_message(t('action_example_basic_action fired'));
   watchdog('action_example', 'action_example_basic_action fired.');
 }
 
-// ---------------------------------------------------------------------------
-/*
- * A complex action for different trigger types.
+/**
+ * Action function for action_example_unblock_user_action.
  *
  * This action is expecting an entity object user, node or comment. If none of
  * the above is provided (because it was not called from an user/node/comment
  * trigger event, then the action will be taken on the current logged in user.
  *
- */
-
-/**
  * Unblock an user. This action can be fired from different trigger types:
  * - User trigger: this user will be unblocked.
  * - Node/Comment trigger: the author of the node or comment will be unblocked.
@@ -240,8 +232,6 @@ function action_example_basic_action(&$entity, $context = array()) {
  * @param array $context
  *   Array with parameters for this action: depends on the trigger. The context
  *   is not used in this example.
- *
- * @ingroup actions
  */
 function action_example_unblock_user_action(&$entity, $context = array()) {
 
@@ -263,28 +253,27 @@ function action_example_unblock_user_action(&$entity, $context = array()) {
   drupal_set_message(t('Unblocked user %name', array('%name' => $account->name)));
 }
 
-// ---------------------------------------------------------------------------
-/*
- * A complex action using customization.
+/**
+ * Form function for action_example_node_sticky_action.
  *
- * The next action requires a configuration form to create/configure the action.
- * In Drupal these are called 'advanced actions', because they must be
- * customized to define their functionality.
+ * Since we defined action_example_node_sticky_action as 'configurable' => TRUE,
+ * this action requires a configuration form to create/configure the action.
+ * In this circumstance, Drupal will attempt to call a function named by
+ * combining the action name (action_example_node_sticky_action) and _form, in
+ * this case yielding action_example_node_sticky_action_form.
+ *
+ * In Drupal, actions requiring creation and configuration are called 'advanced
+ * actions', because they must be customized to define their functionality.
  *
  * The 'action_example_node_sticky_action' allows creating rules to promote and
  * set sticky content created by selected users on certain events. A form is
  * used to configure which user is affected by this action, and this form
  * includes the stanard _validate and _submit hooks.
- */
-
-
-/**
- * Generates settings form for action_example_node_sticky_action().
  *
  * @param array $context
  *  An array of options of this action (in case it is being edited)
  * @return array $form
- *
+ * @see action_example_action_info()
  */
 function action_example_node_sticky_action_form($context) {
 	/*
@@ -332,8 +321,11 @@ function action_example_node_sticky_action_submit($form, $form_state) {
 }
 
 /**
- * Promote and set sticky flag action. This is the special action that has been
- * customized using the configuration form.
+ * Action function for action_example_node_sticky_action.
+ *
+ * Promote and set sticky flag. This is the special action that has been
+ * customized using the configuration form, validated with the validation
+ * function, and submitted with the submit function.
  *
  * @param $node
  *   A node object provided by the associated trigger.
@@ -341,8 +333,6 @@ function action_example_node_sticky_action_submit($form, $form_state) {
  *   Array with the following elements:
  *   - 'author': username of the author's content this function will promote and
  *     set as sticky.
- *
- * @ingroup actions
  */
 function action_example_node_sticky_action($node, $context) {
   if (function_exists('dsm')) {
@@ -359,3 +349,6 @@ function action_example_node_sticky_action($node, $context) {
     drupal_set_message(t('Set @type %title to sticky and promoted by special action for user %username.', array('@type' => node_type_get_name($node), '%title' => $node->title, '%username' => $account->name)));
   }
 }
+/**
+ * @} End of "defgroup action_example".
+ */
\ No newline at end of file
diff --git ajax_example/ajax_example.module ajax_example/ajax_example.module
index e47ca16..564c63d 100644
--- ajax_example/ajax_example.module
+++ ajax_example/ajax_example.module
@@ -8,7 +8,8 @@
  */
 
 /**
- * @defgroup ajax_examples AJAX Examples
+ * @defgroup ajax_example Example: AJAX
+ * @ingroup examples
  * @{
  * These examples show basic AJAX concepts.
  *
@@ -17,15 +18,14 @@
  * @link http://drupal.org/node/752056 AJAX Forms handbook page @endlink.
  *
  * The several examples here demonstrate basic AJAX usage.
- * @}
-*/
+ */
 
 /**
+ * Implements hook_menu().
+ *
  * Set up calls to drupal_get_form() for all our example cases.
  *
- * Implements hook_menu().
- * See @link menu_example.module Menu Example @endlink for more details on
- * hook_menu().
+ * @see menu_example.module for more details on hook_menu().
  */
 function ajax_example_menu() {
   $items = array();
@@ -196,11 +196,6 @@ function ajax_example_intro() {
 }
 
 /**
- * @ingroup ajax_examples
- * @{
- */
-
-/**
  * Simple form whose ajax-enabled 'changethis' member causes a text change
  * in the description of the 'replace_textfield' member.
  * See @link http://drupal.org/node/262422 Form API Tutorial @endlink
@@ -534,4 +529,8 @@ function _ajax_example_get_second_dropdown_options($key = '') {
   else {
     return array();
   }
-}
\ No newline at end of file
+}
+
+/**
+ * @} End of "defgroup ajax_example".
+ */
\ No newline at end of file
diff --git ajax_example/ajax_example_graceful_degradation.inc ajax_example/ajax_example_graceful_degradation.inc
index 154bfe5..0c737f6 100644
--- ajax_example/ajax_example_graceful_degradation.inc
+++ ajax_example/ajax_example_graceful_degradation.inc
@@ -8,7 +8,8 @@
  */
 
 /**
- * @defgroup ajax_degradation_examples AJAX Degradation Examples
+ * @defgroup ajax_degradation_example Example: AJAX Graceful Degradation
+ * @ingroup examples
  * @{
  * These examples show AJAX with graceful degradation when Javascript is not
  * available.
@@ -17,9 +18,7 @@
  * depending on form input. In order to accomplish that, the formbuilder function
  * is in charge of almost all logic.
  *
- * @see ajax
- *
- * @}
+ * @see ajax_example
  */
 
 
@@ -42,8 +41,6 @@
  * ways to call this form, one normal ($no_js_use = FALSE) and one simulating
  * Javascript disabled ($no_js_use = TRUE).
  *
- * @ingroup ajax_examples
- * @ingroup ajax_degradation_examples
  */
 function ajax_example_dependent_dropdown_degrades($form, &$form_state, $no_js_use = FALSE) {
   // Get the list of options to populate the first dropdown.
@@ -168,9 +165,6 @@ function ajax_example_dependent_dropdown_degrades_first_callback($form, $form_st
  *
  * The third $no_js_use argument is strictly for demonstrating operation
  * without javascript, without making the user/developer turn off javascript.
- *
- * @ingroup ajax_examples
- * @ingroup ajax_degradation_examples
  */
 
 function ajax_example_dynamic_sections($form, &$form_state, $no_js_use = FALSE) {
@@ -339,10 +333,6 @@ function ajax_example_dynamic_sections_select_callback($form, $form_state) {
  *   Used for this demonstration only. If true means that the form should be
  *   built using a simulated no-javascript approach (ajax.js will not be
  *   loaded.)
- *
- * @ingroup ajax_examples
- * @ingroup ajax_degradation_examples
- *
  */
 function ajax_example_wizard($form, &$form_state, $no_js_use = FALSE) {
 
@@ -521,9 +511,6 @@ function ajax_example_wizard_submit($form, &$form_state) {
  * The $no_js_use argument is simply for demonstration: When set, it prevents
  * '#ajax' from being set, thus making the example behave as if javascript
  * were disabled in the browser.
- *
- * @ingroup ajax_examples
- * @ingroup ajax_degradation_examples
  */
 
 function ajax_example_add_more($form, &$form_state, $no_js_use = FALSE) {
@@ -638,4 +625,8 @@ function ajax_example_add_more_submit($form, &$form_state) {
   $output = t('These people are coming to the picnic: @names',
     array('@names' => implode(', ', $form_state['values']['names_fieldset']['name'])) );
   drupal_set_message($output);
-}
\ No newline at end of file
+}
+
+/**
+ * @} End of "defgroup ajax_degradation_example".
+ */
\ No newline at end of file
diff --git ajax_example/ajax_example_misc.inc ajax_example/ajax_example_misc.inc
index ad14cc0..7885bc7 100644
--- ajax_example/ajax_example_misc.inc
+++ ajax_example/ajax_example_misc.inc
@@ -17,6 +17,7 @@
  * When using the AJAX framework outside the context of a form, you have to
  * include ajax.js explicitly.
  * @return unknown_type
+ * @ingroup ajax_example
  */
 function ajax_example_render_link() {
   // drupal_add_library is invoked automatically when a form element has the
@@ -51,6 +52,7 @@ URL whether JS was enabled or not, letting it do different things based on that.
  *   If $type == 'ajax', returns an array of AJAX Commands.
  *   Otherwise, just returns the content, which will end up being a page.
  * @see ajax
+ * @ingroup ajax_example
  */
 function ajax_link_response($type = 'ajax') {
   if ($type == 'ajax') {
diff --git batch_example/batch_example.install batch_example/batch_example.install
index 6bd2436..d196f41 100644
--- batch_example/batch_example.install
+++ batch_example/batch_example.install
@@ -22,6 +22,7 @@
  * To make this update function run again and again, execute the query
  * "update system set schema_version = 0 where name = 'batch_example';"
  * and then run /update.php.
+ * @ingroup batch_example
  */
 function batch_example_update_7100(&$sandbox) {
   $ret = array();
diff --git batch_example/batch_example.module batch_example/batch_example.module
index 2dc41f2..269b68c 100644
--- batch_example/batch_example.module
+++ batch_example/batch_example.module
@@ -4,6 +4,13 @@
 /**
  * @file
  * Outlines how a module can use the Batch API.
+ */
+
+/**
+ * @defgroup batch_example Example: Batch API
+ * @ingroup examples
+ * @{
+ * Outlines how a module can use the Batch API.
  *
  * Batches allow heavy processing to be spread out over several page
  * requests, ensuring that the processing does not get interrupted
@@ -14,14 +21,12 @@
  * The @link batch_example.install .install file @endlink also shows how the
  * Batch API can be used to handle long-running hook_update_N() functions.
  *
- * @see batch
- */
-
-/**
  * Two harmless batches are defined:
  * - batch 1: Load the node with the lowest nid 100 times.
  * - batch 2: Load all nodes, 20 times and uses a progressive op, loading nodes
  *   by groups of 5.
+ * @see batch
+ */
  */
 
 /**
@@ -83,12 +88,6 @@ function batch_example_simple_form_submit($form, &$form_state) {
 
 
 /**
- * @defgroup batch_definitions Example batch definitions
- * @{
- * Definitions of the batches used in this module.
- */
-
-/**
  * Batch 1 definition: Load the node with the lowest nid 1000 times.
  * This creates an operations array defining what batch 1 should do, including
  * what it should do when it's finished. In this case, each operation is the
@@ -262,4 +261,8 @@ function _batch_example_update_http_requests() {
 
 function _batch_example_get_http_requests() {
   return !empty($_SESSION['http_request_count']) ? $_SESSION['http_request_count'] : 0;
-}
\ No newline at end of file
+}
+
+/**
+ * @} End of "defgroup batch_example".
+ */
\ No newline at end of file
diff --git block_example/block_example.install block_example/block_example.install
index 4ef44bc..b4b8ba8 100644
--- block_example/block_example.install
+++ block_example/block_example.install
@@ -8,6 +8,8 @@
 
 /**
  * Implements hook_uninstall().
+ *
+ * @ingroup block_example
  */
 function block_example_uninstall() {
   variable_del('block_example_string');
diff --git block_example/block_example.module block_example/block_example.module
index 7546b13..4d2be98 100755
--- block_example/block_example.module
+++ block_example/block_example.module
@@ -3,6 +3,15 @@
 
 /**
  * @file
+ * Module file for block_example.
+ */
+
+/**
+ * @defgroup block_example Example: Block
+ * @ingroup examples
+ * @{
+ * Demonstrates code creation of blocks.
+ *
  * This is an example outlining how a module can define blocks that can be
  * displayed on various pages of a site, or how to alter blocks provided by
  * other modules.
@@ -216,3 +225,7 @@ function block_example_block_view_alter(&$data, $block) {
     $data['subject'] = isset($data['subject']) ? drupal_strtoupper($data['subject']) : '';
   }
 }
+
+/**
+ * @} End of "defgroup block_example".
+ */
\ No newline at end of file
diff --git dbtng_example/dbtng_example.install dbtng_example/dbtng_example.install
index df7680d..ebef9cb 100644
--- dbtng_example/dbtng_example.install
+++ dbtng_example/dbtng_example.install
@@ -15,6 +15,7 @@
  * We will create a default entry in the database.
  *
  * @see hook_install()
+ * @ingroup dbtng_example
  */
 function dbtng_example_install() {
   // Outside of the .install file we would use drupal_write_record() to
@@ -51,8 +52,10 @@ function dbtng_example_install() {
  * for us.
  *
  * @see hook_uninstall()
+ * @ingroup dbtng_example
  */
 function dbtng_example_uninstall() {
+  // nothing.
 }
 
 
@@ -61,10 +64,10 @@ function dbtng_example_uninstall() {
  *
  * Define the database tables used by this module.
  * Remember that the easiest way to create the code for hook_schema is with
- * the schema module:
- * @link http://drupal.org/project/schema @endlink
+ * the @link http://drupal.org/project/schema schema module @endlink
  *
  * @see hook_schema()
+ * @ingroup dbtng_example
  */
 function dbtng_example_schema() {
 
diff --git dbtng_example/dbtng_example.module dbtng_example/dbtng_example.module
index 16667f9..9e32d71 100644
--- dbtng_example/dbtng_example.module
+++ dbtng_example/dbtng_example.module
@@ -15,13 +15,16 @@
  */
 
 /**
- * @defgroup database_examples Database Examples
+ * @defgroup dbtng_example Example: Database (DBTNG)
+ * @ingroup examples
  * @{
- * These examples show basic database examples, including DBTNG.
+ * Database examples, including DBTNG.
+ *
+ * 'DBTNG' means 'Database: The Next Generation.' Yes, Drupallers are nerds.
  *
  * General documentation is available at
- * @link database Database abstraction layer documentation @endlink and
- * at @link http://drupal.org/node/310069 @endlink.
+ * @link database.inc database abstraction layer documentation @endlink and
+ * at @link http://drupal.org/node/310069 Database API @endlink.
  *
  * The several examples here demonstrate basic database usage.
  *
@@ -64,7 +67,6 @@
  * @see db_update()
  * @see db_delete()
  * @see drupal_write_record()
- * @}
 */
 
 /**
@@ -91,7 +93,6 @@
  * @param $entry
  *   An array containing all the fields of the database record.
  *
- * @ingroup database_examples
  * @see db_insert()
  */
 function dbtng_example_entry_insert($entry) {
@@ -128,7 +129,6 @@ function dbtng_example_entry_insert($entry) {
  * @param $entry
  *   An array containing all the fields of the item to be updated.
  *
- * @ingroup database_examples
  * @see db_update()
  */
 function dbtng_example_entry_update($entry) {
@@ -159,7 +159,6 @@ function dbtng_example_entry_update($entry) {
  *   An array containing at least the person identifier 'pid' element of the
  *   entry to delete.
  *
- * @ingroup database_examples
  * @see db_delete()
  */
 function dbtng_example_entry_delete($entry) {
@@ -241,7 +240,6 @@ function dbtng_example_entry_delete($entry) {
  * @return
  *   An object containing the loaded entries if found.
  *
- * @ingroup database_examples
  * @see db_select()
  * @see db_query()
  * @see http://drupal.org/node/310072
@@ -282,7 +280,7 @@ function dbtng_example_entry_load($entry = array()) {
  *  e.name = 'John' AND e.age > 18
  *
  * @see db_select()
- * @seeW http://drupal.org/node/310075
+ * @see http://drupal.org/node/310075
  */
 function dbtng_example_advanced_list() {
   $output = '';
@@ -570,3 +568,7 @@ function dbtng_example_form_update_submit($form, $form_state){
   $count = dbtng_example_entry_update($entry);
   drupal_set_message(t("Updated entry @entry (@count row updated)", array('@count' => $count, '@entry' => print_r($entry, TRUE))));
 }
+
+/**
+ * @} End of "defgroup dbtng_example".
+ */
\ No newline at end of file
diff --git email_example/email_example.module email_example/email_example.module
index cde8958..1c346df 100644
--- email_example/email_example.module
+++ email_example/email_example.module
@@ -4,11 +4,18 @@
 /**
  * @file
  * Example of how to use Drupal's mail API.
+ */
+
+/**
+ * @defgroup email_example Example: Email
+ * @ingroup examples
+ * @{
+ * Example of how to use Drupal's mail API.
  *
- * This example module provides two different examples of the Drupal email API.
- *  - defines a simple contact form and shows how to use drupal_mail()
+ * This example module provides two different examples of the Drupal email API:
+ *  - Defines a simple contact form and shows how to use drupal_mail()
  *    to send an e-mail (defined in hook_mail()) when the form is submitted.
- *  - shows how modules can alter emails defined by other Drupal modules or
+ *  - Shows how modules can alter emails defined by other Drupal modules or
  *    Core using hook_mail_alter by attaching a custom signature before
  *    they are sent.
  */
@@ -200,3 +207,7 @@ function email_example_form_validate($form, &$form_state) {
 function email_example_form_submit($form, &$form_state) {
   email_example_mail_send($form_state['values']);
 }
+
+/**
+ * @} End of "defgroup email_example".
+ */
\ No newline at end of file
diff --git examples.index.php examples.index.php
deleted file mode 100644
index edfd003..0000000
--- examples.index.php
+++ /dev/null
@@ -1,32 +0,0 @@
-<?php
-// $Id: examples.index.php,v 1.6 2010/12/13 19:05:32 rfay Exp $
-
-/**
- * @file
- * Example modules
- *
- * - @link action_example.module Creating actions @endlink
- * - @link ajax_example.module Using AJAX forms @endlink
- * - @link batch_example.module Using the batch API @endlink
- * - @link block_example.module Defining blocks @endlink
- * - @link dbtng_example.module Database examples (DBTNG) @endlink
- * - @link email_example.module Sending e-mail @endlink
- * - @link field_example.module Defining fields in the field API @endlink
- * - @link file_example.module Demonstrates file handling @endlink
- * - @link filter_example.module Defining an input filter @endlink
- * - @link form_example.module Form API examples, including multistep forms @endlink
- * - @link image_exmaple.module Demonstrates image handling with styles and effects @endlink
- * - @link js_example.module Javascript examples @endlink
- * - @link menu_example.module Menu API examples @endlink
- * - @link nodeapi_example.module Node API demonstrations showing how a separate module can change the behavior of a node @endlink
- * - @link node_access_example.module Define custom node access fules using node access hooks @endlink
- * - @link node_example.module Creating custom node types, with fields @endlink
- * - @link page_example.module Creating a custom page @endlink
- * - @link queue_example.module Using the Queue API @endlink
- * - @link render_example.module Demonstrates the render API @endlink
- * - @link simpletest_example.module Writing tests for Drupal @endlink
- * - @link token_example.module Using tokens @endlink
- * - @link trigger_example.module Implementing triggers and actions @endlink
- * - @link vertical_tabs_example.module Using vertical tabs @endlink
- * - @link xmlrpc_example.module XML-RPC example @endlink
- */
\ No newline at end of file
diff --git examples.info examples.info
new file mode 100644
index 0000000..b39fb83
--- /dev/null
+++ examples.info
@@ -0,0 +1,5 @@
+; $Id: $
+name = Examples For Developers
+description = A variety of example code for you to learn from and hack upon.
+package = Example modules
+core = 7.x
diff --git examples.module examples.module
new file mode 100644
index 0000000..04b386a
--- /dev/null
+++ examples.module
@@ -0,0 +1,39 @@
+<?php
+// $Id: $
+
+/**
+ * @file
+ * This file serves as a stub file for the many Examples modules in the
+ * @link http://drupal.org/project/examples Examples for Developers Project @endlink
+ * which you can download and experiment with.
+ *
+ * One might say that examples.module is an example of documentation. However, note
+ * that the example submodules define many doxygen groups, which may or may not be
+ * a good strategy for other modules.
+ */
+
+/**
+ * @defgroup examples Examples
+ * @{
+ * Well-documented API examples for a broad range of Drupal 7 core functionality.
+ * 
+ * Developers can learn how to use a particular API quickly by experimenting with the
+ * examples, and adapt them for their own use.
+ 
+ * Download the Examples for Developers Project (and participate with submissions, bug
+ * reports, patches, and documentation) here: http://drupal.org/project/examples
+ */
+
+/**
+ * Implementation of hook_help().
+ */
+function examples_help($path, $arg) {
+  // re: http://drupal.org/node/767204 
+  // 5. We need a master group (Examples) that will be in a main examples.module.
+  // The examples.module should be mostly doxy comments that point to the other examples.
+  // It will also have a hook_help() explaining its purpose and how to access the other examples.
+}
+
+/**
+ * @} End of 'defgroup examples'.
+ */
\ No newline at end of file
diff --git field_example/field_example.info field_example/field_example.info
index 0c95088..3932a63 100644
--- field_example/field_example.info
+++ field_example/field_example.info
@@ -1,7 +1,7 @@
 ; $Id: field_example.info,v 1.5 2010/12/26 18:11:09 rfay Exp $
 
 name = Field Example
-description = A trivial implementation of a field to show the Field API
+description = An implementation of a field to show the Field API
 package = Example modules
 core = 7.x
 files[] = field_example.test
diff --git field_example/field_example.install field_example/field_example.install
index 74bfc53..b9aeb6e 100644
--- field_example/field_example.install
+++ field_example/field_example.install
@@ -9,14 +9,19 @@
 /**
  * Implements hook_field_schema().
  *
- * This defines the actual database schema of the field, using the format
+ * This defines the database schema of the field, using the format
  * used by the Schema API.
  *
- * The actual data we store here is just one 7-character element, even
+ * The data we will store here is just one 7-character element, even
  * though the widget presents the three portions separately.
  *
+ * All implementations of hook_field_schema() must be in the module's
+ * .install file.
+ *
+ * @see @link http://drupal.org/node/146939 Schema API Reference @endlink
+ * @see @link schemaapi Schema API @endlink
  * @see hook_field_schema()
- * @link schemaapi Schema API @endlink
+ * @ingroup field_example
  */
 function field_example_field_schema($field) {
   $columns = array(
diff --git field_example/field_example.module field_example/field_example.module
index bb183b1..2c833a9 100644
--- field_example/field_example.module
+++ field_example/field_example.module
@@ -3,29 +3,49 @@
 
 /**
  * @file
- * An example field using the Field API.
+ * An example field using the Field Types API.
+ */
+
+/**
+ * @defgroup field_example Example: Field Types API
+ * @ingroup examples
+ * @{
+ * Examples using Field Types API.
  *
  * This is updated from Barry Jaspan's presentation at Drupalcon Paris,
  * @link http://acquia.com/community/resources/acquia-tv/intro-field-api-module-developers Video Presentation @endlink
  *
  * Providing a field requires:
- * - Defining a field
+ * - Defining a field:
  *   - hook_field_info()
  *   - hook_field_schema()
  *   - hook_field_validate()
  *   - hook_field_is_empty()
  *
  * - Defining a formatter for the field (the portion that outputs the field for
- *   display)
+ *   display):
  *   - hook_field_formatter_info()
  *   - hook_field_formatter_view()
  *
- * - Defining a widget for the edit form
+ * - Defining a widget for the edit form:
  *   - hook_field_widget_info()
  *   - hook_field_widget_form()
  *
- * *
- * See @link field_types Field Types API @endlink
+ * Our module defines the field in field_example_field_info(),
+ * field_example_field_validate() and field_example_field_is_empty().
+ * field_example_field_schema() is implemented in field_example.install.
+ *
+ * Our module sets up a formatter in field_example_field_formatter_info() and
+ * field_example_field_formatter_view(). These are the API hooks that present
+ * formatted and themed output to the user.
+
+ * And finally, our module defines the widet in
+ * field_example_field_widget_info() and field_example_field_widget_form().
+ * The widget is the form element used to receive input from the user
+ * when the field is being populated.
+ *
+ * @see field_types
+ * @see field
  */
 
 /***************************************************************
@@ -39,6 +59,7 @@
  */
 function field_example_field_info() {
   return array(
+    // We name our field as the associative name of the array.
     'field_example_rgb' => array(
       'label' => t('Example Color RGB'),
       'description' => t('Demonstrates a field composed of an RGB color.'),
@@ -51,8 +72,14 @@ function field_example_field_info() {
 /**
  * Implements hook_field_validate().
  *
- * Verifies that the RGB field as combined is valid
- * (6 hex digits with a # at the beginning).
+ * This hook gives us a chance to validate content that's in our 
+ * field. We're really only interested in the $items parameter, since
+ * it holds arrays representing content in the field we've defined.
+ * We want to verify that the items only contain RGB hex values like
+ * this: #RRGGBB. If the item validates, we do nothing. If it doesn't
+ * validate, we add our own error notification to the $errors parameter.
+ *
+ * @see field_example_field_widget_error()
  */
 function field_example_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
   foreach ($items as $delta => $item) {
@@ -70,20 +97,23 @@ function field_example_field_validate($entity_type, $entity, $field, $instance,
 
 /**
  * Implements hook_field_is_empty().
+ *
+ * hook_field_is_emtpy() is where Drupal asks us if this field is empty.
+ * Return TRUE if it does not contain data, FALSE if it does. This lets
+ * the form API flag an error when required fields are empty.
  */
 function field_example_field_is_empty($item, $field) {
   return empty($item['rgb']);
 }
 
-/***********************************************************************
- *  Field Type API: Formatter
- *
- *  These are the api hooks that present formatted (themed) output to the
- *  user.
- **********************************************************************/
-
 /**
  * Implements hook_field_formatter_info().
+ *
+ * We need to tell Drupal that we have two different types of formatters
+ * for this field. One will change the text color, and the other will
+ * change the background color.
+ *
+ * @see field_example_field_formatter_view()
  */
 function field_example_field_formatter_info() {
   return array(
@@ -108,6 +138,8 @@ function field_example_field_formatter_info() {
  *   was entered and uses an inline style to set the text color to that value.
  * - field_example_color_background does the same but also changes the
  *   background color of div.region-content.
+ *
+ * @see field_example_field_formatter_info()
  */
 function field_example_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
   $element = array();
@@ -133,14 +165,6 @@ function field_example_field_formatter_view($entity_type, $entity, $field, $inst
   return $element;
 }
 
-
-/**************************************************************************
- * Field Type API: Widget
- *
- * The widget is the form element used to receive input from the user
- * when the field is being populated.
- **************************************************************************/
-
 /**
  * Implements hook_field_widget_info().
  *
@@ -149,6 +173,11 @@ function field_example_field_formatter_view($entity_type, $entity, $field, $inst
  * - A 3-textfield widget that gathers the red, green, and blue values
  *   separately.
  * - A farbtastic colorpicker widget that chooses the value graphically.
+ *
+ * These widget types will eventually show up in hook_field_widget_form,
+ * where we will have to flesh them out.
+ *
+ * @see field_example_field_widget_form()
  */
 function field_example_field_widget_info() {
   return array(
@@ -170,7 +199,11 @@ function field_example_field_widget_info() {
 /**
  * Implements hook_field_widget_form().
  *
- * Three different forms are provided, for the three widget types.
+ * hook_widget_form() is where Drupal tells us to create form elements for
+ * our field's widget.
+ *
+ * We provide one of three different forms, depending on the widget type of
+ * the Form API item provided.
  *
  * The 'field_example_colorpicker' and 'field_example_text' are essentially
  * the same, but field_example_colorpicker adds a javascript colorpicker
@@ -289,6 +322,13 @@ function field_example_3text_validate($element, &$form_state) {
 
 /**
  * Implements hook_field_widget_error().
+ *
+ * hook_field_widget_error() lets us figure out what to do with errors
+ * we might have generated in hook_field_validate(). Generally, we'll just
+ * call form_error().
+ *
+ * @see field_example_field_validate()
+ * @see form_error()
  */
 function field_example_field_widget_error($element, $error, $form, &$form_state) {
   switch ($error['error']) {
@@ -319,3 +359,7 @@ function field_example_menu() {
 function _field_example_page() {
   return t("The Field Example provides a field composed of an HTML RGB value, like #ff00ff. To use it, add the field to a content type.");
 }
+
+/**
+ * @} End of "defgroup field_example".
+ */
\ No newline at end of file
diff --git file_example/file_example.module file_example/file_example.module
index 80b6549..fc05a74 100644
--- file_example/file_example.module
+++ file_example/file_example.module
@@ -8,6 +8,11 @@
  */
 
 /**
+ * @defgroup file_example Example: Files
+ * @ingroup examples
+ * @{
+ * Examples demonstrating the Drupal File API (and Stream Wrappers).
+ *
  * The File Example module is a part of the Examples for Developers Project
  * and provides various Drupal File API Examples. You can download and
  * experiment with this code at the
@@ -16,8 +21,6 @@
  * See @link http://drupal.org/node/555118 Drupal File API @endlink for handbook
  * documentation on the File API and
  * @link file File summary on api.drupal.org @endlink for the function summary.
- *
- * @defgroup file_example Examples: File Examples
  */
 
 /**
@@ -65,7 +68,6 @@ function file_example_permission() {
  *
  * A simple form that allows creation of a file, managed or unmanaged. It
  * also allows reading/deleting a file and creation of a directory.
- * @ingroup file_example
  */
 function file_example_readwrite($form, &$form_state) {
   if (empty($_SESSION['file_example_default_file'])) {
@@ -193,7 +195,6 @@ function file_example_readwrite($form, &$form_state) {
  * - file_create_url(), which converts a URI in the form public://junk.txt or
  *   private://something/test.txt into a URL like
  *   http://example.com/sites/default/files/junk.txt.
- * @ingroup file_example
  */
 function file_example_managed_write_submit($form, &$form_state) {
   $data = $form_state['values']['write_contents'];
@@ -222,7 +223,6 @@ function file_example_managed_write_submit($form, &$form_state) {
  * - file_create_url(), which converts a URI in the form public://junk.txt or
  *   private://something/test.txt into a URL like
  *   http://example.com/sites/default/files/junk.txt.
- * @ingroup file_example
  */
 
 function file_example_unmanaged_write_submit($form, &$form_state) {
@@ -253,7 +253,6 @@ function file_example_unmanaged_write_submit($form, &$form_state) {
  *   private://something/test.txt into a URL like
  *   http://example.com/sites/default/files/junk.txt.
  * - drupal_tempnam() generates a temporary filename for use.
- * @ingroup file_example
  */
 
 function file_example_unmanaged_php_submit($form, &$form_state) {
@@ -307,7 +306,6 @@ function file_example_unmanaged_php_submit($form, &$form_state) {
  * file_get_contents("public://somefile.txt") just works. Although it's
  * not necessary, we use file_unmanaged_save_data() to save this file locally
  * and then find a local URL for it by using file_create_url().
- * @ingroup file_example
  */
 function file_example_read_submit($form, &$form_state) {
   $uri = $form_state['values']['fileops_file'];
@@ -392,7 +390,6 @@ function file_example_file_check_exists_submit($form, &$form_state) {
  * Submit handler for directory creation.
  * Here we create a directory and set proper permissions on it using
  * file_prepare_directory().
- * @ingroup file_example
  */
 function file_example_create_directory_submit($form, &$form_state) {
   $directory = $form_state['values']['directory_name'];
@@ -418,7 +415,6 @@ function file_example_create_directory_submit($form, &$form_state) {
  *
  * @see file_unmanaged_delete_recursive()
  *
- * @ingroup file_example
  */
 function file_example_delete_directory_submit($form, &$form_state) {
   $directory = $form_state['values']['directory_name'];
@@ -489,8 +485,6 @@ function file_example_get_managed_file($uri) {
  * is readable and writable as a location in the $_SESSION variable.
  *
  * @see FileExampleSessionStreamWrapper
- *
- * defgroup streamwrapper_example Stream Wrapper Example
  */
 function file_example_stream_wrappers() {
   $wrappers = array(
@@ -521,3 +515,6 @@ function file_example_session_contents() {
   return t('Contents of ') . check_plain($session_path) . ': ' . print_r($content, TRUE);
 }
 
+/**
+ * @} End of "defgroup file_example".
+ */
\ No newline at end of file
diff --git file_example/file_example_session_streams.inc file_example/file_example_session_streams.inc
index 799eaa7..20b89f1 100644
--- file_example/file_example_session_streams.inc
+++ file_example/file_example_session_streams.inc
@@ -10,6 +10,7 @@
 
 /**
  * Example stream wrapper class to handle session:// streams.
+ *
  * This is just an example, as it could have horrible results if much
  * information were placed in the $_SESSION variable. However, it does
  * demonstrate both the read and write implementation of a stream wrapper.
@@ -34,6 +35,8 @@
  * Note that because this implementation uses simple PHP arrays ($_SESSION)
  * it is limited to string values, so binary files will not work correctly.
  * Only text files can be used.
+ *
+ * @ingroup file_example
  */
 class FileExampleSessionStreamWrapper implements DrupalStreamWrapperInterface {
   /**
@@ -55,6 +58,7 @@ class FileExampleSessionStreamWrapper implements DrupalStreamWrapperInterface {
 
   /**
    * The content of the stream.
+   *
    * Since this trivial example just uses the $_SESSION variable, this is
    * simply a reference to the contents of the related part of
    * $_SESSION['file_example'].
@@ -96,6 +100,7 @@ class FileExampleSessionStreamWrapper implements DrupalStreamWrapperInterface {
 
   /**
    *  Implements getTarget().
+   *
    *  The "target" is the portion of the URI to the right of the scheme.
    *  So in session://example/test.txt, the target is 'example/test.txt'.
    */
@@ -145,6 +150,7 @@ class FileExampleSessionStreamWrapper implements DrupalStreamWrapperInterface {
 
   /**
    * Implements getDirectoryPath().
+   *
    * In this case there is no directory string, so return an empty string.
    */
   public function getDirectoryPath() {
@@ -153,6 +159,7 @@ class FileExampleSessionStreamWrapper implements DrupalStreamWrapperInterface {
 
   /**
    * Overrides getExternalUrl().
+   *
    * We have set up a helper function and menu entry to provide access to this
    * key via HTTP; normally it would be accessible some other way.
    */
@@ -260,6 +267,7 @@ class FileExampleSessionStreamWrapper implements DrupalStreamWrapperInterface {
   }
   /**
    * Support for flock().
+   *
    * The $_SESSION variable has no locking capability, so return TRUE.
    *
    * @param $operation
@@ -545,6 +553,7 @@ class FileExampleSessionStreamWrapper implements DrupalStreamWrapperInterface {
 
   /**
    * Support for stat().
+   *
    * This important function goes back to the Unix way of doing things.
    * In this example almost the entire stat array is irrelevant, but the
    * mode is very important. It tells PHP whether we have a file or a
diff --git filter_example/filter_example.module filter_example/filter_example.module
index 317747a..d714736 100755
--- filter_example/filter_example.module
+++ filter_example/filter_example.module
@@ -3,6 +3,15 @@
 
 /**
  * @file
+ * Module file for filter_example.
+ */
+
+/**
+ * @defgroup filter_example Example: Filter
+ * @ingroup examples
+ * @{
+ * Demonstrates the creation of filters.
+ 
  * This is an example outlining how a module can be used to define a filter
  * to be run on user-submitted content before it is output to the browser.
  *
@@ -10,6 +19,24 @@
  * in this module. One will substitute the string "foo" with an administratively-
  * defined replacement string. The other will find a custom XML tag, <time />, and
  * replace it by the current time.
+ *
+ * Foo filter
+ *
+ * Drupal has several content formats (they are not filters), and in our example
+ * the foo replacement can be configured for each one of them, allowing an html
+ * or php replacement, so the module includes a settings callback, with options
+ * to configure that replacements. Also, a Tips callback will help showing the
+ * current replacement for the content type being edited.
+ *
+ * Time filter.
+ *
+ * This filter is a little trickier to implement than the previous one.
+ * Since the input involves special HTML characters (< and >) we have to
+ * run the filter before HTML is escaped/stripped by other filters. But
+ * we want to use HTML in our result as well, and so if we run this filter
+ * first our replacement string could be escaped or stripped. The solution
+ * is to use the "prepare" operation to escape the special characters, and
+ * to later replace our escaped version in the "process" step.
  */
 
 /**
@@ -53,16 +80,6 @@ function filter_example_filter_info() {
   return $filters;
 }
 
-/*
- * Foo filter
- *
- * Drupal has several content formats (they are not filters), and in our example
- * the foo replacement can be configured for each one of them, allowing an html
- * or php replacement, so the module includes a settings callback, with options
- * to configure that replacements. Also, a Tips callback will help showing the
- * current replacement for the content type being edited.
- */
-
 /**
  * Simply returns a little bit of information about the example.
  */
@@ -129,19 +146,7 @@ function _filter_example_filter_foo_tips($filter, $format, $long = FALSE) {
   }
 }
 
-/*
- * Time filter.
- *
- * This filter is a little trickier to implement than the previous one.
- * Since the input involves special HTML characters (< and >) we have to
- * run the filter before HTML is escaped/stripped by other filters. But
- * we want to use HTML in our result as well, and so if we run this filter
- * first our replacement string could be escaped or stripped. The solution
- * is to use the "prepare" operation to escape the special characters, and
- * to later replace our escaped version in the "process" step.
- */
-
-/*
+/**
  * Time filter prepare callback
  *
  * We'll use [filter-example-time] as a replacement for the time tag.
@@ -153,7 +158,7 @@ function _filter_example_filter_time_prepare($text, $filter) {
   return preg_replace('!<time ?/>!', '[filter-example-time]', $text);
 }
 
-/*
+/**
  * Time filter process callback
  *
  * Now, in the "process" step, we'll search for our escaped time tags and
@@ -175,3 +180,7 @@ function _filter_example_filter_time_process($text, $filter) {
 function _filter_example_filter_time_tips($filter, $format, $long = FALSE) {
   return t('<em>&lt;time /&gt;</em> is replaced with the current time.');
 }
+
+/**
+ * @} End of "defgroup filter_example".
+ */
\ No newline at end of file
diff --git form_example/form_example.module form_example/form_example.module
index 05caadc..ab6d930 100644
--- form_example/form_example.module
+++ form_example/form_example.module
@@ -8,12 +8,15 @@
  */
 
 /**
+ * @defgroup form_example Example: Form API
+ * @ingroup examples
+ * @{
+ * Examples demonstrating the Drupal Form API.
+ *
  * The Form Example module is a part of the Examples for Developers Project
  * and provides various Drupal Form API Examples. You can download and
  * experiment with this code at the
  * @link http://drupal.org/project/examples Examples for Developers project page. @endlink
- *
- * @defgroup form_example Examples: Form Examples
  */
 
 /**
@@ -151,4 +154,8 @@ function form_example_menu() {
 function form_example_intro() {
   $markup = t('The form example module provides a tutorial, extensible multistep example, and a #states example');
   return array('#markup' => $markup);
-}
\ No newline at end of file
+}
+
+/**
+ * @} End of "defgroup form_example".
+ */
\ No newline at end of file
diff --git form_example/form_example_wizard.inc form_example/form_example_wizard.inc
index b970a94..03f9673 100644
--- form_example/form_example_wizard.inc
+++ form_example/form_example_wizard.inc
@@ -4,6 +4,10 @@
 /**
  * @file
  * Estensible wizard form example.
+ */
+
+/**
+ * Estensible wizard form example.
  *
  * This is an example of a multistep form using a wizard style. It will include
  * the 'Previous' and 'Next' buttons when required, and a 'Finish' button at the
@@ -26,6 +30,7 @@
  * - The most important customization sttep is to change the submit handler and
  *   do whatever you want with the collected information. In this case, the
  *   example just shows the collected values in the various steps.
+ * @ingroup form_example
  */
 
 /**
@@ -34,6 +39,7 @@
  * function to include the steps your wizard/multistep form requires.
  *
  * @return $array
+ * @ingroup form_example
  */
 function _form_example_steps() {
   return array(
@@ -65,6 +71,7 @@ function _form_example_steps() {
  * You are not required to change the next or previous handlers, but you must
  * change the form_example_wizard_sbumit handler to perform the operations you
  * need on the collected information.
+ * @ingroup form_example
  */
 function form_example_wizard($form, &$form_state) {
 
@@ -136,6 +143,7 @@ function form_example_wizard($form, &$form_state) {
  * - Forces form rebuild.
  *
  * You are not required to change this function.
+ * @ingroup form_example
  */
 function form_example_wizard_previous_submit($form, &$form_state) {
   $current_step = &$form_state['step'];
@@ -159,6 +167,7 @@ function form_example_wizard_previous_submit($form, &$form_state) {
  *
  * @param unknown_type $form
  * @param unknown_type $form_state
+ * @ingroup form_example
  */
 function form_example_wizard_next_submit($form, &$form_state) {
   $current_step = &$form_state['step'];
@@ -177,19 +186,23 @@ function form_example_wizard_next_submit($form, &$form_state) {
   }
 }
 
-// The previous code was a 'skeleton' of a multistep wizard form. You are not
-// required to change a line on the previous code (apart from defining your own
-// steps in the _form_example_steps() function.
-//
-// All the code included from here is the content of the wizard, the steps of
-// the form.
-
-// First, let's show the defined steps for the wizard example.
+/**
+ * The previous code was a 'skeleton' of a multistep wizard form. You are not
+ * required to change a line on the previous code (apart from defining your own
+ * steps in the _form_example_steps() function.
+ *
+ * All the code included from here is the content of the wizard, the steps of
+ * the form.
+ *
+ * First, let's show the defined steps for the wizard example.
+ * @ingroup form_example
+ */
 
 /**
  * Returns form elements for the 'personal info' page of the wizard. This is the
  * first step of the wizard, asking for two textfields: first name and last
  * name.
+ * @ingroup form_example
  */
 function form_example_wizard_personal_info($form, &$form_state) {
   $form = array();
@@ -210,6 +223,7 @@ function form_example_wizard_personal_info($form, &$form_state) {
  * Returns form elements for the 'location info' page of the wizard. This is the
  * second step of the wizard. This step asks for a textfield value: a City. This
  * step also includes a validation declared later.
+ * @ingroup form_example
  */
 function form_example_wizard_location_info($form, &$form_state) {
   $form = array();
@@ -228,6 +242,7 @@ function form_example_wizard_location_info($form, &$form_state) {
  * Custom validation form for the 'location info' page of the wizard. This is the
  * validation function for the second step of the wizard. The city cannot be empty
  * or be "San Francisco".
+ * @ingroup form_example
  */
 function form_example_wizard_location_info_validate($form, &$form_state) {
   if ($form_state['values']['city'] == 'San Francisco') {
@@ -238,6 +253,7 @@ function form_example_wizard_location_info_validate($form, &$form_state) {
 /**
  * Returns form elements for the 'other info' page of the wizard. This is the
  * thid and last step of the example wizard.
+ * @ingroup form_example
  */
 function form_example_wizard_other_info($form, &$form_state) {
   $form = array();
@@ -261,6 +277,7 @@ function form_example_wizard_other_info($form, &$form_state) {
  *
  * @param unknown_type $form
  * @param unknown_type $form_state
+ * @ingroup form_example
  */
 function form_example_wizard_submit($form, &$form_state) {
   $current_step = &$form_state['step'];
diff --git image_example/image_example.install image_example/image_example.install
index bfd2d20..55f3543 100644
--- image_example/image_example.install
+++ image_example/image_example.install
@@ -7,7 +7,9 @@
  */
 
 /**
- * Implements hook_install(),
+ * Implements hook_install().
+ *
+ * @ingroup image_example
  */
 function image_example_install() {
   // Set a variable containing the name of the style to use when the module
@@ -17,6 +19,8 @@ function image_example_install() {
 
 /**
  * Implements hook_uninstall().
+ *
+ * @ingroup image_example
  */
 function image_example_uninstall() {
   variable_del('image_example_style_name');
@@ -25,6 +29,8 @@ function image_example_uninstall() {
 
 /**
  * Implements hook_enable().
+ *
+ * @ingroup image_example
  */
 function image_example_enable() {
   // There is currently no way to manually flush an image style which causes
@@ -40,6 +46,8 @@ function image_example_enable() {
 
 /**
  * Implemements hook_disable().
+ *
+ * @ingroup image_example
  */
 function image_example_disable() {
   // Solves the same problem as image_example_enable().
diff --git image_example/image_example.module image_example/image_example.module
index b6d4763..255b26c 100644
--- image_example/image_example.module
+++ image_example/image_example.module
@@ -3,7 +3,14 @@
 
 /**
  * @file
- * Image example module demonstrates basic use of image API.
+ * Module file for image_example
+ */
+
+/**
+ * @defgroup image_example Example: Image
+ * @ingroup examples
+ * @{
+ * Demonstrates the basic use of image API.
  *
  * This module demonstrates the use of Drupal 7's new image styles and effects
  * including the following topics.
@@ -364,10 +371,11 @@ function image_example_theme() {
  * @param $variables
  *   An associative array containing:
  *   - data: The current configuration for this colorize effect.
- *
- * @ingroup themeable
  */
 function theme_image_example_colorize_summary($variables) {
   $data = $variables['data'];
   return t('as color #@color.', array('@color' => $data['color']));
 }
+/**
+ * @} End of "defgroup image_example".
+ */
\ No newline at end of file
diff --git image_example/image_example.pages.inc image_example/image_example.pages.inc
index f9e206b..4e5c5d3 100644
--- image_example/image_example.pages.inc
+++ image_example/image_example.pages.inc
@@ -4,7 +4,6 @@
 /**
  * @file
  * Page/form showing image styles in use.
- *
  */
 
 /**
@@ -17,6 +16,8 @@
  * this module are available via Drupal's image handling system.
  *
  * @see theme_image_style().
+ *
+ * @ingroup image_example
  */
 function image_example_style_form($form, &$form_state) {
   // If there is already an uploaded image display the image here.
@@ -62,6 +63,8 @@ function image_example_style_form($form, &$form_state) {
 
 /**
  * Verify that the user supplied an image with the form..
+ *
+ * @ingroup image_example
  */
 function image_example_style_form_validate($form, &$form_state) {
   if (!isset($form_state['values']['image_example_image_fid']) || !is_numeric($form_state['values']['image_example_image_fid'])) {
@@ -71,6 +74,8 @@ function image_example_style_form_validate($form, &$form_state) {
 
 /**
  * Form Builder; Display a form for uploading an image.
+ *
+ * @ingroup image_example
  */
 function image_example_style_form_submit($form, &$form_state) {
   // When using the #managed_file form element the file is automatically
@@ -125,6 +130,8 @@ function image_example_style_form_submit($form, &$form_state) {
 
 /**
  * Theme function displays an image rendered using the specified style.
+ *
+ * @ingroup image_example
  */
 function theme_image_example_image($variables) {
   $image = $variables['image'];
diff --git js_example/accordion.tpl.php js_example/accordion.tpl.php
index eb86d07..a916bc4 100644
--- js_example/accordion.tpl.php
+++ js_example/accordion.tpl.php
@@ -1,5 +1,11 @@
 <?php
 // $Id: accordion.tpl.php,v 1.2 2010/08/11 23:16:27 rfay Exp $
+
+/**
+ * @file
+ * Template file for js_example module.
+ */
+
 ?>
 <div class="demo">
 <h2><?php print $title; ?></h2>
diff --git js_example/js_example.module js_example/js_example.module
index a9f2f82..e590355 100755
--- js_example/js_example.module
+++ js_example/js_example.module
@@ -2,7 +2,19 @@
 // $Id: js_example.module,v 1.3 2010/08/11 23:16:27 rfay Exp $
 
 /**
- * Implementation hook_theme().
+ * @file
+ * Module file for js_example.
+ */
+
+/**
+ * @defgroup js_example Example: JavaScript
+ * @ingroup examples
+ * @{
+ * Examples using Drupal 7's built-in JavaScript.
+ */
+
+/**
+ * Implements hook_theme().
  */
 function js_example_theme() {
   return array(
@@ -31,7 +43,9 @@ function js_example_menu() {
   return $items;
 }
 
-
+/**
+ * js_example_weights implementation.
+ */
 function js_example_js_weights() {
   // add some css to show which line is output by which script
   drupal_add_css(drupal_get_path('module', 'js_example') .'/css/jsweights.css');
@@ -55,6 +69,9 @@ function js_example_js_weights() {
   return $output;
 }
 
+/**
+ * js_example_accordion implementation.
+ */
 function js_example_accordion() {
   $title = t('Click sections to expand or collapse:');
   $build['myelement'] = array(
diff --git menu_example/menu_example.module menu_example/menu_example.module
index 8b939c3..ea9fca5 100644
--- menu_example/menu_example.module
+++ menu_example/menu_example.module
@@ -3,8 +3,18 @@
 
 /**
  * @file
- * Demonstrates uses of the Menu APIs in Drupal, including hook_menu(),
- * hook_menu_alter(), and hook_menu_link_alter().
+ * Module file for menu_example.
+ */
+
+/**
+ * @defgroup menu_example Example: Menu
+ * @ingroup examples
+ * @{
+ * Demonstrates uses of the Menu APIs in Drupal.
+ *
+ * @see hook_menu()
+ * @see hook_menu_alter()
+ * @see hook_menu_link_alter()
  */
 
 /**
@@ -465,4 +475,8 @@ function menu_example_arg_optional_load($id) {
 function menu_example_arg_optional_to_arg($arg) {
   // If our argument is not provided, give a default of 99.
   return (empty($arg) || $arg == '%') ? 99 : $arg;
-}
\ No newline at end of file
+}
+
+/**
+ * @} End of "defgroup menu_example".
+ */
\ No newline at end of file
diff --git node_example/node_example.install node_example/node_example.install
index f7b9b67..8316038 100755
--- node_example/node_example.install
+++ node_example/node_example.install
@@ -18,6 +18,11 @@
 /**
  * Implements hook_install().
  *
+ * This hook is called when the user enables the module for the first time
+ * (or on subsequent enables after the module has been uninstalled). So it's
+ * a good place to define our new module type.
+ *
+ * We will:
  * - Add the body field.
  * - Configure the body field.
  * - Create color, quantity, and image fields.
@@ -28,16 +33,23 @@
  * @see field_update_instance()
  * @see field_create_field()
  * @see field_create_instance()
+ * @ingroup node_example
  */
 function node_example_install() {
-  // use get_t() to get the name of our localization function for translation
-  // during install, when t() is not available.
+  // During installation, the t() function is unavailable. So we use get_t()
+  // to store the name of the translation function.
   $t = get_t();
 
-  // Define the node type.
+  // We define the node type as an associative array.
   $node_example = array(
     'type' => 'node_example',
     'name' => $t('Example Node'),
+    // 'base' tells Drupal the base string for hook functions.
+    // This is often the module name, so if base is set to
+    // 'mymodule', Drupal would call mymodule_insert or similar
+    // for node hooks.
+    // In this case, we say 'node_content' so Drupal will handle
+    // our node as if we had designed it in the UI.
     'base' => 'node_content',
     'description' => $t('This is an example node type with a few fields.'),
     'body_label' => $t('Example Description')
@@ -84,10 +96,66 @@ function node_example_install() {
 }
 
 /**
- * Return a structured array defining the fields created by this content type.
+ * Implements hook_uninstall().
+ *
+ * This hook is called when the user not only has disabled the module,
+ * but also uninstalls it from the 'uninstall' tab in the module page.
+ *
+ * So it's a perfect time to remove our fields and instances and new
+ * node type from the database.
+ *
+ * @ingroup node_example
+ */
+function node_example_uninstall() {
+  // Gather all the example content that might have been created while this
+  // module was enabled.  Simple selects still use db_query().
+  // http://api.drupal.org/api/function/db_query/7
+  $sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
+  $result = db_query($sql, array(':type' => 'node_example'));
+  $nids = array();
+  foreach ($result as $row) {
+    $nids[] = $row->nid;
+  }
+
+  // Delete all the nodes at once
+  // http://api.drupal.org/api/function/node_delete_multiple/7
+  node_delete_multiple($nids);
+
+  // Loop over each of the fields defined by this module and delete
+  // all instances of the field, their data, and the field itself.
+  // http://api.drupal.org/api/function/field_delete_field/7
+  foreach (array_keys(_node_example_installed_fields()) as $field) {
+    field_delete_field($field);
+  }
+
+  // Loop over any remaining field instances attached to the node_example
+  // content type (such as the body field) and delete them individually.
+  // http://api.drupal.org/api/function/field_delete_field/7
+  $instances = field_info_instances('node', 'node_example');
+  foreach ($instances as $instance_name => $instance) {
+    field_delete_instance($instance);
+  }
+
+  // Delete our content type
+  // http://api.drupal.org/api/function/node_type_delete/7
+  node_type_delete('node_example');
+
+  // Purge all field infromation
+  // http://api.drupal.org/api/function/field_purge_batch/7
+  field_purge_batch(1000);
+}
+
+/**
+ * Return an array defining the fields for this content type.
  *
- * This is packaged in a function so it can be used in both
+ * This is factored into this function so it can be used in both
  * node_example_install() and node_example_uninstall().
+ *
+ * @return
+ *  An associative array specifying the fields we wish to add to our
+ *  new node type.
+ *
+ * @ingroup node_example
  */
 function _node_example_installed_fields() {
   $t = get_t();
@@ -114,7 +182,7 @@ function _node_example_installed_fields() {
 }
 
 /**
- * Return a structured array defining the instances for this content type.
+ * Return an array defining the instances for this content type.
  *
  * The instance lets Drupal know which widget to use to allow the user to enter
  * data and how to react in different view modes.  We are going to display a
@@ -122,8 +190,14 @@ function _node_example_installed_fields() {
  * cardinality of three allowing our content type to give the user three color
  * fields.
  *
- * This is provided as a function so that it can be used in both hook_install()
- * and hook_uninstall().
+ * This is factored into this function so it can be used in both
+ * node_example_install() and node_example_uninstall().
+ *
+ * @return
+ *  An associative array specifying the instances we wish to add to our new
+ *  node type.
+ *
+ * @ingroup node_example
  */
 function _node_example_installed_instances() {
   $t = get_t();
@@ -172,47 +246,3 @@ function _node_example_installed_instances() {
     ),
   );
 }
-
-
-/**
- * Implements hook_uninstall().
- *
- */
-function node_example_uninstall() {
-  // Gather all the example content that might have been created while this
-  // module was enabled.  Simple selects still use db_query().
-  // http://api.drupal.org/api/function/db_query/7
-  $sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
-  $result = db_query($sql, array(':type' => 'node_example'));
-  $nids = array();
-  foreach ($result as $row) {
-    $nids[] = $row->nid;
-  }
-
-  // Delete all the nodes at once
-  // http://api.drupal.org/api/function/node_delete_multiple/7
-  node_delete_multiple($nids);
-
-  // Loop over each of the fields defined by this module and delete
-  // all instances of the field, their data, and the field itself.
-  // http://api.drupal.org/api/function/field_delete_field/7
-  foreach (array_keys(_node_example_installed_fields()) as $field) {
-    field_delete_field($field);
-  }
-
-  // Loop over any remaining field instances attached to the node_example
-  // content type (such as the body field) and delete them individually.
-  // http://api.drupal.org/api/function/field_delete_field/7
-  $instances = field_info_instances('node', 'node_example');
-  foreach ($instances as $instance_name => $instance) {
-    field_delete_instance($instance);
-  }
-
-  // Delete our content type
-  // http://api.drupal.org/api/function/node_type_delete/7
-  node_type_delete('node_example');
-
-  // Purge all field infromation
-  // http://api.drupal.org/api/function/field_purge_batch/7
-  field_purge_batch(1000);
-}
diff --git node_example/node_example.module node_example/node_example.module
index e6563bb..bdbda07 100755
--- node_example/node_example.module
+++ node_example/node_example.module
@@ -3,35 +3,48 @@
 
 /**
  * @file
- * This is an example outlining how a module can be used to define a new
- * node type.  In Drupal 7 we move most of what was once needed in this file
- * to the node_example.install file so that it can be managed efficiently.
- *
- * Our example node type will allow users to specify multiple "colors",
- * a "quantity" and an "image" for their nodes; some kind of rudimentary
- * inventory-tracking system, perhaps?
- *
- * In previous versions of Drupal, "teaser" and "page" were node view modes.  In
- * Drupal 7 we can define custom view modes to let the node know how it should
- * return it's data.  This module declares a custom view mode called
- * "example_node_list".
- *
- * We no longer need an extra database table to store this content type's
- * information.
- *
- * Most node types that provide fields do not require any custom code for
- * the fields, as the fields system provides storage and access.
- *
- * See @link http://drupal.org/node/707832 Field API Tutorial @endlink
+ * Module file for Node Example module.
  *
- * See @link http://drupal.org/node/443536 Field API Handbook Page @endlink
+ * Part of the Examples for Developers project.
+ */
+ 
+/**
+ * @defgroup node_example Example: Node
+ * @ingroup examples
+ * @{
+ * Example defining a node type in code.
  *
- * See @link field Field API documentation @endlink
+ * This is an example outlining how a module can be used to define a new
+ * node type. Our example node type will allow users to specify multiple
+ * "colors", a "quantity" and an "image" for their nodes; some kind of
+ * rudimentary inventory-tracking system, perhaps?
  *
- * See @link field_example.install field_example.install @endlink
+ * The basic pattern for defining a node type is to tell Drupal about the
+ * node's field types, and view modes. Drupal will then take over and manage
+ * the storage for this node type. This differs from Drupal 6, where we
+ * would have to handle all the database storage ourselves in the module.
  *
  * Remember that most node types do not require any custom code, as one
- * simply creates them using the fields UI.
+ * simply creates them using the Drupal user interface. Creating a node like
+ * this in code is a special case.
+ *
+ * Drupal 7 has us defining most of our node structure in arrays,
+ * and passing those to node_type_save(). We use hook_install() as
+ * a convenient place to define these types, and hook_uninstall()
+ * as a convenient place to not only uninstall the data contained
+ * in these nodes, but also remove the node types from Drupal's
+ * knowledge. This means that most of the code to define a new node type
+ * would be in the module's .install file.
+ * 
+ * In previous versions of Drupal, "teaser" and "page" were node view modes.
+ * In Drupal 7 we can define custom view modes to let the node know how it
+ * should return it's data.  This module declares a custom view mode called
+ * "example_node_list".
+ *
+ * @see @link http://drupal.org/node/707832 Field API Tutorial @endlink
+ * @see @link http://drupal.org/node/443536 Field API Handbook Page @endlink
+ * @see @link field Field API documentation @endlink
+ * @see field_example.module
  */
 
 
@@ -56,6 +69,8 @@ function node_example_menu() {
  * @return
  *   a build array
  *
+ * @see node_load
+ * @see node_view
  */
 function node_example_page() {
   $build = array();
@@ -69,8 +84,6 @@ function node_example_page() {
 
   // Loop through each of our node_example nodes and instruct node_view
   // to use our custom "example_node_list" view.
-  // http://api.drupal.org/api/function/node_load/7
-  // http://api.drupal.org/api/function/node_view/7
   foreach ($result as $row) {
     $node = node_load($row->nid);
     $build['node_list'][]= node_view($node, 'example_node_list');
@@ -166,3 +179,7 @@ function theme_example_node_color($variables) {
   $output = '<span style="background-color: #ccc; padding: 1em; margin-bottom: 1em; float: left; color: ' . $variables['color'] . '">' . $variables['color'] . '</span>';
   return $output;
 }
+
+/**
+ * @} End of "defgroup node_example".
+ */
\ No newline at end of file
diff --git page_example/page_example.module page_example/page_example.module
index 2577a59..bab062c 100755
--- page_example/page_example.module
+++ page_example/page_example.module
@@ -3,6 +3,13 @@
 
 /**
  * @file
+ * Module file for page_example_module.
+ */
+
+/**
+ * @defgroup page_example Example: Page
+ * @ingroup examples
+ * @{
  * This is an example outlining how a module can be used to display a
  * custom page at a given URL.
  */
@@ -117,9 +124,14 @@ function page_example_menu() {
   return $items;
 }
 
+/**
+ * page_example_description function.
+ * 
+ */
 function page_example_description() {
   return array('#markup' => t('The page_example provides two pages, "simple" and "arguments". The <a href="@simple_link">simple page</a> just returns a renderable array for display. The <a href="@arguments_link">arguments page</a> takes two arguments and displays them, as in @arguments_link', array('@simple_link' => url('examples/page_example/simple', array('absolute' => TRUE)), '@arguments_link' => url('examples/page_example/arguments/23/56', array('absolute' => TRUE)))));
 }
+
 /**
  * A simple page callback.
  *
@@ -166,3 +178,6 @@ function page_example_arguments($first, $second) {
   );
   return $render_array;
 }
+/**
+ * @} End of "defgroup page_example".
+ */
\ No newline at end of file
diff --git queue_example/queue_example.module queue_example/queue_example.module
index 307d46d..c2cbe05 100644
--- queue_example/queue_example.module
+++ queue_example/queue_example.module
@@ -4,6 +4,13 @@
 /**
  * @file
  * Examples demonstrating the Drupal Queue API.
+ */
+
+/**
+ * @defgroup queue_example Example: Queue
+ * @ingroup examples
+ * @{
+ * Demonstrating the Queue API
  *
  * The Queue API provides a traditional FIFO (first-in-first-out) queue,
  * but also provides the concepts of:
@@ -273,4 +280,7 @@ function queue_example_theme() {
       'variables' => array('items' => NULL),
     ),
   );
-}
\ No newline at end of file
+}
+/**
+ * @} End of "defgroup queue_example".
+ */
\ No newline at end of file
diff --git render_example/render_example.module render_example/render_example.module
index b9f1b73..0dd8c73 100644
--- render_example/render_example.module
+++ render_example/render_example.module
@@ -1,8 +1,17 @@
 <?php
 // $Id: render_example.module,v 1.1 2010/09/26 12:04:28 rfay Exp $
+
 /**
- * @file render_example.module
+ * @file
+ * Demonstrates render arrays.
+ */
+
+/**
+ * @defgroup render_example Example: Render
+ * @ingroup examples
+ * @{
  * Demonstrate how render arrays are arranged and how they can be altered.
+ *
  * This alters blocks and the page to show the actual render array
  * that is being used to create each item.
  *
@@ -47,6 +56,7 @@ function render_example_info() {
 
 /**
  * Provides a number of render arrays and show what they do.
+ *
  * Each array is keyed by a description; it's returned for rendering at page
  * render time. It's easy to add new examples to this.
  *
@@ -199,7 +209,9 @@ function render_example_add_prefix($markup, $element) {
 }
 
 /**
- * A #theme function has the responsibility of consolidating/rendering the
+ * A #theme function.
+ *
+ * This #theme function has the responsibility of consolidating/rendering the
  * children's markup and returning it, where it will be placed in the
  * element's #children property.
  */
@@ -397,6 +409,7 @@ function render_example_page_alter(&$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.
  *
@@ -496,4 +509,7 @@ function render_example_change_to_ol($element) {
 function render_example_add_hr($markup, $element) {
   $output = $markup . '<hr />';
   return $output;
-}
\ No newline at end of file
+}
+/**
+ * @} End of "defgroup render_example".
+ */
\ No newline at end of file
diff --git simpletest_example/simpletest_example.module simpletest_example/simpletest_example.module
index c3259e5..b639793 100644
--- simpletest_example/simpletest_example.module
+++ simpletest_example/simpletest_example.module
@@ -3,6 +3,13 @@
 
 /**
  * @file
+ * Module file for simpletest_example
+ */
+
+/**
+ * @defgroup simpletest_example Example: Simpletest
+ * @ingroup examples
+ * @{
  * An example of simpletest tests to accompany the tutorial at
  * http://drupal.org/node/890654.
  *
@@ -10,7 +17,6 @@
  *
  */
 
-
 /**
  * Implements hook_node_info().
  */
@@ -111,3 +117,6 @@ function _simpletest_example_explanation() {
   return $explanation;
 }
 
+/**
+ * @} End of "defgroup simpletest_example".
+ */
\ No newline at end of file
diff --git token_example/token_example.module token_example/token_example.module
index 02ca66a..e1a3e09 100644
--- token_example/token_example.module
+++ token_example/token_example.module
@@ -2,6 +2,29 @@
 // $Id: token_example.module,v 1.8 2010/07/19 02:10:57 davereid Exp $
 
 /**
+ * @file
+ * The Token API module.
+ *
+ * The Token module provides an API for providing tokens to other modules.
+ * Tokens are small bits of text that can be placed into larger documents
+ * via simple placeholders, like %site-name or [user].
+ */
+
+/**
+ * @defgroup token_example Example: Token API
+ * @ingroup examples
+ * @{
+ * Examples using the Token API.
+ *
+ * The Token module provides an API for providing tokens to other modules.
+ * Tokens are small bits of text that can be placed into larger documents
+ * via simple placeholders, like %site-name or [user].
+ *
+ * This example is part of the Examples for Developers Project which you can download
+ * and experiment with here: http://drupal.org/project/examples
+ */
+
+/**
  * Implements hook_menu().
  */
 function token_example_menu() {
@@ -194,3 +217,7 @@ function _token_example_get_file() {
   $files = array_map('check_plain', $files);
   return $files;
 }
+
+/**
+ * @} End of "defgroup token_example".
+ */
\ No newline at end of file
diff --git token_example/token_example.tokens.inc token_example/token_example.tokens.inc
index 2696cf7..968bb1d 100644
--- token_example/token_example.tokens.inc
+++ token_example/token_example.tokens.inc
@@ -8,6 +8,8 @@
 
 /**
  * Implements hook_token_info().
+ *
+ * @ingroup token_example
  */
 function token_example_token_info() {
   // Add two different token types. The first is the generic text format. The
@@ -55,6 +57,8 @@ function token_example_token_info() {
 
 /**
  * Implements hook_tokens().
+ *
+ * @ingroup token_example
  */
 function token_example_tokens($type, $tokens, array $data = array(), array $options = array()) {
   $replacements = array();
diff --git trigger_example/trigger_example.module trigger_example/trigger_example.module
index 223d991..6043649 100644
--- trigger_example/trigger_example.module
+++ trigger_example/trigger_example.module
@@ -4,6 +4,14 @@
 /**
  * @file
  * Trigger definition example module.
+ */
+
+/**
+ * @defgroup trigger_example Example: Trigger
+ * @ingroup examples
+ * @{
+ *
+ * Trigger definition example module.
  *
  * Triggers and actions are a pair of special-purpose functions allowing some
  * Drupal programming without using PHP. Using the
diff --git vertical_tabs_example/vertical_tabs_example.js vertical_tabs_example/vertical_tabs_example.js
index bca0b71..31b00a6 100644
--- vertical_tabs_example/vertical_tabs_example.js
+++ vertical_tabs_example/vertical_tabs_example.js
@@ -3,7 +3,9 @@
 (function ($) {
 
 /**
- * Custom summary for the module vertical tab.
+ * Custom summary for the module vertical tab. (JavaScript)
+ *
+ * @ingroup veritcal_tabs_example
  */
 Drupal.behaviors.vertical_tabs_exampleFieldsetSummaries = {
   attach: function (context) {
diff --git vertical_tabs_example/vertical_tabs_example.module vertical_tabs_example/vertical_tabs_example.module
index a47219c..7b90a80 100644
--- vertical_tabs_example/vertical_tabs_example.module
+++ vertical_tabs_example/vertical_tabs_example.module
@@ -3,9 +3,19 @@
 
 /**
  * @file
- * Shows how to use the vertical tabs functionality provided by Drupal 7. This
- * example does not cover how to save / load custom setting, and only deals with
- * elements visibility.
+ * Module file for vertical_tabs_example module.
+ */
+
+/**
+ * @defgroup vertical_tabs_example Example: Vertical Tabs
+ * @ingroup examples
+ * @{
+ * Demonstrates the vertical tabs functionality provided by Drupal 7.
+ *
+ * This example does not cover how to save / load custom setting, and only
+ * deals with elements visibility.
+ *
+ * @see vertical_tabs_example.js
  */
 
 /**
@@ -88,3 +98,7 @@ function vertical_tabs_example_form_alter(&$form, $form_state, $form_id) {
 function _vertical_tabs_example_explanation() {
   return t("The Vertical Tabs Example shows how a custom module can best support vertical tabs. To see the effects of this module, look at the <a href='!node_add'>node/add</a> form", array('!node_add' => url('node/add')));
 }
+
+/**
+ * @} End of "defgroup vertical_tabs_example".
+ */
\ No newline at end of file
diff --git xmlrpc_example/xmlrpc_example.module xmlrpc_example/xmlrpc_example.module
index 044f7e3..2a317fe 100644
--- xmlrpc_example/xmlrpc_example.module
+++ xmlrpc_example/xmlrpc_example.module
@@ -3,6 +3,15 @@
 
 /**
  * @file
+ * Module file for xmlrpc_example module.
+ */
+
+/**
+ * @defgroup xmlrpc_example Example: XML-RPC
+ * @ingroup examples
+ * @{
+ * Demonstration of XML-RPC in Drupal 7.
+ *
  * This is an example of how to implement and XML-RPC server by registering
  * callbacks to specific methods and how to make xmlrpc calls using the built-in
  * xmlrpc() factory provided by Drupal.
@@ -646,3 +655,7 @@ function xmlrpc_example_alter_form() {
 }
 
 // The alteration part of the module ends here.
+
+/**
+ * @} End of "defgroup xmlrpc_example".
+ */
\ No newline at end of file
