Index: includes/install.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/install.inc,v
retrieving revision 1.16
diff -u -F^f -r1.16 install.inc
--- includes/install.inc	23 Aug 2006 08:25:44 -0000	1.16
+++ includes/install.inc	24 Aug 2006 17:55:14 -0000
@@ -349,6 +349,21 @@ function drupal_install_module($module) 
 }
 
 /**
+ * Calls the uninstall function and updates the system table for a given module.
+ *
+ * @param module
+ *   The module to install.
+ */
+function drupal_uninstall_module($module, $confirm = FALSE) {
+  module_load_install($module);
+  $retval = module_invoke($module, 'uninstall', $confirm);
+  if ($confirm || !$retval) {
+    drupal_set_installed_schema_version($module, SCHEMA_UNINSTALLED);
+  }
+  return $retval;
+}
+
+/**
  * Verify the state of the specified file.
  *
  * @param $file
Index: includes/module.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/module.inc,v
retrieving revision 1.82
diff -u -F^f -r1.82 module.inc
--- includes/module.inc	20 Aug 2006 05:57:40 -0000	1.82
+++ includes/module.inc	24 Aug 2006 17:55:15 -0000
@@ -103,9 +103,8 @@ function module_rebuild_cache() {
   ksort($files);
 
   foreach ($files as $filename => $file) {
-    drupal_get_filename('module', $file->name, $file->filename);
-    drupal_load('module', $file->name);
-
+    $file->metadata = module_get_meta_info($file->name, dirname($file->filename));
+    $files[$filename]->metadata = $file->metadata;
     // log the critical hooks implemented by this module
     $bootstrap = 0;
     foreach (bootstrap_hooks() as $hook) {
@@ -117,17 +116,93 @@ function module_rebuild_cache() {
 
     // Update the contents of the system table:
     if (isset($file->status) || (isset($file->old_filename) && $file->old_filename != $file->filename)) {
-      db_query("UPDATE {system} SET description = '%s', name = '%s', filename = '%s', bootstrap = %d WHERE filename = '%s'", $file->description, $file->name, $file->filename, $bootstrap, $file->old_filename);
+      db_query("UPDATE {system} SET description = '%s', name = '%s', filename = '%s', bootstrap = %d WHERE filename = '%s'", $file->metadata['description'], $file->name, $file->filename, $bootstrap, $file->old_filename);
     }
     else {
       // This is a new module.
-      db_query("INSERT INTO {system} (name, description, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)", $file->name, $file->description, 'module', $file->filename, $file->status, $file->throttle, $bootstrap);
+      db_query("INSERT INTO {system} (name, description, type, filename, status, throttle, bootstrap) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)", $file->name, $file->metadata['description'], 'module', $file->filename, $file->status, $file->throttle, $bootstrap);
     }
   }
 
   return $files;
 }
+/**
+ * Parse drupal meta file format.
+ *
+ * @param $filename 
+ *   The path to the filename
+ * @return 
+ *   The meta data array
+ */
+function module_parse_meta_file($filename) {
+  $handle = fopen($filename, "r");
+  $meta = fread($handle, filesize($filename));
+  fclose($handle);
+  $metadata = array();    
+  $pattern = '@^\s*((?:[^:/]|/(?!/))+?)\s*:\s*(?:("(?:[^"]|(?<=\\\\)")*")|(\'(?:[^\']|(?<=\\\\)\')*\')|([^\n]*?))\s*($|//)@ms';    
+  if (preg_match_all($pattern, $meta, $matches, PREG_SET_ORDER)) {
+    foreach ($matches as $match) {
+      list(, $key, $value1, $value2, $value3) = $match;
+      $value = stripslashes(trim($value1, '"')) . stripslashes(trim($value2, "'")) . $value3;
+      $metadata[$key] = $value;
+    }
+  } 
+  return $metadata;
+}
+  
+/**
+ * Load the metadata associated with a module.
+ *
+ * @param $module
+ *   The name of the module
+ * @param $path
+ *   The path the module lives in, not including the module name.
+ */
+function module_get_meta_info($module, $path) {
+  $filename = $path .'/'. $module .'.meta';
+  $metadata = array();
+  
+  if (file_exists($filename)) {
+    $metadata = module_parse_meta_file($filename);
+  }
 
+  // Fill in a bunch of safe defaults.
+  if (!$metadata['package']) {
+    $metadata['package'] = t('Uncategorized');
+  }
+  if (!$metadata['version']) {
+    $metadata['version'] = t('unknown');
+  }
+  if ($metadata['version'] == 'SYSTEM') {
+    $metadata['version'] = VERSION;
+  }
+  if (!$metadata['drupal']) {
+    $metadata['drupal'] = t('undefined');
+  }
+  if (!$metadata['name']) {
+    $metadata['name'] = $module;
+  }
+  if (!$metadata['links']) {
+    $metadata['links'] = array();
+  }
+  else {
+    $metadata['links'] = explode(",", $metadata['links']);
+    $links = array();
+    foreach ($metadata['links'] as $link) {
+      list($link, $destination) = explode('=', $link, 2);
+      $links[] = array('title' => trim($link), 'href' => trim($destination));
+    }
+    $metadata['links'] = $links;
+  }
+  if ($metadata['dependencies']) {
+    $metadata['dependencies'] = explode(',', $metadata['dependencies']);
+  }
+  else {
+    $metadata['dependencies'] = array();
+  }
+  return $metadata;
+}
+ 
 /**
  * Determine whether a given module exists.
  *
Index: modules/aggregator/aggregator.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.install,v
retrieving revision 1.6
diff -u -F^f -r1.6 aggregator.install
--- modules/aggregator/aggregator.install	24 Aug 2006 06:27:41 -0000	1.6
+++ modules/aggregator/aggregator.install	24 Aug 2006 17:55:15 -0000
@@ -1,6 +1,10 @@
 <?php
 // $Id: aggregator.install,v 1.6 2006/08/24 06:27:41 drumm Exp $
 
+/**
+ * Implementation of hook_install.
+ * Create module tables.
+ */
 function aggregator_install() {
   switch ($GLOBALS['db_type']) {
     case 'mysql':
@@ -112,3 +116,25 @@ function aggregator_install() {
       break;
   }
 }
+
+/**
+ * Implementation of hook_uninstall.
+ * Delete all module variables and drop tables.
+ * @param $confirm user confirmation before uninstall.
+ * @return Confirmation message on before confirmation.
+ */
+function aggregator_uninstall($confirm = FALSE) {
+  if (!$confirm) {
+    return t('All aggregator feeds will be deleted.');
+  }
+  db_query("DROP TABLE {aggregator_category}");
+  db_query("DROP TABLE {aggregator_category_feed}");
+  db_query("DROP TABLE {aggregator_category_item}");
+  db_query("DROP TABLE {aggregator_feed}");
+  db_query("DROP TABLE {aggregator_item}");
+  variable_del('aggregator_allowed_html_tags');
+  variable_del('aggregator_summary_items');
+  variable_del('aggregator_clear');
+  variable_del('aggregator_category_selector');
+}
+
Index: modules/aggregator/aggregator.meta
===================================================================
RCS file: modules/aggregator/aggregator.meta
diff -N modules/aggregator/aggregator.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/aggregator/aggregator.meta	24 Aug 2006 17:55:15 -0000
@@ -0,0 +1,7 @@
+name: Aggregator
+description: Aggregates syndicated content (RSS, RDF, and Atom feeds).
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
+links: administer=admin/content/aggregator, news aggregator=aggregator
+
Index: modules/aggregator/aggregator.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/aggregator/aggregator.module,v
retrieving revision 1.302
diff -u -F^f -r1.302 aggregator.module
--- modules/aggregator/aggregator.module	23 Aug 2006 18:38:41 -0000	1.302
+++ modules/aggregator/aggregator.module	24 Aug 2006 17:55:16 -0000
@@ -27,8 +27,6 @@ function aggregator_help($section) {
 ', array('@admin-aggregator' => url('admin/content/aggregator'), '@admin-aggregator-add-feed' => url('admin/content/aggregator/add/feed'), '@admin-aggregator-add-category' => url('admin/content/aggregator/add/category'), '@admin-settings-aggregator' => url('admin/settings/aggregator'), '@admin-access' => url('admin/user/access'), '@aggregator' => url('aggregator')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@aggregator">Aggregator page</a>.', array('@aggregator' => 'http://drupal.org/handbook/modules/aggregator/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Aggregates syndicated content (RSS, RDF, and Atom feeds).');
     case 'admin/content/aggregator':
       return t('<p>Thousands of sites (particularly news sites and weblogs) publish their latest headlines and/or stories in a machine-readable format so that other sites can easily link to them. This content is usually in the form of an <a href="http://blogs.law.harvard.edu/tech/rss">RSS</a> feed (which is an XML-based syndication standard). To display the feed or category in a block you must decide how many items to show by editing the feed or block and turning on the <a href="@block">feed\'s block</a>.</p>', array('@block' => url('admin/build/block')));
     case 'admin/content/aggregator/add/feed':
Index: modules/block/block.meta
===================================================================
RCS file: modules/block/block.meta
diff -N modules/block/block.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/block/block.meta	24 Aug 2006 17:55:16 -0000
@@ -0,0 +1,6 @@
+name: Block
+description: Controls the boxes that are displayed around the main content.
+package: Required modules
+version: SYSTEM
+drupal: 4.8
+links: administer=admin/build/block
Index: modules/block/block.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.module,v
retrieving revision 1.222
diff -u -F^f -r1.222 block.module
--- modules/block/block.module	23 Aug 2006 04:44:36 -0000	1.222
+++ modules/block/block.module	24 Aug 2006 17:55:17 -0000
@@ -38,8 +38,6 @@ function block_help($section) {
 ', array('@admin-block' => url('admin/build/block'), '@admin-block-add' => url('admin/build/block/add')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@block">Block page</a>.', array('@block' => 'http://drupal.org/handbook/modules/block/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Controls the boxes that are displayed around the main content.');
     case 'admin/build/block':
       return t("
 <p>Blocks are boxes of content that may be rendered into certain regions of your web pages, for example, into sidebars. They are usually generated automatically by modules, but administrators can create blocks manually.</p>
Index: modules/blog/blog.meta
===================================================================
RCS file: modules/blog/blog.meta
diff -N modules/blog/blog.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/blog/blog.meta	24 Aug 2006 17:55:17 -0000
@@ -0,0 +1,6 @@
+name: Blog
+description: Enables keeping an easily and regularly updated web page or a blog.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
+links: view blogs=blogs
Index: modules/blog/blog.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/blog/blog.module,v
retrieving revision 1.262
diff -u -F^f -r1.262 blog.module
--- modules/blog/blog.module	23 Aug 2006 07:32:18 -0000	1.262
+++ modules/blog/blog.module	24 Aug 2006 17:55:17 -0000
@@ -76,8 +76,6 @@ function blog_help($section) {
 ', array('@user' => url('user'), '@node-add-blog' => url('node/add/blog'), '@admin-node-configure-types-blog' => url('admin/content/types/blog'), '@admin-settings-blogapi' => url('admin/settings/blogapi'), '@admin-block' => url('admin/build/block')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@blog">Blog page</a>.', array('@blog' => 'http://drupal.org/handbook/modules/blog/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Enables keeping an easily and regularly updated web page or a blog.');
   }
 }
 
Index: modules/blogapi/blogapi.install
===================================================================
RCS file: modules/blogapi/blogapi.install
diff -N modules/blogapi/blogapi.install
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/blogapi/blogapi.install	24 Aug 2006 17:55:17 -0000
@@ -0,0 +1,12 @@
+<?php
+// $Id:$
+
+/**
+ * Implementation of hook_uninstall.
+ * Delete all module variables.
+ */
+function blogap_uninstall() {
+  variable_del('blogapi_node_types');
+}
+
+?>
Index: modules/blogapi/blogapi.meta
===================================================================
RCS file: modules/blogapi/blogapi.meta
diff -N modules/blogapi/blogapi.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/blogapi/blogapi.meta	24 Aug 2006 17:55:17 -0000
@@ -0,0 +1,6 @@
+name: Blog API
+description: Allows users to post content using applications that support XML-RPC blog APIs.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
+links: settings=admin/settings/blogapi
Index: modules/blogapi/blogapi.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/blogapi/blogapi.module,v
retrieving revision 1.94
diff -u -F^f -r1.94 blogapi.module
--- modules/blogapi/blogapi.module	18 Aug 2006 18:58:44 -0000	1.94
+++ modules/blogapi/blogapi.module	24 Aug 2006 17:55:17 -0000
@@ -23,8 +23,6 @@ function blogapi_help($section) {
 ', array('@file-xmlrpc' => 'xmlrpc.php', '@admin-settings-blogapi' => url('admin/settings/blogapi')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@blogapi">BlogApi page</a>.', array('@blogapi' => 'http://drupal.org/handbook/modules/blogapi/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Allows users to post content using applications that support XML-RPC blog APIs.');
   }
 }
 
Index: modules/book/book.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/book/book.install,v
retrieving revision 1.5
diff -u -F^f -r1.5 book.install
--- modules/book/book.install	20 Aug 2006 06:38:50 -0000	1.5
+++ modules/book/book.install	24 Aug 2006 17:55:18 -0000
@@ -1,6 +1,10 @@
 <?php
 // $Id: book.install,v 1.5 2006/08/20 06:38:50 dries Exp $
 
+/**
+ * Implementation of hook_install.
+ * Create module tables.
+ */
 function book_install() {
   switch ($GLOBALS['db_type']) {
     case 'mysql':
@@ -28,3 +32,17 @@ function book_install() {
       break;
   }
 }
+
+/**
+ * Implementation of hook_uninstall.
+ * Delete all module variables and drop tables.
+ * @param $confirm user confirmation before uninstall.
+ * @return Confirmation message on before confirmation.
+ */
+function book_uninstall($confirm = FALSE) {
+  if (!$confirm) {
+    return t('All books will be deleted.');
+  }
+  db_query("DROP TABLE {book}");
+}
+
Index: modules/book/book.meta
===================================================================
RCS file: modules/book/book.meta
diff -N modules/book/book.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/book/book.meta	24 Aug 2006 17:55:18 -0000
@@ -0,0 +1,6 @@
+name: Book
+description: Allows users to collaboratively author a book.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
+links: administer=admin/content/book, view books=book
Index: modules/book/book.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/book/book.module,v
retrieving revision 1.386
diff -u -F^f -r1.386 book.module
--- modules/book/book.module	23 Aug 2006 06:38:49 -0000	1.386
+++ modules/book/book.module	24 Aug 2006 17:55:18 -0000
@@ -1004,8 +1004,6 @@ function book_help($section) {
 ', array('@node-add-book' => url('node/add/book'), '@admin-node-book' => url('admin/content/book'), '@admin-settings-content-types-book-page' => url('admin/content/types/book'), '@admin-block' => url('admin/build/block'), '@admin-access' => url('admin/user/access')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@book">Book page</a>.', array('@book' => 'http://drupal.org/handbook/modules/book/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Allows users to collaboratively author a book.');
     case 'admin/content/book':
       return t('<p>The book module offers a means to organize content, authored by many users, in an online manual, outline or FAQ.</p>');
     case 'admin/content/book/orphan':
Index: modules/comment/comment.install
===================================================================
RCS file: modules/comment/comment.install
diff -N modules/comment/comment.install
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/comment/comment.install	24 Aug 2006 17:55:18 -0000
@@ -0,0 +1,20 @@
+<?php
+// $Id:$
+
+/**
+ * Implementation of hook_uninstall.
+ * Delete all module variables.
+ */
+function comment_uninstall() {
+  variable_del('comment_form_location');
+  variable_del('comment_default_mode');
+  variable_del('comment_default_order');
+  variable_del('comment_default_per_page');
+  variable_del('comment_controls');
+  variable_del('comment_anonymous');
+  variable_del('comment_subject_field');
+  variable_del('comment_preview');
+  variable_del('comment_roles');
+}
+
+?>
Index: modules/comment/comment.meta
===================================================================
RCS file: modules/comment/comment.meta
diff -N modules/comment/comment.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/comment/comment.meta	24 Aug 2006 17:55:18 -0000
@@ -0,0 +1,6 @@
+name: Comment
+description: Allows users to comment on and discuss published content.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
+links: administer=admin/content/comment
Index: modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.478
diff -u -F^f -r1.478 comment.module
--- modules/comment/comment.module	22 Aug 2006 11:13:03 -0000	1.478
+++ modules/comment/comment.module	24 Aug 2006 17:55:20 -0000
@@ -80,8 +80,6 @@ function comment_help($section) {
 ', array('@admin-access' => url('admin/user/access'), '@admin-settings-comment' => url('admin/content/comment/settings')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@comment">Comment page</a>.', array('@comment' => 'http://drupal.org/handbook/modules/comment/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Allows users to comment on and discuss published content.');
     case 'admin/content/comment':
     case 'admin/content/comment/new':
       return t("<p>Below is a list of the latest comments posted to your site. Click on a subject to see the comment, the author's name to edit the author's user information , \"edit\" to modify the text, and \"delete\" to remove their submission.</p>");
Index: modules/contact/contact.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/contact/contact.install,v
retrieving revision 1.4
diff -u -F^f -r1.4 contact.install
--- modules/contact/contact.install	20 Aug 2006 06:38:50 -0000	1.4
+++ modules/contact/contact.install	24 Aug 2006 17:55:20 -0000
@@ -1,6 +1,10 @@
 <?php
 // $Id: contact.install,v 1.4 2006/08/20 06:38:50 dries Exp $
 
+/**
+ * Implementation of hook_install.
+ * Create module tables.
+ */
 function contact_install() {
   switch ($GLOBALS['db_type']) {
     case 'mysql':
@@ -30,3 +34,19 @@ function contact_install() {
       break;
   }
 }
+
+/**
+ * Implementation of hook_uninstall.
+ * Delete all module variables and drop tables.
+ * @param $confirm user confirmation before uninstall.
+ * @return Confirmation message on before confirmation.
+ */
+function contact_uninstall($confirm = FALSE) {
+  if (!$confirm) {
+    return t('All contact information will be deleted.');
+  }
+  db_query("DROP TABLE {contact}");
+  variable_del('contact_default_status');
+  variable_del('contact_form_information');
+  variable_del('contact_hourly_threshold');
+}
Index: modules/contact/contact.meta
===================================================================
RCS file: modules/contact/contact.meta
diff -N modules/contact/contact.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/contact/contact.meta	24 Aug 2006 17:55:20 -0000
@@ -0,0 +1,6 @@
+name: Contact
+description: Enables the use of both personal and site-wide contact forms.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
+links: administer=admin/build/contact, contact form=contact
Index: modules/contact/contact.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/contact/contact.module,v
retrieving revision 1.63
diff -u -F^f -r1.63 contact.module
--- modules/contact/contact.module	20 Aug 2006 05:57:40 -0000	1.63
+++ modules/contact/contact.module	24 Aug 2006 17:55:21 -0000
@@ -23,8 +23,6 @@ function contact_help($section) {
       $output .= '<li>'. t('Site-wide contact form <a href="@menu-configuration">menu configuration</a>.', array('@menu-configuration' => url('admin/build/menu'))) .'</li></ul>';
       $output .= t('For more information, please read the configuration and customization handbook page for the <a href="@contact">contact module</a>.', array('@contact' => url('http://drupal.org/handbook/modules/contact/', NULL, NULL, TRUE)));
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Enables the use of both personal and site-wide contact forms.');
     case 'admin/build/contact':
       $output = t('This page lets you setup <a href="@form">your site-wide contact form</a>. To do so, add one or more categories. You can associate different recipients with each category to route e-mails to different people. For example, you can route website feedback to the webmaster and direct product information requests to the sales department. On the <a href="@settings">settings page</a>, you can customize the information shown above the contact form. This can be useful to provide additional contact information such as your postal address and telephone number.', array('@settings' => url('admin/build/contact/settings'), '@form' => url('contact')));
       if (!module_exists('menu')) {
Index: modules/drupal/drupal.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/drupal/drupal.install,v
retrieving revision 1.4
diff -u -F^f -r1.4 drupal.install
--- modules/drupal/drupal.install	20 Aug 2006 06:38:50 -0000	1.4
+++ modules/drupal/drupal.install	24 Aug 2006 17:55:21 -0000
@@ -1,6 +1,10 @@
 <?php
 // $Id: drupal.install,v 1.4 2006/08/20 06:38:50 dries Exp $
 
+/**
+ * Implementation of hook_install.
+ * Create module tables.
+ */
 function drupal_install() {
   switch ($GLOBALS['db_type']) {
     case 'mysql':
@@ -52,3 +56,27 @@ function drupal_install() {
       break;
   }
 }
+
+/**
+ * Implementation of hook_uninstall.
+ * Delete all module variables and drop tables.
+ * @param $confirm user confirmation before uninstall.
+ * @return Confirmation message on before confirmation.
+ */
+function drupal_uninstall($confirm = FALSE) {
+  if (!$confirm) {
+    return t('All drupal client information will be deleted.');
+  }
+  db_query("DROP TABLE {client}");
+  db_query("DROP TABLE {client_system}");
+  variable_del('drupal_authentication_service');
+  variable_del('drupal_directory');
+  variable_del('drupal_register');
+  variable_del('drupal_server');
+  variable_del('drupal_system');
+  variable_del('drupal_statistics');
+  variable_del('drupal_client_service');
+  variable_del('drupal_default_da_server');
+  variable_del('drupal_default_da_server_only');
+}
+
Index: modules/drupal/drupal.meta
===================================================================
RCS file: modules/drupal/drupal.meta
diff -N modules/drupal/drupal.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/drupal/drupal.meta	24 Aug 2006 17:55:21 -0000
@@ -0,0 +1,6 @@
+name: Drupal
+description: Lets you register your site with a central server and improve ranking of Drupal projects by posting information on your installed modules and themes; also enables users to log in using a Drupal ID.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
+links: sites registry=admin/settings/sites-registry, authentication=admin/settings/distributed-authentication
Index: modules/drupal/drupal.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/drupal/drupal.module,v
retrieving revision 1.127
diff -u -F^f -r1.127 drupal.module
--- modules/drupal/drupal.module	18 Aug 2006 18:58:45 -0000	1.127
+++ modules/drupal/drupal.module	24 Aug 2006 17:55:21 -0000
@@ -44,8 +44,6 @@ function drupal_help($section) {
 
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@drupal">Drupal page</a>.', array('@drupal' => 'http://drupal.org/handbook/modules/drupal/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Lets you register your site with a central server and improve ranking of Drupal projects by posting information on your installed modules and themes; also enables users to log in using a Drupal ID.');
     case 'admin/settings/distributed-authentication':
       return t('<p>Using this your site can "call home" to another Drupal server. By calling home to drupal.org and sending a list of your installed modules and themes, you help rank projects on drupal.org and so assist all Drupal administrators to find the best components for meeting their needs. If you want to register with a different server, you can change the Drupal XML-RPC server setting -- but the server has to be able to handle Drupal XML. Some XML-RPC servers may present directories of all registered sites. To get all your site information listed, go to the <a href="@site-settings">site information settings page</a> and set the site name, the e-mail address, the slogan, and the mission statement.</p>', array('@site-settings' => url('admin/settings/site-information')));
     case 'user/help#drupal':
Index: modules/filter/filter.meta
===================================================================
RCS file: modules/filter/filter.meta
diff -N modules/filter/filter.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/filter/filter.meta	24 Aug 2006 17:55:21 -0000
@@ -0,0 +1,6 @@
+name: Filter
+description: Handles the filtering of content in preparation for display.
+package: Required modules
+version: SYSTEM
+drupal: 4.8
+links: administer=admin/settings/filters, tips=filter/tips
Index: modules/filter/filter.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/filter/filter.module,v
retrieving revision 1.136
diff -u -F^f -r1.136 filter.module
--- modules/filter/filter.module	20 Aug 2006 06:53:08 -0000	1.136
+++ modules/filter/filter.module	24 Aug 2006 17:55:22 -0000
@@ -30,8 +30,6 @@ function filter_help($section) {
 ', array('@admin-filters' => url('admin/settings/filters')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@filter">Filter page</a>.', array('@filter' => 'http://drupal.org/handbook/modules/filter/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Handles the filtering of content in preparation for display.');
 
     case 'admin/settings/filters':
       return t('
Index: modules/forum/forum.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/forum/forum.install,v
retrieving revision 1.5
diff -u -F^f -r1.5 forum.install
--- modules/forum/forum.install	20 Aug 2006 06:38:50 -0000	1.5
+++ modules/forum/forum.install	24 Aug 2006 17:55:22 -0000
@@ -1,6 +1,10 @@
 <?php
 // $Id: forum.install,v 1.5 2006/08/20 06:38:50 dries Exp $
 
+/**
+ * Implementation of hook_install.
+ * Create module tables.
+ */
 function forum_install() {
   switch ($GLOBALS['db_type']) {
     case 'mysql':
@@ -26,3 +30,24 @@ function forum_install() {
       break;
   }
 }
+
+/**
+ * Implementation of hook_uninstall.
+ * Delete all module variables and drop tables.
+ * @param $confirm user confirmation before uninstall.
+ * @return Confirmation message on before confirmation.
+ */
+function forum_uninstall($confirm = FALSE) {
+  if (!$confirm) {
+    return t('All your forums and forum posts will be deleted.');
+  }
+  db_query("DROP TABLE {forum}");
+  db_query("DELETE FROM {node} WHERE type = 'forum'");
+  variable_del('forum_containers');
+  variable_del('forum_nav_vocabulary');
+  variable_del('forum_hot_topic');
+  variable_del('forum_per_page');
+  variable_del('forum_order');
+  variable_del('forum_block_num_0');
+  variable_del('forum_block_num_1');
+}
Index: modules/forum/forum.meta
===================================================================
RCS file: modules/forum/forum.meta
diff -N modules/forum/forum.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/forum/forum.meta	24 Aug 2006 17:55:22 -0000
@@ -0,0 +1,8 @@
+name: Forum
+description: Enables threaded discussions about general topics.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
+dependencies: taxonomy
+links: administer=admin/content/forum, view forums=forum
+
Index: modules/forum/forum.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/forum/forum.module,v
retrieving revision 1.352
diff -u -F^f -r1.352 forum.module
--- modules/forum/forum.module	23 Aug 2006 07:23:08 -0000	1.352
+++ modules/forum/forum.module	24 Aug 2006 17:55:23 -0000
@@ -25,8 +25,6 @@ function forum_help($section) {
 ', array('@admin-forum' => url('admin/content/forum'), '@admin-modules' => url('admin/settings/modules'), '@admin-help-comment' => url('admin/help/comment'), '@admin-help-taxonomy' => url('admin/help/taxonomy')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@forum">Forum page</a>.', array('@forum' => 'http://drupal.org/handbook/modules/forum/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Enables threaded discussions about general topics.');
     case 'admin/content/forum':
       return t('<p>This is a list of existing containers and forums that you can edit. Containers hold forums and, in turn, forums hold threaded discussions. Both containers and forums can be placed inside other containers and forums. By planning the structure of your containers and forums well, you make it easier for users to find a topic area of interest to them.</p>');
     case 'admin/content/forum/add/container':
Index: modules/help/help.meta
===================================================================
RCS file: modules/help/help.meta
diff -N modules/help/help.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/help/help.meta	24 Aug 2006 17:55:23 -0000
@@ -0,0 +1,6 @@
+name: Help
+description: Manages the display of online help.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
+links: view help=admin/help
Index: modules/help/help.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/help/help.module,v
retrieving revision 1.56
diff -u -F^f -r1.56 help.module
--- modules/help/help.module	20 Aug 2006 07:07:17 -0000	1.56
+++ modules/help/help.module	24 Aug 2006 17:55:23 -0000
@@ -116,8 +116,6 @@ function help_help($section) {
       $output .= '<p>'. t('You can not administer the help system.') .'</p>';
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@help">Help page</a>.', array('@help' => 'http://drupal.org/handbook/modules/help/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Manages the display of online help.');
   }
 }
 
Index: modules/legacy/legacy.meta
===================================================================
RCS file: modules/legacy/legacy.meta
diff -N modules/legacy/legacy.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/legacy/legacy.meta	24 Aug 2006 17:55:23 -0000
@@ -0,0 +1,5 @@
+name: Legacy
+description: Provides legacy handlers for upgrades from older Drupal installations.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
Index: modules/legacy/legacy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/legacy/legacy.module,v
retrieving revision 1.12
diff -u -F^f -r1.12 legacy.module
--- modules/legacy/legacy.module	18 Aug 2006 12:16:58 -0000	1.12
+++ modules/legacy/legacy.module	24 Aug 2006 17:55:24 -0000
@@ -27,8 +27,6 @@ function legacy_help($section) {
       $output .= '<p>'. t('Legacy module has no configurable options.') .'</p>';
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@legacy">Legacy page</a>.', array('@legacy' => 'http://drupal.org/handbook/modules/legacy/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Provides legacy handlers for upgrades from older Drupal installations.');
   }
 }
 
Index: modules/locale/locale.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/locale/locale.install,v
retrieving revision 1.4
diff -u -F^f -r1.4 locale.install
--- modules/locale/locale.install	20 Aug 2006 06:38:50 -0000	1.4
+++ modules/locale/locale.install	24 Aug 2006 17:55:24 -0000
@@ -1,6 +1,10 @@
 <?php
 // $Id: locale.install,v 1.4 2006/08/20 06:38:50 dries Exp $
 
+/**
+ * Implementation of hook_install.
+ * Create module tables.
+ */
 function locale_install() {
   switch ($GLOBALS['db_type']) {
     case 'mysql':
@@ -67,3 +71,19 @@ function locale_install() {
   }
   db_query("INSERT INTO {locales_meta} (locale, name, enabled, isdefault) VALUES ('en', 'English', '1', '1')");
 }
+
+/**
+ * Implementation of hook_uninstall.
+ * Delete all module variables and drop tables.
+ * @param $confirm user confirmation before uninstall.
+ * @return Confirmation message on before confirmation.
+ */
+function locale_uninstall($confirm = FALSE) {
+  if (!$confirm) {
+    return t('All locale information will be deleted.');
+  }
+  db_query("DROP TABLE {locales_meta}");
+  db_query("DROP TABLE {locales_source}");
+  db_query("DROP TABLE {locales_target}");
+}
+
Index: modules/locale/locale.meta
===================================================================
RCS file: modules/locale/locale.meta
diff -N modules/locale/locale.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/locale/locale.meta	24 Aug 2006 17:55:24 -0000
@@ -0,0 +1,6 @@
+name: Locale
+description: Enables the translation of the user interface to languages other than English.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
+links: administer=admin/settings/locale
Index: modules/locale/locale.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/locale/locale.module,v
retrieving revision 1.143
diff -u -F^f -r1.143 locale.module
--- modules/locale/locale.module	18 Aug 2006 18:58:46 -0000	1.143
+++ modules/locale/locale.module	24 Aug 2006 17:55:24 -0000
@@ -33,8 +33,6 @@ function locale_help($section) {
 ', array('@admin-locale' => url('admin/settings/locale'), '@admin-locale-string-search' => url('admin/settings/locale/string/search'), '@admin-locale-language-add' => url('admin/settings/locale/language/add'), '@external-http-drupal-org-project-Translations' => 'http://drupal.org/project/Translations'));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@locale">Locale page</a>.', array('@locale' => 'http://drupal.org/handbook/modules/locale/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Enables the translation of the user interface to languages other than English.');
     case 'admin/settings/locale':
     case 'admin/settings/locale/language/overview':
       return t("<p>Drupal provides support for the translation of its interface text into different languages. This page provides an overview of the installed languages. You can add a language on the <a href=\"@add-language\">add language page</a>, or directly by <a href=\"@import\">importing a translation</a>. If multiple languages are enabled, registered users will be able to set their preferred language. The site default will be used for anonymous visitors and for users without their own settings.</p><p>Drupal interface translations may be added or extended by several courses: by <a href=\"@import\">importing</a> an existing translation, by <a href=\"@search\">translating everything</a> from scratch, or by a combination of these approaches.</p>", array("@search" => url("admin/settings/locale/string/search"), "@import" => url("admin/settings/locale/language/import"), "@add-language" => url("admin/settings/locale/language/add")));
Index: modules/menu/menu.meta
===================================================================
RCS file: modules/menu/menu.meta
diff -N modules/menu/menu.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/menu/menu.meta	24 Aug 2006 17:55:24 -0000
@@ -0,0 +1,6 @@
+name: Menu
+description: Allows administrators to customize the site navigation menu.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
+links: administer=admin/build/menu
Index: modules/menu/menu.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/menu/menu.module,v
retrieving revision 1.82
diff -u -F^f -r1.82 menu.module
--- modules/menu/menu.module	22 Aug 2006 11:13:03 -0000	1.82
+++ modules/menu/menu.module	24 Aug 2006 17:55:25 -0000
@@ -31,8 +31,6 @@ function menu_help($section) {
 ', array('@admin-menu' => url('admin/build/menu'), '@admin-block' => url('admin/build/block'), '@admin-menu-menu-add' => url('admin/build/menu/menu/add'), '@admin-menu-item-add' => url('admin/build/menu/item/add'), '@admin-settings-menus' => url('admin/build/menu/settings')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@menu">Menu page</a>.', array('@menu' => 'http://drupal.org/handbook/modules/menu/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Allows administrators to customize the site navigation menu.');
     case 'admin/build/menu':
       return '<p>'. t('Menus are a collection of links (menu items) used to navigate a website. The list(s) below display the currently available menus along with their menu items. Select an operation from the list to manage each menu or menu item.', array('@admin-settings-menus' => url('admin/build/menu/settings'), '@admin-block'=> url('admin/build/block'))) .'</p>';
     case 'admin/build/menu/menu/add':
Index: modules/node/node.meta
===================================================================
RCS file: modules/node/node.meta
diff -N modules/node/node.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/node/node.meta	24 Aug 2006 17:55:25 -0000
@@ -0,0 +1,6 @@
+name: Node
+description: Allows content to be submitted to the site and displayed on pages.
+package: Required modules
+version: SYSTEM
+drupal: 4.8
+links: administer=admin/content/node, settings=admin/content/node-settings, content types=admin/content/types
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.685
diff -u -F^f -r1.685 node.module
--- modules/node/node.module	23 Aug 2006 18:38:41 -0000	1.685
+++ modules/node/node.module	24 Aug 2006 17:55:27 -0000
@@ -32,8 +32,6 @@ function node_help($section) {
 ', array('@search' => url('search'), '@admin-settings-content-types' => url('admin/content/types')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@node">Node page</a>.', array('@node' => 'http://drupal.org/handbook/modules/node/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Allows content to be submitted to the site and displayed on pages.');
     case 'admin/content/search':
       return t('<p>Enter a simple pattern to search for a post. This can include the wildcard character *.<br />For example, a search for "br*" might return "bread bakers", "our daily bread" and "brenda".</p>');
     case 'admin/content/types':
Index: modules/path/path.meta
===================================================================
RCS file: modules/path/path.meta
diff -N modules/path/path.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/path/path.meta	24 Aug 2006 17:55:27 -0000
@@ -0,0 +1,6 @@
+name: Path
+description: Allows users to rename URLs.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
+links: administer=admin/build/path
Index: modules/path/path.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/path/path.module,v
retrieving revision 1.91
diff -u -F^f -r1.91 path.module
--- modules/path/path.module	22 Aug 2006 11:13:04 -0000	1.91
+++ modules/path/path.module	24 Aug 2006 17:55:27 -0000
@@ -34,8 +34,6 @@ function path_help($section) {
 ', array('@admin-path-add' => url('admin/build/path/add'), '@admin-path' => url('admin/build/path'), '@external-http-drupal-org-node-15365' => 'http://drupal.org/node/15365', '@admin-clean-url-settings' => url('admin/settings/clean-urls')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@path">Path page</a>.', array('@path' => 'http://drupal.org/handbook/modules/path/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Allows users to rename URLs.');
     case 'admin/build/path':
       return t("<p>Drupal provides users complete control over URLs through aliasing. This feature is typically used to make URLs human-readable or easy to remember. For example, one could map the relative URL 'node/1' onto 'about'. Each system path can have multiple aliases.</p>");
     case 'admin/build/path/add':
Index: modules/ping/ping.meta
===================================================================
RCS file: modules/ping/ping.meta
diff -N modules/ping/ping.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/ping/ping.meta	24 Aug 2006 17:55:27 -0000
@@ -0,0 +1,5 @@
+name: Ping
+description: Alerts other sites when your site has been updated.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
Index: modules/ping/ping.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/ping/ping.module,v
retrieving revision 1.42
diff -u -F^f -r1.42 ping.module
--- modules/ping/ping.module	18 Aug 2006 12:16:58 -0000	1.42
+++ modules/ping/ping.module	24 Aug 2006 17:55:27 -0000
@@ -23,8 +23,6 @@ function ping_help($section) {
 ', array('@admin-modules' => url('admin/settings/modules'), '@file-cron' => 'cron.php', '@external-http-drupal-org-node-23714' => 'http://drupal.org/node/23714'));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@ping">Ping page</a>.', array('@ping' => 'http://drupal.org/handbook/modules/ping/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Alerts other sites when your site has been updated.');
   }
 }
 
Index: modules/poll/poll.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/poll/poll.install,v
retrieving revision 1.6
diff -u -F^f -r1.6 poll.install
--- modules/poll/poll.install	20 Aug 2006 06:38:50 -0000	1.6
+++ modules/poll/poll.install	24 Aug 2006 17:55:28 -0000
@@ -1,6 +1,10 @@
 <?php
 // $Id: poll.install,v 1.6 2006/08/20 06:38:50 dries Exp $
 
+/**
+ * Implementation of hook_install.
+ * Create module tables.
+ */
 function poll_install() {
   switch ($GLOBALS['db_type']) {
     case 'mysql':
@@ -63,3 +67,18 @@ function poll_install() {
       break;
   }
 }
+
+/**
+ * Implementation of hook_uninstall.
+ * Delete all module variables and drop tables.
+ * @param $confirm user confirmation before uninstall.
+ * @return Confirmation message on before confirmation.
+ */
+function poll_uninstall($confirm = FALSE) {
+  if (!$confirm) {
+    return t('All configured pols and votes will be deleted.');
+  }
+  db_query("DROP TABLE {poll}");
+  db_query("DROP TABLE {poll_votes}");
+  db_query("DROP TABLE {poll_choices}");
+}
Index: modules/poll/poll.meta
===================================================================
RCS file: modules/poll/poll.meta
diff -N modules/poll/poll.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/poll/poll.meta	24 Aug 2006 17:55:28 -0000
@@ -0,0 +1,6 @@
+name: Poll
+description: Allows your site to capture votes on different topics in the form of multiple choice questions.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
+links: view polls=poll
Index: modules/poll/poll.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/poll/poll.module,v
retrieving revision 1.211
diff -u -F^f -r1.211 poll.module
--- modules/poll/poll.module	24 Aug 2006 08:56:17 -0000	1.211
+++ modules/poll/poll.module	24 Aug 2006 17:55:28 -0000
@@ -23,8 +23,6 @@ function poll_help($section) {
 ', array('@poll' => url('poll'), '@admin-node-configure-types-poll' => url('admin/content/types/poll')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@poll">Poll page</a>.', array('@poll' => 'http://drupal.org/handbook/modules/poll/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t("Allows your site to capture votes on different topics in the form of multiple choice questions.");
   }
 }
 
Index: modules/profile/profile.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/profile/profile.install,v
retrieving revision 1.6
diff -u -F^f -r1.6 profile.install
--- modules/profile/profile.install	20 Aug 2006 06:38:50 -0000	1.6
+++ modules/profile/profile.install	24 Aug 2006 17:55:28 -0000
@@ -1,6 +1,10 @@
 <?php
 // $Id: profile.install,v 1.6 2006/08/20 06:38:50 dries Exp $
 
+/**
+ * Implementation of hook_install.
+ * Create module tables.
+ */
 function profile_install() {
   switch ($GLOBALS['db_type']) {
     case 'mysql':
@@ -63,3 +67,18 @@ function profile_install() {
       break;
   }
 }
+
+/**
+ * Implementation of hook_uninstall.
+ * Delete all module variables and drop tables.
+ * @param $confirm user confirmation before uninstall.
+ * @return Confirmation message on before confirmation.
+ */
+function profile_uninstall($confirm = FALSE) {
+  if (!$confirm) {
+    return t('All configure user profiles will be deleted.');
+  }
+  db_query("DROP TABLE {profile_fields}");
+  db_query("DROP TABLE {profile_values}");
+  variable_del('profile_block_author_fields');
+}
Index: modules/profile/profile.meta
===================================================================
RCS file: modules/profile/profile.meta
diff -N modules/profile/profile.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/profile/profile.meta	24 Aug 2006 17:55:28 -0000
@@ -0,0 +1,7 @@
+name: Profile
+description: Supports configurable user profiles.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
+links: administer=admin/user/profile, user list=profile
+
Index: modules/profile/profile.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/profile/profile.module,v
retrieving revision 1.167
diff -u -F^f -r1.167 profile.module
--- modules/profile/profile.module	20 Aug 2006 07:07:17 -0000	1.167
+++ modules/profile/profile.module	24 Aug 2006 17:55:29 -0000
@@ -40,8 +40,6 @@ function profile_help($section) {
 ', array('@profile' => url('profile'), '@admin-settings-profile' => url('admin/user/profile')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@profile">Profile page</a>.', array('@profile' => 'http://drupal.org/handbook/modules/profile/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Supports configurable user profiles.');
     case 'admin/user/profile':
       return t('<p>Here you can define custom fields that users can fill in in their user profile (such as <em>country</em>, <em>real name</em>, <em>age</em>, ...).</p>');
   }
Index: modules/search/search.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.install,v
retrieving revision 1.5
diff -u -F^f -r1.5 search.install
--- modules/search/search.install	20 Aug 2006 06:38:50 -0000	1.5
+++ modules/search/search.install	24 Aug 2006 17:55:29 -0000
@@ -1,6 +1,10 @@
 <?php
 // $Id: search.install,v 1.5 2006/08/20 06:38:50 dries Exp $
 
+/**
+ * Implementation of hook_install.
+ * Create module tables.
+ */
 function search_install() {
   switch ($GLOBALS['db_type']) {
     case 'mysql':
@@ -58,3 +62,20 @@ function search_install() {
       break;
   }
 }
+
+/**
+ * Implementation of hook_uninstall.
+ * Delete all module variables and drop tables.
+ * @param $confirm user confirmation before uninstall.
+ * @return Confirmation message on before confirmation.
+ */
+function search_uninstall($confirm = FALSE) {
+  if (!$confirm) {
+    return t('All indexes will be deleted.');
+  }
+  db_query("DROP TABLE {search_dataset}");
+  db_query("DROP TABLE {search_index}");
+  db_query("DROP TABLE {search_total}");
+  variable_del('minimum_word_size');
+  variable_del('overlap_cjk');
+}
Index: modules/search/search.meta
===================================================================
RCS file: modules/search/search.meta
diff -N modules/search/search.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/search/search.meta	24 Aug 2006 17:55:29 -0000
@@ -0,0 +1,6 @@
+name: Search
+description: Enables site-wide keyword searching.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
+links: settings=admin/settings/search, search=search
Index: modules/search/search.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/search/search.module,v
retrieving revision 1.193
diff -u -F^f -r1.193 search.module
--- modules/search/search.module	18 Aug 2006 18:58:46 -0000	1.193
+++ modules/search/search.module	24 Aug 2006 17:55:30 -0000
@@ -107,8 +107,6 @@ function search_help($section) {
 ', array('@admin-help-system' => url('admin/help/system'), '@file-cron' => 'cron.php', '@external-http-drupal-org-node-23714' => 'http://drupal.org/node/23714', '@admin-settings-search' => url('admin/settings/search')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@search">Search page</a>.', array('@search' => 'http://drupal.org/handbook/modules/search/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Enables site-wide keyword searching.');
     case 'admin/settings/search':
       return t('
 <p>The search engine works by maintaining an index of the words in your site\'s content. You can adjust the settings below to tweak the indexing behaviour. Note that the search requires cron to be set up correctly.</p>
Index: modules/statistics/statistics.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/statistics/statistics.install,v
retrieving revision 1.5
diff -u -F^f -r1.5 statistics.install
--- modules/statistics/statistics.install	20 Aug 2006 06:38:50 -0000	1.5
+++ modules/statistics/statistics.install	24 Aug 2006 17:55:30 -0000
@@ -1,6 +1,10 @@
 <?php
 // $Id: statistics.install,v 1.5 2006/08/20 06:38:50 dries Exp $
 
+/**
+ * Implementation of hook_install.
+ * Create module tables.
+ */
 function statistics_install() {
   switch ($GLOBALS['db_type']) {
     case 'mysql':
@@ -36,3 +40,23 @@ function statistics_install() {
       break;
   }
 }
+
+/**
+ * Implementation of hook_uninstall.
+ * Delete all module variables and drop tables.
+ * @param $confirm user confirmation before uninstall.
+ * @return Confirmation message on before confirmation.
+ */
+function statistics_uninstall($confirm = FALSE) {
+  if (!$confirm) {
+    return t('All site statistics will be deleted.');
+  }
+  db_query("DROP TABLE {accesslog}");
+  variable_del('statistics_count_content_views');
+  variable_del('statistics_enable_access_log');
+  variable_del('statistics_flush_accesslog_timer');
+  variable_del('statistics_day_timestamp');
+  variable_del('statistics_block_top_day_num');
+  variable_del('statistics_block_top_all_num');
+  variable_del('statistics_block_top_last_num');
+}
Index: modules/statistics/statistics.meta
===================================================================
RCS file: modules/statistics/statistics.meta
diff -N modules/statistics/statistics.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/statistics/statistics.meta	24 Aug 2006 17:55:30 -0000
@@ -0,0 +1,6 @@
+name: Statistics
+description: Logs access statistics for your site.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
+links: settings=admin/logs/settings
Index: modules/statistics/statistics.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/statistics/statistics.module,v
retrieving revision 1.237
diff -u -F^f -r1.237 statistics.module
--- modules/statistics/statistics.module	18 Aug 2006 18:58:46 -0000	1.237
+++ modules/statistics/statistics.module	24 Aug 2006 17:55:31 -0000
@@ -41,8 +41,6 @@ function statistics_help($section) {
 ', array('@admin-settings-statistics' => url('admin/logs/settings'), '@admin-logs' => url('admin/logs'), '@admin-logs-hits' => url('admin/logs/hits'), '@admin-block' => url('admin/build/block')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@statistics">Statistics page</a>.', array('@statistics' => 'http://drupal.org/handbook/modules/statistics/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Logs access statistics for your site.');
     case 'admin/logs/settings':
       return t('<p>Settings for the statistical information that Drupal will keep about the site. See <a href="@statistics">site statistics</a> for the actual information.</p>', array('@statistics' => url('admin/logs/hits')));
     case 'admin/logs/hits':
Index: modules/system/admin.css
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/admin.css,v
retrieving revision 1.2
diff -u -F^f -r1.2 admin.css
--- modules/system/admin.css	17 Aug 2006 21:39:47 -0000	1.2
+++ modules/system/admin.css	24 Aug 2006 17:55:31 -0000
@@ -49,3 +49,79 @@
   margin-right: 1em;
   padding-right: 4px;
 }
+
+
+/*
+** Formatting for modules page
+*/
+
+table.modules-table {
+  width: 100%;
+}
+
+th.modules-header {
+  font-size: 140%;
+  border: none;
+  background-color: white;
+  padding: 1em 0 0.5em 0;
+}
+
+th.modules-heading {
+  font-size: 110%;
+  padding: 0.2em 0 0.2em 0.5em;
+}
+
+th.modules-heading.name {
+  width: 9%;
+}
+
+th.modules-heading.version {
+  width: 9%;
+}
+
+th.modules-heading.related {
+  width: 62%;
+  padding-right: 4em;
+}
+
+th.modules-heading.operations {
+  width: 16%;
+}
+
+table.modules-table tr.odd td, table.modules-table tr.even td {
+  padding: 0.5em 0 0.5em 0.5em;
+  vertical-align: top;
+}
+
+table.modules-table p {
+  margin: 0;
+  font-size: 90%;
+}
+
+table.modules-table p.required { 
+  color: #ff0000;
+  font-style: italic;
+  padding-top: 0.25em;
+}
+
+input.modules-button {
+  cursor: pointer;
+  font-size:95%;
+}
+
+ul.modules-links {
+  margin: 0 0 0.5em 0;
+  padding: 0;
+  list-style: none;
+}
+
+ul.modules-links li {
+  display: inline;
+  padding:0 1em;
+  border-left: 1px solid #ccc;
+}
+
+ul.modules-links li.first {
+  border: none;
+  padding-left: 0;
+}
Index: modules/system/system.meta
===================================================================
RCS file: modules/system/system.meta
diff -N modules/system/system.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/system/system.meta	24 Aug 2006 17:55:31 -0000
@@ -0,0 +1,6 @@
+name: System
+description: Handles general site configuration for administrators.
+package: Required modules
+version: SYSTEM
+drupal: 4.8
+links: administer=admin, settings=admin/settings, themes=admin/build/themes
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.349
diff -u -F^f -r1.349 system.module
--- modules/system/system.module	23 Aug 2006 04:40:57 -0000	1.349
+++ modules/system/system.module	24 Aug 2006 17:55:32 -0000
@@ -30,8 +30,6 @@ function system_help($section) {
 ', array('@file-cron' => 'cron.php', '@external-http-drupal-org-cron' => 'http://drupal.org/cron', '@cron-status' => url('admin/settings/cron-status'), '@cron-manually' => url('admin/settings/cron-status/cron'), '@admin-settings' => url('admin/settings/page-caching')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@system">System page</a>.', array('@system' => 'http://drupal.org/handbook/modules/system/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Handles general site configuration for administrators.');
     case 'admin':
       return t('<p>Welcome to the administration section. Here you may control how your site functions.</p>');
     case 'admin/build/themes':
@@ -43,8 +41,10 @@ function system_help($section) {
       $theme = array_pop($reference);
       return t('<p>These options control the display settings for the <code>%template</code> theme. When your site is displayed using this theme, these settings will be used. By clicking "Reset to defaults," you can choose to use the <a href="@global">global settings</a> for this theme.</p>', array('%template' => $theme, '@global' => url('admin/build/themes/settings')));
     case 'admin/settings/modules':
-      return t('<p>Modules are plugins for Drupal that extend its core functionality. Here you can select which modules are enabled. Click on the name of the module in the navigation menu for their individual configuration pages. Once a module is enabled, new <a href="@permissions">permissions</a> might be made available. Modules can automatically be temporarily disabled to reduce server load when your site becomes extremely busy by enabling the throttle.module and checking throttle. The auto-throttle functionality must be enabled on the <a href="@throttle">throttle configuration page</a> after having enabled the throttle module.</p>
-<p>It is important that <a href="@update-php">update.php</a> is run every time a module is updated to a newer version.</p>', array('@permissions' => url('admin/user/access'), '@throttle' => url('admin/settings/throttle'), '@update-php' => $base_url .'/update.php'));
+      return t('<p>Modules are plugins for Drupal that extend its core functionality. Here you can see which modules are enabled. Some modules may include links to their administration pages. Once a module is enabled, new <a href="@permissions">permissions</a> might be made available. Modules can automatically be temporarily disabled to reduce server load when your site becomes extremely busy by enabling the throttle.module and visiting the throttle administration pages.</p><p>If a module is required by another module that is enabled, you will not be able to disable that module until all modules that require it are disabled.</p>
+<p>It is important that <a href="@update-php">update.php</a> is run every time a module is updated to a newer version.</p>', array('@permissions' => url('admin/user/access'), '@update-php' => $base_url .'/update.php'));
+    case 'admin/settings/modules/disabled':
+      return t('<p>Modules are plugins for Drupal that extend its core functionality. Here you can install new modules or re-enable/uninstall previously disabled modules. Once a module is enabled, new <a href="@permissions">permissions</a> might be made available.</p><p><strong>Note that uninstalling a module will remove that module\'s data from your system, and that this operation is not recoverable!</strong> If you are not sure, be sure to make a backup of your database before selecting uninstall!</p><p>If a module is required by another module, you will not be able to enable that module until all modules that it requires are enabled.</p>', array('@permissions' => url('admin/user/access')));
   }
 }
 
@@ -185,9 +185,28 @@ function system_menu($may_cache) {
       'title' => t('modules'),
       'description' => t('Enable or disable add-on modules for your site.'),
       'weight' => -10,
-      'callback' => 'drupal_get_form',
-      'callback arguments' => array('system_modules'),
+      'callback' => 'system_modules',
+      'callback arguments' => array('enabled'),
       'access' => $access);
+    $items[] = array('path' => 'admin/settings/modules/enabled', 
+      'title' => t('enabled'),
+      'callback' => 'system_modules', 
+      'callback arguments' => array('enabled'), 
+      'access' => $access, 
+      'type' => MENU_DEFAULT_LOCAL_TASK, 
+      'weight' => -10);
+    $items[] = array('path' => 'admin/settings/modules/disabled',
+      'title' => t('disabled'),
+      'callback' => 'system_modules', 
+      'callback arguments' => array('disabled'), 
+      'access' => $access, 
+      'type' => MENU_LOCAL_TASK);    
+    $items[] = array('path' => 'admin/settings/modules/uninstall',
+      'title' => t('confirm uninstall'),
+      'callback' => 'drupal_get_form',
+      'callback arguments' => array('system_confirm_uninstall'), 
+      'access' => $access, 
+      'type' => MENU_CALLBACK);    
 
     // Settings:
     $items[] = array(
@@ -1199,115 +1218,297 @@ function system_themes_submit($form_id, 
 }
 
 /**
+ * Helper function to reduce code. Provides a form that is a button or two
+ * keyed to the module.
+ */
+function system_module_form($module, $metadata, $type, $type2 = NULL) {
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => $type,
+    '#attributes' => array('class' => 'modules-button'),
+  );
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => $type,
+    '#attributes' => array('class' => 'modules-button'),
+  );
+  
+  $form['metadata'] = array(
+    '#type' => 'value',
+    '#value' => $metadata,
+    '#attributes' => array('class' => 'modules-button'),
+  );
+  
+  $form['#submit']['system_module_form_submit'] = array();
+
+  if ($type2) {
+    $form['submit2'] = array(
+      '#type' => 'submit',
+      '#value' => $type2,
+      '#attributes' => array('class' => 'modules-button'),
+    );
+  }
+  return $form;
+}
+
+function system_forms() {
+  static $forms = array();
+  if (!$forms) {
+    $files = system_listing('\.module$', 'modules', 'name', 0);
+    foreach ($files as $file) {
+      $forms["system_module_form_$file->name"]['callback'] = 'system_module_form';
+    }
+  }
+  return $forms;
+
+}
+
+/**
  * Menu callback; displays a listing of all modules.
  */
-function system_modules() {
+function system_modules($type) {
+  // Set page title correctly
+  drupal_set_title(t('@type modules', array('@type' => $type));
+  
   // Get current list of modules
   $files = module_rebuild_cache();
+  $required = array('block', 'filter', 'node', 'system', 'user', 'watchdog');
 
   foreach ($files as $filename => $file) {
-    drupal_get_filename('module', $file->name, $file->filename);
-    drupal_load('module', $file->name);
-
-    $file->description = module_invoke($file->name, 'help', 'admin/settings/modules#description');
+    $metadata = $file->metadata;
+    if (($type == 'enabled' && $file->status) || ($type == 'disabled' && !$file->status)) {
+      $packages[$metadata['package']][] = $file->name;
+      $options[$file->name] = '';
+    }
 
-    $form['name'][$file->name] = array('#value' => $file->name);
-    $form['description'][$file->name] = array('#value' => $file->description);
-    $options[$file->name] = '';
+    $file->description = $metadata['description'];
+ 
+    // for later dependency checking.
     if ($file->status) {
-      $status[] = $file->name;
+      $metadata['enabled'] = TRUE;
     }
-    if ($file->throttle) {
-      $throttle[] = $file->name;
+    else if ($file->schema_version != -1) {
+      $metadata['uninstalled'] = TRUE;
     }
+    $metadata['filename'] = $file->filename;
+    $modules[$filename] = $metadata;
   }
 
-  // Handle status checkboxes, including overriding the generated
-  // checkboxes for required modules.
-  $form['status'] = array('#type' => 'checkboxes', '#default_value' => $status, '#options' => $options);
-  $required = array('block', 'filter', 'node', 'system', 'user', 'watchdog');
-  foreach ($required as $require) {
-    $form['status'][$require] = array('#type' => 'hidden', '#value' => 1, '#suffix' => t('required'));
+  if (!$packages) {
+    return t('<p>There are currently no modules that you can enable.</p>');
+  }
+
+  $top_array = array();
+  // Re-order packages to force core modules to the top.
+  foreach (array(t('Required modules'), t('Drupal core modules')) as $key) {
+    if (is_array($packages[$key])) { 
+      $top_array[$key] = $packages[$key];
+      unset($packages[$key]);
+    }
   }
 
-  /**
-   * Handle throttle checkboxes, including overriding the generated checkboxes for required modules.
-   */
-  if (module_exists('throttle')) {
-    $form['throttle'] = array('#type' => 'checkboxes', '#default_value' => $throttle, '#options' => $options);
-    $throttle_required = array_merge($required, array('throttle'));
-    foreach ($throttle_required as $require) {
-      $form['throttle'][$require] = array('#type' => 'hidden', '#value' => 0, '#suffix' => t('required'));
+  ksort($packages);
+  $packages = array_merge($top_array, $packages);
+
+  $header = array(
+    array('data' => t('Name'), 
+          'header' => TRUE, 
+          'class' => 'modules-heading name',
+    ),
+    array('data' => t('Version'), 
+          'header' => TRUE, 
+          'class' => 'modules-heading version',
+    ),
+    array('data' => ($type == 'enabled' ? t('Related links and description') : t('Description')), 
+          'header' => TRUE, 
+          'class' => 'modules-heading related',
+    ),
+    array('data' => t('Operations'), 
+          'header' => TRUE, 
+          'class' => 'modules-heading operations', 
+          'colspan' => 2,
+    ),
+  );
+       
+  $rows = array();
+  foreach ($packages as $group => $package) {
+    $rows[] = array(
+      array(
+        'colspan' => 5,
+        'header'  => TRUE,
+        'data' => $group,
+        'class' => 'modules-header', 
+      ),
+    );
+    $rows[] = $header;
+    foreach ($package as $module) {
+      $modules[$module]['buttons'] = array();
+    
+      // Check for dependencies.
+      $depends = '';
+      $can_change = TRUE;
+      $compatible = strpos(VERSION, $modules[$module]['drupal']) === 0;
+          
+      if (!$modules[$module]['enabled']) {
+        // disabled modules and don't get their links
+        $modules[$module]['links'] = array();
+        foreach ($modules[$module]['dependencies'] as $dependency) {
+          $depends .= (!$depends ? t('Depends on: ') : ', ') ."<em>$dependency</em>";
+          if (!$modules[$dependency]['enabled']) {
+            $depends .= t(' (not present)');
+            $can_change = FALSE;
+          }
+        }
+        if ($can_change && $compatible) {
+          if ($modules[$module]['uninstalled']) {
+            $modules[$module]['buttons'][] = drupal_get_form("system_module_form_$module", $module, $modules[$module], t('Enable'), t('Uninstall'));
+          } 
+          else {
+            $modules[$module]['buttons'][] = drupal_get_form("system_module_form_$module", $module, $modules[$module], t('Install'));  
+          }
+        }
+        else {
+          if ($modules[$module]['uninstalled']) {
+            $modules[$module]['buttons'][] = drupal_get_form("system_module_form_$module", $module, $modules[$module], t('Uninstall'));
+          } 
+        }
+      }
+      else {
+        // Check for modules that depend on this module.
+        foreach ($modules as $dependency => $module_data) {
+          if (in_array($module, $module_data['dependencies']) && $module_data['enabled']) {
+            $depends .= (!$depends ? t('Required by: ') : ', ') ."<em>$dependency</em>";
+            $can_change = FALSE;
+          }
+        }
+        if ($can_change && !in_array($module, $required)) {
+          $modules[$module]['buttons'][] = drupal_get_form("system_module_form_$module", $module, $modules[$module], t('Disable'));
+        }
+      }
+      $cells = array();
+      $cells[] = $modules[$module]['name'];
+      $cells[] = $modules[$module]['version'];
+      if ($perms = module_invoke($module, 'perm')) {
+        array_unshift($modules[$module]['links'], array('title' => t('permissions'), 'href' => 'admin/user/access', 'fragment' => "module-$module"));
+      }
+      if ($help = module_invoke($module, 'help', "admin/help#$module")) {
+        array_unshift($modules[$module]['links'], array('title' => t('help'), 'href' => "admin/help/$module"));
+      }
+      $description = theme('system_module_links', $modules[$module]['links']) .'<p class="modules-description">'. $modules[$module]['description'] .'</p>';
+      if ($depends) {
+        $description .= '<p class="required">'. $depends .'</p>';
+      }
+      $cells[] = $description;
+
+      $cells[] = array(
+        'data' => implode(' ', $modules[$module]['buttons']),
+        'nowrap' => TRUE,
+      );
+      $rows[] = $cells;
+      if (!$compatible) {
+        $rows[] = array('', array(
+          'data' => t('(This module is for Drupal version %version and not compatible with your current version)', array('%version' => $modules[$module]['drupal'])), 
+          'colspan' => 4),
+        );
+      }
     }
   }
 
-  $form['buttons']['submit'] = array('#type' => 'submit', '#value' => t('Save configuration'));
+  if ($rows) {
+    $output .= theme('table', array(), $rows, array('class' => 'modules-table'));
+  }  
 
-  return $form;
+  return $output;
 }
 
-function theme_system_modules($form) {
-  foreach (element_children($form['name']) as $key) {
-    $row = array();
-    $row[] = drupal_render($form['name'][$key]);
-    $row[] = drupal_render($form['description'][$key]);
-    $row[] = array('data' => drupal_render($form['status'][$key]), 'align' => 'center');
-
-    if (module_exists('throttle')) {
-      $row[] = array('data' => drupal_render($form['throttle'][$key]), 'align' => 'center');
+function theme_system_module_links($links) {
+  $output = '';
+  
+  if ($links) {
+    $l = array();
+    
+    foreach ($links as $link) {
+      $l[] = l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment']);
     }
-    $rows[] = $row;
-  }
-
-  $header = array(t('Name'), t('Description'), t('Enabled'));
-  if (module_exists('throttle')) {
-    $header[] = t('Throttle');
+    
+    $output = '<ul class="modules-links"><li class="first">'. implode('</li><li>', $l) .'</li></ul>';
   }
 
-  $output = theme('table', $header, $rows);
-  $output .= drupal_render($form);
   return $output;
 }
 
-
-function system_modules_submit($form_id, $edit) {
+/**
+ * Implementation of the module form hook_submit().
+ * @param $form_id
+ *  The id of the form.
+ * @param $form_values
+ *  The values passed back from the client.
+ */
+function system_module_form_submit($form_id, $form_values) {
   include_once './includes/install.inc';
-  $new_modules = array();
-  foreach ($edit['status'] as $key => $choice) {
-    if ($choice) {
-      if (drupal_get_installed_schema_version($key) == SCHEMA_UNINSTALLED) {
-        $new_modules[] = $key;
-      }
-      else {
-        module_enable($key);
+  $module = str_replace('system_module_form_', '', $form_id);
+  $metadata = $form_values['metadata'];
+
+  $op = $_POST['op'];
+  if ($op == t('Install') || $op == t('Enable')) {
+    $status = 1;
+    if ($op == t('Install')) {
+      drupal_install_module($module);
+      drupal_set_message(t('%module installed.', array('%module' => $metadata['name'])));
+    } 
+    else {
+      module_enable($module);
+      drupal_set_message(t('%module enabled.', array('%module' => $metadata['name'])));
+    }
+  }
+  else {
+    $status = 0;
+    if ($op == t('Uninstall')) {
+      $confirm = drupal_uninstall_module($module);
+      if ($confirm) {
+        return "admin/settings/modules/uninstall/$module";
       }
+      drupal_set_message(t('%module uninstalled.', array('%module' => $metadata['name'])));
     }
     else {
-      module_disable($key);
+      module_disable($module);
+      drupal_set_message(t('%module disabled.', array('%module' => $metadata['name'])));
     }
   }
 
-  module_list(TRUE, FALSE);
+  menu_rebuild();
+  return $_GET['q'];
+}
 
-  foreach ($new_modules as $module) {
-    drupal_install_module($module);
+function system_confirm_uninstall($module = NULL) {
+  if (!$module) {
+    return drupal_not_found();
   }
+  include_once './includes/install.inc';
+  $message = drupal_uninstall_module($module);
 
-  if (is_array($edit['throttle'])) {
-    foreach ($edit['throttle'] as $key => $choice) {
-      if ($choice) {
-        db_query("UPDATE {system} SET throttle = 1 WHERE type = 'module' and name = '%s'", $key);
-      }
-    }
+  if (!$message) {
+    return drupal_goto('admin/settings/modules/disabled');
   }
 
-  menu_rebuild();
-  node_types_rebuild();
-
-  drupal_set_message(t('The configuration options have been saved.'));
-  return 'admin/settings/modules';
+  $form['module'] = array('#type' => 'value', '#value' => $module);
+  return confirm_form($form,
+    t('Are you sure you want to uninstall @module?', array('@module' => $module)),
+    ($_GET['destination'] ? $_GET['destination'] : 'admin/settings/modules/disabled'),
+    '<p>'. $message .'</p>',
+    t('Uninstall'), t('Cancel')
+  );
 }
 
+function system_confirm_uninstall_submit($form_id, $form) {
+  if ($form['confirm']) {
+    include_once './includes/install.inc';
+    drupal_uninstall_module($form['module'], TRUE);
+    drupal_set_message(t('%module uninstalled.', array('%module' => $form['module'])));
+  }
+  return 'admin/settings/modules/disabled';
+}
 
 /**
  * Menu callback; displays a module's settings page.
Index: modules/taxonomy/taxonomy.meta
===================================================================
RCS file: modules/taxonomy/taxonomy.meta
diff -N modules/taxonomy/taxonomy.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/taxonomy/taxonomy.meta	24 Aug 2006 17:55:32 -0000
@@ -0,0 +1,6 @@
+name: Taxonomy
+description: Enables the categorization of content.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
+links: administer=admin/content/taxonomy
Index: modules/taxonomy/taxonomy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.308
diff -u -F^f -r1.308 taxonomy.module
--- modules/taxonomy/taxonomy.module	24 Aug 2006 06:29:50 -0000	1.308
+++ modules/taxonomy/taxonomy.module	24 Aug 2006 17:55:34 -0000
@@ -1331,8 +1331,6 @@ function taxonomy_help($section) {
 ', array('@admin-taxonomy-add-vocabulary' => url('admin/content/taxonomy/add/vocabulary'), '@admin-taxonomy' => url('admin/content/taxonomy'), '@external-http-drupal-org-project-taxonomy_access' => 'http://drupal.org/project/taxonomy_access', '@external-http-drupal-org-project-taxonomy_browser' => 'http://drupal.org/project/taxonomy_browser'));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@taxonomy">Taxonomy page</a>.', array('@taxonomy' => 'http://drupal.org/handbook/modules/taxonomy/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Enables the categorization of content.');
     case 'admin/content/taxonomy':
       return t('<p>The taxonomy module allows you to classify content into categories and subcategories; it allows multiple lists of categories for classification (controlled vocabularies) and offers the possibility of creating thesauri (controlled vocabularies that indicate the relationship of terms), taxonomies (controlled vocabularies where relationships are indicated hierarchically), and free vocabularies where terms, or tags, are defined during content creation. To view and manage the terms of each vocabulary, click on the associated <em>list terms</em> link. To delete a vocabulary and all its terms, choose "edit vocabulary".</p>');
     case 'admin/content/taxonomy/add/vocabulary':
Index: modules/throttle/throttle.install
===================================================================
RCS file: modules/throttle/throttle.install
diff -N modules/throttle/throttle.install
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/throttle/throttle.install	24 Aug 2006 17:55:34 -0000
@@ -0,0 +1,15 @@
+<?php
+// $Id:$
+
+/**
+ * Implementation of hook_uninstall.
+ * Delete all module variables.
+ */
+function throttle_uninstall() {
+  variable_del('throttle_level');
+  variable_del('throttle_probability_limiter');
+  variable_del('throttle_anonymous');
+  variable_del('throttle_user');
+}
+
+?>
Index: modules/throttle/throttle.meta
===================================================================
RCS file: modules/throttle/throttle.meta
diff -N modules/throttle/throttle.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/throttle/throttle.meta	24 Aug 2006 17:55:34 -0000
@@ -0,0 +1,6 @@
+name: Throttle
+description: Handles the auto-throttling mechanism, to control site congestion.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
+links: administer=admin/settings/throttle
Index: modules/throttle/throttle.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/throttle/throttle.module,v
retrieving revision 1.65
diff -u -F^f -r1.65 throttle.module
--- modules/throttle/throttle.module	18 Aug 2006 18:58:46 -0000	1.65
+++ modules/throttle/throttle.module	24 Aug 2006 17:55:34 -0000
@@ -14,10 +14,26 @@ function throttle_menu($may_cache) {
       'path' => 'admin/settings/throttle',
       'description' => t('Control how your site cuts out content during heavy load.'),
       'title' => t('throttle'),
+      'access' => user_access('administer site configuration'),
+      'callback' => 'drupal_get_form',
+      'callback arguments' => array('throttle_admin_modules'),
+      'type' => MENU_NORMAL_ITEM,
+    );
+    $items[] = array(
+      'path' => 'admin/settings/throttle/modules',
+      'title' => t('modules'),
+      'callback' => 'drupal_get_form',
+      'callback arguments' => array('throttle_admin_modules'),
+      'access' => user_access('administer site configuration'),
+      'type' => MENU_DEFAULT_LOCAL_TASK,
+    );
+    $items[] = array(
+      'path' => 'admin/settings/throttle/settings',
+      'title' => t('settings'),
       'callback' => 'drupal_get_form',
       'callback arguments' => array('throttle_admin_settings'),
       'access' => user_access('administer site configuration'),
-      'type' => MENU_NORMAL_ITEM
+      'type' => MENU_LOCAL_TASK,
     );
   }
 
@@ -133,8 +149,6 @@ function throttle_help($section) {
 ', array('@admin-modules' => url('admin/settings/modules'), '@admin-block' => url('admin/build/block'), '@admin-settings-throttle' => url('admin/settings/throttle')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@throttle">Throttle page</a>.', array('@throttle' => 'http://drupal.org/handbook/modules/throttle/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Handles the auto-throttling mechanism, to control site congestion.');
     case 'admin/settings/throttle':
       return t('If your site gets linked to by a popular website, or otherwise comes under a "Denial of Service" (DoS) attack, your webserver might become overwhelmed. This module provides a congestion control throttling mechanism for automatically detecting a surge in incoming traffic. This mechanism is utilized by other Drupal modules to automatically optimize their performance by temporarily disabling CPU-intensive functionality.');
   }
@@ -171,3 +185,65 @@ function throttle_admin_settings() {
 
   return system_settings_form($form);
 }
+
+function throttle_admin_modules() {
+  // Get current list of modules
+  $result = db_query("SELECT * FROM {system} WHERE type = 'module' AND status = 1");
+
+  $required = array('block', 'filter', 'node', 'system', 'user', 'watchdog', 'throttle');
+  while ($file = db_fetch_object($result)) {
+    if (!in_array($file->name, $required) && file_exists($file->filename)) {
+      $form['name'][$file->name] = array('#value' => $file->name);
+      $form['description'][$file->name] = array('#value' => $file->description);
+      $options[$file->name] = '';
+      $form['original'][$file->name] = array(
+        '#type' => 'value', 
+        '#value' => $file->throttle,
+      );
+      $form['original']['#tree'] = TRUE;
+      if ($file->throttle) {
+        $throttle[] = $file->name;
+      }
+    }
+  }
+
+  // Handle status checkboxes, including overriding the generated
+  // checkboxes for required modules.
+  $form['throttle'] = array('#type' => 'checkboxes', '#default_value' => $throttle, '#options' => $options);
+  foreach ($throttle_required as $require) {
+    $form['throttle'][$require] = array('#type' => 'hidden', '#value' => 0, '#suffix' => t('required'));
+  }
+
+  $form['buttons']['submit'] = array('#type' => 'submit', '#value' => t('Save configuration'));
+
+  return $form;
+}
+
+function theme_throttle_admin_modules($form) {
+  foreach (element_children($form['name']) as $key) {
+    $row = array();
+    $row[] = drupal_render($form['name'][$key]);
+    $row[] = drupal_render($form['description'][$key]);
+    $row[] = array('data' => drupal_render($form['throttle'][$key]), 'align' => 'center');
+    $rows[] = $row;
+  }
+
+  $header = array(t('Name'), t('Description'), t('Throttle'));
+
+  $output = theme('table', $header, $rows);
+  $output .= drupal_render($form);
+  return $output;
+}
+
+function throttle_admin_modules_submit($form_id, $edit) {
+  foreach ($edit['throttle'] as $key => $choice) {
+    if ($choice && !$edit['original'][$key]) {
+      db_query("UPDATE {system} SET throttle = 1 WHERE type = 'module' and name = '%s'", $key);
+    }
+    else if (!$choice && $edit['original'][$key]) {
+      db_query("UPDATE {system} SET throttle = 0 WHERE type = 'module' and name = '%s'", $key);
+    }
+  }
+  
+  drupal_set_message(t('The configuration has been saved.'));
+}
Index: modules/tracker/tracker.meta
===================================================================
RCS file: modules/tracker/tracker.meta
diff -N modules/tracker/tracker.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/tracker/tracker.meta	24 Aug 2006 17:55:34 -0000
@@ -0,0 +1,6 @@
+name: Tracker
+description: Enables tracking of recent posts for users.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
+links: recent posts=tracker
Index: modules/tracker/tracker.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/tracker/tracker.module,v
retrieving revision 1.135
diff -u -F^f -r1.135 tracker.module
--- modules/tracker/tracker.module	20 Aug 2006 05:57:41 -0000	1.135
+++ modules/tracker/tracker.module	24 Aug 2006 17:55:34 -0000
@@ -23,8 +23,6 @@ function tracker_help($section) {
 ', array('@tracker' => url('tracker'), '@profile' => url('profile')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@tracker">Tracker page</a>.', array('@tracker' => 'http://drupal.org/handbook/modules/tracker/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Enables tracking of recent posts for users.');
   }
 }
 
Index: modules/upload/upload.install
===================================================================
RCS file: modules/upload/upload.install
diff -N modules/upload/upload.install
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/upload/upload.install	24 Aug 2006 17:55:34 -0000
@@ -0,0 +1,16 @@
+<?php
+// $Id:$
+
+/**
+ * Implementation of hook_uninstall.
+ * Delete all module variables.
+ */
+function upload_uninstall() {
+  variable_del('upload_extensions_default');
+  variable_del('upload_uploadsize_default');
+  variable_del('upload_usersize_default');
+  variable_del('upload_max_resolution');
+  variable_del('upload_list_default');
+}
+
+?>
Index: modules/upload/upload.meta
===================================================================
RCS file: modules/upload/upload.meta
diff -N modules/upload/upload.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/upload/upload.meta	24 Aug 2006 17:55:34 -0000
@@ -0,0 +1,6 @@
+name: Upload
+description: Allows users to upload and attach files to content.
+package: Drupal core modules
+version: SYSTEM
+drupal: 4.8
+links: settings=admin/settings/uploads
Index: modules/upload/upload.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/upload/upload.module,v
retrieving revision 1.121
diff -u -F^f -r1.121 upload.module
--- modules/upload/upload.module	22 Aug 2006 11:13:04 -0000	1.121
+++ modules/upload/upload.module	24 Aug 2006 17:55:35 -0000
@@ -24,8 +24,6 @@ function upload_help($section) {
 ', array('@admin-access' => url('admin/user/access'), '@admin-content-types' => url('admin/settings/types'), '@admin-upload' => url('admin/settings/upload')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@upload">Upload page</a>.', array('@upload' => 'http://drupal.org/handbook/modules/upload/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Allows users to upload and attach files to content.');
     case 'admin/settings/upload':
       return t('<p>Users with the <a href="@permissions">upload files permission</a> can upload attachments. Users with the <a href="@permissions">view uploaded files permission</a> can view uploaded attachments. You can choose which post types can take attachments on the <a href="@types">content types settings</a> page.</p>', array('@permissions' => url('admin/user/access'), '@types' => url('admin/settings/types')));
   }
Index: modules/user/user.meta
===================================================================
RCS file: modules/user/user.meta
diff -N modules/user/user.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/user/user.meta	24 Aug 2006 17:55:35 -0000
@@ -0,0 +1,7 @@
+name: User
+description: Manages the user registration and login system.
+package: Required modules
+version: SYSTEM
+drupal: 4.8
+links: administer=admin/user, settings=admin/user/settings, user account=user
+
Index: modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.660
diff -u -F^f -r1.660 user.module
--- modules/user/user.module	24 Aug 2006 09:14:19 -0000	1.660
+++ modules/user/user.module	24 Aug 2006 17:55:37 -0000
@@ -2269,8 +2269,6 @@ function user_help($section) {
 ', array('@user' => url('user'), '@admin-user' => url('admin/user/user'), '@admin-themes' => url('admin/build/themes'), '@admin-help-profile' => url('admin/help/profile'), '@admin-help-system' => url('admin/help/system')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@user">User page</a>.', array('@user' => 'http://drupal.org/handbook/modules/user/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Manages the user registration and login system.');
     case 'admin/user/user':
       return t('<p>Drupal allows users to register, login, log out, maintain user profiles, etc. Users of the site may not use their own names to post content until they have signed up for a user account.</p>');
     case 'admin/user/user/create':
Index: modules/watchdog/watchdog.meta
===================================================================
RCS file: modules/watchdog/watchdog.meta
diff -N modules/watchdog/watchdog.meta
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/watchdog/watchdog.meta	24 Aug 2006 17:55:37 -0000
@@ -0,0 +1,6 @@
+name: Watchdog
+description: Logs and records system events.
+package: Required modules
+version: SYSTEM
+drupal: 4.8
+links: view logs=admin/logs/watchdog
Index: modules/watchdog/watchdog.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/watchdog/watchdog.module,v
retrieving revision 1.151
diff -u -F^f -r1.151 watchdog.module
--- modules/watchdog/watchdog.module	23 Aug 2006 18:16:45 -0000	1.151
+++ modules/watchdog/watchdog.module	24 Aug 2006 17:55:37 -0000
@@ -28,8 +28,6 @@ function watchdog_help($section) {
 ', array('@admin-watchdog' => url('admin/logs/watchdog'), '@admin-watchdog-events' => url('admin/logs/watchdog/events')));
       $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="@watchdog">Watchdog page</a>.', array('@watchdog' => 'http://drupal.org/handbook/modules/watchdog/')) .'</p>';
       return $output;
-    case 'admin/settings/modules#description':
-      return t('Logs and records system events.');
     case 'admin/logs':
       return t('<p>The watchdog module monitors your web site, capturing system events in a log to be reviewed by an authorized individual at a later time. The watchdog log is simply a list of recorded events containing usage data, performance data, errors, warnings and operational information. It is vital to check the watchdog report on a regular basis as it is often the only way to tell what is going on.</p>');
   }
