diff --git a/libraries.api.php b/libraries.api.php
index a54b7b4..54033d3 100644
--- a/libraries.api.php
+++ b/libraries.api.php
@@ -16,14 +16,35 @@
  *   - name: The official, human-readable name of the library.
  *   - vendor url: The URL of the homepage of the library.
  *   - download url: The URL of a web page on which the library can be obtained.
- *   - path: (optional) A relative path from the directory of the library to the
- *     actual library. Only required if the extracted download package contains
- *     the actual library files in a sub-directory.
- *   - library path: (optional) The absolute path to the library directory. This
+ *   - path: (optional) The absolute path to the library directory. This
  *     should not be declared normally, as it is automatically detected, to
  *     allow for multiple possible library locations. A valid use-case is an
  *     external library, in which case the full URL to the library should be
  *     specified here.
+ *   - path callback: (optional) The name of a function that detects and
+ *     returns the full path to the library. If the library cannot be found, it
+ *     returns FALSE. The first argument is always $library, an array containing
+ *     all library information as described here. There are two ways to declare
+ *     the path callback's additional arguments, either as a single $options
+ *     parameter or as multiple parameters, which correspond to the two ways to
+ *     specify the argument values (see 'path arguments'). Defaults to
+ *     libraries_get_path().
+ *   - path arguments: (optional) A list of arguments to pass to the path
+ *     callback. Path arguments can be declared either as an associative array
+ *     whose keys are the argument names or as an indexed array without
+ *     specifying keys. If declared as an associative array, the arguments get
+ *     passed to the location callback as a single $options parameter whose keys
+ *     are the argument names (i.e. $options is identical to the specified
+ *     array). If declared as an indexed array, the array values get passed to
+ *     the version callback as seperate arguments in the order they were
+ *     declared. The default location callback libraries_get_path() expects a
+ *     single, associative array with the following named keys:
+ *     - fallback: (optional) A fallback path to use in case the library is not
+ *       found locally. This can be used for libraries that can be downloaded,
+ *       but are also available externally.
+ *   - directory: (optional) A relative path from the directory of the library
+ *     to the actual library. Only required if the extracted download package
+ *     contains the actual library files in a sub-directory.
  *   - version: (optional) The version of the library. This should not be
  *     declared normally, as it is automatically detected (see 'version
  *     callback' below) to allow for version changes of libraries without code
@@ -47,7 +68,7 @@
  *     declared as an indexed array, the array values get passed to the version
  *     callback as seperate arguments in the order they were declared. The
  *     default version callback libraries_get_version() expects a single,
- *     associative array with named keys:
+ *     associative array with the following named keys:
  *     - file: The filename to parse for the version, relative to the library
  *       path. For example: 'docs/changelog.txt'.
  *     - pattern: A string containing a regular expression (PCRE) to match the
@@ -159,7 +180,7 @@ function hook_libraries_info() {
     'download url' => 'http://example.com/download',
     // Optional: If, after extraction, the actual library files are contained in
     // 'sites/all/libraries/example/lib', specify the relative path here.
-    'path' => 'lib',
+    'directory' => 'lib',
     // Optional: Define a custom version detection callback, if required.
     'version callback' => 'mymodule_get_version',
     // Specify arguments for the version callback. By default,
@@ -286,7 +307,7 @@ function hook_libraries_info() {
     'name' => 'TinyMCE',
     'vendor url' => 'http://tinymce.moxiecode.com',
     'download url' => 'http://tinymce.moxiecode.com/download.php',
-    'path' => 'jscripts/tiny_mce',
+    'directory' => 'jscripts/tiny_mce',
     // The regular expression catches two parts (the major and the minor
     // version), which libraries_get_version() doesn't allow.
     'version callback' => 'tinymce_get_version',
@@ -356,6 +377,50 @@ function hook_libraries_info() {
       ),
     ),
   );
+
+  // A simple external library.
+  $libraries['external'] = array(
+    'name' => 'External library',
+    // This library does not have a download url!
+    'vendor url' => 'http://example.com/external',
+    // It is only availably externally so we must declare the library path.
+    'path' => 'http://example.com/external/source',
+    // The version cannot be detected programmatically, so it must be declared
+    // upfront.
+    'version' => '1.0.1',
+    // The library only consists of one file, which is located at
+    // http://example.com/external/source/external.js. We have already declared
+    // the library path above, so we only need to specify the filename here.
+    'files' => array(
+      'js' => array(
+        'external.js',
+      ),
+    ),
+  );
+
+  // A library that is both available locally and externally, i.e. you can
+  // download it to your server for performance or use the online version for
+  // convenience.
+  $libraries['openlayers'] = array(
+    'name' => 'OpenLayers',
+    'vendor url' => 'http://openlayers.org/',
+    'download url' => 'http://trac.osgeo.org/openlayers/wiki/HowToDownload',
+    // Because we want people to be able to use the library locally, but fall
+    // back to the external library, we declare the optional 'fallback' option.
+    // The path we specify is then used as a fallback if the library is not
+    // found locally.
+    'path arguments' => array(
+      'fallback' => 'http://openlayers.org/api',
+    ),
+    // Regardless of whether it is available locally or externally, the files
+    // are the same.
+    'files' => array(
+      'js' => array(
+        'OpenLayers.js',
+      ),
+    ),
+  );
+
   return $libraries;
 }
 
