diff --git includes/install.inc includes/install.inc
index 7cc2439..21fdf87 100644
--- includes/install.inc
+++ includes/install.inc
@@ -531,52 +531,6 @@ function drupal_verify_profile($install_state) {
 }
 
 /**
- * Calls the install function for a given list of modules.
- *
- * @param $module_list
- *   The modules to install.
- * @param $disable_modules_installed_hook
- *   Normally just testing wants to set this to TRUE.
- * 
- * @return
- *   TRUE if installation was attempted, FALSE if one or more dependencies are
- *   missing.
- */
-function drupal_install_modules($module_list = array(), $disable_modules_installed_hook = FALSE) {
-  $files = system_rebuild_module_data();
-  $module_list = array_flip(array_values($module_list));
-  do {
-    $moved = FALSE;
-    foreach ($module_list as $module => $weight) {
-      $file = $files[$module];
-      if (isset($file->info['dependencies']) && is_array($file->info['dependencies'])) {
-        foreach ($file->info['dependencies'] as $dependency) {
-          if (!isset($module_list[$dependency])) {
-            if (!isset($files[$dependency])) {
-              // A dependency was not found, abort installation.
-              return FALSE;
-            }
-            elseif (!$files[$dependency]->status) {
-              // Add dependencies to $module_list and install them first.
-              $module_list[$dependency] = $weight - 1;
-              $moved = TRUE;
-            }
-          }
-          elseif ($module_list[$module] < $module_list[$dependency] +1) {
-            $module_list[$module] = $module_list[$dependency] +1;
-            $moved = TRUE;
-          }
-        }
-      }
-    }
-  } while ($moved);
-  asort($module_list);
-  $module_list = array_keys($module_list);
-  module_enable($module_list, $disable_modules_installed_hook);
-  return TRUE;
-}
-
-/**
  * Callback to install an individual install profile module.
  *
  * Used during installation to install modules one at a time and then
diff --git includes/module.inc includes/module.inc
index 2fb4379..254b4b9 100644
--- includes/module.inc
+++ includes/module.inc
@@ -289,49 +289,62 @@ function module_load_all_includes($type, $name = NULL) {
  *   An array of module names.
  * @param $disable_modules_installed_hook
  *   Normally just testing wants to set this to TRUE.
+ * @param $check_dependencies
+ *   If FALSE, dependency checks will be skipped.
+ *
+ * @return
+ *   FALSE if one or more dependencies are missing, TRUE otherwise.
  */
