diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index 00c4c41..b5adee7 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -855,7 +855,6 @@ function system_modules($form, $form_state = array()) {
       if (isset($visible_files[$required_by])) {
         if ($files[$required_by]->status == 1 && $module->status == 1) {
           $extra['required_by'][] = t('@module (<span class="admin-enabled">enabled</span>)', array('@module' => $files[$required_by]->info['name']));
-          $extra['disabled'] = TRUE;
         }
         else {
           $extra['required_by'][] = t('@module (<span class="admin-disabled">disabled</span>)', array('@module' => $files[$required_by]->info['name']));
@@ -1028,13 +1027,21 @@ function system_modules_confirm_form($modules, $storage) {
     $items[] = format_plural(count($info['depends']), 'The @module module is missing, so the following module will be disabled: @depends.', 'The @module module is missing, so the following modules will be disabled: @depends.', $t_argument);
   }
 
+  foreach ($storage['more_disable'] as $info) {
+    $t_argument = array(
+      '@module' => $info['name'],
+      '@disable' => implode(', ', $info['required_by']),
+    );
+    $items[] = format_plural(count($info['required_by']), 'You must disable the @disable module to disable @module.', 'You must disable the @disable modules to disable @module.', $t_argument);
+  }
+
   $form['text'] = array('#markup' => theme('item_list', array('items' => $items)));
 
   if ($form) {
     // Set some default form values
     $form = confirm_form(
       $form,
-      t('Some required modules must be enabled'),
+      t('Some required modules must be enabled or disabled'),
       'admin/modules',
       t('Would you like to continue with the above?'),
       t('Continue'),
@@ -1078,9 +1085,11 @@ function system_modules_submit($form, &$form_state) {
 
   // Makes sure all required modules are set to be enabled.
   $more_required = array();
+  // Make sure all dependent modules are set to be disabled.
+  $more_disable = array();
   $missing_modules = array();
   foreach ($modules as $name => $module) {
-    if ($module['enabled']) {
+    if ($module['enabled'] && empty($more_disable[$name])) {
       // Checks that all dependencies are set to be enabled.  Stores the ones
       // that are not in $dependencies variable so that the user can be alerted
       // in the confirmation form that more modules need to be enabled.
@@ -1106,12 +1115,34 @@ function system_modules_submit($form, &$form_state) {
         );
       }
     }
+    elseif (empty($module['enabled']) && $files[$name]->status) {
+      // Check that all dependants are set to be disabled.
+      $dependants = array();
+      foreach (array_keys($files[$name]->required_by) as $required_by) {
+        if (!empty($modules[$required_by]['enabled'])) {
+          if (isset($files[$required_by])) {
+            $dependants[] = $files[$required_by]->info['name'];
+            $modules[$required_by]['enabled'] = FALSE;
+            unset($more_required[$required_by]);
+          }
+        }
+      }
+      $modules[$name]['enabled'] = FALSE;
+      // Stores additional modules that need to be disabled in $more_disable.
+      if (!empty($dependants)) {
+        $more_disable[$name] = array(
+          'name' => $files[$name]->info['name'],
+          'required_by' => $dependants,
+        );
+      }
+    }
   }
 
-  // Redirects to confirmation form if more modules need to be enabled.
-  if ((!empty($more_required) || !empty($missing_modules)) && !isset($form_state['values']['confirm'])) {
+  // Redirects to confirmation form if more modules need to be enabled/disabled.
+  if ((!empty($more_required) || !empty($more_disable) || !empty($missing_modules)) && !isset($form_state['values']['confirm'])) {
     $form_state['storage'] = array(
       'more_required' => $more_required,
+      'more_disable' => $more_disable,
       'modules' => $modules,
       'missing_modules' => $missing_modules,
     );
diff --git a/core/modules/system/system.test b/core/modules/system/system.test
index ba7003d..be2a1bf 100644
--- a/core/modules/system/system.test
+++ b/core/modules/system/system.test
@@ -351,7 +351,7 @@ class ModuleDependencyTestCase extends ModuleTestCase {
   public static function getInfo() {
     return array(
       'name' => 'Module dependencies',
-      'description' => 'Enable module without dependency enabled.',
+      'description' => 'Enable module without dependency enabled, disable module with dependent enabled.',
       'group' => 'Module',
     );
   }
@@ -364,7 +364,7 @@ class ModuleDependencyTestCase extends ModuleTestCase {
     $edit = array();
     $edit['modules[Core][translation][enable]'] = 'translation';
     $this->drupalPost('admin/modules', $edit, t('Save configuration'));
-    $this->assertText(t('Some required modules must be enabled'), t('Dependency required.'));
+    $this->assertText(t('Some required modules must be enabled or disabled'), t('Dependency required.'));
 
     $this->assertModules(array('translation', 'locale', 'language'), FALSE);
 
@@ -523,6 +523,68 @@ class ModuleDependencyTestCase extends ModuleTestCase {
     $this->drupalPost(NULL, NULL, t('Uninstall'));
     $this->assertText(t('The selected modules have been uninstalled.'), t('Modules status has been updated.'));
   }
+
+  /**
+  * Attempt to disable locale module with translation enabled.
+  */
+  function testDisableWithDependency() {
+    module_enable(array('translation'), TRUE);
+    $edit = array();
+    $edit['modules[Core][locale][enable]'] = FALSE;
+    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
+    $this->assertText(t('Some required modules must be enabled or disabled'), t('Dependency must be disabled.'));
+
+    $this->assertModules(array('translation', 'locale'), TRUE);
+
+    $this->drupalPost(NULL, NULL, t('Continue'));
+    $this->assertText(t('The configuration options have been saved.'), t('Modules status has been updated.'));
+
+    $this->assertModules(array('translation', 'locale'), FALSE);
+  }
+
+  /**
+   * Tests that module dependencies are disabled in the correct order via the
+   * UI. Dependents should be disabled before their dependencies.
+   */
+  function testModuleDisableOrder() {
+    module_enable(array('forum', 'poll', 'php', 'module_test'), FALSE);
+    $this->resetAll();
+    $this->assertModules(array('module_test'), TRUE);
+    variable_set('dependency_test', 'dependency');
+    // module_test creates a dependency chain: forum depends on poll, which
+    // depends on php. The correct disable order is forum, poll, php.
+    $expected_order = array('forum', 'poll', 'php');
+
+    // Disable the modules through the UI, verifying that the dependency chain
+    // is correct.
+    $edit = array();
+    $edit['modules[Core][php][enable]'] = FALSE;
+    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
+    $this->assertText(t('You must disable the Poll, Forum modules to disable PHP filter.'), t('Dependency chain created.'));
+    $edit['modules[Core][forum][enable]'] = FALSE;
+    $edit['modules[Core][poll][enable]'] = FALSE;
+    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
+    $this->assertModules(array('forum', 'poll', 'php'), FALSE);
+
+    // Check the actual order which is saved by module_test_modules_disabled().
+    $this->assertIdentical(variable_get('test_module_disable_order', FALSE), $expected_order, t('Modules disabled in the correct order.'));
+  }
+
+  /**
+   * Check that hooks only fire in enabled modules when multiple dependent
+   * modules are disabled.
+   */
+  function testDisableHooks() {
+    // Enable the test module that depends on forum.
+    module_enable(array('disable_test'));
+    // Disable forum now, hook_modules_disabled() in disable_test should not
+    // fire.
+    $edit = array();
+    $edit['modules[Core][forum][enable]'] = FALSE;
+    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
+    $this->drupalPost(NULL, NULL, t('Continue'));
+    $this->pass('Disable test did not fire hook_modules_disabled().');
+  }
 }
 
 /**
