diff --git a/includes/file.inc b/includes/file.inc
index 4423b2d6b037a36f637bc50b298cf32a8748dfa9..6395c632337bcf8a8ea7cb556b13390b6812ee62 100644
--- a/includes/file.inc
+++ b/includes/file.inc
@@ -90,16 +90,24 @@
  *
  * A stream is referenced as "scheme://target".
  *
+ * @param $filter
+ *  Optionally filter out all types except these.  Defaults to
+ *  STREAM_WRAPPERS_ALL, which returns all registered stream wrappers.
+ *
  * @return
  *   Returns the entire Drupal stream wrapper registry.
  * @see hook_stream_wrappers()
  * @see hook_stream_wrappers_alter()
  */
-function file_get_stream_wrappers() {
-  $wrappers = &drupal_static(__FUNCTION__);
+function file_get_stream_wrappers($filter = STREAM_WRAPPERS_ALL) {
+  $wrappers_storage = &drupal_static(__FUNCTION__);
 
-  if (!isset($wrappers)) {
+  if (!isset($wrappers_storage)) {
     $wrappers = module_invoke_all('stream_wrappers');
+    foreach ($wrappers as $scheme => $info) {
+      // Add defaults.
+      $wrappers[$scheme] += array('type' => STREAM_WRAPPERS_NORMAL);
+    }
     drupal_alter('stream_wrappers', $wrappers);
     $existing = stream_get_wrappers();
     foreach ($wrappers as $scheme => $info) {
@@ -115,9 +123,25 @@ function file_get_stream_wrappers() {
         }
         stream_wrapper_register($scheme, $info['class']);
       }
+      // Pre-populate the static cache with the filters most typically used.
+      $wrappers_storage[STREAM_WRAPPERS_ALL][$scheme] = $wrappers[$scheme];
+      if (($info['type'] & STREAM_WRAPPERS_WRITE_VISIBLE) == STREAM_WRAPPERS_WRITE_VISIBLE) {
+        $wrappers_storage[STREAM_WRAPPERS_WRITE_VISIBLE][$scheme] = $wrappers[$scheme];
+      }
     }
   }
-  return $wrappers;
+
+  if (!isset($wrappers_storage[$filter])) {
+    $wrappers_storage[$filter] = array();
+    foreach ($wrappers_storage[STREAM_WRAPPERS_ALL] as $scheme => $info) {
+      // Bit-wise filter.
+      if ($info['type'] & $filter == $filter) {
+        $wrappers_storage[$filter][$scheme] = $info;
+      }
+    }
+  }
+
+  return $wrappers_storage[$filter];
 }
 
 /**
diff --git a/includes/stream_wrappers.inc b/includes/stream_wrappers.inc
index 8ed5c851766dd4dfd3279789e828c955ed0aed77..b4edb0933735b266498d78a6177771bff4073435 100644
--- a/includes/stream_wrappers.inc
+++ b/includes/stream_wrappers.inc
@@ -20,6 +20,65 @@
  * @link http://bugs.php.net/bug.php?id=47070
  */
 
+/**
+ * Stream wrapper bit flags that are the basis for composite types.
+ */
+
+/**
+ * Stream wrapper bit flag -- a filter that matches all wrappers.
+ */
+define ('STREAM_WRAPPERS_ALL', 0x0000);
+
+/**
+ * Stream wrapper bit flag -- refers to a local file system location.
+ */
+define ('STREAM_WRAPPERS_LOCAL', 0x0001);
+
+/**
+ * Stream wrapper bit flag -- refers to a remote filesystem location.
+ */
+define ('STREAM_WRAPPERS_REMOTE', 0x0002);
+
+/**
+ * Stream wrapper bit flag -- wrapper is readable (almost always true).
+ */
+define ('STREAM_WRAPPERS_READ', 0x0004);
+
+/**
+ * Stream wrapper bit flag -- wrapper is writeable.
+ */
+define ('STREAM_WRAPPERS_WRITE', 0x0008);
+
+/**
+ * Stream wrapper bit flag -- exposed in the UI and potentially web accessible.
+ */
+define ('STREAM_WRAPPERS_VISIBLE', 0x0010);
+
+/**
+ * Composite stream wrapper bit flags that are usually used as the types.
+ */
+
+/**
+ * Stream wrapper type flag -- not visible in the UI or accessible via web,
+ * but readable and writable. E.g. the temporary directory for uploads.
+ */
+define ('STREAM_WRAPPERS_HIDDEN', STREAM_WRAPPERS_READ | STREAM_WRAPPERS_WRITE);
+
+/**
+ * Stream wrapper type flag -- visible, readable and writeable.
+ */
+define ('STREAM_WRAPPERS_WRITE_VISIBLE', STREAM_WRAPPERS_READ | STREAM_WRAPPERS_WRITE | STREAM_WRAPPERS_VISIBLE);
+
+/**
+ * Stream wrapper type flag -- visible and read-only.
+ */
+define ('STREAM_WRAPPERS_READ_VISIBLE', STREAM_WRAPPERS_READ | STREAM_WRAPPERS_VISIBLE);
+
+/**
+ * Stream wrapper type flag -- visible, readable and writeable using local files.
+ */
+define ('STREAM_WRAPPERS_NORMAL', STREAM_WRAPPERS_LOCAL | STREAM_WRAPPERS_WRITE_VISIBLE);
+
 /**
  * Generic PHP stream wrapper interface.
  *
diff --git a/modules/file/file.field.inc b/modules/file/file.field.inc
index 5a85bc0c7cc0eb25389d31e72993f0bb2e4ccbd5..97002f5ad9edcf0083f9c85b0872f5e518c57558 100644
--- a/modules/file/file.field.inc
+++ b/modules/file/file.field.inc
@@ -86,10 +86,8 @@ function file_field_settings_form($field, $instance, $has_data) {
   );
 
   $scheme_options = array();
-  foreach (file_get_stream_wrappers() as $scheme => $stream_wrapper) {
-    if ($scheme != 'temporary') {
-      $scheme_options[$scheme] = $stream_wrapper['name'];
-    }
+  foreach (file_get_stream_wrappers(STREAM_WRAPPERS_WRITE_VISIBLE) as $scheme => $stream_wrapper) {
+    $scheme_options[$scheme] = $stream_wrapper['name'];
   }
   $form['uri_scheme'] = array(
     '#type' => 'radios',
diff --git a/modules/image/image.field.inc b/modules/image/image.field.inc
index 1b4a968527e5a32144d3df44bb75e98c8dbc9b38..39fcf2c1047c75ab050397e5cd7cde6339a2d896 100644
--- a/modules/image/image.field.inc
+++ b/modules/image/image.field.inc
@@ -72,10 +72,8 @@ function image_field_settings_form($field, $instance) {
   $settings = array_merge($defaults, $field['settings']);
 
   $scheme_options = array();
-  foreach (file_get_stream_wrappers() as $scheme => $stream_wrapper) {
-    if ($scheme != 'temporary') {
-      $scheme_options[$scheme] = $stream_wrapper['name'];
-    }
+  foreach (file_get_stream_wrappers(STREAM_WRAPPERS_WRITE_VISIBLE) as $scheme => $stream_wrapper) {
+    $scheme_options[$scheme] = $stream_wrapper['name'];
   }
   $form['uri_scheme'] = array(
     '#type' => 'radios',
diff --git a/modules/system/system.admin.inc b/modules/system/system.admin.inc
index be9597fdf62d4d27bd120d0bacfcdd7f88598810..284d8a55f6c2d14579169d0df5ff84e757d3bb95 100644
--- a/modules/system/system.admin.inc
+++ b/modules/system/system.admin.inc
@@ -1743,11 +1743,11 @@ function system_file_system_settings() {
     '#description' => t('A local file system path where temporary files will be stored. This directory should not be accessible over the web.'),
     '#after_build' => array('system_check_directory'),
   );
-  $wrappers = file_get_stream_wrappers();
-  $options = array(
-    'public' => $wrappers['public']['description'],
-    'private' => $wrappers['private']['description']
-  );
+  // Any visible, writeable wrapper can potentially be used for the files
+  // directory, including a remote file system that integrates with a CDN.
+  foreach(file_get_stream_wrappers(STREAM_WRAPPERS_WRITE_VISIBLE) as $scheme => $info) {
+    $options[$scheme] = $info['description'];
+  }
   $form['file_default_scheme'] = array(
     '#type' => 'radios',
     '#title' => t('Default download method'),
diff --git a/modules/system/system.module b/modules/system/system.module
index 3e3702746de539d18fdc1951278478ce5bbbc8f7..cae7a1bb4e32aa66cb169f233e2e93945e3a496f 100644
--- a/modules/system/system.module
+++ b/modules/system/system.module
@@ -1458,6 +1458,7 @@ function system_stream_wrappers() {
       'name' => t('Temporary files'),
       'class' => 'DrupalTemporaryStreamWrapper',
       'description' => t('Temporary local files for upload and previews.'),
+      'type' => STREAM_WRAPPERS_HIDDEN,
     )
   );
 }