diff --git a/libraries.module b/libraries.module
index 65f2bf1..a81eb5d 100644
--- a/libraries.module
+++ b/libraries.module
@@ -15,32 +15,31 @@ function libraries_flush_caches() {
 /**
  * Gets the path of a library.
  *
- * @param $name
- *   The machine name of a library to return the path for.
- * @param $base_path
- *   Whether to prefix the resulting path with base_path().
+ * @param $library
+ *   An associative array containing all information about the library.
+ * @param $options
+ *   An associative array containing with the following keys:
+ *   - fallback: An external URL that, if specified, is returned if the library
+ *     is not found locally.
  *
  * @return
  *   The path to the specified library or FALSE if the library wasn't found.
  *
  * @ingroup libraries
  */
-function libraries_get_path($name, $base_path = FALSE) {
-  $libraries = &drupal_static(__FUNCTION__);
+function libraries_get_path($library, $options = array()) {
+  $directories = &drupal_static(__FUNCTION__);
 
-  if (!isset($libraries)) {
-    $libraries = libraries_get_libraries();
+  if (!isset($directories)) {
+    $directories = libraries_get_directories();
   }
 
-  $path = ($base_path ? base_path() : '');
-  if (!isset($libraries[$name])) {
-    return FALSE;
+  if (!isset($directories[$library['machine name']])) {
+    return (isset($options['fallback']) ? $options['fallback'] : FALSE);
   }
   else {
-    $path .= $libraries[$name];
+    return $directories[$library['machine name']];
   }
-
-  return $path;
 }
 
 /**
@@ -59,7 +58,7 @@ function libraries_get_path($name, $base_path = FALSE) {
  *
  * @ingroup libraries
  */
-function libraries_get_libraries() {
+function libraries_get_directories() {
   $directory = 'libraries';
   $searchdir = array();
   $profile = drupal_get_profile();
@@ -334,8 +333,9 @@ function libraries_info_defaults(&$library, $name) {
     'name' => $name,
     'vendor url' => '',
     'download url' => '',
-    'path' => '',
-    'library path' => NULL,
+    'path callback' => 'libraries_get_path',
+    'path arguments' => array(),
+    'directory' => '',
     'version callback' => 'libraries_get_version',
     'version arguments' => array(),
     'files' => array(),
@@ -394,10 +394,18 @@ function libraries_detect($name) {
   $library['installed'] = FALSE;
 
   // Check whether the library exists.
-  if (!isset($library['library path'])) {
-    $library['library path'] = libraries_get_path($library['machine name']);
+  if (!isset($library['path'])) {
+    // We support both a single parameter, which is an associative array, and an
+    // indexed array of multiple parameters.
+    if (isset($library['path arguments'][0])) {
+      // Add the library name as the first argument.
+      $library['path'] = call_user_func_array($library['path callback'], array_merge(array($library), $library['path arguments']));
+    }
+    else {
+      $library['path'] = $library['path callback']($library, $library['path arguments']);
+    }
   }
-  if ($library['library path'] === FALSE || !file_exists($library['library path'])) {
+  if ($library['path'] == FALSE) {
     $library['error'] = 'not found';
     $library['error message'] = t('The %library library could not be found.', array(
       '%library' => $library['name'],
@@ -564,15 +572,15 @@ function libraries_load_files($library) {
     foreach ($library['integration files'] as $module => $files) {
       libraries_load_files(array(
         'files' => $files,
-        'path' => '',
-        'library path' => drupal_get_path('module', $module),
+        'path' => drupal_get_path('module', $module),
+        'directory' => '',
       ));
     }
   }
 
   // Construct the full path to the library for later use.
-  $path = $library['library path'];
-  $path = ($library['path'] !== '' ? $path . '/' . $library['path'] : $path);
+  $path = $library['path'];
+  $path = ($library['directory'] !== '' ? $path . '/' . $library['directory'] : $path);
 
   // Count the number of loaded files for the return value.
   $count = 0;
@@ -654,7 +662,7 @@ function libraries_get_version($library, $options) {
     'cols' => 200,
   );
 
-  $file = DRUPAL_ROOT . '/' . $library['library path'] . '/' . $options['file'];
+  $file = DRUPAL_ROOT . '/' . $library['path'] . '/' . $options['file'];
   if (empty($options['file']) || !file_exists($file)) {
     return;
   }
diff --git a/tests/libraries.test b/tests/libraries.test
index 2a2e2cf..a292bff 100644
--- a/tests/libraries.test
+++ b/tests/libraries.test
@@ -53,7 +53,7 @@ class LibrariesTestCase extends DrupalWebTestCase {
     // Test that library information is found correctly.
     $expected = array(
       'name' => 'Example files',
-      'library path' => drupal_get_path('module', 'libraries') . '/tests/example',
+      'path' => drupal_get_path('module', 'libraries') . '/tests/example',
       'version' => '1',
       'files' => array(
         'js' => array('example_1.js' => array()),
@@ -160,7 +160,7 @@ class LibrariesTestCase extends DrupalWebTestCase {
     // Test the applying of callbacks.
     $expected = array(
       'name' => 'Example callback',
-      'library path' => drupal_get_path('module', 'libraries') . '/tests/example',
+      'path' => drupal_get_path('module', 'libraries') . '/tests/example',
       'version' => '1',
       'versions' => array(
         '1' => array(
diff --git a/tests/libraries_test.module b/tests/libraries_test.module
index 4893b11..076b85b 100644
--- a/tests/libraries_test.module
+++ b/tests/libraries_test.module
@@ -12,17 +12,18 @@ function libraries_test_libraries_info() {
   // Test library detection.
   $libraries['example_missing'] = array(
     'name' => 'Example missing',
-    'library path' => drupal_get_path('module', 'libraries') . '/tests/missing',
+    // Not specifying a path invokes libraries_get_path(), which will return
+    // FALSE.
   );
   $libraries['example_undetected_version'] = array(
     'name' => 'Example undetected version',
-    'library path' => drupal_get_path('module', 'libraries') . '/tests',
+    'path' => drupal_get_path('module', 'libraries') . '/tests',
     'version callback' => '_libraries_test_return_version',
     'version arguments' => array(FALSE),
   );
   $libraries['example_unsupported_version'] = array(
     'name' => 'Example unsupported version',
-    'library path' => drupal_get_path('module', 'libraries') . '/tests',
+    'path' => drupal_get_path('module', 'libraries') . '/tests',
     'version callback' => '_libraries_test_return_version',
     'version arguments' => array('1'),
     'versions' => array(
@@ -32,7 +33,7 @@ function libraries_test_libraries_info() {
 
   $libraries['example_supported_version'] = array(
     'name' => 'Example supported version',
-    'library path' => drupal_get_path('module', 'libraries') . '/tests',
+    'path' => drupal_get_path('module', 'libraries') . '/tests',
     'version callback' => '_libraries_test_return_version',
     'version arguments' => array('1'),
     'versions' => array(
@@ -43,7 +44,7 @@ function libraries_test_libraries_info() {
   // Test the default version callback.
   $libraries['example_default_version_callback'] = array(
     'name' => 'Example default version callback',
-    'library path' => drupal_get_path('module', 'libraries') . '/tests/example',
+    'path' => drupal_get_path('module', 'libraries') . '/tests/example',
     'version arguments' => array(
       'file' => 'README.txt',
       // Version 1
@@ -55,7 +56,7 @@ function libraries_test_libraries_info() {
   // Test a multiple-parameter version callback.
   $libraries['example_multiple_parameter_version_callback'] = array(
     'name' => 'Example multiple parameter version callback',
-    'library path' => drupal_get_path('module', 'libraries') . '/tests/example',
+    'path' => drupal_get_path('module', 'libraries') . '/tests/example',
     // Version 1
     'version callback' => '_libraries_test_get_version',
     'version arguments' => array('README.txt', '/Version (\d+)/', 5),
@@ -64,7 +65,7 @@ function libraries_test_libraries_info() {
   // Test a top-level files property.
   $libraries['example_files'] = array(
     'name' => 'Example files',
-    'library path' => drupal_get_path('module', 'libraries') . '/tests/example',
+    'path' => drupal_get_path('module', 'libraries') . '/tests/example',
     'version' => '1',
     'files' => array(
       'js' => array('example_1.js'),
@@ -78,7 +79,7 @@ function libraries_test_libraries_info() {
   // these files should be automatically loaded when the library is loaded.
   $libraries['example_integration_files'] = array(
     'name' => 'Example integration files',
-    'library path' => drupal_get_path('module', 'libraries') . '/tests/example',
+    'path' => drupal_get_path('module', 'libraries') . '/tests/example',
     'version' => '1',
     'integration files' => array(
       'libraries_test' => array(
@@ -92,7 +93,7 @@ function libraries_test_libraries_info() {
   // Test version overloading.
   $libraries['example_versions'] = array(
     'name' => 'Example versions',
-    'library path' => drupal_get_path('module', 'libraries') . '/tests/example',
+    'path' => drupal_get_path('module', 'libraries') . '/tests/example',
     'version' => '2',
     'versions' => array(
       '1' => array(
@@ -115,7 +116,7 @@ function libraries_test_libraries_info() {
   // Test variant detection.
   $libraries['example_variant_missing'] = array(
     'name' => 'Example variant missing',
-    'library path' => drupal_get_path('module', 'libraries') . '/tests/example',
+    'path' => drupal_get_path('module', 'libraries') . '/tests/example',
     'version' => '1',
     'variants' => array(
       'example_variant' => array(
@@ -132,7 +133,7 @@ function libraries_test_libraries_info() {
 
   $libraries['example_variant'] = array(
     'name' => 'Example variant',
-    'library path' => drupal_get_path('module', 'libraries') . '/tests/example',
+    'path' => drupal_get_path('module', 'libraries') . '/tests/example',
     'version' => '1',
     'variants' => array(
       'example_variant' => array(
@@ -150,7 +151,7 @@ function libraries_test_libraries_info() {
   // Test correct behaviour with multiple versions and multiple variants.
   $libraries['example_versions_and_variants'] = array(
     'name' => 'Example versions and variants',
-    'library path' => drupal_get_path('module', 'libraries') . '/tests/example',
+    'path' => drupal_get_path('module', 'libraries') . '/tests/example',
     'version' => '2',
     'versions' => array(
       '1' => array(
@@ -203,7 +204,7 @@ function libraries_test_libraries_info() {
   // Test the applying of callbacks.
   $libraries['example_callback'] = array(
     'name' => 'Example callback',
-    'library path' => drupal_get_path('module', 'libraries') . '/tests/example',
+    'path' => drupal_get_path('module', 'libraries') . '/tests/example',
     'version' => '1',
     'versions' => array(
       '1' => array(
@@ -299,8 +300,7 @@ function _libraries_test_return_version($library, $version) {
  * @see libraries_get_version()
  */
 function _libraries_test_get_version($library, $file, $pattern, $lines = 20, $cols = 200) {
-
-  $file = DRUPAL_ROOT . '/' . $library['library path'] . '/' . $file;
+  $file = DRUPAL_ROOT . '/' . $library['path'] . '/' . $file;
   if (!file_exists($file)) {
     return;
   }
