diff --git README.txt README.txt
index afcd30d..a73b5b7 100644
--- README.txt
+++ README.txt
@@ -1,7 +1,17 @@
 CSS Injector
 ============
-Allows administrators to inject CSS into the page output based on configurable rules. It's useful for adding simple CSS tweaks without modifying a site's official theme -- for example, a 'nighttime' color scheme could be added during certain hours. The CSS is added using Drupal's standard drupal_add_css() function and respects page caching, etc.
+Allows administrators to inject CSS into the page output based on configurable
+rules. It's useful for adding simple CSS tweaks without modifying a site's
+official theme -- for example, a 'nighttime' color scheme could be added during
+certain hours. The CSS is added using Drupal's standard drupal_add_css()
+function and respects page caching, etc.
 
-This module is definitely not a replacement for full-fledged theming, but it provides site administrators with a quick and easy way of tweaking things without diving into full-fledged theme hacking.
+This module is definitely not a replacement for full-fledged theming, but it
+provides site administrators with a quick and easy way of tweaking things
+without diving into full-fledged theme hacking.
 
-An important point to keep in mind is that in Drupal, themes always get last crack at display. Theme CSS is applied after modules. That means themes can and will override CSS put into play by CSS Injector module. If you want to override CSS that a theme is already applying, use CSS rules the way they were intended -- higher specificity rules, or the !important flag.
+An important point to keep in mind is that in Drupal, themes always get last
+crack at display. Theme CSS is applied after modules. That means themes can and
+will override CSS put into play by CSS Injector module. If you want to override
+CSS that a theme is already applying, use CSS rules the way they were intended
+-- higher specificity rules, or the !important flag.
diff --git css_injector.admin.inc css_injector.admin.inc
index 9f9f8f5..e1261f4 100644
--- css_injector.admin.inc
+++ css_injector.admin.inc
@@ -4,24 +4,31 @@
 /**
  * Page callback for CSS Injector's main admin page.
  */
