diff --git a/core/modules/system/file.api.php b/core/modules/system/file.api.php
new file mode 100644
index 0000000..244113c
--- /dev/null
+++ b/core/modules/system/file.api.php
@@ -0,0 +1,282 @@
+<?php
+
+/**
+ * @file
+ * Hooks related to the File management system.
+ */
+
+/**
+ * @addtogroup hooks
+ * @{
+ */
+
+/**
+ * Registers PHP stream wrapper implementations associated with a module.
+ *
+ * Provide a facility for managing and querying user-defined stream wrappers
+ * in PHP. PHP's internal stream_get_wrappers() doesn't return the class
+ * registered to handle a stream, which we need to be able to find the handler
+ * for class instantiation.
+ *
+ * If a module registers a scheme that is already registered with PHP, it will
+ * be unregistered and replaced with the specified class.
+ *
+ * @return
+ *   A nested array, keyed first by scheme name ("public" for "public://"),
+ *   then keyed by the following values:
+ *   - 'name' A short string to name the wrapper.
+ *   - 'class' A string specifying the PHP class that implements the
+ *     Drupal\Core\StreamWrapper\StreamWrapperInterface interface.
+ *   - 'description' A string with a short description of what the wrapper does.
+ *   - 'type' (Optional) A bitmask of flags indicating what type of streams this
+ *     wrapper will access - local or remote, readable and/or writeable, etc.
+ *     Many shortcut constants are defined in file.inc. Defaults to
+ *     STREAM_WRAPPERS_NORMAL which includes all of these bit flags:
+ *     - STREAM_WRAPPERS_READ
+ *     - STREAM_WRAPPERS_WRITE
+ *     - STREAM_WRAPPERS_VISIBLE
+ *
+ * @see file_get_stream_wrappers()
+ * @see hook_stream_wrappers_alter()
+ * @see system_stream_wrappers()
+ */
+function hook_stream_wrappers() {
+  return array(
+    'public' => array(
+      'name' => t('Public files'),
+      'class' => 'Drupal\Core\StreamWrapper\PublicStream',
+      'description' => t('Public local files served by the webserver.'),
+      'type' => STREAM_WRAPPERS_LOCAL_NORMAL,
+    ),
+    'private' => array(
+      'name' => t('Private files'),
+      'class' => 'Drupal\Core\StreamWrapper\PrivateStream',
+      'description' => t('Private local files served by Drupal.'),
+      'type' => STREAM_WRAPPERS_LOCAL_NORMAL,
+    ),
+    'temp' => array(
+      'name' => t('Temporary files'),
+      'class' => 'Drupal\Core\StreamWrapper\TemporaryStream',
+      'description' => t('Temporary local files for upload and previews.'),
+      'type' => STREAM_WRAPPERS_LOCAL_HIDDEN,
+    ),
+    'cdn' => array(
+      'name' => t('Content delivery network files'),
+      // @todo: Fix the name of this class when we decide on module PSR-0 usage.
+      'class' => 'MyModuleCDNStream',
+      'description' => t('Files served by a content delivery network.'),
+      // 'type' can be omitted to use the default of STREAM_WRAPPERS_NORMAL
+    ),
+    'youtube' => array(
+      'name' => t('YouTube video'),
+      // @todo: Fix the name of this class when we decide on module PSR-0 usage.
+      'class' => 'MyModuleYouTubeStream',
+      'description' => t('Video streamed from YouTube.'),
+      // A module implementing YouTube integration may decide to support using
+      // the YouTube API for uploading video, but here, we assume that this
+      // particular module only supports playing YouTube video.
+      'type' => STREAM_WRAPPERS_READ_VISIBLE,
+    ),
+  );
+}
+
+/**
+ * Alters the list of PHP stream wrapper implementations.
+ *
+ * @see file_get_stream_wrappers()
+ * @see hook_stream_wrappers()
+ */
+function hook_stream_wrappers_alter(&$wrappers) {
+  // Change the name of private files to reflect the performance.
+  $wrappers['private']['name'] = t('Slow files');
+}
+
+/**
+ * Control access to private file downloads and specify HTTP headers.
+ *
+ * This hook allows modules to enforce permissions on file downloads whenever
+ * Drupal is handling file download, as opposed to the web server bypassing
+ * Drupal and returning the file from a public directory. Modules can also
+ * provide headers to specify information like the file's name or MIME type.
+ *
+ * @param $uri
+ *   The URI of the file.
+ * @return
+ *   If the user does not have permission to access the file, return -1. If the
+ *   user has permission, return an array with the appropriate headers. If the
+ *   file is not controlled by the current module, the return value should be
+ *   NULL.
+ *
+ * @see file_download()
+ */
+function hook_file_download($uri) {
+  // Check to see if this is a config download.
+  $scheme = file_uri_scheme($uri);
+  $target = file_uri_target($uri);
+  if ($scheme == 'temporary' && $target == 'config.tar.gz') {
+    return array(
+      'Content-disposition' => 'attachment; filename="config.tar.gz"',
+    );
+  }
+}
+
+/**
+ * Alter the URL to a file.
+ *
+ * This hook is called from file_create_url(), and  is called fairly
+ * frequently (10+ times per page), depending on how many files there are in a
+ * given page.
+ * If CSS and JS aggregation are disabled, this can become very frequently
+ * (50+ times per page) so performance is critical.
+ *
+ * This function should alter the URI, if it wants to rewrite the file URL.
+ *
+ * @param $uri
+ *   The URI to a file for which we need an external URL, or the path to a
+ *   shipped file.
+ */
+function hook_file_url_alter(&$uri) {
+  $user = \Drupal::currentUser();
+
+  // User 1 will always see the local file in this example.
+  if ($user->id() == 1) {
+    return;
+  }
+
+  $cdn1 = 'http://cdn1.example.com';
+  $cdn2 = 'http://cdn2.example.com';
+  $cdn_extensions = array('css', 'js', 'gif', 'jpg', 'jpeg', 'png');
+
+  // Most CDNs don't support private file transfers without a lot of hassle,
+  // so don't support this in the common case.
+  $schemes = array('public');
+
+  $scheme = file_uri_scheme($uri);
+
+  // Only serve shipped files and public created files from the CDN.
+  if (!$scheme || in_array($scheme, $schemes)) {
+    // Shipped files.
+    if (!$scheme) {
+      $path = $uri;
+    }
+    // Public created files.
+    else {
+      $wrapper = file_stream_wrapper_get_instance_by_scheme($scheme);
+      $path = $wrapper->getDirectoryPath() . '/' . file_uri_target($uri);
+    }
+
+    // Clean up Windows paths.
+    $path = str_replace('\\', '/', $path);
+
+    // Serve files with one of the CDN extensions from CDN 1, all others from
+    // CDN 2.
+    $pathinfo = pathinfo($path);
+    if (isset($pathinfo['extension']) && in_array($pathinfo['extension'], $cdn_extensions)) {
+      $uri = $cdn1 . '/' . $path;
+    }
+    else {
+      $uri = $cdn2 . '/' . $path;
+    }
+  }
+}
+
+/**
+ * Alter MIME type mappings used to determine MIME type from a file extension.
+ *
+ * Invoked by \Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser::guess(). It
+ * is used to allow modules to add to or modify the default mapping from
+ * \Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser::$defaultMapping.
+ *
+ * @param $mapping
+ *   An array of mimetypes correlated to the extensions that relate to them.
+ *   The array has 'mimetypes' and 'extensions' elements, each of which is an
+ *   array.
+ *
+ * @see \Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser::guess()
+ * @see \Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser::$defaultMapping
+ */
+function hook_file_mimetype_mapping_alter(&$mapping) {
+  // Add new MIME type 'drupal/info'.
+  $mapping['mimetypes']['example_info'] = 'drupal/info';
+  // Add new extension '.info.yml' and map it to the 'drupal/info' MIME type.
+  $mapping['extensions']['info'] = 'example_info';
+  // Override existing extension mapping for '.ogg' files.
+  $mapping['extensions']['ogg'] = 189;
+}
+
+/**
+ * Alter archiver information declared by other modules.
+ *
+ * See hook_archiver_info() for a description of archivers and the archiver
+ * information structure.
+ *
+ * @param $info
+ *   Archiver information to alter (return values from hook_archiver_info()).
+ */
+function hook_archiver_info_alter(&$info) {
+  $info['tar']['extensions'][] = 'tgz';
+}
+
+/**
+ * Register information about FileTransfer classes provided by a module.
+ *
+ * The FileTransfer class allows transferring files over a specific type of
+ * connection. Core provides classes for FTP and SSH. Contributed modules are
+ * free to extend the FileTransfer base class to add other connection types,
+ * and if these classes are registered via hook_filetransfer_info(), those
+ * connection types will be available to site administrators using the Update
+ * manager when they are redirected to the authorize.php script to authorize
+ * the file operations.
+ *
+ * @return array
+ *   Nested array of information about FileTransfer classes. Each key is a
+ *   FileTransfer type (not human readable, used for form elements and
+ *   variable names, etc), and the values are subarrays that define properties
+ *   of that type. The keys in each subarray are:
+ *   - 'title': Required. The human-readable name of the connection type.
+ *   - 'class': Required. The name of the FileTransfer class. The constructor
+ *     will always be passed the full path to the root of the site that should
+ *     be used to restrict where file transfer operations can occur (the $jail)
+ *     and an array of settings values returned by the settings form.
+ *   - 'file': Required. The include file containing the FileTransfer class.
+ *     This should be a separate .inc file, not just the .module file, so that
+ *     the minimum possible code is loaded when authorize.php is running.
+ *   - 'file path': Optional. The directory (relative to the Drupal root)
+ *     where the include file lives. If not defined, defaults to the base
+ *     directory of the module implementing the hook.
+ *   - 'weight': Optional. Integer weight used for sorting connection types on
+ *     the authorize.php form.
+ *
+ * @see \Drupal\Core\FileTransfer\FileTransfer
+ * @see authorize.php
+ * @see hook_filetransfer_info_alter()
+ * @see drupal_get_filetransfer_info()
+ */
+function hook_filetransfer_info() {
+  $info['sftp'] = array(
+    'title' => t('SFTP (Secure FTP)'),
+    'class' => 'Drupal\Core\FileTransfer\SFTP',
+    'weight' => 10,
+  );
+  return $info;
+}
+
+/**
+ * Alter the FileTransfer class registry.
+ *
+ * @param array $filetransfer_info
+ *   Reference to a nested array containing information about the FileTransfer
+ *   class registry.
+ *
+ * @see hook_filetransfer_info()
+ */
+function hook_filetransfer_info_alter(&$filetransfer_info) {
+  // Remove the FTP option entirely.
+  unset($filetransfer_info['ftp']);
+  // Make sure the SSH option is listed first.
+  $filetransfer_info['ssh']['weight'] = -10;
+}
+
+/**
+ * @} End of "addtogroup hooks".
+ */
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index 35dbb36..0b6586c 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -1415,175 +1415,6 @@ function hook_modules_uninstalled($modules) {
   mymodule_cache_rebuild();
 }
 
