diff --git a/includes/common.inc b/includes/common.inc
index df885d362a697bd94aac60442982c13b9cd185bc..45bd28842df29736baa8dd58e12ba8f72e4ac71c 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -2423,13 +2423,16 @@ function drupal_add_link($attributes) {
  *   - 'inline': A string of CSS that should be placed in the given scope. Note
  *     that it is better practice to use 'file' stylesheets, rather than 'inline'
  *     as the CSS would then be aggregated and cached.
+ *   - 'external': The absolute path to an external CSS file that is not hosted
+ *     on the local server. These files will not be aggregated if CSS aggregation
+ *     is enabled.
  *
  * @param $options
  *   (optional) A string defining the 'type' of CSS that is being added in the
  *   $data parameter ('file'/'inline'), or an array which can have any or all of
  *   the following keys:
- *   - 'type': The type of stylesheet being added. Available options are 'file'
- *     or 'inline'. Defaults to 'file'.
+ *   - 'type': The type of stylesheet being added. Available options are 'file',
+ *     'inline' or 'external'. Defaults to 'file'.
  *   - 'weight': The weight of the stylesheet specifies the order in which the
  *     CSS will appear when presented on the page.
  *
@@ -2454,7 +2457,8 @@ function drupal_add_link($attributes) {
  *     files into one file that is then compressed by removing all extraneous
  *     white space. Note that preprocessed inline stylesheets will not be
  *     aggregated into this single file, instead it will just be compressed
- *     when being output on the page.
+ *     when being output on the page. External stylesheets will not be
+ *     aggregated.
  *
  *     The reason for merging the CSS files is outlined quite thoroughly here:
  *     http://www.die.net/musings/page_load_time/
@@ -2501,14 +2505,15 @@ function drupal_add_css($data = NULL, $options = NULL) {
 
     // Add the data to the CSS array depending on the type.
     switch ($options['type']) {
-      case 'file':
-        $css[$data] = $options;
-        break;
       case 'inline':
         // For inline stylesheets, we don't want to use the $data as the array
         // key as $data could be a very long string of CSS.
         $css[] = $options;
         break;
+      default:
+        // Local and external files must keep their name as the associative key
+        // so the same CSS file is not be added twice.
+        $css[$data] = $options;
     }
   }
 
@@ -2576,6 +2581,7 @@ function drupal_get_css($css = NULL) {
   // Additionally, go through any remaining styles if CSS preprocessing is on and output the non-cached ones.
   $rendered_css = array();
   $inline_css = '';
+  $external_css = '';
   $preprocess_items = array();
   foreach ($css as $data => $item) {
     // Loop through each of the stylesheets, including them appropriately based
@@ -2597,6 +2603,10 @@ function drupal_get_css($css = NULL) {
         // Include inline stylesheets.
         $inline_css .= drupal_load_stylesheet_content($item['data'], $item['preprocess']);
         break;
+      case 'external':
+        // Preprocessing for external CSS files is ignored.
+        $external_css .= '<link type="text/css" rel="stylesheet" media="' . $item['media'] . '" href="' . $item['data'] . '" />' . "\n";
+        break;
     }
   }
 
@@ -2615,7 +2625,7 @@ function drupal_get_css($css = NULL) {
   }
 
   // Output all the CSS files with the inline stylesheets showing up last.
-  return implode("\n", $rendered_css) . $inline_css;
+  return implode("\n", $rendered_css) . $external_css . $inline_css;
 }
 
 /**
@@ -2826,7 +2836,9 @@ function drupal_clear_css_cache() {
  *   (optional) If given, the value depends on the $options parameter:
  *   - 'file': Path to the file relative to base_path().
  *   - 'inline': The JavaScript code that should be placed in the given scope.
- *   - 'external': The absolute path to a JavaScript file hosted externally.
+ *   - 'external': The absolute path to an external JavaScript file that is not
+ *     hosted on the local server. These files will not be aggregated if 
+ *     JavaScript aggregation is enabled.
  *   - 'setting': An array with configuration options as associative array. The
  *       array is directly placed in Drupal.settings. All modules should wrap
  *       their actual configuration settings in another variable to prevent
@@ -2940,7 +2952,6 @@ function drupal_add_js($data = NULL, $options = NULL) {
         // Local and external files must keep their name as the associative key
         // so the same JavaScript file is not be added twice.
         $javascript[$options['data']] = $options;
-        break;
     }
   }
   return $javascript;
diff --git a/modules/simpletest/tests/common.test b/modules/simpletest/tests/common.test
index d0b16e9ab088c1b4a7b8fb1e50ee7af978176283..bbea196b21051155b814c858076175a6704ec8ec 100644
--- a/modules/simpletest/tests/common.test
+++ b/modules/simpletest/tests/common.test
@@ -224,6 +224,15 @@ class CascadingStylesheetsTestCase extends DrupalWebTestCase {
     $this->assertEqual($css[$path]['data'], $path, t('Adding a CSS file caches it properly.'));
   }
 
+  /**
+   * Tests adding an external stylesheet.
+   */
+  function testAddExternal() {
+    $path = 'http://example.com/style.css';
+    $css = drupal_add_css($path, 'external');
+    $this->assertEqual($css[$path]['type'], 'external', t('Adding an external CSS file caches it properly.'));
+  }
+
   /**
    * Makes sure that reseting the CSS empties the cache.
    */
@@ -238,7 +247,18 @@ class CascadingStylesheetsTestCase extends DrupalWebTestCase {
   function testRenderFile() {
     $css = drupal_get_path('module', 'simpletest') . '/simpletest.css';
     drupal_add_css($css);
-    $this->assertTrue(strpos(drupal_get_css(), $css) > 0, t('Rendered CSS includes the added stylesheet.'));
+    $styles = drupal_get_css();
+    $this->assertTrue(strpos($styles, $css) > 0, t('Rendered CSS includes the added stylesheet.'));
+  }
+
+  /**
+   * Tests rendering an external stylesheet.
+   */
+  function testRenderExternal() {
+    $css = 'http://example.com/style.css';
+    drupal_add_css($css, 'external');
+    $styles = drupal_get_css();
+    $this->assertTrue(strpos($styles, 'href="' . $css) > 0, t('Rendering an external CSS file.'));
   }
 
   /**
@@ -248,8 +268,8 @@ class CascadingStylesheetsTestCase extends DrupalWebTestCase {
     $css = 'body { padding: 0px; }';
     $css_preprocessed = '<style type="text/css">' . drupal_load_stylesheet_content($css, TRUE) . '</style>';
     drupal_add_css($css, 'inline');
-    $css = drupal_get_css();
-    $this->assertEqual($css, "\n" . $css_preprocessed, t('Rendering preprocessed inline CSS adds it to the page.'));
+    $styles = drupal_get_css();
+    $this->assertEqual($styles, "\n" . $css_preprocessed, t('Rendering preprocessed inline CSS adds it to the page.'));
   }
 
   /**
@@ -258,7 +278,8 @@ class CascadingStylesheetsTestCase extends DrupalWebTestCase {
   function testRenderInlineNoPreprocess() {
     $css = 'body { padding: 0px; }';
     drupal_add_css($css, array('type' => 'inline', 'preprocess' => FALSE));
-    $this->assertTrue(strpos(drupal_get_css(), $css) > 0, t('Rendering non-preprocessed inline CSS adds it to the page.'));
+    $styles = drupal_get_css();
+    $this->assertTrue(strpos($styles, $css) > 0, t('Rendering non-preprocessed inline CSS adds it to the page.'));
   }
 
   /**
@@ -300,8 +321,8 @@ class CascadingStylesheetsTestCase extends DrupalWebTestCase {
       drupal_get_path('module', 'simpletest') . '/simpletest.css',
     );
 
-    $css = drupal_get_css();
-    if (preg_match_all('/href="' . preg_quote(base_path(), '/') . '([^?]+)\?/', $css, $matches)) {
+    $styles = drupal_get_css();
+    if (preg_match_all('/href="' . preg_quote(base_path(), '/') . '([^?]+)\?/', $styles, $matches)) {
       $result = $matches[1];
     }
     else {
@@ -319,17 +340,17 @@ class CascadingStylesheetsTestCase extends DrupalWebTestCase {
     drupal_add_css(drupal_get_path('module', 'simpletest') . '/tests/system.css');
 
     // The dummy stylesheet should be the only one included.
-    $css = drupal_get_css();
-    $this->assert(strpos($css, drupal_get_path('module', 'simpletest') . '/tests/system.css') !== FALSE, t('The overriding CSS file is output.'));
-    $this->assert(strpos($css, drupal_get_path('module', 'system') . '/system.css') === FALSE, t('The overriden CSS file is not output.'));
+    $styles = drupal_get_css();
+    $this->assert(strpos($styles, drupal_get_path('module', 'simpletest') . '/tests/system.css') !== FALSE, t('The overriding CSS file is output.'));
+    $this->assert(strpos($styles, drupal_get_path('module', 'system') . '/system.css') === FALSE, t('The overriden CSS file is not output.'));
 
     drupal_add_css(drupal_get_path('module', 'simpletest') . '/tests/system.css');
     drupal_add_css(drupal_get_path('module', 'system') . '/system.css');
 
     // The standard stylesheet should be the only one included.
-    $css = drupal_get_css();
-    $this->assert(strpos($css, drupal_get_path('module', 'system') . '/system.css') !== FALSE, t('The overriding CSS file is output.'));
-    $this->assert(strpos($css, drupal_get_path('module', 'simpletest') . '/tests/system.css') === FALSE, t('The overriden CSS file is not output.'));
+    $styles = drupal_get_css();
+    $this->assert(strpos($styles, drupal_get_path('module', 'system') . '/system.css') !== FALSE, t('The overriding CSS file is output.'));
+    $this->assert(strpos($styles, drupal_get_path('module', 'simpletest') . '/tests/system.css') === FALSE, t('The overriden CSS file is not output.'));
   }
 
   /**
@@ -342,8 +363,8 @@ class CascadingStylesheetsTestCase extends DrupalWebTestCase {
     drupal_add_css(drupal_get_path('module', 'system') . '/system.css');
 
     // Check to see if system-rtl.css was also added.
-    $css = drupal_get_css();
-    $this->assert(strpos($css, drupal_get_path('module', 'system') . '/system-rtl.css') !== FALSE, t('CSS is alterable as right to left overrides are added.'));
+    $styles = drupal_get_css();
+    $this->assert(strpos($styles, drupal_get_path('module', 'system') . '/system-rtl.css') !== FALSE, t('CSS is alterable as right to left overrides are added.'));
 
     // Change the language back to left to right.
     $language->direction = LANGUAGE_LTR;
@@ -559,6 +580,15 @@ class JavaScriptTestCase extends DrupalWebTestCase {
     $this->assertEqual('rocks', $javascript['settings']['data'][1]['drupal'], t('The other JavaScript setting is set correctly.'));
   }
 
+  /**
+   * Tests adding an external JavaScript File.
+   */
+  function testAddExternal() {
+    $path = 'http://example.com/script.js';
+    $javascript = drupal_add_js($path, 'external');
+    $this->assertTrue(array_key_exists('http://example.com/script.js', $javascript), t('Added an external JavaScript file.'));
+  }
+
   /**
    * Test drupal_get_js() for JavaScript settings.
    */