diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index cf0e3dd..a585787 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -721,9 +721,9 @@ function drupal_settings_initialize() {
  * configuration. For example, a module 'foo' may legally be be located
  * in any of these three places:
  *
- * core/modules/foo/foo.module
- * modules/foo/foo.module
- * sites/example.com/modules/foo/foo.module
+ * core/modules/foo/foo.info.yml
+ * modules/foo/foo.info.yml
+ * sites/example.com/modules/foo/foo.info.yml
  *
  * Calling drupal_get_filename('module', 'foo') will give you one of
  * the above, depending on where the module is located.
@@ -794,14 +794,14 @@ function drupal_get_filename($type, $name, $filename = NULL) {
         $dir = 'themes/engines';
         $extension = 'engine';
       }
-      elseif ($type == 'theme') {
+      elseif ($type == 'theme' || $type == 'module') {
         $extension = 'info.yml';
       }
       // Profiles are converted into modules in system_rebuild_module_data().
       // @todo Remove false-exposure of profiles as modules.
       elseif ($original_type == 'profile') {
         $dir = 'profiles';
-        $extension = 'profile';
+        $extension = 'info.yml';
       }
       else {
         $extension = $type;
@@ -816,7 +816,7 @@ function drupal_get_filename($type, $name, $filename = NULL) {
         // extension, not just the file we are currently looking for. This
         // prevents unnecessary scans from being repeated when this function is
         // called more than once in the same page request.
-        $matches = drupal_system_listing("/^" . DRUPAL_PHP_FUNCTION_PATTERN . "\.$extension$/", $dir);
+        $matches = drupal_system_listing("/^" . DRUPAL_PHP_FUNCTION_PATTERN . "\.$extension$/", $dir, $type);
         foreach ($matches as $matched_name => $file) {
           $files[$type][$matched_name] = $file->uri;
         }
@@ -1051,10 +1051,13 @@ function drupal_load($type, $name) {
   $filename = drupal_get_filename($type, $name);
 
   if ($filename) {
-    include_once DRUPAL_ROOT . '/' . $filename;
-    $files[$type][$name] = TRUE;
+    $file = DRUPAL_ROOT . '/' . str_replace('info.yml', $type, $filename);
+    if (file_exists($file)) {
+      include_once $file;
+      $files[$type][$name] = TRUE;
 
-    return TRUE;
+      return TRUE;
+    }
   }
 
   return FALSE;
diff --git a/core/includes/common.inc b/core/includes/common.inc
index 3ff8096..cf5389b 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -4193,12 +4193,12 @@ function drupal_cron_run() {
  *
  * @see \Drupal\Core\SystemListing::scan().
  */
-function drupal_system_listing($mask, $directory, $key = 'name', $min_depth = 1) {
+function drupal_system_listing($mask, $directory, $type, $key = 'name') {
   // As SystemListing is required to build a dependency injection container
   // from scratch and SystemListingInfo only extends SystemLising, this
   // class needs to be hardwired.
   $listing = new SystemListingInfo();
-  return $listing->scan($mask, $directory, $key, $min_depth);
+  return $listing->scan($mask, $directory, $type, $key);
 }
 
 /**
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 77771d8..b31ca77 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -490,7 +490,7 @@ function install_begin_request(&$install_state) {
   $install_state['database_tables_exist'] = !empty($task);
 
   // Add the list of available profiles to the installation state.
-  $install_state['profiles'] += drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles');
+  $install_state['profiles'] += drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info\.yml$/', 'profiles', 'profile');
 }
 
 /**
@@ -819,7 +819,7 @@ function install_tasks($install_state) {
   // Allow the installation profile to modify the full list of tasks.
   if (!empty($install_state['parameters']['profile'])) {
     $profile = $install_state['parameters']['profile'];
-    $profile_file = $install_state['profiles'][$profile]->uri;
+    $profile_file = dirname($install_state['profiles'][$profile]->uri) . '/' . $profile . '.profile';
     if (file_exists($profile_file)) {
       include_once $profile_file;
       $function = $install_state['parameters']['profile'] . '_install_tasks_alter';
@@ -1728,7 +1728,7 @@ function install_already_done_error() {
  */
 function install_load_profile(&$install_state) {
   $profile = $install_state['parameters']['profile'];
-  $profile_file = $install_state['profiles'][$profile]->uri;
+  $profile_file = dirname($install_state['profiles'][$profile]->uri) . '/' . $profile . '.profile';
   if (file_exists($profile_file)) {
     include_once $profile_file;
     $install_state['profile_info'] = install_profile_info($install_state['parameters']['profile'], $install_state['parameters']['langcode']);
diff --git a/core/includes/install.inc b/core/includes/install.inc
index b0ca296..e07ef4c 100644
--- a/core/includes/install.inc
+++ b/core/includes/install.inc
@@ -579,7 +579,7 @@ function drupal_verify_profile($install_state) {
 
   // Get a list of modules that exist in Drupal's assorted subdirectories.
   $present_modules = array();
-  foreach (drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules') as $present_module) {
+  foreach (drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info\.yml$/', 'modules', 'module') as $present_module) {
     $present_modules[] = $present_module->name;
   }
 
diff --git a/core/includes/module.inc b/core/includes/module.inc
index cdd3ddd..f482842 100644
--- a/core/includes/module.inc
+++ b/core/includes/module.inc
@@ -296,7 +296,7 @@ function module_uninstall($module_list = array(), $uninstall_dependents = TRUE)
  * Returns an array of modules required by core.
  */
 function drupal_required_modules() {
-  $files = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info.yml$/', 'modules');
+  $files = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info.yml$/', 'modules', 'module');
   $required = array();
 
   // An installation profile is required and one must always be loaded.
diff --git a/core/lib/Drupal/Core/Config/InstallStorage.php b/core/lib/Drupal/Core/Config/InstallStorage.php
index 53612b4..89b8ee6 100644
--- a/core/lib/Drupal/Core/Config/InstallStorage.php
+++ b/core/lib/Drupal/Core/Config/InstallStorage.php
@@ -111,8 +111,8 @@ public function listAll($prefix = '') {
   protected function getAllFolders() {
     if (!isset($this->folders)) {
       $this->folders = $this->getComponentNames('profile', array(drupal_get_profile()));
-      $this->folders += $this->getComponentNames('module', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules', 'name', 0)));
-      $this->folders += $this->getComponentNames('theme', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info.yml$/', 'themes')));
+      $this->folders += $this->getComponentNames('module', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info\.yml$/', 'modules', 'module')));
+      $this->folders += $this->getComponentNames('theme', array_keys(drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info\.yml$/', 'themes', 'theme')));
     }
     return $this->folders;
   }
diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index 6d7d4fa..f359d25 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -240,7 +240,7 @@ protected function moduleData($module) {
     if (!$this->moduleData) {
       // First, find profiles.
       $profiles_scanner = new SystemListing();
-      $all_profiles = $profiles_scanner->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles');
+      $all_profiles = $profiles_scanner->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info\.yml$/', 'profiles', 'profile');
       $profiles = array_keys(array_intersect_key($this->moduleList, $all_profiles));
       // If a module is within a profile directory but specifies another
       // profile for testing, it needs to be found in the parent profile.
@@ -251,7 +251,7 @@ protected function moduleData($module) {
       }
       // Now find modules.
       $modules_scanner = new SystemListing($profiles);
-      $this->moduleData = $all_profiles + $modules_scanner->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules');
+      $this->moduleData = $all_profiles + $modules_scanner->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info\.yml$/', 'modules', 'module');
     }
     return isset($this->moduleData[$module]) ? $this->moduleData[$module] : FALSE;
   }
diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php
index 656e918..efa0717 100644
--- a/core/lib/Drupal/Core/Extension/ModuleHandler.php
+++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php
@@ -96,8 +96,11 @@ public function load($name) {
     }
 
     if (isset($this->moduleList[$name])) {
-      $filename = $this->moduleList[$name];
-      include_once DRUPAL_ROOT . '/' . $filename;
+      $filename = DRUPAL_ROOT . '/' . $this->moduleList[$name];
+      $filename = str_replace('.info.yml', '.module', $filename);
+      if (file_exists($filename)) {
+        include_once $filename;
+      }
       $this->loadedFiles[$name] = TRUE;
       return TRUE;
     }
diff --git a/core/lib/Drupal/Core/SystemListing.php b/core/lib/Drupal/Core/SystemListing.php
index d627505..552f12e 100644
--- a/core/lib/Drupal/Core/SystemListing.php
+++ b/core/lib/Drupal/Core/SystemListing.php
@@ -64,6 +64,13 @@ function __construct($profiles = array()) {
    *   The subdirectory name in which the files are found. For example,
    *   'modules' will search all 'modules' directories and their
    *   sub-directories as explained above.
+   * @param string $type
+   *   The type of the extensions that should be included in results.
+   *   Possible values are:
+   *   - 'module'
+   *   - 'profile'
+   *   - 'theme'
+   *   - 'engine'
    * @param string $key
    *   (optional) The key to be used for the associative array returned.
    *   Possible values are:
@@ -81,7 +88,7 @@ function __construct($profiles = array()) {
    *   - 'filename': File name.
    *   - 'name': Name of file without the extension.
    */
-  function scan($mask, $directory, $key = 'name') {
+  function scan($mask, $directory, $type, $key = 'name') {
     if (!in_array($key, array('uri', 'filename', 'name'))) {
       $key = 'uri';
     }
@@ -109,7 +116,7 @@ function scan($mask, $directory, $key = 'name') {
     $files = array();
     // Get current list of items.
     foreach ($searchdir as $dir) {
-      $files = array_merge($files, $this->process($files, $this->scanDirectory($dir, $key, $mask, $nomask)));
+      $files = array_merge($files, $this->process($files, $this->scanDirectory($dir, $key, $mask, $nomask), $type));
     }
     return $files;
   }
@@ -141,7 +148,7 @@ protected function profiles($directory) {
    *   The processed list of file objects. For example, the SystemListingInfo
    *   class removes files not compatible with the current core version.
    */
-  protected function process(array $files, array $files_to_add) {
+  protected function process(array $files, array $files_to_add, $type) {
     return $files_to_add;
   }
 
@@ -204,6 +211,12 @@ protected function scanDirectory($dir, $key, $mask, $nomask) {
    *   A file object.
    */
   protected function processFile($file) {
+    // info, routing and services files have double extensions. The yaml one is
+    // already removed, but still the name is not actually the file name unless
+    // we strip the second extension as well.
+    $file->name = basename($file->name, '.info');
+    $file->name = basename($file->name, '.routing');
+    $file->name = basename($file->name, '.services');
   }
 
 }
diff --git a/core/lib/Drupal/Core/SystemListingInfo.php b/core/lib/Drupal/Core/SystemListingInfo.php
index 989b0f2..d66574b 100644
--- a/core/lib/Drupal/Core/SystemListingInfo.php
+++ b/core/lib/Drupal/Core/SystemListingInfo.php
@@ -43,7 +43,7 @@ protected function profiles($directory) {
   /**
    * Overrides Drupal\Core\SystemListing::process().
    */
-  protected function process(array $files, array $files_to_add) {
+  protected function process(array $files, array $files_to_add, $type) {
     // Duplicate files found in later search directories take precedence over
     // earlier ones, so we want them to overwrite keys in our resulting
     // $files array.
@@ -64,16 +64,13 @@ protected function process(array $files, array $files_to_add) {
         if (isset($info['core']) && $info['core'] != DRUPAL_CORE_COMPATIBILITY) {
           unset($files_to_add[$file_key]);
         }
+        // If the extension is different from the requested one, remove it.
+        if ($info['type'] != $type) {
+          unset($files_to_add[$file_key]);
+        }
       }
     }
     return $files_to_add;
   }
 
-  /**
-   * Overrides Drupal\Core\SystemListing::processFile().
-   */
-  protected function processFile($file) {
-    $file->name = basename($file->name, '.info');
-  }
-
 }
diff --git a/core/lib/Drupal/Core/Updater/Module.php b/core/lib/Drupal/Core/Updater/Module.php
index acc3028..daab4f1 100644
--- a/core/lib/Drupal/Core/Updater/Module.php
+++ b/core/lib/Drupal/Core/Updater/Module.php
@@ -49,10 +49,9 @@ public function isInstalled() {
    * Implements Drupal\Core\Updater\UpdaterInterface::canUpdateDirectory().
    */
   public static function canUpdateDirectory($directory) {
-    if (file_scan_directory($directory, '/.*\.module$/')) {
-      return TRUE;
-    }
-    return FALSE;
+    $files = file_scan_directory($directory, '/.*\.info\.yml$/');
+    $info = drupal_parse_info_file(reset($files)->uri);
+    return $info['type'] == 'module';
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Updater/Theme.php b/core/lib/Drupal/Core/Updater/Theme.php
index 4bd716a..3f02b0d 100644
--- a/core/lib/Drupal/Core/Updater/Theme.php
+++ b/core/lib/Drupal/Core/Updater/Theme.php
@@ -49,11 +49,9 @@ public function isInstalled() {
    * Implements Drupal\Core\Updater\UpdaterInterface::canUpdateDirectory().
    */
   static function canUpdateDirectory($directory) {
-    // This is a lousy test, but don't know how else to confirm it is a theme.
-    if (file_scan_directory($directory, '/.*\.module$/')) {
-      return FALSE;
-    }
-    return TRUE;
+    $files = file_scan_directory($directory, '/.*\.info\.yml$/');
+    $info = drupal_parse_info_file(reset($files)->uri);
+    return $info['type'] == 'theme';
   }
 
   /**
diff --git a/core/modules/action/tests/action_bulk_test/action_bulk_test.module b/core/modules/action/tests/action_bulk_test/action_bulk_test.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/action/tests/action_bulk_test/action_bulk_test.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/aggregator/tests/modules/aggregator_test_views/aggregator_test_views.module b/core/modules/aggregator/tests/modules/aggregator_test_views/aggregator_test_views.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/aggregator/tests/modules/aggregator_test_views/aggregator_test_views.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/block/tests/block_test_views/block_test_views.module b/core/modules/block/tests/block_test_views/block_test_views.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/block/tests/block_test_views/block_test_views.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/comment/tests/modules/comment_test_views/comment_test_views.module b/core/modules/comment/tests/modules/comment_test_views/comment_test_views.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/comment/tests/modules/comment_test_views/comment_test_views.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/config/tests/config_integration_test/config_integration_test.module b/core/modules/config/tests/config_integration_test/config_integration_test.module
deleted file mode 100644
index 9c92696..0000000
--- a/core/modules/config/tests/config_integration_test/config_integration_test.module
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-/**
- * @file
- * ConfigTest entity integration test module.
- */
diff --git a/core/modules/config/tests/config_test_invalid_name/config_test_invalid_name.module b/core/modules/config/tests/config_test_invalid_name/config_test_invalid_name.module
deleted file mode 100644
index 890776d..0000000
--- a/core/modules/config/tests/config_test_invalid_name/config_test_invalid_name.module
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-/**
- * @file
- * Test module containing a configuration file with an invalid name.
- */
diff --git a/core/modules/contact/tests/modules/contact_test_views/contact_test_views.module b/core/modules/contact/tests/modules/contact_test_views/contact_test_views.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/contact/tests/modules/contact_test_views/contact_test_views.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/content_translation/tests/modules/content_translation_test_views/content_translation_test_views.module b/core/modules/content_translation/tests/modules/content_translation_test_views/content_translation_test_views.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/content_translation/tests/modules/content_translation_test_views/content_translation_test_views.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/edit/tests/modules/edit_test.module b/core/modules/edit/tests/modules/edit_test.module
deleted file mode 100644
index d74528d..0000000
--- a/core/modules/edit/tests/modules/edit_test.module
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-/**
- * @file
- * Helper module for the Edit tests.
- */
diff --git a/core/modules/entity_reference/tests/modules/entity_reference_test/entity_reference_test.module b/core/modules/entity_reference/tests/modules/entity_reference_test/entity_reference_test.module
deleted file mode 100644
index 37dc050..0000000
--- a/core/modules/entity_reference/tests/modules/entity_reference_test/entity_reference_test.module
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-/**
- * @file
- * Helper module for the Entity Reference tests.
- */
diff --git a/core/modules/field/tests/modules/field_test_config/field_test_config.module b/core/modules/field/tests/modules/field_test_config/field_test_config.module
deleted file mode 100644
index 3d7730d..0000000
--- a/core/modules/field/tests/modules/field_test_config/field_test_config.module
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-/**
- * @file
- * Helper module for the Field API configuration tests.
- */
diff --git a/core/modules/field/tests/modules/field_test_views/field_test_views.module b/core/modules/field/tests/modules/field_test_views/field_test_views.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/field/tests/modules/field_test_views/field_test_views.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/field_ui/tests/modules/field_ui_test/field_ui_test.module b/core/modules/field_ui/tests/modules/field_ui_test/field_ui_test.module
deleted file mode 100644
index dae31c6..0000000
--- a/core/modules/field_ui/tests/modules/field_ui_test/field_ui_test.module
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-/**
- * @file
- * Field UI test module.
- */
diff --git a/core/modules/file/tests/modules/file_test_views/file_test_views.module b/core/modules/file/tests/modules/file_test_views/file_test_views.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/file/tests/modules/file_test_views/file_test_views.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/forum/tests/modules/forum_test_views/forum_test_views.module b/core/modules/forum/tests/modules/forum_test_views/forum_test_views.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/forum/tests/modules/forum_test_views/forum_test_views.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/hal/hal.module b/core/modules/hal/hal.module
deleted file mode 100644
index 72e9b86..0000000
--- a/core/modules/hal/hal.module
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-/**
- * @file
- * Drupal-required module file for HAL module.
- */
diff --git a/core/modules/node/tests/modules/node_test_views/node_test_views.module b/core/modules/node/tests/modules/node_test_views/node_test_views.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/node/tests/modules/node_test_views/node_test_views.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/rest/tests/modules/rest_test_views/rest_test_views.module b/core/modules/rest/tests/modules/rest_test_views/rest_test_views.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/rest/tests/modules/rest_test_views/rest_test_views.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/serialization/serialization.module b/core/modules/serialization/serialization.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/serialization/serialization.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/serialization/tests/serialization_test/serialization_test.module b/core/modules/serialization/tests/serialization_test/serialization_test.module
deleted file mode 100644
index c4e35c7..0000000
--- a/core/modules/serialization/tests/serialization_test/serialization_test.module
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-
-/**
- * @file
- * Helper module for serialization tests. This file is empty, because all
- * implementation is in autoloaded classes.
- */
diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module
index 5461cab..d11bc07 100644
--- a/core/modules/simpletest/simpletest.module
+++ b/core/modules/simpletest/simpletest.module
@@ -448,7 +448,7 @@ function simpletest_test_get_all() {
       $classes = array();
       $module_data = system_rebuild_module_data();
       $all_data = $module_data + system_rebuild_theme_data();
-      $all_data += drupal_system_listing('/\.profile$/', 'profiles', 'name');
+      $all_data += drupal_system_listing('/\.info\.yml$/', 'profiles', 'profile');
       foreach ($all_data as $name => $data) {
         // Build directory in which the test files would reside.
         $tests_dir = DRUPAL_ROOT . '/' . dirname($data->uri) . '/lib/Drupal/' . $name . '/Tests';
@@ -512,12 +512,12 @@ function simpletest_classloader_register() {
   // @see drupal_get_filename()
   $types = array(
     'theme_engine' => array('dir' => 'themes/engines', 'extension' => 'engine'),
-    'module' => array('dir' => 'modules', 'extension' => 'module'),
-    'theme' => array('dir' => 'themes', 'extension' => 'info'),
-    'profile' => array('dir' => 'profiles', 'extension' => 'profile'),
+    'module' => array('dir' => 'modules', 'extension' => 'info\.yml'),
+    'theme' => array('dir' => 'themes', 'extension' => 'info\.yml'),
+    'profile' => array('dir' => 'profiles', 'extension' => 'info\.yml'),
   );
   foreach ($types as $type => $info) {
-    $matches = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.' . $info['extension'] . '$/', $info['dir']);
+    $matches = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.' . $info['extension'] . '$/', $info['dir'], $type);
     foreach ($matches as $name => $file) {
       drupal_classloader_register($name, dirname($file->uri));
       drupal_classloader()->addPrefix('Drupal\\' . $name . '\\Tests', DRUPAL_ROOT . '/' . dirname($file->uri) . '/tests');
diff --git a/core/modules/statistics/tests/modules/statistics_test_views/statistics_test_views.module b/core/modules/statistics/tests/modules/statistics_test_views/statistics_test_views.module
deleted file mode 100644
index e69de29..0000000
diff --git a/core/modules/system/lib/Drupal/system/Tests/Bootstrap/GetFilenameUnitTest.php b/core/modules/system/lib/Drupal/system/Tests/Bootstrap/GetFilenameUnitTest.php
index d2d4cc7..4b80dbd 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Bootstrap/GetFilenameUnitTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Bootstrap/GetFilenameUnitTest.php
@@ -30,7 +30,7 @@ function testDrupalGetFilename() {
     // does not exist.
     $this->assertFalse(drupal_container()->has('keyvalue'), 'The container has no keyvalue service.');
     // Retrieving the location of a module.
-    $this->assertIdentical(drupal_get_filename('module', 'php'), 'core/modules/php/php.module', 'Retrieve module location.');
+    $this->assertIdentical(drupal_get_filename('module', 'php'), 'core/modules/php/php.info.yml', 'Retrieve module location.');
 
     // Retrieving the location of a theme.
     $this->assertIdentical(drupal_get_filename('theme', 'stark'), 'core/themes/stark/stark.info.yml', 'Retrieve theme location.');
@@ -40,7 +40,7 @@ function testDrupalGetFilename() {
 
     // Retrieving the location of a profile. Profiles are a special case with
     // a fixed location and naming.
-    $this->assertIdentical(drupal_get_filename('profile', 'standard'), 'core/profiles/standard/standard.profile', 'Retrieve installation profile location.');
+    $this->assertIdentical(drupal_get_filename('profile', 'standard'), 'core/profiles/standard/standard.info.yml', 'Retrieve installation profile location.');
 
     // When a file is not found in the database cache, drupal_get_filename()
     // searches several locations on the filesystem, including the core/
diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/SystemListingTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/SystemListingTest.php
index ee1f12b..23303db 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Common/SystemListingTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Common/SystemListingTest.php
@@ -48,17 +48,17 @@ function testDirectoryPrecedence() {
     // meaning, so assert their presence first.
     foreach ($expected_directories as $module => $directories) {
       foreach ($directories as $directory) {
-        $filename = "$directory/$module/$module.module";
+        $filename = "$directory/$module/$module.info.yml";
         $this->assertTrue(file_exists(DRUPAL_ROOT . '/' . $filename), format_string('@filename exists.', array('@filename' => $filename)));
       }
     }
 
     // Now scan the directories and check that the files take precedence as
     // expected.
-    $files = drupal_system_listing('/\.module$/', 'modules');
+    $files = drupal_system_listing('/\.info\.yml$/', 'modules', 'module');
     foreach ($expected_directories as $module => $directories) {
       $expected_directory = array_shift($directories);
-      $expected_filename = "$expected_directory/$module/$module.module";
+      $expected_filename = "$expected_directory/$module/$module.info.yml";
       $this->assertEqual($files[$module]->uri, $expected_filename, format_string('Module @module was found at @filename.', array('@module' => $module, '@filename' => $expected_filename)));
     }
   }
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 3d7896b..340c246 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -10,6 +10,8 @@
 use Drupal\Core\Language\Language;
 use Drupal\Core\Utility\ModuleInfo;
 use Drupal\Core\TypedData\Primitive;
+use Drupal\Core\SystemListing;
+use Drupal\Core\SystemListingInfo;
 use Drupal\system\Plugin\Block\SystemMenuBlock;
 use Symfony\Component\HttpFoundation\JsonResponse;
 use Symfony\Component\HttpFoundation\RedirectResponse;
@@ -2812,11 +2814,12 @@ function system_get_module_info($property) {
  *   An associative array of module information.
  */
 function _system_rebuild_module_data() {
+  $scanner = new SystemListingInfo();
   // Find modules
-  $modules = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules', 'name', 0);
+  $modules = $scanner->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info\.yml$/', 'modules', 'module');
 
   // Find installation profiles.
-  $profiles = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles', 'name', 0);
+  $profiles = $scanner->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info\.yml$/', 'profiles', 'profile');
 
   // Include the installation profile in modules that are loaded.
   $profile = drupal_get_profile();
@@ -2943,8 +2946,9 @@ function _system_update_bootstrap_status() {
  *   An associative array of themes information.
  */
 function _system_rebuild_theme_data() {
+  $scanner = new SystemListingInfo();
   // Find themes
-  $themes = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info.yml$/', 'themes');
+  $themes = $scanner->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.info.yml$/', 'themes', 'theme');
   // Allow modules to add further themes.
   if ($module_themes = module_invoke_all('system_theme_info')) {
     foreach ($module_themes as $name => $uri) {
@@ -2957,8 +2961,9 @@ function _system_rebuild_theme_data() {
     }
   }
 
+  $scanner = new SystemListing();
   // Find theme engines
-  $engines = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.engine$/', 'themes/engines');
+  $engines = $scanner->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.engine$/', 'themes/engines', 'engine');
 
   // Set defaults for theme info.
   $defaults = array(
diff --git a/core/modules/system/tests/modules/action_test/action_test.module b/core/modules/system/tests/modules/action_test/action_test.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/system/tests/modules/action_test/action_test.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/system/tests/modules/cache_test/cache_test.module b/core/modules/system/tests/modules/cache_test/cache_test.module
deleted file mode 100644
index 3d2e68d..0000000
--- a/core/modules/system/tests/modules/cache_test/cache_test.module
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-/**
- * @file
- * Support module for testing the cache system.
- */
diff --git a/core/modules/system/tests/modules/config_upgrade/config_upgrade.module b/core/modules/system/tests/modules/config_upgrade/config_upgrade.module
deleted file mode 100644
index 461e96e..0000000
--- a/core/modules/system/tests/modules/config_upgrade/config_upgrade.module
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-/**
- * @file
- * A support module for update_variables_to_config() testing.
- */
diff --git a/core/modules/system/tests/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.module b/core/modules/system/tests/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/system/tests/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/system/tests/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.module b/core/modules/system/tests/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/system/tests/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/system/tests/modules/image_test/image_test.module b/core/modules/system/tests/modules/image_test/image_test.module
deleted file mode 100644
index 92f1ca2..0000000
--- a/core/modules/system/tests/modules/image_test/image_test.module
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-/**
- * @file
- * Helper module for the image tests.
- */
diff --git a/core/modules/system/tests/modules/invalid_module_name_over_the_maximum_allowed_character_length/invalid_module_name_over_the_maximum_allowed_character_length.module b/core/modules/system/tests/modules/invalid_module_name_over_the_maximum_allowed_character_length/invalid_module_name_over_the_maximum_allowed_character_length.module
deleted file mode 100644
index d0dc049..0000000
--- a/core/modules/system/tests/modules/invalid_module_name_over_the_maximum_allowed_character_length/invalid_module_name_over_the_maximum_allowed_character_length.module
+++ /dev/null
@@ -1,8 +0,0 @@
-<?php
-
-/**
- * @file
- * Module with a module name over the maximum allowed number of characters.
- *
- * @see DRUPAL_MODULE_NAME_MAX_LENGTH
- */
diff --git a/core/modules/system/tests/modules/module_autoload_test/module_autoload_test.module b/core/modules/system/tests/modules/module_autoload_test/module_autoload_test.module
deleted file mode 100644
index a4abe2d..0000000
--- a/core/modules/system/tests/modules/module_autoload_test/module_autoload_test.module
+++ /dev/null
@@ -1,2 +0,0 @@
-<?php
-
diff --git a/core/modules/system/tests/modules/paramconverter_test/paramconverter_test.module b/core/modules/system/tests/modules/paramconverter_test/paramconverter_test.module
deleted file mode 100644
index c37a9e2..0000000
--- a/core/modules/system/tests/modules/paramconverter_test/paramconverter_test.module
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-/**
- * @file
- * Intentionally blank file.
- */
diff --git a/core/modules/system/tests/modules/requirements1_test/requirements1_test.module b/core/modules/system/tests/modules/requirements1_test/requirements1_test.module
deleted file mode 100644
index e52266b..0000000
--- a/core/modules/system/tests/modules/requirements1_test/requirements1_test.module
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-
-/**
- * @file
- * Tests that a module is not installed when it fails
- * hook_requirements('install').
- */
diff --git a/core/modules/system/tests/modules/requirements2_test/requirements2_test.module b/core/modules/system/tests/modules/requirements2_test/requirements2_test.module
deleted file mode 100644
index a4f4305..0000000
--- a/core/modules/system/tests/modules/requirements2_test/requirements2_test.module
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-
-/**
- * @file
- * Tests that a module is not installed when the one it depends on fails
- * hook_requirements('install').
- */
diff --git a/core/modules/system/tests/modules/serialization_test/serialization_test.info.yml b/core/modules/system/tests/modules/serialization_test/serialization_test.info.yml
deleted file mode 100644
index f10027e..0000000
--- a/core/modules/system/tests/modules/serialization_test/serialization_test.info.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-name: 'Serialization test module'
-type: module
-description: 'Support module for serialization tests.'
-package: Testing
-core: 8.x
-hidden: true
diff --git a/core/modules/system/tests/modules/system_dependencies_test/system_dependencies_test.module b/core/modules/system/tests/modules/system_dependencies_test/system_dependencies_test.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/system/tests/modules/system_dependencies_test/system_dependencies_test.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/system/tests/modules/system_incompatible_core_version_dependencies_test/system_incompatible_core_version_dependencies_test.module b/core/modules/system/tests/modules/system_incompatible_core_version_dependencies_test/system_incompatible_core_version_dependencies_test.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/system/tests/modules/system_incompatible_core_version_dependencies_test/system_incompatible_core_version_dependencies_test.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/system/tests/modules/system_incompatible_core_version_test/system_incompatible_core_version_test.module b/core/modules/system/tests/modules/system_incompatible_core_version_test/system_incompatible_core_version_test.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/system/tests/modules/system_incompatible_core_version_test/system_incompatible_core_version_test.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/system/tests/modules/system_incompatible_module_version_dependencies_test/system_incompatible_module_version_dependencies_test.module b/core/modules/system/tests/modules/system_incompatible_module_version_dependencies_test/system_incompatible_module_version_dependencies_test.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/system/tests/modules/system_incompatible_module_version_dependencies_test/system_incompatible_module_version_dependencies_test.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/system/tests/modules/system_incompatible_module_version_test/system_incompatible_module_version_test.module b/core/modules/system/tests/modules/system_incompatible_module_version_test/system_incompatible_module_version_test.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/system/tests/modules/system_incompatible_module_version_test/system_incompatible_module_version_test.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/system/tests/modules/system_mail_failure_test/system_mail_failure_test.module b/core/modules/system/tests/modules/system_mail_failure_test/system_mail_failure_test.module
deleted file mode 100644
index 6acb6c4..0000000
--- a/core/modules/system/tests/modules/system_mail_failure_test/system_mail_failure_test.module
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-
-/**
- * @file
- * Disables the email function for testing purposes.
- */
-
diff --git a/core/modules/system/tests/modules/update_test_1/update_test_1.module b/core/modules/system/tests/modules/update_test_1/update_test_1.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/system/tests/modules/update_test_1/update_test_1.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/system/tests/modules/update_test_2/update_test_2.module b/core/modules/system/tests/modules/update_test_2/update_test_2.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/system/tests/modules/update_test_2/update_test_2.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/system/tests/modules/update_test_3/update_test_3.module b/core/modules/system/tests/modules/update_test_3/update_test_3.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/system/tests/modules/update_test_3/update_test_3.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/taxonomy_test_views.module b/core/modules/taxonomy/tests/modules/taxonomy_test_views/taxonomy_test_views.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/taxonomy_test_views.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/tracker/tests/modules/tracker_test_views/tracker_test_views.module b/core/modules/tracker/tests/modules/tracker_test_views/tracker_test_views.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/tracker/tests/modules/tracker_test_views/tracker_test_views.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/update/tests/aaa_update_test.tar.gz b/core/modules/update/tests/aaa_update_test.tar.gz
index 478f038..615cfcc 100644
--- a/core/modules/update/tests/aaa_update_test.tar.gz
+++ b/core/modules/update/tests/aaa_update_test.tar.gz
@@ -1,2 +1,3 @@
-^0tQ aaa_update_test.tar.gz Ak0+r<6u&l;KQlש 94	i_ֳJ,6dTʉ^"2S"RDlLWx9O=ҽ{שMܣ_$\Ks׺2|0NO켋}xՔqmXiڹ.ئoѹƇ$_4oH9=K};捧lY.hصO~mTK%R\eEQPU9?<=cl42>/KNXU
-'Ab              ھsM (  
\ No newline at end of file
+2Q aaa_update_test.tar.gz j p}
+riѻ<"v&1оt]a]le}?rrRj;{F3r<i̫h%^Q튋tNJ&o0KU`xtwwJ-_ԥw<#W-2$]ׄzky̚]ױ{,^x?8=fѺ1}w!~l\:yeA_>z>hB#}Z4.п
+                 YZ (  
\ No newline at end of file
diff --git a/core/modules/update/tests/aaa_update_test/aaa_update_test.module b/core/modules/update/tests/aaa_update_test/aaa_update_test.module
deleted file mode 100644
index 4d67b8e..0000000
--- a/core/modules/update/tests/aaa_update_test/aaa_update_test.module
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-/**
- * @file
- * Dummy module for testing Update status.
- */
diff --git a/core/modules/update/tests/modules/aaa_update_test/aaa_update_test.module b/core/modules/update/tests/modules/aaa_update_test/aaa_update_test.module
deleted file mode 100644
index 4d67b8e..0000000
--- a/core/modules/update/tests/modules/aaa_update_test/aaa_update_test.module
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-/**
- * @file
- * Dummy module for testing Update status.
- */
diff --git a/core/modules/update/tests/modules/bbb_update_test/bbb_update_test.module b/core/modules/update/tests/modules/bbb_update_test/bbb_update_test.module
deleted file mode 100644
index 4d67b8e..0000000
--- a/core/modules/update/tests/modules/bbb_update_test/bbb_update_test.module
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-/**
- * @file
- * Dummy module for testing Update status.
- */
diff --git a/core/modules/update/tests/modules/ccc_update_test/ccc_update_test.module b/core/modules/update/tests/modules/ccc_update_test/ccc_update_test.module
deleted file mode 100644
index 4d67b8e..0000000
--- a/core/modules/update/tests/modules/ccc_update_test/ccc_update_test.module
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-/**
- * @file
- * Dummy module for testing Update status.
- */
diff --git a/core/modules/user/tests/modules/user_custom_phpass_params_test/user_custom_phpass_params_test.module b/core/modules/user/tests/modules/user_custom_phpass_params_test/user_custom_phpass_params_test.module
deleted file mode 100644
index e69de29..0000000
diff --git a/core/modules/user/tests/modules/user_test_views/user_test_views.module b/core/modules/user/tests/modules/user_test_views/user_test_views.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/user/tests/modules/user_test_views/user_test_views.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
diff --git a/core/modules/views/tests/modules/views_test_config/views_test_config.module b/core/modules/views/tests/modules/views_test_config/views_test_config.module
deleted file mode 100644
index b3d9bbc..0000000
--- a/core/modules/views/tests/modules/views_test_config/views_test_config.module
+++ /dev/null
@@ -1 +0,0 @@
-<?php