-function css_injector_admin_form() {
+function css_injector_admin_form($form, &$form_state) {
   $rules = _css_injector_load_rule(NULL, TRUE);
-  $path = drupal_get_path('module', 'css_injector') .'/';
+  $path = drupal_get_path('module', 'css_injector') . '/';
   $form = array();
   $form['#tree'] = TRUE;
+
+  // TODO: Turn these 'submit' buttons back into image_buttons when
+  // http://drupal.org/node/873070 lands. Currently you can't use
+  // #submit with an image_button.
   foreach ($rules as $rule) {
     $form['rules'][$rule['crid']]['#rule'] = $rule;
     $form['rules'][$rule['crid']]['edit'] = array(
-      '#type' => 'image_button',
-      '#title' => t('Edit rule'),
-      '#src' => $path .'text-editor.png',
+      '#type' => 'submit',
+      '#value' => t('Edit rule'),
+      // '#src' => $path . 'text-editor.png',
+      '#name' => 'edit' . $rule['crid'],
+
       '#submit' => array('css_injector_admin_edit_button'),
       '#crid' => $rule['crid'],
     );
     $form['rules'][$rule['crid']]['delete'] = array(
-      '#type' => 'image_button',
-      '#title' => t('Delete rule'),
-      '#src' => $path .'edit-delete.png',
+      '#type' => 'submit',
+      '#value' => t('Delete rule'),
+      '#name' => 'delete' . $rule['crid'],
+      // '#src' => $path . 'edit-delete.png',
       '#submit' => array('css_injector_admin_delete_button'),
       '#crid' => $rule['crid'],
     );
@@ -33,9 +40,9 @@ function css_injector_admin_form() {
  * Edit button callback for the CSS rule listing form.
  */
 function css_injector_admin_edit_button($form, &$form_state) {
-  $button = $form_state['clicked_button'];
+  $button = $form_state['triggering_element'];
   $crid = $button['#crid'];
-  $form_state['redirect'] = 'admin/settings/css_injector/edit/'. $crid;
+  $form_state['redirect'] = 'admin/config/development/css_injector/edit/' . $crid;
 }
 
 /**
@@ -43,16 +50,17 @@ function css_injector_admin_edit_button($form, &$form_state) {
  * Redirects the user to the confirmation form.
  */
 function css_injector_admin_delete_button($form, &$form_state) {
-  $button = $form_state['clicked_button'];
+  $button = $form_state['triggering_element'];
   $crid = $button['#crid'];
-  $form_state['redirect'] = 'admin/settings/css_injector/delete/'. $crid;
+  $form_state['redirect'] = 'admin/config/development/css_injector/delete/' . $crid;
 }
 
 /**
  * Theme function for the CSS Injector admin overview form.
  */
-function theme_css_injector_admin_form($form) {
-  $headers = array(t('Title'), t('File path'), t('Actions'));
+function theme_css_injector_admin_form($variables) {
+  $form = $variables['form'];
+  $headers = array(t('Title'), t('Location'), t('Actions'));
   $rows = array();
   if (!empty($form['rules'])) {
     foreach (element_children($form['rules']) as $crid) {
@@ -65,7 +73,7 @@ function theme_css_injector_admin_form($form) {
     }
   }
 
-  $link = l(t('Create a new rule'), 'admin/settings/css_injector/add');
+  $link = l(t('Create a new rule'), 'admin/config/development/css_injector/add');
   $row = array();
   if (empty($rows)) {
     $row[] = array(
@@ -81,23 +89,19 @@ function theme_css_injector_admin_form($form) {
   }
   $rows[] = $row;
 
-  $output .= theme('table', $headers, $rows);
-  $output .= drupal_render($form);
+  $output = theme('table', array('header' => $headers, 'rows' => $rows));
+  $output .= drupal_render_children($form);
   return $output;
 }
 
 /**
- * Constructor for the CSS rule edit form.
+ * Form builder function for the CSS rule edit form.
  */
-function css_injector_edit($form_state, $crid = NULL) {
+function css_injector_edit($form, $form_state, $crid = NULL) {
   if (isset($crid)) {
     $rule = _css_injector_load_rule($crid, TRUE);
-    $form['crid'] = array(
-      '#type' => 'value',
-      '#value' => $crid,
-    );
 
-    $path = file_create_path(_css_injector_rule_path($rule['crid']));
+    $path = _css_injector_rule_path($rule['crid']);
     if (file_exists($path)) {
       $rule['css_text'] = file_get_contents($path);
     }
@@ -116,6 +120,12 @@ function css_injector_edit($form_state, $crid = NULL) {
     );
   }
 
+  if (isset($crid)) {
+    $form['crid'] = array(
+      '#type' => 'value',
+      '#value' => $crid,
+    );
+  }
   $form['title'] = array(
     '#type' => 'textfield',
     '#title' => t('Title'),
@@ -133,7 +143,7 @@ function css_injector_edit($form_state, $crid = NULL) {
 
   // Shamelessly ripped from block.module. Who doesn't use this snippet
   // of code, really?
-  $access = user_access('use PHP for block visibility');
+  $access = user_access('use PHP for settings');
   if ($rule['rule_type'] == 2 && !$access) {
     $form['conditional'] = array();
     $form['conditional']['rule_type'] = array('#type' => 'value', '#value' => 2);
@@ -145,7 +155,7 @@ function css_injector_edit($form_state, $crid = NULL) {
 
     if ($access) {
       $options[] = t('Add if the following PHP code returns <code>TRUE</code> (PHP-mode, experts only).');
-      $description .= ' '. t('If the PHP-mode is chosen, enter PHP code between %php. Note that executing incorrect PHP-code can break your Drupal site.', array('%php' => '<?php ?>'));
+      $description .= ' ' . t('If the PHP-mode is chosen, enter PHP code between %php. Note that executing incorrect PHP-code can break your Drupal site.', array('%php' => '<?php ?>'));
     }
     $form['conditional']['rule_type'] = array(
       '#type' => 'radios',
@@ -181,7 +191,7 @@ function css_injector_edit($form_state, $crid = NULL) {
   );
   $form['buttons']['save_and_continue'] = array(
     '#type' => 'submit',
-    '#value' => t('Save and Continue'),
+    '#value' => t('Save and Continue Editing'),
     '#submit' => array('css_injector_edit_save_and_continue'),
   );
 
@@ -189,8 +199,8 @@ function css_injector_edit($form_state, $crid = NULL) {
     $form['buttons']['delete'] = array(
       '#type' => 'submit',
       '#value' => t('Delete'),
-      '#submit' => array('css_injector_admin_delete_button'),
       '#crid' => $rule['crid'],
+      '#submit' => array('css_injector_admin_delete_button'),
     );
   }
 
@@ -201,39 +211,40 @@ function css_injector_edit($form_state, $crid = NULL) {
  * Validation callback for the CSS rule edit form.
  */
 function css_injector_edit_validate($form, &$form_state) {
-  $rule = $form_state['values'];
-  $directory = file_directory_path();
-  file_check_directory($directory, 1);
-  $form_state['rule'] = $rule;
+  $directory = 'public://css_injector';
+  if (!file_prepare_directory($directory, FILE_MODIFY_PERMISSIONS)) {
+    form_error($form, t('The directory %directory is not writable', $directory));
+  }
 }
 
 /**
  * Submit button callback for the CSS rule edit form.
  */
 function css_injector_edit_save($form, &$form_state) {
-  $rule = $form_state['rule'];
-  drupal_write_record('css_injector_rule', $rule, empty($rule['crid']) ? NULL : 'crid');
-
-  file_save_data($rule['css_text'], file_create_path(_css_injector_rule_path($rule['crid'])), FILE_EXISTS_REPLACE);
+  $rule = $form_state['values'];
+  $crid = !empty($form_state['values']['crid']) ? $form_state['values']['crid'] : NULL;
+  drupal_write_record('css_injector_rule', $rule, empty($crid) ? NULL : 'crid');
+  $form_state['values']['rule'] = $rule;
+  file_unmanaged_save_data($rule['css_text'], _css_injector_rule_path($rule['crid']), FILE_EXISTS_REPLACE);
   _css_injector_load_rule(NULL, TRUE);
 
-  drupal_set_message('Your CSS injection rule was saved.');
-  $form_state['redirect'] = 'admin/settings/css_injector';
+  drupal_set_message(t('Your CSS injection rule %title was saved.', array('%title' => $rule['title'])));
+  $form_state['redirect'] = 'admin/config/development/css_injector';
 }
 
 /**
  * Save and continue callback for the CSS rule edit form.
  */
- function css_injector_edit_save_and_continue($form, &$form_state) {
-   css_injector_edit_save($form, $form_state);
-   $form_state['redirect'] = 'admin/settings/css_injector/edit/' . $form_state['rule']['crid'];
- } 
+function css_injector_edit_save_and_continue($form, &$form_state) {
+  css_injector_edit_save($form, $form_state);
+  $form_state['redirect'] = 'admin/config/development/css_injector/edit/' . $form_state['values']['rule']['crid'];
+}
 
 
 /**
  * Menu callback -- ask for confirmation of rule deletion.
  */
-function css_injector_delete_confirm(&$form_state, $crid) {
+function css_injector_delete_confirm($form, &$form_state, $crid) {
   $form['crid'] = array(
     '#type' => 'value',
     '#value' => $crid,
@@ -242,7 +253,7 @@ function css_injector_delete_confirm(&$form_state, $crid) {
   $rule = _css_injector_load_rule($crid);
   return confirm_form($form,
     t('Are you sure you want to delete %title?', array('%title' => $rule['title'])),
-    isset($_GET['destination']) ? $_GET['destination'] : 'admin/settings/css_injector',
+    isset($_GET['destination']) ? $_GET['destination'] : 'admin/config/development/css_injector',
     t('This action cannot be undone.'),
     t('Delete'),
     t('Cancel')
@@ -257,6 +268,6 @@ function css_injector_delete_confirm_submit($form, &$form_state) {
     _css_injector_delete_rule($form_state['values']['crid']);
   }
 
-  $form_state['redirect'] = 'admin/settings/css_injector';
+  $form_state['redirect'] = 'admin/config/development/css_injector';
   return;
 }
diff --git css_injector.info css_injector.info
index d922c48..c6b8308 100644
--- css_injector.info
+++ css_injector.info
@@ -1,4 +1,8 @@
 ;$Id: css_injector.info,v 1.1.2.2 2008/08/10 01:56:58 add1sun Exp $
 name = CSS Injector
 description = Adds CSS to the page output based on configurable rules.
-core = 6.x
+core = 7.x
+
+files[] = css_injector.admin.inc
+files[] = css_injector.install
+files[] = css_injector.module
diff --git css_injector.install css_injector.install
index 8442947..75bf8cf 100644
--- css_injector.install
+++ css_injector.install
@@ -2,14 +2,19 @@
 // $Id: css_injector.install,v 1.1.2.3 2010/03/07 23:59:47 eaton Exp $
 
 /**
- * Implementation of hook_install().
+ * @file
+ * Install, update and uninstall functions for the css_injector module.
+ *
+ */
+
+/**
+ * Implements hook_install().
  */
 function css_injector_install() {
-  drupal_install_schema('css_injector');
 }
 
 /**
- * Implementation of hook_schema().
+ * Implements hook_schema().
  */
 function css_injector_schema() {
   $schema['css_injector_rule'] = array(
@@ -52,22 +57,37 @@ function css_injector_schema() {
 }
 
 /**
- * Implementation of hook_uninstall().
+ * Implements hook_uninstall().
  */
 function css_injector_uninstall() {
   cache_clear_all('css_injector:*', 'cache', TRUE);
-  $results = db_query("SELECT * FROM {css_injector_rule}");
-  while ($rule = db_fetch_array($results)) {
-    file_delete(file_create_path($rule['file_path']));
+  $rules = db_query("SELECT * FROM {css_injector_rule}", array(), array('fetch' => PDO::FETCH_ASSOC))->fetchAllAssoc('crid');
+  foreach($rules as $id => $rule) {
+    file_unmanaged_delete(_css_injector_rule_path($id));
   }
-  db_query("DROP TABLE {css_injector_rule}");
+  db_drop_table('css_injector_rule');
 }
 
 /**
- * Removes file path field from table
+ * Implements hook_requirements().
+ * We'll use this to prevent installation of the module if the file directory
+ * is not available and writable.
  */
-function css_injector_update_6000() {
-  $ret = array();
-  db_drop_field($ret, 'css_injector_rule', 'file_path');
-  return $ret;
+function css_injector_requirements($phase) {
+  $status = REQUIREMENT_OK;
+  $dir = 'public://css_injector';
+  if (!file_prepare_directory($dir, FILE_MODIFY_PERMISSIONS)) {
+    if (!file_prepare_directory($dir, FILE_CREATE_DIRECTORY)) {
+      $status = REQUIREMENT_ERROR;
+    }
+  }
+  $requirements = array(
+    'css_injector' => array(
+      'title' => t('CSS Injector directory writable'),
+      'description' => $status == REQUIREMENT_OK ? t('CSS Injector Directory %dir is writable', array('%dir' => $dir)) : t('Directory %dir is not writable', array('%dir' => $dir)),
+      'severity' => $status,
+      'value' => t('Not writable'),
+    ),
+  );
+  return $requirements;
 }
diff --git css_injector.module css_injector.module
index fcd3b65..a8d5b73 100644
--- css_injector.module
+++ css_injector.module
@@ -9,24 +9,24 @@
  */
 
 /**
- * Implementation of hook_help().
+ * Implements hook_help().
  */
 function css_injector_help($path, $arg) {
   $output = '';
   switch ($path) {
-    case 'admin/settings/modules#description':
+    case 'admin/config/modules#description':
       $output .= t('Allows administrators to inject CSS into the page output based on configurable rules.');
       break;
-    case 'admin/settings/css_injector':
-      $output .= '<p>'. t('Use CSS injection rules to add small snippets of CSS to the page output when specific criteria are met. For example, a simple rule could change the page background color at night or float a particular div to the right on node editing pages.') .'</p>';
-      $output .= '<p>'. t('An important point to keep in mind is that in Drupal, themes always get last crack at display. Theme CSS is applied after modules. That means themes can and will override CSS put into play by CSS Injector module. If you want to override CSS that a theme is already applying, use CSS rules the way they were intended -- higher specificity rules, or the !important flag.') .'</p>';
+    case 'admin/config/development/css_injector':
+      $output .= '<p>' . t('Use CSS injection rules to add small snippets of CSS to the page output when specific criteria are met. For example, a simple rule could change the page background color at night or float a particular div to the right on node editing pages.') . '</p>';
+      $output .= '<p>' . t('An important point to keep in mind is that in Drupal, themes always get last crack at display. Theme CSS is applied after modules. That means themes can and will override CSS put into play by CSS Injector module. If you want to override CSS that a theme is already applying, use CSS rules the way they were intended -- higher specificity rules, or the !important flag.') . '</p>';
       break;
   }
   return $output;
 }
 
 /**
- * Implementation of hook_init().
+ * Implements hook_init().
  * Checks to see whether any CSS files should be added to the current page,
  * based on rules configured by the site administrator.
  */
@@ -34,18 +34,24 @@ function css_injector_init() {
   $css_rules = _css_injector_load_rule();
   foreach ($css_rules as $css_rule) {
     if (_css_injector_evaluate_rule($css_rule)) {
-      drupal_add_css(file_create_path(_css_injector_rule_path($css_rule['crid'])), 'module', $css_rule['media'], $css_rule['preprocess']);
+      // TODO: Can't this be cleaner? An awful lot of work to translate the
+      // stream path to a local file path.
+      $scheme_base = file_directory_path('public');
+      $scheme_path = _css_injector_rule_path($css_rule['crid']);
+      $parts = parse_url($scheme_path);
+      $local_path = $scheme_base . '/' . $parts['host'] . $parts['path'];
+      drupal_add_css($local_path, array('type' => 'file', 'media' => $css_rule['media'], 'preprocess' => $css_rule['preprocess']));
     }
   }
 }
 
 /**
- * Implementation of hook_menu().
+ * Implements hook_menu().
  * Defines menu callbacks for CSS Injector's configuration pages.
  */
 function css_injector_menu() {
   $items = array(
-    'admin/settings/css_injector' => array(
+    'admin/config/development/css_injector' => array(
       'title' => 'CSS injector',
       'description' => 'Add CSS to the page output based on configurable rules.',
       'page callback' => 'drupal_get_form',
@@ -53,7 +59,7 @@ function css_injector_menu() {
       'access arguments' => array('administer css injection'),
       'file' => 'css_injector.admin.inc',
     ),
-    'admin/settings/css_injector/edit' => array(
+    'admin/config/development/css_injector/edit' => array(
       'title' => 'Edit CSS injector rule',
       'page callback' => 'drupal_get_form',
       'page arguments' => array('css_injector_edit'),
@@ -61,7 +67,7 @@ function css_injector_menu() {
       'file' => 'css_injector.admin.inc',
       'type' => MENU_CALLBACK,
     ),
-    'admin/settings/css_injector/add' => array(
+    'admin/config/development/css_injector/add' => array(
       'title' => 'Add CSS injector rule',
       'page callback' => 'drupal_get_form',
       'page arguments' => array('css_injector_edit'),
@@ -69,7 +75,7 @@ function css_injector_menu() {
       'file' => 'css_injector.admin.inc',
       'type' => MENU_CALLBACK,
     ),
-    'admin/settings/css_injector/delete' => array(
+    'admin/config/development/css_injector/delete' => array(
       'title' => 'Delete CSS injector rule',
       'page callback' => 'drupal_get_form',
       'page arguments' => array('css_injector_delete_confirm'),
@@ -82,21 +88,26 @@ function css_injector_menu() {
 }
 
 /**
- * Implementation of hook_theme().
+ * Implements hook_theme().
  */
 function css_injector_theme() {
   $items['css_injector_admin_form'] = array(
-    'arguments' => array('form' => array()),
+    'render element' => 'form',
     'file' => 'css_injector.admin.inc',
   );
   return $items;
 }
 
 /**
- * Implementation of hook_perm().
+ * Implements hook_permission().
  */
-function css_injector_perm() {
-  return array('administer css injection');
+function css_injector_permission() {
+  return array(
+    'administer css injection' => array(
+      'title' => t('administer css injection'),
+      'description' => t('Administer the CSS Injector module'),
+    ),
+  );
 }
 
 /**
@@ -104,15 +115,16 @@ function css_injector_perm() {
  */
 function _css_injector_load_rule($crid = NULL, $reset = FALSE) {
   static $rules;
+  // TODO: Change to drupal_static_fast pattern.
   if (!isset($rules) || $reset) {
     if (!$reset && ($cache = cache_get('css_injector:rules')) && !empty($cache->data)) {
       $rules = $cache->data;
     }
     else {
       $rules = array();
-      $results = db_query("SELECT * FROM {css_injector_rule}");
-      while ($rule = db_fetch_array($results)) {
-        $rules[$rule['crid']] = $rule;
+      $results = db_query("SELECT * FROM {css_injector_rule}", array(), array('fetch' => PDO::FETCH_ASSOC))->fetchAllAssoc('crid');
+      foreach ($results as $id => $rule) {
+        $rules[$id] = $rule;
       }
       cache_set('css_injector:rules', $rules);
     }
@@ -131,8 +143,10 @@ function _css_injector_load_rule($crid = NULL, $reset = FALSE) {
  */
 function _css_injector_delete_rule($crid) {
   if ($rule = _css_injector_load_rule($crid)) {
-    file_delete(file_create_path(_css_injector_rule_path($crid)));
-    db_query("DELETE FROM {css_injector_rule} WHERE crid = %d", $crid);
+    file_unmanaged_delete(_css_injector_rule_path($crid));
+    db_delete('css_injector_rule')
+      ->condition('crid', $crid)
+      ->execute();
   }
 }
 
@@ -156,7 +170,10 @@ function _css_injector_evaluate_rule($css_rule = array()) {
       $page_match = !($css_rule['rule_type'] xor $page_match);
     }
     else {
-      $page_match = drupal_eval($css_rule['rule_conditions']);
+      if (module_exists('php')) {
+        $page_match = php_eval($css_rule['rule_conditions']);
+
+      }
     }
   }
   else {
@@ -170,8 +187,7 @@ function _css_injector_evaluate_rule($css_rule = array()) {
  */
 function _css_injector_rule_path($crid) {
   if (!empty($crid)) {
-    $directory = file_directory_path();
-    return $directory . '/css_injector_'. $crid .'.css';
+    return 'public://css_injector/' . 'css_injector_' . $crid . '.css';
   }
   return NULL;
 }
