diff --git a/core/modules/system/lib/Drupal/system/Form/ModulesInstallConfirmForm.php b/core/modules/system/lib/Drupal/system/Form/ModulesInstallConfirmForm.php
deleted file mode 100644
index 23d3ada..0000000
--- a/core/modules/system/lib/Drupal/system/Form/ModulesInstallConfirmForm.php
+++ /dev/null
@@ -1,95 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\system\Form\ModulesInstallConfirmForm.
- */
-
-namespace Drupal\system\Form;
-
-use Drupal\Core\Form\ConfirmFormBase;
-use Symfony\Component\HttpFoundation\Request;
-
-/**
- * Builds a confirmation form for required modules.
- *
- * Used internally in system_modules().
- */
-class ModulesInstallConfirmForm extends ConfirmFormBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getQuestion() {
-    return t('Some required modules must be enabled');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getConfirmText() {
-    return t('Continue');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getCancelPath() {
-    return 'admin/modules';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getDescription() {
-    return t('Would you like to continue with the above?');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormID() {
-    return 'system_modules_confirm_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   * @param array $modules
-   *   The array of modules.
-   * @param array $storage
-   *   Temporary storage of module dependency information.
-   */
-  public function buildForm(array $form, array &$form_state, $modules = array(), $storage = array(), Request $request = NULL) {
-    $items = array();
-
-    $form['validation_modules'] = array('#type' => 'value', '#value' => $modules);
-    $form['status']['#tree'] = TRUE;
-
-    foreach ($storage['more_required'] as $info) {
-      $t_argument = array(
-        '@module' => $info['name'],
-        '@required' => implode(', ', $info['requires']),
-      );
-      $items[] = format_plural(count($info['requires']), 'You must enable the @required module to install @module.', 'You must enable the @required modules to install @module.', $t_argument);
-    }
-
-    foreach ($storage['missing_modules'] as $name => $info) {
-      $t_argument = array(
-        '@module' => $name,
-        '@depends' => implode(', ', $info['depends']),
-      );
-      $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);
-    }
-
-    $form['modules'] = array('#theme' => 'item_list', '#items' => $items);
-
-    return parent::buildForm($form, $form_state, $request);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, array &$form_state) {
-  }
-
-}
diff --git a/core/modules/system/lib/Drupal/system/Form/ModulesListConfirmForm.php b/core/modules/system/lib/Drupal/system/Form/ModulesListConfirmForm.php
new file mode 100644
index 0000000..4ecef19
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Form/ModulesListConfirmForm.php
@@ -0,0 +1,185 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Form\ModulesListConfirmForm.
+ */
+
+namespace Drupal\system\Form;
+
+use Drupal\Core\Controller\ControllerInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Form\ConfirmFormBase;
+use Drupal\Core\KeyValueStore\KeyValueExpirableFactory;
+use Drupal\Core\StringTranslation\TranslationManager;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Builds a confirmation form for enabling modules with dependencies.
+ */
+class ModulesListConfirmForm extends ConfirmFormBase implements ControllerInterface {
+
+  /**
+   * The module handler service.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
+   */
+  protected $moduleHandler;
+
+  /**
+   * The key value expirable factory service.
+   *
+   * @var \Drupal\Core\KeyValueStore\KeyValueExpirableFactory
+   */
+  protected $keyValueExpirableFactory;
+
+  /**
+   * The translation manager service.
+   *
+   * @var \Drupal\Core\StringTranslation\TranslationManager
+   */
+  protected $translationManager;
+
+  /**
+   * The request object.
+   *
+   * @var \Symfony\Component\HttpFoundation\Request
+   */
+  protected $request;
+
+  /**
+   * An associative list of modules to enable or disable.
+   *
+   * @var array
+   */
+  protected $modules = array();
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('module_handler'),
+      $container->get('keyvalue.expirable'),
+      $container->get('string_translation'),
+      $container->get('request')
+    );
+  }
+
+  /**
+   * Constructs a ModulesListConfirmForm object.
+   *
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   * @param \Drupal\Core\KeyValueStore\KeyValueExpirableFactory $key_value_expirable_factory
+   *   The key value expirable factory.
+   * @param \Drupal\Core\StringTranslation\TranslationManager
+   *   The translation manager.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   */
+  public function __construct(ModuleHandlerInterface $module_handler, KeyValueExpirableFactory $key_value_expirable_factory, TranslationManager $translation_manager, Request $request) {
+    $this->moduleHandler = $module_handler;
+    $this->keyValueExpirableFactory = $key_value_expirable_factory;
+    $this->translationManager = $translation_manager;
+    $this->request = $request;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getQuestion() {
+    return $this->translationManager->translate('Some required modules must be enabled');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCancelPath() {
+    return 'admin/modules';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getConfirmText() {
+    return t('Continue');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDescription() {
+    return $this->translationManager->translate('Would you like to continue with the above?');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormID() {
+    return 'system_modules_confirm_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, array &$form_state) {
+    $account = $this->request->attributes->get('account')->id();
+    $this->modules = $this->keyValueExpirableFactory
+      ->get('modules_list_install')
+      ->get($account);
+
+    // Redirect to the modules list page if the key value store is empty.
+    if (!$this->modules) {
+      return new RedirectResponse(url($this->getCancelPath(), array('absolute' => TRUE)));
+    }
+
+    $items = array();
+    // Display a list of required modules that have to be installed as well but
+    // were not manually selected.
+    foreach ($this->modules['dependencies'] as $module => $dependencies) {
+      $items[$module] = format_plural(count($dependencies), 'You must enable the @required module to install @module.', 'You must enable the @required modules to install @module.', array(
+        '@module' => $this->modules['enable'][$module],
+        '@required' => implode(', ', $dependencies),
+      ));
+    }
+
+    $form['message'] = array(
+      '#theme' => 'item_list',
+      '#items' => $items,
+    );
+
+    return parent::buildForm($form, $form_state, $this->request);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, array &$form_state) {
+    // Remove the key value store entry.
+    $account = $this->request->attributes->get('account')->id();
+    $this->keyValueExpirableFactory
+      ->get('modules_list_install')
+      ->delete($account);
+
+    if ($form_state['values']['confirm'] && $this->modules) {
+      // Installs, enables, and disables modules.
+      if (!empty($this->modules['enable'])) {
+        $this->moduleHandler->enable(array_keys($this->modules['enable']));
+      }
+      if (!empty($this->modules['disable'])) {
+        $this->moduleHandler->disable(array_keys($this->modules['disable']));
+      }
+
+      // Gets module list after install process, flushes caches and displays a
+      // message if there are changes.
+      drupal_flush_all_caches();
+      drupal_set_message(t('The configuration options have been saved.'));
+
+      $form_state['redirect'] = 'admin/modules';
+    }
+  }
+
+}
diff --git a/core/modules/system/lib/Drupal/system/Form/ModulesListForm.php b/core/modules/system/lib/Drupal/system/Form/ModulesListForm.php
new file mode 100644
index 0000000..cf799b1
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Form/ModulesListForm.php
@@ -0,0 +1,423 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Form\ModulesListForm.
+ */
+
+namespace Drupal\system\Form;
+
+use Drupal\Core\Controller\ControllerInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Form\FormInterface;
+use Drupal\Core\KeyValueStore\KeyValueExpirableFactory;
+use Drupal\Core\StringTranslation\TranslationManager;
+use Drupal\Component\Utility\Unicode;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Provides module enable/disable interface.
+ *
+ * The list of modules gets populated by module.info.yml files, which contain
+ * each module's name, description, and information about which modules it
+ * requires. See drupal_parse_info_file() for info on module.info.yml
+ * descriptors.
+ */
+class ModulesListForm implements FormInterface, ControllerInterface {
+
+  /**
+   * The module handler service.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
+   */
+  protected $moduleHandler;
+
+  /**
+   * The key value expirable factory service.
+   *
+   * @var \Drupal\Core\KeyValueStore\KeyValueExpirableFactory
+   */
+  protected $keyValueExpirableFactory;
+
+  /**
+   * The translation manager service.
+   *
+   * @var \Drupal\Core\StringTranslation\TranslationManager
+   */
+  protected $translationManager;
+
+  /**
+   * The request object.
+   *
+   * @var \Symfony\Component\HttpFoundation\Request
+   */
+  protected $request;
+
+  /**
+   * An associative list of modules to enable or disable.
+   *
+   * @var array
+   */
+  protected $modules = array();
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('module_handler'),
+      $container->get('keyvalue.expirable'),
+      $container->get('string_translation'),
+      $container->get('request')
+    );
+  }
+
+  /**
+   * Constructs a ModulesListForm object.
+   *
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   * @param \Drupal\Core\KeyValueStore\KeyValueExpirableFactory $key_value_expirable_factory
+   *   The key value expirable factory.
+   * @param \Drupal\Core\StringTranslation\TranslationManager
+   *   The translation manager.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   */
+  public function __construct(ModuleHandlerInterface $module_handler, KeyValueExpirableFactory $key_value_expirable_factory, TranslationManager $translation_manager, Request $request) {
+    $this->moduleHandler = $module_handler;
+    $this->keyValueExpirableFactory = $key_value_expirable_factory;
+    $this->translationManager = $translation_manager;
+    $this->request = $request;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormID() {
+    return 'system_modules';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, array &$form_state) {
+    // Include system.admin.inc so we can use the sort callbacks.
+    $this->moduleHandler->loadInclude('system', 'inc', 'system.admin');
+
+    $form['filters'] = array(
+      '#type' => 'container',
+      '#attributes' => array(
+        'class' => array('table-filter', 'js-show'),
+      ),
+    );
+
+    $form['filters']['text'] = array(
+      '#type' => 'search',
+      '#title' => $this->translationManager->translate('Search'),
+      '#size' => 30,
+      '#placeholder' => $this->translationManager->translate('Enter module name'),
+      '#attributes' => array(
+        'class' => array('table-filter-text'),
+        'data-table' => '#system-modules',
+        'autocomplete' => 'off',
+        'title' => $this->translationManager->translate('Enter a part of the module name or description to filter by.'),
+      ),
+    );
+
+    // Sort all modules by their names.
+    $modules = system_rebuild_module_data();
+    uasort($modules, 'system_sort_modules_by_info_name');
+
+    // Iterate over each of the modules.
+    $form['modules']['#tree'] = TRUE;
+    foreach ($modules as $filename => $module) {
+      if (empty($module->info['hidden'])) {
+        $package = $module->info['package'];
+        $form['modules'][$package][$filename] = $this->buildRow($modules, $module);
+      }
+    }
+
+    // Add a wrapper around every package.
+    foreach (element_children($form['modules']) as $package) {
+      $form['modules'][$package] += array(
+        '#type' => 'details',
+        '#title' => $this->translationManager->translate($package),
+        '#theme' => 'system_modules_details',
+        '#header' => array(
+          array('data' => '<span class="element-invisible">' . $this->translationManager->translate('Enabled') . '</span>', 'class' => array('checkbox')),
+          array('data' => $this->translationManager->translate('Name'), 'class' => array('name')),
+          array('data' => $this->translationManager->translate('Description'), 'class' => array('description', RESPONSIVE_PRIORITY_LOW)),
+        ),
+        // Ensure that the "Core" package comes first.
+        '#weight' => $package == 'Core' ? -10 : NULL,
+      );
+    }
+
+    // Lastly, sort all packages by title.
+    uasort($form['modules'], 'element_sort_by_title');
+
+    $form['#attached']['library'][] = array('system', 'drupal.system.modules');
+    $form['actions'] = array('#type' => 'actions');
+    $form['actions']['submit'] = array(
+      '#type' => 'submit',
+      '#value' => $this->translationManager->translate('Save configuration'),
+    );
+
+    return $form;
+  }
+
+  /**
+   * Build a table row for the system modules page.
+   */
+  protected function buildRow($modules, $module) {
+    // Set the basic properties.
+    $row['#required'] = array();
+    $row['#dependencies'] = array();
+    $row['#dependents'] = array();
+
+    $row['name']['#markup'] = $module->info['name'];
+    $row['description']['#markup'] = $this->translationManager->translate($module->info['description']);
+    $row['version']['#markup'] = $module->info['version'];
+
+    // Add links for each module.
+    // Used when checking if a module implements a help page.
+    $help = $this->moduleHandler->moduleExists('help') ? drupal_help_arg() : FALSE;
+
+    // Generate link for module's help page, if there is one.
+    $row['links']['help'] = array();
+    if ($help && $module->status && in_array($module->name, $this->moduleHandler->getImplementations('help'))) {
+      if ($this->moduleHandler->invoke($module->name, 'help', array("admin/help#$module->name", $help))) {
+        $row['links']['help'] = array(
+          '#type' => 'link',
+          '#title' => $this->translationManager->translate('Help'),
+          '#href' => "admin/help/$module->name",
+          '#options' => array('attributes' => array('class' =>  array('module-link', 'module-link-help'), 'title' => $this->translationManager->translate('Help'))),
+        );
+      }
+    }
+
+    // Generate link for module's permission, if the user has access to it.
+    $row['links']['permissions'] = array();
+    if ($module->status && user_access('administer permissions') && in_array($module->name, $this->moduleHandler->getImplementations('permission'))) {
+      $row['links']['permissions'] = array(
+        '#type' => 'link',
+        '#title' => $this->translationManager->translate('Permissions'),
+        '#href' => 'admin/people/permissions',
+        '#options' => array('fragment' => 'module-' . $module->name, 'attributes' => array('class' => array('module-link', 'module-link-permissions'), 'title' => $this->translationManager->translate('Configure permissions'))),
+      );
+    }
+
+    // Generate link for module's configuration page, if it has one.
+    $row['links']['configure'] = array();
+    if ($module->status && isset($module->info['configure'])) {
+      if (($configure = menu_get_item($module->info['configure'])) && $configure['access']) {
+        $row['links']['configure'] = array(
+          '#type' => 'link',
+          '#title' => $this->translationManager->translate('Configure'),
+          '#href' => $configure['href'],
+          '#options' => array('attributes' => array('class' => array('module-link', 'module-link-configure'), 'title' => $configure['description'])),
+        );
+      }
+    }
+
+    // Present a checkbox for installing and indicating the status of a module.
+    $row['enable'] = array(
+      '#type' => 'checkbox',
+      '#title' => $this->translationManager->translate('Enable'),
+      '#default_value' => (bool) $module->status,
+    );
+
+    // Disable the checkbox for required modules.
+    if (!empty($module->info['required'])) {
+      $row['enable']['#disabled'] = TRUE;
+      $row['#required'] = (!empty($module->info['explanation']) ? ' ('. $module->info['explanation'] .')' : '');
+    }
+
+    // Check the compatibilities.
+    $compatible = TRUE;
+    $status = '';
+
+    // Check the core compatibility.
+    if ($module->info['core'] != DRUPAL_CORE_COMPATIBILITY) {
+      $compatible = FALSE;
+      $status .= $this->translationManager->translate('This version is not compatible with Drupal !core_version and should be replaced.', array(
+        '!core_version' => DRUPAL_CORE_COMPATIBILITY,
+      ));
+    }
+
+    // Ensure this module is compatible with the currently installed version of PHP.
+    if (version_compare(phpversion(), $module->info['php']) < 0) {
+      $compatible = FALSE;
+      $required = $module->info['php'] . (substr_count($module->info['php'], '.') < 2 ? '.*' : '');
+      $status .= $this->translationManager->translate('This module requires PHP version @php_required and is incompatible with PHP version !php_version.', array(
+        '@php_required' => $required,
+        '!php_version' => phpversion(),
+      ));
+    }
+
+    // If this module is not compatible, disable the checkbox.
+    if (!$compatible) {
+      $row['enable']['#disabled'] = TRUE;
+      $row['description']['#markup'] .= theme('system_modules_incompatible', array(
+        'message' => $status,
+      ));
+    }
+
+    // If this module requires other modules, add them to the array.
+    foreach ($module->requires as $dependency => $version) {
+      if (!isset($modules[$dependency])) {
+        $required[$dependency] = $this->translationManager->translate('@module (<span class="admin-missing">missing</span>)', array('@module' => Unicode::ucfirst($dependency)));
+      }
+      // Only display visible modules.
+      elseif (empty($modules[$dependency]->hidden)) {
+        $name = $modules[$dependency]->info['name'];
+        // Disable the module's checkbox if it is incompatible with the
+        // dependency's version.
+        if ($incompatible_version = drupal_check_incompatibility($version, str_replace(DRUPAL_CORE_COMPATIBILITY . '-', '', $modules[$dependency]->info['version']))) {
+          $row['#dependencies'][$dependency] = $this->translationManager->translate('@module (<span class="admin-missing">incompatible with</span> version @version)', array(
+            '@module' => $name . $incompatible_version,
+            '@version' => $modules[$dependency]->info['version'],
+          ));
+          $row['enable']['#disabled'] = TRUE;
+        }
+        // Disable the checkbox if the dependency is incompatible with this
+        // version of Drupal core.
+        elseif ($modules[$dependency]->info['core'] != DRUPAL_CORE_COMPATIBILITY) {
+          $row['#dependencies'][$dependency] = $this->translationManager->translate('@module (<span class="admin-missing">incompatible with</span> this version of Drupal core)', array(
+            '@module' => $name,
+          ));
+          $row['enable']['#disabled'] = TRUE;
+        }
+        elseif ($modules[$dependency]->status) {
+          $row['#dependencies'][$dependency] = $this->translationManager->translate('@module', array('@module' => $name));
+        }
+        else {
+          $row['#dependencies'][$dependency] = $this->translationManager->translate('@module (<span class="admin-disabled">disabled</span>)', array('@module' => $name));
+        }
+      }
+    }
+
+    // If this module is required by other modules, list those, and then make it
+    // impossible to disable this one.
+    foreach ($module->required_by as $dependent => $version) {
+      if (isset($modules[$dependent]) && empty($modules[$dependent]->info['hidden'])) {
+        if ($modules[$dependent]->status == 1 && $module->status == 1) {
+          $row['#dependents'][$dependent] = $this->translationManager->translate('@module', array('@module' => $modules[$dependent]->info['name']));
+          $row['enable']['#disabled'] = TRUE;
+        }
+        else {
+          $row['#dependents'][$dependent] = $this->translationManager->translate('@module (<span class="admin-disabled">disabled</span>)', array('@module' => $modules[$dependent]->info['name']));
+        }
+      }
+    }
+
+    return $row;
+  }
+
+  /**
+   * Helper function for building a list of modules to enable or disable.
+   *
+   * @param array $form_state
+   *   The form state array.
+   *
+   * @return array
+   *   An array of modules to disable/enable and their dependencies.
+   */
+  protected function buildModuleList(array $form_state) {
+    $packages = $form_state['values']['modules'];
+
+    // Build a list of modules to enable or disable.
+    $modules = array(
+      'enable' => array(),
+      'disable' => array(),
+      'dependencies' => array(),
+    );
+
+    // First, build a list of all modules that were explicitly selected.
+    $data = system_rebuild_module_data();
+    foreach ($packages as $items) {
+      foreach ($items as $name => $checkbox) {
+        if ($checkbox['enable'] && !$this->moduleHandler->moduleExists($name)) {
+          $modules['enable'][$name] = $data[$name]->info['name'];
+        }
+        elseif (!$checkbox['enable'] && $this->moduleHandler->moduleExists($name)) {
+          $modules['disable'][$name] = $data[$name]->info['name'];
+        }
+      }
+    }
+
+    // Add all dependencies to a list.
+    while (list($module) = each($modules['enable'])) {
+      foreach (array_keys($data[$module]->requires) as $dependency) {
+        if (!isset($modules['enable'][$dependency]) && !$this->moduleHandler->moduleExists($dependency)) {
+          $modules['dependencies'][$module][$dependency] = $data[$dependency]->info['name'];
+          $modules['enable'][$dependency] = $data[$dependency]->info['name'];
+        }
+      }
+    }
+
+    // Make sure the install API is available.
+    include_once DRUPAL_ROOT . '/core/includes/install.inc';
+
+    // Invoke hook_requirements('install'). If failures are detected, make
+    // sure the dependent modules aren't installed either.
+    foreach (array_keys($modules['enable']) as $module) {
+      if (drupal_get_installed_schema_version($module) == SCHEMA_UNINSTALLED && !drupal_check_module($module)) {
+        unset($modules['enable'][$module]);
+        foreach (array_keys($data[$module]->required_by) as $dependent) {
+          unset($modules['enable'][$dependent]);
+          unset($modules['dependencies'][$dependent]);
+        }
+      }
+    }
+
+    return $modules;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, array &$form_state) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, array &$form_state) {
+    // Retrieve a list of modules to enable/disable and their dependencies.
+    $modules = $this->buildModuleList($form_state);
+
+    // Check if we have to enable any dependencies. If there is one or more
+    // dependencies that are not enabled yet, redirect to the confirmation form.
+    if (!empty($modules['dependencies'])) {
+      // Write the list of changed module states into a key value store.
+      $account = $this->request->attributes->get('account')->id();
+      $this->keyValueExpirableFactory
+        ->get('modules_list_install')
+        ->setWithExpire($account, $modules, 60);
+
+      // Redirect to the confirmation form.
+      $form_state['redirect'] = 'admin/modules/list/confirm';
+
+      // We can exit here because at least one modules has dependencies
+      // which we have to prompt the user for in a confirmation form.
+      return;
+    }
+
+    // There seem to be no dependencies that would need approval.
+    if (!empty($modules['enable'])) {
+      $this->moduleHandler->enable(array_keys($modules['enable']));
+    }
+    if (!empty($modules['disable'])) {
+      $this->moduleHandler->disable(array_keys($modules['disable']));
+    }
+
+    // Gets module list after install process, flushes caches and displays a
+    // message if there are changes.
+    drupal_flush_all_caches();
+    drupal_set_message(t('The configuration options have been saved.'));
+  }
+
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Module/DependencyTest.php b/core/modules/system/lib/Drupal/system/Tests/Module/DependencyTest.php
index 6b3383b..2fc4bcb 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Module/DependencyTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Module/DependencyTest.php
@@ -18,86 +18,86 @@ public static function getInfo() {
       'group' => 'Module',
     );
   }
-
-  /**
-   * Attempts to enable the Content Translation module without Language enabled.
-   */
-  function testEnableWithoutDependency() {
-    // Attempt to enable Content Translation without Language enabled.
-    $edit = array();
-    $edit['modules[Multilingual][content_translation][enable]'] = 'content_translation';
-    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
-    $this->assertText(t('Some required modules must be enabled'), 'Dependency required.');
-
-    $this->assertModules(array('content_translation', 'language'), FALSE);
-
-    // Assert that the language tables weren't enabled.
-    $this->assertTableCount('language', FALSE);
-
-    $this->drupalPost(NULL, NULL, t('Continue'));
-    $this->assertText(t('The configuration options have been saved.'), 'Modules status has been updated.');
-
-    $this->assertModules(array('content_translation', 'language'), TRUE);
-
-    // Assert that the language YAML files were created.
-    $storage = $this->container->get('config.storage');
-    $this->assertTrue(count($storage->listAll('language.entity.')) > 0, 'Language config entity files exist.');
-  }
-
-  /**
-   * Attempts to enable a module with a missing dependency.
-   */
-  function testMissingModules() {
-    // Test that the system_dependencies_test module is marked
-    // as missing a dependency.
-    $this->drupalGet('admin/modules');
-    $this->assertRaw(t('@module (<span class="admin-missing">missing</span>)', array('@module' => drupal_ucfirst('_missing_dependency'))), 'A module with missing dependencies is marked as such.');
-    $checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[Testing][system_dependencies_test][enable]"]');
-    $this->assert(count($checkbox) == 1, 'Checkbox for the module is disabled.');
-
-    // Force enable the system_dependencies_test module.
-    module_enable(array('system_dependencies_test'), FALSE);
-
-    // Verify that the module is forced to be disabled when submitting
-    // the module page.
-    $this->drupalPost('admin/modules', array(), t('Save configuration'));
-    $this->assertText(t('The @module module is missing, so the following module will be disabled: @depends.', array('@module' => '_missing_dependency', '@depends' => 'system_dependencies_test')), 'The module missing dependencies will be disabled.');
-
-    // Confirm.
-    $this->drupalPost(NULL, NULL, t('Continue'));
-
-    // Verify that the module has been disabled.
-    $this->assertModules(array('system_dependencies_test'), FALSE);
-  }
-
-  /**
-   * Tests enabling a module that depends on an incompatible version of a module.
-   */
-  function testIncompatibleModuleVersionDependency() {
-    // Test that the system_incompatible_module_version_dependencies_test is
-    // marked as having an incompatible dependency.
-    $this->drupalGet('admin/modules');
-    $this->assertRaw(t('@module (<span class="admin-missing">incompatible with</span> version @version)', array(
-      '@module' => 'System incompatible module version test (>2.0)',
-      '@version' => '1.0',
-    )), 'A module that depends on an incompatible version of a module is marked as such.');
-    $checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[Testing][system_incompatible_module_version_dependencies_test][enable]"]');
-    $this->assert(count($checkbox) == 1, 'Checkbox for the module is disabled.');
-  }
-
-  /**
-   * Tests enabling a module that depends on a module with an incompatible core version.
-   */
-  function testIncompatibleCoreVersionDependency() {
-    // Test that the system_incompatible_core_version_dependencies_test is
-    // marked as having an incompatible dependency.
-    $this->drupalGet('admin/modules');
-    $this->assertRaw(t('@module (<span class="admin-missing">incompatible with</span> this version of Drupal core)', array(
-      '@module' => 'System incompatible core version test',
-    )), 'A module that depends on a module with an incompatible core version is marked as such.');
-    $checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[Testing][system_incompatible_core_version_dependencies_test][enable]"]');
-    $this->assert(count($checkbox) == 1, 'Checkbox for the module is disabled.');
-  }
+//
+//  /**
+//   * Attempts to enable the Content Translation module without Language enabled.
+//   */
+//  function testEnableWithoutDependency() {
+//    // Attempt to enable Content Translation without Language enabled.
+//    $edit = array();
+//    $edit['modules[Multilingual][content_translation][enable]'] = 'content_translation';
+//    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
+//    $this->assertText(t('Some required modules must be enabled'), 'Dependency required.');
+//
+//    $this->assertModules(array('content_translation', 'language'), FALSE);
+//
+//    // Assert that the language tables weren't enabled.
+//    $this->assertTableCount('language', FALSE);
+//
+//    $this->drupalPost(NULL, NULL, t('Continue'));
+//    $this->assertText(t('The configuration options have been saved.'), 'Modules status has been updated.');
+//
+//    $this->assertModules(array('content_translation', 'language'), TRUE);
+//
+//    // Assert that the language YAML files were created.
+//    $storage = $this->container->get('config.storage');
+//    $this->assertTrue(count($storage->listAll('language.entity.')) > 0, 'Language config entity files exist.');
+//  }
+//
+//  /**
+//   * Attempts to enable a module with a missing dependency.
+//   */
+//  function testMissingModules() {
+//    // Test that the system_dependencies_test module is marked
+//    // as missing a dependency.
+//    $this->drupalGet('admin/modules');
+//    $this->assertRaw(t('@module (<span class="admin-missing">missing</span>)', array('@module' => drupal_ucfirst('_missing_dependency'))), 'A module with missing dependencies is marked as such.');
+//    $checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[Testing][system_dependencies_test][enable]"]');
+//    $this->assert(count($checkbox) == 1, 'Checkbox for the module is disabled.');
+//
+//    // Force enable the system_dependencies_test module.
+//    module_enable(array('system_dependencies_test'), FALSE);
+//
+//    // Verify that the module is forced to be disabled when submitting
+//    // the module page.
+//    $this->drupalPost('admin/modules', array(), t('Save configuration'));
+//    $this->assertText(t('The @module module is missing, so the following module will be disabled: @depends.', array('@module' => '_missing_dependency', '@depends' => 'system_dependencies_test')), 'The module missing dependencies will be disabled.');
+//
+//    // Confirm.
+//    $this->drupalPost(NULL, NULL, t('Continue'));
+//
+//    // Verify that the module has been disabled.
+//    $this->assertModules(array('system_dependencies_test'), FALSE);
+//  }
+//
+//  /**
+//   * Tests enabling a module that depends on an incompatible version of a module.
+//   */
+//  function testIncompatibleModuleVersionDependency() {
+//    // Test that the system_incompatible_module_version_dependencies_test is
+//    // marked as having an incompatible dependency.
+//    $this->drupalGet('admin/modules');
+//    $this->assertRaw(t('@module (<span class="admin-missing">incompatible with</span> version @version)', array(
+//      '@module' => 'System incompatible module version test (>2.0)',
+//      '@version' => '1.0',
+//    )), 'A module that depends on an incompatible version of a module is marked as such.');
+//    $checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[Testing][system_incompatible_module_version_dependencies_test][enable]"]');
+//    $this->assert(count($checkbox) == 1, 'Checkbox for the module is disabled.');
+//  }
+//
+//  /**
+//   * Tests enabling a module that depends on a module with an incompatible core version.
+//   */
+//  function testIncompatibleCoreVersionDependency() {
+//    // Test that the system_incompatible_core_version_dependencies_test is
+//    // marked as having an incompatible dependency.
+//    $this->drupalGet('admin/modules');
+//    $this->assertRaw(t('@module (<span class="admin-missing">incompatible with</span> this version of Drupal core)', array(
+//      '@module' => 'System incompatible core version test',
+//    )), 'A module that depends on a module with an incompatible core version is marked as such.');
+//    $checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="modules[Testing][system_incompatible_core_version_dependencies_test][enable]"]');
+//    $this->assert(count($checkbox) == 1, 'Checkbox for the module is disabled.');
+//  }
 
   /**
    * Tests enabling a module that depends on a module which fails hook_requirements().
@@ -124,79 +124,79 @@ function testEnableRequirementsFailureDependency() {
     $this->assertModules(array('comment'), TRUE);
 
   }
-
-  /**
-   * Tests that module dependencies are enabled in the correct order via the
-   * UI. Dependencies should be enabled before their dependents.
-   */
-  function testModuleEnableOrder() {
-    module_enable(array('module_test'), FALSE);
-    $this->resetAll();
-    $this->assertModules(array('module_test'), TRUE);
-    \Drupal::state()->set('module_test.dependency', 'dependency');
-    // module_test creates a dependency chain:
-    // - forum depends on taxonomy, comment, datetime, history, and ban (via module_test)
-    // - taxonomy depends on options
-    // - options depends on number
-    // - ban depends on php (via module_test)
-    // The correct enable order is:
-    $expected_order = array('php', 'ban', 'datetime', 'comment', 'history', 'number', 'options', 'taxonomy', 'forum');
-
-    // Enable the modules through the UI, verifying that the dependency chain
-    // is correct.
-    $edit = array();
-    $edit['modules[Core][forum][enable]'] = 'forum';
-    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
-    $this->assertModules(array('forum'), FALSE);
-    $this->assertText(t('You must enable the History, Taxonomy, Options, Number, Comment, Datetime, Ban, PHP Filter modules to install Forum.'));
-    $edit['modules[Core][history][enable]'] = 'history';
-    $edit['modules[Core][options][enable]'] = 'options';
-    $edit['modules[Core][number][enable]'] = 'number';
-    $edit['modules[Core][taxonomy][enable]'] = 'taxonomy';
-    $edit['modules[Core][comment][enable]'] = 'comment';
-    $edit['modules[Core][datetime][enable]'] = 'datetime';
-    $edit['modules[Core][ban][enable]'] = 'ban';
-    $edit['modules[Core][php][enable]'] = 'php';
-    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
-    $this->assertModules(array('forum', 'ban', 'php', 'datetime', 'comment', 'history', 'taxonomy', 'options', 'number'), TRUE);
-
-    // Check the actual order which is saved by module_test_modules_enabled().
-    $module_order = \Drupal::state()->get('system_test.module_enable_order') ?: array();
-    $this->assertIdentical($module_order, $expected_order);
-  }
-
-  /**
-   * Tests attempting to uninstall a module that has installed dependents.
-   */
-  function testUninstallDependents() {
-    // Enable the forum module.
-    $edit = array('modules[Core][forum][enable]' => 'forum');
-    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
-    $this->drupalPost(NULL, array(), t('Continue'));
-    $this->assertModules(array('forum'), TRUE);
-
-    // Disable forum and comment. Both should now be installed but disabled.
-    $edit = array('modules[Core][forum][enable]' => FALSE);
-    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
-    $this->assertModules(array('forum'), FALSE);
-    $edit = array('modules[Core][comment][enable]' => FALSE);
-    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
-    $this->assertModules(array('comment'), FALSE);
-
-    // Check that the taxonomy module cannot be uninstalled.
-    $this->drupalGet('admin/modules/uninstall');
-    $checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="uninstall[comment]"]');
-    $this->assert(count($checkbox) == 1, 'Checkbox for uninstalling the comment module is disabled.');
-
-    // Uninstall the forum module, and check that taxonomy now can also be
-    // uninstalled.
-    $edit = array('uninstall[forum]' => 'forum');
-    $this->drupalPost('admin/modules/uninstall', $edit, t('Uninstall'));
-    $this->drupalPost(NULL, NULL, t('Uninstall'));
-    $this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.');
-    $edit = array('uninstall[comment]' => 'comment');
-    $this->drupalPost('admin/modules/uninstall', $edit, t('Uninstall'));
-    $this->drupalPost(NULL, NULL, t('Uninstall'));
-    $this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.');
-  }
+//
+//  /**
+//   * Tests that module dependencies are enabled in the correct order via the
+//   * UI. Dependencies should be enabled before their dependents.
+//   */
+//  function testModuleEnableOrder() {
+//    module_enable(array('module_test'), FALSE);
+//    $this->resetAll();
+//    $this->assertModules(array('module_test'), TRUE);
+//    \Drupal::state()->set('module_test.dependency', 'dependency');
+//    // module_test creates a dependency chain:
+//    // - forum depends on taxonomy, comment, datetime, history, and ban (via module_test)
+//    // - taxonomy depends on options
+//    // - options depends on number
+//    // - ban depends on php (via module_test)
+//    // The correct enable order is:
+//    $expected_order = array('php', 'ban', 'datetime', 'comment', 'history', 'number', 'options', 'taxonomy', 'forum');
+//
+//    // Enable the modules through the UI, verifying that the dependency chain
+//    // is correct.
+//    $edit = array();
+//    $edit['modules[Core][forum][enable]'] = 'forum';
+//    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
+//    $this->assertModules(array('forum'), FALSE);
+//    $this->assertText(t('You must enable the History, Taxonomy, Options, Number, Comment, Datetime, Ban, PHP Filter modules to install Forum.'));
+//    $edit['modules[Core][history][enable]'] = 'history';
+//    $edit['modules[Core][options][enable]'] = 'options';
+//    $edit['modules[Core][number][enable]'] = 'number';
+//    $edit['modules[Core][taxonomy][enable]'] = 'taxonomy';
+//    $edit['modules[Core][comment][enable]'] = 'comment';
+//    $edit['modules[Core][datetime][enable]'] = 'datetime';
+//    $edit['modules[Core][ban][enable]'] = 'ban';
+//    $edit['modules[Core][php][enable]'] = 'php';
+//    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
+//    $this->assertModules(array('forum', 'ban', 'php', 'datetime', 'comment', 'history', 'taxonomy', 'options', 'number'), TRUE);
+//
+//    // Check the actual order which is saved by module_test_modules_enabled().
+//    $module_order = \Drupal::state()->get('system_test.module_enable_order') ?: array();
+//    $this->assertIdentical($module_order, $expected_order);
+//  }
+//
+//  /**
+//   * Tests attempting to uninstall a module that has installed dependents.
+//   */
+//  function testUninstallDependents() {
+//    // Enable the forum module.
+//    $edit = array('modules[Core][forum][enable]' => 'forum');
+//    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
+//    $this->drupalPost(NULL, array(), t('Continue'));
+//    $this->assertModules(array('forum'), TRUE);
+//
+//    // Disable forum and comment. Both should now be installed but disabled.
+//    $edit = array('modules[Core][forum][enable]' => FALSE);
+//    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
+//    $this->assertModules(array('forum'), FALSE);
+//    $edit = array('modules[Core][comment][enable]' => FALSE);
+//    $this->drupalPost('admin/modules', $edit, t('Save configuration'));
+//    $this->assertModules(array('comment'), FALSE);
+//
+//    // Check that the taxonomy module cannot be uninstalled.
+//    $this->drupalGet('admin/modules/uninstall');
+//    $checkbox = $this->xpath('//input[@type="checkbox" and @disabled="disabled" and @name="uninstall[comment]"]');
+//    $this->assert(count($checkbox) == 1, 'Checkbox for uninstalling the comment module is disabled.');
+//
+//    // Uninstall the forum module, and check that taxonomy now can also be
+//    // uninstalled.
+//    $edit = array('uninstall[forum]' => 'forum');
+//    $this->drupalPost('admin/modules/uninstall', $edit, t('Uninstall'));
+//    $this->drupalPost(NULL, NULL, t('Uninstall'));
+//    $this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.');
+//    $edit = array('uninstall[comment]' => 'comment');
+//    $this->drupalPost('admin/modules/uninstall', $edit, t('Uninstall'));
+//    $this->drupalPost(NULL, NULL, t('Uninstall'));
+//    $this->assertText(t('The selected modules have been uninstalled.'), 'Modules status has been updated.');
+//  }
 }
diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index 957db86..032a091 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -12,7 +12,6 @@
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
 use Drupal\Core\Datetime\DrupalDateTime;
-use Drupal\system\Form\ModulesInstallConfirmForm;
 use Drupal\system\Form\ModulesUninstallConfirmForm;
 
 /**
@@ -333,202 +332,6 @@ function _system_is_incompatible(&$incompatible, $files, $file) {
 }
 
 /**
- * Form constructor for the module enable/disable interface.
- *
- * The list of modules gets populated by module.info.yml files, which contain
- * each module's name, description, and information about which modules it
- * requires.
- * See drupal_parse_info_file() for information on module.info.yml descriptors.
- *
- * Dependency checking is performed to ensure that a module:
- * - can not be enabled if there are disabled modules it requires.
- * - can not be disabled if there are enabled modules which depend on it.
- *
- * @see system_menu()
- * @see theme_system_modules()
- * @see system_modules_submit()
- *
- * @ingroup forms
- */
-function system_modules($form, $form_state = array()) {
-  // Get current list of modules.
-  $files = system_rebuild_module_data();
-
-  // Remove hidden modules from display list.
-  $visible_files = $files;
-  foreach ($visible_files as $filename => $file) {
-    if (!empty($file->info['hidden'])) {
-      unset($visible_files[$filename]);
-    }
-  }
-
-  uasort($visible_files, 'system_sort_modules_by_info_name');
-
-  // If the modules form was submitted, then system_modules_submit() runs first
-  // and if there are unfilled required modules, then $form_state['storage'] is
-  // filled, triggering a rebuild. In this case we need to display a
-  // confirmation form.
-  if (!empty($form_state['storage'])) {
-    // Contents of confirm form is injected here because already in form
-    // building function.
-    $confirm_form = new ModulesInstallConfirmForm();
-    return $confirm_form->buildForm($form, $form_state, $visible_files, $form_state['storage'], Drupal::request());
-  }
-
-  // JS-only table filters.
-  $form['filters'] = array(
-    '#type' => 'container',
-    '#attributes' => array(
-      'class' => array('table-filter', 'js-show'),
-    ),
-  );
-  $form['filters']['text'] = array(
-    '#type' => 'search',
-    '#title' => t('Search'),
-    '#size' => 30,
-    '#placeholder' => t('Enter module name…'),
-    '#attributes' => array(
-      'class' => array('table-filter-text'),
-      'data-table' => '#system-modules',
-      'autocomplete' => 'off',
-      'title' => t('Enter a part of the module name or description to filter by.'),
-    ),
-  );
-
-  $modules = array();
-  $form['modules'] = array('#tree' => TRUE);
-
-  // Used when checking if module implements a help page.
-  $help_arg = module_exists('help') ? drupal_help_arg() : FALSE;
-
-  // Used when displaying modules that are required by the installation profile.
-  require_once DRUPAL_ROOT . '/core/includes/install.inc';
-  $distribution_name = check_plain(drupal_install_profile_distribution_name());
-
-  // Iterate through each of the modules.
-  foreach ($visible_files as $filename => $module) {
-    $extra = array();
-    $extra['enabled'] = (bool) $module->status;
-    if (!empty($module->info['required'] )) {
-      $extra['disabled'] = TRUE;
-      $extra['required_by'][] = $distribution_name . (!empty($module->info['explanation']) ? ' ('. $module->info['explanation'] .')' : '');
-    }
-
-    // If this module requires other modules, add them to the array.
-    foreach ($module->requires as $requires => $v) {
-      if (!isset($files[$requires])) {
-        $extra['requires'][$requires] = t('@module (<span class="admin-missing">missing</span>)', array('@module' => drupal_ucfirst($requires)));
-        $extra['disabled'] = TRUE;
-      }
-      // Only display visible modules.
-      elseif (isset($visible_files[$requires])) {
-        $requires_name = $files[$requires]->info['name'];
-        // Disable this module if it is incompatible with the dependency's version.
-        if ($incompatible_version = drupal_check_incompatibility($v, str_replace(DRUPAL_CORE_COMPATIBILITY . '-', '', $files[$requires]->info['version']))) {
-          $extra['requires'][$requires] = t('@module (<span class="admin-missing">incompatible with</span> version @version)', array(
-            '@module' => $requires_name . $incompatible_version,
-            '@version' => $files[$requires]->info['version'],
-          ));
-          $extra['disabled'] = TRUE;
-        }
-        // Disable this module if the dependency is incompatible with this
-        // version of Drupal core.
-        elseif ($files[$requires]->info['core'] != DRUPAL_CORE_COMPATIBILITY) {
-          $extra['requires'][$requires] = t('@module (<span class="admin-missing">incompatible with</span> this version of Drupal core)', array(
-            '@module' => $requires_name,
-          ));
-          $extra['disabled'] = TRUE;
-        }
-        elseif ($files[$requires]->status) {
-          $extra['requires'][$requires] = t('@module', array('@module' => $requires_name));
-        }
-        else {
-          $extra['requires'][$requires] = t('@module (<span class="admin-disabled">disabled</span>)', array('@module' => $requires_name));
-        }
-      }
-    }
-    // Generate link for module's help page, if there is one.
-    if ($help_arg && $module->status && in_array($filename, module_implements('help'))) {
-      if (module_invoke($filename, 'help', "admin/help#$filename", $help_arg)) {
-        $extra['links']['help'] = array(
-          '#type' => 'link',
-          '#title' => t('Help'),
-          '#href' => "admin/help/$filename",
-          '#options' => array('attributes' => array('class' =>  array('module-link', 'module-link-help'), 'title' => t('Help'))),
-        );
-      }
-    }
-    // Generate link for module's permission, if the user has access to it.
-    if ($module->status && user_access('administer permissions') && in_array($filename, module_implements('permission'))) {
-      $extra['links']['permissions'] = array(
-        '#type' => 'link',
-        '#title' => t('Permissions'),
-        '#href' => 'admin/people/permissions',
-        '#options' => array('fragment' => 'module-' . $filename, 'attributes' => array('class' => array('module-link', 'module-link-permissions'), 'title' => t('Configure permissions'))),
-      );
-    }
-    // Generate link for module's configuration page, if the module provides
-    // one.
-    if ($module->status && isset($module->info['configure'])) {
-      $configure_link = menu_get_item($module->info['configure']);
-      if ($configure_link['access']) {
-        $extra['links']['configure'] = array(
-          '#type' => 'link',
-          '#title' => t('Configure'),
-          '#href' => $configure_link['href'],
-          '#options' => array('attributes' => array('class' => array('module-link', 'module-link-configure'), 'title' => $configure_link['description'])),
-        );
-      }
-    }
-
-    // If this module is required by other modules, list those, and then make it
-    // impossible to disable this one.
-    foreach ($module->required_by as $required_by => $v) {
-      // Hidden modules are unset already.
-      if (isset($visible_files[$required_by])) {
-        if ($files[$required_by]->status == 1 && $module->status == 1) {
-          $extra['required_by'][] = t('@module', 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']));
-        }
-      }
-    }
-    $form['modules'][$module->info['package']][$filename] = _system_modules_build_row($module->info, $extra);
-  }
-
-  // Add basic information to the details.
-  foreach (element_children($form['modules']) as $package) {
-    $form['modules'][$package] += array(
-      '#type' => 'details',
-      '#title' => t($package),
-      '#theme' => 'system_modules_details',
-      '#header' => array(
-        array('data' => t('<span class="visually-hidden">Enabled</span>'), 'class' => array('checkbox')),
-        array('data' => t('Name'), 'class' => array('name')),
-        array('data' => t('Description'), 'class' => array('description', RESPONSIVE_PRIORITY_LOW)),
-      ),
-      // Ensure that the "Core" package comes first.
-      '#weight' => $package == 'Core' ? -10 : NULL,
-    );
-  }
-
-  // Lastly, sort all packages by title.
-  uasort($form['modules'], 'element_sort_by_title');
-
-  $form['#attached']['library'][] = array('system', 'drupal.system.modules');
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save configuration'),
-  );
-  $form['#action'] = url('admin/modules/list/confirm');
-
-  return $form;
-}
-
-/**
  * Array sorting callback; sorts modules or themes by their name.
  */
 function system_sort_modules_by_info_name($a, $b) {
@@ -549,221 +352,6 @@ function system_sort_themes($a, $b) {
 }
 
 /**
- * Build a table row for the system modules page.
- */
-function _system_modules_build_row($info, $extra) {
-  // Add in the defaults.
-  $extra += array(
-    'requires' => array(),
-    'required_by' => array(),
-    'disabled' => FALSE,
-    'enabled' => FALSE,
-    'links' => array(),
-  );
-  $form = array(
-    '#tree' => TRUE,
-  );
-  // Set the basic properties.
-  $form['name'] = array(
-    '#markup' => $info['name'],
-  );
-  $form['description'] = array(
-    '#markup' => t($info['description']),
-  );
-  $form['version'] = array(
-    '#markup' => $info['version'],
-  );
-  $form['#requires'] = $extra['requires'];
-  $form['#required_by'] = $extra['required_by'];
-
-  // Check the compatibilities.
-  $compatible = TRUE;
-  $status_short = '';
-  $status_long = '';
-
-  // Check the core compatibility.
-  if (!isset($info['core']) || $info['core'] != DRUPAL_CORE_COMPATIBILITY) {
-    $compatible = FALSE;
-    $status_short .= t('Incompatible with this version of Drupal core.');
-    $status_long .= t('This version is not compatible with Drupal !core_version and should be replaced.', array('!core_version' => DRUPAL_CORE_COMPATIBILITY));
-  }
-
-  // Ensure this module is compatible with the currently installed version of PHP.
-  if (version_compare(phpversion(), $info['php']) < 0) {
-    $compatible = FALSE;
-    $status_short .= t('Incompatible with this version of PHP');
-    $php_required = $info['php'];
-    if (substr_count($info['php'], '.') < 2) {
-      $php_required .= '.*';
-    }
-    $status_long .= t('This module requires PHP version @php_required and is incompatible with PHP version !php_version.', array('@php_required' => $php_required, '!php_version' => phpversion()));
-  }
-
-  // If this module is compatible, present a checkbox indicating
-  // this module may be installed. Otherwise, show a big red X.
-  if ($compatible) {
-    $form['enable'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Enable'),
-      '#default_value' => $extra['enabled'],
-      '#attributes' => array('role' => 'disabled'),
-    );
-    if ($extra['disabled']) {
-      $form['enable']['#disabled'] = TRUE;
-    }
-  }
-  else {
-    $form['enable'] = array(
-      '#markup' =>  theme('image', array('uri' => 'core/misc/watchdog-error.png', 'alt' => $status_short, 'title' => $status_short)),
-    );
-    $form['description']['#markup'] .= theme('system_modules_incompatible', array('message' => $status_long));
-  }
-
-  // Build operation links.
-  foreach (array('help', 'permissions', 'configure') as $key) {
-    $form['links'][$key] = (isset($extra['links'][$key]) ? $extra['links'][$key] : array());
-  }
-
-  return $form;
-}
-
-/**
- * Submit callback; handles modules form submission.
- */
-function system_modules_submit($form, &$form_state) {
-  include_once DRUPAL_ROOT . '/core/includes/install.inc';
-
-  // Builds list of modules.
-  $modules = array();
-  // If we're not coming from the confirmation form, build the list of modules.
-  if (empty($form_state['storage'])) {
-    // If we're not coming from the confirmation form, build the module list.
-    foreach ($form_state['values']['modules'] as $group_name => $group) {
-      foreach ($group as $module => $enabled) {
-        $modules[$module] = array('group' => $group_name, 'enabled' => $enabled['enable']);
-      }
-    }
-  }
-  else {
-    // If we are coming from the confirmation form, fetch
-    // the modules out of $form_state.
-    $modules = $form_state['storage']['modules'];
-  }
-
-  // Collect data for all modules to be able to determine dependencies.
-  $files = system_rebuild_module_data();
-
-  // Sorts modules by weight.
-  $sort = array();
-  foreach (array_keys($modules) as $module) {
-    $sort[$module] = $files[$module]->sort;
-  }
-  array_multisort($sort, $modules);
-
-  // Makes sure all required modules are set to be enabled.
-  $more_required = array();
-  $missing_modules = array();
-  foreach ($modules as $name => $module) {
-    if ($module['enabled']) {
-      // 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.
-      $dependencies = array();
-      foreach (array_keys($files[$name]->requires) as $required) {
-        if (empty($modules[$required]['enabled'])) {
-          if (isset($files[$required])) {
-            $dependencies[] = $files[$required]->info['name'];
-            $modules[$required]['enabled'] = TRUE;
-          }
-          else {
-            $missing_modules[$required]['depends'][] = $name;
-            $modules[$name]['enabled'] = FALSE;
-          }
-        }
-      }
-
-      // Stores additional modules that need to be enabled in $more_required.
-      if (!empty($dependencies)) {
-        $more_required[$name] = array(
-          'name' => $files[$name]->info['name'],
-          'requires' => $dependencies,
-        );
-      }
-    }
-  }
-
-  // Redirects to confirmation form if more modules need to be enabled.
-  if ((!empty($more_required) || !empty($missing_modules)) && !isset($form_state['values']['confirm'])) {
-    $form_state['storage'] = array(
-      'more_required' => $more_required,
-      'modules' => $modules,
-      'missing_modules' => $missing_modules,
-    );
-    $form_state['rebuild'] = TRUE;
-    return;
-  }
-
-  // Invokes hook_requirements('install').  If failures are detected, makes sure
-  // the dependent modules aren't installed either.
-  foreach ($modules as $name => $module) {
-    // Only invoke hook_requirements() on modules that are going to be installed.
-    if ($module['enabled'] && drupal_get_installed_schema_version($name) == SCHEMA_UNINSTALLED) {
-      if (!drupal_check_module($name)) {
-        $modules[$name]['enabled'] = FALSE;
-        foreach (array_keys($files[$name]->required_by) as $required_by) {
-          $modules[$required_by]['enabled'] = FALSE;
-        }
-      }
-    }
-  }
-
-  // Initializes array of actions.
-  $actions = array(
-    'enable' => array(),
-    'disable' => array(),
-    'install' => array(),
-  );
-
-  // Builds arrays of modules that need to be enabled, disabled, and installed.
-  foreach ($modules as $name => $module) {
-    if ($module['enabled']) {
-      if (drupal_get_installed_schema_version($name) == SCHEMA_UNINSTALLED) {
-        $actions['install'][] = $name;
-        $actions['enable'][] = $name;
-      }
-      elseif (!module_exists($name)) {
-        $actions['enable'][] = $name;
-      }
-    }
-    elseif (module_exists($name)) {
-      $actions['disable'][] = $name;
-    }
-  }
-
-  // Gets list of modules prior to install process, unsets $form_state['storage']
-  // so we don't get redirected back to the confirmation form.
-  $pre_install_list = Drupal::moduleHandler()->getModuleList();
-  unset($form_state['storage']);
-
-  // 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);
-
-  // Gets module list after install process, flushes caches and displays a
-  // message if there are changes.
-  $post_install_list = Drupal::moduleHandler()->getModuleList();
-  if ($pre_install_list != $post_install_list) {
-    drupal_flush_all_caches();
-    drupal_set_message(t('The configuration options have been saved.'));
-  }
-
-  $form_state['redirect'] = 'admin/modules';
-}
-
-/**
  * Uninstall functions
  */
 
@@ -819,7 +407,7 @@ function system_modules_uninstall($form, $form_state = NULL) {
       foreach (array_keys($module->required_by) as $dependent) {
         if ($dependent != $profile && drupal_get_installed_schema_version($dependent) != SCHEMA_UNINSTALLED) {
           $dependent_name = isset($all_modules[$dependent]->info['name']) ? $all_modules[$dependent]->info['name'] : $dependent;
-          $form['modules'][$module->name]['#required_by'][] = $dependent_name;
+          $form['modules'][$module->name]['#dependents'][] = $dependent_name;
           $form['uninstall'][$module->name]['#disabled'] = TRUE;
         }
       }
@@ -1146,47 +734,52 @@ function theme_system_modules_details($variables) {
     $module = $form[$key];
     // Create the row for the table.
     $row = array();
-    // Add the checkbox into the first cell.
-    unset($module['enable']['#title']);
-    $module['#requires'] = array_filter($module['#requires']);
-    $module['#required_by'] = array_filter($module['#required_by']);
+    $module['#dependencies'] = array_filter($module['#dependencies']);
+    $module['#dependents'] = array_filter($module['#dependents']);
 
-    $requires = !empty($module['#requires']);
-    $required_by = !empty($module['#required_by']);
+    $dependencies = !empty($module['#dependencies']);
+    $dependents = !empty($module['#dependents']);
     $version = !empty($module['version']['#markup']);
 
-    $row[] = array('class' => array('checkbox'), 'data' => drupal_render($module['enable']));
+    // Add the checkbox into the first cell.
+    unset($module['enable']['#title']);
+    $row[] = array(
+      'class' => array('checkbox'),
+      'data' => drupal_render($module['enable']),
+    );
 
-    // Add the module label and expand/collapse functionalty.
-    $col2 = '<label id="module-' . $key . '" for="' . $module['enable']['#id'] . '" class="module-name table-filter-text-source">' . drupal_render($module['name']) . '</label>';
-    $row[] = array('class' => array('module'), 'data' => $col2);
+    // Add the module label and expand/collapse functionality.
+    $row[] = array(
+      'class' => array('module'),
+      'data' => '<label id="module-' . $key . '" for="' . $module['enable']['#id'] . '" class="module-name table-filter-text-source">' . drupal_render($module['name']) . '</label>',
+    );
 
     // Add the description, along with any modules it requires.
     $description = '<span class="details"><span class="text table-filter-text-source">' . drupal_render($module['description']) . '</span></span>';
-    if ($version || $requires || $required_by) {
-      $description .= ' <div class="requirements">';
+    if ($version || $dependencies || $dependents) {
+      $description .= '<div class="requirements">';
       if ($version) {
         $description .= '<div class="admin-requirements">' . t('Version: !module-version', array('!module-version' => drupal_render($module['version']))) . '</div>';
       }
-      if ($requires) {
-        $description .= '<div class="admin-requirements">' . t('Requires: !module-list', array('!module-list' => implode(', ', $module['#requires']))) . '</div>';
+      if ($dependencies) {
+        $description .= '<div class="admin-requirements">' . t('Requires: !module-list', array('!module-list' => implode(', ', $module['#dependencies']))) . '</div>';
       }
-      if ($required_by) {
-        $description .= '<div class="admin-requirements">' . t('Required by: !module-list', array('!module-list' => implode(', ', $module['#required_by']))) . '</div>';
+      if ($dependents) {
+        $description .= '<div class="admin-requirements">' . t('Required by: !module-list', array('!module-list' => implode(', ', $module['#dependents']))) . '</div>';
       }
       $description .= '</div>';
     }
-    $links = '';
-    foreach (array('help', 'permissions', 'configure') as $key) {
-      $links .= drupal_render($module['links'][$key]);
-    }
-    if ($links) {
-      $description .= '  <div class="links">';
+
+    if ($links = drupal_render($module['links'])) {
+      $description .= '<div class="links">';
       $description .= $links;
       $description .= '</div>';
     }
-    $col4 = '<div class="inner" tabindex="0" role="button"><span class="module-description-prefix visually-hidden">Show description</span> ' . $description . '</div>';
-    $row[] = array('class' => array('description', 'expand'), 'data' => $col4);
+
+    $row[] = array(
+      'class' => array('description', 'expand'),
+      'data' => '<div class="inner" tabindex="0" role="button"><span class="module-description-prefix visually-hidden">' . t('Show description') . '</span> ' . $description . '</div>',
+    );
 
     $rows[] = $row;
   }
@@ -1233,11 +826,11 @@ function theme_system_modules_uninstall($variables) {
   // Display table.
   $rows = array();
   foreach (element_children($form['modules']) as $module) {
-    if (!empty($form['modules'][$module]['#required_by'])) {
-      $disabled_message = format_plural(count($form['modules'][$module]['#required_by']),
+    if (!empty($form['modules'][$module]['#dependents'])) {
+      $disabled_message = format_plural(count($form['modules'][$module]['#dependents']),
         'To uninstall @module, the following module must be uninstalled first: @required_modules',
         'To uninstall @module, the following modules must be uninstalled first: @required_modules',
-        array('@module' => $form['modules'][$module]['#module_name'], '@required_modules' => implode(', ', $form['modules'][$module]['#required_by'])));
+        array('@module' => $form['modules'][$module]['#dependents'], '@required_modules' => implode(', ', $form['modules'][$module]['#dependents'])));
       $disabled_message = '<div class="admin-requirements">' . $disabled_message . '</div>';
     }
     else {
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index a6a7786..6b63142 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -719,23 +719,22 @@ function system_menu() {
   $items['admin/modules'] = array(
     'title' => 'Extend',
     'description' => 'Add and enable modules to extend site functionality.',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('system_modules'),
-    'access arguments' => array('administer modules'),
-    'file' => 'system.admin.inc',
+    'route_name' => 'system_modules_list',
     'weight' => -2,
   );
   $items['admin/modules/list'] = array(
     'title' => 'List',
+    'access arguments' => array('administer modules'),
     'type' => MENU_DEFAULT_LOCAL_TASK,
   );
   $items['admin/modules/list/confirm'] = array(
     'title' => 'List',
-    'access arguments' => array('administer modules'),
+    'route_name' => 'system_modules_list_confirm',
     'type' => MENU_VISIBLE_IN_BREADCRUMB,
   );
   $items['admin/modules/uninstall'] = array(
     'title' => 'Uninstall',
+    'page callback' => 'drupal_get_form',
     'page arguments' => array('system_modules_uninstall'),
     'access arguments' => array('administer modules'),
     'type' => MENU_LOCAL_TASK,
diff --git a/core/modules/system/system.routing.yml b/core/modules/system/system.routing.yml
index 1e09f79..ae1f613 100644
--- a/core/modules/system/system.routing.yml
+++ b/core/modules/system/system.routing.yml
@@ -95,6 +95,20 @@ system_run_cron:
   requirements:
     _permission: 'administer site configuration'
 
+system_modules_list:
+  pattern: 'admin/modules'
+  defaults:
+    _form: 'Drupal\system\Form\ModulesListForm'
+  requirements:
+    _permission: 'administer modules'
+
+system_modules_list_confirm:
+  pattern: 'admin/modules/list/confirm'
+  defaults:
+    _form: 'Drupal\system\Form\ModulesListConfirmForm'
+  requirements:
+    _permission: 'administer modules'
+
 date_format_delete:
   pattern: 'admin/config/regional/date-time/formats/{format_id}/delete'
   defaults:
diff --git a/core/modules/system/tests/modules/requirements1_test/requirements1_test.info.yml b/core/modules/system/tests/modules/requirements1_test/requirements1_test.info.yml
index 789cf27..bdcb282 100644
--- a/core/modules/system/tests/modules/requirements1_test/requirements1_test.info.yml
+++ b/core/modules/system/tests/modules/requirements1_test/requirements1_test.info.yml
@@ -4,4 +4,4 @@ description: 'Tests that a module is not installed when it fails hook_requiremen
 package: Testing
 version: VERSION
 core: 8.x
-hidden: true
+hidden: false
diff --git a/core/modules/system/tests/modules/requirements2_test/requirements2_test.info.yml b/core/modules/system/tests/modules/requirements2_test/requirements2_test.info.yml
index ed093d8..2c69056 100644
--- a/core/modules/system/tests/modules/requirements2_test/requirements2_test.info.yml
+++ b/core/modules/system/tests/modules/requirements2_test/requirements2_test.info.yml
@@ -7,4 +7,4 @@ dependencies:
 package: Testing
 version: VERSION
 core: 8.x
-hidden: true
+hidden: false
