Index: includes/module.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/module.inc,v
retrieving revision 1.85
diff -u -F^f -r1.85 module.inc
--- includes/module.inc	31 Aug 2006 22:12:15 -0000	1.85
+++ includes/module.inc	7 Sep 2006 17:04:15 -0000
@@ -159,6 +159,9 @@ function _module_parse_info_file($filena
   if (file_exists($filename)) {
     $info = parse_ini_file($filename);
   }
+  if(isset($info['dependencies'])) {
+    $info['dependencies'] = explode(" ", $info['dependencies']);
+  }  
   return $info;
 }
 
Index: modules/forum/forum.info
===================================================================
RCS file: /cvs/drupal/drupal/modules/forum/forum.info,v
retrieving revision 1.1
diff -u -F^f -r1.1 forum.info
--- modules/forum/forum.info	31 Aug 2006 20:22:35 -0000	1.1
+++ modules/forum/forum.info	7 Sep 2006 17:04:25 -0000
@@ -1,4 +1,4 @@
 ; $Id: forum.info,v 1.1 2006/08/31 20:22:35 dries Exp $
 name = Forum
 description = Enables threaded discussions about general topics.
-
+dependencies = taxonomy comment
Index: modules/system/admin.css
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/admin.css,v
retrieving revision 1.7
diff -u -F^f -r1.7 admin.css
--- modules/system/admin.css	6 Sep 2006 08:35:59 -0000	1.7
+++ modules/system/admin.css	7 Sep 2006 17:04:30 -0000
@@ -39,6 +39,11 @@
   padding-right: 4px;
 }
 
+div.admin-missing, div.admin-required {
+  font-size:  0.9em;
+  color: #444;
+}
+
 /**
  * Formatting for status report
  */
@@ -63,3 +68,4 @@
 table.system-status-report tr.ok th {
   background-image: url('../../misc/watchdog-ok.png');
 }
+
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.367
diff -u -F^f -r1.367 system.module
--- modules/system/system.module	7 Sep 2006 08:03:08 -0000	1.367
+++ modules/system/system.module	7 Sep 2006 17:04:32 -0000
@@ -1217,49 +1217,191 @@ function system_themes_submit($form_id, 
 }
 
 /**
- * Menu callback; displays a listing of all modules.
+ * Menu callback; provides module enable/disable interface.
+ * 
+ * Modules can be enabled or disabled and set for throttling if the throttle module is enabled. 
+ * The list of modules gets populated by module.info files, which contain each module's name
+ * and description. 
+ *
+ * Dependency checking is performed both forward and reverse to enforce that both dependents and
+ * dependencies are availible. Dependencies are added to the info file space delimited.
+ * 
+ * Example of .info file:
+ *   name = Forum
+ *   description = Enables threaded discussions about general topics.
+ *   dependencies = taxonomy comment
+ * 
+ * @return 
+ *    The form array.
  */
 function system_modules() {
-  // Get current list of modules
+  // Get current list of modules.
   $files = module_rebuild_cache();
+  
+  // Store information for validation hook.
+  $form['validation_modules'] = array('#type' => 'value', '#value' => array());
+  
+  //Create store for disabled modules as browser will not. 
+  $form['disabled_modules'] = array('#type' => 'value', '#value' => array());
 
+  $dependents = array();
+  // Traverse the files retrieved and build the form.
   foreach ($files as $filename => $file) {
-    $info = $file->info;
-    $form['name'][$file->name] = array('#value' => $info['name']);
-    $form['description'][$file->name] = array('#value' => t($info['description']));
-    $options[$file->name] = '';
+    // Populate validation list with only the necessities to save on session space. 	
+    $form['validation_modules']['#value'][$filename]['name'] = $file->info['name']; 
+    $form['validation_modules']['#value'][$filename]['dependencies'] = $file->info['dependencies'];
+    $form['validation_modules']['#value'][$filename]['status'] = $file->status;
+     	
+    $form['name'][$filename] = array('#value' => $file->info['name']);
+    $form['description'][$filename] = array('#value' => t($file->info['description']));
+    $options[$filename] = '';
     if ($file->status) {
       $status[] = $file->name;
     }
     if ($file->throttle) {
       $throttle[] = $file->name;
     }
+
+    $missing_dependencies = array();
+    // Check missing dependencies.
+    if (is_array($file->info['dependencies'])) {
+      foreach ($file->info['dependencies'] as $dependency) {
+        if (!isset($files[$dependency]) || !$files[$dependency]->status) {
+          $disabled[] = $filename;
+          if (isset($files[$dependency])) {
+            $missing_dependencies[] = $files[$dependency]->info['name']; 
+          } else {
+            $missing_dependencies[] = l($dependency, 'http://drupal.org/project/'. $dependency);	
+          } 
+        }
+        elseif ($file->status) {
+          $disabled[] = $dependency;
+          $dependents[$dependency][] = $file->info['name'];
+          $form['disabled_modules']['#value'][$dependency] = $file->status; 
+        }
+      }
+
+      // Add text for missing dependencies.
+      if (!empty($missing_dependencies)) {
+        $form['description'][$filename]['missing_dependencies'] = array(
+          '#value' => t('Missing dependencies: !missing_dependencies', 
+            array('!missing_dependencies' => implode(', ', $missing_dependencies))
+          ),
+          '#prefix' => '<div class="admin-missing">',
+          '#suffix' => '</div>',
+        );
+      }
+    }
+  }
+
+
+  // Add dependent descriptions if any
+  foreach ($dependents as $filename => $dependency) {
+    $form['description'][$filename]['required'] = array(
+      '#value' => t('Required by: @required', 
+        array('@required' => implode(', ', $dependency))
+      ),
+      '#prefix' => '<div class="admin-required">',
+      '#suffix' => '</div>',
+    );
   }
 
-  // Handle status checkboxes, including overriding the generated
-  // checkboxes for required modules.
-  $form['status'] = array('#type' => 'checkboxes', '#default_value' => $status, '#options' => $options);
+  // Handle status checkboxes, including overriding 
+  // the generated checkboxes for required modules.
+  $form['status'] = array(
+    '#type' => 'checkboxes', 
+    '#default_value' => $status, 
+    '#options' => $options, 
+    '#process' => array( 
+      'expand_checkboxes' => array(), 
+      'system_module_disable' => array($disabled),
+    ),
+  );
   $required = array('block', 'filter', 'node', 'system', 'user', 'watchdog');
   foreach ($required as $require) {
-    $form['status'][$require] = array('#type' => 'hidden', '#value' => 1, '#suffix' => t('required'));
+    $form['status'][$require] = array(
+      '#type' => 'hidden', 
+      '#value' => 1, 
+      '#suffix' => t('required'),
+    );
   }
 
-  /**
-   * Handle throttle checkboxes, including overriding the generated checkboxes for required modules.
-   */
+  // 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);
+    $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'));
+      $form['throttle'][$require] = array(
+        '#type' => 'hidden', 
+        '#value' => 0, 
+        '#suffix' => t('required'),
+      );
     }
   }
 
