diff --git a/drupal/sites/all/modules/patched/cdn/cdn.test b/drupal/sites/all/modules/patched/cdn/cdn.test
deleted file mode 100644
index 011f68e..0000000
--- a/drupal/sites/all/modules/patched/cdn/cdn.test
+++ /dev/null
@@ -1,604 +0,0 @@
-<?php
-
-/**
- * @file
- * Test CDN.
- */
-
-class CDNTestCase extends DrupalUnitTestCase {
-  function setUp() {
-    parent::setUp();
-
-    // Alter $_SERVER to include some relatively rarely set HTTP headers.
-    $alt_server = array(
-      'HTTP_ACCEPT_ENCODING',
-      'HTTPS' => 'off',
-      'HTTP_X_FORWARDED_PROTO' => 'http',
-    );
-    $alt_server = array_merge($alt_server, $_SERVER);
-    $_SERVER = $alt_server;
-    $this->setRequestProtocol('http');
-
-    // Pretend the CDN module is enabled; this ensures invocations of its own
-    // hook implementations will work as expected.
-    $cdn_module_file = drupal_get_path('module', 'cdn') . '/cdn.module';
-    $module_list = module_list();
-    $module_list['cdn']['filename'] = $cdn_module_file;
-    module_list(TRUE, FALSE, FALSE, $module_list);
-    $implementations = &drupal_static('module_implements');
-    $implementations = array();
-
-    $this->loadFile('cdn.constants.inc');
-    $this->loadFile('cdn.module');
-
-    // Override $conf to be able to use variable_set() and variable_get() in
-    // DrupalUnitTestCase. At the same time, make sure we can restore the
-    // original values.
-    global $conf;
-    $this->originalConfig = $conf;
-    $this->variableSetDefaults();
-  }
-
-  function tearDown() {
-    // Restore the original values that are used by variable_get().
-    global $conf;
-    $conf = $this->originalConfig;
-
-    parent::tearDown();
-  }
-
-  function loadFile($file) {
-    $cdn_path = DRUPAL_ROOT . '/' . drupal_get_path('module', 'cdn');
-    require_once "$cdn_path/$file";
-  }
-
-  /**
-   * Mock function for variable_set().
-   */
-  function variableSet($name, $value) {
-    global $conf;
-    $conf[$name] = $value;
-  }
-
-  /**
-   * Set the default variable values for the CDN module.
-   */
-  function variableSetDefaults() {
-    global $conf;
-    $this->defaultConfig = array(
-      CDN_STATUS_VARIABLE => CDN_ENABLED,
-      CDN_MODE_VARIABLE => FALSE,
-      CDN_HTTPS_SUPPORT_VARIABLE => FALSE,
-      CDN_BASIC_MAPPING_VARIABLE => '',
-      CDN_BASIC_MAPPING_HTTPS_VARIABLE => '',
-      CDN_BASIC_FARFUTURE_VARIABLE => FALSE,
-    );
-    $conf = array_merge($conf, $this->defaultConfig);
-  }
-
-  /**
-   * Set the protocol of the current "request".
-   *
-   * @param $protocol
-   *   'http' or 'https'.
-   */
-  function setRequestProtocol($protocol) {
-    if ($protocol == 'http') {
-      $_SERVER['HTTPS'] = 'off';
-      $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'http';
-    }
-    elseif ($protocol == 'https') {
-      $_SERVER['HTTPS'] = 'on';
-      $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https';
-    }
-  }
-
-  /**
-   * Configure HTTPS-related settings.
-   *
-   * @param $supported
-   *   Boolean that indicates whether HTTPS is supported by the current CDN
-   *   or not.
-   * @param $mapping
-   *   The CDN mapping to use when the CDN supports HTTPS and the current
-   *   request is happening over HTTPS.
-   */
-  function configureHTTPS($supported, $mapping = '') {
-    $this->variableSet(CDN_HTTPS_SUPPORT_VARIABLE, $supported);
-    $this->variableSet(CDN_BASIC_MAPPING_HTTPS_VARIABLE, $mapping);
-  }
-
-  /**
-   * Given a file URI, get the expanded file path.
-   *
-   * @param $uri
-   *   @see file_stream_wrapper_get_instance_by_uri()
-   * @return
-   *  A Drupal root-relative path.
-   */
-  function getExpandedFilePath($uri) {
-    $wrapper = file_stream_wrapper_get_instance_by_uri($uri);
-    return str_replace($GLOBALS['base_url'] . '/', '', $wrapper->getExternalUrl());
-  }
-
-  /**
-   * Given a file URI, get its path, create the file and ensure it exists.
-   *
-   * @param $uri
-   *   @see getExpandedFilePath()
-   */
-  function touchFile($uri) {
-    $path = $this->getExpandedFilePath($uri);
-    $this->assertTrue(touch(rawurldecode($path)), 'Test file created.');
-    return $path;
-  }
-}
-
-class CDNGeneralTestCase extends CDNTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'General',
-      'description' => 'Verify general functionality.',
-      'group' => 'CDN',
-    );
-  }
-
-  function testHTTPSDetection() {
-    // HTTPS + HTTP_X_FORWARDED_PROTO permutations.
-    $_SERVER['HTTPS'] = 'off';
-    $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'http';
-    $this->assertEqual(FALSE, cdn_request_is_https(), 'HTTP request detected.');
-
-    $_SERVER['HTTPS'] = 'off';
-    $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https';
-    $this->assertEqual(TRUE, cdn_request_is_https(), 'HTTPS request detected.');
-
-    $_SERVER['HTTPS'] = 'on';
-    $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https';
-    $this->assertEqual(TRUE, cdn_request_is_https(), 'HTTPS request detected.');
-
-    $_SERVER['HTTPS'] = 'on';
-    $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'http';
-    $this->assertEqual(TRUE, cdn_request_is_https(), 'HTTPS request detected.');
-
-    // HTTPS + HTTP_X_FORWARDED_PROTOCOL permutations.
-    unset($_SERVER['HTTP_X_FORWARDED_PROTO']);
-    $_SERVER['HTTPS'] = 'off';
-    $_SERVER['HTTP_X_FORWARDED_PROTOCOL'] = 'http';
-    $this->assertEqual(FALSE, cdn_request_is_https(), 'HTTP request detected.');
-
-    $_SERVER['HTTPS'] = 'off';
-    $_SERVER['HTTP_X_FORWARDED_PROTOCOL'] = 'https';
-    $this->assertEqual(TRUE, cdn_request_is_https(), 'HTTPS request detected.');
-
-    $_SERVER['HTTPS'] = 'on';
-    $_SERVER['HTTP_X_FORWARDED_PROTOCOL'] = 'https';
-    $this->assertEqual(TRUE, cdn_request_is_https(), 'HTTPS request detected.');
-
-    $_SERVER['HTTPS'] = 'on';
-    $_SERVER['HTTP_X_FORWARDED_PROTOCOL'] = 'http';
-    $this->assertEqual(TRUE, cdn_request_is_https(), 'HTTPS request detected.');
-  }
-}
-
-class CDNOriginPullTestCase extends CDNTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Origin Pull mode',
-      'description' => 'Verify Origin Pull mode-related functionality.',
-      'group' => 'CDN',
-    );
-  }
-
-  function setUp() {
-    parent::setUp();
-    $this->loadFile('cdn.basic.inc');
-    $this->loadFile('cdn.basic.farfuture.inc');
-    $this->variableSet(CDN_MODE_VARIABLE, CDN_MODE_BASIC);
-  }
-
-  /**
-   * Assert a CDN mapping (and optionally set a mapping).
-   *
-   * @param $mapping
-   *   The mapping to set; if FALSE, no new mapping will be set.
-   * @param $parsed_reference
-   *   The reference the parsed mapping will be compared to.
-   * @param $domains_reference
-   *   The reference the domains (as returned by cdn_get_domains()) will be
-   *   compared to.
-   */
-  function assertMapping($mapping, $parsed_reference, $domains_reference) {
-    if ($mapping !== FALSE) {
-      $this->variableSet(CDN_BASIC_MAPPING_VARIABLE, $mapping);
-    }
-    $this->assertEqual($parsed_reference, _cdn_basic_parse_raw_mapping(cdn_basic_get_mapping()), 'CDN mapping parsed correctly.');
-    $domains = cdn_get_domains();
-    sort($domains);
-    $this->assertEqual($domains_reference, $domains, 'CDN domains parsed correctly.');
-  }
-
-  function testMapping() {
-    $this->setRequestProtocol('http');
-
-    $this->assertEqual('', cdn_basic_get_mapping(), 'The default CDN mapping is empty.');
-
-    // Ensure the parsing of the raw mapping works correctly.
-    $this->assertMapping('', array(), array());
-    $this->assertMapping('http://cdn-a.com',  array('*' => array('http://cdn-a.com')), array('cdn-a.com'));
-    $this->assertMapping('http://cdn-a.com/', array('*' => array('http://cdn-a.com')), array('cdn-a.com'));
-    $this->assertMapping('//cdn-a.com',       array('*' => array('//cdn-a.com')), array('cdn-a.com'));
-    $this->assertMapping('//cdn-a.com/',      array('*' => array('//cdn-a.com')), array('cdn-a.com'));
-    $parsed_mapping = array(
-      'css'  => array('http://cdn-a.com'),
-      'jpg'  => array('http://cdn-a.com'),
-      'jpeg' => array('http://cdn-a.com'),
-      'png'  => array('http://cdn-a.com'),
-      'zip'  => array('http://cdn-b.com'),
-      '*'    => array('http://cdn-c.com'),
-    );
-    $domains = array('cdn-a.com', 'cdn-b.com', 'cdn-c.com');
-    $this->assertMapping(
-      "http://cdn-a.com|.css .jpg .jpeg .png\nhttp://cdn-b.com|.zip\nhttp://cdn-c.com",
-      $parsed_mapping,
-      $domains
-    );
-    $parsed_mapping = array(
-      'css'  => array('http://cdn-a.com', 'http://cdn-d.com'),
-      'jpg'  => array('http://cdn-a.com', 'http://cdn-d.com'),
-      'jpeg' => array('http://cdn-a.com', 'http://cdn-d.com'),
-      'png'  => array('http://cdn-a.com', 'http://cdn-d.com', 'http://cdn-b.com'),
-      '*'    => array('http://cdn-c.com'),
-    );
-    $domains = array('cdn-a.com', 'cdn-b.com', 'cdn-c.com', 'cdn-d.com');
-    $this->assertMapping(
-      "http://cdn-a.com http://cdn-d.com|.css .jpg .jpeg .png\nhttp://cdn-b.com|.png\nhttp://cdn-c.com",
-      $parsed_mapping,
-      $domains
-    );
-
-    // When a HTTPS request is performed and the CDN is not marked to support
-    // HTTPS, then it should fall back to the default CDN mapping.
-    $this->setRequestProtocol('https');
-    $this->assertMapping(FALSE, $parsed_mapping, $domains);
-
-    // When a HTTPS request is performed and the CDN *is* marked to support
-    // HTTPS, then it should still fall back to the default CDN mapping. (When
-    // file URLs are actually altered, it will then replace `http://` with
-    // `https://` -- this will be tested in a different test.)
-    $this->configureHTTPS(TRUE);
-    $this->assertMapping(FALSE, $parsed_mapping, $domains);
-
-    // When a HTTPS request is performed *and* the CDN is marked to support
-    // HTTPS *and* there's a HTTPS-specific CDN mapping, that mapping should
-    // be used instead!
-    $this->configureHTTPS(TRUE, "https://cdn-a.com|.css .jpg .jpeg .png\nhttps://cdn-b.com|.zip\nhttps://cdn-c.com");
-    $this->assertMapping(
-      FALSE,
-      array(
-        'css'  => array('https://cdn-a.com'),
-        'jpg'  => array('https://cdn-a.com'),
-        'jpeg' => array('https://cdn-a.com'),
-        'png'  => array('https://cdn-a.com'),
-        'zip'  => array('https://cdn-b.com'),
-        '*'    => array('https://cdn-c.com'),
-      ),
-      array('cdn-a.com', 'cdn-b.com', 'cdn-c.com')
-    );
-
-    // Ensure the default CDN mapping is used whenever a HTTP request occurs
-    // and the CDN is marked to suppport HTTPS and there's a HTTPS-specific
-    // CDN mapping.
-    $this->configureHTTPS(FALSE);
-    $this->assertMapping(FALSE, $parsed_mapping, $domains);
-  }
-
-  function testFileUrlAlterHook() {
-    // Provide a very basic CDN mapping.
-    $this->variableSet(CDN_BASIC_MAPPING_VARIABLE, 'http://cdn-a.com');
-
-    $filename = 'újjáépítésérol — 100% in B&W.jpg';
-    $uri = "public://$filename";
-    $this->touchFile($uri);
-
-    cdn_file_url_alter($uri);
-    $expected = 'http://cdn-a.com' . base_path() . variable_get('file_public_path', conf_path() . '/files') . '/' . drupal_encode_path($filename);
-    $this->assertIdentical($uri, $expected, 'cdn_file_url_alter() works correctly.');
-  }
-}
-
-class CDNOriginPullFarFutureTestCase extends CDNTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Origin Pull mode — Far Future expiration',
-      'description' => 'Verify Origin Pull mode\'s Far Future expiration functionality.',
-      'group' => 'CDN',
-    );
-  }
-
-  function setUp() {
-    parent::setUp();
-    $this->loadFile('cdn.basic.inc');
-    $this->loadFile('cdn.basic.farfuture.inc');
-    $this->variableSet(CDN_MODE_VARIABLE, CDN_MODE_BASIC);
-    $this->variableSet(CDN_BASIC_FARFUTURE_VARIABLE, TRUE);
-  }
-
-  /**
-   * Assert a UFI mapping (and optionally set a mapping).
-   *
-   * @param $mapping
-   *   The mapping to set; if FALSE, no new mapping will be set.
-   * @param $parsed_reference
-   *   The reference the parsed mapping will be compared to.
-   * @param $message
-   */
-  function assertUFIMapping($mapping, $parsed_reference, $message = NULL) {
-    if (is_null($message)) {
-      $message = 'UFI mapping parsed correctly.';
-    }
-
-    if ($mapping !== FALSE) {
-      $this->variableSet(CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_VARIABLE, $mapping);
-    }
-    $parsed = _cdn_basic_farfuture_parse_raw_mapping(variable_get(CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_VARIABLE, CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_DEFAULT));
-    $this->assertEqual($parsed_reference, $parsed, $message);
-  }
-
-  /**
-   * Assert a UFI method. Must be run after a UFI mapping is asserted (and
-   * set) by assertUFIMapping().
-   *
-   * @param $path
-   *   The path to get a UFI for.
-   * @param $ufi_method_reference
-   *   The reference the resulting UFI method will be compared to.
-   */
-  function assertUFIMethod($path, $ufi_method_reference) {
-    $ufi_mapping = _cdn_basic_farfuture_parse_raw_mapping(variable_get(CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_VARIABLE, CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_DEFAULT));
-    $this->assertEqual(
-      $ufi_method_reference,
-      cdn_basic_farfuture_get_ufi_method($path, $ufi_mapping),
-      'Correct UFI method applied.'
-    );
-  }
-
-  function testUFIMapping() {
-    $default = CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_DEFAULT;
-    $parsed_mapping = _cdn_basic_farfuture_parse_raw_mapping($default);
-    $this->assertUFIMapping(
-      FALSE,
-      $parsed_mapping,
-      'The default UFI mapping is set to sensible defaults.'
-    );
-
-    // Growing complexity for a single-directory UFI.
-    $this->assertUFIMapping(
-      "sites/*|mtime",
-      array(
-        'sites/*' => array(
-          '*' => array(
-            'ufi method' => 'mtime',
-            'specificity' => 20, // two directories (2*10), no extension (0)
-          ),
-        ),
-      ),
-      'Simple single-directory UFI mapping (step 1).'
-    );
-    $this->assertUFIMethod('sites/foo', 'mtime');
-    $this->assertUFIMapping(
-      "sites/*|mtime\nsites/*|.woff .ttf|md5_hash",
-      array(
-        'sites/*' => array(
-          '*' => array(
-            'ufi method' => 'mtime',
-            'specificity' => 20, // two directories (2*10), no extension (0)
-          ),
-          'woff' => array(
-            'ufi method' => 'md5_hash',
-            'specificity' => 21, // two directories (2*10), one extension (1)
-          ),
-          'ttf' => array(
-            'ufi method' => 'md5_hash',
-            'specificity' => 21, // two directories (2*10), one extension (1)
-          ),
-        ),
-      ),
-      'Simple single-directory UFI mapping (step 2).'
-    );
-    $this->assertUFIMethod('sites/foo', 'mtime');
-    $this->assertUFIMethod('sites/foobambamb.woff', 'md5_hash');
-    $this->assertUFIMethod('sites/foo/bar/baz.ttf', 'md5_hash');
-    $this->assertUFIMapping(
-      "sites/*|mtime\nsites/*|.woff .ttf|md5_hash\nsites/*|.mov .mp4|perpetual",
-      array(
-        'sites/*' => array(
-          '*' => array(
-            'ufi method' => 'mtime',
-            'specificity' => 20, // two directories (2*10), no extension (0)
-          ),
-          'woff' => array(
-            'ufi method' => 'md5_hash',
-            'specificity' => 21, // two directories (2*10), one extension (1)
-          ),
-          'ttf' => array(
-            'ufi method' => 'md5_hash',
-            'specificity' => 21, // two directories (2*10), one extension (1)
-          ),
-          'mov' => array(
-            'ufi method' => 'perpetual',
-            'specificity' => 21, // two directories (2*10), one extension (1)
-          ),
-          'mp4' => array(
-            'ufi method' => 'perpetual',
-            'specificity' => 21, // two directories (2*10), one extension (1)
-          ),
-        ),
-      ),
-      'Simple single-directory UFI mapping (step 2).'
-    );
-    $this->assertUFIMethod('sites/foo', 'mtime');
-    $this->assertUFIMethod('sites/foobambamb.woff', 'md5_hash');
-    $this->assertUFIMethod('sites/foo/bar/baz.ttf', 'md5_hash');
-    $this->assertUFIMethod('sites/movies/foo.mov', 'perpetual');
-    $this->assertUFIMethod('sites/movies/bar.mp4', 'perpetual');
-  }
-
-  function testFileUrlAlterHook() {
-    // We don't want to test the UFI functionality here.
-    $this->variableSet(CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_VARIABLE, '*|perpetual');
-    // Provide a very basic CDN mapping.
-    $this->variableSet(CDN_BASIC_MAPPING_VARIABLE, 'http://cdn-a.com');
-
-    $filename = 'újjáépítésérol — 100% in B&W.jpg';
-    $uri = "public://$filename";
-    $this->touchFile($uri);
-
-    cdn_file_url_alter($uri);
-
-    $path_info = pathinfo($filename);
-    $expected = implode('/', array(
-      'http://cdn-a.com' . base_path() . 'cdn/farfuture',
-      drupal_hmac_base64('perpetual:forever' . $path_info['filename'], drupal_get_private_key() . drupal_get_hash_salt()),
-      'perpetual:forever',
-      variable_get('file_public_path', conf_path() . '/files'),
-      drupal_encode_path($filename)
-    ));
-    $this->assertIdentical($uri, $expected, 'cdn_file_url_alter() works correctly.');
-  }
-}
-
-class CDNImageTestCase extends CDNTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Image HTML altering',
-      'description' => 'Verify that image URLs inside HTML are rewritten correctly.',
-      'group' => 'CDN',
-    );
-  }
-
-  function setUp() {
-    parent::setUp();
-    $this->loadFile('cdn.fallback.inc');
-  }
-
-  function testImage() {
-    $cdn = 'http://cdn-a.com';
-    $this->variableSet(CDN_BASIC_MAPPING_VARIABLE, $cdn);
-    $this->variableSet(CDN_MODE_VARIABLE, CDN_MODE_BASIC);
-
-    // Image altering type 1: "just image", i.e. "<img />".
-    $template = function($url) {
-      return '<img alt="Foo!" src="' . $url . '" title="Bar!"/>';
-    };
-    // Simplest case possible.
-    $img_url = base_path() . 'foo/bar/image.png';
-    $html = $template($img_url);
-    cdn_html_alter_image_urls($html);
-    $this->assertIdentical($template($cdn . $img_url), $html, 'Image HTML correctly altered.');
-    // Query strings should not be stripped
-    $img_url = base_path() . 'foo/bar/image.png?foobar';
-    $html = $template($img_url);
-    cdn_html_alter_image_urls($html);
-    $this->assertIdentical($template($cdn . $img_url), $html, 'Image HTML correctly altered (query string not stripped).');
-    // In particular: not the query string used to generate image styles.
-    $img_url = base_path() . 'foo/bar/image.png?itok=1234abcd';
-    $html = $template($img_url);
-    cdn_html_alter_image_urls($html);
-    $this->assertIdentical($template($cdn . $img_url), $html, 'Image HTML correctly altered (image style query string not stripped).');
-    // Edge case: a script generating an image is not (yet) supported.
-    $img_url = base_path() . 'foo/bar/showimage?formula=12345.png';
-    $html = $template($img_url);
-    cdn_html_alter_image_urls($html);
-    $this->assertIdentical($template($cdn . $img_url), $html, 'Image HTML correctly altered (query string not stripped).');
-
-    // Image altering type 2: "linked image", i.e. "<a><img /></a>"..
-    $template = function($a_url, $img_url) {
-      return '<a rel="gallery" href="' . $a_url . '" class="gallery-image"><img alt="Foo!" src="' . $img_url . '" title="Bar!" /></a>';
-    };
-    // Simplest case possible: a linked image linking to the same image.
-    $img_base_url = base_path() . 'foo/bar/image';
-    $a_url = $img_url = $img_base_url . '.png';
-    $html = $template($a_url, $img_url);
-    cdn_html_alter_image_urls($html);
-    $this->assertIdentical($template($cdn . $a_url, $cdn . $img_url), $html, 'Linked image HTML correctly altered.');
-    // Slightly more complex: a linked image linking to a derivative image.
-    $img_url = $img_base_url . '-thumbnail.png?itok=5678wxyz';
-    $html = $template($a_url, $img_url);
-    cdn_html_alter_image_urls($html);
-    $this->assertIdentical($template($cdn . $a_url, $cdn . $img_url), $html, 'Linked image HTML correctly altered.');
-    // Slightly more complex: a linked derivative image linking to another
-    // derivative image.
-    $a_url = $img_base_url . '-large.png?itok=9012klmn';
-    $img_url = $img_base_url . '-thumbnail.png?itok=5678wxyz';
-    $html = $template($a_url, $img_url);
-    cdn_html_alter_image_urls($html);
-    $this->assertIdentical($template($cdn . $a_url, $cdn . $img_url), $html, 'Linked image HTML correctly altered.');
-    // Ensure that images linking to content (i.e. not a bigger version of the
-    // image) don't get their anchors modified
-    $a_url = base_path() . 'node';
-    $html = $template($a_url, $img_url);
-    cdn_html_alter_image_urls($html);
-    $this->assertIdentical($template($a_url, $cdn . $img_url), $html, 'Linked image HTML correctly altered (anchor unmodified).');
-    // Same, but now for a link with a query string.
-    $a_url = base_path() . 'node?foobar';
-    $html = $template($a_url, $img_url);
-    cdn_html_alter_image_urls($html);
-    $this->assertIdentical($template($a_url, $cdn . $img_url), $html, 'Linked image HTML correctly altered (anchor unmodified, even with query strings).');
-  }
-}
-
-class CDNCssUrlTestCase extends DrupalWebTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'CSS URLs',
-      'description' => 'Verify URLs in CSS files are rewritten properly.',
-      'group' => 'CDN',
-    );
-  }
-
-  function setUp() {
-    parent::setUp();
-
-    // Pretend the CDN module is enabled; this ensures invocations of its own
-    // hook implementations will work as expected.
-    $cdn_module_file = drupal_get_path('module', 'cdn') . '/cdn.module';
-    $module_list = module_list();
-    $module_list['cdn']['filename'] = $cdn_module_file;
-    module_list(TRUE, FALSE, FALSE, $module_list);
-    $implementations = &drupal_static('module_implements');
-    $implementations = array();
-
-    $this->loadFile('cdn.constants.inc');
-    $this->loadFile('cdn.module');
-    $this->loadFile('cdn.basic.inc');
-    $this->loadFile('cdn.basic.css.inc');
-    $this->loadFile('cdn.basic.farfuture.inc');
-    variable_set(CDN_MODE_VARIABLE, CDN_MODE_BASIC);
-    variable_set(CDN_BASIC_FARFUTURE_VARIABLE, TRUE);
-  }
-
-  function loadFile($file) {
-    $cdn_path = DRUPAL_ROOT . '/' . drupal_get_path('module', 'cdn');
-    require_once "$cdn_path/$file";
-  }
-
-  // Makes sure the URL components are preserved.
-  function testCssUrl() {
-    global $base_url;
-    $css_info = array(
-      array(
-        'type' => 'file',
-        'data' => drupal_get_path('module', 'cdn') . '/tests/css/orig/url.css',
-      ),
-    );
-    try {
-      // Make sure the URL in the supplied CSS file matches what we expect.
-      // trim() is needed to avoid issues with differences in newlines.
-      $this->assertEqual(trim(file_get_contents(_cdn_build_css_cache($css_info))), '.home{background:url('. $base_url . '/' . drupal_get_path('module', 'cdn') . '/tests/css/orig/geo-md-webfont.eot?#iefix);}');
-    } catch (Exception $exc) {
-      $this->fail($exc);
-    }
-  }
-
-}
diff --git a/drupal/sites/all/modules/patched/cdn/tests/cdn.test b/drupal/sites/all/modules/patched/cdn/tests/cdn.test
new file mode 100644
index 0000000..011f68e
--- /dev/null
+++ b/drupal/sites/all/modules/patched/cdn/tests/cdn.test
@@ -0,0 +1,604 @@
+<?php
+
+/**
+ * @file
+ * Test CDN.
+ */
+
+class CDNTestCase extends DrupalUnitTestCase {
+  function setUp() {
+    parent::setUp();
+
+    // Alter $_SERVER to include some relatively rarely set HTTP headers.
+    $alt_server = array(
+      'HTTP_ACCEPT_ENCODING',
+      'HTTPS' => 'off',
+      'HTTP_X_FORWARDED_PROTO' => 'http',
+    );
+    $alt_server = array_merge($alt_server, $_SERVER);
+    $_SERVER = $alt_server;
+    $this->setRequestProtocol('http');
+
+    // Pretend the CDN module is enabled; this ensures invocations of its own
+    // hook implementations will work as expected.
+    $cdn_module_file = drupal_get_path('module', 'cdn') . '/cdn.module';
+    $module_list = module_list();
+    $module_list['cdn']['filename'] = $cdn_module_file;
+    module_list(TRUE, FALSE, FALSE, $module_list);
+    $implementations = &drupal_static('module_implements');
+    $implementations = array();
+
+    $this->loadFile('cdn.constants.inc');
+    $this->loadFile('cdn.module');
+
+    // Override $conf to be able to use variable_set() and variable_get() in
+    // DrupalUnitTestCase. At the same time, make sure we can restore the
+    // original values.
+    global $conf;
+    $this->originalConfig = $conf;
+    $this->variableSetDefaults();
+  }
+
+  function tearDown() {
+    // Restore the original values that are used by variable_get().
+    global $conf;
+    $conf = $this->originalConfig;
+
+    parent::tearDown();
+  }
+
+  function loadFile($file) {
+    $cdn_path = DRUPAL_ROOT . '/' . drupal_get_path('module', 'cdn');
+    require_once "$cdn_path/$file";
+  }
+
+  /**
+   * Mock function for variable_set().
+   */
+  function variableSet($name, $value) {
+    global $conf;
+    $conf[$name] = $value;
+  }
+
+  /**
+   * Set the default variable values for the CDN module.
+   */
+  function variableSetDefaults() {
+    global $conf;
+    $this->defaultConfig = array(
+      CDN_STATUS_VARIABLE => CDN_ENABLED,
+      CDN_MODE_VARIABLE => FALSE,
+      CDN_HTTPS_SUPPORT_VARIABLE => FALSE,
+      CDN_BASIC_MAPPING_VARIABLE => '',
+      CDN_BASIC_MAPPING_HTTPS_VARIABLE => '',
+      CDN_BASIC_FARFUTURE_VARIABLE => FALSE,
+    );
+    $conf = array_merge($conf, $this->defaultConfig);
+  }
+
+  /**
+   * Set the protocol of the current "request".
+   *
+   * @param $protocol
+   *   'http' or 'https'.
+   */
+  function setRequestProtocol($protocol) {
+    if ($protocol == 'http') {
+      $_SERVER['HTTPS'] = 'off';
+      $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'http';
+    }
+    elseif ($protocol == 'https') {
+      $_SERVER['HTTPS'] = 'on';
+      $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https';
+    }
+  }
+
+  /**
+   * Configure HTTPS-related settings.
+   *
+   * @param $supported
+   *   Boolean that indicates whether HTTPS is supported by the current CDN
+   *   or not.
+   * @param $mapping
+   *   The CDN mapping to use when the CDN supports HTTPS and the current
+   *   request is happening over HTTPS.
+   */
+  function configureHTTPS($supported, $mapping = '') {
+    $this->variableSet(CDN_HTTPS_SUPPORT_VARIABLE, $supported);
+    $this->variableSet(CDN_BASIC_MAPPING_HTTPS_VARIABLE, $mapping);
+  }
+
+  /**
+   * Given a file URI, get the expanded file path.
+   *
+   * @param $uri
+   *   @see file_stream_wrapper_get_instance_by_uri()
+   * @return
+   *  A Drupal root-relative path.
+   */
+  function getExpandedFilePath($uri) {
+    $wrapper = file_stream_wrapper_get_instance_by_uri($uri);
+    return str_replace($GLOBALS['base_url'] . '/', '', $wrapper->getExternalUrl());
+  }
+
+  /**
+   * Given a file URI, get its path, create the file and ensure it exists.
+   *
+   * @param $uri
+   *   @see getExpandedFilePath()
+   */
+  function touchFile($uri) {
+    $path = $this->getExpandedFilePath($uri);
+    $this->assertTrue(touch(rawurldecode($path)), 'Test file created.');
+    return $path;
+  }
+}
+
+class CDNGeneralTestCase extends CDNTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'General',
+      'description' => 'Verify general functionality.',
+      'group' => 'CDN',
+    );
+  }
+
+  function testHTTPSDetection() {
+    // HTTPS + HTTP_X_FORWARDED_PROTO permutations.
+    $_SERVER['HTTPS'] = 'off';
+    $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'http';
+    $this->assertEqual(FALSE, cdn_request_is_https(), 'HTTP request detected.');
+
+    $_SERVER['HTTPS'] = 'off';
+    $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https';
+    $this->assertEqual(TRUE, cdn_request_is_https(), 'HTTPS request detected.');
+
+    $_SERVER['HTTPS'] = 'on';
+    $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https';
+    $this->assertEqual(TRUE, cdn_request_is_https(), 'HTTPS request detected.');
+
+    $_SERVER['HTTPS'] = 'on';
+    $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'http';
+    $this->assertEqual(TRUE, cdn_request_is_https(), 'HTTPS request detected.');
+
+    // HTTPS + HTTP_X_FORWARDED_PROTOCOL permutations.
+    unset($_SERVER['HTTP_X_FORWARDED_PROTO']);
+    $_SERVER['HTTPS'] = 'off';
+    $_SERVER['HTTP_X_FORWARDED_PROTOCOL'] = 'http';
+    $this->assertEqual(FALSE, cdn_request_is_https(), 'HTTP request detected.');
+
+    $_SERVER['HTTPS'] = 'off';
+    $_SERVER['HTTP_X_FORWARDED_PROTOCOL'] = 'https';
+    $this->assertEqual(TRUE, cdn_request_is_https(), 'HTTPS request detected.');
+
+    $_SERVER['HTTPS'] = 'on';
+    $_SERVER['HTTP_X_FORWARDED_PROTOCOL'] = 'https';
+    $this->assertEqual(TRUE, cdn_request_is_https(), 'HTTPS request detected.');
+
+    $_SERVER['HTTPS'] = 'on';
+    $_SERVER['HTTP_X_FORWARDED_PROTOCOL'] = 'http';
+    $this->assertEqual(TRUE, cdn_request_is_https(), 'HTTPS request detected.');
+  }
+}
+
+class CDNOriginPullTestCase extends CDNTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Origin Pull mode',
+      'description' => 'Verify Origin Pull mode-related functionality.',
+      'group' => 'CDN',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+    $this->loadFile('cdn.basic.inc');
+    $this->loadFile('cdn.basic.farfuture.inc');
+    $this->variableSet(CDN_MODE_VARIABLE, CDN_MODE_BASIC);
+  }
+
+  /**
+   * Assert a CDN mapping (and optionally set a mapping).
+   *
+   * @param $mapping
+   *   The mapping to set; if FALSE, no new mapping will be set.
+   * @param $parsed_reference
+   *   The reference the parsed mapping will be compared to.
+   * @param $domains_reference
+   *   The reference the domains (as returned by cdn_get_domains()) will be
+   *   compared to.
+   */
+  function assertMapping($mapping, $parsed_reference, $domains_reference) {
+    if ($mapping !== FALSE) {
+      $this->variableSet(CDN_BASIC_MAPPING_VARIABLE, $mapping);
+    }
+    $this->assertEqual($parsed_reference, _cdn_basic_parse_raw_mapping(cdn_basic_get_mapping()), 'CDN mapping parsed correctly.');
+    $domains = cdn_get_domains();
+    sort($domains);
+    $this->assertEqual($domains_reference, $domains, 'CDN domains parsed correctly.');
+  }
+
+  function testMapping() {
+    $this->setRequestProtocol('http');
+
+    $this->assertEqual('', cdn_basic_get_mapping(), 'The default CDN mapping is empty.');
+
+    // Ensure the parsing of the raw mapping works correctly.
+    $this->assertMapping('', array(), array());
+    $this->assertMapping('http://cdn-a.com',  array('*' => array('http://cdn-a.com')), array('cdn-a.com'));
+    $this->assertMapping('http://cdn-a.com/', array('*' => array('http://cdn-a.com')), array('cdn-a.com'));
+    $this->assertMapping('//cdn-a.com',       array('*' => array('//cdn-a.com')), array('cdn-a.com'));
+    $this->assertMapping('//cdn-a.com/',      array('*' => array('//cdn-a.com')), array('cdn-a.com'));
+    $parsed_mapping = array(
+      'css'  => array('http://cdn-a.com'),
+      'jpg'  => array('http://cdn-a.com'),
+      'jpeg' => array('http://cdn-a.com'),
+      'png'  => array('http://cdn-a.com'),
+      'zip'  => array('http://cdn-b.com'),
+      '*'    => array('http://cdn-c.com'),
+    );
+    $domains = array('cdn-a.com', 'cdn-b.com', 'cdn-c.com');
+    $this->assertMapping(
+      "http://cdn-a.com|.css .jpg .jpeg .png\nhttp://cdn-b.com|.zip\nhttp://cdn-c.com",
+      $parsed_mapping,
+      $domains
+    );
+    $parsed_mapping = array(
+      'css'  => array('http://cdn-a.com', 'http://cdn-d.com'),
+      'jpg'  => array('http://cdn-a.com', 'http://cdn-d.com'),
+      'jpeg' => array('http://cdn-a.com', 'http://cdn-d.com'),
+      'png'  => array('http://cdn-a.com', 'http://cdn-d.com', 'http://cdn-b.com'),
+      '*'    => array('http://cdn-c.com'),
+    );
+    $domains = array('cdn-a.com', 'cdn-b.com', 'cdn-c.com', 'cdn-d.com');
+    $this->assertMapping(
+      "http://cdn-a.com http://cdn-d.com|.css .jpg .jpeg .png\nhttp://cdn-b.com|.png\nhttp://cdn-c.com",
+      $parsed_mapping,
+      $domains
+    );
+
+    // When a HTTPS request is performed and the CDN is not marked to support
+    // HTTPS, then it should fall back to the default CDN mapping.
+    $this->setRequestProtocol('https');
+    $this->assertMapping(FALSE, $parsed_mapping, $domains);
+
+    // When a HTTPS request is performed and the CDN *is* marked to support
+    // HTTPS, then it should still fall back to the default CDN mapping. (When
+    // file URLs are actually altered, it will then replace `http://` with
+    // `https://` -- this will be tested in a different test.)
+    $this->configureHTTPS(TRUE);
+    $this->assertMapping(FALSE, $parsed_mapping, $domains);
+
+    // When a HTTPS request is performed *and* the CDN is marked to support
+    // HTTPS *and* there's a HTTPS-specific CDN mapping, that mapping should
+    // be used instead!
+    $this->configureHTTPS(TRUE, "https://cdn-a.com|.css .jpg .jpeg .png\nhttps://cdn-b.com|.zip\nhttps://cdn-c.com");
+    $this->assertMapping(
+      FALSE,
+      array(
+        'css'  => array('https://cdn-a.com'),
+        'jpg'  => array('https://cdn-a.com'),
+        'jpeg' => array('https://cdn-a.com'),
+        'png'  => array('https://cdn-a.com'),
+        'zip'  => array('https://cdn-b.com'),
+        '*'    => array('https://cdn-c.com'),
+      ),
+      array('cdn-a.com', 'cdn-b.com', 'cdn-c.com')
+    );
+
+    // Ensure the default CDN mapping is used whenever a HTTP request occurs
+    // and the CDN is marked to suppport HTTPS and there's a HTTPS-specific
+    // CDN mapping.
+    $this->configureHTTPS(FALSE);
+    $this->assertMapping(FALSE, $parsed_mapping, $domains);
+  }
+
+  function testFileUrlAlterHook() {
+    // Provide a very basic CDN mapping.
+    $this->variableSet(CDN_BASIC_MAPPING_VARIABLE, 'http://cdn-a.com');
+
+    $filename = 'újjáépítésérol — 100% in B&W.jpg';
+    $uri = "public://$filename";
+    $this->touchFile($uri);
+
+    cdn_file_url_alter($uri);
+    $expected = 'http://cdn-a.com' . base_path() . variable_get('file_public_path', conf_path() . '/files') . '/' . drupal_encode_path($filename);
+    $this->assertIdentical($uri, $expected, 'cdn_file_url_alter() works correctly.');
+  }
+}
+
+class CDNOriginPullFarFutureTestCase extends CDNTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Origin Pull mode — Far Future expiration',
+      'description' => 'Verify Origin Pull mode\'s Far Future expiration functionality.',
+      'group' => 'CDN',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+    $this->loadFile('cdn.basic.inc');
+    $this->loadFile('cdn.basic.farfuture.inc');
+    $this->variableSet(CDN_MODE_VARIABLE, CDN_MODE_BASIC);
+    $this->variableSet(CDN_BASIC_FARFUTURE_VARIABLE, TRUE);
+  }
+
+  /**
+   * Assert a UFI mapping (and optionally set a mapping).
+   *
+   * @param $mapping
+   *   The mapping to set; if FALSE, no new mapping will be set.
+   * @param $parsed_reference
+   *   The reference the parsed mapping will be compared to.
+   * @param $message
+   */
+  function assertUFIMapping($mapping, $parsed_reference, $message = NULL) {
+    if (is_null($message)) {
+      $message = 'UFI mapping parsed correctly.';
+    }
+
+    if ($mapping !== FALSE) {
+      $this->variableSet(CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_VARIABLE, $mapping);
+    }
+    $parsed = _cdn_basic_farfuture_parse_raw_mapping(variable_get(CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_VARIABLE, CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_DEFAULT));
+    $this->assertEqual($parsed_reference, $parsed, $message);
+  }
+
+  /**
+   * Assert a UFI method. Must be run after a UFI mapping is asserted (and
+   * set) by assertUFIMapping().
+   *
+   * @param $path
+   *   The path to get a UFI for.
+   * @param $ufi_method_reference
+   *   The reference the resulting UFI method will be compared to.
+   */
+  function assertUFIMethod($path, $ufi_method_reference) {
+    $ufi_mapping = _cdn_basic_farfuture_parse_raw_mapping(variable_get(CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_VARIABLE, CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_DEFAULT));
+    $this->assertEqual(
+      $ufi_method_reference,
+      cdn_basic_farfuture_get_ufi_method($path, $ufi_mapping),
+      'Correct UFI method applied.'
+    );
+  }
+
+  function testUFIMapping() {
+    $default = CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_DEFAULT;
+    $parsed_mapping = _cdn_basic_farfuture_parse_raw_mapping($default);
+    $this->assertUFIMapping(
+      FALSE,
+      $parsed_mapping,
+      'The default UFI mapping is set to sensible defaults.'
+    );
+
+    // Growing complexity for a single-directory UFI.
+    $this->assertUFIMapping(
+      "sites/*|mtime",
+      array(
+        'sites/*' => array(
+          '*' => array(
+            'ufi method' => 'mtime',
+            'specificity' => 20, // two directories (2*10), no extension (0)
+          ),
+        ),
+      ),
+      'Simple single-directory UFI mapping (step 1).'
+    );
+    $this->assertUFIMethod('sites/foo', 'mtime');
+    $this->assertUFIMapping(
+      "sites/*|mtime\nsites/*|.woff .ttf|md5_hash",
+      array(
+        'sites/*' => array(
+          '*' => array(
+            'ufi method' => 'mtime',
+            'specificity' => 20, // two directories (2*10), no extension (0)
+          ),
+          'woff' => array(
+            'ufi method' => 'md5_hash',
+            'specificity' => 21, // two directories (2*10), one extension (1)
+          ),
+          'ttf' => array(
+            'ufi method' => 'md5_hash',
+            'specificity' => 21, // two directories (2*10), one extension (1)
+          ),
+        ),
+      ),
+      'Simple single-directory UFI mapping (step 2).'
+    );
+    $this->assertUFIMethod('sites/foo', 'mtime');
+    $this->assertUFIMethod('sites/foobambamb.woff', 'md5_hash');
+    $this->assertUFIMethod('sites/foo/bar/baz.ttf', 'md5_hash');
+    $this->assertUFIMapping(
+      "sites/*|mtime\nsites/*|.woff .ttf|md5_hash\nsites/*|.mov .mp4|perpetual",
+      array(
+        'sites/*' => array(
+          '*' => array(
+            'ufi method' => 'mtime',
+            'specificity' => 20, // two directories (2*10), no extension (0)
+          ),
+          'woff' => array(
+            'ufi method' => 'md5_hash',
+            'specificity' => 21, // two directories (2*10), one extension (1)
+          ),
+          'ttf' => array(
+            'ufi method' => 'md5_hash',
+            'specificity' => 21, // two directories (2*10), one extension (1)
+          ),
+          'mov' => array(
+            'ufi method' => 'perpetual',
+            'specificity' => 21, // two directories (2*10), one extension (1)
+          ),
+          'mp4' => array(
+            'ufi method' => 'perpetual',
+            'specificity' => 21, // two directories (2*10), one extension (1)
+          ),
+        ),
+      ),
+      'Simple single-directory UFI mapping (step 2).'
+    );
+    $this->assertUFIMethod('sites/foo', 'mtime');
+    $this->assertUFIMethod('sites/foobambamb.woff', 'md5_hash');
+    $this->assertUFIMethod('sites/foo/bar/baz.ttf', 'md5_hash');
+    $this->assertUFIMethod('sites/movies/foo.mov', 'perpetual');
+    $this->assertUFIMethod('sites/movies/bar.mp4', 'perpetual');
+  }
+
+  function testFileUrlAlterHook() {
+    // We don't want to test the UFI functionality here.
+    $this->variableSet(CDN_BASIC_FARFUTURE_UNIQUE_IDENTIFIER_MAPPING_VARIABLE, '*|perpetual');
+    // Provide a very basic CDN mapping.
+    $this->variableSet(CDN_BASIC_MAPPING_VARIABLE, 'http://cdn-a.com');
+
+    $filename = 'újjáépítésérol — 100% in B&W.jpg';
+    $uri = "public://$filename";
+    $this->touchFile($uri);
+
+    cdn_file_url_alter($uri);
+
+    $path_info = pathinfo($filename);
+    $expected = implode('/', array(
+      'http://cdn-a.com' . base_path() . 'cdn/farfuture',
+      drupal_hmac_base64('perpetual:forever' . $path_info['filename'], drupal_get_private_key() . drupal_get_hash_salt()),
+      'perpetual:forever',
+      variable_get('file_public_path', conf_path() . '/files'),
+      drupal_encode_path($filename)
+    ));
+    $this->assertIdentical($uri, $expected, 'cdn_file_url_alter() works correctly.');
+  }
+}
+
+class CDNImageTestCase extends CDNTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Image HTML altering',
+      'description' => 'Verify that image URLs inside HTML are rewritten correctly.',
+      'group' => 'CDN',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+    $this->loadFile('cdn.fallback.inc');
+  }
+
+  function testImage() {
+    $cdn = 'http://cdn-a.com';
+    $this->variableSet(CDN_BASIC_MAPPING_VARIABLE, $cdn);
+    $this->variableSet(CDN_MODE_VARIABLE, CDN_MODE_BASIC);
+
+    // Image altering type 1: "just image", i.e. "<img />".
+    $template = function($url) {
+      return '<img alt="Foo!" src="' . $url . '" title="Bar!"/>';
+    };
+    // Simplest case possible.
+    $img_url = base_path() . 'foo/bar/image.png';
+    $html = $template($img_url);
+    cdn_html_alter_image_urls($html);
+    $this->assertIdentical($template($cdn . $img_url), $html, 'Image HTML correctly altered.');
+    // Query strings should not be stripped
+    $img_url = base_path() . 'foo/bar/image.png?foobar';
+    $html = $template($img_url);
+    cdn_html_alter_image_urls($html);
+    $this->assertIdentical($template($cdn . $img_url), $html, 'Image HTML correctly altered (query string not stripped).');
+    // In particular: not the query string used to generate image styles.
+    $img_url = base_path() . 'foo/bar/image.png?itok=1234abcd';
+    $html = $template($img_url);
+    cdn_html_alter_image_urls($html);
+    $this->assertIdentical($template($cdn . $img_url), $html, 'Image HTML correctly altered (image style query string not stripped).');
+    // Edge case: a script generating an image is not (yet) supported.
+    $img_url = base_path() . 'foo/bar/showimage?formula=12345.png';
+    $html = $template($img_url);
+    cdn_html_alter_image_urls($html);
+    $this->assertIdentical($template($cdn . $img_url), $html, 'Image HTML correctly altered (query string not stripped).');
+
+    // Image altering type 2: "linked image", i.e. "<a><img /></a>"..
+    $template = function($a_url, $img_url) {
+      return '<a rel="gallery" href="' . $a_url . '" class="gallery-image"><img alt="Foo!" src="' . $img_url . '" title="Bar!" /></a>';
+    };
+    // Simplest case possible: a linked image linking to the same image.
+    $img_base_url = base_path() . 'foo/bar/image';
+    $a_url = $img_url = $img_base_url . '.png';
+    $html = $template($a_url, $img_url);
+    cdn_html_alter_image_urls($html);
+    $this->assertIdentical($template($cdn . $a_url, $cdn . $img_url), $html, 'Linked image HTML correctly altered.');
+    // Slightly more complex: a linked image linking to a derivative image.
+    $img_url = $img_base_url . '-thumbnail.png?itok=5678wxyz';
+    $html = $template($a_url, $img_url);
+    cdn_html_alter_image_urls($html);
+    $this->assertIdentical($template($cdn . $a_url, $cdn . $img_url), $html, 'Linked image HTML correctly altered.');
+    // Slightly more complex: a linked derivative image linking to another
+    // derivative image.
+    $a_url = $img_base_url . '-large.png?itok=9012klmn';
+    $img_url = $img_base_url . '-thumbnail.png?itok=5678wxyz';
+    $html = $template($a_url, $img_url);
+    cdn_html_alter_image_urls($html);
+    $this->assertIdentical($template($cdn . $a_url, $cdn . $img_url), $html, 'Linked image HTML correctly altered.');
+    // Ensure that images linking to content (i.e. not a bigger version of the
+    // image) don't get their anchors modified
+    $a_url = base_path() . 'node';
+    $html = $template($a_url, $img_url);
+    cdn_html_alter_image_urls($html);
+    $this->assertIdentical($template($a_url, $cdn . $img_url), $html, 'Linked image HTML correctly altered (anchor unmodified).');
+    // Same, but now for a link with a query string.
+    $a_url = base_path() . 'node?foobar';
+    $html = $template($a_url, $img_url);
+    cdn_html_alter_image_urls($html);
+    $this->assertIdentical($template($a_url, $cdn . $img_url), $html, 'Linked image HTML correctly altered (anchor unmodified, even with query strings).');
+  }
+}
+
+class CDNCssUrlTestCase extends DrupalWebTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'CSS URLs',
+      'description' => 'Verify URLs in CSS files are rewritten properly.',
+      'group' => 'CDN',
+    );
+  }
+
+  function setUp() {
+    parent::setUp();
+
+    // Pretend the CDN module is enabled; this ensures invocations of its own
+    // hook implementations will work as expected.
+    $cdn_module_file = drupal_get_path('module', 'cdn') . '/cdn.module';
+    $module_list = module_list();
+    $module_list['cdn']['filename'] = $cdn_module_file;
+    module_list(TRUE, FALSE, FALSE, $module_list);
+    $implementations = &drupal_static('module_implements');
+    $implementations = array();
+
+    $this->loadFile('cdn.constants.inc');
+    $this->loadFile('cdn.module');
+    $this->loadFile('cdn.basic.inc');
+    $this->loadFile('cdn.basic.css.inc');
+    $this->loadFile('cdn.basic.farfuture.inc');
+    variable_set(CDN_MODE_VARIABLE, CDN_MODE_BASIC);
+    variable_set(CDN_BASIC_FARFUTURE_VARIABLE, TRUE);
+  }
+
+  function loadFile($file) {
+    $cdn_path = DRUPAL_ROOT . '/' . drupal_get_path('module', 'cdn');
+    require_once "$cdn_path/$file";
+  }
+
+  // Makes sure the URL components are preserved.
+  function testCssUrl() {
+    global $base_url;
+    $css_info = array(
+      array(
+        'type' => 'file',
+        'data' => drupal_get_path('module', 'cdn') . '/tests/css/orig/url.css',
+      ),
+    );
+    try {
+      // Make sure the URL in the supplied CSS file matches what we expect.
+      // trim() is needed to avoid issues with differences in newlines.
+      $this->assertEqual(trim(file_get_contents(_cdn_build_css_cache($css_info))), '.home{background:url('. $base_url . '/' . drupal_get_path('module', 'cdn') . '/tests/css/orig/geo-md-webfont.eot?#iefix);}');
+    } catch (Exception $exc) {
+      $this->fail($exc);
+    }
+  }
+
+}
