diff --git a/modules/system.skinr.inc b/modules/system.skinr.inc
new file mode 100644
index 0000000000000000000000000000000000000000..aa946b19796729d8066317dd29831f8907e36968
--- /dev/null
+++ b/modules/system.skinr.inc
@@ -0,0 +1,45 @@
+<?php
+/**
+ * @file
+ * Implements Skinr hooks for system.module.
+ */
+
+/**
+ * Implements hook_skinr_config_info().
+ */
+function system_skinr_config_info() {
+  return array('system');
+}
+
+/**
+ * Implements hook_skinr_theme_hooks().
+ */
+function system_skinr_theme_hooks($module, $element) {
+  $theme_hooks = array();
+
+  if ($module == 'system') {
+    if ($element == 'html') {
+      $theme_hooks[] = 'html';
+    }
+    else {
+      $theme_hooks[] = $element;
+      $theme_hooks[] = 'region';
+    }
+  }
+
+  return $theme_hooks;
+}
+
+/**
+ * Implements hook_skinr_elements().
+ */
+function system_skinr_elements($variables, $hook) {
+  $elements = array();
+  if ($hook == 'html') {
+    $elements['system'] = array('html');
+  }
+  elseif ($hook == 'region') {
+    $elements['system'] = array('region__' . $variables['region']);
+  }
+  return $elements;
+}
diff --git a/skinr.install b/skinr.install
index 8a2577ab941703ca3710c3757150450a22cc00c0..f96450958a73ba36b754aca82fe5c8faa8377514 100644
--- a/skinr.install
+++ b/skinr.install
@@ -73,58 +73,6 @@ function skinr_schema() {
     ),
   );
 
