diff --git a/speedy.drush.inc b/speedy.drush.inc
index 1471e3b..9c03c86 100644
--- a/speedy.drush.inc
+++ b/speedy.drush.inc
@@ -38,95 +38,7 @@ function speedy_drush_help($section) {
 
 /**
  * Command callback to minify JS using UglifyJS.
- *
- * This is a command that walks through a Drupal codebase and produces minified
- * JavaScript files.
  */
-function drush_speedy_min($uglifyjs) {
-
-  if (empty($uglifyjs)) {
-    drush_log(dt('The path to UglifyJS is missing.'), 'error');
-    return;
-  }
-
-  $directory = DRUPAL_ROOT . '/' . drupal_get_path('module', 'speedy') . '/js/' . VERSION . '/';
-  $directory_strlen = strlen(DRUPAL_ROOT . '/');
-
-  // @todo Is there a cleaner way to create the directory?
-  if (!is_dir($directory)) {
-    mkdir($directory, 0775, TRUE);
-  }
-
-  // A list of files and directories to not act on.
-  // @todo Make this configurable
-  $blacklist = array(
-    'misc/jquery.js',
-    'misc/farbtastic/farbtastic.js',
-    'misc/jquery.ba-bbq.js',
-    'misc/jquery.cookie.js',
-    'misc/jquery.form.js',
-    'misc/ui',
-    'sites',
-  );
-
-  // Make the blacklist full paths so all things are equal.
-  foreach ($blacklist as $k => $v) {
-    $blacklist[$k] = DRUPAL_ROOT . '/' . $v;
-  }
-
-  // @todo Replace file_scan_directory with PHP navite call. Why does Drupal
-  // reproduce a native php feature?
-  $all_files = file_scan_directory(DRUPAL_ROOT, '/.js/');
-
-  // Walk though each file and act on those not blacklisted.
-  foreach ($all_files as $k => $file) {
-    
-    // Make sure the file isn't blacklisted.
-    if (!_speedy_drush_blacklisted($blacklist, $file)) {
-      // Minify and store the file.
-
-      $new_path = $directory . substr($file->uri, $directory_strlen);
-      $pathinfo = pathinfo($new_path);
-      if (!is_dir($pathinfo['dirname'])) {
-        mkdir($pathinfo['dirname'], 0775, TRUE);
-      }
-
-      $return = drush_shell_exec($uglifyjs . ' ' . $file->uri . ' > ' . $new_path);
-
-      if ($return) {
-        drush_log(dt('!filename was minified.', array('!filename' => $file->filename)), 'success');
-      }
-      else {
-        // @todo Note that a file was created with the error information in it.
-        drush_log(dt('There was an error when trying to minify !filename.', array('!filename' => $file->filename)), 'error');
-      }
-    }
-  }
+function drush_speedy_min() {
+  speedy_minify('speedy_node_js_minfiy');
 }
-
-/**
- * Make sure a file uri is not on a blacklist.
- *
- * @param array $blacklist
- *  A list of files and directories for a blacklist.
- * @param stdClass $file
- *  A file object as returned from file_scan_directory(). At the very least it
- *  needs to have the public property $file->uri with the full path to the file.
- *
- * @return bool
- *  TRUE if the file is on the blacklist and FALSE otherwise.
- */
-function _speedy_drush_blacklisted($blacklist, $file) {
-  foreach ($blacklist as $k => $v) {
-    if (is_dir($v)) {
-      if (strpos($file->uri, $v) === 0) {
-        return TRUE;
-      }
-    }
-    elseif ($v == $file->uri) {
-      return TRUE;
-    }
-  }
-
-  return FALSE;
-}
\ No newline at end of file
diff --git a/speedy.module b/speedy.module
index 762ff2c..a1a0a81 100644
--- a/speedy.module
+++ b/speedy.module
@@ -8,38 +8,249 @@
  */
 
 /**
- * Implements hook_library_alter().
+ * Implements hook_FORM_ID_alter().
  *
- * If minified core JS exists for the current version of Drupal swap it out.
+ * @param type $form
+ * @param type $form_state
+ */
+function speedy_form_system_performance_settings_alter(&$form, &$form_state) {
+  $form['bandwidth_optimization']['speedy_js_production'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Use minified JS files created by Speedy'),
+    '#default_value' => variable_get('speedy_js_production'),
+    '#description' => t('Enabling this will replace non-minified Drupal core,
+      contributed, and theme Javascript files with a minfied versions - if they
+      exist.'),
+  );
+  $form['bandwidth_optimization']['speedy_js_blacklist_list'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Blacklisted Javascript files'),
+    '#default_value' => implode("\r", speedy_blacklist()),
+    '#description' => t('List the files that you do not want to minimize.Enter
+      the full path to the file relative to the Drupal root.'),
+    '#states' => array(
+      'visible' => array(
+        ':input[name="speedy_js_production"]' => array('checked' => TRUE),
+      ),
+    ),
+  );
+  // Ensure that we can remap the values on submit to an array
+  $form['#submit'][] = 'speedy_blacklist_save';
+
+  // @todo Add configuration for the path to the minified files directory?
+}
+
+
+/**
+ * Helper function to convert the string values into an array
+ *
+ * @param type $form
+ * @param type $form_state
+ */
+function speedy_blacklist_save($form, $form_state) {
+  if (! empty($form_state['values']['speedy_js_blacklist_list'])) {
+    $blacklist = preg_split('/\s+/', $form_state['values']['speedy_js_blacklist_list']);
+    $blacklist = array_combine(array_values($blacklist), $blacklist);
+    variable_set('speedy_js_blacklist', $blacklist);
+  }
+}
+
+
+/**
+ * Implements hook_js_alter().
  */
 function speedy_js_alter(&$javascript) {
-  
-  // Manage the map of replacements. This is cached so we don't have to hit the
-  // file system on each pageload to do the swap.
-  static $replacement_map = NULL;
-  if (is_null($replacement_map)) {
-    if (FALSE && $cache = cache_get('speedy_min_js_files')) {
-      $replacement_map = $cache->data;
+  // If production not enabled do not return minified files
+  if (! variable_get('speedy_js_production', FALSE)) {
+    return;
+  }
+
+  // If there are no replacements in the system there is nothing to do
+  if (! $replacements = variable_get('speedy_minified_files', FALSE)) {
+    return;
+  }
+  // Check incoming files against our replacements
+  // @todo should this look against $javascript instead for performance?
+  foreach ($replacements as $path => $file) {
+    if (! empty($javascript[$path]) && $javascript[$path]['type'] == 'file') {
+      $javascript[$path]['data'] = $file->minified;
     }
-    else {
-      $directory = DRUPAL_ROOT . '/' . drupal_get_path('module', 'speedy') . '/js/' . VERSION;
-      $directory_strlen = strlen($directory . '/');
+  }
+}
 
-      $all_files = file_scan_directory($directory, '/.js/');
-      $replacement_map = array();
 
-      foreach ($all_files as $file) {
-        $replacement_map[] = substr($file->uri, $directory_strlen);
-      }
+/**
+ * Returns a list of blacklisted JS files
+ *
+ * @todo should this be alterable?
+ *
+ * @return
+ *   Array of paths to blacklist
+ */
+function speedy_blacklist() {
+  // Get any stored values
+  if (! $blacklist = variable_get('speedy_js_blacklist', FALSE)) {
+    // A list of files and directories to not act on.
+    $blacklist = array(
+      'misc/jquery.js',
+      'misc/farbtastic/farbtastic.js',
+      'misc/jquery.ba-bbq.js',
+      'misc/jquery.cookie.js',
+      'misc/jquery.form.js',
+      'misc/ui',
+      drupal_get_path('module', 'speedy') . '/js'
+    );
+    $blacklist = array_combine(array_values($blacklist), $blacklist);
+  }
+  return $blacklist;
+}
 
-      cache_set('speedy_min_js_files', $replacement_map);
+
+/**
+ * Make sure a file uri is not on a blacklist.
+ *
+ * @param stdClass $file
+ *  A file object as returned from file_scan_directory(). At the very least it
+ *  needs to have the public property $file->uri with the full path to the file.
+ *
+ * @return bool
+ *  TRUE if the file is on the blacklist and FALSE otherwise.
+ */
+function speedy_file_blacklisted($file) {
+  $blacklist = speedy_blacklist();
+  // Allow $file to be a drupal object or a string
+  if (is_object($file)) {
+    $file = $file->drupal_filepath;
+  }
+  // Do we have a direct path match?
+  if (isset($blacklist[$file])) {
+    return TRUE;
+  }
+  // Check all of the existing blacklist paths
+  foreach ($blacklist as $blacklist_path) {
+    // It is only considered a match if the paths share the same root
+    if (strpos($file, $blacklist_path) === 0) {
+      return TRUE;
     }
   }
+  // No matches found
+  return FALSE;
+}
+
+
+/**
+ * Finds all JS files that need to be modified
+ *
+ * @todo this function should not be drush specific with its error messages
+ * @todo handle the core specific JS spereately maybe?
+ *
+ * @param string $callback
+ *   Function call generate the JS files. Callback boolean based on success of
+ *   minification. $file can be modified by the callbacks.
+ */
+function speedy_minify($callback) {
+  // Complete list of files which are blacklist or minified processed by this function
+  $minfied_files = array();
+ variable_set('speedy_minified_files', FALSE);
+  // Path to the minified JS library
+  $minified_directory = variable_get('speedy_js_path', drupal_get_path('module', 'speedy') . '/js/');
+  // Ensure that we can write to this directory
+  // @todo what is the error condition here?
+  file_prepare_directory($minified_directory, FILE_CREATE_DIRECTORY);
 
-  $new_path = drupal_get_path('module', 'speedy') . '/js/' . VERSION . '/';
-  foreach ($javascript as $name => $data) {
-    if ($data['type'] == 'file' && in_array($data['data'], $replacement_map)) {
-      $javascript[$name]['data'] = $new_path . $data['data'];
+  // Find all JS files. Note that we ignore *.min.js files
+  $all_js_files = speedy_file_scan_directory(DRUPAL_ROOT, '/.js$/', array('nomask' => '/(\.\.?|CVS?|\.min\.js)$/'));
+
+  // Current minfied files
+  $current_minified_files = variable_get('speedy_minified_files', array());
+
+  // Start minifying files
+  foreach ($all_js_files as $file) {
+    // By default we do not modify this file
+    $minify = FALSE;
+
+    // Make sure the file is not blacklisted.
+    if (speedy_file_blacklisted($file->drupal_filepath)) {
+      $minify = FALSE;
+    }
+    // Do we have a record of this minified file?
+    elseif (empty($current_minified_files[$file->drupal_filepath])) {
+      $minify = TRUE;
     }
+    // Is the original modified date more recent than the current minified file?
+    elseif ($current_minified_files[$file->drupal_filepath]->modified > $file->modified) {
+      $minify = TRUE;
+    }
+    // We do not need to minify this file but we need to keep a record of it
+    elseif (! empty($current_minified_files[$file->drupal_filepath])) {
+      $minified_files[$file->drupal_filepath] = $current_minified_files[$file->drupal_filepath];
+    }
+
+    // Should we minify this file?
+    if ($minify) {
+      // Create a file path to the store directory. Note that we have to add in
+      // a / because of how file_prepare_directory() modifies the path
+      $filepath_min = $minified_directory . '/' . preg_replace("/.js/", ".min.js", basename($file->uri));
+      // Now we can attempt to generate the file with the requested callback
+      if ($callback($file, $filepath_min)) {
+        if (empty($file->minified)) {
+          $file->minified = $filepath_min;
+        }
+        // Add the minified filepath to the list of saved files
+        $minified_files[$file->drupal_filepath] = $file;
+        drush_log(dt('!filename was minified.', array('!filename' => $file->drupal_filepath)), 'success');
+      }
+      else {
+        // @todo Note that a file was created with the error information in it.
+        drush_log(dt('There was an error when trying to minify !filename.', array('!filename' => $file->drupal_filepath)), 'error');
+      }
+    }
+  }
+
+  // Save the list of minified files if there are any changes
+  if (! empty($minified_files)) {
+    variable_set('speedy_minified_files', $minified_files);
+  }
+}
+
+
+/**
+ * Wrapper for file scan directory to add modified dates to files
+ *
+ * @return array()
+ *   Array of file pseudo objects
+ */
+function speedy_file_scan_directory($path, $regex, $options = array()) {
+  $files = file_scan_directory($path, $regex, $options);
+  foreach ($files as $key => $file) {
+    $files[$key]->modified = filemtime($files[$key]->uri);
+    $files[$key]->drupal_filepath = str_replace(DRUPAL_ROOT . '/', '', $file->uri);
+  }
+  return $files;
+}
+
+
+/**
+ * This is the default function to execute nodejs minification
+ *
+ * @param object $file
+ *   File scan directory object
+ * @param string $minfied_file
+ *   Path where the minified file is stored
+ */
+function speedy_node_js_minfiy($filepath, $filepath_min) {
+  // Set the command for uglify
+  $node_js_command = variable_get('speedy_node_js_command', 'uglifyjs');
+  // Execute the command
+  $return = drush_shell_exec($node_js_command . ' ' . $file->uri . ' > ' . $filepath_min);
+
+  if ($return) {
+    drush_log(dt('!filename was minified.', array('!filename' => $file->filename)), 'success');
+    return TRUE;
+  }
+  else {
+    // @todo Note that a file was created with the error information in it.
+    drush_log(dt('There was an error when trying to minify !filename.', array('!filename' => $file->filename)), 'error');
+    return FALSE;
   }
 }
\ No newline at end of file