-  $form['buttons']['submit'] = array('#type' => 'submit', '#value' => t('Save configuration'));
+  $form['buttons']['submit'] = array(
+    '#type' => 'submit', 
+    '#value' => t('Save configuration'),
+  );
 
   return $form;
 }
 
+/**
+ * Form process callback function to disbale check boxes.
+ */
+function system_module_disable($form, $form_values, $disabled) {
+  foreach ($disabled as $key) {
+    $form[$key]['#attributes']['disabled'] = 'disabled';
+  }
+  return $form;
+}
+
+/**
+ * Valiate callback; performs dependency integrity checks to ensure that modules don't get added
+ * if dependencies fail.
+ */
+function system_modules_validate($form_id, $form_values, $form) {
+  // Recheck values for submitted dependency errors.
+  foreach ($form_values['validation_modules'] as $name => $module) {
+    $failed_dependencies = array();
+    // Does module have dependencies.
+    if (!$module['status'] && $form_values['status'][$name] && is_array($module['dependencies'])) {
+      foreach ($module['dependencies'] as $dependency) {
+        // Check if dependendency is enabled on the form.
+        if (!($form_values['status'][$dependency])) {
+          // Give appropriate task to enable dependency.
+          $failed_dependencies['tasks'][] = t('Please enable the %dependent module to continue.', 
+            array('%dependent' => $form_values['validation_modules'][$dependency]['name'])
+          );
+          $failed_dependencies['dependencies'][] = $form_values['validation_modules'][$dependency]['name'];
+        }
+      }
+    }
+    if (!empty($failed_dependencies)) {
+      form_set_error("status][$name", 
+        t('Could not enable the %module module, as it depends on %dependency.', 
+          array(
+            '%module' => $form_values['validation_modules'][$name]['name'], 
+            '%dependency' => implode(', ', $failed_dependencies['dependencies']),
+          )
+        )
+      );
+      foreach ($failed_dependencies['tasks'] as $task) {
+        drupal_set_message($task, 'error');
+      }
+    }
+  }
+}
+
+/**
+ * Theme call back for the modules form.
+ */
 function theme_system_modules($form) {
   foreach (element_children($form['name']) as $key) {
     $row = array();
@@ -1285,13 +1427,18 @@ function theme_system_modules($form) {
   return $output;
 }
 
-
+/**
+ * Submit callback; handles modules form submission.
+ */
 function system_modules_submit($form_id, $edit) {
   include_once './includes/install.inc';
   $new_modules = array();
 
-  // Enable/disable modules that have already been installed
-  foreach ($edit['status'] as $key => $choice) {
+  // Merge in disabled active modules since they should be enabled.
+  // They don't appear because disabled checkboxes are not submited
+  // by browsers.
+  $modules = array_merge($edit['status'], $edit['disabled_modules']);
+  foreach ($modules as $key => $choice) {
     if ($choice) {
       if (drupal_get_installed_schema_version($key) == SCHEMA_UNINSTALLED) {
         $new_modules[] = $key;
