diff --git a/includes/install.core.inc b/includes/install.core.inc
index 38ad724..794b15b 100644
--- a/includes/install.core.inc
+++ b/includes/install.core.inc
@@ -1585,19 +1585,6 @@
 }
 
 /**
- * Batch callback for batch installation of modules.
- */
-function _install_module_batch($module, $module_name, &$context) {
-  // Install and enable the module right away, so that the module will be
-  // loaded by drupal_bootstrap in subsequent batch requests, and other
-  // modules possibly depending on it can safely perform their installation
-  // steps.
-  module_enable(array($module), FALSE);
-  $context['results'][] = $module;
-  $context['message'] = st('Installed %module module.', array('%module' => $module_name));
-}
-
-/**
  * 'Finished' callback for module installation batch.
  */
 function _install_profile_modules_finished($success, $results, $operations) {
diff --git a/includes/install.inc b/includes/install.inc
index 71de3e6..5b0a056 100644
--- a/includes/install.inc
+++ b/includes/install.inc
@@ -1330,3 +1330,38 @@
   $task_class = 'DatabaseTasks_' . $driver;
   return new $task_class();
 }
+
+/**
+ * Batch callback for batch installation of modules.
+ */
+function _install_module_batch($module, $module_name, &$context) {
+  // Install and enable the module right away, so that the module will be
+  // loaded by drupal_bootstrap in subsequent batch requests, and other
+  // modules possibly depending on it can safely perform their installation
+  // steps.
+  module_enable(array($module), FALSE);
+  $context['results'][] = $module;
+  $context['message'] = st('Installed %module module.', array('%module' => $module_name));
+}
+
+/**
+ * Batch callback for batch uninstallation of modules.
+ */
+function _uninstall_module_batch($module, $module_name, &$context) {
+  module_disable(array($module), FALSE);
+  $context['results'][] = $module;
+  $context['message'] = st('Uninstalled %module module.', array('%module' => $module_name));
+}
+
+/**
+ * Batch finish callback for bath installation / uninstallation of modules.
+ */
+function _install_modules_batch_finished($success, $results, $operations) {
+  if ($success && count($results)) {
+    drupal_flush_all_caches();
+    drupal_set_message(st('The configuration options have been saved.'));
+  }
+  else if(!$success) {
+    drupal_set_message(st('An error occured while trying to save onfiguration options.'));
+  }
+}
diff --git a/modules/simpletest/tests/module.test b/modules/simpletest/tests/module.test
index 371339f..9702449 100644
--- a/modules/simpletest/tests/module.test
+++ b/modules/simpletest/tests/module.test
@@ -154,6 +154,7 @@
     // Now, fix the missing dependency. Forum module depends on poll, but poll
     // depends on the PHP module. module_enable() should work.
     variable_set('dependency_test', 'dependency');
+    variable_set('test_module_enable_order', array());
     drupal_static_reset('system_rebuild_module_data');
     $result = module_enable(array('forum'));
     $this->assertTrue($result, 'module_enable() returns the correct value.');
@@ -217,6 +218,7 @@
     // on a specific version of php module in its info file. Make sure that
     // module_enable() still works.
     variable_set('dependency_test', 'version dependency');
+    variable_set('test_module_enable_order', array());
     drupal_static_reset('system_rebuild_module_data');
     $result = module_enable(array('forum'));
     $this->assertTrue($result, 'module_enable() returns the correct value.');
diff --git a/modules/simpletest/tests/module_test.module b/modules/simpletest/tests/module_test.module
index d781350..f222bdd 100644
--- a/modules/simpletest/tests/module_test.module
+++ b/modules/simpletest/tests/module_test.module
@@ -109,7 +109,8 @@
 function module_test_modules_enabled($modules) {
   // Record the ordered list of modules that were passed in to this hook so we
   // can check that the modules were enabled in the correct sequence.
-  variable_set('test_module_enable_order', $modules);
+  $sequence = variable_get('test_module_enable_order', array());
+  variable_set('test_module_enable_order', array_merge($sequence, $modules));
 }
 
 /**
diff --git a/modules/system/system.admin.inc b/modules/system/system.admin.inc
index b6f6789..ad1d8a2 100644
--- a/modules/system/system.admin.inc
+++ b/modules/system/system.admin.inc
@@ -1221,19 +1221,29 @@
   // Reverse the 'enable' list, to order dependencies before dependents.
   krsort($actions['enable']);
 
-  // Installs, enables, and disables modules.
-  module_enable($actions['enable'], FALSE);
-  module_disable($actions['disable'], FALSE);
+  // Make sure we redirect to modules page after batch process.
+  $form_state['redirect'] = 'admin/modules';
 
-  // Gets module list after install process, flushes caches and displays a
-  // message if there are changes.
-  $post_install_list = module_list(TRUE);
-  if ($pre_install_list != $post_install_list) {
-    drupal_flush_all_caches();
-    drupal_set_message(t('The configuration options have been saved.'));
+  // Prepare the batch operations and set the batch.
+  $operations = array();
+  foreach ($actions['enable'] as $weight => $module) {
+    $operations[] = array('_install_module_batch', array($module, $files[$module]->info['name']));
+  }
+  foreach ($actions['disable'] as $weight => $module) {
+    $operations[] = array('_uninstall_module_batch', array($module, $files[$module]->info['name']));
   }
 
-  $form_state['redirect'] = 'admin/modules';
+  // Prevent starting a batch with no operation.
+  if (count($operations)) {
+    $batch = array(
+      'operations' => $operations,
+      'title' => t('Updating modules.'),
+      'error_message' => t('The installation has encountered an error.'),
+      'finished' => '_install_modules_batch_finished',
+      'file' => 'includes/install.inc',
+    );
+    batch_set($batch);
+  }
 }
 
 /**
diff --git a/modules/system/system.test b/modules/system/system.test
index cae5cc7..630fc29 100644
--- a/modules/system/system.test
+++ b/modules/system/system.test
@@ -506,6 +506,7 @@
     // module_test creates a dependency chain: forum depends on poll, which
     // depends on php. The correct enable order is, php, poll, forum.
     $expected_order = array('php', 'poll', 'forum');
+    variable_set('test_module_enable_order', array());
 
     // Enable the modules through the UI, verifying that the dependency chain
     // is correct.
