diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 17c8e83..2cf9a99 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -158,6 +158,8 @@ define('REGISTRY_WRITE_LOOKUP_CACHE', 2);
  */
 define('DRUPAL_PHP_FUNCTION_PATTERN', '[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*');
 
+require_once DRUPAL_ROOT . '/includes/module-fs.inc';
+
 /**
  * Start the timer with the specified name. If you start and stop the same
  * timer multiple times, the measured intervals will be accumulated.
@@ -538,102 +540,6 @@ function drupal_settings_initialize() {
 }
 
 /**
- * Returns and optionally sets the filename for a system item (module,
- * theme, etc.). The filename, whether provided, cached, or retrieved
- * from the database, is only returned if the file exists.
- *
- * This function plays a key role in allowing Drupal's resources (modules
- * and themes) to be located in different places depending on a site's
- * configuration. For example, a module 'foo' may legally be be located
- * in any of these three places:
- *
- * modules/foo/foo.module
- * sites/all/modules/foo/foo.module
- * sites/example.com/modules/foo/foo.module
- *
- * Calling drupal_get_filename('module', 'foo') will give you one of
- * the above, depending on where the module is located.
- *
- * @param $type
- *   The type of the item (i.e. theme, theme_engine, module, profile).
- * @param $name
- *   The name of the item for which the filename is requested.
- * @param $filename
- *   The filename of the item if it is to be set explicitly rather
- *   than by consulting the database.
- *
- * @return
- *   The filename of the requested item.
- */
-function drupal_get_filename($type, $name, $filename = NULL) {
-  // The location of files will not change during the request, so do not use
-  // drupal_static().
-  static $files = array();
-
-  if (!isset($files[$type])) {
-    $files[$type] = array();
-  }
-
-  if (!empty($filename) && file_exists($filename)) {
-    $files[$type][$name] = $filename;
-  }
-  elseif (isset($files[$type][$name])) {
-    // nothing
-  }
-  // Verify that we have an active database connection, before querying
-  // the database. This is required because this function is called both
-  // before we have a database connection (i.e. during installation) and
-  // when a database connection fails.
-  else {
-    try {
-      if (function_exists('db_query')) {
-        $file = db_query("SELECT filename FROM {system} WHERE name = :name AND type = :type", array(':name' => $name, ':type' => $type))->fetchField();
-        if (file_exists(DRUPAL_ROOT . '/' . $file)) {
-          $files[$type][$name] = $file;
-        }
-      }
-    }
-    catch (Exception $e) {
-      // The database table may not exist because Drupal is not yet installed,
-      // or the database might be down. We have a fallback for this case so we
-      // hide the error completely.
-    }
-    // Fallback to searching the filesystem if the database could not find the
-    // file or the file returned by the database is not found.
-    if (!isset($files[$type][$name])) {
-      // We have a consistent directory naming: modules, themes...
-      $dir = $type . 's';
-      if ($type == 'theme_engine') {
-        $dir = 'themes/engines';
-        $extension = 'engine';
-      }
-      elseif ($type == 'theme') {
-        $extension = 'info';
-      }
-      else {
-        $extension = $type;
-      }
-
-      if (!function_exists('drupal_system_listing')) {
-        require_once DRUPAL_ROOT . '/includes/common.inc';
-      }
-      // Scan the appropriate directories for all files with the requested
-      // 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, 'name', 0);
-      foreach ($matches as $matched_name => $file) {
-        $files[$type][$matched_name] = $file->uri;
-      }
-    }
-  }
-
-  if (isset($files[$type][$name])) {
-    return $files[$type][$name];
-  }
-}
-
-/**
  * Load the persistent variable table.
  *
  * The variable table is composed of values that have been saved in the table
@@ -838,10 +744,10 @@ function drupal_load($type, $name) {
     return TRUE;
   }
 
-  $filename = drupal_get_filename($type, $name);
+  $filename = DrupalModuleStreamWrapper::getBaseFilename($type, $name);
 
   if ($filename) {
-    include_once DRUPAL_ROOT . '/' . $filename;
+    include_once $filename;
     $files[$type][$name] = TRUE;
 
     return TRUE;
diff --git a/includes/common.inc b/includes/common.inc
index 4ec37dc..ee90e0c 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -2664,7 +2664,7 @@ function drupal_set_time_limit($time_limit) {
  *   The path to the requested item.
  */
 function drupal_get_path($type, $name) {
-  return dirname(drupal_get_filename($type, $name));
+  return DrupalModuleStreamWrapper::getBaseDirectory($type, $name);
 }
 
 /**
@@ -5154,6 +5154,17 @@ function drupal_system_listing($mask, $directory, $key = 'name', $min_depth = 1)
   if (!function_exists('file_scan_directory')) {
     require_once DRUPAL_ROOT . '/includes/file.inc';
   }
+
+  // Add the PHAR archives from the search directories as search directories
+  // themselves. They will be scanned for files matching the pattern below.
+  $pharfiles = array();
+  foreach ($searchdir as $dir) {
+    foreach (file_scan_directory($dir, '/\.phar$/', array('key' => $key, 'min_depth' => $min_depth)) as $file) {
+      $pharfiles[] = 'phar://' . $file->uri;
+    }
+  }
+  $searchdir = array_merge($searchdir, $pharfiles);
+
   foreach ($searchdir as $dir) {
     $files_to_add = file_scan_directory($dir, $mask, array('key' => $key, 'min_depth' => $min_depth));
 
diff --git a/includes/file.inc b/includes/file.inc
index b7a1204..7698b68 100644
--- a/includes/file.inc
+++ b/includes/file.inc
@@ -220,6 +220,11 @@ function file_uri_scheme($uri) {
  *   or FALSE if the scheme does not have a registered handler.
  */
 function file_stream_wrapper_valid_scheme($scheme) {
+  // Is the scheme already known by PHP?
+  if (in_array($scheme, stream_get_wrappers())) {
+    return TRUE;
+  }
+
   // Does the scheme have a registered handler that is callable?
   $class = file_stream_wrapper_get_class($scheme);
   if (class_exists($class)) {
diff --git a/includes/module-fs.inc b/includes/module-fs.inc
new file mode 100644
index 0000000..0f5c54b
--- /dev/null
+++ b/includes/module-fs.inc
@@ -0,0 +1,191 @@
+<?php
+
+class DrupalModuleStreamWrapper {
+  public $context;
+  public $handle = NULL;
+  protected $uri;
+
+  protected function getFilename() {
+    list($scheme, $target) = explode('://', $this->uri, 2);
+    list($type, $name, $file) = explode('/', $target, 3);
+
+    return DrupalModuleStreamWrapper::getBaseDirectory($type, $name) . '/' . $file;
+  }
+
+  public static $baseFilenames = array();
+
+  public static function getBaseFilename($type, $name) {
+    if (!isset(DrupalModuleStreamWrapper::$baseFilenames[$type])) {
+      DrupalModuleStreamWrapper::$baseFilenames[$type] = array();
+    }
+
+    if (!isset(DrupalModuleStreamWrapper::$baseFilenames[$type][$name])) {
+      // Verify that we have an active database connection, before querying
+      // the database. This is required because this function is called both
+      // before we have a database connection (i.e. during installation) and
+      // when a database connection fails.
+      try {
+        if (function_exists('db_query')) {
+          $result = db_query("SELECT type, name, filename FROM {system} WHERE status = 1");
+          foreach ($result as $file) {
+            DrupalModuleStreamWrapper::$baseFilenames[$file->type][$file->name] = $file->filename;
+          }
+        }
+      }
+      catch (Exception $e) {
+        // The database table may not exist because Drupal is not yet installed,
+        // or the database might be down. We have a fallback for this case so we
+        // hide the error completely.
+      }
+
+      // Fallback to searching the filesystem if the database could not find the
+      // file or the file returned by the database is not found.
+      if (!isset(DrupalModuleStreamWrapper::$baseFilenames[$type][$name])) {
+        // We have a consistent directory naming: modules, themes...
+        $dir = $type . 's';
+        if ($type == 'theme_engine') {
+          $dir = 'themes/engines';
+          $extension = 'engine';
+        }
+        elseif ($type == 'theme') {
+          $extension = 'info';
+        }
+        else {
+          $extension = $type;
+        }
+
+        if (!function_exists('drupal_system_listing')) {
+          require_once DRUPAL_ROOT . '/includes/common.inc';
+        }
+        // Scan the appropriate directories for all files with the requested
+        // 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, 'name', 0);
+        foreach ($matches as $matched_name => $file) {
+          DrupalModuleStreamWrapper::$baseFilenames[$type][$matched_name] = $file->uri;
+        }
+      }
+    }
+
+    if (isset(DrupalModuleStreamWrapper::$baseFilenames[$type][$name])) {
+      return DrupalModuleStreamWrapper::$baseFilenames[$type][$name];
+    }
+  }
+
+  public static function getBaseDirectory($type, $name) {
+    return dirname(DrupalModuleStreamWrapper::getBaseFilename($type, $name));
+  }
+
+  public function stream_open($uri, $mode, $options, &$opened_path) {
+    $this->uri = $uri;
+    $path = $this->getFilename();
+    $this->handle = ($options & STREAM_REPORT_ERRORS) ? fopen($path, $mode) : @fopen($path, $mode);
+
+    if ((bool) $this->handle && $options & STREAM_USE_PATH) {
+      $opened_url = $path;
+    }
+
+    return (bool) $this->handle;
+  }
+
+  public function stream_lock($operation) {
+    // This streamwrapper is read-only.
+    return FALSE;
+  }
+
+  public function stream_read($count) {
+    return fread($this->handle, $count);
+  }
+
+  public function stream_write($data) {
+    return FALSE;
+  }
+
+  public function stream_eof() {
+    return feof($this->handle);
+  }
+
+  public function stream_seek($offset, $whence) {
+    // fseek returns 0 on success and -1 on a failure.
+    // stream_seek   1 on success and  0 on a failure.
+    return !fseek($this->handle, $offset, $whence);
+  }
+
+  public function stream_flush() {
+    return FALSE;
+  }
+
+  public function stream_tell() {
+    return ftell($this->handle);
+  }
+
+  public function stream_stat() {
+    return fstat($this->handle);
+  }
+
+  public function stream_close() {
+    return fclose($this->handle);
+  }
+
+  public function unlink($uri) {
+    // This streamwrapper is read-only.
+    return FALSE;
+  }
+
+  public function rename($from_uri, $to_uri) {
+    // This streamwrapper is read-only.
+    return FALSE;
+  }
+
+  public function mkdir($uri, $mode, $options) {
+    // This streamwrapper is read-only.
+    return FALSE;
+  }
+
+  public function rmdir($uri, $options) {
+    // This streamwrapper is read-only.
+    return FALSE;
+  }
+
+  public function url_stat($uri, $flags) {
+    $this->uri = $uri;
+    $path = $this->getFilename();
+    // Suppress warnings if requested or if the file or directory does not
+    // exist. This is consistent with PHP's plain filesystem stream wrapper.
+    if ($flags & STREAM_URL_STAT_QUIET || !file_exists($path)) {
+      return @stat($path);
+    }
+    else {
+      return stat($path);
+    }
+  }
+
+  public function dir_opendir($uri, $options) {
+    $this->uri = $uri;
+    $this->handle = opendir($this->getFilename());
+
+    return (bool) $this->handle;
+  }
+
+  public function dir_readdir() {
+    return readdir($this->handle);
+  }
+
+  public function dir_rewinddir() {
+    rewinddir($this->handle);
+    // We do not really have a way to signal a failure as rewinddir() does not
+    // have a return value and there is no way to read a directory handler
+    // without advancing to the next file.
+    return TRUE;
+  }
+
+  public function dir_closedir() {
+    closedir($this->handle);
+    // We do not really have a way to signal a failure as closedir() does not
+    // have a return value.
+    return TRUE;
+  }
+}
+
+stream_wrapper_register('drupal', 'DrupalModuleStreamWrapper');
diff --git a/includes/module.inc b/includes/module.inc
index 23f2fa8..b66d7c4 100644
--- a/includes/module.inc
+++ b/includes/module.inc
@@ -71,7 +71,7 @@ function module_list($refresh = FALSE, $bootstrap_refresh = FALSE, $sort = FALSE
     $sorted_list = NULL;
     if ($fixed_list) {
       foreach ($fixed_list as $name => $module) {
-        drupal_get_filename('module', $name, $module['filename']);
+        DrupalModuleStreamWrapper::$baseFilenames['module'][$name] = $module['filename'];
         $list[$name] = $name;
       }
     }
@@ -137,10 +137,10 @@ function system_list($type) {
       cache_set('bootstrap_modules', $bootstrap_list, 'cache_bootstrap');
     }
     // To avoid a separate database lookup for the filepath, prime the
-    // drupal_get_filename() static cache for bootstrap modules only.
+    // DrupalModuleStreamWrapper::$baseFilenames cache for bootstrap modules only.
     // The rest is stored separately to keep the bootstrap module cache small.
     foreach ($bootstrap_list as $module) {
-      drupal_get_filename('module', $module->name, $module->filename);
+      DrupalModuleStreamWrapper::$baseFilenames['module'][$module->name] = $module->filename;
     }
     // We only return the module names here since module_list() doesn't need
     // the filename itself.
@@ -173,7 +173,7 @@ function system_list($type) {
         if ($record->type == 'theme') {
           $lists['theme'][$record->name] = $record;
         }
-        // Build a list of filenames so drupal_get_filename can use it.
+        // Build a list of filenames so DrupalModuleStreamWrapper can use it.
         if ($record->status) {
           $lists['filepaths'][] = array('type' => $record->type, 'name' => $record->name, 'filepath' => $record->filename);
         }
@@ -181,9 +181,10 @@ function system_list($type) {
       cache_set('system_list', $lists, 'cache_bootstrap');
     }
     // To avoid a separate database lookup for the filepath, prime the
-    // drupal_get_filename() static cache with all enabled modules and themes.
+    // DrupalModuleStreamWrapper::$baseFilenames cache with all enabled modules
+    // and themes.
     foreach ($lists['filepaths'] as $item) {
-      drupal_get_filename($item['type'], $item['name'], $item['filepath']);
+      DrupalModuleStreamWrapper::$baseFilenames[$item['type']][$item['name']] = $item['filepath'];
     }
   }
 
diff --git a/modules/simpletest/simpletest.module b/modules/simpletest/simpletest.module
index b992fd2..25cf639 100644
--- a/modules/simpletest/simpletest.module
+++ b/modules/simpletest/simpletest.module
@@ -329,7 +329,7 @@ function simpletest_test_get_all() {
           // If this test class requires a non-existing module, skip it.
           if (!empty($info['dependencies'])) {
             foreach ($info['dependencies'] as $module) {
-              if (!drupal_get_filename('module', $module)) {
+              if (!DrupalModuleStreamWrapper::getBaseDirectory('module', $module)) {
                 continue 2;
               }
             }
diff --git a/modules/simpletest/tests/bootstrap.test b/modules/simpletest/tests/bootstrap.test
index 14c16a9..7c8912d 100644
--- a/modules/simpletest/tests/bootstrap.test
+++ b/modules/simpletest/tests/bootstrap.test
@@ -321,37 +321,38 @@ class HookBootExitTestCase extends DrupalWebTestCase {
 }
 
 /**
- * Test drupal_get_filename()'s availability.
+ * Test DrupalModuleStreamWrapper availability.
  */
-class BootstrapGetFilenameTestCase extends DrupalUnitTestCase {
+class BootstrapStreamWrapperTestCase extends DrupalUnitTestCase {
 
   public static function getInfo() {
     return array(
-      'name' => 'Get filename test',
-      'description' => 'Test that drupal_get_filename() works correctly when the file is not found in the database.',
+      'name' => 'Bootstrap Stream Wrapper',
+      'description' => 'Test that DrupalModuleStreamWrapper works correctly when the file is not found in the database.',
       'group' => 'Bootstrap',
     );
   }
 
   /**
-   * Test that drupal_get_filename() works correctly when the file is not found in the database.
+   * Test that DrupalModuleStreamWrapper works correctly when the file is not found in the database.
    */
-  function testDrupalGetFilename() {
-    // Reset the static cache so we can test the "db is not active" code of
-    // drupal_get_filename().
-    drupal_static_reset('drupal_get_filename');
+  function testDrupalModuleStreamWrapper() {
+    // Clear the cache of DrupalModuleStreamWrapper. Because the database is not
+    // available (this is a DrupalUnitTestCase), so this will force the implementation
+    // to discover files from disk.
+    DrupalModuleStreamWrapper::$baseFilenames = array();
 
     // Retrieving the location of a module.
-    $this->assertIdentical(drupal_get_filename('module', 'php'), 'modules/php/php.module', t('Retrieve module location.'));
+    $this->assertIdentical(DrupalModuleStreamWrapper::getBaseFileName('module', 'php'), 'modules/php/php.module', t('Retrieve module location.'));
 
     // Retrieving the location of a theme.
-    $this->assertIdentical(drupal_get_filename('theme', 'stark'), 'themes/stark/stark.info', t('Retrieve theme location.'));
+    $this->assertIdentical(DrupalModuleStreamWrapper::getBaseFileName('theme', 'stark'), 'themes/stark/stark.info', t('Retrieve theme location.'));
 
     // Retrieving the location of a theme engine.
-    $this->assertIdentical(drupal_get_filename('theme_engine', 'phptemplate'), 'themes/engines/phptemplate/phptemplate.engine', t('Retrieve theme engine location.'));
+    $this->assertIdentical(DrupalModuleStreamWrapper::getBaseFileName('theme_engine', 'phptemplate'), 'themes/engines/phptemplate/phptemplate.engine', t('Retrieve theme engine location.'));
 
     // Retrieving a file that is definitely not stored in the database.
-    $this->assertIdentical(drupal_get_filename('profile', 'standard'), 'profiles/standard/standard.profile', t('Retrieve install profile location.'));
+    $this->assertIdentical(DrupalModuleStreamWrapper::getBaseFileName('profile', 'standard'), 'profiles/standard/standard.profile', t('Retrieve install profile location.'));
   }
 }
 