-function module_enable($module_list, $disable_modules_installed_hook = FALSE) {
-  $invoke_modules = array();
+function module_enable($module_list, $disable_modules_installed_hook = FALSE, $check_dependencies = TRUE) {
+  if ($check_dependencies) {
+    // Get all module data so we can find dependencies and sort.
+    $module_data = system_rebuild_module_data();
+    // Create an associative array with weights as values.
+    $module_list = array_flip(array_values($module_list));
+
+    while (list($module) = each($module_list)) {
+      if (!isset($module_data[$module])) {
+        // This module is not found in the filesystem, abort.
+        return FALSE;
+      }
+      if ($module_data[$module]->status) {
+        // Skip already enabled modules.
+        unset($module_list[$module]);
+        continue;
+      }
+      $module_list[$module] = $module_data[$module]->sort;
 
-  // Try to install the enabled modules and collect which were installed.
-  // $module_list is not changed and already installed modules are ignored.
-  $modules_installed = array_filter($module_list, '_drupal_install_module');
-  foreach ($module_list as $module) {
-    $existing = db_query("SELECT status FROM {system} WHERE type = :type AND name = :name", array(
-      ':type' => 'module',
-      ':name' => $module))
-      ->fetchObject();
-    if ($existing->status == 0) {
-      module_load_install($module);
-      db_update('system')
-        ->fields(array('status' => 1))
-        ->condition('type', 'module')
-        ->condition('name', $module)
-        ->execute();
-      drupal_load('module', $module);
-      $invoke_modules[] = $module;
-      watchdog('system', '%module module enabled.', array('%module' => $module), WATCHDOG_INFO);
+      // Add dependencies to the module list.
+      foreach ($module_data[$module]->info['dependencies'] as $dependency) {
+        if (!isset($module_list[$dependency])) {
+          $module_list[$dependency] = 0;
+        }
+      }
     }
-  }
-
-  if (!empty($invoke_modules)) {
-    // Refresh the module list to exclude the disabled modules.
-    system_list_reset();
-    module_list(TRUE);
-    module_implements('', FALSE, TRUE);
-    // Update the registry to include the new enabled module.
-    registry_update();
-    // Refresh the schema to include the new enabled module.
-    drupal_get_schema(NULL, TRUE);
 
-    // If any modules were newly installed, execute the hook for them.
-    if (!$disable_modules_installed_hook && !empty($modules_installed)) {
-      module_invoke_all('modules_installed', $modules_installed);
+    if (!$module_list) {
+      return TRUE;
     }
+
+    // Sort the module list by pre-calculated weights.
+    arsort($module_list);
+    $module_list = array_keys($module_list);
   }
 
-  foreach ($invoke_modules as $module) {
-    module_invoke($module, 'enable');
+  // Make sure the installation API is available.
+  include_once DRUPAL_ROOT . '/includes/install.inc';
+
+  // Try to install each module and collect which were installed.
+  $modules_installed = array_filter($module_list, '_drupal_install_module');
+
+  foreach ($module_list as $module) {
+    db_update('system')
+      ->fields(array('status' => 1))
+      ->condition('type', 'module')
+      ->condition('name', $module)
+      ->execute();
+    drupal_load('module', $module);
+    module_load_install($module);
     // Check if node_access table needs rebuilding.
     // We check for the existence of node_access_needs_rebuild() since
     // at install time, module_enable() could be called while node.module
@@ -341,11 +354,26 @@ function module_enable($module_list, $disable_modules_installed_hook = FALSE) {
     }
   }
 
-  if (!empty($invoke_modules)) {
-    // Invoke hook_modules_enabled after all the modules have been
-    // enabled.
-    module_invoke_all('modules_enabled', $invoke_modules);
+  // Refresh lists and caches to include the enabled module(s).
+  system_list_reset();
+  module_list(TRUE);
+  module_implements('', FALSE, TRUE);
+  registry_update();
+  if (!empty($modules_installed)) {
+    drupal_get_schema(NULL, TRUE);
   }
+
+  // Invoke necessary hooks.
+  if (!empty($modules_installed) && !$disable_modules_installed_hook) {
+    module_invoke_all('modules_installed', $modules_installed);
+  }
+  foreach ($module_list as $module) {
+    module_invoke($module, 'enable');
+    watchdog('system', '%module module enabled.', array('%module' => $module), WATCHDOG_INFO);
+  }
+  module_invoke_all('modules_enabled', $module_list);
+
+  return TRUE;
 }
 
 /**
@@ -353,39 +381,63 @@ function module_enable($module_list, $disable_modules_installed_hook = FALSE) {
  *
  * @param $module_list
  *   An array of module names.
+ * @param $check_dependencies
+ *   If TRUE, $module_list will be processed for dependents.
  */
-function module_disable($module_list) {
-  $invoke_modules = array();
-  foreach ($module_list as $module) {
-    if (module_exists($module)) {
-      // Check if node_access table needs rebuilding.
-      if (!node_access_needs_rebuild() && module_hook($module, 'node_grants')) {
-        node_access_needs_rebuild(TRUE);
+function module_disable($module_list, $check_dependencies = FALSE) {
+  if ($check_dependencies) {
+    // Get all module data so we can find dependents and sort.
+    $module_data = system_rebuild_module_data();
+    // Create an associative array with weights as values.
+    $module_list = array_flip(array_values($module_list));
+
+    while (list($module) = each($module_list)) {
+      if (!isset($module_data[$module]) || !$module_data[$module]->status) {
+        // This module doesn't exist or is already disabled, skip it.
+        unset($module_list[$module]);
+        continue;
       }
+      $module_list[$module] = $module_data[$module]->sort;
 
-      module_load_install($module);
-      module_invoke($module, 'disable');
-      db_update('system')
-        ->fields(array('status' => 0))
-        ->condition('type', 'module')
-        ->condition('name', $module)
-        ->execute();
-      $invoke_modules[] = $module;
-      watchdog('system', '%module module disabled.', array('%module' => $module), WATCHDOG_INFO);
+      // Add dependent modules.
+      foreach ($module_data[$module]->required_by as $dependent => $dependent_data) {
+        if (!isset($module_list[$dependent]) && !strstr($module_data[$dependent]->filename, '.profile')) {
+          $module_list[$dependent] = 0;
+        }
+      }
+    }
+
+    // Sort the module list by pre-calculated weights.
+    asort($module_list);
+    $module_list = array_keys($module_list);
+  }
+
+  foreach ($module_list as $module) {
+    // Check if node_access table needs rebuilding.
+    if (!node_access_needs_rebuild() && module_hook($module, 'node_grants')) {
+      node_access_needs_rebuild(TRUE);
     }
+    module_load_install($module);
+    module_invoke($module, 'disable');
+    db_update('system')
+      ->fields(array('status' => 0))
+      ->condition('type', 'module')
+      ->condition('name', $module)
+      ->execute();
+    watchdog('system', '%module module disabled.', array('%module' => $module), WATCHDOG_INFO);
   }
 
-  if (!empty($invoke_modules)) {
-    // Refresh the module list to exclude the disabled modules.
-    system_list_reset();
-    module_list(TRUE);
-    module_implements('', FALSE, TRUE);
-    // Invoke hook_modules_disabled before disabling modules,
-    // so we can still call module hooks to get information.
-    module_invoke_all('modules_disabled', $invoke_modules);
-    // Update the registry to remove the newly-disabled module.
-    registry_update();
+  // Refresh the module list to exclude the disabled modules.
+  system_list_reset();
+  module_list(TRUE);
+  module_implements('', FALSE, TRUE);
+  // Invoke hook_modules_disabled before disabling modules,
+  // so we can still call module hooks to get information.
+  if ($module_list) {
+    module_invoke_all('modules_disabled', $module_list);
   }
+  // Update the registry to remove the newly-disabled module.
+  registry_update();
 
   // If there remains no more node_access module, rebuilding will be
   // straightforward, we can do it right now.
diff --git install.php install.php
index bc8cb11..bc57f07 100644
--- install.php
+++ install.php
@@ -1709,7 +1709,7 @@ function install_configure_form_submit($form, &$form_state) {
 
   // Enable update.module if this option was selected.
   if ($form_state['values']['update_status_module'][1]) {
-    drupal_install_modules(array('update'));
+    module_enable(array('update'));
  
     // Add the site maintenance account's email address to the list of
     // addresses to be notified when updates are available, if selected.
diff --git modules/simpletest/drupal_web_test_case.php modules/simpletest/drupal_web_test_case.php
index 266ffcd..35524cc 100644
--- modules/simpletest/drupal_web_test_case.php
+++ modules/simpletest/drupal_web_test_case.php
@@ -1141,13 +1141,13 @@ class DrupalWebTestCase extends DrupalTestCase {
     $profile_details = install_profile_info('default', 'en');
 
     // Install the modules specified by the default profile.
-    drupal_install_modules($profile_details['dependencies'], TRUE);
+    module_enable($profile_details['dependencies'], TRUE);
 
     drupal_static_reset('_node_types_build');
 
     if ($modules = func_get_args()) {
       // Install modules needed for this test.
-      drupal_install_modules($modules, TRUE);
+      module_enable($modules, TRUE, TRUE);
     }
 
     // Because the schema is static cached, we need to flush
@@ -1158,7 +1158,7 @@ class DrupalWebTestCase extends DrupalTestCase {
 
     // Run default profile tasks.
     $install_state = array();
-    drupal_install_modules(array('default'), TRUE);
+    module_enable(array('default'), TRUE);
 
     // Rebuild caches.
     node_types_rebuild();
diff --git modules/simpletest/tests/module.test modules/simpletest/tests/module.test
index 5f3b584..2c9a862 100644
--- modules/simpletest/tests/module.test
+++ modules/simpletest/tests/module.test
@@ -37,7 +37,7 @@ class ModuleUnitTest extends DrupalWebTestCase {
     $this->assertModuleList($module_list, t('Default profile'));
 
     // Try to install a new module.
-    drupal_install_modules(array('contact'));
+    module_enable(array('contact'));
     $module_list[] = 'contact';
     sort($module_list);
     $this->assertModuleList($module_list, t('After adding a module'));
@@ -101,25 +101,25 @@ class ModuleUnitTest extends DrupalWebTestCase {
   }
 
   /**
-   * Test drupal_install_modules() and dependency resolution.
+   * Test dependency resolution.
    */
-  function testDrupalInstallModules() {
-    drupal_install_modules(array('module_test'));
+  function testDependencyResolution() {
+    module_enable(array('module_test'));
     $this->assertTrue(module_exists('module_test'), t('Test module is enabled.'));
 
     // First, create a fake missing dependency. Forum depends on poll, which
     // depends on a made-up module, foo. Nothing should be installed.
     variable_set('dependency_test', 'missing dependency');
-    $result = drupal_install_modules(array('forum'));
-    $this->assertFalse($result, t('drupal_install_modules() returns FALSE if dependencies are missing.'));
-    $this->assertFalse(module_exists('forum'), t('drupal_install_modules() aborts if dependencies are missing.'));
+    $result = module_enable(array('forum'), TRUE, TRUE);
+    $this->assertFalse($result, t('module_enable() returns FALSE if dependencies are missing.'));
+    $this->assertFalse(module_exists('forum'), t('module_enable() aborts if dependencies are missing.'));
 
-    // Now, fix the missing dependency. drupal_install_modules() should work.
+    // Now, fix the missing dependency. module_enable() should work.
     variable_set('dependency_test', 'dependency');
-    $result = drupal_install_modules(array('forum'));
-    $this->assertTrue($result, t('drupal_install_modules() returns the correct value.'));
+    $result = module_enable(array('forum'), TRUE, TRUE);
+    $this->assertTrue($result, t('module_enable() returns the correct value.'));
     // Verify that the fake dependency chain was installed.
-    $this->assertTrue(module_exists('poll') && module_exists('php'), t('Dependency chain was installed by drupal_install_modules().'));
+    $this->assertTrue(module_exists('poll') && module_exists('php'), t('Dependency chain was installed by module_enable().'));
     // Finally, verify that the original module was installed.
     $this->assertTrue(module_exists('forum'), t('Module installation with unlisted dependencies succeeded.'));
   }
diff --git modules/system/system.admin.inc modules/system/system.admin.inc
index f36e018..f21c5f2 100644
--- modules/system/system.admin.inc
+++ modules/system/system.admin.inc
@@ -1229,7 +1229,7 @@ function system_modules_submit($form, &$form_state) {
       $sort[$module] = $files[$module]->sort;
     }
     array_multisort($sort, $new_modules);
-    drupal_install_modules($new_modules);
+    module_enable($new_modules);
   }
 
   $current_module_list = module_list(TRUE);
diff --git modules/system/system.install modules/system/system.install
index 2d3b992..86179a5 100644
--- modules/system/system.install
+++ modules/system/system.install
@@ -2090,7 +2090,6 @@ function system_update_7018() {
  */
 function system_update_7020() {
   $module_list = array('field_sql_storage', 'field');
-  drupal_install_modules($module_list);
   module_enable($module_list);
 }
 
@@ -2356,7 +2355,6 @@ function system_update_7027() {
     ->condition('type', 'module')
     ->condition('name', $module_list)
     ->execute();
-  drupal_install_modules($module_list);
   module_enable($module_list);
 }
 
