diff --git a/core/core.services.yml b/core/core.services.yml
index 18e37f98ebea9ba604c9d55e4781ff0a249e1a2a..4563d66908aa79a373106c92c329d5c432bd7a06 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -740,5 +740,8 @@ services:
     class: Drupal\Core\Asset\JsCollectionGrouper
   asset.js.dumper:
     class: Drupal\Core\Asset\AssetDumper
+  library.discovery:
+    class: Drupal\Core\Asset\LibraryDiscovery
+    arguments: ['@cache.cache', '@module_handler']
   info_parser:
     class: Drupal\Core\Extension\InfoParser
diff --git a/core/includes/common.inc b/core/includes/common.inc
index 9ec0e8613093e8363c612e26b84a5297a2fd5c49..d118c5600465a2e14af1261011ffc42b9993c410 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -2602,16 +2602,18 @@ function drupal_process_states(&$elements) {
  *   TRUE if the library was successfully added; FALSE if the library or one of
  *   its dependencies could not be added.
  *
- * @see drupal_get_library()
+ * @see \Drupal\Core\Asset\LibraryDiscovery
  * @see hook_library_info_alter()
  */
 function _drupal_add_library($library_name, $every_page = NULL) {
   $added = &drupal_static(__FUNCTION__, array());
+  /** @var \Drupal\Core\Asset\LibraryDiscoveryInterface $library_discovery */
+  $library_discovery = \Drupal::service('library.discovery');
 
   list($extension, $name) = explode('/', $library_name, 2);
   // Only process the library if it exists and it was not added already.
   if (!isset($added[$extension][$name])) {
-    if ($library = drupal_get_library($library_name)) {
+    if ($library = $library_discovery->getLibraryByName($extension, $name)) {
       // Allow modules and themes to dynamically attach request and context
       // specific data for this library; e.g., localization.
       \Drupal::moduleHandler()->alter('library', $library, $library_name);
@@ -2642,188 +2644,6 @@ function _drupal_add_library($library_name, $every_page = NULL) {
   return $added[$extension][$name];
 }
 
-/**
- * Retrieves information for a JavaScript/CSS library.
- *
- * Library information is statically cached. Libraries are keyed by module for
- * several reasons:
- * - Libraries are not unique. Multiple modules might ship with the same library
- *   in a different version or variant. This registry cannot (and does not
- *   attempt to) prevent library conflicts.
- * - Modules implementing and thereby depending on a library that is registered
- *   by another module can only rely on that module's library.
- * - Two (or more) modules can still register the same library and use it
- *   without conflicts in case the libraries are loaded on certain pages only.
- *
- * @param $library_name
- *   The name of a registered library to retrieve. By default, all
- *   libraries registered by the extension are returned.
- *
- * @return
- *   The definition of the requested library, if $name was passed and it exists,
- *   or FALSE if it does not exist. If no $name was passed, an associative array
- *   of libraries registered by the module is returned (which may be empty).
- *
- * @see _drupal_add_library()
- * @see hook_library_info_alter()
- *
- * @todo The purpose of drupal_get_*() is completely different to other page
- *   requisite API functions; find and use a different name.
- */
-function drupal_get_library($library_name) {
-  $libraries = &drupal_static(__FUNCTION__, array());
-
-  $library_info = explode('/', $library_name, 2);
-  $extension = $library_info[0];
-  $name = isset($library_info[1]) ? $library_info[1] : NULL;
-  if (!isset($libraries[$extension]) && ($cache = \Drupal::cache()->get('library:info:' . $extension))) {
-    $libraries[$extension] = $cache->data;
-  }
-
-  if (!isset($libraries[$extension])) {
-    $libraries[$extension] = array();
-    if ($extension === 'core') {
-      $path = 'core';
-      $extension_type = 'core';
-    }
-    else {
-      // @todo Add a $type argument OR automatically figure out the type based
-      //   on current extension data, possibly using a module->theme fallback.
-      $path = drupal_get_path('module', $extension);
-      $extension_type = 'module';
-      if (!$path) {
-        $path = drupal_get_path('theme', $extension);
-        $extension_type = 'theme';
-      }
-    }
-    $library_file = $path . '/' . $extension . '.libraries.yml';
-
-    if ($library_file && file_exists(DRUPAL_ROOT . '/' . $library_file)) {
-      $libraries[$extension] = array();
-      $parser = new Parser();
-      try {
-        $libraries[$extension] = $parser->parse(file_get_contents(DRUPAL_ROOT . '/' . $library_file));
-      }
-      catch (ParseException $e) {
-        // Rethrow a more helpful exception, since ParseException lacks context.
-        throw new \RuntimeException(sprintf('Invalid library definition in %s: %s', $library_file, $e->getMessage()), 0, $e);
-      }
-      // Allow modules to alter the module's registered libraries.
-      \Drupal::moduleHandler()->alter('library_info', $libraries[$extension], $extension);
-    }
-
-    foreach ($libraries[$extension] as $id => &$library) {
-      if (!isset($library['js']) && !isset($library['css']) && !isset($library['settings'])) {
-        throw new \RuntimeException(sprintf("Incomplete library definition for '%s' in %s", $id, $library_file));
-      }
-      $library += array('dependencies' => array(), 'js' => array(), 'css' => array());
-
-      if (isset($library['version'])) {
-        // @todo Retrieve version of a non-core extension.
-        if ($library['version'] === 'VERSION') {
-          $library['version'] = \Drupal::VERSION;
-        }
-        // Remove 'v' prefix from external library versions.
-        elseif ($library['version'][0] === 'v') {
-          $library['version'] = substr($library['version'], 1);
-        }
-      }
-
-      foreach (array('js', 'css') as $type) {
-        // Prepare (flatten) the SMACSS-categorized definitions.
-        // @todo After Asset(ic) changes, retain the definitions as-is and
-        //   properly resolve dependencies for all (css) libraries per category,
-        //   and only once prior to rendering out an HTML page.
-        if ($type == 'css' && !empty($library[$type])) {
-          foreach ($library[$type] as $category => $files) {
-            foreach ($files as $source => $options) {
-              if (!isset($options['weight'])) {
-                $options['weight'] = 0;
-              }
-              // Apply the corresponding weight defined by CSS_* constants.
-              $options['weight'] += constant('CSS_' . strtoupper($category));
-              $library[$type][$source] = $options;
-            }
-            unset($library[$type][$category]);
-          }
-        }
-        foreach ($library[$type] as $source => $options) {
-          unset($library[$type][$source]);
-          // Allow to omit the options hashmap in YAML declarations.
-          if (!is_array($options)) {
-            $options = array();
-          }
-          if ($type == 'js' && isset($options['weight']) && $options['weight'] > 0) {
-            throw new \UnexpectedValueException("The $extension/$id library defines a positive weight for '$source'. Only negative weights are allowed (but should be avoided). Instead of a positive weight, specify accurate dependencies for this library.");
-          }
-          // Unconditionally apply default groups for the defined asset files.
-          // The library system is a dependency management system. Each library
-          // properly specifies its dependencies instead of relying on a custom
-          // processing order.
-          if ($type == 'js') {
-            $options['group'] = JS_LIBRARY;
-          }
-          elseif ($type == 'css') {
-            $options['group'] = $extension_type == 'theme' ? CSS_AGGREGATE_THEME : CSS_AGGREGATE_DEFAULT;
-          }
-          // By default, all library assets are files.
-          if (!isset($options['type'])) {
-            $options['type'] = 'file';
-          }
-          if ($options['type'] == 'external') {
-            $options['data'] = $source;
-          }
-          // Determine the file asset URI.
-          else {
-            if ($source[0] === '/') {
-              // An absolute path maps to DRUPAL_ROOT / base_path().
-              if ($source[1] !== '/') {
-                $options['data'] = substr($source, 1);
-              }
-              // A protocol-free URI (e.g., //cdn.com/example.js) is external.
-              else {
-                $options['type'] = 'external';
-                $options['data'] = $source;
-              }
-            }
-            // A stream wrapper URI (e.g., public://generated_js/example.js).
-            elseif (file_valid_uri($source)) {
-              $options['data'] = $source;
-            }
-            // By default, file paths are relative to the registering extension.
-            else {
-              $options['data'] = $path . '/' . $source;
-            }
-          }
-          $options['version'] = $library['version'];
-
-          $library[$type][] = $options;
-        }
-      }
-      // @todo Introduce drupal_add_settings().
-      if (isset($library['settings'])) {
-        $library['js'][] = array(
-          'type' => 'setting',
-          'data' => $library['settings'],
-        );
-        unset($library['settings']);
-      }
-    }
-    \Drupal::cache()->set('library:info:' . $extension, $libraries[$extension], Cache::PERMANENT, array(
-      'extension' => array(TRUE, $extension),
-      'library_info' => array(TRUE),
-    ));
-  }
-
-  if (isset($name)) {
-    if (!isset($libraries[$extension][$name])) {
-      $libraries[$extension][$name] = FALSE;
-    }
-    return $libraries[$extension][$name];
-  }
-  return $libraries[$extension];
-}
-
 /**
  * Assists in attaching the tableDrag JavaScript behavior to a themed table.
  *
diff --git a/core/lib/Drupal/Core/Asset/Exception/IncompleteLibraryDefinitionException.php b/core/lib/Drupal/Core/Asset/Exception/IncompleteLibraryDefinitionException.php
new file mode 100644
index 0000000000000000000000000000000000000000..52aa09cb448741666bb883e90061ee723ea317d6
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/Exception/IncompleteLibraryDefinitionException.php
@@ -0,0 +1,15 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\Exception\IncompleteLibraryDefinitionException.
+ */
+
+namespace Drupal\Core\Asset\Exception;
+
+/**
+ * Defines a custom exception if a library has no CSS/JS/JS setting specified.
+ */
+class IncompleteLibraryDefinitionException extends \RuntimeException {
+
+}
diff --git a/core/lib/Drupal/Core/Asset/Exception/InvalidLibraryFileException.php b/core/lib/Drupal/Core/Asset/Exception/InvalidLibraryFileException.php
new file mode 100644
index 0000000000000000000000000000000000000000..33cf83095bc9ab67e68d9170d2fef552a1031b60
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/Exception/InvalidLibraryFileException.php
@@ -0,0 +1,15 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\Exception\InvalidLibraryFileException.
+ */
+
+namespace Drupal\Core\Asset\Exception;
+
+/**
+ * Defines an exception if the library file could not be parsed.
+ */
+class InvalidLibraryFileException extends \RunTimeException {
+
+}
diff --git a/core/lib/Drupal/Core/Asset/LibraryDiscovery.php b/core/lib/Drupal/Core/Asset/LibraryDiscovery.php
new file mode 100644
index 0000000000000000000000000000000000000000..130876a84e3de22f7200ec7152a0c20ba6a1168e
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/LibraryDiscovery.php
@@ -0,0 +1,314 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\LibraryDiscovery.
+ */
+
+namespace Drupal\Core\Asset;
+
+use Drupal\Core\Asset\Exception\IncompleteLibraryDefinitionException;
+use Drupal\Core\Asset\Exception\InvalidLibraryFileException;
+use Drupal\Core\Cache\Cache;
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Extension\ThemeHandlerInterface;
+use Symfony\Component\Yaml\Exception\ParseException;
+use Symfony\Component\Yaml\Parser;
+
+
+/**
+ * Discovers available asset libraries in Drupal.
+ */
+class LibraryDiscovery implements LibraryDiscoveryInterface {
+
+  /**
+   * Stores the library information keyed by extension.
+   *
+   * @var array
+   */
+  protected $libraries;
+
+  /**
+   * The cache backend.
+   *
+   * @var \Drupal\Core\Cache\CacheBackendInterface
+   */
+  protected $cache;
+
+  /**
+   * The module handler.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
+   */
+  protected $moduleHandler;
+
+  /**
+   * Constructs a new LibraryDiscovery instance.
+   *
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
+   *   The cache backend.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   */
+  public function __construct(CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
+    $this->cache = $cache_backend;
+    $this->moduleHandler = $module_handler;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getLibrariesByExtension($extension) {
+    $this->ensureLibraryInformation($extension);
+    return $this->libraries[$extension];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getLibraryByName($extension, $name) {
+    $this->ensureLibraryInformation($extension);
+    return isset($this->libraries[$extension][$name]) ? $this->libraries[$extension][$name] : FALSE;
+  }
+
+  /**
+   * Ensures that the libraries property is filled.
+   *
+   * @param string $extension
+   *   The name of the extension that registered a library.
+   */
+  protected function ensureLibraryInformation($extension) {
+    $this->getCache($extension);
+    if (!isset($this->libraries[$extension])) {
+      if ($information = $this->buildLibrariesByExtension($extension)) {
+        $this->libraries[$extension] = $information;
+      }
+      else {
+        $this->libraries[$extension] = FALSE;
+      }
+      $this->setCache($extension, $this->libraries[$extension]);
+    }
+  }
+
+  /**
+   * Fills up the libraries property from cache, if available.
+   *
+   * @param string $extension
+   *   The name of the extension that registered a library.
+   */
+  protected function getCache($extension) {
+    if (!isset($this->libraries[$extension])) {
+      if ($cache = $this->cache->get('library:info:' . $extension)) {
+        $this->libraries[$extension] = $cache->data;
+      }
+    }
+  }
+
+  /**
+   * Sets the library information into a cache entry.
+   *
+   * @param string $extension
+   *   The name of the extension that registered a library.
+   *
+   * @param bool|array $information
+   *   All library definitions of the passed extension or FALSE if no
+   *   information is available.
+   */
+  protected function setCache($extension, $information) {
+    $this->cache->set('library:info:' . $extension, $information, Cache::PERMANENT, array(
+      'extension' => array(TRUE, $extension),
+      'library_info' => array(TRUE),
+    ));
+  }
+
+  /**
+   * Parses and builds up all the libraries information of an extension.
+   *
+   * @param string $extension
+   *   The name of the extension that registered a library.
+   *
+   * @return array
+   *   All library definitions of the passed extension.
+   *
+   * @throws \Drupal\Core\Asset\Exception\IncompleteLibraryDefinitionException
+   *   Thrown when a library has no js/css/setting.
+   * @throws \UnexpectedValueException
+   *   Thrown when a js file defines a positive weight.
+   */
+  protected function buildLibrariesByExtension($extension) {
+    $this->libraries[$extension] = array();
+    if ($extension === 'core') {
+      $path = 'core';
+      $extension_type = 'core';
+    }
+    else {
+      if ($this->moduleHandler->moduleExists($extension)) {
+        $extension_type = 'module';
+      }
+      else {
+        $extension_type = 'theme';
+      }
+      $path = $this->drupalGetPath($extension_type, $extension);
+    }
+    $library_file = $path . '/' . $extension . '.libraries.yml';
+
+    if ($library_file && file_exists(DRUPAL_ROOT . '/' . $library_file)) {
+      $this->libraries[$extension] = array();
+      $this->parseLibraryInfo($extension, $library_file);
+    }
+
+    foreach ($this->libraries[$extension] as $id => &$library) {
+      if (!isset($library['js']) && !isset($library['css']) && !isset($library['settings'])) {
+        throw new IncompleteLibraryDefinitionException(sprintf("Incomplete library definition for '%s' in %s", $id, $library_file));
+      }
+      $library += array('dependencies' => array(), 'js' => array(), 'css' => array());
+
+      if (isset($library['version'])) {
+        // @todo Retrieve version of a non-core extension.
+        if ($library['version'] === 'VERSION') {
+          $library['version'] = \Drupal::VERSION;
+        }
+        // Remove 'v' prefix from external library versions.
+        elseif ($library['version'][0] === 'v') {
+          $library['version'] = substr($library['version'], 1);
+        }
+      }
+
+      foreach (array('js', 'css') as $type) {
+        // Prepare (flatten) the SMACSS-categorized definitions.
+        // @todo After Asset(ic) changes, retain the definitions as-is and
+        //   properly resolve dependencies for all (css) libraries per category,
+        //   and only once prior to rendering out an HTML page.
+        if ($type == 'css' && !empty($library[$type])) {
+          foreach ($library[$type] as $category => $files) {
+            foreach ($files as $source => $options) {
+              if (!isset($options['weight'])) {
+                $options['weight'] = 0;
+              }
+              // Apply the corresponding weight defined by CSS_* constants.
+              $options['weight'] += constant('CSS_' . strtoupper($category));
+              $library[$type][$source] = $options;
+            }
+            unset($library[$type][$category]);
+          }
+        }
+        foreach ($library[$type] as $source => $options) {
+          unset($library[$type][$source]);
+          // Allow to omit the options hashmap in YAML declarations.
+          if (!is_array($options)) {
+            $options = array();
+          }
+          if ($type == 'js' && isset($options['weight']) && $options['weight'] > 0) {
+            throw new \UnexpectedValueException("The $extension/$id library defines a positive weight for '$source'. Only negative weights are allowed (but should be avoided). Instead of a positive weight, specify accurate dependencies for this library.");
+          }
+          // Unconditionally apply default groups for the defined asset files.
+          // The library system is a dependency management system. Each library
+          // properly specifies its dependencies instead of relying on a custom
+          // processing order.
+          if ($type == 'js') {
+            $options['group'] = JS_LIBRARY;
+          }
+          elseif ($type == 'css') {
+            $options['group'] = $extension_type == 'theme' ? CSS_AGGREGATE_THEME : CSS_AGGREGATE_DEFAULT;
+          }
+          // By default, all library assets are files.
+          if (!isset($options['type'])) {
+            $options['type'] = 'file';
+          }
+          if ($options['type'] == 'external') {
+            $options['data'] = $source;
+          }
+          // Determine the file asset URI.
+          else {
+            if ($source[0] === '/') {
+              // An absolute path maps to DRUPAL_ROOT / base_path().
+              if ($source[1] !== '/') {
+                $options['data'] = substr($source, 1);
+              }
+              // A protocol-free URI (e.g., //cdn.com/example.js) is external.
+              else {
+                $options['type'] = 'external';
+                $options['data'] = $source;
+              }
+            }
+            // A stream wrapper URI (e.g., public://generated_js/example.js).
+            elseif ($this->fileValidUri($source)) {
+              $options['data'] = $source;
+            }
+            // By default, file paths are relative to the registering extension.
+            else {
+              $options['data'] = $path . '/' . $source;
+            }
+          }
+
+          if (!isset($library['version'])) {
+            // @todo Get the information from the extension.
+            $options['version'] = -1;
+          }
+          else {
+            $options['version'] = $library['version'];
+          }
+
+          $library[$type][] = $options;
+        }
+      }
+
+      // @todo Introduce drupal_add_settings().
+      if (isset($library['settings'])) {
+        $library['js'][] = array(
+          'type' => 'setting',
+          'data' => $library['settings'],
+        );
+        unset($library['settings']);
+      }
+      // @todo Convert all uses of #attached[library][]=array('provider','name')
+      //   into #attached[library][]='provider/name' and remove this.
+      foreach ($library['dependencies'] as $i => $dependency) {
+        $library['dependencies'][$i] = $dependency;
+      }
+    }
+    return $this->libraries[$extension];
+  }
+
+  /**
+   * Wraps drupal_get_path().
+   */
+  protected function drupalGetPath($type, $name) {
+    return drupal_get_path($type, $name);
+  }
+
+  /**
+   * Wraps file_valid_uri().
+   */
+  protected function fileValidUri($source) {
+    return file_valid_uri($source);
+  }
+
+  /**
+   * Parses a given library file and allows module to alter it.
+   *
+   * This method sets the parsed information onto the library property.
+   *
+   * @param string $extension
+   *   The name of the extension that registered a library.
+   * @param string $library_file
+   *   The relative filename to the DRUPAL_ROOT of the wanted library file.
+   *
+   * @throws \Drupal\Core\Asset\Exception\InvalidLibraryFileException
+   *   Thrown when a parser exception got thrown.
+   */
+  protected function parseLibraryInfo($extension, $library_file) {
+    $parser = new Parser();
+    try {
+      $this->libraries[$extension] = $parser->parse(file_get_contents(DRUPAL_ROOT . '/' . $library_file));
+    }
+    catch (ParseException $e) {
+      // Rethrow a more helpful exception, since ParseException lacks context.
+      throw new InvalidLibraryFileException(sprintf('Invalid library definition in %s: %s', $library_file, $e->getMessage()), 0, $e);
+    }
+    // Allow modules to alter the module's registered libraries.
+    $this->moduleHandler->alter('library_info', $this->libraries[$extension], $extension);
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Asset/LibraryDiscoveryInterface.php b/core/lib/Drupal/Core/Asset/LibraryDiscoveryInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..ac77f70c9db9389b1670a77e9059fde7fd452b75
--- /dev/null
+++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryInterface.php
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Asset\LibraryDiscoveryInterface.
+ */
+
+namespace Drupal\Core\Asset;
+
+/**
+ * Discovers information for asset (CSS/JavaScript) libraries.
+ *
+ * Library information is statically cached. Libraries are keyed by extension
+ * for several reasons:
+ * - Libraries are not unique. Multiple extensions might ship with the same
+ *   library in a different version or variant. This registry cannot (and does
+ *   not attempt to) prevent library conflicts.
+ * - Extensions implementing and thereby depending on a library that is
+ *   registered by another extension can only rely on that extension's library.
+ * - Two (or more) extensions can still register the same library and use it
+ *   without conflicts in case the libraries are loaded on certain pages only.
+ */
+interface LibraryDiscoveryInterface {
+
+  /**
+   * Gets all libraries defined by an extension.
+   *
+   * @param string $extension
+   *   The name of the extension that registered a library.
+   *
+   * @return array
+   *   An associative array of libraries registered by $extension is returned
+   *   (which may be empty).
+   *
+   * @see self::getLibraryByName()
+   */
+  public function getLibrariesByExtension($extension);
+
+  /**
+   * Gets a single library defined by an extension by name.
+   *
+   * @param string $extension
+   *   The name of the extension that registered a library.
+   * @param string $name
+   *   The name of a registered library to retrieve.
+   *
+   * @return array|FALSE
+   *   The definition of the requested library, if $name was passed and it
+   *   exists, otherwise FALSE.
+   */
+  public function getLibraryByName($extension, $name);
+
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php
index 0881810841dc979dde209fb7b1933708745839cf..937b83ccb90d0cee535c14dadee796a15d23d83f 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Common/JavaScriptTest.php
@@ -621,7 +621,9 @@ function testLibraryRender() {
    */
   function testLibraryAlter() {
     // Verify that common_test altered the title of Farbtastic.
-    $library = drupal_get_library('core/jquery.farbtastic');
+    /** @var \Drupal\Core\Asset\LibraryDiscoveryInterface $library_discovery */
+    $library_discovery = \Drupal::service('library.discovery');
+    $library = $library_discovery->getLibraryByName('core', 'jquery.farbtastic');
     $this->assertEqual($library['version'], '0.0', 'Registered libraries were altered.');
 
     // common_test_library_info_alter() also added a dependency on jQuery Form.
@@ -637,7 +639,9 @@ function testLibraryAlter() {
    * @see common_test.library.yml
    */
   function testLibraryNameConflicts() {
-    $farbtastic = drupal_get_library('common_test/jquery.farbtastic');
+    /** @var \Drupal\Core\Asset\LibraryDiscoveryInterface $library_discovery */
+    $library_discovery = \Drupal::service('library.discovery');
+    $farbtastic = $library_discovery->getLibraryByName('common_test', 'jquery.farbtastic');
     $this->assertEqual($farbtastic['version'], '0.1', 'Alternative libraries can be added to the page.');
   }
 
@@ -645,7 +649,9 @@ function testLibraryNameConflicts() {
    * Tests non-existing libraries.
    */
   function testLibraryUnknown() {
-    $result = drupal_get_library('unknown/unknown');
+    /** @var \Drupal\Core\Asset\LibraryDiscoveryInterface $library_discovery */
+    $library_discovery = \Drupal::service('library.discovery');
+    $result = $library_discovery->getLibraryByName('unknown', 'unknown');
     $this->assertFalse($result, 'Unknown library returned FALSE.');
     drupal_static_reset('drupal_get_library');
 
@@ -669,19 +675,21 @@ function testAttachedLibrary() {
    * Tests retrieval of libraries via drupal_get_library().
    */
   function testGetLibrary() {
+    /** @var \Drupal\Core\Asset\LibraryDiscoveryInterface $library_discovery */
+    $library_discovery = \Drupal::service('library.discovery');
     // Retrieve all libraries registered by a module.
-    $libraries = drupal_get_library('common_test');
+    $libraries = $library_discovery->getLibrariesByExtension('common_test');
     $this->assertTrue(isset($libraries['jquery.farbtastic']), 'Retrieved all module libraries.');
     // Retrieve all libraries for a module not declaring any libraries.
     // Note: This test installs language module.
-    $libraries = drupal_get_library('dblog');
+    $libraries = $library_discovery->getLibrariesByExtension('dblog');
     $this->assertEqual($libraries, array(), 'Retrieving libraries from a module not declaring any libraries returns an emtpy array.');
 
     // Retrieve a specific library by module and name.
-    $farbtastic = drupal_get_library('common_test/jquery.farbtastic');
+    $farbtastic = $library_discovery->getLibraryByName('common_test', 'jquery.farbtastic');
     $this->assertEqual($farbtastic['version'], '0.1', 'Retrieved a single library.');
     // Retrieve a non-existing library by module and name.
-    $farbtastic = drupal_get_library('common_test/foo');
+    $farbtastic = $library_discovery->getLibraryByName('common_test', 'foo');
     $this->assertIdentical($farbtastic, FALSE, 'Retrieving a non-existing library returns FALSE.');
   }
 
diff --git a/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryTest.php b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..230cac61dd57a7081a2b71320685f415f0da9a4b
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/LibraryDiscoveryTest.php
@@ -0,0 +1,494 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\Asset\LibraryDiscoveryTest.
+ */
+
+namespace Drupal\Tests\Core\Asset;
+
+use Drupal\Core\Asset\LibraryDiscovery;
+use Drupal\Core\Cache\Cache;
+use Drupal\Tests\UnitTestCase;
+
+if (!defined('DRUPAL_ROOT')) {
+  define('DRUPAL_ROOT', dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__)))));
+}
+
+if (!defined('CSS_AGGREGATE_DEFAULT')) {
+  define('CSS_AGGREGATE_DEFAULT', 0);
+  define('CSS_AGGREGATE_THEME', 100);
+  define('CSS_BASE', -200);
+  define('CSS_LAYOUT', -100);
+  define('CSS_COMPONENT', 0);
+  define('CSS_STATE', 100);
+  define('CSS_THEME', 200);
+  define('JS_SETTING', -200);
+  define('JS_LIBRARY', -100);
+  define('JS_DEFAULT', 0);
+  define('JS_THEME', 100);
+}
+
+/**
+ * Tests the library discovery.
+ *
+ * @coversDefaultClass \Drupal\Core\Asset\LibraryDiscovery
+ */
+class LibraryDiscoveryTest extends UnitTestCase {
+
+  /**
+   * The tested library provider.
+   *
+   * @var \Drupal\Core\Asset\LibraryDiscovery|\Drupal\Tests\Core\Asset\TestLibraryDiscovery
+   */
+  protected $libraryDiscovery;
+
+  /**
+   * The mocked cache backend.
+   *
+   * @var \Drupal\Core\Cache\CacheBackendInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $cache;
+
+  /**
+   * The mocked module handler.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $moduleHandler;
+
+  /**
+   * The mocked theme handler.
+   *
+   * @var \Drupal\Core\Extension\ThemeHandlerInterface
+   */
+  protected $themeHandler;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'Tests \Drupal\Core\Asset\LibraryProvider',
+      'description' => '',
+      'group' => 'Asset handling',
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    $this->cache = $this->getMock('Drupal\Core\Cache\CacheBackendInterface');
+    $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
+    $this->themeHandler = $this->getMock('Drupal\Core\Extension\ThemeHandlerInterface');
+    $this->libraryDiscovery = new TestLibraryDiscovery($this->cache, $this->moduleHandler, $this->themeHandler);
+  }
+
+  /**
+   * Tests that basic functionality works for getLibraryByName.
+   *
+   * @covers ::getLibraryByName()
+   * @covers ::buildLibrariesByExtension()
+   */
+  public function testGetLibraryByNameSimple() {
+    $this->moduleHandler->expects($this->atLeastOnce())
+      ->method('moduleExists')
+      ->with('example_module')
+      ->will($this->returnValue(TRUE));
+
+    $path = __DIR__ . '/library_test_files';
+    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $this->libraryDiscovery->setPaths('module', 'example_module', $path);
+
+    $library = $this->libraryDiscovery->getLibraryByName('example_module', 'example');
+    $this->assertCount(0, $library['js']);
+    $this->assertCount(1, $library['css']);
+    $this->assertCount(0, $library['dependencies']);
+    $this->assertEquals($path . '/css/example.css', $library['css'][0]['data']);
+
+    // Ensures that VERSION is replaced by the current core version.
+    $this->assertEquals(\Drupal::VERSION, $library['version']);
+  }
+
+  /**
+   * Tests that basic functionality works for getLibrariesByExtension.
+   *
+   * @covers ::getLibrariesByExtension()
+   * @covers ::buildLibrariesByExtension()
+   */
+  public function testGetLibrariesByExtensionSimple() {
+    $this->moduleHandler->expects($this->atLeastOnce())
+      ->method('moduleExists')
+      ->with('example_module')
+      ->will($this->returnValue(TRUE));
+
+    $path = __DIR__ . '/library_test_files';
+    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $this->libraryDiscovery->setPaths('module', 'example_module', $path);
+
+    $libraries = $this->libraryDiscovery->getLibrariesByExtension('example_module', 'example');
+    $this->assertCount(1, $libraries);
+    $this->assertEquals($path . '/css/example.css', $libraries['example']['css'][0]['data']);
+  }
+
+  /**
+   * Tests that a theme can be used instead of a module.
+   *
+   * @covers ::getLibraryByName()
+   * @covers ::buildLibrariesByExtension()
+   */
+  public function testGetLibraryByNameWithTheme() {
+    $this->moduleHandler->expects($this->atLeastOnce())
+      ->method('moduleExists')
+      ->with('example_theme')
+      ->will($this->returnValue(FALSE));
+
+    $path = __DIR__ . '/library_test_files';
+    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $this->libraryDiscovery->setPaths('theme', 'example_theme', $path);
+
+    $library = $this->libraryDiscovery->getLibraryByName('example_theme', 'example');
+    $this->assertCount(0, $library['js']);
+    $this->assertCount(1, $library['css']);
+    $this->assertCount(0, $library['dependencies']);
+    $this->assertEquals($path . '/css/example.css', $library['css'][0]['data']);
+  }
+
+  /**
+   * Tests that a module with a missing library file results in FALSE.
+   *
+   * @covers ::getLibraryByName()
+   * @covers ::getLibrariesByExtension()
+   * @covers ::buildLibrariesByExtension()
+   */
+  public function testGetLibraryWithMissingLibraryFile() {
+    $this->moduleHandler->expects($this->atLeastOnce())
+      ->method('moduleExists')
+      ->with('example_module')
+      ->will($this->returnValue(TRUE));
+
+    $path = __DIR__ . '/library_test_files_not_existing';
+    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $this->libraryDiscovery->setPaths('module', 'example_module', $path);
+
+    $this->assertFalse($this->libraryDiscovery->getLibraryByName('example_module', 'example'));
+    $this->assertFalse($this->libraryDiscovery->getLibrariesByExtension('example_module'));
+  }
+
+  /**
+   * Tests that an exception is thrown when a libraries file couldn't be parsed.
+   *
+   * @expectedException \Drupal\Core\Asset\Exception\InvalidLibraryFileException
+   *
+   * @covers ::buildLibrariesByExtension()
+   */
+  public function testInvalidLibrariesFile() {
+    $this->moduleHandler->expects($this->atLeastOnce())
+      ->method('moduleExists')
+      ->with('invalid_file')
+      ->will($this->returnValue(TRUE));
+
+    $path = __DIR__ . '/library_test_files';
+    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $this->libraryDiscovery->setPaths('module', 'invalid_file', $path);
+
+    $this->libraryDiscovery->getLibrariesByExtension('invalid_file');
+  }
+
+  /**
+   * Tests that an exception is thrown when no CSS/JS/setting is specified.
+   *
+   * @expectedException \Drupal\Core\Asset\Exception\IncompleteLibraryDefinitionException
+   * @expectedExceptionMessage Incomplete library definition for 'example' in core/tests/Drupal/Tests/Core/Asset/library_test_files/example_module_missing_information.libraries.yml
+   *
+   * @covers ::buildLibrariesByExtension()
+   */
+  public function testGetLibraryWithMissingInformation() {
+    $this->moduleHandler->expects($this->atLeastOnce())
+      ->method('moduleExists')
+      ->with('example_module_missing_information')
+      ->will($this->returnValue(TRUE));
+
+    $path = __DIR__ . '/library_test_files';
+    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $this->libraryDiscovery->setPaths('module', 'example_module_missing_information', $path);
+
+    $this->libraryDiscovery->getLibrariesByExtension('example_module_missing_information');
+  }
+
+  /**
+   * Tests that the version property of external libraries is handled.
+   *
+   * @covers ::buildLibrariesByExtension()
+   */
+  public function testExternalLibraries() {
+    $this->moduleHandler->expects($this->atLeastOnce())
+      ->method('moduleExists')
+      ->with('external')
+      ->will($this->returnValue(TRUE));
+
+    $path = __DIR__ . '/library_test_files';
+    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $this->libraryDiscovery->setPaths('module', 'external', $path);
+
+    $library = $this->libraryDiscovery->getLibraryByName('external', 'example_external');
+    $this->assertEquals($path . '/css/example_external.css', $library['css'][0]['data']);
+    $this->assertEquals('3.14', $library['version']);
+  }
+
+  /**
+   * Ensures that CSS weights are taken into account properly.
+   *
+   * @covers ::buildLibrariesByExtension()
+   */
+  public function testDefaultCssWeights() {
+    $this->moduleHandler->expects($this->atLeastOnce())
+      ->method('moduleExists')
+      ->with('css_weights')
+      ->will($this->returnValue(TRUE));
+
+    $path = __DIR__ . '/library_test_files';
+    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $this->libraryDiscovery->setPaths('module', 'css_weights', $path);
+
+    $library = $this->libraryDiscovery->getLibraryByName('css_weights', 'example');
+    $css = $library['css'];
+    $this->assertCount(10, $css);
+
+    // The following default weights are tested:
+    // - CSS_BASE: -200
+    // - CSS_LAYOUT: -100
+    // - CSS_COMPONENT: 0
+    // - CSS_STATE: 100
+    // - CSS_THEME: 200
+    $this->assertEquals(200, $css[0]['weight']);
+    $this->assertEquals(200 + 29, $css[1]['weight']);
+    $this->assertEquals(-200, $css[2]['weight']);
+    $this->assertEquals(-200 + 97, $css[3]['weight']);
+    $this->assertEquals(-100, $css[4]['weight']);
+    $this->assertEquals(-100 + 92, $css[5]['weight']);
+    $this->assertEquals(0, $css[6]['weight']);
+    $this->assertEquals(45, $css[7]['weight']);
+    $this->assertEquals(100, $css[8]['weight']);
+    $this->assertEquals(100 + 8, $css[9]['weight']);
+  }
+
+  /**
+   * Ensures that you cannot provide positive weights for JavaScript libraries.
+   *
+   * @expectedException \UnexpectedValueException
+   *
+   * @covers ::buildLibrariesByExtension()
+   */
+  public function testJsWithPositiveWeight() {
+    $this->moduleHandler->expects($this->atLeastOnce())
+      ->method('moduleExists')
+      ->with('js_positive_weight')
+      ->will($this->returnValue(TRUE));
+
+    $path = __DIR__ . '/library_test_files';
+    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $this->libraryDiscovery->setPaths('module', 'js_positive_weight', $path);
+
+    $this->libraryDiscovery->getLibrariesByExtension('js_positive_weight');
+  }
+
+  /**
+   * Tests a library with CSS/JavaScript and a setting.
+   *
+   * @covers ::buildLibrariesByExtension()
+   */
+  public function testLibraryWithCssJsSetting() {
+    $this->moduleHandler->expects($this->atLeastOnce())
+      ->method('moduleExists')
+      ->with('css_js_settings')
+      ->will($this->returnValue(TRUE));
+
+    $path = __DIR__ . '/library_test_files';
+    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $this->libraryDiscovery->setPaths('module', 'css_js_settings', $path);
+
+    $library = $this->libraryDiscovery->getLibraryByName('css_js_settings', 'example');
+
+    // Ensures that the group and type are set automatically.
+    $this->assertEquals(-100, $library['js'][0]['group']);
+    $this->assertEquals('file', $library['js'][0]['type']);
+    $this->assertEquals($path . '/js/example.js', $library['js'][0]['data']);
+
+    $this->assertEquals(0, $library['css'][0]['group']);
+    $this->assertEquals('file', $library['css'][0]['type']);
+    $this->assertEquals($path . '/css/base.css', $library['css'][0]['data']);
+
+    $this->assertEquals('setting', $library['js'][1]['type']);
+    $this->assertEquals(array('key' => 'value'), $library['js'][1]['data']);
+  }
+
+  /**
+   * Tests a library with dependencies.
+   *
+   * @covers ::buildLibrariesByExtension()
+   */
+  public function testLibraryWithDependencies() {
+     $this->moduleHandler->expects($this->atLeastOnce())
+      ->method('moduleExists')
+      ->with('dependencies')
+      ->will($this->returnValue(TRUE));
+
+    $path = __DIR__ . '/library_test_files';
+    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $this->libraryDiscovery->setPaths('module', 'dependencies', $path);
+
+    $library = $this->libraryDiscovery->getLibraryByName('dependencies', 'example');
+    $this->assertCount(2, $library['dependencies']);
+    $this->assertEquals('external/example_external', $library['dependencies'][0]);
+    $this->assertEquals('example_module/example', $library['dependencies'][1]);
+  }
+
+  /**
+   * Tests a library with a couple of data formats like full URL.
+   *
+   * @covers ::buildLibrariesByExtension()
+   */
+  public function testLibraryWithDataTypes() {
+    $this->moduleHandler->expects($this->atLeastOnce())
+      ->method('moduleExists')
+      ->with('data_types')
+      ->will($this->returnValue(TRUE));
+
+    $path = __DIR__ . '/library_test_files';
+    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $this->libraryDiscovery->setPaths('module', 'data_types', $path);
+
+    $this->libraryDiscovery->setFileValidUri('public://test.css', TRUE);
+    $this->libraryDiscovery->setFileValidUri('public://test2.css', FALSE);
+
+    $library = $this->libraryDiscovery->getLibraryByName('data_types', 'example');
+    $this->assertCount(5, $library['css']);
+    $this->assertEquals('external', $library['css'][0]['type']);
+    $this->assertEquals('http://example.com/test.css', $library['css'][0]['data']);
+    $this->assertEquals('file', $library['css'][1]['type']);
+    $this->assertEquals('tmp/test.css', $library['css'][1]['data']);
+    $this->assertEquals('external', $library['css'][2]['type']);
+    $this->assertEquals('//cdn.com/test.css', $library['css'][2]['data']);
+    $this->assertEquals('file', $library['css'][3]['type']);
+    $this->assertEquals('public://test.css', $library['css'][3]['data']);
+  }
+
+  /**
+   * Tests the internal static cache.
+   *
+   * @covers ::ensureLibraryInformation()
+   */
+  public function testStaticCache() {
+    $this->moduleHandler->expects($this->once())
+      ->method('moduleExists')
+      ->with('example_module')
+      ->will($this->returnValue(TRUE));
+    $this->cache->expects($this->once())
+      ->method('get')
+      ->with('library:info:' . 'example_module')
+      ->will($this->returnValue(NULL));
+
+    $path = __DIR__ . '/library_test_files';
+    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $this->libraryDiscovery->setPaths('module', 'example_module', $path);
+
+    $library = $this->libraryDiscovery->getLibraryByName('example_module', 'example');
+    $this->assertEquals($path . '/css/example.css', $library['css'][0]['data']);
+
+    $library = $this->libraryDiscovery->getLibraryByName('example_module', 'example');
+    $this->assertEquals($path . '/css/example.css', $library['css'][0]['data']);
+  }
+
+  /**
+   * Tests the external cache.
+   *
+   * @covers ::getCache()
+   */
+  public function testExternalCache() {
+    // Ensure that the module handler does not need to be touched.
+    $this->moduleHandler->expects($this->never())
+      ->method('moduleExists');
+
+    $path = __DIR__ . '/library_test_files';
+    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+
+    // Setup a cache entry which will be retrieved, but just once, so the static
+    // cache still works.
+    $this->cache->expects($this->once())
+      ->method('get')
+      ->with('library:info:' . 'example_module')
+      ->will($this->returnValue((object) array(
+        'data' => array(
+          'example' => array(
+            'css' => array(
+              array(
+                'data' => $path . '/css/example.css',
+              ),
+            ),
+          ),
+        )
+      )));
+
+    $library = $this->libraryDiscovery->getLibraryByName('example_module', 'example');
+    $this->assertEquals($path . '/css/example.css', $library['css'][0]['data']);
+
+    $library = $this->libraryDiscovery->getLibraryByName('example_module', 'example');
+    $this->assertEquals($path . '/css/example.css', $library['css'][0]['data']);
+  }
+
+  /**
+   * Tests setting the external cache.
+   *
+   * @covers ::setCache()
+   */
+  public function testSetCache() {
+    $this->moduleHandler->expects($this->once())
+      ->method('moduleExists')
+      ->with('example_module')
+      ->will($this->returnValue(TRUE));
+
+    $path = __DIR__ . '/library_test_files';
+    $path = substr($path, strlen(DRUPAL_ROOT) + 1);
+    $this->libraryDiscovery->setPaths('module', 'example_module', $path);
+
+    $this->cache->expects($this->once())
+      ->method('set')
+      ->with('library:info:example_module', $this->isType('array'), Cache::PERMANENT, array(
+      'extension' => array(TRUE, 'example_module'),
+      'library_info' => array(TRUE),
+    ));
+
+    $library = $this->libraryDiscovery->getLibraryByName('example_module', 'example');
+    $this->assertEquals($path . '/css/example.css', $library['css'][0]['data']);
+  }
+
+}
+
+/**
+ * Wraps the tested class to mock the external dependencies.
+ */
+class TestLibraryDiscovery extends LibraryDiscovery {
+
+  protected $paths;
+
+  protected $validUris;
+
+  protected function drupalGetPath($type, $name) {
+    return isset($this->paths[$type][$name]) ? $this->paths[$type][$name] : NULL;
+  }
+
+  public function setPaths($type, $name, $path) {
+    $this->paths[$type][$name] = $path;
+  }
+
+  protected function fileValidUri($source) {
+    return isset($this->validUris[$source]) ? $this->validUris[$source] : FALSE;
+  }
+
+  public function setFileValidUri($source, $valid) {
+    $this->validUris[$source] = $valid;
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Asset/library_test_files/css_js_settings.libraries.yml b/core/tests/Drupal/Tests/Core/Asset/library_test_files/css_js_settings.libraries.yml
new file mode 100644
index 0000000000000000000000000000000000000000..fdb479ff1e298a147bc5fc78fe46d9ac306cbe31
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/library_test_files/css_js_settings.libraries.yml
@@ -0,0 +1,8 @@
+example:
+  css:
+    base:
+      css/base.css: {}
+  js:
+    js/example.js: {}
+  settings:
+    key: value
diff --git a/core/tests/Drupal/Tests/Core/Asset/library_test_files/css_weights.libraries.yml b/core/tests/Drupal/Tests/Core/Asset/library_test_files/css_weights.libraries.yml
new file mode 100644
index 0000000000000000000000000000000000000000..fd0d6eca44cd5247861dc8c4088b45ee99297d94
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/library_test_files/css_weights.libraries.yml
@@ -0,0 +1,22 @@
+example:
+  css:
+    theme:
+      css/theme__no_weight.css: {}
+      css/theme__weight.css:
+        weight: 29
+    base:
+      css/base__no_weight.css: {}
+      css/base__weight.css:
+        weight: 97
+    layout:
+      css/layout__no_weight.css: {}
+      css/layout__weight.css:
+        weight: 92
+    component:
+      css/component__no_weight.css: {}
+      css/component__weight.css:
+        weight: 45
+    state:
+      css/state__no_weight.css: {}
+      css/state__weight.css:
+        weight: 8
diff --git a/core/tests/Drupal/Tests/Core/Asset/library_test_files/data_types.libraries.yml b/core/tests/Drupal/Tests/Core/Asset/library_test_files/data_types.libraries.yml
new file mode 100644
index 0000000000000000000000000000000000000000..eb817df18b8eb2ca292fde4053f37e315463d063
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/library_test_files/data_types.libraries.yml
@@ -0,0 +1,13 @@
+example:
+  css:
+    theme:
+      # External URL.
+      'http://example.com/test.css':
+        type: external
+      # Absolute path.
+      /tmp/test.css: {}
+      # Protocol free.
+      //cdn.com/test.css: {}
+      # Stream wrapper URI.
+      'public://test.css': {}
+      'example://test2.css': {}
diff --git a/core/tests/Drupal/Tests/Core/Asset/library_test_files/dependencies.libraries.yml b/core/tests/Drupal/Tests/Core/Asset/library_test_files/dependencies.libraries.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9a8b4ddf2818e9b1efb4143dbbf8131936fc098d
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/library_test_files/dependencies.libraries.yml
@@ -0,0 +1,6 @@
+example:
+  css:
+    css/example.js: {}
+  dependencies:
+    - external/example_external
+    - example_module/example
diff --git a/core/tests/Drupal/Tests/Core/Asset/library_test_files/example_module.libraries.yml b/core/tests/Drupal/Tests/Core/Asset/library_test_files/example_module.libraries.yml
new file mode 100644
index 0000000000000000000000000000000000000000..653438ce90d1d0cc846e714bf2b446c5a38e8b0a
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/library_test_files/example_module.libraries.yml
@@ -0,0 +1,5 @@
+example:
+  version: VERSION
+  css:
+    theme:
+      css/example.css: {}
diff --git a/core/tests/Drupal/Tests/Core/Asset/library_test_files/example_module_missing_information.libraries.yml b/core/tests/Drupal/Tests/Core/Asset/library_test_files/example_module_missing_information.libraries.yml
new file mode 100644
index 0000000000000000000000000000000000000000..0495fb603f02669657356d82dc92947fd54c400e
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/library_test_files/example_module_missing_information.libraries.yml
@@ -0,0 +1,2 @@
+example:
+  version: VERSION
diff --git a/core/tests/Drupal/Tests/Core/Asset/library_test_files/example_theme.libraries.yml b/core/tests/Drupal/Tests/Core/Asset/library_test_files/example_theme.libraries.yml
new file mode 100644
index 0000000000000000000000000000000000000000..62c13461e18581c424254205c2b7f2fbc3cdca45
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/library_test_files/example_theme.libraries.yml
@@ -0,0 +1,4 @@
+example:
+  css:
+    theme:
+      css/example.css: {}
diff --git a/core/tests/Drupal/Tests/Core/Asset/library_test_files/external.libraries.yml b/core/tests/Drupal/Tests/Core/Asset/library_test_files/external.libraries.yml
new file mode 100644
index 0000000000000000000000000000000000000000..0486a7271970e02723e85965e16e318e9f075ce5
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/library_test_files/external.libraries.yml
@@ -0,0 +1,5 @@
+example_external:
+  version: v3.14
+  css:
+    theme:
+      css/example_external.css: {}
diff --git a/core/tests/Drupal/Tests/Core/Asset/library_test_files/invalid_file.libraries.yml b/core/tests/Drupal/Tests/Core/Asset/library_test_files/invalid_file.libraries.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f62f2896e13b810f677530024d4d3bad05a97275
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/library_test_files/invalid_file.libraries.yml
@@ -0,0 +1,3 @@
+example:
+   key1: value1
+  key2: value2
diff --git a/core/tests/Drupal/Tests/Core/Asset/library_test_files/js_positive_weight.libraries.yml b/core/tests/Drupal/Tests/Core/Asset/library_test_files/js_positive_weight.libraries.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9fc48142bef2ec5a1291005ee3301c239ad1b578
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Asset/library_test_files/js_positive_weight.libraries.yml
@@ -0,0 +1,4 @@
+example:
+  js:
+    js/positive_weight.js:
+      weight: 10