diff --git a/advagg_relocate/advagg_relocate.admin.inc b/advagg_relocate/advagg_relocate.admin.inc
new file mode 100644
index 0000000..4c274ab
--- /dev/null
+++ b/advagg_relocate/advagg_relocate.admin.inc
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * @file
+ * Admin page callbacks for the advagg relocate module.
+ */
+
+/**
+ * Form builder; Configure advagg settings.
+ *
+ * @ingroup forms
+ *
+ * @see system_settings_form()
+ */
+function advagg_relocate_admin_settings_form() {
+  drupal_set_title(t('AdvAgg: Relocate'));
+  $form = array();
+
+  // Clear the cache bins on submit.
+  $form['#submit'][] = 'advagg_relocate_admin_settings_form_submit';
+
+  return system_settings_form($form);
+}
+
+// Submit callback.
+/**
+ * Clear out the advagg cache bin when the save configuration button is pressed.
+ */
+function advagg_relocate_admin_settings_form_submit($form, &$form_state) {
+  // Clear caches.
+  advagg_cache_clear_admin_submit();
+}
diff --git a/advagg_relocate/advagg_relocate.advagg.inc b/advagg_relocate/advagg_relocate.advagg.inc
new file mode 100644
index 0000000..55d6ec0
--- /dev/null
+++ b/advagg_relocate/advagg_relocate.advagg.inc
@@ -0,0 +1,360 @@
+<?php
+
+/**
+ * @file
+ * Advanced aggregation relocate module.
+ */
+
+/**
+ * Implements hook_advagg_get_css_aggregate_contents_alter().
+ */
+function advagg_relocate_advagg_get_css_aggregate_contents_alter(&$data, $files, $aggregate_settings) {
+  // Do nothing if this is disabled.
+  if (strpos($data, '@import') !== FALSE) {
+    $data = preg_replace_callback('%@import\s*+(?:url\(\s*+)?+[\'"]?+((?:http:\/\/|https:\/\/|\/\/)(?:[^\'"()\s]++))[\'"]?+\s*+\)?+\s*+;%i', '_advagg_relocate_callback', $data);
+  }
+}
+
+/**
+ * Implements hook_advagg_get_info_on_files_alter().
+ */
+function advagg_relocate_advagg_get_info_on_files_alter(&$return, $cached_data, $bypass_cache) {
+
+}
+
+function _advagg_relocate_callback(array $matches) {
+  // Bail if not matched.
+  if (empty($matches[1])) {
+    return $matches[0];
+  }
+
+  // Bail if the host or path and query string are empty.
+  $parse = @parse_url($matches[1]);
+  if (empty($parse)
+    || empty($parse['host'])
+    || (empty($parse['path']) && empty($parse['query']))
+  ) {
+    return $matches[0];
+  }
+
+  $font_faces = advagg_relocate_get_remote_data($matches[1]);
+
+  $new_css = '';
+  foreach ($font_faces as $values => $src) {
+    $output = '';
+    $output .= str_replace('; ', ";\n", $values);
+    if (isset($src['eot'])) {
+      $output .= "src: {$src['eot']};\n";
+    }
+    $output .= 'src:';
+    foreach ($src as $key => $location) {
+      if (is_numeric($key)) {
+        $output .= "$location,";
+      }
+    }
+    if (isset($src['eot'])) {
+      $src['eot'] = str_replace('.eot', '.eot?#iefix', $src['eot']);
+      $output .= "{$src['eot']} format('embedded-opentype'),";
+    }
+    if (isset($src['woff2'])) {
+      $output .= "{$src['woff2']},";
+    }
+    if (isset($src['woff'])) {
+      $output .= "{$src['woff']},";
+    }
+    if (isset($src['tiff'])) {
+      $output .= "{$src['tiff']},";
+    }
+    if (isset($src['svg'])) {
+      $output .= "{$src['svg']},";
+    }
+    $output = str_replace(array('),l', '),u'), array("),\nl", "),\nu"), trim($output, ',') . ';');
+    $new_css .= "@font-face {\n$output\n}\n";
+  }
+  return $new_css;
+}
+
+function advagg_relocate_get_remote_data($url) {
+  // Set arguments for drupal_http_request().
+  $options = array(
+    'headers' => array(
+      'Accept-Encoding' => 'gzip, deflate',
+      'Connection' => 'close',
+      'Referer' => $GLOBALS['base_root'] . request_uri(),
+    ),
+    'timeout' => 8,
+    'version' => '1.0',
+  );
+  if (function_exists('brotli_uncompress')) {
+    $options['headers']['Accept-Encoding'] .= ', br';
+  }
+
+  //$options['headers']['If-None-Match'] = $response->headers['etag'];
+
+  $responses = array();
+  if (module_exists('httprl')) {
+    // Get ttf.
+    $options['#font-type'] = 'ttf';
+    httprl_request($url . '#ttf', $options);
+
+    // Get eot.
+    $options['#font-type'] = 'eot';
+    $options['headers']['User-Agent'] = 'Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)';
+    httprl_request($url . '#eot', $options);
+
+    // Get svg.
+    $options['#font-type'] = 'svg';
+    $options['headers']['User-Agent'] = 'Mozilla/5.0 (iPad; U; CPU OS 3_2_2 like Mac OS X; nl-nl) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B500 Safari/531.21.10';
+    httprl_request($url . '#svg', $options);
+
+    // Get woff.
+    $options['#font-type'] = 'woff';
+    $options['headers']['User-Agent'] = 'Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)';
+    httprl_request($url . '#woff', $options);
+
+    // Get woff2.
+    $options['#font-type'] = 'woff2';
+    $options['headers']['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1';
+    httprl_request($url . '#woff2', $options);
+
+    $responses = httprl_send_request();
+  }
+  else {
+    // Get ttf.
+    $options['#font-type'] = 'ttf';
+    $responses[] = drupal_http_request($url . '#ttf', $options);
+
+    // Get eot.
+    $options['#font-type'] = 'eot';
+    $options['headers']['User-Agent'] = 'Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)';
+    $responses[] = drupal_http_request($url . '#eot', $options);
+
+    // Get svg.
+    $options['#font-type'] = 'svg';
+    $options['headers']['User-Agent'] = 'Mozilla/5.0 (iPad; U; CPU OS 3_2_2 like Mac OS X; nl-nl) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B500 Safari/531.21.10';
+    $responses[] = drupal_http_request($url . '#svg', $options);
+
+    // Get woff.
+    $options['#font-type'] = 'woff';
+    $options['headers']['User-Agent'] = 'Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)';
+    $responses[] = drupal_http_request($url . '#woff', $options);
+
+    // Get woff2.
+    $options['#font-type'] = 'woff2';
+    $options['headers']['User-Agent'] = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1';
+    $responses[] = drupal_http_request($url . '#woff2', $options);
+  }
+
+  $font_faces = array();
+  foreach ($responses as $response) {
+    if ($response->code == 304) {
+
+    }
+
+    if ($response->code != 200
+      && $response->code != 201
+      && $response->code != 202
+      && $response->code != 206
+    ) {
+      return FALSE;
+    }
+    if (empty($response->data)) {
+      return FALSE;
+    }
+
+    // Uncompress.
+    if (!empty($response->headers['content-encoding'])
+      && !empty($response->data)
+      && !isset($response->chunk_size)
+      && ($response->headers['content-encoding'] === 'gzip'
+        || $response->headers['content-encoding'] === 'deflate'
+        || $response->headers['content-encoding'] === 'br'
+    )) {
+      // Do the first level of decoding if not already done.
+      if ($response->headers['content-encoding'] === 'gzip') {
+        $response->data = @gzinflate(substr($response->data, 10));
+      }
+      elseif ($response->headers['content-encoding'] === 'deflate') {
+        $response->data = @gzinflate($response->data);
+      }
+      elseif ($response->headers['content-encoding'] === 'br' && is_callable('brotli_uncompress')) {
+        $response->data = @brotli_uncompress($response->data);
+      }
+    }
+
+    // Get ttl.
+    $ttl = 0;
+    if (isset($response->headers['expires'])) {
+      $ttl = strtotime($response->headers['expires']);
+      $now = REQUEST_TIME;
+      if (isset($response->headers['date'])) {
+        $now = strtotime($response->headers['date']);
+      }
+      $ttl = $ttl - $now;
+    }
+    if (isset($response->headers['cache-control'])) {
+      $cache_control_array = advagg_relocate_parse_cache_control($response->headers['cache-control']);
+      if (isset($cache_control_array['max-age']) && is_numeric($cache_control_array['max-age'])) {
+        $ttl = max($ttl, $cache_control_array['max-age']);
+      }
+      if (isset($cache_control_array['s-maxage']) && is_numeric($cache_control_array['s-maxage'])) {
+        $ttl = max($ttl, $cache_control_array['s-maxage']);
+      }
+    }
+
+    // Parse the CSS.
+    $font_face = advagg_relocate_parse_css_font_face(
+      $response->data,
+      array('font-family', 'font-style', 'font-weight', 'src'),
+      $response->options['#font-type']
+    );
+
+    // Format into a better data structure and combine.
+    foreach ($font_face as $k => $values) {
+      if (!isset($font_faces[$k])) {
+        $font_faces[$k] = $font_face[$k];
+        continue;
+      }
+
+      foreach ($values as $index => $value) {
+        if (!in_array($value, $font_faces[$k])) {
+          if ($index === $response->options['#font-type']) {
+            $font_faces[$k][$index] = $values[$index];
+          }
+          else {
+            $font_faces[$k][] = $values[$index];
+          }
+        }
+      }
+    }
+  }
+  return $font_faces;
+}
+
+/**
+ * Parse the cache-control string into a key value array.
+ *
+ * @param string $cache_control
+ *   The cache-control string.
+ *
+ * @return array
+ *   Returns a key value array.
+ */
+function advagg_relocate_parse_cache_control($cache_control) {
+  $cache_control_array = explode(',', $cache_control);
+  $cache_control_array = array_map('trim', $cache_control_array);
+  $cache_control_parsed = array();
+  foreach ($cache_control_array as $value) {
+    if (strpos($value, '=') !== FALSE) {
+      $temp = array();
+      parse_str($value, $temp);
+      $cache_control_parsed += $temp;
+    }
+    else {
+      $cache_control_parsed[$value] = TRUE;
+    }
+  }
+  return $cache_control_parsed;
+}
+
+function advagg_relocate_parse_css_font_face($css_string, $properties, $type) {
+  // Get the CSS that contains a font-family rule.
+  $length = strlen($css_string);
+  $property_position = 0;
+  $replacements = array();
+  $lower = strtolower($css_string);
+
+  $attributes = array();
+  foreach ($properties as $index => $property) {
+    while (($property_position = strpos($lower, $property, $property_position)) !== FALSE) {
+      // Find the start of the values for the property.
+      $start_of_values = strpos($css_string, ':', $property_position);
+      // Get the property at this location of the css.
+      $property_in_loop = trim(substr($css_string, $property_position, ($start_of_values - $property_position)));
+
+      // Make sure this property is one of the ones we're looking for.
+      if ($property_in_loop !== $property) {
+        $property_position += strlen($property);
+        continue;
+      }
+
+      // Get position of the last closing bracket plus 1 (start of this section).
+      $start = strrpos($css_string, '}', -($length - $property_position));
+      if ($start === FALSE) {
+        // Property is in the first selector and a declaration block (full rule
+        // set).
+        $start = 0;
+      }
+      else {
+        // Add one to start after the }.
+        $start++;
+      }
+
+      // Get closing bracket (end of this section).
+      $end = strpos($css_string, '}', $property_position);
+      if ($end === FALSE) {
+        // The end is the end of this file.
+        $end = $length;
+      }
+
+      // Get closing ; in order to get the end of the declaration of the property.
+      $declaration_end_a = strpos($css_string, ';', $property_position);
+      $declaration_end_b = strpos($css_string, '}', $property_position);
+      if ($declaration_end_a === FALSE) {
+        $declaration_end = $declaration_end_b;
+      }
+      else {
+        $declaration_end = min($declaration_end_a, $declaration_end_b);
+      }
+      if ($declaration_end > $end) {
+        $declaration_end = $end;
+      }
+      // Add one in order to capture the } when we ge the full rule set.
+      $end++;
+      // Advance position for the next run of the while loop.
+      $property_position = $end;
+
+      // Get values assigned to this property.
+      $values_string = substr($css_string, $start_of_values + 1, $declaration_end - ($start_of_values + 1));
+      // Parse values string into an array of values.
+      $values_array = explode(',', $values_string);
+      $values_array = array_map('trim', $values_array);
+
+      foreach ($values_array as $key => $value) {
+        if (stripos($value, "'$type'") !== FALSE || stripos($value, ".$type") !== FALSE ) {
+          unset($values_array[$key]);
+          $values_array[$type] = $value;
+        }
+      }
+      $attributes[$property][] = $values_array;
+    }
+  }
+
+
+
+  // Make sure src is the last one.
+  $temp = $attributes['src'];
+  unset($attributes['src']);
+  $attributes['src'] = $temp;
+
+
+  $temp = array();
+  $output = array();
+  foreach ($attributes as $property => $values) {
+    foreach ($values as $key => $value) {
+      if ($property !== 'src') {
+
+        $value = implode(',', $value);
+        if (!isset($temp[$key])) {
+          $temp[$key] = '';
+        }
+        $temp[$key] .= "$property: $value; ";
+      }
+      else {
+        $output[$temp[$key]] = $value;
+      }
+    }
+  }
+
+  return $output;
+}
diff --git a/advagg_relocate/advagg_relocate.info b/advagg_relocate/advagg_relocate.info
new file mode 100644
index 0000000..277c7e9
--- /dev/null
+++ b/advagg_relocate/advagg_relocate.info
@@ -0,0 +1,6 @@
+name = AdvAgg Relocate
+description = Inline css import rules; also make any external file local.
+core = 7.x
+dependencies[] = advagg
+package = Advanced CSS/JS Aggregation
+configure = admin/config/development/performance/advagg/relocate
diff --git a/advagg_relocate/advagg_relocate.module b/advagg_relocate/advagg_relocate.module
new file mode 100644
index 0000000..48041d1
--- /dev/null
+++ b/advagg_relocate/advagg_relocate.module
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * @file
+ * Advanced aggregation relocate module.
+ */
+
+// Core hook implementations.
+/**
+ * Implements hook_menu().
+ */
+function advagg_relocate_menu() {
+  $file_path = drupal_get_path('module', 'advagg_relocate');
+  $config_path = advagg_admin_config_root_path();
+
+  $items[$config_path . '/advagg/relocate'] = array(
+    'title' => 'Relocate',
+    'description' => 'Move external items to be local.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('advagg_relocate_admin_settings_form'),
+    'type' => MENU_LOCAL_TASK,
+    'access arguments' => array('administer site configuration'),
+    'file path' => $file_path,
+    'file' => 'advagg_relocate.admin.inc',
+    'weight' => 10,
+  );
+
+  return $items;
+}
+
+/**
+ * Implements hook_js_alter().
+ */
+function advagg_relocate_js_alter(&$js) {
+}
+
+
+/**
+ * Implements hook_css_alter().
+ */
+function advagg_relocate_css_alter(&$css) {
+}
+
+/**
+ * Implements hook_cron().
+ */
+function advagg_relocate_cron() {
+}
+
+// Contrib hook implementations.
+/**
+ * Implements hook_advagg_current_hooks_hash_array_alter().
+ */
+function advagg_relocate_advagg_current_hooks_hash_array_alter(&$aggregate_settings) {
+
+}
+
+// Helper functions.
