diff --git a/libraries.module b/libraries.module
index c92bd01..1326a1b 100644
--- a/libraries.module
+++ b/libraries.module
@@ -213,11 +213,15 @@ function libraries_traverse_library(&$library, $callback) {
  * into
  * @code
  * $library['files']['js'] = array(
- *   'example_1.js' => array(),
- *   'example_2.js' => array(),
+ *   'example_1.js' => array('type' => 'file'),
+ *   'example_2.js' => array('type' => 'file'),
  * );
  * @endcode
  * It does the same for the 'integration files' property.
+ * As you can see in see above example, this function also detects the type of
+ * file. For CSS and JavaScript files this can be either 'file' (local file),
+ * 'external' (external file), or 'inline (inline code). JavaScript also has the
+ * 'setting' type (JavaScript settings). PHP files do not have a type.
  *
  * @param $library
  *   An associative array of library information or a part of it, passed by
@@ -250,10 +254,43 @@ function libraries_prepare_files(&$library, $version = NULL, $variant = NULL) {
     foreach (array('js', 'css', 'php') as $type) {
       if (isset($files[$type])) {
         foreach ($files[$type] as $key => $value) {
-          // Unset numeric keys and turn the respective values into keys.
-          if (is_numeric($key)) {
-            $files[$type][$value] = array();
-            unset($files[$type][$key]);
+          // Entries with non-integer keys are assumed to be fine the way they
+          // are.
+          if (is_int($key)) {
+            if ($type != 'php') {
+              // JavaScript settings.
+              if ($type == 'js' && is_array($value)) {
+                // Because for JavaScript settings the data is an array, it
+                // cannot be passed as the array key. We special-case this in
+                // libraries_load_files().
+                $files[$type][$key] = array(
+                  'type' => 'setting',
+                  'data' => $value,
+                );
+              }
+              else {
+                // External files.
+                if (url_is_external($value)) {
+                  $files[$type][$value] = array('type' => 'external');
+                }
+                // Local files.
+                elseif(!preg_match('$[^a-zA-Z0-9-_.\/]$', $value)) {
+                  $files[$type][$value] = array('type' => 'file');
+                }
+                // Inline JavaScript and CSS.
+                // This is based on the assumption that inline code contains at
+                // least one character that is invalid for a filename.
+                else {
+                  $files[$type][$value] = array('type' => 'inline');
+                }
+                unset($files[$type][$key]);
+              }
+            }
+            // PHP files.
+            else {
+              $files[$type][$value] = array();
+              unset($files[$type][$key]);
+            }
           }
         }
       }
@@ -580,21 +617,17 @@ function libraries_load_files($library) {
   // Load both the JavaScript and the CSS files.
   // The parameters for drupal_add_js() and drupal_add_css() require special
   // handling.
-  // @see drupal_process_attached()
+  // @see libraries_prepare_files()
   foreach (array('js', 'css') as $type) {
     if (!empty($library['files'][$type])) {
       foreach ($library['files'][$type] as $data => $options) {
-        // If the value is not an array, it's a filename and passed as first
-        // (and only) argument.
-        if (!is_array($options)) {
-          // Prepend the library path to the file name.
-          $data = "$path/$options";
-          $options = NULL;
+        // For local files, prepend the library path.
+        if ($options['type'] == 'file') {
+          $data = "$path/$data";
         }
-        // In some cases, the first parameter ($data) is an array. Arrays can't
-        // be passed as keys in PHP, so we have to get $data from the value
-        // array.
-        if (is_numeric($data)) {
+        // JavaScript settings have an array as the data, so it cannot be passed
+        // as the array key, but is stored in the options array instead.
+        if (is_int($data)) {
           $data = $options['data'];
           unset($options['data']);
         }
diff --git a/tests/libraries.test b/tests/libraries.test
index 2a2e2cf..6c1b8fc 100644
--- a/tests/libraries.test
+++ b/tests/libraries.test
@@ -35,8 +35,8 @@ class LibrariesTestCase extends DrupalWebTestCase {
     // Test libraries_prepare_files().
     $expected = array(
       'files' => array(
-        'js' => array('example.js' => array()),
-        'css' => array('example.css' => array()),
+        'js' => array('example.js' => array('type' => 'file')),
+        'css' => array('example.css' => array('type' => 'file')),
         'php' => array('example.php' => array()),
       ),
     );
@@ -56,8 +56,8 @@ class LibrariesTestCase extends DrupalWebTestCase {
       'library path' => drupal_get_path('module', 'libraries') . '/tests/example',
       'version' => '1',
       'files' => array(
-        'js' => array('example_1.js' => array()),
-        'css' => array('example_1.css' => array()),
+        'js' => array('example_1.js' => array('type' => 'file')),
+        'css' => array('example_1.css' => array('type' => 'file')),
         'php' => array('example_1.php' => array()),
       ),
       'module' => 'libraries_test',
@@ -125,8 +125,8 @@ class LibrariesTestCase extends DrupalWebTestCase {
     // Test a top-level files property.
     $library = libraries_detect('example_files');
     $files = array(
-      'js' => array('example_1.js' => array()),
-      'css' => array('example_1.css' => array()),
+      'js' => array('example_1.js' => array('type' => 'file')),
+      'css' => array('example_1.css' => array('type' => 'file')),
       'php' => array('example_1.php' => array()),
     );
     $this->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
@@ -135,8 +135,8 @@ class LibrariesTestCase extends DrupalWebTestCase {
     // Test version-specific library files.
     $library = libraries_detect('example_versions');
     $files = array(
-      'js' => array('example_2.js' => array()),
-      'css' => array('example_2.css' => array()),
+      'js' => array('example_2.js' => array('type' => 'file')),
+      'css' => array('example_2.css' => array('type' => 'file')),
       'php' => array('example_2.php' => array()),
     );
     $this->verbose('<pre>' . var_export($library, TRUE) . '</pre>');
diff --git a/tests/libraries_test.module b/tests/libraries_test.module
index 4893b11..dd1aa1d 100644
--- a/tests/libraries_test.module
+++ b/tests/libraries_test.module
@@ -73,6 +73,46 @@ function libraries_test_libraries_info() {
     ),
   );
 
+  // Test all types of JavaScript and CSS supported by drupal_add_js() and
+  // drupal_add_css().
+  // We cannot test JavaScript and CSS programatically, so this currently
+  // serves only for manual testing.
+  $libraries['example_js_css'] = array(
+    'name' => 'Example JavaScript and CSS',
+    'library path' => drupal_get_path('module', 'libraries') . '/tests/example',
+    'version' => 1,
+    'variants' => array(
+      'file' => array(
+        'files' => array(
+          'js' => array('example_1.js'),
+          'css' => array('example_1.css'),
+        ),
+      ),
+      'external' => array(
+        'files' => array(
+          'js' => array(url(NULL, array('absolute' => TRUE)) . '/' . drupal_get_path('module', 'libraries') . '/tests/example/example_1.js'),
+          'css' => array(url(NULL, array('absolute' => TRUE)) . '/' . drupal_get_path('module', 'libraries') . '/tests/example/example_1.css'),
+        ),
+      ),
+      'inline' => array(
+        'files' => array(
+          'js' => array('jQuery(document).ready(function(){jQuery(".libraries-test-javascript").text("If this text shows up, inline JavaScript code was loaded successfully.");});'),
+          // This is the content of example_1.css.
+          'css' => array('.libraries-test-css{color:red;}'),
+        ),
+      ),
+      // There is no CSS equivalent of JavaScript settings.
+      'setting' => array(
+        'files' => array(
+          'js' => array(
+            array('librariesTest' => array('testSetting' => TRUE)),
+            'jQuery(document).ready(function(){if(Drupal.settings.librariesTest.testSetting){jQuery(".libraries-test-javascript").text("If this text shows up, JavaScript settings were loaded successfully.");}});',
+          ),
+        ),
+      )
+    ),
+  );
+
   // Test loading of integration files.
   // Normally added by the corresponding module via hook_libraries_info_alter(),
   // these files should be automatically loaded when the library is loaded.
@@ -333,7 +373,7 @@ function _libraries_test_return_installed($library, $name, $installed) {
  *
  * @see _libraries_test_callback()
  */
-function _libraries_test_info_callback(&$library, $version, $variant) {
+function _libraries_test_info_callback(&$library, $version = NULL, $variant = NULL) {
   _libraries_test_callback($library, $version, $variant, 'info');
 }
 
@@ -344,7 +384,7 @@ function _libraries_test_info_callback(&$library, $version, $variant) {
  *
  * @see _libraries_test_callback()
  */
-function _libraries_test_pre_detect_callback(&$library, $version, $variant) {
+function _libraries_test_pre_detect_callback(&$library, $version = NULL, $variant = NULL) {
   _libraries_test_callback($library, $version, $variant, 'pre-detect');
 }
 
@@ -355,7 +395,7 @@ function _libraries_test_pre_detect_callback(&$library, $version, $variant) {
  *
  * @see _libraries_test_callback()
  */
-function _libraries_test_post_detect_callback(&$library, $version, $variant) {
+function _libraries_test_post_detect_callback(&$library, $version = NULL, $variant = NULL) {
   _libraries_test_callback($library, $version, $variant, 'post-detect');
 }
 
@@ -366,7 +406,7 @@ function _libraries_test_post_detect_callback(&$library, $version, $variant) {
  *
  * @see _libraries_test_callback()
  */
-function _libraries_test_load_callback(&$library, $version, $variant) {
+function _libraries_test_load_callback(&$library, $version = NULL, $variant = NULL) {
   _libraries_test_callback($library, $version, $variant, 'load');
 }
 
@@ -442,6 +482,30 @@ function libraries_test_menu() {
     'page arguments' => array('example_versions_and_variants', 'example_variant_2'),
     'access callback' => TRUE,
   );
+  $items['libraries_test/js_css/file'] = array(
+    'title' => 'Test JavaScript and CSS: Local files',
+    'page callback' => '_libraries_test_load',
+    'page arguments' => array('example_js_css', 'file'),
+    'access callback' => TRUE,
+  );
+  $items['libraries_test/js_css/external'] = array(
+    'title' => 'Test JavaScript and CSS: External files',
+    'page callback' => '_libraries_test_load',
+    'page arguments' => array('example_js_css', 'external'),
+    'access callback' => TRUE,
+  );
+  $items['libraries_test/js_css/inline'] = array(
+    'title' => 'Test JavaScript and CSS: Inline code',
+    'page callback' => '_libraries_test_load',
+    'page arguments' => array('example_js_css', 'inline'),
+    'access callback' => TRUE,
+  );
+  $items['libraries_test/js_css/setting'] = array(
+    'title' => 'Test JavaScript and CSS: JavaScript settings',
+    'page callback' => '_libraries_test_load',
+    'page arguments' => array('example_js_css', 'setting'),
+    'access callback' => TRUE,
+  );
   return $items;
 }
 