-  $schema['skinr_rules'] = array(
-    'description' => 'Stores skinr rule data.',
-    'fields' => array(
-      'rid' => array(
-        'type' => 'serial',
-        'not null' => TRUE,
-        'description' => 'Primary Key: Unique skinr rule ID.',
-      ),
-      'title' => array(
-        'description' => 'The administrative title for this rule.',
-        'type' => 'varchar',
-        'length' => 128,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'rule_type' => array(
-        'description' => 'The content type of this rule.',
-        'type' => 'varchar',
-        'length' => 128,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'node_types' => array(
-        'type' => 'text',
-        'size' => 'normal',
-        'not null' => FALSE,
-        'serialize' => TRUE,
-        'description' => 'A serialized array of node types for this record.',
-      ),
-      'roles' => array(
-        'type' => 'text',
-        'size' => 'normal',
-        'not null' => FALSE,
-        'serialize' => TRUE,
-        'description' => 'A serialized array of roles for this record.',
-      ),
-      'visibility' => array(
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'tiny',
-        'description' => 'Flag to indicate how to show rules on pages. (0 = Show on all pages except listed pages, 1 = Show only on listed pages, 2 = Use custom PHP code to determine visibility)',
-      ),
-      'pages' => array(
-        'type' => 'text',
-        'not null' => TRUE,
-        'description' => 'Contains either a list of paths on which to include/exclude the rule or PHP code, depending on "visibility" setting.',
-      ),
-    ),
-    'primary key' => array('rid'),
-  );
-
   return $schema;
 }
 
@@ -165,26 +113,11 @@ function skinr_update_7001() {
  *
  * @todo Should we remove this? It was ported from skinr_update_6001(), but
  *   shouldn't have been.
+ *
+ * Contents removed because the table added here is no longer required.
  */
 function skinr_update_7002() {
   // @todo skinr_update_6001() contains additional field manipulations.
-
-  if (!db_field_exists('skinr_rules', 'rule_type')) {
-    db_add_field('skinr_rules', 'rule_type', array(
-      'description' => 'The content type of this rule.',
-      'type' => 'varchar',
-      'length' => 128,
-      'not null' => TRUE,
-      'default' => '',
-    ));
-    db_update('skinr_rules')
-      ->fields(array('rule_type' => 'page'))
-      ->execute();
-    db_update('skinr')
-      ->fields(array('module' => 'rules'))
-      ->condition('module', 'page')
-      ->execute();
-  }
 }
 
 /**
diff --git a/skinr.module b/skinr.module
index 07699af021ebf86ef39880676eedd9bebcf384e0..85cc4f3f73191667462e20bcb00560cd76e40725 100644
--- a/skinr.module
+++ b/skinr.module
@@ -11,21 +11,6 @@
 define('SKINR_VERSION', 2);
 
 /**
- * Show this rule on every page except the listed pages.
- */
-define('SKINR_RULE_VISIBILITY_NOTLISTED', 0);
-
-/**
- * Show this rule on only the listed pages.
- */
-define('SKINR_RULE_VISIBILITY_LISTED', 1);
-
-/**
- * Show this rule if the associated PHP code returns TRUE.
- */
-define('SKINR_RULE_VISIBILITY_PHP', 2);
-
-/**
  * Implements hook_help().
  */
 function skinr_help($path, $arg) {
@@ -111,22 +96,21 @@ function skinr_preprocess(&$variables, $hook) {
     }
 
     $applied_skins = array();
-    foreach (skinr_skin_load_multiple($sids) as $skin) {
-      $applied_skins = array($skin->skin => $skin->options) + $applied_skins;
-    }
+    $skins = skinr_skin_load_multiple($sids);
 
     // Invoke hook_skinr_preprocess_alter() in all modules.
-    // @todo Review whether this alter hook is useful or not, and if it's in
-    //   the right place or not.
     $context = array(
       'hook' => $hook,
       'variables' => &$variables,
       'theme' => $current_theme,
       'module' => $module,
       'elements' => $elements,
-      'options' => $applied_skins,
     );
-    drupal_alter('skinr_preprocess', $context);
+    drupal_alter('skinr_preprocess', $skins, $context);
+
+    foreach ($skins as $skin) {
+      $applied_skins = array($skin->skin => $skin->options) + $applied_skins;
+    }
 
     // Use drupal_process_attached() to add attachements such as JS and CSS.
     if (!empty($applied_skins)) {
@@ -189,225 +173,6 @@ function skinr_flatten_skins_array($skin_options) {
   return array_unique($classes);
 }
 
-// ------------------------------------------------------------------
-// Rule functions.
-
-/**
- * Validate a rule object.
- *
- * @param $rule
- *   A rule object.
- *
- * @return
- *   TRUE on success, FALSE on failure.
- */
-
-function skinr_rule_validate(&$rule) {
-  if (empty($rule->title) || empty($rule->rule_type)) {
-    return FALSE;
-  }
-
-  if (!isset($rule->node_types)) {
-    $rule->node_types = array();
-  }
-  if (!isset($rule->roles)) {
-    $rule->roles = array();
-  }
-  if (!isset($rule->visibility)) {
-    $rule->visibility = 0;
-  }
-  if (!isset($rule->pages)) {
-    $rule->pages = '';
-  }
-
-  if (!is_array($rule->node_types) || !is_array($rule->roles)) {
-    return FALSE;
-  }
-  if ($rule->visibility !== 0 && $rule->visibility !== 1 && $rule->visibility !== 2) {
-    return FALSE;
-  }
-
-  return TRUE;
-}
-
-/**
- * Save a skinr rule object.
- *
- * @param $rule
- *   A rule object.
- *
- * @return
- *   The rule ID.
- */
-function skinr_rule_save($rule) {
-  // Make sure we're getting valid data.
-  if (!skinr_rule_validate($rule)) {
-    return FALSE;
-  }
-
-  $status = drupal_write_record('skinr_rules', $rule, !empty($rule->rid) ? array('rid') : array());
-  return $status;
-}
-
-/**
- * Load a skinr rule object.
- *
- * @param $rid
- *   (optional) The rule ID.
- *
- * @return
- *   A rule object. If no $rid is specified an array of all rules will be
- *   returned.
- */
-function skinr_rule_load($rid = NULL) {
-  $rids = (isset($rid) ? array($rid) : array());
-  $rules = skinr_rule_load_multiple($rids);
-  return $rules ? reset($rules) : FALSE;
-}
-
-/**
- * Loads multiple skinr rule objects.
- *
- * @param $rids
- *   An array of rule IDs. Optional.
- * @param $conditions
- *   An array of conditions on the {skinr_rules} table in the form 'field' =>
- *   $value.
- *
- * @return
- *   An array of rule objects indexed by rid. If $rids is not provided, all
- *   rules are returned.
- */
-function skinr_rule_load_multiple($rids = array(), $conditions = array()) {
-  $rules = array();
-  $select = db_select('skinr_rules')->fields('skinr_rules');
-  if (!empty($rids)) {
-    $select->condition('rid', $rids);
-  }
-  foreach ($conditions as $field => $condition) {
-    $select->condition($field, $condition);
-  }
-  foreach ($select->execute() as $rule) {
-    $rule->node_types = unserialize($rule->node_types);
-    $rule->roles = unserialize($rule->roles);
-    $rules[$rule->rid] = $rule;
-  }
-  return $rules;
-}
-
-/**
- * Delete a skinr rule object.
- *
- * @param $rid
- *   The rule ID.
- */
-function skinr_rule_delete($rid) {
-  if ($rule = skinr_rule_load($rid)) {
-    db_delete('skinr_rules')
-      ->condition('rid', $rule->rid)
-      ->execute();
-    db_delete('skinr_skins')
-      ->condition('module', 'page')
-      ->condition('element', $rule->rid)
-      ->execute();
-  }
-}
-
-/**
- * Determines if the rule should be visible for a given path.
- *
- * @param $rid
- *   The rule ID.
- * @param $path
- *   (optional) The path to check. Defaults to the path of the current page.
- * @param $account
- *   (optional) The account to check. Defaults to currently logged in user.
- *
- * @return
- *   TRUE if the rule should be visible, FALSE otherwise.
- */
-function skinr_rule_is_visible($rid, $path = NULL, $account = NULL) {
-  global $user;
-
-  if (!isset($account)) {
-    $account = $user;
-  }
-
-  if ($rule = skinr_rule_load($rid)) {
-    if (!isset($path)) {
-      $path = $_GET['q'];
-    }
-
-    // Check role visibility.
-    if (!empty($rule->roles) && ($account->uid != 1) && !count(array_intersect(array_keys($account->roles), $rule->roles))) {
-      return FALSE;
-    }
-
-    // Check content type visibility.
-    // If a rule has no node types associated, it is displayed for every type.
-    // For rules with node types associated, if the node type does not match
-    // the settings from this rule, return FALSE.
-    if (!empty($rule->node_types)) {
-      $node = menu_get_object('node', 1, $path);
-      $node_types = node_type_get_types();
-      if (arg(0, $path) == 'node' && arg(1, $path) == 'add' && arg(2, $path)) {
-        $node_add_arg = strtr(arg(2, $path), '-', '_');
-      }
-
-      if (!empty($node)) {
-        // This is a node or node edit page.
-        if (empty($rule->node_types[$node->type])) {
-          // This rule should not be displayed for this node type.
-          return FALSE;
-        }
-      }
-      elseif (isset($node_add_arg) && isset($node_types[$node_add_arg])) {
-        // This is a node creation page.
-        if (!isset($rule->node_types[$node_add_arg]) || !$rule->node_types[$node_add_arg]) {
-          // This rule should not be displayed for this node type.
-          return FALSE;
-        }
-      }
-      else {
-        // This is not a node page, remove the rule.
-        return FALSE;
-      }
-    }
-
-    // Match path if necessary.
-    if ($rule->pages) {
-      // Convert path to lowercase. This allows comparison of the same path
-      // with different case. Ex: /Page, /page, /PAGE.
-      $pages = drupal_strtolower($rule->pages);
-      if ($rule->visibility < SKINR_RULE_VISIBILITY_PHP) {
-        // Convert the Drupal path to lowercase
-        $path = drupal_strtolower(drupal_get_path_alias($path));
-        // Compare the lowercase internal and lowercase path alias (if any).
-        $page_match = drupal_match_path($path, $pages);
-        if ($path != $_GET['q']) {
-          $page_match = $page_match || drupal_match_path($path, $pages);
-        }
-        // When $rule->visibility has a value of 0 (SKINR_RULE_VISIBILITY_NOTLISTED),
-        // the rule is displayed on all pages except those listed in $rule->pages.
-        // When set to 1 (SKINR_RULE_VISIBILITY_LISTED), it is displayed only on those
-        // pages listed in $rule->pages.
-        $page_match = !($rule->visibility xor $page_match);
-      }
-      elseif (module_exists('php')) {
-        $page_match = php_eval($rule->pages);
-      }
-      else {
-        $page_match = FALSE;
-      }
-    }
-    else {
-      $page_match = TRUE;
-    }
-    return $page_match;
-  }
-  return FALSE;
-}
-
 /**
  * Returns a list of extensions that implement this API version of Skinr.
  *
@@ -936,10 +701,12 @@ function skinr_skin_load_multiple($sids = array()) {
   // sids left to load.
   if ($sids === FALSE || $sids) {
     // Build the query.
-    $queried_skins = db_select('skinr_skins', 's')
-      ->fields('s')
-      ->condition('sid', $sids)
-      ->execute()
+    $query = db_select('skinr_skins', 's')
+      ->fields('s');
+    if ($sids !== FALSE) {
+      $query->condition('sid', $sids);
+    }
+    $queried_skins = $query->execute()
       ->fetchAllAssoc('sid');
 
     foreach ($queried_skins as $sid => $skin) {
@@ -1465,6 +1232,10 @@ function node_skinr_api_2() {
   return skinr_skinr_api_modules();
 }
 
+function system_skinr_api_2() {
+  return skinr_skinr_api_modules();
+}
+
 function views_skinr_api_2() {
   return skinr_skinr_api_modules();
 }
diff --git a/skinr.skinr.inc b/skinr.skinr.inc
index f8c2e80abfed0e5b40dbbcb140010761a5b88726..ea04ff466d91afe80529cf99003d65b697cbddc6 100644
--- a/skinr.skinr.inc
+++ b/skinr.skinr.inc
@@ -34,51 +34,3 @@ function skinr_skinr_group_info() {
   );
   return $groups;
 }
-
-/**
- * Implementation of hook_skinr_config_info().
- */
-function skinr_skinr_config_info() {
-  return array('rules');
-}
-
-/**
- * Implements hook_skinr_theme_hooks().
- */
-function skinr_skinr_theme_hooks($module, $element) {
-  $theme_hooks = array();
-
-  if ($module == 'rules') {
-    $rule = skinr_rule_load($element);
-    $hooks = explode('__', $rule->rule_type);
-    while (count($hooks)) {
-      $theme_hooks[] = implode('__', $hooks);
-      array_pop($hooks);
-    }
-  }
-
-  return $theme_hooks;
-}
-
-/**
- * Implements hook_skinr_elements().
- */
-function skinr_skinr_elements($variables, $hook) {
-  $elements = array();
-  if ($hook == 'html' || $hook == 'region') {
-    $elements['rules'] = array();
-
-    $rule_type = 'page';
-    if ($hook == 'region') {
-      $rule_type = 'region__' . $variables['region'];
-    }
-
-    $rules = skinr_rule_load_multiple(array(), array('rule_type' => $rule_type));
-    foreach ($rules as $rule) {
-      if (skinr_rule_is_visible($rule->rid)) {
-        $elements['rules'][] = $rule->rid;
-      }
-    }
-  }
-  return $elements;
-}
diff --git a/skinr_context/skinr_context.info b/skinr_context/skinr_context.info
new file mode 100644
index 0000000000000000000000000000000000000000..4c097cc1335ef602ddf865b4fe331df3fd68076c
--- /dev/null
+++ b/skinr_context/skinr_context.info
@@ -0,0 +1,8 @@
+name = Skinr Context
+description = Provides Skinr integration with Context.
+package = Skinr
+core = 7.x
+dependencies[] = context
+dependencies[] = skinr
+
+files[] = tests/skinr_context.test
diff --git a/skinr_context/skinr_context.install b/skinr_context/skinr_context.install
new file mode 100644
index 0000000000000000000000000000000000000000..14798aeff46a5246d130e36026a344c8b30b5294
--- /dev/null
+++ b/skinr_context/skinr_context.install
@@ -0,0 +1,166 @@
+<?php
+
+/**
+ * @file
+ * Contains install, update, and uninstall functions for Skinr Context.
+ */
+
+/**
+ * Implements hook_schema().
+ */
+function skinr_context_schema() {
+  $schema['skinr_groups'] = array(
+    'description' => 'Stores skin configuration group data for Skinr.',
+    'fields' => array(
+      'gid' => array(
+        'description' => 'The primary identifier for a skin configuration group.',
+        'type' => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'module' => array(
+        'description' => 'The module this group applies to.',
+        'type' => 'varchar',
+        'length' => 64,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'element' => array(
+        'description' => 'The element this group applies to.',
+        'type' => 'varchar',
+        'length' => 128,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'title' => array(
+        'description' => 'The administrative title for this group.',
+        'type' => 'varchar',
+        'length' => 128,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'description' => array(
+        'description' => 'Description for this group.',
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'conditions' => array(
+        'description' => 'Serialized storage of all context condition settings.',
+        'type' => 'text',
+        'serialize' => TRUE,
+      ),
+      'condition_mode' => array(
+        'description' => 'Condition mode for this context.',
+        'type' => 'int',
+        'default' => 0,
+      ),
+      'weight' => array(
+        'description' => 'Weight of the group. Lighter weights are higher up, heavier weights go down.',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
+      'status' => array(
+        'description' => 'Boolean indicating whether or not this item is enabled.',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 1,
+        'size' => 'tiny',
+      ),
+    ),
+    'primary key' => array('gid'),
+    'indexes' => array(
+      'module' => array('module'),
+      'element' => array('module', 'element'),
+    ),
+  );
+
+  $schema['skinr_group_skins'] = array(
+    'description' => 'Associates skin configurations with a particular group.',
+    'fields' => array(
+      'gid' => array(
+        'description' => 'The skin configuration group ID.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'sid' => array(
+        'description' => 'The skin configuration ID.',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+    ),
+    'primary key' => array('gid', 'sid'),
+    'indexes' => array(
+      'gid' => array('gid'),
+    ),
+  );
+
+  return $schema;
+}
+
+/**
+ * Implements hook_uninstall().
+ */
+function skinr_context_uninstall() {
+}
+
+/**
+ * Implements hook_enable().
+ */
+function skinr_context_enable() {
+  $t = get_t();
+
+  // Associate each skin with a group, if it isn't already.
+  $query = db_select('skinr_skins', 's');
+  $query->leftJoin('skinr_group_skins', 'gs', 's.sid = gs.sid');
+  $query->fields('s');
+  $query->fields('gs', array('gid'));
+  $result = $query->execute();
+  foreach ($result as $skin) {
+    $skin->options = unserialize($skin->options);
+
+    $group = NULL;
+    if (empty($skin->gid)) {
+      // Lookup existing group. Grab the one with the lowest weight for this set.
+      $params = array(
+        'module' => $skin->module,
+        'element' => $skin->element,
+      );
+      $gids = skinr_context_group_get_gids($params);
+      $gid = reset($gids);
+      if (!$gid) {
+        // Create a group.
+        $group = (object) array(
+          'gid' => NULL,
+          'module' => $skin->module,
+          'element' => $skin->element,
+          'title' => $t('Default'),
+          'description' => '',
+          'conditions' => array('sitewide' => array('values' => array(1 => 1))),
+          'condition_mode' => CONTEXT_CONDITION_MODE_OR,
+          'weight' => 0,
+          'status' => 1,
+        );
+        skinr_context_group_save($group);
+        $gid = $group->gid;
+      }
+      $skin->gid = $gid;
+      // Simulate insert to ensure group is linked.
+      skinr_context_skinr_skin_insert($skin);
+    }
+
+    if (!$group) {
+      $group = skinr_context_group_load($skin->gid);
+    }
+
+    if ($skin->status && $group && !$group->status) {
+      // Disable skins where group is disabled.
+      $skin->status = 0;
+      skinr_skin_save($skin);
+    }
+  }
+}
diff --git a/skinr_context/skinr_context.module b/skinr_context/skinr_context.module
new file mode 100644
index 0000000000000000000000000000000000000000..df856eb1d514731c0c1b9d1778c78aa2c7403358
--- /dev/null
+++ b/skinr_context/skinr_context.module
@@ -0,0 +1,424 @@
+<?php
+
+/**
+ * @file
+ * Provides Skinr integration with Context.
+ */
+
+/**
+ * Save a skin group object.
+ *
+ * @param $group
+ *   A skin settings group object.
+ *
+ * @return
+ *   TRUE on success, FALSE on failure.
+ */
+function skinr_context_group_save(&$group) {
+  // Load the stored skin settings group object, if any.
+  if (!empty($group->gid)) {
+    if (!isset($group->original)) {
+      // Load an uncached version of the skin settings object.
+      $group->original = skinr_context_group_load_unchanged($group->gid);
+    }
+  }
+
+  // Let modules modify the node before it is saved to the database.
+  module_invoke_all('skinr_context_group_presave', $group);
+
+  if (!empty($group->gid)) {
+    // Record exists, so let's update.
+    $status = drupal_write_record('skinr_groups', $group, 'gid');
+
+    // When status changes, update status of linked skin settings.
+    if ($group->status != $group->original->status) {
+      $params = array(
+        'gid' => $group->gid,
+      );
+      $sids = skinr_context_group_get_sids($params);
+      foreach ($sids as $sid) {
+      }
+      // @todo
+    }
+
+    module_invoke_all('skinr_context_group_update', $group);
+  }
+  else {
+    // Insert a new record.
+    $status = drupal_write_record('skinr_groups', $group);
+    module_invoke_all('skinr_context_group_insert', $group);
+  }
+
+  // Clear internal properties.
+  unset($group->original);
+  // Clear the static loading cache.
+  // @todo Once we have a more granular reset for skinr_skin_load_multiple(), we
+  //   need to use it here.
+  drupal_static_reset('skinr_context_group_load_multiple');
+  // Clear context's cache.
+  context_invalidate_cache();
+
+  return $status;
+}
+
+/**
+ * Delete a skin group object.
+ *
+ * @param $gid
+ *   The skin settings group ID.
+ */
+function skinr_context_group_delete($gid) {
+  skinr_context_group_delete_multiple(array($gid));
+}
+
+/**
+ * Delete multiple skin settings group objects.
+ *
+ * @param $gids
+ *   An array of skin settings group IDs.
+ */
+function skinr_context_group_delete_multiple($gids) {
+  $transaction = db_transaction();
+  if (!empty($gids)) {
+    $groups = skinr_context_group_load_multiple($gids);
+
+    try {
+      foreach ($groups as $gid => $group) {
+        module_invoke_all('skinr_context_group_delete', $group);
+
+        // Delete all skin settings associated with this group.
+        $params = array(
+          'gid' => $gid,
+        );
+        $sids = skinr_context_group_get_sids($params);
+        skinr_skin_delete_multiple($sids);
+      }
+
+      // Delete after calling hooks so that they can query node tables as needed.
+      db_delete('skinr_groups')
+        ->condition('gid', $gids, 'IN')
+        ->execute();
+    }
+    catch (Exception $e) {
+      $transaction->rollback();
+      watchdog_exception('skinr', $e);
+      throw $e;
+    }
+
+    // Clear the skinr_context_group_load_multiple cache.
+    drupal_static_reset('skinr_context_group_load_multiple');
+    // Clear context's cache.
+    context_invalidate_cache();
+  }
+}
+
+/**
+ * Load a skin settings group object from the database.
+ *
+ * @param $gid
+ *   The skin settings group ID.
+ *
+ * @return
+ *   A fully-populated skin settings group object.
+ */
+function skinr_context_group_load($gid = NULL) {
+  $gids = (isset($gid) ? array($gid) : array());
+  $group = skinr_context_group_load_multiple($gids);
+  return $group ? reset($group) : FALSE;
+}
+
+/**
+ * Load skin settings group objects from the database.
+ *
+ * This function should be used whenever you need to load more than one skin
+ * configuration group from the database. Skin settings groups are loaded
+ * into memory and will not require database access if loaded again during the
+ * same page request.
+ *
+ * @see skinr_context_group_get_gids()
+ *
+ * @param $gids
+ *   An array of skin settings group IDs.
+ *
+ * @return
+ *   An array of skin settings group objects indexed by gid.
+ */
+function skinr_context_group_load_multiple($gids = array()) {
+  // @todo Do we want to write a more granular cache reset?
+  $groups = &drupal_static(__FUNCTION__, array());
+
+  // Create a new variable which is either a prepared version of the $gids
+  // array for later comparison with cached skin group objects, or FALSE
+  // if no $gids were passed. The $gids array is reduced as items are loaded
+  // from cache, and we need to know if it's empty for this reason to avoid
+  // querying the database when all requested skin group objects are
+  // loaded from cache.
+  $passed_gids = !empty($gids) ? array_flip($gids) : FALSE;
+  if ($passed_gids) {
+    $gids = array_keys(array_diff_key($passed_gids, $groups));
+  }
+
+  // Load any remaining skin groups from the database. This is the
+  // case if $gids is set to FALSE (so we load all groups), or if there are any
+  // gids left to load.
+  if ($gids === FALSE || $gids) {
+    // Build the query.
+    $query = db_select('skinr_groups', 'g')
+      ->fields('g');
+    if ($gids !== FALSE) {
+      $query->condition('gid', $gids);
+    }
+    $queried_groups = $query->execute()
+      ->fetchAllAssoc('gid');
+
+    foreach ($queried_groups as $gid => $group) {
+      // Unserialize options array.
+      $queried_groups[$gid]->conditions = unserialize($group->conditions);
+
+      // Let modules modify the skin settings group.
+      module_invoke_all('skinr_context_group_load', $queried_groups[$gid]);
+    }
+    $groups += $queried_groups;
+  }
+
+  // Ensure that the returned array is ordered the same as the original
+  // $gids array if this was passed in and remove any invalid gids.
+  if ($passed_gids) {
+    // Remove any invalid gids from the array.
+    $passed_gids = array_intersect_key($passed_gids, $groups);
+    $return = array();
+    foreach ($passed_gids as $gid => $ignore) {
+      $return[$gid] = $groups[$gid];
+    }
+  }
+  else {
+    $return = $groups;
+  }
+
+  return $return;
+}
+
+/**
+ * Load an uncached version of a skin settings group object.
+ *
+ * @param $gid
+ *   The skin settings group ID.
+ *
+ * @return
+ *   A fully-populated skin settings group object.
+ */
+function skinr_context_group_load_unchanged($gid) {
+  // Load an uncached version of the skin settings object.
+  $group = db_query("SELECT * FROM {skinr_groups} WHERE gid = :gid", array(
+    ':gid' => $gid,
+  ))
+  ->fetchObject();
+
+  // Unserialize options array.
+  $group->conditions = unserialize($group->conditions);
+
+  // Let modules modify the skin settings group.
+  module_invoke_all('skinr_context_group_load', $group);
+
+  return $group;
+}
+
+/**
+ * Get skin settings group IDs.
+ *
+ * @param $filter_by
+ *   An associative array whose keys are:
+ *   - module: (optional) The module.
+ *   - element: (optional) The element ID.
+ *
+ * @return
+ *   An array of skin settings group IDs.
+ */
+function skinr_context_group_get_gids($filter_by = array()) {
+  $query = db_select('skinr_groups', 'g')
+      ->fields('g', array('gid'));
+  if (isset($filter_by['module'])) {
+    $query->condition('module', $filter_by['module']);
+  }
+  if (isset($filter_by['element'])) {
+    $query->condition('element', $filter_by['element']);
+  }
+
+  // Take weight into account.
+  $query->orderBy('weight');
+  $query->orderBy('gid');
+
+  return $query->execute()
+    ->fetchCol();
+}
+
+/**
+ * Get skin settings IDs for grouped skin settings.
+ *
+ * @param $filter_by
+ *   An associative array whose keys are:
+ *   - theme: (optional) The theme.
+ *   - module: (optional) The module.
+ *   - element: (optional) The element ID.
+ *   - gid: (optional) The group ID.
+ *   - skin: (optional) The skin name.
+ *   - status: (optional) Boolean indicating whether or not this skin
+ *     configuration is enabled.
+ *
+ * @return
+ *   An array of skin settings IDs.
+ */
+function skinr_context_group_get_sids($filter_by = array()) {
+  $query = db_select('skinr_skins', 's');
+  $query->join('skinr_group_skins', 'gs', 's.sid = gs.sid');
+  $query->fields('s', array('sid'));
+
+  if (isset($filter_by['theme'])) {
+    $query->condition('s.theme', $filter_by['theme']);
+  }
+  if (isset($filter_by['module'])) {
+    $query->condition('s.module', $filter_by['module']);
+  }
+  if (isset($filter_by['element'])) {
+    $query->condition('s.element', $filter_by['element']);
+  }
+  if (isset($filter_by['gid'])) {
+    $query->condition('gs.gid', $filter_by['gid']);
+  }
+  if (isset($filter_by['skin'])) {
+    $query->condition('s.skin', $filter_by['skin']);
+  }
+  if (isset($filter_by['status'])) {
+    $query->condition('s.status', $filter_by['status']);
+  }
+  return $query->execute()
+    ->fetchCol();
+}
+
+/**
+ * Helper function to create a context object from a skin settings group.
+ *
+ * @param $group
+ *   Skinr settings group object.
+ *
+ * @return
+ *   A context object.
+ */
+function skinr_context_group_to_context($group) {
+  $context = (object) array(
+    'name' => 'skinr_group__' . $group->gid,
+    'description' => !empty($group->description) ? t('@title: @description', array('@title' => $group->title, '@description' => $group->description)) : check_plain($group->title),
+    'tag' => 'Skinr',
+    'conditions' => $group->conditions,
+    'reactions' => array(),
+    'condition_mode' => $group->condition_mode,
+  );
+  return $context;
+}
+
+/**
+ * Implements hook_ctools_plugin_api().
+ */
+function skinr_context_ctools_plugin_api($module, $api) {
+  if ($module == "context" && $api == "context") {
+    return array("version" => 3);
+  }
+}
+
+/**
+ * Implements hook_context_default_contexts().
+ */
+function skinr_context_context_default_contexts() {
+  $contexts = array();
+  foreach (skinr_context_group_load_multiple(FALSE) as $group) {
+    $context = skinr_context_group_to_context($group);
+    $context->disabled = FALSE;
+    $context->api_version = 3;
+    $contexts[$context->name] = $context;
+  }
+  return $contexts;
+}
+
+/**
+ * Implements hook_skinr_skin_presave().
+ */
+function skinr_context_skinr_skin_presave($skin) {
+  if (!empty($skin->gid)) {
+    // Load group object.
+    if ($group = skinr_context_group_load($skin->gid)) {
+      if (!$group->status) {
+        // Disable skin status if group is disabled.
+        $skin->status = 0;
+      }
+    }
+  }
+}
+
+/**
+ * Implements hook_skinr_skin_insert().
+ */
+function skinr_context_skinr_skin_insert($skin) {
+  if (!empty($skin->gid)) {
+    $gs = (object) array(
+      'gid' => $skin->gid,
+      'sid' => $skin->sid,
+    );
+    drupal_write_record('skinr_group_skins', $gs);
+  }
+}
+
+/**
+ * Implements hook_skinr_skin_delete().
+ */
+function skinr_context_skinr_skin_delete($skin) {
+  if (!empty($skin->gid)) {
+    db_delete('skinr_group_skins')
+      ->condition('sid', $skin->sid)
+      ->execute();
+  }
+}
+
+/**
+ * Implements hook_skinr_skin_load().
+ */
+function skinr_context_skinr_skin_load($skin) {
+  $query = db_select('skinr_group_skins', 'gs');
+  $query->fields('gs', array('gid'));
+  $query->condition('sid', $skin->sid);
+
+  $skin->gid = $query->execute()->fetchField();
+}
+
+/**
+ * Function used by uasort to sort classes by weight.
+ *
+ * @see skinr_context_skinr_preprocess_alter()
+ */
+function skinr_context_sort_weight($a, $b) {
+  $a_weight = (is_object($a) && isset($a->weight)) ? $a->weight : 0;
+  $b_weight = (is_object($b) && isset($b->weight)) ? $b->weight : 0;
+  if ($a_weight == $b_weight) {
+    return 0;
+  }
+  return ($a_weight < $b_weight) ? -1 : 1;
+}
+
+/**
+ * Implements hook_skinr_preprocess_alter().
+ */
+function skinr_context_skinr_preprocess_alter(&$skins, $context) {
+  $contexts = context_active_contexts();
+  foreach ($skins as $key => $skin) {
+    if (!empty($skin->gid) && $group = skinr_context_group_load($skin->gid)) {
+      // Remove skins for groups that arent in the right context.
+      if (!isset($contexts['skinr_group__' . $skin->gid])) {
+        unset($skins[$key]);
+      }
+
+      // Set group based weight on skins.
+      $skin->weight = $group->weight;
+    }
+  }
+  // Reorder by weight.
+  uasort($skins, 'skinr_context_sort_weight');
+}
diff --git a/skinr_context/skinr_context_ui.info b/skinr_context/skinr_context_ui.info
new file mode 100644
index 0000000000000000000000000000000000000000..ab520aae390fbed1b0878839b69175743adc14f0
--- /dev/null
+++ b/skinr_context/skinr_context_ui.info
@@ -0,0 +1,8 @@
+name = Skinr Context UI
+description = Administrative interface for Skinr Context. Without this module, you cannot edit your skins with context.
+package = Skinr
+core = 7.x
+dependencies[] = context_ui
+dependencies[] = skinr_ui
+
+files[] = tests/skinr_context_ui.test
diff --git a/skinr_context/skinr_context_ui.module b/skinr_context/skinr_context_ui.module
new file mode 100644
index 0000000000000000000000000000000000000000..00caa554a39ef1300dfa79597ead8b0fa981f093
--- /dev/null
+++ b/skinr_context/skinr_context_ui.module
@@ -0,0 +1,834 @@
+<?php
+
+/**
+ * @file
+ * Administrative interface for Skinr Context. Without this module, you cannot edit your skins with context.
+ */
+
+/**
+ * Implements hook_menu().
+ */
+function skinr_context_ui_menu() {
+  $items['admin/structure/skinr/edit/%/%/%skinr_context_group'] = array(
+    'title' => 'Edit skin',
+    'title callback' => 'skinr_context_ui_edit_title',
+    'title arguments' => array(4, 5, 6),
+    'page callback' => 'skinr_context_ui_edit',
+    'page arguments' => array(4, 5, 6), // module, element, gid
+    'type' => MENU_LOCAL_TASK,
+    'access arguments' => array('edit skin settings'),
+  );
+  $items['admin/structure/skinr/edit/%/%/add'] = array(
+    'title' => 'Add group',
+    'page callback' => 'skinr_context_ui_group_add',
+    'page arguments' => array(4, 5), // module, element
+    'type' => MENU_LOCAL_ACTION,
+    'access arguments' => array('edit skin settings'),
+  );
+  $items['admin/structure/skinr/edit/%/%/%skinr_context_group/delete'] = array(
+    'title' => 'Delete group',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('skinr_context_ui_group_delete_confirm', 6),
+    'type' => MENU_CALLBACK,
+    'access arguments' => array('edit skin settings'),
+  );
+
+  return $items;
+}
+
+/**
+ * Implements hook_menu_alter().
+ */
+function skinr_context_ui_menu_alter(&$items) {
+  $items['admin/structure/skinr/edit/%/%']['page callback'] = 'skinr_context_ui_group_list';
+  $items['admin/structure/skinr']['page arguments'] = array('skinr_context_ui_skin_list');
+}
+
+/**
+ * Implements hook_menu_local_tasks_alter().
+ */
+function skinr_context_ui_menu_local_tasks_alter(&$data, $router_item, $root_path) {
+  $destination = array();
+  if (isset($_GET['destination'])) {
+    $path = $_GET['q'];
+    $query = drupal_http_build_query(drupal_get_query_parameters());
+    if ($query != '') {
+      $path .= '?' . $query;
+    }
+    $destination = array('destination' => $path);
+  }
+
+  if ($destination && $root_path == 'admin/structure/skinr/edit/%/%') {
+    foreach ($data['actions']['output'] as $key => $item) {
+      if ($item['#link']['path'] == 'admin/structure/skinr/edit/%/%/add') {
+        // Add destination query string to link to preserve it.
+        if (empty($data['actions']['output'][$key]['#link']['localized_options']['query'])) {
+          $data['actions']['output'][$key]['#link']['localized_options']['query'] = array();
+        }
+        $data['actions']['output'][$key]['#link']['localized_options']['query'] += $destination;
+      }
+    }
+  }
+}
+
+/**
+ * Menu title callback; sets the title for a skins configuration form page.
+ *
+ * @param $module
+ *   The module that we're editing settings of.
+ * @param $element
+ *   The element we're editing settings of.
+ */
+function skinr_context_ui_edit_title($module, $element, $group) {
+  return t('Skin settings for !group group (!module type !element)', array('!group' => $group->title, '!module' => $module, '!element' => $element));
+}
+
+/**
+ * Implements hook_theme().
+ */
+function skinr_context_ui_theme() {
+  $items['skinr_context_ui_group_list_form'] = array(
+    'render element' => 'form',
+  );
+  $items['skinr_context_ui_group_summary'] = array(
+    'variables' => array('title' => NULL, 'description' => NULL),
+  );
+  return $items;
+}
+
+/**
+ * Implements hook_help().
+ */
+function skinr_context_ui_help($path, $arg) {
+  switch ($path) {
+    case 'admin/structure/skinr/edit/%/%/%':
+      // We're overriding paths in skinr_ui so make sure the proper help text
+      // still appears.
+      return skinr_ui_help('admin/structure/skinr/edit/%/%', $arg);
+  }
+}
+
+/**
+ * Menu callback; adds a skin settings group to an element.
+ *
+ * @param $module
+ *   The module that we're adding a group to.
+ * @param $element
+ *   The element of the object we're adding a group to.
+ */
+function skinr_context_ui_group_add($module, $element) {
+  return drupal_get_form('skinr_context_ui_group_add_form', $module, $element);
+}
+
+function skinr_context_ui_group_add_form($form, $form_state, $module, $element) {
+  $form['module'] = array(
+    '#type' => 'hidden',
+    '#value' => $module,
+  );
+  $form['element'] = array(
+    '#type' => 'hidden',
+    '#value' => $element,
+  );
+  $form['title'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Group title'),
+    '#required' => TRUE,
+    '#description' => t('Descriptive title for this skin settings group.'),
+  );
+  $form['description'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Description'),
+    '#description' => t('A description for this group.'),
+  );
+
+  $form['actions'] = array(
+    '#tree' => FALSE,
+    '#type' => 'actions',
+  );
+  $form['actions']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Add group'),
+  );
+
+  return $form;
+}
+
+/**
+ * Menu callback; allows adding a new skin settings group.
+ */
+function skinr_context_ui_group_add_form_submit($form, $form_state) {
+  $group = (object) array(
+    'gid' => NULL,
+    'module' => $form_state['values']['module'],
+    'element' => $form_state['values']['element'],
+    'title' => $form_state['values']['title'],
+    'description' => $form_state['values']['description'],
+    'conditions' => array('sitewide' => array('values' => array(1 => 1))),
+    'condition_mode' => CONTEXT_CONDITION_MODE_OR,
+    'weight' => 0,
+    'status' => 1,
+  );
+  skinr_context_group_save($group);
+  drupal_goto('admin/structure/skinr/edit/' . $group->module . '/' . $group->element . '/' . $group->gid);
+}
+
+/**
+ * Menu callback; lists skin settings groups for an element.
+ *
+ * @param $module
+ *   The module that we're editing settings of.
+ * @param $element
+ *   The element of the object we're editing settings of.
+ */
+function skinr_context_ui_group_list($module, $element) {
+  // Output list of groups.
+  $gids = skinr_context_group_get_gids(array(
+    'module' => $module,
+    'element' => $element,
+  ));
+  $groups = skinr_context_group_load_multiple($gids);
+
+  return drupal_get_form('skinr_context_ui_group_list_form', $groups);
+}
+
+/**
+ * Form builder for the skin settings group listing.
+ */
+function skinr_context_ui_group_list_form($form, $form_state, $groups) {
+  // Weights range from -delta to +delta, so delta should be at least half
+  // of the amount of blocks present. This makes sure all blocks in the same
+  // region get an unique weight.
+  $weight_delta = round(count($groups) / 2);
+
+  $form['groups'] = array();
+  $form['#tree'] = TRUE;
+  $form['#empty_text'] = t("You don't have any groups for this element.");
+
+  foreach ($groups as $gid => $group) {
+    $group = (array) $group;
+
+    $form['groups'][$gid]['info'] = array(
+      '#markup' => theme('skinr_context_ui_group_summary', array('title' => $group['title'], 'description' => $group['description'])),
+    );
+    $form['groups'][$gid]['status'] = array(
+      '#type' => 'checkbox',
+      '#default_value' => $group['status'],
+      '#title_display' => 'invisible',
+      '#title' => t('Enable @group group', array('@group' => $group['title'])),
+    );
+    $form['groups'][$gid]['weight'] = array(
+      '#type' => 'weight',
+      '#default_value' => $group['weight'],
+      '#delta' => $weight_delta,
+      '#title_display' => 'invisible',
+      '#title' => t('Weight for @group group', array('@group' => $group['title'])),
+    );
+
+    $destination = array();
+    if (isset($_GET['destination'])) {
+      $path = $_GET['q'];
+      $query = drupal_http_build_query(drupal_get_query_parameters());
+      if ($query != '') {
+        $path .= '?' . $query;
+      }
+      $destination = array('destination' => $path);
+    }
+
+    $operations = array();
+    $operations['edit'] = array(
+      '#type' => 'link',
+      '#title' => t('edit'),
+      '#href' => 'admin/structure/skinr/edit/' . $group['module'] . '/' . $group['element'] . '/' . $group['gid'],
+      '#options' => array('query' => $destination),
+    );
+    $operations['delete'] = array(
+      '#type' => 'link',
+      '#title' => t('delete'),
+      '#href' => 'admin/structure/skinr/edit/' . $group['module'] . '/' . $group['element'] . '/' . $group['gid'] . '/delete',
+      '#options' => array('query' => $destination),
+    );
+    $form['groups'][$gid]['operations'] = $operations;
+  }
+
+  // Prepare cancel link.
+  if (isset($_GET['destination'])) {
+    $options = drupal_parse_url(urldecode($_GET['destination']));
+  }
+  else {
+    $options = array('path' => 'admin/structure/skinr');
+  }
+
+  $form['actions'] = array(
+    '#tree' => FALSE,
+    '#type' => 'actions',
+  );
+  $form['actions']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save groups'),
+  );
+  $form['actions']['done'] = array(
+    '#type' => 'link',
+    '#title' => t('Done'),
+    '#href' => $options['path'],
+    '#options' => $options,
+  );
+
+  return $form;
+}
+
+/**
+ * Form submission handler for skinr_context_ui_group_list_form().
+ */
+function skinr_context_ui_group_list_form_submit($form, $form_state) {
+  foreach ($form_state['values']['groups'] as $gid => $data) {
+    // Load an uncached version of the skin settings group object.
+    $group = skinr_context_group_load_unchanged($gid);
+    // Let's save some time in skinr_context_group_save() by setting $group->original here.
+    $group->original = clone($group);
+
+    // Update status and weight.
+    $group->status = $data['status'];
+    $group->weight = $data['weight'];
+    skinr_context_group_save($group);
+  }
+}
+
+/**
+ * Returns HTML for the menu overview form into a table.
+ *
+ * @param $variables
+ *   An associative array containing:
+ *   - form: A render element representing the form.
+ *
+ * @ingroup themeable
+ */
+function theme_skinr_context_ui_group_list_form($variables) {
+  $form = $variables['form'];
+
+  drupal_add_tabledrag('skinr-context-ui-group-list', 'order', 'sibling', 'skinr-context-ui-group-weight');
+
+  $header = array(
+    t('Skin settings group'),
+    array('data' => t('Enabled'), 'class' => array('checkbox')),
+    t('Weight'),
+    array('data' => t('Operations'), 'colspan' => '2'),
+  );
+
+  $rows = array();
+  foreach (element_children($form['groups']) as $gid) {
+    if (isset($form['groups'][$gid]['status'])) {
+      $element = &$form['groups'][$gid];
+      // Build a list of operations.
+      $operations = array();
+      foreach (element_children($element['operations']) as $op) {
+        $operations[] = array('data' => drupal_render($element['operations'][$op]), 'class' => array('skinr-context-ui-group-operations'));
+      }
+
+      // Add special classes to be used for tabledrag.js.
+      $element['weight']['#attributes']['class'] = array('skinr-context-ui-group-weight');
+
+      $row = array();
+      $row[] = drupal_render($element['info']);
+      $row[] = array('data' => drupal_render($element['status']), 'class' => array('checkbox', 'skinr-context-ui-group-enabled'));
+      $row[] = drupal_render($element['weight']);
+      $row = array_merge($row, $operations);
+
+      $row = array_merge(array('data' => $row), $element['#attributes']);
+      $row['class'][] = 'draggable';
+      $rows[] = $row;
+    }
+  }
+  $output = '';
+  if (empty($rows)) {
+    $rows[] = array(array('data' => $form['#empty_text'], 'colspan' => '7'));
+  }
+  $output .= theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'skinr-context-ui-group-list')));
+  $output .= drupal_render_children($form);
+  return $output;
+}
+
+/**
+ * Form builder for the skinr settings group delete confirmation form.
+ *
+ * @param $group
+ *   Skinr settings group object.
+ *
+ * @ingroup forms
+ */
+function skinr_context_ui_group_delete_confirm($form, &$form_state, $group) {
+  $form['#group'] = $group;
+  $form['gid'] = array(
+    '#type' => 'value',
+    '#value' => $group->gid,
+  );
+
+  return confirm_form($form,
+    t('Are you sure you want to delete this skin settings group?'),
+    isset($_GET['destination']) ? $_GET['destination'] : 'admin/structure/skinr/edit/' . $group->module . '/' . $group->element,
+    t('This action cannot be undone.<br />Module: %module<br />Element: %element<br />Group: %group', array('%module' => $group->module, '%element' => $group->element, '%group' => $group->title)),
+    t('Delete'),
+    t('Cancel')
+  );
+}
+
+/**
+ * Form submission handler for skinr_context_ui_group_delete_confirm().
+ */
+function skinr_context_ui_group_delete_confirm_submit($form, &$form_state) {
+  if ($form_state['values']['confirm']) {
+    skinr_context_group_delete($form_state['values']['gid']);
+    watchdog('content', 'Deleted a skin settings group.');
+    drupal_set_message(t('A skin settings group has been deleted.'));
+  }
+
+  $group = $form['#group'];
+  $form_state['redirect'] = 'admin/structure/skinr/edit/' . $group->module . '/' . $group->element;
+}
+
+/**
+ * Menu callback; prepares some variables and displays a Skinr edit form.
+ *
+ * @param $module
+ *   The module that we're editing settings of.
+ * @param $element
+ *   The element of the object we're editing settings of.
+ * @param $elements
+ *   An array of $element when more than one is returned from the preprocess
+ *   index handler. Used by the javascript UI to update all elements involved.
+ */
+function skinr_context_ui_edit($module, $element, $group) {
+  // Set defaults.
+  $defaults = array();
+  $themes = list_themes();
+  foreach ($themes as $theme) {
+    if (!$theme->status) {
+      continue;
+    }
+
+    $params = array(
+      'theme' => $theme->name,
+      'module' => $module,
+      'element' => $element,
+      'gid' => $group->gid,
+    );
+    // Don't nest the call to skinr_skin_get_sids() in skinr_skin_load_multiple().
+    // If the prior functions returns no results, the second function will load
+    // ALL skins.
+    if ($sids = skinr_context_group_get_sids($params)) {
+      $skins = skinr_skin_load_multiple($sids);
+      foreach ($skins as $skin) {
+        $defaults[$theme->name][$skin->skin] = $skin->options;
+      }
+    }
+  }
+  return drupal_get_form('skinr_ui_form', array('module' => $module, 'element' => $element, 'gid' => $group->gid), $defaults);
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ */
+function skinr_context_ui_form_ctools_export_ui_edit_item_form_alter(&$form, &$form_state) {
+  if ($form['info']['tag']['#default_value'] == 'Skinr') {
+    // Prevent changing of required elements. For some reason if we disable the
+    // tag field directly it doesn't get submitted. So we make a disabled copy
+    // for display.
+    $form['info']['alt_tag'] = $form['info']['tag'];
+    $form['info']['alt_tag']['#disabled'] = TRUE;
+    // Add weight to description to ensure proper order.
+    $form['info']['description']['#weight'] = 1;
+    $form['info']['tag']['#type'] = 'hidden';
+
+    unset($form['reactions']);
+  }
+}
+
+/**
+ * Implements hook_form_alter().
+ */
+function skinr_context_ui_form_alter(&$form, $form_state, $form_id) {
+  // Fix for update script.
+  if ($form_id == 'update_script_selection_form') {
+    return;
+  }
+
+  // Ensure module and element values are set.
+  if (empty($form['skinr']['module']['#value']) || empty($form['skinr']['element']['#value'])) {
+    return;
+  }
+
+  // Check for access.
+  if (!skinr_ui_access('edit skin settings')) {
+    // Deny access.
+    return;
+  }
+
+  $group = skinr_context_group_load($form_state['build_info']['args'][0]['gid']);
+  $form['skinr']['gid'] = array(
+    '#type' => 'hidden',
+    '#value' => $group->gid,
+  );
+  $form['skinr_group'] = array(
+    '#tree' => TRUE,
+    '#type' => 'container',
+    // Move group settings to top.
+    '#weight' => -1,
+  );
+  $form['skinr_group']['title'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Group title'),
+    '#required' => TRUE,
+    '#default_value' => $group->title,
+    '#description' => t('Descriptive title for this skin settings group.'),
+  );
+  $form['skinr_group']['description'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Description'),
+    '#description' => t('A description for this group.'),
+  );
+
+  // Context form elements.
+  $context = skinr_context_group_to_context($group);
+
+  // Condition mode
+  $form['condition_mode'] = array(
+    '#type' => 'checkbox',
+    '#default_value' => isset($context->condition_mode) ? $context->condition_mode : FALSE,
+    '#title' => t('Require all conditions'),
+    '#description' => t('If checked, all conditions must be met for this context to be active. Otherwise, the first condition that is met will activate this context.')
+  );
+  // Condition plugin forms
+  $form['conditions'] = array(
+    '#theme' => 'context_ui_plugins',
+    '#title' => t('Conditions'),
+    '#description' => t('Trigger the activation of this context'),
+    '#tree' => TRUE,
+    'selector' => array(
+      '#type' => 'select',
+      '#options' => array(0 => '<'. t('Add a condition') .'>'),
+      '#default_value' => 0,
+    ),
+    'state' => array(
+      '#attributes' => array('class' => array('context-plugins-state')),
+      '#type' => 'hidden',
+    ),
+    'plugins' => array('#tree' => TRUE),
+  );
+
+  $conditions = array_keys(context_conditions());
+  sort($conditions);
+  foreach ($conditions as $condition) {
+    if ($plugin = context_get_plugin('condition', $condition)) {
+      $form['conditions']['plugins'][$condition] = array(
+        '#tree' => TRUE,
+        '#plugin' => $plugin,
+        '#context_enabled' => isset($context->conditions[$condition]), // This flag is used at the theme layer.
+        'values' => $plugin->condition_form($context),
+        'options' => $plugin->options_form($context),
+      );
+      $form['conditions']['selector']['#options'][$condition] = $plugin->title;
+    }
+  }
+
+  // Only add submit handler once.
+  if (isset($form['#submit']) && in_array('skinr_ui_form_submit', $form['#submit'])) {
+    foreach ($form['#submit'] as $key => $submit_handler) {
+      if ($submit_handler == 'skinr_ui_form_submit') {
+        $form['#submit'][$key] = 'skinr_context_ui_form_submit';
+      }
+    }
+  }
+}
+
+/**
+ * Form submission handler for skinr_context_form_alter().
+ */
+function skinr_context_ui_form_submit($form, &$form_state) {
+  $current_theme = skinr_current_theme(TRUE);
+
+  $module = $form_state['values']['module'];
+  $element = $form_state['values']['element'];
+  $gid = $form_state['values']['gid'];
+
+  // Save group settings.
+  // Load an uncached version of the skin settings group object.
+  $group = skinr_context_group_load_unchanged($gid);
+  // Let's save some time in skinr_context_group_save() by setting $group->original here.
+  $group->original = clone($group);
+
+  // Update status and weight.
+  $group->title = $form_state['values']['skinr_group']['title'];
+  $group->description = $form_state['values']['skinr_group']['description'];
+
+  // Update context.
+  if (!empty($form['conditions'])) {
+    $enabled = explode(',', $form_state['values']['conditions']['state']);
+    foreach ($form_state['values']['conditions']['plugins'] as $condition => $values) {
+      if (in_array($condition, $enabled, TRUE) && ($plugin = context_get_plugin('condition', $condition))) {
+        if (isset($values['values'])) {
+          $group->conditions[$condition]['values'] = $plugin->condition_form_submit($values['values']);
+        }
+        if (isset($values['options'])) {
+          $group->conditions[$condition]['options'] = $plugin->options_form_submit($values['options']);
+        }
+        if (context_empty($group->conditions[$condition]['values'])) {
+          unset($group->conditions[$condition]);
+        }
+      }
+      else {
+        unset($group->conditions[$condition]);
+      }
+    }
+  }
+
+  // Save group.
+  skinr_context_group_save($group);
+
+  // Save skin settings.
+  if (!empty($form_state['values']['skinr_settings'])) {
+    foreach ($form_state['values']['skinr_settings'] as $theme_name => $theme) {
+      // Process widgets.
+      if (!empty($theme) && is_array($theme)) {
+        foreach ($theme as $skin_name => $options) {
+          if ($skin_name == '_additional' && !user_access('edit advanced skin settings')) {
+            // This user doesn't have access to alter these options.
+            continue;
+          }
+
+          // Ensure options is an array.
+          if (!is_array($options)) {
+            $options = $skin_name == '_additional' ? explode(' ', $options) : array($options);
+          }
+          // Sanitize options.
+          $options = _skinr_array_strip_empty($options);
+
+          // Find existing skin.
+          $params = array(
+            'theme' => $theme_name,
+            'module' => $module,
+            'element' => $element,
+            'gid' => $gid,
+            'skin' => $skin_name,
+          );
+          $sids = skinr_context_group_get_sids($params);
+
+          unset($skin);
+          if (!empty($sids)) {
+            $sid = reset($sids);
+            $skin = skinr_skin_load($sid);
+          }
+
+          if (empty($options)) {
+            if (!empty($skin)) {
+              // Delete this skin setting.
+              skinr_skin_delete($skin->sid);
+            }
+            continue;
+          }
+
+          if (empty($skin)) {
+            // It doesn't exist, so create a new skin.
+            $skin = new stdClass();
+            $skin->theme = $theme_name;
+            $skin->module = $module;
+            $skin->element = $element;
+            $skin->gid = $gid;
+            $skin->skin = $skin_name;
+          }
+          $skin->options = $options;
+          $skin->status = 1;
+
+          // Save skin.
+          if (!skinr_skin_save($skin)) {
+            drupal_set_message(t("Skinr settings for %skin weren't saved due to an error.", array('%skin' => $skin_name)), 'error');
+          }
+        }
+      }
+    }
+  }
+}
+
+/**
+ * Implements hook_skinr_ui_filters_alter().
+ */
+function skinr_context_ui_skinr_ui_filters_alter(&$filters) {
+  $groups = skinr_context_group_load_multiple(FALSE);
+
+  $options = array('[any]' => t('any'));
+  foreach ($groups as $group) {
+    $options[$group->gid] = t('@group [gid: !gid]', array('@group' => $group->title, '!gid' => $group->gid));
+  }
+
+  $filters['gid'] = array(
+    'title' => t('group'),
+    'options' => $options,
+  );
+
+  // Reorder filters.
+  $skin = $filters['skin'];
+  unset($filters['skin']);
+  $filters['skin'] = $skin;
+
+  $status = $filters['status'];
+  unset($filters['status']);
+  $filters['status'] = $status;
+}
+
+/**
+ * Apply filters for skin configuration administration filters based on session.
+ *
+ * @param $query
+ *   A SelectQuery to which the filters should be applied.
+ */
+function skinr_context_ui_build_filter_query(SelectQueryInterface $query) {
+  // Build query
+  $filter_data = isset($_SESSION['skinr_ui_overview_filter']) ? $_SESSION['skinr_ui_overview_filter'] : array();
+  foreach ($filter_data as $index => $filter) {
+    list($key, $value) = $filter;
+    if ($key == 'gid') {
+      // Make exception for gid, which is in a different table.
+      $query->condition('gs.' . $key, $value);
+    }
+    else {
+      $query->condition('s.' . $key, $value);
+    }
+  }
+}
+
+/**
+ * Overrides skinr_ui_list().
+ *
+ * @see skinr_ui_list()
+ */
+function skinr_context_ui_skin_list($form, &$form_state) {
+  if (isset($form_state['values']['operation']) && $form_state['values']['operation'] == 'delete') {
+    return skinr_ui_multiple_delete_confirm($form, $form_state, array_filter($form_state['values']['skins']));
+  }
+  $form['filter'] = skinr_ui_filter_form();
+  $form['#submit'][] = 'skinr_ui_filter_form_submit';
+  $form['admin'] = skinr_context_ui_skin_list_subform();
+
+  return $form;
+}
+
+/**
+ * Overrides skinr_ui_admin_skins().
+ *
+ * @see skinr_ui_admin_skins()
+ */
+function skinr_context_ui_skin_list_subform() {
+  // Build the 'Update options' form.
+  $form['options'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Update options'),
+    '#attributes' => array('class' => array('container-inline')),
+  );
+  $options = array();
+  foreach (module_invoke_all('skinr_ui_operations') as $operation => $array) {
+    $options[$operation] = $array['label'];
+  }
+  $form['options']['operation'] = array(
+    '#type' => 'select',
+    '#title' => t('Operation'),
+    '#title_display' => 'invisible',
+    '#options' => $options,
+    '#default_value' => 'enable',
+  );
+  $form['options']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Update'),
+    '#validate' => array('skinr_ui_admin_skins_validate'),
+    '#submit' => array('skinr_ui_admin_skins_submit'),
+  );
+
+  $header = array(
+    'theme' => array('data' => t('Theme'), 'field' => 's.theme'),
+    'type' => array('data' => t('Type'), 'field' => 's.module'),
+    'group' => array('data' => t('Group'), 'field' => 'gs.gid'),
+    'element' => array('data' => t('Element ID'), 'field' => 's.element'),
+    'skin' => array('data' => t('Skin'), 'field' => 's.skin'),
+    'status' => array('data' => t('Status'), 'field' => 's.status'),
+    'operations' => array('data' => t('Operations')),
+  );
+
+  $query = db_select('skinr_skins', 's')->extend('PagerDefault')->extend('TableSort');
+  $query->join('skinr_group_skins', 'gs', 's.sid = gs.sid');
+  skinr_context_ui_build_filter_query($query);
+
+  $sids = $query
+    ->fields('s', array('sid'))
+    ->limit(50)
+    ->orderByHeader($header)
+    ->execute()
+    ->fetchCol();
+  $skins = skinr_skin_load_multiple($sids);
+
+  $themes = list_themes();
+  $skin_info = skinr_get_skin_info();
+  $destination = drupal_get_destination();
+  $options = array();
+  foreach ($skins as $skin) {
+    $operations = array(
+      'edit' => array(
+        'title' => t('edit'),
+        'href' => 'admin/structure/skinr/edit/' . $skin->module . '/' . $skin->element . '/' . $skin->gid,
+        'query' => $destination,
+      ),
+      'status' => array(
+        'title' => $skin->status ? t('disable') : t('enable'),
+        'href' => 'admin/structure/skinr/skin/' . $skin->sid . '/' . ($skin->status ? 'disable' : 'enable'),
+        'query' => $destination + array(
+          'token' => drupal_get_token('admin/structure/skinr/skin/' . $skin->sid . '/' . ($skin->status ? 'disable' : 'enable')),
+        ),
+      ),
+      'delete' => array(
+        'title' => t('delete'),
+        'href' => 'admin/structure/skinr/skin/' . $skin->sid . '/delete',
+        'query' => $destination,
+      ),
+    );
+    $group = skinr_context_group_load($skin->gid);
+    $options[$skin->sid] = array(
+      'theme' => isset($themes[$skin->theme]) ? $themes[$skin->theme]->info['name'] : '<em>' . $skin->theme . '</em>',
+      'type' => $skin->module,
+      'group' => t('@group [gid: !gid]', array('@group' => $group->title, '!gid' => $group->gid)),
+      'element' => $skin->element,
+      'skin' => $skin->skin == '_additional' ? '<em>' . t('Additional classes') . '</em>' : (isset($skin_info[$skin->skin]) ? $skin_info[$skin->skin]['title'] : '<em>' . $skin->skin . '</em>'),
+      'status' => $skin->status ? t('enabled') : t('disabled'),
+      'operations' => array(
+        'data' => array(
+          '#theme' => 'links__skinr_ui_operations',
+          '#links' => $operations,
+          '#attributes' => array('class' => array('links', 'inline')),
+        ),
+      ),
+    );
+  }
+
+  $form['skins'] = array(
+    '#type' => 'tableselect',
+    '#header' => $header,
+    '#options' => $options,
+    '#empty' => t('No content available.'),
+  );
+
+  $form['pager'] = array('#markup' => theme('pager'));
+  return $form;
+}
+
+/**
+ * Returns HTML for title and descrition info for the skin settings groups listing.
+ *
+ * @param $variables
+ *   An associative array containing:
+ *   - title: The group's title.
+ *   - description: The group's description.
+ *
+ * @ingroup themeable
+ */
+function theme_skinr_context_ui_group_summary($variables) {
+  $info = '<strong class="title">' . $variables['title'] . '</strong>';
+  if (!empty($variables['description'])) {
+    $info .= '<div class="description">' . $variables['description'] . '</div>';
+  }
+  return '<div class="skin-group-summary">' . $info . '</div>';
+}
diff --git a/skinr_context/tests/skinr_context.test b/skinr_context/tests/skinr_context.test
new file mode 100644
index 0000000000000000000000000000000000000000..3695d5b51d66e4a087dfdcd4460af8d45fecb15c
--- /dev/null
+++ b/skinr_context/tests/skinr_context.test
@@ -0,0 +1,239 @@
+<?php
+
+/**
+ * @file
+ * Tests for the Skinr Context module.
+ */
+
+/**
+ * Tests Skinr Context API functionality.
+ */
+class SkinrContextApiTestCase extends SkinrWebTestCase {
+  protected $profile = 'testing';
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Context',
+      'description' => 'Tests Skinr Context API functionality.',
+      'dependencies' => array('ctools', 'context'),
+      'group' => 'Skinr',
+    );
+  }
+
+  function setUp() {
+    parent::setUp(array('skinr', 'skinr_context', 'skinr_context_test'));
+  }
+
+  /**
+   * Test skinr_skin_save() against invalid entries.
+   */
+  public function testSkinrContextGroupLoadSave() {
+    // @todo Validation for groups.
+
+    // Only save valid groups.
+    $group = (object) array(
+      'module' => 'block',
+      'element' => 'system__user-menu',
+      'title' => 'Default',
+      'description' => '',
+      'conditions' => array('sitewide' => array('values' => array(1 => 1))),
+      'condition_mode' => CONTEXT_CONDITION_MODE_OR,
+      'weight' => 0,
+      'status' => 1,
+    );
+    $this->assertTrue(skinr_context_group_save($group), 'Skin settings group object saved.');
+    $this->assertTrue(isset($group->gid), 'Gid was added to skin settings group object.');
+
+    // Test loading a group.
+    $loaded_group = skinr_context_group_load($group->gid);
+    $this->assertTrue(is_array($loaded_group->conditions), 'Conditions for skin settings group object unserialized.');
+
+    $this->assertTrue($loaded_group->module == $group->module && $loaded_group->element == $group->element && $loaded_group->title == $group->title && $loaded_group->description == $group->description && $loaded_group->condition_mode == $group->condition_mode && $loaded_group->weight == $group->weight && $loaded_group->status == $group->status && isset($loaded_group->conditions['sitewide']) && isset($loaded_group->conditions['sitewide']['values']) && $loaded_group->conditions['sitewide']['values'][1] == $group->conditions['sitewide']['values'][1], 'Skin settings group object loaded properly.');
+
+    // Save a second group.
+    $second_group = (object) array(
+      'module' => 'block',
+      'element' => 'system__main-menu',
+      'title' => 'Default',
+      'description' => '',
+      'conditions' => array('sitewide' => array('values' => array(1 => 1))),
+      'condition_mode' => CONTEXT_CONDITION_MODE_OR,
+      'weight' => 0,
+      'status' => 1,
+    );
+    skinr_context_group_save($second_group);
+
+    // Test loading multiple groups.
+    $groups = skinr_context_group_load_multiple(array($group->gid, $second_group->gid));
+    $this->assertTrue(count($groups) == 2 && isset($groups[$group->gid]->gid) && isset($groups[$second_group->gid]->gid), 'Successfully loaded multiple skin settings groups.');
+
+    // Test loading all skin settings.
+    drupal_static_reset('skinr_context_group_load_multiple');
+    $groups = skinr_context_group_load_multiple(FALSE);
+    $this->assertTrue(count($groups) == 2 && isset($groups[$group->gid]->gid) && isset($groups[$second_group->gid]->gid), 'Successfully loaded all skin settings groups.');
+
+    // Test deleting groups.
+    $third_group = (object) array(
+      'module' => 'block',
+      'element' => 'system__main-menu',
+      'title' => 'Alternate',
+      'description' => '',
+      'conditions' => array('sitewide' => array('values' => array(1 => 1))),
+      'condition_mode' => CONTEXT_CONDITION_MODE_OR,
+      'weight' => 0,
+      'status' => 1,
+    );
+    $this->assertTrue(skinr_context_group_save($third_group), 'Skin settings group object saved.');
+
+    // Delete a single group.
+    $gid = $third_group->gid;
+    skinr_context_group_delete($gid);
+    $this->assertFalse(skinr_context_group_load($gid), 'Successfully deleted a skin settings group.');
+
+    // Delete multiple groups.
+    skinr_context_group_delete_multiple(array($group->gid, $second_group->gid));
+    $groups = skinr_context_group_load_multiple(FALSE);
+    $this->assertTrue(count($groups) == 0, 'Successfully deleted multiple skin settings groups.');
+  }
+
+  /**
+   * Test hook invocations for CRUD operations on skin settings groups.
+   */
+  public function testSkinrContextGroupHooks() {
+    $group = (object) array(
+      'module' => 'block',
+      'element' => 'system__user-menu',
+      'title' => 'Default',
+      'description' => '',
+      'conditions' => array('sitewide' => array('values' => array(1 => 1))),
+      'condition_mode' => CONTEXT_CONDITION_MODE_OR,
+      'weight' => 0,
+      'status' => 1,
+    );
+    $_SESSION['skinr_test'] = array();
+    skinr_context_group_save($group);
+    $this->verbose(highlight_string('<?php ' . var_export($group, TRUE), TRUE));
+    $this->verbose(highlight_string('<?php ' . var_export($_SESSION['skinr_context_test'], TRUE), TRUE));
+
+    $this->assertHookMessage('skinr_context_test_skinr_context_group_presave called');
+    $this->assertHookMessage('skinr_context_test_skinr_context_group_insert called');
+
+    $_SESSION['skinr_test'] = array();
+    $group = skinr_context_group_load($group->gid);
+
+    $this->assertHookMessage('skinr_context_test_skinr_context_group_load called');
+
+    $_SESSION['skinr_test'] = array();
+    $group = skinr_context_group_load_unchanged($group->gid);
+
+    $this->assertHookMessage('skinr_context_test_skinr_context_group_load called');
+
+    $_SESSION['skinr_test'] = array();
+    $group->status = 0;
+    skinr_context_group_save($group);
+
+    $this->assertHookMessage('skinr_context_test_skinr_context_group_presave called');
+    $this->assertHookMessage('skinr_context_test_skinr_context_group_update called');
+
+    $_SESSION['skinr_test'] = array();
+    skinr_context_group_delete($group->gid);
+
+    $this->assertHookMessage('skinr_context_test_skinr_context_group_delete called');
+  }
+}
+
+/**
+ * Tests API functionality.
+ *
+ * @link http://drupal.org/node/953336#comment-3738456 Make sure this patch is applied to drupal core @endlink
+ */
+class SkinrContextDisplayTestCase extends SkinrWebTestCase {
+  protected $profile = 'testing';
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Display',
+      'description' => 'Tests if applied skins appear on the front-end.',
+      'dependencies' => array('ctools', 'context'),
+      'group' => 'Skinr',
+    );
+  }
+
+  public function setUp() {
+    parent::setUp(array('block', 'skinr', 'skinr_context', 'skinr_test'));
+
+    $this->admin_user = $this->drupalCreateUser(array(
+      'administer blocks',
+    ));
+    $this->drupalLogin($this->admin_user);
+
+    // Enable main system block for content region and the user menu block for
+    // the first sidebar.
+    // @see http://drupal.org/node/913086
+    $default_theme = variable_get('theme_default', 'bartik');
+    db_merge('block')
+      ->key(array(
+        'theme' => $default_theme,
+        'module' => 'system',
+        'delta' => 'main',
+      ))
+      ->fields(array(
+        'status' => 1,
+        'region' => 'content',
+        'pages' => '',
+      ))
+      ->execute();
+    db_merge('block')
+      ->key(array(
+        'theme' => $default_theme,
+        'module' => 'system',
+        'delta' => 'user-menu',
+      ))
+      ->fields(array(
+        'status' => 1,
+        'region' => 'sidebar_first',
+        'pages' => '',
+      ))
+      ->execute();
+
+    // Enable Garland.
+    theme_enable(array('garland'));
+  }
+
+  public function testSkinrContextDisplayed() {
+    // Save a group.
+    $group = (object) array(
+      'module' => 'block',
+      'element' => 'system__main',
+      'title' => 'Default',
+      'description' => '',
+      'conditions' => array('path' => array('values' => array('<front>' => '<front>'))),
+      'condition_mode' => CONTEXT_CONDITION_MODE_OR,
+      'weight' => 0,
+      'status' => 1,
+    );
+    $this->assertTrue(skinr_context_group_save($group), 'Skin settings group object saved.');
+
+    // Save a skin configuration object.
+    $skin = (object) array(
+      'module' => 'block',
+      'element' => 'system__main',
+      'gid' => $group->gid,
+      'theme' => 'bartik',
+      'skin' => 'skinr_test_font',
+      'options' => array('font_1'),
+      'status' => 1,
+    );
+    $this->assertTrue(skinr_skin_save($skin), 'Skin configuration object was saved.');
+
+    // Go to the front page.
+    $this->drupalGet('');
+    $this->assertSkinrClass('block-system-main', 'font-1', 'CSS class of configured skin option found.');
+
+    // Check another page to make sure it only appears on the front page.
+    $this->drupalGet('user');
+    $this->assertNoSkinrClass('block-system-main', 'font-1', 'CSS class of configured skin option not found on other pages.');
+
+    // @todo Check for group B overriding group A.
+  }
+}
diff --git a/skinr_context/tests/skinr_context_test/skinr_context_test.info b/skinr_context/tests/skinr_context_test/skinr_context_test.info
new file mode 100644
index 0000000000000000000000000000000000000000..3ab6d898eff51ce732e2223bd1f7d50c06499a7e
--- /dev/null
+++ b/skinr_context/tests/skinr_context_test/skinr_context_test.info
@@ -0,0 +1,6 @@
+name = Skinr Context Testing
+description = A test module used for testing Skinr Context.
+package = Testing
+core = 7.x
+hidden = TRUE
+dependencies[] = skinr_context
diff --git a/skinr_context/tests/skinr_context_test/skinr_context_test.module b/skinr_context/tests/skinr_context_test/skinr_context_test.module
new file mode 100644
index 0000000000000000000000000000000000000000..b4785004b36bcc80fc94792dd003155b9abd62f5
--- /dev/null
+++ b/skinr_context/tests/skinr_context_test/skinr_context_test.module
@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * @file
+ * Skinr Context testing module.
+ */
+
+//
+// Presave hooks
+//
+
+/**
+ * Implements hook_skinr_context_group_presave().
+ */
+function skinr_context_test_skinr_context_group_presave() {
+  $_SESSION['skinr_test'][] = (__FUNCTION__ . ' called');
+}
+
+//
+// Insert hooks
+//
+
+/**
+ * Implements hook_skinr_context_group_insert().
+ */
+function skinr_context_test_skinr_context_group_insert() {
+  $_SESSION['skinr_test'][] = (__FUNCTION__ . ' called');
+}
+
+//
+// Load hooks
+//
+
+/**
+ * Implements hook_skinr_context_group_load().
+ */
+function skinr_context_test_skinr_context_group_load() {
+  $_SESSION['skinr_test'][] = (__FUNCTION__ . ' called');
+}
+
+//
+// Update hooks
+//
+
+/**
+ * Implements hook_skinr_context_group_update().
+ */
+function skinr_context_test_skinr_context_group_update() {
+  $_SESSION['skinr_test'][] = (__FUNCTION__ . ' called');
+}
+
+//
+// Delete hooks
+//
+
+/**
+ * Implements hook_skinr_context_group_delete().
+ */
+function skinr_context_test_skinr_context_group_delete() {
+  $_SESSION['skinr_test'][] = (__FUNCTION__ . ' called');
+}
diff --git a/skinr_context/tests/skinr_context_ui.test b/skinr_context/tests/skinr_context_ui.test
new file mode 100644
index 0000000000000000000000000000000000000000..09fbbbfd2ea93383935029caab4d0b1cc5a98ed7
--- /dev/null
+++ b/skinr_context/tests/skinr_context_ui.test
@@ -0,0 +1,175 @@
+<?php
+
+/**
+ * @file
+ * Tests for the Skinr UI module.
+ */
+
+/**
+ * Base class for Skinr UI tests.
+ */
+class SkinrContextUITestCase extends SkinrUITestCase {
+  protected $profile = 'testing';
+
+  function setUp() {
+    parent::setUp(array('skinr_context', 'skinr_context_ui'));
+  }
+}
+
+/**
+ * Tests UI functionality.
+ */
+class SkinrContextUIBasicTestCase extends SkinrContextUITestCase {
+  public static function getInfo() {
+    return array(
+      'name' => 'Context UI',
+      'description' => 'Tests basic Skinr Context UI functionality.',
+      'dependencies' => array('ctools', 'context', 'context_ui'),
+      'group' => 'Skinr',
+    );
+  }
+
+  /**
+   * Tests basic configuration and applying of a skin.
+   */
+  function testGroupList() {
+    // Add a group.
+    $group = (object) array(
+      'module' => 'block',
+      'element' => 'system__user-menu',
+      'title' => 'Default',
+      'description' => '',
+      'conditions' => array('sitewide' => array('values' => array(1 => 1))),
+      'condition_mode' => CONTEXT_CONDITION_MODE_OR,
+      'weight' => 0,
+      'status' => 1,
+    );
+    skinr_context_group_save($group);
+
+    $this->drupalGet('');
+    // Click the first (index 0) 'Edit skin' link on the page, which should be
+    // the link in the contextual links of the user menu block, since no other
+    // skinnable elements are visible on the page.
+    $this->clickLink(t('Edit skin'), 0);
+    // Verify that we end up on the expected URL.
+    $front = variable_get('site_frontpage', 'node');
+    $this->assertUrl('admin/structure/skinr/edit/block/system__user-menu/configure', array(
+      'query' => array('destination' => $front),
+    ));
+
+    // Make sure the group list is showing instead of the skin settings edit page.
+    $this->assertText('Skin settings group', 'Skin settings groups are listed.');
+
+    // Click the first 'edit' link which should bring us to the group's edit
+    // skin settings page.
+    $this->clickLink(t('edit'), 0);
+    // Verify that we end up on the expected URL to configure skins for our group.
+    $this->assertUrl('admin/structure/skinr/edit/block/system__user-menu/1', array(
+      'query' => array('destination' => 'admin/structure/skinr/edit/block/system__user-menu/configure?destination=' . $front),
+    ));
+
+    // Verify that we can apply the skinr_ui_test_border skin to the block, and
+    // limit the groups visibility to the front page.
+    $edit = array(
+      'skinr_group[title]' => 'SkinrContextGroupTitle',
+      'skinr_group[description]' => 'SkinrContextGroupDescription',
+      'skinr_settings[bartik][groups][general][skinr_ui_test_bgcolor]' => 'bgcolor_red',
+      'conditions[state]' => 'path',
+      'conditions[plugins][path][values]' => '<front>',
+    );
+    $this->drupalPost(NULL, $edit, t('Save'));
+
+    // Verify that we were redirected back to the originating page.
+    $this->assertUrl('admin/structure/skinr/edit/block/system__user-menu/configure', array(
+      'query' => array('destination' => $front),
+    ));
+
+    // Make sure the group title and description were updated.
+    $this->assertText('SkinrContextGroupTitle', 'Skin settings group title was updated.');
+    $this->assertText('SkinrContextGroupDescription', 'Skin settings group description was updated.');
+
+    // Click the done link.
+    $this->clickLink(t('Done'), 0);
+    // Verify that we were redirected to the originating page.
+    $this->assertUrl($front);
+
+    // Verify that the skin has been applied.
+    $this->assertSkinrClass('block-system-user-menu', 'bgcolor-red', 'CSS class of configured skin option found.');
+
+    // Verify that the skin has only been applied to the front page.
+    $this->drupalGet('user');
+    $this->assertNoSkinrClass('block-system-user-menu', 'bgcolor-red', 'CSS class of configured skin option not found on other pages.');
+  }
+
+  /**
+   * Tests adding a group to an element.
+   */
+  function testGroupAdd() {
+    $this->drupalGet('');
+    $this->clickLink(t('Edit skin'), 0);
+    // Verify that we end up on the expected URL.
+    $front = variable_get('site_frontpage', 'node');
+    $this->assertUrl('admin/structure/skinr/edit/block/system__user-menu/configure', array(
+      'query' => array('destination' => $front),
+    ));
+
+    // Make sure the add group link is present.
+    $this->assertLink('Add group', 0, 'Add group link is present.');
+
+    // Click on the 'Add group' link.
+    $this->clickLink(t('Add group'), 0);
+
+    // Verify that we end up on the expected URL to configure skins for our group.
+    $this->assertUrl('admin/structure/skinr/edit/block/system__user-menu/add', array(
+      'query' => array('destination' => 'admin/structure/skinr/edit/block/system__user-menu/configure?destination=' . $front),
+    ));
+
+    // Post the form.
+    $edit = array(
+      'title' => 'SkinrContextGroupTest',
+    );
+    $this->drupalPost(NULL, $edit, t('Add group'));
+
+    // Verify that we were redirected back to the originating page.
+    $this->assertUrl('admin/structure/skinr/edit/block/system__user-menu/configure', array(
+      'query' => array('destination' => $front),
+    ));
+
+    // Verify that the new group is added.
+    $this->assertText('SkinrContextGroupTest', 'Successfully added a skin settings group.');
+  }
+
+  /**
+   * Tests skin configuration listing functionality.
+   */
+  function testSkinListingWithGroups() {
+    $group = (object) array(
+      'module' => 'block',
+      'element' => 'system__user-menu',
+      'title' => 'SkinListingWithGroup',
+      'description' => '',
+      'conditions' => array('sitewide' => array('values' => array(1 => 1))),
+      'condition_mode' => CONTEXT_CONDITION_MODE_OR,
+      'weight' => 0,
+      'status' => 1,
+    );
+    skinr_context_group_save($group);
+
+    $skin = (object) array(
+      'theme' => 'skinr_test_subtheme',
+      'module' => 'block',
+      'element' => 'system__user-menu',
+      'gid' => $group->gid,
+      'skin' => 'skinr_test_subtheme',
+      'options' => array('option1', 'option2'),
+      'status' => 1,
+    );
+    skinr_skin_save($skin);
+
+    // Verify that the skin configuration appears on the skin configurations overview page.
+    $this->drupalGet('admin/structure/skinr');
+    $this->assertLinkByHref('admin/structure/skinr/edit/' . $skin->module . '/' . $skin->element . '/' . $skin->gid, 0, 'Skin configuration was found on overview page.');
+
+    // @todo Should we check the filtering and update options functionality?
+  }
+}
diff --git a/skinr_panels/skinr_panels.module b/skinr_panels/skinr_panels.module
index 4691248968ef55cb1825ab8ce051d46630c9bd95..8bd093c73340d703747e5803b58ed78fc7f5dad4 100644
--- a/skinr_panels/skinr_panels.module
+++ b/skinr_panels/skinr_panels.module
@@ -62,14 +62,14 @@ function skinr_panels_preprocess(&$variables, $hook) {
 
     foreach ($elements as $element) {
       $contextual_links['skinr-' .  $module . '-' . $counter++] = array(
-        'admin/structure/skinr/edit/nojs', array($module, $element),
+        'admin/structure/skinr/edit', array($module, $element),
       );
     }
     if (!empty($contextual_links)) {
       // Need to set contextual links through  Skinr API so we have a valid, and
       // consistent, link title. It's also used in our hook_preprocess_links()
       // hack.
-      _skinr_ui_set_contextual_links($hook, $contextual_links);
+      _skinr_panels_set_contextual_links($hook, $contextual_links);
 
       // Render links.
       $element = array(
@@ -90,6 +90,34 @@ function skinr_panels_preprocess(&$variables, $hook) {
 }
 
 /**
+ * Get all contextual links as returned from Skinr's contextual links handler.
+ *
+ * @return
+ *   An array of contextual links data.
+ */
+function skinr_panels_get_contextual_links() {
+  return _skinr_panels_set_contextual_links();
+}
+
+/**
+ * Store contextual links internally for future use.
+ *
+ * @return
+ *   An array of contextual links data.
+ */
+function _skinr_panels_set_contextual_links($hook = NULL, $links = NULL) {
+  static $contextual_links = array();
+
+  if ($hook && $links) {
+    if (!isset($contextual_links[$hook])) {
+      $contextual_links[$hook] = $links;
+    }
+  }
+
+  return $contextual_links;
+}
+
+/**
  * Implements hook_preprocess_links().
  *
  * This hack is panels on panel pages only.
@@ -97,7 +125,7 @@ function skinr_panels_preprocess(&$variables, $hook) {
 function skinr_panels_preprocess_links(&$variables, $hook) {
   if (isset($variables['links'][0]['title']) && $variables['links'][0]['title'] == t('Edit @type', array('@type' => 'Panel')) && user_access('edit skin settings')) {
     // Get contextual links.
-    $contextual_links = skinr_ui_get_contextual_links();
+    $contextual_links = skinr_panels_get_contextual_links();
     if (isset($contextual_links['panels_pane'])) {
       $contextual_links = $contextual_links['panels_pane'];
 
diff --git a/skinr_panels/tests/skinr_panels.test b/skinr_panels/tests/skinr_panels.test
index 7923cbb5f780d1809fbd8434054cc91c2ae2d824..8d9f2c0fb197cdf85a9d3c0350325977f6570588 100644
--- a/skinr_panels/tests/skinr_panels.test
+++ b/skinr_panels/tests/skinr_panels.test
@@ -52,7 +52,7 @@ class SkinrPanelsTestCase extends DrupalWebTestCase {
     $this->drupalGet('skinr-panels-test-panel');
 
     // Make sure our contextual link appears on the page.
-    $this->assertLinkByHref('admin/structure/skinr/edit/nojs/panels/pane__1__1/configure', 0, "Contexual link to edit pane's skin configuration on panel page (stored in code) was found.");
+    $this->assertLinkByHref('admin/structure/skinr/edit/panels/pane__1__1/configure', 0, "Contexual link to edit pane's skin configuration on panel page (stored in code) was found.");
 
 
     $this->drupalGet('admin/structure/mini-panels');
@@ -78,7 +78,7 @@ class SkinrPanelsTestCase extends DrupalWebTestCase {
 
     // Make sure our contextual link appears on the page.
     // @todo Is there a better way to determine did and pid used for this panel?
-    $this->assertLinkByHref('admin/structure/skinr/edit/nojs/panels/pane__2__2/configure', 0, 'Contexual link to edit pane\'s skin configuration on mini panel (stored in code) was found.');
+    $this->assertLinkByHref('admin/structure/skinr/edit/panels/pane__2__2/configure', 0, 'Contexual link to edit pane\'s skin configuration on mini panel (stored in code) was found.');
   }
 
   /**
@@ -107,7 +107,7 @@ class SkinrPanelsTestCase extends DrupalWebTestCase {
 
     // Make sure our contextual link appears on the page.
     // @todo Is there a better way to determine did and pid used for this panel?
-    $this->assertLinkByHref('admin/structure/skinr/edit/nojs/panels/pane__1__1/configure', 0, 'Contexual link to edit pane\'s skin configuration on panel node was found.');
+    $this->assertLinkByHref('admin/structure/skinr/edit/panels/pane__1__1/configure', 0, 'Contexual link to edit pane\'s skin configuration on panel node was found.');
 
 
     // Test panels pages.
@@ -120,7 +120,7 @@ class SkinrPanelsTestCase extends DrupalWebTestCase {
     $this->drupalGet('skinr-panels-test-panel');
 
     // Make sure our contextual link appears on the page.
-    $this->assertLinkByHref('admin/structure/skinr/edit/nojs/panels/pane__2__2/configure', 0, "Contexual link to edit pane's skin configuration on panel page (stored in DB) was found.");
+    $this->assertLinkByHref('admin/structure/skinr/edit/panels/pane__2__2/configure', 0, "Contexual link to edit pane's skin configuration on panel page (stored in DB) was found.");
 
 
     // Test mini panels.
@@ -148,6 +148,6 @@ class SkinrPanelsTestCase extends DrupalWebTestCase {
 
     // Make sure our contextual link appears on the page.
     // @todo Is there a better way to determine did and pid used for this panel?
-    $this->assertLinkByHref('admin/structure/skinr/edit/nojs/panels/pane__3__3/configure', 0, 'Contexual link to edit pane\'s skin configuration on mini panel (stored in DB) was found.');
+    $this->assertLinkByHref('admin/structure/skinr/edit/panels/pane__3__3/configure', 0, 'Contexual link to edit pane\'s skin configuration on mini panel (stored in DB) was found.');
   }
 }
diff --git a/skinr_ui.admin.inc b/skinr_ui.admin.inc
index 5fbe937683b54471566b198d7468c03044e02390..bad0c54f122dcd594f8dc22587e534ee40a427dc 100644
--- a/skinr_ui.admin.inc
+++ b/skinr_ui.admin.inc
@@ -22,11 +22,19 @@ function skinr_ui_skin_status_set($skin, $status) {
   // Update the status and save the skin configuration.
   $skin->status = $status ? 1 : 0;
   skinr_skin_save($skin);
-  if ($status) {
-    drupal_set_message(t('Skin configuration has been enabled.'));
+
+  // The skinr_context module, for instance, prevents enabling a skin in some
+  // cases. So check for it.
+  if ($skin->status == $status) {
+    if ($status) {
+      drupal_set_message(t('Skin configuration has been enabled.'));
+    }
+    else {
+      drupal_set_message(t('Skin configuration has been disabled.'));
+    }
   }
   else {
-    drupal_set_message(t('Skin configuration has been disabled.'));
+    drupal_set_message(t('Changing skin configuration status failed.'), 'warning');
   }
 
   // Return to the skin configuration overview page.
@@ -116,6 +124,9 @@ function skinr_ui_filters() {
     ),
   );
 
+  // Allow modules to add filters.
+  drupal_alter('skinr_ui_filters', $filters);
+
   return $filters;
 }
 
@@ -414,7 +425,7 @@ function skinr_ui_admin_skins() {
     $operations = array(
       'edit' => array(
         'title' => t('edit'),
-        'href' => 'admin/structure/skinr/edit/nojs/' . $skin->module . '/' . $skin->element,
+        'href' => 'admin/structure/skinr/edit/' . $skin->module . '/' . $skin->element,
         'query' => $destination,
       ),
       'status' => array(
@@ -619,7 +630,7 @@ function skinr_ui_admin_library_form($form, $form_state, $theme) {
     $extra = array();
 
     // Set status.
-    $extra['enabled'] = $skin_info['status'][$theme];
+    $extra['enabled'] = !empty($skin_info['status'][$theme]) ? $skin_info['status'][$theme] : 0;
 
     // Create a row entry for this skin.
     $group = $groups[$skin_info['group']]['title'];
diff --git a/skinr_ui.module b/skinr_ui.module
index 68c4cf28d8bb22b97185db1f5a5f025d834682c5..3f8e660c45fceae409e1f25bdcbc6698d05105c5 100644
--- a/skinr_ui.module
+++ b/skinr_ui.module
@@ -46,7 +46,7 @@ function skinr_ui_access($string, $account = NULL) {
 function skinr_ui_menu() {
   $items['admin/structure/skinr'] = array(
     'title' => 'Skinr',
-    'description' => 'Manage your skin configurations and rules, import and export skin configurations.',
+    'description' => 'Manage your skin configurations and import/export skin configurations.',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('skinr_ui_list'),
     'access arguments' => array('administer skinr'),
@@ -82,41 +82,6 @@ function skinr_ui_menu() {
     );
   }
 
-  // Rules.
-  $items['admin/structure/skinr/rules'] = array(
-    'title' => 'Rules',
-    'page callback' => 'skinr_rules',
-    'type' => MENU_LOCAL_TASK,
-    'access arguments' => array('administer skinr'),
-    'weight' => 1,
-    'description' => t('Configure region and page level Skinr rules.'),
-    'file' => 'skinr_ui.rules.inc',
-  );
-  $items['admin/structure/skinr/rules/add'] = array(
-    'title' => 'Create a new rule',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('skinr_rule_add'),
-    'type' => MENU_LOCAL_ACTION,
-    'access arguments' => array('administer skinr'),
-    'file' => 'skinr_ui.rules.inc',
-  );
-  $items['admin/structure/skinr/rules/%skinr_rule/edit'] = array(
-    'title' => 'Edit rule',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('skinr_rule_edit', 4),
-    'type' => MENU_CALLBACK,
-    'access arguments' => array('administer skinr'),
-    'file' => 'skinr_ui.rules.inc',
-  );
-  $items['admin/structure/skinr/rules/%skinr_rule/delete'] = array(
-    'title' => 'Delete rule',
-    'page callback' => 'drupal_get_form',
-    'page arguments' => array('skinr_rule_delete_confirm', 4),
-    'type' => MENU_CALLBACK,
-    'access arguments' => array('administer skinr'),
-    'file' => 'skinr_ui.rules.inc',
-  );
-
   // Import & Export.
   $items['admin/structure/skinr/import'] = array(
     'title' => 'Import',
@@ -140,20 +105,18 @@ function skinr_ui_menu() {
   );
 
   // Configure skin settings for an element.
-  $items['admin/structure/skinr/edit/%skinr_js/%/%'] = array(
+  $items['admin/structure/skinr/edit/%/%'] = array(
     'title' => 'Edit skin',
     'title callback' => 'skinr_ui_edit_title',
-    'title arguments' => array(5, 6),
+    'title arguments' => array(4, 5),
     'page callback' => 'skinr_ui_edit',
-    'page arguments' => array(4, 5, 6), // js|nojs, module, element
+    'page arguments' => array(4, 5), // module, element
     'type' => MENU_CALLBACK,
     'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
     'access arguments' => array('edit skin settings'),
   );
-  $items['admin/structure/skinr/edit/%skinr_js/%/%/configure'] = array(
+  $items['admin/structure/skinr/edit/%/%/configure'] = array(
     'title' => 'Edit skin',
-    'title callback' => 'skinr_ui_edit_contextual_title',
-    'title arguments' => array(5, 6),
     'type' => MENU_DEFAULT_LOCAL_TASK,
     'context' => MENU_CONTEXT_INLINE,
   );
@@ -192,16 +155,6 @@ function skinr_ui_menu() {
 }
 
 /**
- * Helper function to determine if ajax is used to call a function.
- */
-function skinr_js_load($js = 'nojs') {
-  if ($js == 'ajax') {
-    return TRUE;
-  }
-  return 0;
-}
-
-/**
  * Menu item access callback - only admin or enabled themes can be accessed.
  */
 function _skinr_ui_themes_access($theme) {
@@ -238,21 +191,13 @@ function skinr_ui_help($path, $arg) {
   switch ($path) {
     case 'admin/structure/skinr':
       return  '<p>' . t('Below is a list of all skin configurations in use on this site.') . '</p>' . $advanced_help;
-    case 'admin/structure/skinr/rule':
-      return  '<p>' . t('Below is a list of Skinr rules. Rules can be created for <em>region</em> and <em>page</em> elements.  Start by creating a new rule.') . '</p>';
-    case 'admin/structure/skinr/rule/add':
-      return  '<p>' . t('Choose the type of rule you wish to create. Page rules apply classes to the &lt;body&gt; tag. Region rules apply to the region wrapper &lt;div&gt; tag.') . '</p>';
     case 'admin/structure/skinr/import':
       return  '<p>' . t('To import skin configurations, paste exported code and click the "Import" button.') . '</p>';
     case 'admin/structure/skinr/export':
       return  '<p>' . t('To export skin configurations, ensure the correct theme is selected and click the "Export" button.') . '</p>';
-    case 'admin/structure/skinr/edit/%/%/%':
-      // @todo Make this help text more relevant.
-      $theme_hooks = skinr_theme_hooks($arg[5], $arg[6]);
-      return  '<p>' . t('Manage which skins you want to apply to the hooks <strong>!hooks</strong>.', array('!hooks' => implode(', ', $theme_hooks))) . '</p>';
-    case 'admin/structure/skinr/rules/%/edit':
+    case 'admin/structure/skinr/edit/%/%':
       // @todo Make this help text more relevant.
-      $theme_hooks = skinr_theme_hooks('rules', $arg[4]);
+      $theme_hooks = skinr_theme_hooks($arg[4], $arg[5]);
       return  '<p>' . t('Manage which skins you want to apply to the hooks <strong>!hooks</strong>.', array('!hooks' => implode(', ', $theme_hooks))) . '</p>';
   }
 }
@@ -270,84 +215,73 @@ function skinr_ui_edit_title($module, $element) {
 }
 
 /**
- * Menu title callback; sets the title for a skins configuration form page.
- *
- * @param $module
- *   The module that we're editing settings for.
- * @param $element
- *   The element we're editing settings for.
- */
-function skinr_ui_edit_contextual_title($module, $element) {
-  $contextual_links = skinr_ui_get_contextual_links();
-  foreach ($contextual_links as $hook => $links) {
-    $counter = 1;
-    foreach ($links as $link) {
-      if ($link[1][0] == $module && $link[1][1] == $element) {
-        if (count($links) > 1) {
-          return t('Edit skin !number', array('!number' => $counter++));
-        }
-        break 2;
-      }
-    }
-  }
-  return t('Edit skin');
-}
-
-/**
  * Menu callback; prepares some variables and displays a Skinr edit form.
  *
- * @param $js
- *   TRUE if called from javascript, FALSE otherwise.
  * @param $module
  *   The module that we're editing settings of.
  * @param $element
  *   The element of the object we're editing settings of.
- * @param $elements
- *   An array of $element when more than one is returned from the preprocess
- *   index handler. Used by the javascript UI to update all elements involved.
  */
-function skinr_ui_edit($js = FALSE, $module, $element, $elements = NULL) {
-  if ($js) {
-    // Do additional ajax related stuff.
-  }
+function skinr_ui_edit($module, $element) {
+  // Set defaults.
+  $defaults = array();
+  $themes = list_themes();
+  foreach ($themes as $theme) {
+    if (!$theme->status) {
+      continue;
+    }
 
-  $arguments = array(
-    'skinr' => array(
+    $params = array(
+      'theme' => $theme->name,
       'module' => $module,
       'element' => $element,
-      'elements' => $elements,
-    ),
-  );
-  return drupal_get_form('skinr_ui_form', $arguments);
+    );
+    // Don't nest the call to skinr_skin_get_sids() in skinr_skin_load_multiple().
+    // If the prior functions returns no results, the second function will load
+    // ALL skins.
+    if ($sids = skinr_skin_get_sids($params)) {
+      $skins = skinr_skin_load_multiple($sids);
+      foreach ($skins as $skin) {
+        $defaults[$theme->name][$skin->skin] = $skin->options;
+      }
+    }
+  }
+  return drupal_get_form('skinr_ui_form', array('module' => $module, 'element' => $element), $defaults);
 }
 
 /**
  * Form builder for the skins configuration form.
  *
- * @param $arguments
- *   An array of arguments as passed in by skinr_ui_edit().
+ * @param $module
+ *   The module that we're editing settings of.
+ * @param $element
+ *   The element of the object we're editing settings of.
+ * @param $defaults
+ *   An array of default values keyed by theme name.
  *
  * @ingroup forms
  */
-function skinr_ui_form($form, &$form_state, $arguments) {
+function skinr_ui_form($form, &$form_state, $arguments, $defaults) {
+  // Set arguments.
+  $module = $arguments['module'];
+  $element = $arguments['element'];
+
+  // Set default values.
+  $form_state['values']['skinr_settings'] = $defaults;
+
+  // Build form.
   $form = array(
     '#attributes' => array('class' => 'skinr-form'),
   );
 
   $form['skinr']['module'] = array(
     '#type' => 'hidden',
-    '#value' => !empty($form_state['skinr']['module']) ? $form_state['skinr']['module'] : $arguments['skinr']['module'],
+    '#value' => $module,
   );
   $form['skinr']['element'] = array(
     '#type' => 'hidden',
-    '#value' => !empty($form_state['skinr']['element']) ? $form_state['skinr']['element'] : $arguments['skinr']['element'],
+    '#value' => $element,
   );
-  if (!empty($form_state['skinr']['elements']) || !empty($arguments['skinr']['elements'])) {
-    $form['skinr']['elements'] = array(
-      '#type' => 'hidden',
-      '#value' => !empty($form_state['skinr']['elements']) ? $form_state['skinr']['elements'] : $arguments['skinr']['elements'],
-    );
-  }
 
   $form['actions'] = array('#type' => 'actions');
   $form['actions']['submit'] = array(
@@ -395,7 +329,8 @@ function skinr_ui_form_alter(&$form, $form_state, $form_id) {
 
   $form['skinr_settings'] = array(
     '#tree' => TRUE,
-    // Set weight to accommodate Rules UI.
+    '#type' => 'container',
+    // Move settings to top.
     '#weight' => 0,
   );
 
@@ -422,42 +357,11 @@ function skinr_ui_form_alter(&$form, $form_state, $form_id) {
       }
     }
 
-    if (!$form_state['submitted']) {
-      $params = array(
-        'theme' => $theme->name,
-        'module' => $module,
-        'element' => $element,
-      );
-      if ($skins = skinr_skin_load_multiple(skinr_skin_get_sids($params))) {
-        $defaults = array();
-        foreach ($skins as $skin) {
-          $defaults[$skin->skin] = $skin->options;
-        }
-      }
-      else {
-        $defaults = array();
-      }
-    }
-    else {
-      // Handle preview before submit.
-      // @todo Is this still needed? If so, it needs to be fixed.
-      $defaults = $form_state['values'];
-    }
-
-    if (!isset($form['skinr_settings'][$module . '_type'])) {
-      $form['skinr_settings'][$module . '_type'] = array(
-        '#type' => 'container',
-      );
-      if ($module == 'rules') {
-        $form['skinr_settings']['skinr_settings_title'] = array(
-          '#type' => 'item',
-          '#title' => t('Skinr settings'),
-          '#weight' => -1,
-        );
-      }
-    }
+    // Load defaults for theme sub-form.
+    $defaults = isset($form_state['values']['skinr_settings']) ? $form_state['values']['skinr_settings'] : array();
 
-    $form['skinr_settings'][$module . '_type'][$theme->name] = array(
+    // Build theme sub-form.
+    $form['skinr_settings'][$theme->name] = array(
       '#type' => 'fieldset',
       '#title' => $theme->info['name'] . ($theme->name == $current_theme ? ' (' . t('enabled + default') . ')' : ''),
       '#collapsible' => TRUE,
@@ -465,11 +369,11 @@ function skinr_ui_form_alter(&$form, $form_state, $form_id) {
     );
     if ($theme->name == $current_theme) {
       // Current theme goes at the top.
-      $form['skinr_settings'][$module . '_type'][$theme->name]['#attributes'] = array('class' => array('skinr-ui-current-theme'));
-      $form['skinr_settings'][$module . '_type'][$theme->name]['#weight'] = -10;
+      $form['skinr_settings'][$theme->name]['#attributes'] = array('class' => array('skinr-ui-current-theme'));
+      $form['skinr_settings'][$theme->name]['#weight'] = -10;
 
       // Use vertical tabs.
-      $form['skinr_settings'][$module . '_type'][$theme->name]['groups'] = array(
+      $form['skinr_settings'][$theme->name]['groups'] = array(
         '#type' => 'vertical_tabs',
       );
     }
@@ -514,7 +418,7 @@ function skinr_ui_form_alter(&$form, $form_state, $form_id) {
               '#multiple' => TRUE,
               '#title' => t($skin_info['title']),
               '#options' => skinr_ui_info_options_to_form_options($skin_info['options']),
-              '#default_value' => isset($defaults[$skin_name]) ? $defaults[$skin_name] : array(),
+              '#default_value' => isset($defaults[$theme->name][$skin_name]) ? $defaults[$theme->name][$skin_name] : array(),
               '#description' => t($skin_info['description']),
               '#weight' => isset($skin_info['weight']) ? $skin_info['weight'] : NULL,
             );
@@ -524,7 +428,7 @@ function skinr_ui_form_alter(&$form, $form_state, $form_id) {
               '#type' => 'radios',
               '#title' => t($skin_info['title']),
               '#options' => array_merge(array('' => '&lt;none&gt;'), skinr_ui_info_options_to_form_options($skin_info['options'])),
-              '#default_value' => isset($defaults[$skin_name]) ? $defaults[$skin_name] : '',
+              '#default_value' => isset($defaults[$theme->name][$skin_name]) ? $defaults[$theme->name][$skin_name] : '',
               '#description' => t($skin_info['description']),
               '#weight' => isset($skin_info['weight']) ? $skin_info['weight'] : NULL,
             );
@@ -534,7 +438,7 @@ function skinr_ui_form_alter(&$form, $form_state, $form_id) {
               '#type' => 'select',
               '#title' => t($skin_info['title']),
               '#options' => array_merge(array('' => '<none>'), skinr_ui_info_options_to_form_options($skin_info['options'])),
-              '#default_value' => isset($defaults[$skin_name]) ? $defaults[$skin_name] : '',
+              '#default_value' => isset($defaults[$theme->name][$skin_name]) ? $defaults[$theme->name][$skin_name] : '',
               '#description' => t($skin_info['description']),
               '#weight' => isset($skin_info['weight']) ? $skin_info['weight'] : NULL,
             );
@@ -546,36 +450,36 @@ function skinr_ui_form_alter(&$form, $form_state, $form_id) {
         }
       }
       if (empty($skin_info['group']) || empty($groups[$skin_info['group']])) {
-        $form['skinr_settings'][$module . '_type'][$theme->name][$skin_name] = $field;
+        $form['skinr_settings'][$theme->name][$skin_name] = $field;
       }
       else {
-        if (!empty($field) && !isset($form['skinr_settings'][$module . '_type'][$theme->name]['groups'][$skin_info['group']])) {
+        if (!empty($field) && !isset($form['skinr_settings'][$theme->name]['groups'][$skin_info['group']])) {
           $group = $groups[$skin_info['group']];
-          $form['skinr_settings'][$module . '_type'][$theme->name]['groups'][$skin_info['group']] = array(
+          $form['skinr_settings'][$theme->name]['groups'][$skin_info['group']] = array(
             '#type' => 'fieldset',
             '#title' => t($group['title']),
             '#description' => t($group['description']),
             '#weight' => isset($group['weight']) ? $group['weight'] : NULL,
           );
         }
-        $form['skinr_settings'][$module . '_type'][$theme->name]['groups'][$skin_info['group']][$skin_name] = $field;
+        $form['skinr_settings'][$theme->name]['groups'][$skin_info['group']][$skin_name] = $field;
       }
     }
 
     // Check for access.
     if (skinr_ui_access('edit advanced skin settings')) {
       $skin_name = '_additional';
-      $form['skinr_settings'][$module . '_type'][$theme->name]['groups']['_additional'] = array(
+      $form['skinr_settings'][$theme->name]['groups']['_additional'] = array(
         '#type' => 'fieldset',
         '#title' => t('Advanced'),
         '#weight' => 50,
       );
-      $form['skinr_settings'][$module . '_type'][$theme->name]['groups']['_additional']['_additional'] = array(
+      $form['skinr_settings'][$theme->name]['groups']['_additional']['_additional'] = array(
         '#type' => 'textfield',
         '#title' => t('CSS classes'),
         '#size' => 40,
         '#description' => t('To add CSS classes manually, enter classes separated by a single space i.e. <code>first-class second-class</code>'),
-        '#default_value' => isset($defaults[$skin_name]) ? $defaults[$skin_name] : '',
+        '#default_value' => isset($defaults[$theme->name][$skin_name]) ? $defaults[$theme->name][$skin_name] : '',
       );
     }
   }
@@ -599,12 +503,12 @@ function skinr_ui_form_validate($form, &$form_state) {
   $element = $form_state['values']['element'];
 
   $error = FALSE;
-  if (isset($form_state['values']['skinr_settings'][$module . '_type'])) {
-    foreach ($form_state['values']['skinr_settings'][$module . '_type'] as $theme_name => $theme) {
+  if (isset($form_state['values']['skinr_settings'])) {
+    foreach ($form_state['values']['skinr_settings'] as $theme_name => $theme) {
       if (isset($theme['groups']['_additional']['_additional'])) {
         // Validate additional classes field.
         if (preg_match('/[^a-zA-Z0-9\-\_\s]/', $theme['groups']['_additional']['_additional'])) {
-          form_set_error('skinr_settings][' . $module . '_type][' . $theme_name . '][groups][_additional][_additional', t('Additional classes for Skinr may only contain alphanumeric characters, spaces, - and _.'));
+          form_set_error('skinr_settings][' . $theme_name . '][groups][_additional][_additional', t('Additional classes for Skinr may only contain alphanumeric characters, spaces, - and _.'));
           $error = TRUE;
         }
       }
@@ -613,12 +517,19 @@ function skinr_ui_form_validate($form, &$form_state) {
 
   if (!$error) {
     $groups = skinr_get_group_info();
-    if (isset($form_state['values']['skinr_settings'][$module . '_type'])) {
-      foreach ($form_state['values']['skinr_settings'][$module . '_type'] as $theme_name => $theme) {
+    // Add hard-coded additional classes group.
+    $groups['_additional'] = array(
+      'title' => 'Additional',
+      'description' => 'Additional custom classes.',
+      'weight' => 0,
+    );
+
+    if (!empty($form_state['values']['skinr_settings'])) {
+      foreach ($form_state['values']['skinr_settings'] as $theme_name => $theme) {
         // Unset active tab variables.
         foreach ($theme['groups'] as $skin_name => $options) {
           if (strpos($skin_name, '__groups__active_tab') !== FALSE) {
-            unset($form_state['values']['skinr_settings'][$module . '_type'][$theme_name]['groups'][$skin_name]);
+            unset($form_state['values']['skinr_settings'][$theme_name]['groups'][$skin_name]);
             continue;
           }
         }
@@ -626,10 +537,11 @@ function skinr_ui_form_validate($form, &$form_state) {
         foreach ($groups as $group_name => $group) {
           if (!empty($theme['groups'][$group_name]) && is_array($theme['groups'][$group_name])) {
             $group_values = $theme['groups'][$group_name];
-            unset($form_state['values']['skinr_settings'][$module . '_type'][$theme_name]['groups'][$group_name]);
-            $form_state['values']['skinr_settings'][$module . '_type'][$theme_name]['groups'] = array_merge($form_state['values']['skinr_settings'][$module . '_type'][$theme_name]['groups'], $group_values);
+            unset($form_state['values']['skinr_settings'][$theme_name]['groups'][$group_name]);
+            $form_state['values']['skinr_settings'][$theme_name] = array_merge($form_state['values']['skinr_settings'][$theme_name], $group_values);
           }
         }
+        unset($form_state['values']['skinr_settings'][$theme_name]['groups']);
       }
     }
   }
@@ -644,11 +556,11 @@ function skinr_ui_form_submit($form, &$form_state) {
   $module = $form_state['values']['module'];
   $element = $form_state['values']['element'];
 
-  if (isset($form_state['values']['skinr_settings'][$module . '_type'])) {
-    foreach ($form_state['values']['skinr_settings'][$module . '_type'] as $theme_name => $theme) {
+  if (!empty($form_state['values']['skinr_settings'])) {
+    foreach ($form_state['values']['skinr_settings'] as $theme_name => $theme) {
       // Process widgets.
-      if (!empty($theme['groups']) && is_array($theme['groups'])) {
-        foreach ($theme['groups'] as $skin_name => $options) {
+      if (!empty($theme) && is_array($theme)) {
+        foreach ($theme as $skin_name => $options) {
           if ($skin_name == '_additional' && !user_access('edit advanced skin settings')) {
             // This user doesn't have access to alter these options.
             continue;
@@ -721,7 +633,7 @@ function skinr_ui_preprocess(&$variables, $hook) {
   foreach ($array_elements as $module => $elements) {
     foreach ($elements as $element) {
       $contextual_links['skinr-' .  $module . '-' . $counter++] = array(
-        'admin/structure/skinr/edit/nojs', array($module, $element),
+        'admin/structure/skinr/edit', array($module, $element),
       );
     }
   }
@@ -743,8 +655,6 @@ function skinr_ui_preprocess(&$variables, $hook) {
  *   links handler.
  */
 function skinr_ui_contextual_links(&$variables, $hook, $contextual_links) {
-  _skinr_ui_set_contextual_links($hook, $contextual_links);
-
   $hooks = theme_get_registry();
 
   // Determine the primary theme function argument.
@@ -768,34 +678,6 @@ function skinr_ui_contextual_links(&$variables, $hook, $contextual_links) {
 }
 
 /**
- * Get all contextual links as returned from Skinr's contextual links handler.
- *
- * @return
- *   An array of contextual links data.
- */
-function skinr_ui_get_contextual_links() {
-  return _skinr_ui_set_contextual_links();
-}
-
-/**
- * Store contextual links internally for future use.
- *
- * @return
- *   An array of contextual links data.
- */
-function _skinr_ui_set_contextual_links($hook = NULL, $links = NULL) {
-  static $contextual_links = array();
-
-  if ($hook && $links) {
-    if (!isset($contextual_links[$hook])) {
-      $contextual_links[$hook] = $links;
-    }
-  }
-
-  return $contextual_links;
-}
-
-/**
  * Helper function to determine whether one of a set of hooks exists in a list
  * of required theme hooks.
  *
diff --git a/skinr_ui.rules.inc b/skinr_ui.rules.inc
deleted file mode 100644
index b741be8ab6facd32acc99f2b1cd42c90d9f78998..0000000000000000000000000000000000000000
--- a/skinr_ui.rules.inc
+++ /dev/null
@@ -1,347 +0,0 @@
-<?php
-
-/**
- * @file
- * Admin page callbacks for Skinr module's rules.
- */
-
-/**
- * Menu callback; displays the skinr rules listing.
- */
-function skinr_rules() {
-  $output = '';
-
-  $headers = array(
-    array('data' => t('Title'), 'field' => 'title'),
-    array('data' => t('Type'), 'field' => 'type'),
-    array('data' => t('Operations'), 'colspan' => 2)
-  );
-
-  $rules = skinr_rule_load_multiple();
-  $rows = array();
-  foreach ($rules as $rule) {
-    $row = array(
-      check_plain($rule->title),
-      check_plain($rule->rule_type),
-      l(t('edit'), 'admin/structure/skinr/rules/'. $rule->rid . '/edit'),
-      l(t('delete'), 'admin/structure/skinr/rules/'. $rule->rid . '/delete'),
-    );
-    $rows[] = $row;
-  }
-
-  $link = l(t('Create a new rule'), 'admin/structure/skinr/rules/add');
-  $row = array();
-  if (empty($rows)) {
-    $row[] = array(
-      'data' => t('No rules have been set up yet. !url.', array('!url' => $link)),
-      'colspan' => 4,
-    );
-  }
-  else {
-    $row[] = array(
-      'data' => t('!url.', array('!url' => $link)),
-      'colspan' => 4,
-    );
-  }
-  $rows[] = $row;
-
-  $output .= theme('table', array('header' => $headers, 'rows' => $rows));
-  $output .= drupal_render($form);
-
-  return $output;
-}
-
-/**
- * Menu callback; displays the edit form for a skinr rule.
- *
- * @ingroup forms
- */
-function skinr_rule_add($form, &$form_state) {
-  $form = array();
-  $form['#tree'] = TRUE;
-
-  $form['rule']['title'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Title'),
-    '#default_value' => !empty($form_state['values']['rule']['title']) ? $form_state['values']['rule']['title'] : '',
-    '#description' => t('Descriptive title for this rule; used by administrators.'),
-    '#required' => TRUE,
-  );
-  $options = array('page' => t('Page'));
-   foreach (list_themes() as $theme_name => $theme) {
-     if (empty($theme->status)) {
-       continue;
-     }
-     // Create a list options containing visible regions of this theme.
-     $regions = array();
-     foreach (system_region_list($theme_name, REGIONS_VISIBLE) as $region_name => $region) {
-       $regions['region__' . $region_name] = $region;
-     }
-     // Group the list of options by theme.
-     $key = t('@name Regions', array('@name' => $theme->info['name']));
-     $options[$key] = $regions;
-  }
-  $form['rule']['rule_type'] = array(
-    '#type' => 'select',
-    '#title' => t('Type'),
-    '#options' => $options,
-    '#default_value' => !empty($form_state['values']['rule']['rule_type']) ? $form_state['values']['rule']['rule_type'] : '',
-    '#description' => t('Type of element the rule is applied to.'),
-    '#required' => TRUE,
-  );
-
-  $form['buttons']['save'] = array(
-    '#type' => 'submit',
-    '#value' => t('Add'),
-  );
-
-  return $form;
-}
-
-/**
- * Process skinr_rule_add() submissions.
- */
-function skinr_rule_add_submit($form, &$form_state) {
-  $rule = new stdClass();
-  $rule->rid = NULL;
-  $rule->title = $form_state['values']['rule']['title'];
-  $rule->rule_type = $form_state['values']['rule']['rule_type'];
-  $rule->node_types = array();
-  $rule->roles = array();
-  $rule->visibility = 0;
-  $rule->pages = '';
-
-  skinr_rule_save($rule);
-  // Set rule id, if we inserted a new rule to allow others to know what rule they're working with.
-  $form_state['values']['rule']['rid'] = $rule->rid;
-
-  $form_state['redirect'] = 'admin/structure/skinr/rules/'. $rule->rid . '/edit';
-}
-
-/**
- * Form builder for the rule configuration form.
- *
- * @param $rid
- *   The rule ID.
- *
- * @see skinr_rule_edit_submit()
- * @ingroup forms
- */
-function skinr_rule_edit($form, &$form_state, $rule) {
-  $form['skinr']['module'] = array(
-    '#type' => 'hidden',
-    '#value' => 'rules',
-  );
-  $form['skinr']['element'] = array(
-    '#type' => 'hidden',
-    '#value' => $rule->rid,
-  );
-
-  $form['rule'] = array(
-    '#weight' => -1,
-  );
-
-  $form['rule']['rid'] = array(
-    '#type' => 'value',
-    '#value' => $rule->rid,
-  );
-
-  $form['rule']['title'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Rule title'),
-    '#default_value' => $rule->title,
-    '#description' => t('Descriptive title for this rule; used by administrators.'),
-    '#required' => TRUE,
-  );
-
-  $form['rule']['rule_type'] = array(
-    '#type' => 'hidden',
-    '#value' => $rule->rule_type,
-  );
-  $form['rule']['rule_type_displayed'] = array(
-    '#type' => 'item',
-    '#title' => t('Rule type'),
-    '#markup' => $rule->rule_type,
-    '#description' => t('Type of element the rule is applied to.'),
-  );
-
-  // Visibility settings.
-  $form['visibility_title'] = array(
-    '#type' => 'item',
-    '#title' => t('Visibility settings'),
-  );
-  $form['visibility'] = array(
-    '#type' => 'vertical_tabs',
-    '#attached' => array(
-      'js' => array(drupal_get_path('module', 'skinr_ui') . '/js/skinr_ui.rules.js'),
-    ),
-  );
-
-  // Per-path visibility.
-  $form['visibility']['path'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Pages'),
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-    '#group' => 'visibility',
-    '#weight' => 0,
-  );
-
-  $access = user_access('use PHP for settings');
-  if ($rule->visibility == SKINR_RULE_VISIBILITY_PHP && !$access) {
-    $form['visibility']['path']['visibility'] = array(
-      '#type' => 'value',
-      '#value' => SKINR_RULE_VISIBILITY_PHP,
-    );
-    $form['visibility']['path']['pages'] = array(
-      '#type' => 'value',
-      '#value' => $rule->pages,
-    );
-  }
-  else {
-    $options = array(
-      SKINR_RULE_VISIBILITY_NOTLISTED => t('All pages except those listed'),
-      SKINR_RULE_VISIBILITY_LISTED => t('Only the listed pages'),
-    );
-    $description = t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page.", array('%blog' => 'blog', '%blog-wildcard' => 'blog/*', '%front' => '<front>'));
-
-    if (module_exists('php') && $access) {
-      $options += array(SKINR_RULE_VISIBILITY_PHP => t('Pages on which this PHP code returns <code>TRUE</code> (experts only)'));
-      $title = t('Pages or PHP code');
-      $description .= ' ' . t('If the PHP option is chosen, enter PHP code between %php. Note that executing incorrect PHP code can break your Drupal site.', array('%php' => '<?php ?>'));
-    }
-    else {
-      $title = t('Pages');
-    }
-    $form['visibility']['path']['visibility'] = array(
-      '#type' => 'radios',
-      '#title' => t('Show block on specific pages'),
-      '#options' => $options,
-      '#default_value' => $rule->visibility,
-    );
-    $form['visibility']['path']['pages'] = array(
-      '#type' => 'textarea',
-      '#title' => '<span class="element-invisible">' . $title . '</span>',
-      '#default_value' => $rule->pages,
-      '#description' => $description,
-    );
-  }
-
-  // Per-node visbility.
-  $form['visibility']['node_type'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Content types'),
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-    '#group' => 'visibility',
-    '#weight' => 5,
-  );
-  $form['visibility']['node_type']['types'] = array(
-    '#type' => 'checkboxes',
-    '#title' => t('Show block for specific content types'),
-    '#default_value' => $rule->node_types,
-    '#options' => node_type_get_names(),
-    '#description' => t('Show this block only on pages that display content of the given type(s). If you select no types, there will be no type-specific limitation.'),
-  );
-
-  // Per-role visibility.
-  $role_options = array_map('check_plain', user_roles());
-  $form['visibility']['role'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Roles'),
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-    '#group' => 'visibility',
-    '#weight' => 10,
-  );
-  $form['visibility']['role']['roles'] = array(
-    '#type' => 'checkboxes',
-    '#title' => t('Show block for specific roles'),
-    '#default_value' => $rule->roles,
-    '#options' => $role_options,
-    '#description' => t('Show this rule only for the selected role(s). If you select no roles, the rule will be visible to all users.'),
-  );
-
-  $form['actions'] = array('#type' => 'actions');
-  $form['actions']['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save rule'),
-  );
-  $form['actions']['delete'] = array(
-    '#type' => 'submit',
-    '#value' => t('Delete'),
-    '#submit' => array('skinr_rule_delete_submit'),
-  );
-
-  return $form;
-}
-
-/**
- * Form submission handler for the rule configuration form.
- *
- * @see skinr_rule_edit()
- */
-function skinr_rule_edit_submit($form, &$form_state) {
-  $rule = new stdClass();
-  $rule->rid = !empty($form_state['values']['rid']) ? $form_state['values']['rid'] : NULL;
-  $rule->rule_type = $form_state['values']['rule_type'];
-  $rule->title = $form_state['values']['title'];
-  $rule->node_types = array_filter($form_state['values']['types']);
-  $rule->roles = $form_state['values']['roles'];
-  $rule->visibility = (int) $form_state['values']['visibility'];
-  $rule->pages = trim($form_state['values']['pages']);
-
-  skinr_rule_save($rule);
-  // Set rule id, if we inserted a new rule to allow others to know what rule they're working with.
-  $form_state['values']['rid'] = $rule->rid;
-
-  $form_state['redirect'] = 'admin/structure/skinr/rules';
-}
-
-/**
- * Called from within the rule edit form; redirects to skinr_rule_delete_confirm().
- *
- * @ingroup forms
- */
-function skinr_rule_delete_submit($form, &$form_state) {
-  $destination = array();
-  if (isset($_REQUEST['destination'])) {
-    $destination = drupal_get_destination();
-    unset($_REQUEST['destination']);
-  }
-  $form_state['redirect'] = array('admin/structure/skinr/rules/' . $form_state['values']['rid'] . 'delete', $destination);
-}
-
-/**
- * Menu callback; displays the delete confirmation for a skinr rule.
- *
- * @param $rid
- *   The rule ID.
- *
- * @ingroup forms
- */
-function skinr_rule_delete_confirm($form, &$form_state, $rule) {
-  $form['rid'] = array(
-    '#type' => 'value',
-    '#value' => $rule->rid,
-  );
-
-  return confirm_form($form,
-    t('Are you sure you want to delete %title?', array('%title' => $rule->title)),
-    isset($_GET['destination']) ? $_GET['destination'] : 'admin/structure/skinr/rules',
-    t('This action cannot be undone.'),
-    t('Delete'),
-    t('Cancel')
-  );
-}
-
-/**
- * Process skinr_rule_delete_confirm() submissions.
- */
-function skinr_rule_delete_confirm_submit($form, &$form_state) {
-  if ($form_state['values']['confirm']) {
-    skinr_rule_delete($form_state['values']['rid']);
-  }
-
-  $form_state['redirect'] = 'admin/structure/skinr/rules';
-}
diff --git a/tests/skinr.test b/tests/skinr.test
index 7748d20f90f1ca3d09c6df72a7b5c474da67f08d..87b3ae14c2ebc0de3d6634621125b9640e990454 100644
--- a/tests/skinr.test
+++ b/tests/skinr.test
@@ -43,6 +43,27 @@ class SkinrWebTestCase extends DrupalWebTestCase {
     $class_attr = (string) $elements[0]['class'];
     $this->assertTrue(strpos($class_attr, $class) === FALSE, $message);
   }
+
+  /**
+   * Pass if the message $text was set by one of the CRUD hooks in
+   * skinr_test.module, i.e., if the $text is an element of
+   * $_SESSION['skinr_test'].
+   *
+   * @param $text
+   *   Plain text to look for.
+   * @param $message
+   *   Message to display.
+   * @param $group
+   *   The group this message belongs to, defaults to 'Other'.
+   * @return
+   *   TRUE on pass, FALSE on fail.
+   */
+  protected function assertHookMessage($text, $message = NULL, $group = 'Other') {
+    if (!isset($message)) {
+      $message = $text;
+    }
+    return $this->assertTrue(array_search($text, $_SESSION['skinr_test']) !== FALSE, $message, $group);
+  }
 }
 
 /**
@@ -144,39 +165,24 @@ class SkinrApiTestCase extends SkinrWebTestCase {
   }
 
   /**
-   * Pass if the message $text was set by one of the CRUD hooks in
-   * skinr_test.module, i.e., if the $text is an element of
-   * $_SESSION['skinr_test'].
-   *
-   * @param $text
-   *   Plain text to look for.
-   * @param $message
-   *   Message to display.
-   * @param $group
-   *   The group this message belongs to, defaults to 'Other'.
-   * @return
-   *   TRUE on pass, FALSE on fail.
-   */
-  protected function assertHookMessage($text, $message = NULL, $group = 'Other') {
-    if (!isset($message)) {
-      $message = $text;
-    }
-    return $this->assertTrue(array_search($text, $_SESSION['skinr_test']) !== FALSE, $message, $group);
-  }
-
-  /**
    * Tests skinr_implements().
    */
   public function testSkinrImplementsAPI() {
     // Verify that skinr_implements() only returns extensions that are
     // compatible with this version of Skinr.
     $extensions = skinr_implements_api();
+    $this->verbose(highlight_string('<?php ' . var_export($extensions, TRUE), TRUE));
 
     // The expected extensions and their specific properties, if any.
     $all_expected = array(
       // Skinr is always expected.
       'skinr' => array(),
-      // Node is a required core module, so always expected.
+      // System and node are required core modules, so always expected.
+      'system' => array (
+        'version' => VERSION,
+        'path' => drupal_get_path('module', 'skinr') . '/modules',
+        'include file' => drupal_get_path('module', 'skinr') . '/modules/system.skinr.inc',
+      ),
       'node' => array(
         'version' => VERSION,
         'path' => drupal_get_path('module', 'skinr') . '/modules',
@@ -329,7 +335,8 @@ class SkinrApiTestCase extends SkinrWebTestCase {
     // Ensure functions from $module.skinr.inc in both module root and in
     // custom paths are triggered.
     $config_info = skinr_invoke_all('skinr_config_info');
-    $this->assertTrue(in_array('rules', $config_info), 'Function triggered in $module.skinr.inc file auto-loaded by module_hook().');
+    $this->verbose(highlight_string('<?php ' . var_export($config_info, TRUE), TRUE));
+    $this->assertTrue(in_array('system', $config_info), 'Function triggered in $module.skinr.inc file auto-loaded by module_hook().');
     $this->assertTrue(in_array('node', $config_info), 'Function triggered in $module.skinr.inc file in custom path.');
 
     // Ensure that skinr_test_incompatible is not included.
@@ -441,9 +448,9 @@ class SkinrApiTestCase extends SkinrWebTestCase {
     $config = skinr_get_config_info();
 
     // Skinr's own implementation in skinr.skinr.inc should always be found.
-    $this->assertTrue(in_array('rules', $config), 'hook_skinr_config_info() in $module.skinr.inc found.');
+    $this->assertTrue(in_array('system', $config), 'hook_skinr_config_info() in $module.skinr.inc found.');
     foreach ($config as $key => $type) {
-      if ($type == 'rules') {
+      if ($type == 'system') {
         unset($config[$key]);
       }
     }
@@ -548,7 +555,7 @@ class SkinrApiTestCase extends SkinrWebTestCase {
 
     // Test loading a skin configuration.
     $loaded_skin = skinr_skin_load($skin->sid);
-    $this->assertTrue(is_array($skin->options), 'Options for the skin configuration object were unserialized.');
+    $this->assertTrue(is_array($loaded_skin->options), 'Options for the skin configuration object were unserialized.');
 
     $this->assertTrue($loaded_skin->theme == $skin->theme && $loaded_skin->module == $skin->module && $loaded_skin->element == $skin->element && $loaded_skin->status == $skin->status && $loaded_skin->options[0] == $skin->options[0] && $loaded_skin->options[1] == $skin->options[1], 'Skin configuration object was loaded properly.');
 
@@ -568,7 +575,8 @@ class SkinrApiTestCase extends SkinrWebTestCase {
     $this->assertTrue(count($skins) == 2 && isset($skins[$skin->sid]->sid) && isset($skins[$second_skin->sid]->sid), 'Successfully loaded multiple skins.');
 
     // Test loading all skin configurations.
-    $skins = skinr_skin_load_multiple();
+    drupal_static_reset('skinr_skin_load_multiple');
+    $skins = skinr_skin_load_multiple(FALSE);
     $this->assertTrue(count($skins) == 2 && isset($skins[$skin->sid]->sid) && isset($skins[$second_skin->sid]->sid), 'Successfully loaded all skins.');
   }
 }
@@ -656,175 +664,4 @@ class SkinrDisplayTestCase extends SkinrWebTestCase {
     $js = drupal_get_path('module', 'skinr_test') . '/skinr_test.js';
     $this->assertRaw($js, t('Javascript was included on page.'));
   }
-
-  /**
-   * Tests loading and saving of rules.
-   */
-  public function testSkinrRulesLoadSave() {
-    // Test saving a rule.
-    $rule = (object) array(
-      'title' => 'Rule 1',
-      'rule_type' => 'page',
-      'node_types' => array(),
-      'roles' => array(),
-      'visibility' => 0, // Show on all pages, except those listed.
-      'pages' => '',
-    );
-    $this->assertTrue(skinr_rule_save($rule), 'Rule object was saved when no filtering is applied.');
-
-    $rule->title = '';
-    $this->assertFalse($status = skinr_rule_save($rule), 'Rule object was not saved when the required $rule->title field was empty.');
-    $this->pass('Status: ' . ($status ? 'true' : 'false'));
-    $rule->title = 'Rule 1';
-
-    $rule->rule_type = '';
-    $this->assertFalse(skinr_rule_save($rule), 'Rule object was not saved when the required $rule->rule_type field was empty.');
-    $rule->rule_type = 'page';
-
-    $rule->node_types = FALSE;
-    $this->assertFalse(skinr_rule_save($rule), 'Rule object was not saved when $rule->node_types was not an array.');
-    $rule->node_types = array();
-
-    $rule->roles = FALSE;
-    $this->assertFalse(skinr_rule_save($rule), 'Rule object was not saved when $rule->roles was not an array.');
-    $rule->roles = array();
-
-    // Test loading a rule.
-    $loaded_rule = skinr_rule_load($rule->rid);
-    $this->assertTrue(is_array($loaded_rule->node_types), 'Node types for the rule object were unserialized.');
-    $this->assertTrue(is_array($loaded_rule->roles), 'Roles for the rule object were unserialized.');
-
-    $this->assertTrue($loaded_rule->title == $rule->title && $loaded_rule->rule_type == $rule->rule_type && $loaded_rule->node_types == $rule->node_types && $loaded_rule->roles == $rule->roles && $loaded_rule->visibility == $rule->visibility && $loaded_rule->pages == $rule->pages, 'Rule object was loaded properly.');
-
-    // Save a second rule.
-    $second_rule = (object) array(
-      'title' => 'Rule 2',
-      'rule_type' => 'page',
-      'node_types' => array(),
-      'roles' => array(),
-      'visibility' => 0, // Show on all pages, except those listed.
-      'pages' => '',
-    );
-    skinr_rule_save($second_rule);
-
-    // Test loading multiple skin configurations.
-    $rules = skinr_rule_load_multiple(array($rule->rid, $second_rule->rid));
-    $this->assertTrue(count($rules) == 2 && isset($rules[$rule->rid]->rid) && isset($rules[$second_rule->rid]->rid), 'Successfully loaded multiple rules.');
-
-    // Test loading all skin configurations.
-    $rules = skinr_rule_load_multiple();
-    $this->assertTrue(count($rules) == 2 && isset($rules[$rule->rid]->rid) && isset($rules[$second_rule->rid]->rid), 'Successfully loaded all rules.');
-  }
-}
-
-/**
- * Tests API functionality.
- */
-class SkinrRulesApiTestCase extends DrupalWebTestCase {
-  // @todo Requires http://drupal.org/node/913086
-  // protected $profile = 'testing';
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Rules API',
-      'description' => 'Tests Skinr Rules API functionality.',
-      'group' => 'Skinr',
-    );
-  }
-
-  function setUp() {
-    parent::setUp(array('skinr', 'php'));
-
-    // Set up some nodes.
-    $this->article = $this->drupalCreateNode(array(
-      'type' => 'article',
-      'title' => 'Article node',
-    ));
-    $this->page = $this->drupalCreateNode(array(
-      'type' => 'page',
-      'title' => 'Page node',
-    ));
-
-    // Set up some users.
-    $this->web_user = $this->drupalCreateUser(array());
-  }
-
-  /**
-   * Tests visibility of rules.
-   */
-  public function testSkinrRulesVisibility() {
-    global $user;
-    $front = variable_get('site_frontpage', 'node');
-
-    $rule = (object) array(
-      'title' => 'Rule 1',
-      'rule_type' => 'page',
-      'node_types' => array(),
-      'roles' => array(),
-      'visibility' => 0, // Show on all pages, except those listed.
-      'pages' => '',
-    );
-    skinr_rule_save($rule);
-
-    // Test visibility when no filters are applied.
-    $this->assertTrue(skinr_rule_is_visible($rule->rid, $front), 'Rule is visible on front page.');
-    $this->assertTrue(skinr_rule_is_visible($rule->rid, 'node/' . $this->article->nid), 'Rule is visible on an article node page.');
-    $this->assertTrue(skinr_rule_is_visible($rule->rid, 'node/' . $this->page->nid), 'Rule is visible on a basic page node.');
-
-    // Test visibility with a node type filter.
-    $rule->node_types = array('article' => 'article');
-    skinr_rule_save($rule);
-
-    $this->assertFalse(skinr_rule_is_visible($rule->rid, $front), 'Node type limited rule is not visible on front page.');
-    $this->assertTrue(skinr_rule_is_visible($rule->rid, 'node/' . $this->article->nid), 'Node type limited rule is visible on the node type.');
-    $this->assertFalse(skinr_rule_is_visible($rule->rid, 'node/' . $this->page->nid), 'Node type limited rule is not visible on a different node type.');
-
-    // Verify visibility on node/add/* paths.
-    $this->assertTrue(skinr_rule_is_visible($rule->rid, 'node/add/article'), 'Node type limited rule is visible on the node type add page.');
-    $this->assertFalse(skinr_rule_is_visible($rule->rid, 'node/add/page'), 'Node type limited rule is not visible on a different node type add page.');
-
-    // Test visibility with a roles filter.
-    $rule->node_types = array();
-    $rule->roles = array(DRUPAL_AUTHENTICATED_RID => DRUPAL_AUTHENTICATED_RID);
-    skinr_rule_save($rule);
-
-    $user = $this->web_user;
-    $this->assertTrue(skinr_rule_is_visible($rule->rid, $front), 'Role limited rule is visible for authenticated users.');
-
-    $user = drupal_anonymous_user();
-    $this->assertFalse(skinr_rule_is_visible($rule->rid, $front), 'Role limited rule is not visible for anonymous users.');
-
-    // Test visibility with an exclude page filter.
-    $rule->roles = array();
-    $rule->pages = "<front>";
-    skinr_rule_save($rule);
-
-    $this->assertFalse(skinr_rule_is_visible($rule->rid, $front), 'Path excluded rule is not visible on excluded path.');
-    $this->assertTrue(skinr_rule_is_visible($rule->rid, 'node/' . $this->article->nid), 'Path excluded rule is visible on not excluded path.');
-
-    // Test visibility with an include page filter.
-    $rule->visibility = 1;
-    skinr_rule_save($rule);
-
-    $this->assertTrue(skinr_rule_is_visible($rule->rid, $front), 'Path limited rule is visible on included path.');
-    $this->assertFalse(skinr_rule_is_visible($rule->rid, 'node/' . $this->article->nid), 'Path limited rule is not visible on different path.');
-
-    // Test visibility with a PHP page filter.
-    $rule->visibility = 2;
-    $rule->pages = '<?php
-return FALSE;
-?>';
-    skinr_rule_save($rule);
-
-    $this->assertFalse(skinr_rule_is_visible($rule->rid, $front), 'PHP disabled rule is not visible on front page.');
-    $this->assertFalse(skinr_rule_is_visible($rule->rid, 'node/' . $this->article->nid), 'PHP disabled rule is not visible on node type page.');
-
-    $rule->pages = '<?php
-return TRUE;
-?>';
-    skinr_rule_save($rule);
-
-    $this->assertTrue(skinr_rule_is_visible($rule->rid), 'PHP enabled rule is visible on front page.');
-    $this->assertTrue(skinr_rule_is_visible($rule->rid, 'node/' . $this->article->nid), 'PHP enabled rule is visible on node type page.');
-  }
 }
diff --git a/tests/skinr_ui.test b/tests/skinr_ui.test
index dd737c0273cedaaf1deedd739071d42579968e0e..d34aace1de93a1e92f54ec77ed4a8e4912c9285e 100644
--- a/tests/skinr_ui.test
+++ b/tests/skinr_ui.test
@@ -143,7 +143,7 @@ class SkinrUIBasicTestCase extends SkinrUITestCase {
     // Verify that we end up on the expected URL to configure skins for the
     // user menu block.
     $front = variable_get('site_frontpage', 'node');
-    $this->assertUrl('admin/structure/skinr/edit/nojs/block/system__user-menu/configure', array(
+    $this->assertUrl('admin/structure/skinr/edit/block/system__user-menu/configure', array(
       'query' => array('destination' => $front),
     ));
 
@@ -151,7 +151,7 @@ class SkinrUIBasicTestCase extends SkinrUITestCase {
     // available.
     // Verify that we can apply the skinr_ui_test_border skin to the block.
     $edit = array(
-      'skinr_settings[block_type][bartik][groups][general][skinr_ui_test_bgcolor]' => 'bgcolor_red',
+      'skinr_settings[bartik][groups][general][skinr_ui_test_bgcolor]' => 'bgcolor_red',
     );
     // NULL means that we want to post to the page that is still contained in
     // SimpleTest's internal browser; i.e., the page of the path above. Instead
@@ -176,9 +176,9 @@ class SkinrUIBasicTestCase extends SkinrUITestCase {
   function testSkinAdditionalEdit() {
     // Verify that we can apply additional CSS classes.
     $edit = array(
-      'skinr_settings[block_type][bartik][groups][_additional][_additional]' => 'additional',
+      'skinr_settings[bartik][groups][_additional][_additional]' => 'additional',
     );
-    $this->drupalPost('admin/structure/skinr/edit/nojs/block/system__user-menu/configure', $edit, t('Save'));
+    $this->drupalPost('admin/structure/skinr/edit/block/system__user-menu/configure', $edit, t('Save'));
 
     // Verify that the skin has been applied.
     $this->drupalGet('');
@@ -189,8 +189,8 @@ class SkinrUIBasicTestCase extends SkinrUITestCase {
     $this->drupalLogin($user);
 
     // Verify that the additional CSS classes field is not enabled.
-    $this->drupalGet('admin/structure/skinr/edit/nojs/block/system__user-menu/configure');
-    $this->assertNoFieldByName('skinr_settings[block_type][bartik][groups][_additional][_additional]', NULL, 'Additional CSS classes field is not enabled for this user.');
+    $this->drupalGet('admin/structure/skinr/edit/block/system__user-menu/configure');
+    $this->assertNoFieldByName('skinr_settings[bartik][groups][_additional][_additional]', NULL, 'Additional CSS classes field is not enabled for this user.');
 
     // Save form when additional CSS classes is not set.
     $edit = array();
@@ -207,12 +207,12 @@ class SkinrUIBasicTestCase extends SkinrUITestCase {
   function testSkinEditWidgets() {
     // Go to the edit page for system__user_menu block.
     $this->drupalGet('admin/structure/skinr/library');
-    $this->drupalGet('admin/structure/skinr/edit/nojs/block/system__user-menu/configure');
+    $this->drupalGet('admin/structure/skinr/edit/block/system__user-menu/configure');
 
     // Check the widgets.
-    $this->assertFieldByName('skinr_settings[block_type][bartik][groups][general][skinr_ui_test_bgcolor]', NULL, 'Widget with valid type is displayed.');
-    $this->assertNoFieldByName('skinr_settings[block_type][bartik][groups][box][skinr_ui_test_border]', NULL, 'Widget with invalid type is not displayed.');
-    $this->assertFieldByName('skinr_settings[block_type][bartik][groups][general][skinr_ui_test_custom][custom]', NULL, 'Widget with form callback is displayed.');
+    $this->assertFieldByName('skinr_settings[bartik][groups][general][skinr_ui_test_bgcolor]', NULL, 'Widget with valid type is displayed.');
+    $this->assertNoFieldByName('skinr_settings[bartik][groups][box][skinr_ui_test_border]', NULL, 'Widget with invalid type is not displayed.');
+    $this->assertFieldByName('skinr_settings[bartik][groups][general][skinr_ui_test_custom][custom]', NULL, 'Widget with form callback is displayed.');
 
     // Check for output from empty groups.
     $this->assertNoRaw('id="edit-skinr-settings-block-group-bartik-box"', 'Resulting empty group is not displayed.');
@@ -223,30 +223,30 @@ class SkinrUIBasicTestCase extends SkinrUITestCase {
    */
   function testSkinEditThemeHooks() {
     // Widget should appear for system blocks.
-    $this->drupalGet('admin/structure/skinr/edit/nojs/block/system__user-menu/configure');
-    $this->assertField('edit-skinr-settings-block-type-bartik-groups-general-skinr-ui-test-color-color-white', 'The widget, which is limited to system blocks, appeared on the configuration form for system\'s user-menu block.');
+    $this->drupalGet('admin/structure/skinr/edit/block/system__user-menu/configure');
+    $this->assertField('edit-skinr-settings-bartik-groups-general-skinr-ui-test-color-color-white', 'The widget, which is limited to system blocks, appeared on the configuration form for system\'s user-menu block.');
 
     // Widget should not appear search blocks.
-    $this->drupalGet('admin/structure/skinr/edit/nojs/block/search__form/configure');
-    $this->assertNoField('edit-skinr-settings-block-type-bartik-groups-general-skinr-ui-test-color-color-white', 'The widget, which is limited to system blocks, did not appear on the configuration form for search\'s form block.');
+    $this->drupalGet('admin/structure/skinr/edit/block/search__form/configure');
+    $this->assertNoField('edit-skinr-settings-bartik-groups-general-skinr-ui-test-color-color-white', 'The widget, which is limited to system blocks, did not appear on the configuration form for search\'s form block.');
 
 
     // Widget should appear for page node comments.
-    $this->drupalGet('admin/structure/skinr/edit/nojs/comment/page/configure');
-    $this->assertField('edit-skinr-settings-comment-type-bartik-groups-general-skinr-ui-test-color-color-white', 'The widget, which is limited to page node comments, appeared on the configuration form for page node comments.');
+    $this->drupalGet('admin/structure/skinr/edit/comment/page/configure');
+    $this->assertField('edit-skinr-settings-bartik-groups-general-skinr-ui-test-color-color-white', 'The widget, which is limited to page node comments, appeared on the configuration form for page node comments.');
 
     // Widget should not appear for article node comments.
-    $this->drupalGet('admin/structure/skinr/edit/nojs/comment/article/configure');
-    $this->assertNoField('edit-skinr-settings-comment-type-bartik-groups-general-skinr-ui-test-color-color-white', 'The widget, which is limited to page node comments, did not appear on the configuration form for article node comments.');
+    $this->drupalGet('admin/structure/skinr/edit/comment/article/configure');
+    $this->assertNoField('edit-skinr-settings-bartik-groups-general-skinr-ui-test-color-color-white', 'The widget, which is limited to page node comments, did not appear on the configuration form for article node comments.');
 
 
     // Widget should appear for page nodes.
-    $this->drupalGet('admin/structure/skinr/edit/nojs/node/page/configure');
-    $this->assertField('edit-skinr-settings-node-type-bartik-groups-general-skinr-ui-test-color-color-white', 'The widget, which is limited to page node types, appeared on the configuration form for page node types.');
+    $this->drupalGet('admin/structure/skinr/edit/node/page/configure');
+    $this->assertField('edit-skinr-settings-bartik-groups-general-skinr-ui-test-color-color-white', 'The widget, which is limited to page node types, appeared on the configuration form for page node types.');
 
     // Widget should not appear for article nodes.
-    $this->drupalGet('admin/structure/skinr/edit/nojs/node/article/configure');
-    $this->assertNoField('edit-skinr-settings-node-type-bartik-groups-general-skinr-ui-test-color-color-white', 'The widget, which is limited to page node types, did not appear on the configuration form for article node types.');
+    $this->drupalGet('admin/structure/skinr/edit/node/article/configure');
+    $this->assertNoField('edit-skinr-settings-bartik-groups-general-skinr-ui-test-color-color-white', 'The widget, which is limited to page node types, did not appear on the configuration form for article node types.');
   }
 }
 
@@ -366,57 +366,6 @@ class SkinrUIAdminTestCase extends SkinrUITestCase {
 }
 
 /**
- * Tests rules administrative pages functionality.
- */
-class SkinrUIRulesTestCase extends SkinrUITestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Rules UI',
-      'description' => 'Tests rules functionality for Skinr UI.',
-      'group' => 'Skinr',
-    );
-  }
-
-  /**
-   * Tests administrative interface for rules.
-   */
-  function testRules() {
-    // Test that there is a rules page.
-    $this->drupalGet('admin/structure/skinr');
-    $this->assertLinkByHref('admin/structure/skinr/rules');
-
-    // Test that there is a way to add rules.
-    $this->drupalGet('admin/structure/skinr/rules');
-    $this->clickLink(t('Create a new rule'), 0);
-
-    // Verify that we end up on the expected URL.
-    $this->assertUrl('admin/structure/skinr/rules/add');
-
-    // Verify that we can create the rule.
-    $edit = array(
-      'rule[title]' => 'Rule 1',
-      'rule[rule_type]' => 'page',
-    );
-    $this->drupalPost(NULL, $edit, t('Add'));
-
-    // After posting, we expect to be redirected to the rule edit page.
-    $this->assertUrl('admin/structure/skinr/rules/1/edit');
-
-    // Save rule.
-    // @todo Add a skin and test whether it applies properly or not.
-    $edit = array(
-    );
-    $this->drupalPost(NULL, $edit, t('Save rule'));
-
-    // We should be returned back to the rules page.
-    $this->assertUrl('admin/structure/skinr/rules');
-
-    // Make sure the new rule appears listed on this page.
-    $this->assertLinkByHref('admin/structure/skinr/rules/1/edit');
-  }
-}
-
-/**
  * Tests UI functionality for Block plugin.
  */
 class SkinrUIPluginTestCase extends DrupalWebTestCase {
@@ -471,7 +420,7 @@ class SkinrUIPluginTestCase extends DrupalWebTestCase {
     $this->drupalGet('');
 
     // Make sure our contextual link appears on the page.
-    $this->assertLinkByHref('admin/structure/skinr/edit/nojs/block/system__user-menu/configure', 0, 'Contexual link to edit block\'s skin configuration was found.');
+    $this->assertLinkByHref('admin/structure/skinr/edit/block/system__user-menu/configure', 0, 'Contexual link to edit block\'s skin configuration was found.');
   }
 
   /**
@@ -493,7 +442,7 @@ class SkinrUIPluginTestCase extends DrupalWebTestCase {
     $this->drupalPost(NULL, $edit, t('Save'));
 
     // Make sure our contextual link appears on the page.
-    $this->assertLinkByHref('admin/structure/skinr/edit/nojs/comment/article/configure', 0, 'Contexual link to edit comment\'s skin configuration was found.');
+    $this->assertLinkByHref('admin/structure/skinr/edit/comment/article/configure', 0, 'Contexual link to edit comment\'s skin configuration was found.');
   }
 
   /**
@@ -508,7 +457,14 @@ class SkinrUIPluginTestCase extends DrupalWebTestCase {
     $this->drupalGet($uri['path']);
 
     // Make sure our contextual link appears on the page.
-    $this->assertLinkByHref('admin/structure/skinr/edit/nojs/node/article/configure', 0, 'Contexual link to edit node\'s skin configuration was found.');
+    $this->assertLinkByHref('admin/structure/skinr/edit/node/article/configure', 0, 'Contexual link to edit node\'s skin configuration was found.');
+  }
+
+  /**
+   * Tests node plugin.
+   */
+  function testSystem() {
+    // @todo Add tests for html and region hooks.
   }
 }
 
@@ -551,6 +507,6 @@ class SkinrUIPluginViewsTestCase extends DrupalWebTestCase {
     $this->drupalGet('skinr-ui-test-view');
 
     // Make sure our contextual link appears on the page.
-    $this->assertLinkByHref('admin/structure/skinr/edit/nojs/views/skinr_ui_test__page/configure', 0, "Contexual link to edit view's skin configuration was found.");
+    $this->assertLinkByHref('admin/structure/skinr/edit/views/skinr_ui_test__page/configure', 0, "Contexual link to edit view's skin configuration was found.");
   }
 }