-/**
- * Registers PHP stream wrapper implementations associated with a module.
- *
- * Provide a facility for managing and querying user-defined stream wrappers
- * in PHP. PHP's internal stream_get_wrappers() doesn't return the class
- * registered to handle a stream, which we need to be able to find the handler
- * for class instantiation.
- *
- * If a module registers a scheme that is already registered with PHP, it will
- * be unregistered and replaced with the specified class.
- *
- * @return
- *   A nested array, keyed first by scheme name ("public" for "public://"),
- *   then keyed by the following values:
- *   - 'name' A short string to name the wrapper.
- *   - 'class' A string specifying the PHP class that implements the
- *     Drupal\Core\StreamWrapper\StreamWrapperInterface interface.
- *   - 'description' A string with a short description of what the wrapper does.
- *   - 'type' (Optional) A bitmask of flags indicating what type of streams this
- *     wrapper will access - local or remote, readable and/or writeable, etc.
- *     Many shortcut constants are defined in file.inc. Defaults to
- *     STREAM_WRAPPERS_NORMAL which includes all of these bit flags:
- *     - STREAM_WRAPPERS_READ
- *     - STREAM_WRAPPERS_WRITE
- *     - STREAM_WRAPPERS_VISIBLE
- *
- * @see file_get_stream_wrappers()
- * @see hook_stream_wrappers_alter()
- * @see system_stream_wrappers()
- */
-function hook_stream_wrappers() {
-  return array(
-    'public' => array(
-      'name' => t('Public files'),
-      'class' => 'Drupal\Core\StreamWrapper\PublicStream',
-      'description' => t('Public local files served by the webserver.'),
-      'type' => STREAM_WRAPPERS_LOCAL_NORMAL,
-    ),
-    'private' => array(
-      'name' => t('Private files'),
-      'class' => 'Drupal\Core\StreamWrapper\PrivateStream',
-      'description' => t('Private local files served by Drupal.'),
-      'type' => STREAM_WRAPPERS_LOCAL_NORMAL,
-    ),
-    'temp' => array(
-      'name' => t('Temporary files'),
-      'class' => 'Drupal\Core\StreamWrapper\TemporaryStream',
-      'description' => t('Temporary local files for upload and previews.'),
-      'type' => STREAM_WRAPPERS_LOCAL_HIDDEN,
-    ),
-    'cdn' => array(
-      'name' => t('Content delivery network files'),
-      // @todo: Fix the name of this class when we decide on module PSR-0 usage.
-      'class' => 'MyModuleCDNStream',
-      'description' => t('Files served by a content delivery network.'),
-      // 'type' can be omitted to use the default of STREAM_WRAPPERS_NORMAL
-    ),
-    'youtube' => array(
-      'name' => t('YouTube video'),
-      // @todo: Fix the name of this class when we decide on module PSR-0 usage.
-      'class' => 'MyModuleYouTubeStream',
-      'description' => t('Video streamed from YouTube.'),
-      // A module implementing YouTube integration may decide to support using
-      // the YouTube API for uploading video, but here, we assume that this
-      // particular module only supports playing YouTube video.
-      'type' => STREAM_WRAPPERS_READ_VISIBLE,
-    ),
-  );
-}
-
-/**
- * Alters the list of PHP stream wrapper implementations.
- *
- * @see file_get_stream_wrappers()
- * @see hook_stream_wrappers()
- */
-function hook_stream_wrappers_alter(&$wrappers) {
-  // Change the name of private files to reflect the performance.
-  $wrappers['private']['name'] = t('Slow files');
-}
-
-/**
- * Control access to private file downloads and specify HTTP headers.
- *
- * This hook allows modules to enforce permissions on file downloads whenever
- * Drupal is handling file download, as opposed to the web server bypassing
- * Drupal and returning the file from a public directory. Modules can also
- * provide headers to specify information like the file's name or MIME type.
- *
- * @param $uri
- *   The URI of the file.
- * @return
- *   If the user does not have permission to access the file, return -1. If the
- *   user has permission, return an array with the appropriate headers. If the
- *   file is not controlled by the current module, the return value should be
- *   NULL.
- *
- * @see file_download()
- */
-function hook_file_download($uri) {
-  // Check to see if this is a config download.
-  $scheme = file_uri_scheme($uri);
-  $target = file_uri_target($uri);
-  if ($scheme == 'temporary' && $target == 'config.tar.gz') {
-    return array(
-      'Content-disposition' => 'attachment; filename="config.tar.gz"',
-    );
-  }
-}
-
-/**
- * Alter the URL to a file.
- *
- * This hook is called from file_create_url(), and  is called fairly
- * frequently (10+ times per page), depending on how many files there are in a
- * given page.
- * If CSS and JS aggregation are disabled, this can become very frequently
- * (50+ times per page) so performance is critical.
- *
- * This function should alter the URI, if it wants to rewrite the file URL.
- *
- * @param $uri
- *   The URI to a file for which we need an external URL, or the path to a
- *   shipped file.
- */
-function hook_file_url_alter(&$uri) {
-  $user = \Drupal::currentUser();
-
-  // User 1 will always see the local file in this example.
-  if ($user->id() == 1) {
-    return;
-  }
-
-  $cdn1 = 'http://cdn1.example.com';
-  $cdn2 = 'http://cdn2.example.com';
-  $cdn_extensions = array('css', 'js', 'gif', 'jpg', 'jpeg', 'png');
-
-  // Most CDNs don't support private file transfers without a lot of hassle,
-  // so don't support this in the common case.
-  $schemes = array('public');
-
-  $scheme = file_uri_scheme($uri);
-
-  // Only serve shipped files and public created files from the CDN.
-  if (!$scheme || in_array($scheme, $schemes)) {
-    // Shipped files.
-    if (!$scheme) {
-      $path = $uri;
-    }
-    // Public created files.
-    else {
-      $wrapper = file_stream_wrapper_get_instance_by_scheme($scheme);
-      $path = $wrapper->getDirectoryPath() . '/' . file_uri_target($uri);
-    }
-
-    // Clean up Windows paths.
-    $path = str_replace('\\', '/', $path);
-
-    // Serve files with one of the CDN extensions from CDN 1, all others from
-    // CDN 2.
-    $pathinfo = pathinfo($path);
-    if (isset($pathinfo['extension']) && in_array($pathinfo['extension'], $cdn_extensions)) {
-      $uri = $cdn1 . '/' . $path;
-    }
-    else {
-      $uri = $cdn2 . '/' . $path;
-    }
-  }
-}
 
 /**
  * Check installation requirements and do status reporting.
@@ -2302,43 +2133,6 @@ function hook_install_tasks_alter(&$tasks, $install_state) {
 }
 
 /**
- * Alter MIME type mappings used to determine MIME type from a file extension.
- *
- * Invoked by \Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser::guess(). It
- * is used to allow modules to add to or modify the default mapping from
- * \Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser::$defaultMapping.
- *
- * @param $mapping
- *   An array of mimetypes correlated to the extensions that relate to them.
- *   The array has 'mimetypes' and 'extensions' elements, each of which is an
- *   array.
- *
- * @see \Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser::guess()
- * @see \Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser::$defaultMapping
- */
-function hook_file_mimetype_mapping_alter(&$mapping) {
-  // Add new MIME type 'drupal/info'.
-  $mapping['mimetypes']['example_info'] = 'drupal/info';
-  // Add new extension '.info.yml' and map it to the 'drupal/info' MIME type.
-  $mapping['extensions']['info'] = 'example_info';
-  // Override existing extension mapping for '.ogg' files.
-  $mapping['extensions']['ogg'] = 189;
-}
-
-/**
- * Alter archiver information declared by other modules.
- *
- * See hook_archiver_info() for a description of archivers and the archiver
- * information structure.
- *
- * @param $info
- *   Archiver information to alter (return values from hook_archiver_info()).
- */
-function hook_archiver_info_alter(&$info) {
-  $info['tar']['extensions'][] = 'tgz';
-}
-
-/**
  * Alter the list of mail backend plugin definitions.
  *
  * @param array $info
@@ -2706,66 +2500,6 @@ function hook_countries_alter(&$countries) {
 }
 
 /**
- * Register information about FileTransfer classes provided by a module.
- *
- * The FileTransfer class allows transferring files over a specific type of
- * connection. Core provides classes for FTP and SSH. Contributed modules are
- * free to extend the FileTransfer base class to add other connection types,
- * and if these classes are registered via hook_filetransfer_info(), those
- * connection types will be available to site administrators using the Update
- * manager when they are redirected to the authorize.php script to authorize
- * the file operations.
- *
- * @return array
- *   Nested array of information about FileTransfer classes. Each key is a
- *   FileTransfer type (not human readable, used for form elements and
- *   variable names, etc), and the values are subarrays that define properties
- *   of that type. The keys in each subarray are:
- *   - 'title': Required. The human-readable name of the connection type.
- *   - 'class': Required. The name of the FileTransfer class. The constructor
- *     will always be passed the full path to the root of the site that should
- *     be used to restrict where file transfer operations can occur (the $jail)
- *     and an array of settings values returned by the settings form.
- *   - 'file': Required. The include file containing the FileTransfer class.
- *     This should be a separate .inc file, not just the .module file, so that
- *     the minimum possible code is loaded when authorize.php is running.
- *   - 'file path': Optional. The directory (relative to the Drupal root)
- *     where the include file lives. If not defined, defaults to the base
- *     directory of the module implementing the hook.
- *   - 'weight': Optional. Integer weight used for sorting connection types on
- *     the authorize.php form.
- *
- * @see \Drupal\Core\FileTransfer\FileTransfer
- * @see authorize.php
- * @see hook_filetransfer_info_alter()
- * @see drupal_get_filetransfer_info()
- */
-function hook_filetransfer_info() {
-  $info['sftp'] = array(
-    'title' => t('SFTP (Secure FTP)'),
-    'class' => 'Drupal\Core\FileTransfer\SFTP',
-    'weight' => 10,
-  );
-  return $info;
-}
-
-/**
- * Alter the FileTransfer class registry.
- *
- * @param array $filetransfer_info
- *   Reference to a nested array containing information about the FileTransfer
- *   class registry.
- *
- * @see hook_filetransfer_info()
- */
-function hook_filetransfer_info_alter(&$filetransfer_info) {
-  // Remove the FTP option entirely.
-  unset($filetransfer_info['ftp']);
-  // Make sure the SSH option is listed first.
-  $filetransfer_info['ssh']['weight'] = -10;
-}
-
-/**
  * Alter the parameters for links.
  *
  * @param array $variables
