diff --git js/skinr.js js/skinr.js
index 6dd8e35..781f83d 100644
--- js/skinr.js
+++ js/skinr.js
@@ -11,7 +11,7 @@ Drupal.behaviors.Skinr = {
   attach: function(context, settings) {
     for (var i in settings.skinr['areas']) {
       var $module = settings.skinr['areas'][i]['module'];
-      var $sids = settings.skinr['areas'][i]['sids'];
+      var $elements = settings.skinr['areas'][i]['elements'];
       var $id = settings.skinr['areas'][i]['id'];
 
       var $region = $('.skinr-id-' + $id).once('skinr-region', function() {});
@@ -21,19 +21,19 @@ Drupal.behaviors.Skinr = {
 
       if ($region.length > 0) {
         var $links = '';
-        for (var $j in $sids) {
+        for (var $j in $elements) {
           var $classes = '';
           if ($j == 0) {
             $classes += ' first';
           }
-          if ($j == $sids.length - 1) {
+          if ($j == $elements.length - 1) {
             $classes += ' last';
           }
-          if ($sids.length > 1) {
-            $links += '<li class="skinr-link-' + $j + $classes + '"><a href="' + settings.basePath + Drupal.Skinr.editUrl + '/' + $module + '/' + $sids[$j] + '/' + $sids +'" class="skinr-link ctools-use-dialog">' + Drupal.t('Edit skin') + ' ' + (parseInt($j) + 1) + '</a></li>';
+          if ($elements.length > 1) {
+            $links += '<li class="skinr-link-' + $j + $classes + '"><a href="' + settings.basePath + Drupal.Skinr.editUrl + '/' + $module + '/' + $elements[$j] + '/' + $elements +'" class="skinr-link ctools-use-dialog">' + Drupal.t('Edit skin') + ' ' + (parseInt($j) + 1) + '</a></li>';
           }
           else {
-            $links = '<li class="skinr-link-0 first last"><a href="' + settings.basePath + Drupal.Skinr.editUrl + '/' + $module + '/' + $sids[$j] +'" class="skinr-link ctools-use-dialog">' + Drupal.t('Edit skin') + '</a></li>';
+            $links = '<li class="skinr-link-0 first last"><a href="' + settings.basePath + Drupal.Skinr.editUrl + '/' + $module + '/' + $elements[$j] +'" class="skinr-link ctools-use-dialog">' + Drupal.t('Edit skin') + '</a></li>';
           }
         }
 
@@ -43,7 +43,7 @@ Drupal.behaviors.Skinr = {
         }
 
         $region.prepend('<div class="skinr-links-wrapper' + $wrapper_classes + '"><ul class="skinr-links">' + $links + '</ul></div>');
-        $region.get(0).skinr = { 'module': $module, 'sids': $sids, 'id': $id };
+        $region.get(0).skinr = { 'module': $module, 'elements': $elements, 'id': $id };
 
         Drupal.behaviors.Dialog($region);
       };
@@ -100,40 +100,40 @@ Drupal.behaviors.SkinrLivePreview = {
     $('#skinr-ui-form .skinr-ui-current-theme :input:not(.skinr-live-preview-processed)', context).addClass('skinr-live-preview-processed').change(function () {
       var $tag = $(this).attr('tagName');
       $tag = $tag.toLowerCase();
-      
+
       var $module = $('#skinr-ui-form #edit-module').val();
-      var $sid = $('#skinr-ui-form #edit-sid').val();
-      var $sids = $('#skinr-ui-form #edit-sids').val();
-      if (!$sids) {
-        $sids = $sid;
+      var $element = $('#skinr-ui-form #edit-element').val();
+      var $elements = $('#skinr-ui-form #edit-elements').val();
+      if (!$elements) {
+        $elements = $element;
       }
-  
+
       var $name = $(this).attr('name');
-      $name = $name.replace(/skinr_settings\[.*_group\]\[[^\]]*\]\[widgets\]\[([^\]]*)\]/, '$1');
-  
+      $name = $name.replace(/skinr_settings\[.*_group\]\[[^\]]*\]\[([^\]]*)\]/, '$1');
+
       var $classes = '';
       var $add_classes = $(this).val();
-  
+
       if ($tag == 'select') {
         $(this).find('option').each(function() {
           $classes += ' ' + $(this).attr('value');
         });
       }
       else if ($tag == 'input') {
-        
+
       }
-      
+
       // Use AJAX to grab the CSS and JS filename.
       $.ajax({
         type: 'GET',
         dataType: 'json',
         url: Drupal.settings.basePath + Drupal.Skinr.infoUrl + '/' + $name + '/' + $add_classes,
         success: function($data) {
-  
+
           var $command = {
             command: 'skinrAfterupdate',
             module: $module,
-            sids: $sids,
+            elements: $elements,
             classes: {
               remove: $classes,
               add: $add_classes
@@ -142,7 +142,7 @@ Drupal.behaviors.SkinrLivePreview = {
             js: $data.js,
             nosave: true
           };
-          
+
           Drupal.CTools.AJAX.commands.skinrAfterupdate($command);
         }
       });
@@ -154,7 +154,7 @@ Drupal.behaviors.SkinrLivePreview = {
  * AJAX responder command to dismiss the modal.
  */
 Drupal.CTools.AJAX.commands.skinrAfterupdate = function(command) {
-  if (command.module && command.sids && (command.classes.remove || command.classes.add)) {
+  if (command.module && command.elements && (command.classes.remove || command.classes.add)) {
     if (command.css) {
       for (var j in command.css) {
         $(document.createElement('link')).attr({href: Drupal.settings.basePath + command.css[j].path, media: command.css[j].media, rel: 'stylesheet', type: 'text/css'}).appendTo('head');
@@ -165,9 +165,9 @@ Drupal.CTools.AJAX.commands.skinrAfterupdate = function(command) {
         $.getScript(Drupal.settings.basePath + command.js[j].path);
       }
     }
-    
+
     for (var i in Drupal.settings.skinr['areas']) {
-      if (Drupal.settings.skinr['areas'][i]['module'] == command.module && Drupal.settings.skinr['areas'][i]['sids'] == command.sids) {
+      if (Drupal.settings.skinr['areas'][i]['module'] == command.module && Drupal.settings.skinr['areas'][i]['elements'] == command.elements) {
         $('.skinr-id-' + Drupal.settings.skinr['areas'][i]['id']).removeClass(command.classes.remove).addClass(command.classes.add);
         if (command.nosave == undefined || command.nosave == false) {
           Drupal.settings.skinr['areas'][i]['classes'] = $('.skinr-id-' + Drupal.settings.skinr['areas'][i]['id']).attr('class');
diff --git modules/block.skinr.inc modules/block.skinr.inc
index 3e49d37..3392fa0 100644
--- modules/block.skinr.inc
+++ modules/block.skinr.inc
@@ -84,11 +84,11 @@ function block_skinr_form_index_handler($op, &$form, $form_state) {
 function block_skinr_preprocess_hook_callback(&$form, $form_state) {
   $preprocess_hooks = array();
 
-  if (empty($form['module']['#value']) && !empty($form['skinr']['sid']['#value'])) {
+  if (empty($form['module']['#value']) && !empty($form['skinr']['element']['#value'])) {
     $result = db_select('block', 'b')
       ->fields('b')
       ->distinct()
-      ->where('CONCAT(b.module, \'-\', b.delta) = :identifier', array(':identifier' => $form['skinr']['sid']['#value']))
+      ->where('CONCAT(b.module, \'-\', b.delta) = :identifier', array(':identifier' => $form['skinr']['element']['#value']))
       ->range(0, 1)
       ->execute();
     foreach ($result as $block) {
@@ -115,7 +115,7 @@ function block_skinr_preprocess_hook_callback(&$form, $form_state) {
  *   structure and merge the returned classes.
  */
 function block_skinr_preprocess_index_handler(&$variables) {
-  return $variables['block']->module . '-' . $variables['block']->delta;
+  return array($variables['block']->module . '-' . $variables['block']->delta);
 }
 
 /**
diff --git modules/comment.skinr.inc modules/comment.skinr.inc
index 28e4047..d823cbe 100644
--- modules/comment.skinr.inc
+++ modules/comment.skinr.inc
@@ -65,7 +65,7 @@ function comment_skinr_form_index_handler($op, &$form, &$form_state) {
           $skinr = new stdClass();
           $skinr->theme = $theme_name;
           $skinr->module = 'comment';
-          $skinr->sid = $form_state['values']['old_type'];
+          $skinr->element = $form_state['values']['old_type'];
           $skinr->skins = array();
 
           skinr_skin_save($skinr);
@@ -89,8 +89,8 @@ function comment_skinr_form_index_handler($op, &$form, &$form_state) {
 function comment_skinr_preprocess_hook_callback(&$form, $form_state) {
   $preprocess_hooks = array();
 
-  if (!isset($form['#node_type']->type) && !empty($form['skinr']['sid']['#value'])) {
-    $preprocess_hooks[] = 'comment_wrapper_' . $form['skinr']['sid']['#value'];
+  if (!isset($form['#node_type']->type) && !empty($form['skinr']['element']['#value'])) {
+    $preprocess_hooks[] = 'comment_wrapper_' . $form['skinr']['element']['#value'];
   }
   else {
     $preprocess_hooks[] = 'comment_wrapper_' . $form['#node_type']->type;
@@ -112,7 +112,7 @@ function comment_skinr_preprocess_hook_callback(&$form, $form_state) {
  *   structure and merge the returned classes.
  */
 function comment_skinr_preprocess_index_handler(&$variables) {
-  return $variables['node']->type;
+  return array($variables['node']->type);
 }
 
 /**
diff --git modules/node.skinr.inc modules/node.skinr.inc
index b172ac1..ad634d7 100644
--- modules/node.skinr.inc
+++ modules/node.skinr.inc
@@ -63,7 +63,7 @@ function node_skinr_form_index_handler($op, &$form, $form_state) {
           $skinr = new stdClass();
           $skinr->theme = $theme_name;
           $skinr->module = 'node';
-          $skinr->sid = $form_state['values']['old_type'];
+          $skinr->element = $form_state['values']['old_type'];
           $skinr->skins = array();
 
           skinr_skin_save($skinr);
@@ -87,8 +87,8 @@ function node_skinr_form_index_handler($op, &$form, $form_state) {
 function node_skinr_preprocess_hook_callback(&$form, $form_state) {
   $preprocess_hooks = array();
 
-  if (!isset($form['#node_type']->type) && !empty($form['skinr']['sid']['#value'])) {
-    $preprocess_hooks[] = 'node_' . $form['skinr']['sid']['#value'];
+  if (!isset($form['#node_type']->type) && !empty($form['skinr']['element']['#value'])) {
+    $preprocess_hooks[] = 'node_' . $form['skinr']['element']['#value'];
   }
   else {
     $preprocess_hooks[] = 'node_' . $form['#node_type']->type;
@@ -110,7 +110,7 @@ function node_skinr_preprocess_hook_callback(&$form, $form_state) {
  *   structure and merge the returned classes.
  */
 function node_skinr_preprocess_index_handler(&$variables) {
-  return $variables['node']->type;
+  return array($variables['node']->type);
 }
 
 /**
diff --git modules/panels.skinr.inc modules/panels.skinr.inc
index 07c2e5e..b45efa0 100644
--- modules/panels.skinr.inc
+++ modules/panels.skinr.inc
@@ -216,7 +216,7 @@ function panels_skinr_submit_handler_settings(&$form, $form_state, $module, $for
   foreach ($form_state['values']['skinr_settings'][$module . '_group'] as $theme_name => $theme) {
     if ((!empty($theme['widgets']) && is_array($theme['widgets'])) || isset($theme['_additional'])) {
       $hook  = $module;
-      $sid   = skinr_handler('form_index_handler', 'submit', $form_settings['index_handler'], $form, $form_state);
+      $element = skinr_handler('form_index_handler', 'submit', $form_settings['index_handler'], $form, $form_state);
 
       // Key doesn't exist properly for new displays. Perhaps we should inject a timestamp based key into the display object
       // and use that for reference on the final submit? If it works...
@@ -236,8 +236,8 @@ function panels_skinr_submit_handler_settings(&$form, $form_state, $module, $for
         }
       }
 
-      if (empty($sid)) {
-        // We didn't receive a valid sid, so raise an error.
+      if (empty($element)) {
+        // We didn't receive a valid element, so raise an error.
         drupal_set_message(t("Skinr settings weren't saved due to an error."), 'error');
       }
 
@@ -255,7 +255,7 @@ function panels_skinr_submit_handler_settings(&$form, $form_state, $module, $for
           }
         }
       }
-      $skinr_data[$theme_name][$sid] = $value;
+      $skinr_data[$theme_name][$element] = $value;
       ctools_object_cache_set('skinr', $form_state['display']->did, $skinr_data);
     }
   }
@@ -310,11 +310,11 @@ function panels_skinr_submit_handler_display(&$form, $form_state, $module, $form
 function _panels_skinr_save_and_clear_cache($did) {
   if ($skinr_data = ctools_object_cache_get('skinr', $did, TRUE)) {
     foreach ($skinr_data as $theme_name => $theme) {
-      foreach ($theme as $sid => $skins) {
+      foreach ($theme as $element => $skins) {
         $skinr = new stdClass();
         $skinr->theme = $theme_name;
         $skinr->module = 'panels';
-        $skinr->sid = $sid;
+        $skinr->element = $element;
         $skinr->skins = $skins;
 
         skinr_skin_save($skinr);
@@ -358,10 +358,10 @@ function panels_skinr_preprocess_hook_callback(&$form, $form_state) {
  *   An array of preprocess hooks we wish to use.
  */
 function panels_skinr_ajax_preprocess_hook_callback(&$form, $form_state) {
-  if (strpos($form['skinr']['sid']['#value'], '-region-') !== FALSE) {
+  if (strpos($form['skinr']['element']['#value'], '-region-') !== FALSE) {
     return 'panels_region';
   }
-  elseif (strpos($form['skinr']['sid']['#value'], '-pane-') !== FALSE) {
+  elseif (strpos($form['skinr']['element']['#value'], '-pane-') !== FALSE) {
     return 'panels_pane';
   }
   else {
@@ -381,9 +381,9 @@ function panels_skinr_ajax_preprocess_hook_callback(&$form, $form_state) {
  *   structure and merge the returned classes.
  */
 function panels_skinr_preprocess_index_handler(&$variables) {
-  $index = '';
+  $index = array();
   if (isset($variables['pane']->style['style']) && $variables['pane']->style['style'] == 'skinr') {
-    $index = 'display-' . $variables['pane']->did . '-pane-' . $variables['pane']->pid;
+    $index[] = 'display-' . $variables['pane']->did . '-pane-' . $variables['pane']->pid;
   }
   return $index;
 }
diff --git modules/panels/skinr.inc modules/panels/skinr.inc
index a03c612..a8de707 100644
--- modules/panels/skinr.inc
+++ modules/panels/skinr.inc
@@ -22,11 +22,11 @@ $plugin = array(
  */
 function theme_panels_skinr_style_render_region($variables) {
   $hook = 'panels';
-  $sid = 'display-' . $variables['display']->did . '-region-' . $variables['region_id'];
+  $element = 'display-' . $variables['display']->did . '-region-' . $variables['region_id'];
 
   // Add skinr styles.
   $style = array();
-  if ($skinr = skinr_skin_load(NULL, $hook, $sid)) {
+  if ($skinr = skinr_skin_load(NULL, $hook, $element)) {
     $style = implode(' ', skinr_flatten_skins_array($skinr->skins));
   }
 
@@ -39,7 +39,7 @@ function theme_panels_skinr_style_render_region($variables) {
   if (user_access('skinr access')) {
     $variables['content']->admin_links[] = array(
       'title' => t('Edit skin'),
-      'href' => 'admin/appearance/skinr/edit/nojs/panels/' . $sid,
+      'href' => 'admin/appearance/skinr/edit/nojs/panels/' . $element,
       'query' => drupal_get_destination(),
     );
   }
@@ -54,11 +54,11 @@ function theme_panels_skinr_style_render_region($variables) {
  */
 function theme_panels_skinr_style_render_pane($variables) {
   $hook = 'panels';
-  $sid = 'display-' . $variables['display']->did . '-pane-' . $variables['pane']->pid;
+  $element = 'display-' . $variables['display']->did . '-pane-' . $variables['pane']->pid;
 
   // Add skinr styles
   $style = array();
-  if ($skinr = skinr_skin_load(NULL, $hook, $sid)) {
+  if ($skinr = skinr_skin_load(NULL, $hook, $element)) {
     $style = skinr_flatten_skins_array($skinr->skins);
   }
 
@@ -75,7 +75,7 @@ function theme_panels_skinr_style_render_pane($variables) {
   if (user_access('skinr access')) {
     $variables['content']->admin_links[] = array(
       'title' => t('Edit skin'),
-      'href' => 'admin/appearance/skinr/edit/nojs/panels/' . $sid,
+      'href' => 'admin/appearance/skinr/edit/nojs/panels/' . $element,
       'query' => drupal_get_destination(),
     );
   }
diff --git modules/views.skinr.inc modules/views.skinr.inc
index 9c1d7b5..7beda1f 100644
--- modules/views.skinr.inc
+++ modules/views.skinr.inc
@@ -167,7 +167,7 @@ function views_skinr_data_handler(&$form, $form_state, $theme, $module, $form_se
       $skinr = new stdClass();
       $skinr->theme = $theme;
       $skinr->module = $module;
-      $skinr->sid = $index;
+      $skinr->element = $index;
       $skinr->skins = $skinrs[$theme][$index];
 
       return $skinr;
@@ -197,7 +197,7 @@ function views_skinr_data_handler(&$form, $form_state, $theme, $module, $form_se
 function views_skinr_submit_handler_display(&$form, $form_state, $module, $form_settings) {
   foreach ($form_state['values']['skinr_settings'][$module .'_group'] as $theme_name => $theme) {
     if ((!empty($theme['widgets']) && is_array($theme['widgets'])) || isset($theme['_additional'])) {
-      $sid   = skinr_handler('form_index_handler', 'submit', $form_settings['index_handler'], $form, $form_state);
+      $element = skinr_handler('form_index_handler', 'submit', $form_settings['index_handler'], $form, $form_state);
       $value = array();
 
       if (!empty($theme['widgets']) && is_array($theme['widgets'])) {
@@ -213,8 +213,8 @@ function views_skinr_submit_handler_display(&$form, $form_state, $module, $form_
         }
       }
 
-      if (empty($sid)) {
-        // We didn't receive a valid sid, so raise an error
+      if (empty($element)) {
+        // We didn't receive a valid element, so raise an error
         drupal_set_message(t("Skinr settings weren't saved due to an error."), 'error');
       }
 
@@ -232,7 +232,7 @@ function views_skinr_submit_handler_display(&$form, $form_state, $module, $form_
           }
         }
       }
-      $skinrs[$theme_name][$sid] = $value;
+      $skinrs[$theme_name][$element] = $value;
       ctools_object_cache_set('skinr', $form_state['view']->name, $skinrs);
     }
   }
@@ -246,11 +246,11 @@ function views_skinr_submit_handler_view(&$form, $form_state, $module, $form_set
 
       if ($skinrs = ctools_object_cache_get('skinr', $form_state['view']->name, TRUE)) {
         foreach ($skinrs as $theme_name => $theme) {
-          foreach ($theme as $sid => $skins) {
+          foreach ($theme as $element => $skins) {
             $skinr = new stdClass();
             $skinr->theme = $theme_name;
             $skinr->module = $module;
-            $skinr->sid = $sid;
+            $skinr->element = $element;
             $skinr->skins = $skins;
 
             skinr_skin_save($skinr);
@@ -285,10 +285,10 @@ function views_skinr_preprocess_hook_callback(&$form, $form_state) {
   if (!empty($form_state['view']) && !empty($form_state['view']->name)) {
     $view = $form_state['view'];
   }
-  elseif(isset($form['skinr']['sid']['#value'])) {
-    $sidinfo = _views_skinr_sidinfo($form['skinr']['sid']['#value']);
-    if ($view = views_get_view($sidinfo['view'])) {
-      $view->execute_display($sidinfo['display']);
+  elseif(isset($form['skinr']['element']['#value'])) {
+    $element_info = _views_skinr_element_info($form['skinr']['element']['#value']);
+    if ($view = views_get_view($element_info['view'])) {
+      $view->execute_display($element_info['display']);
     }
   }
 
@@ -306,15 +306,15 @@ function views_skinr_preprocess_hook_callback(&$form, $form_state) {
   return $preprocess_hooks;
 }
 
-function _views_skinr_sidinfo($sid) {
+function _views_skinr_element_info($element) {
   // view-[view_name]-display-[display_name]
-  $pos = strpos($sid, '-display-');
+  $pos = strpos($element, '-display-');
   if ($pos !== FALSE) {
-    $sidinfo = array();
-    $sidinfo['view'] = substr($sid, strlen('view-'), $pos - strlen('view-'));
-    $sidinfo['display'] = substr($sid, $pos + strlen('-display-'));
+    $element_info = array();
+    $element_info['view'] = substr($element, strlen('view-'), $pos - strlen('view-'));
+    $element_info['display'] = substr($element, $pos + strlen('-display-'));
 
-    return $sidinfo;
+    return $element_info;
   }
 
   return FALSE;
@@ -334,10 +334,10 @@ function _views_skinr_sidinfo($sid) {
 function views_skinr_preprocess_index_handler(&$variables) {
   $default = $variables['view']->display_handler->is_defaulted('style_options');
   if ($default) {
-    return 'view-'. $variables['view']->name .'-display-default';
+    return array('view-'. $variables['view']->name .'-display-default');
   }
   else {
-    return 'view-'. $variables['view']->name .'-display-'. $variables['view']->current_display;
+    return array('view-'. $variables['view']->name .'-display-'. $variables['view']->current_display);
   }
 }
 
@@ -347,15 +347,15 @@ function views_skinr_preprocess_index_handler(&$variables) {
 function views_views_admin_links_alter(&$links, &$view) {
   $default = $view->display_handler->is_defaulted('style_options');
   if ($default) {
-    $sid = 'view-'. $view->name .'-display-default';
+    $element = 'view-'. $view->name .'-display-default';
   }
   else {
-    $sid = 'view-'. $view->name .'-display-'. $view->current_display;
+    $element = 'view-'. $view->name .'-display-'. $view->current_display;
   }
 
   $links[] = array(
-    'title' => skinr_ui_edit_contextual_title('views', $sid),
-    'href' => 'admin/appearance/skinr/edit/nojs/views/' . $sid,
+    'title' => skinr_ui_edit_contextual_title('views', $element),
+    'href' => 'admin/appearance/skinr/edit/nojs/views/' . $element,
     'query' => drupal_get_destination(),
   );
 }
diff --git skinr.handlers.inc skinr.handlers.inc
index fb4241b..80985e9 100644
--- skinr.handlers.inc
+++ skinr.handlers.inc
@@ -49,18 +49,18 @@ function skinr_access_handler($op, &$form, $form_state) {
 function skinr_index_handler($op, &$form, $form_state) {
   switch ($op) {
     case 'form':
-      if (empty($form['skinr']['sid']['#value'])) {
+      if (empty($form['skinr']['element']['#value'])) {
         trigger_error(sprintf("The form with form_id '%' is not a valid skinr form.", $form['form_id']['#value']), E_USER_ERROR);
         return FALSE;
       }
-      return $form['skinr']['sid']['#value'];
+      return $form['skinr']['element']['#value'];
 
     case 'submit':
-      if (empty($form_state['values']['sid'])) {
+      if (empty($form_state['values']['element'])) {
         trigger_error(sprintf("The form with form_id '%' is not a valid skinr form.", $form['form_id']['#value']), E_USER_ERROR);
         return FALSE;
       }
-      return $form_state['values']['sid'];
+      return $form_state['values']['element'];
   }
 }
 
@@ -87,9 +87,14 @@ function skinr_data_handler(&$form, $form_state, $theme, $module, $form_settings
   if (empty($form_settings['index_handler'])) {
     trigger_error(sprintf("No index_handler was found for form_id '%s' in module '%s'.", $form_id, $module), E_USER_ERROR);
   }
-  $index = skinr_handler('form_index_handler', 'form', $form_settings['index_handler'], $form, $form_state);
+  $element = skinr_handler('form_index_handler', 'form', $form_settings['index_handler'], $form, $form_state);
 
-  return skinr_skin_load($theme, $module, $index);
+  $params = array(
+    'theme' => $theme,
+    'module' => $module,
+    'element' => $element,
+  );
+  return skinr_skin_load_multiple(skinr_skin_get_sids($params));
 }
 
 /**
@@ -106,34 +111,64 @@ function skinr_data_handler(&$form, $form_state, $theme, $module, $form_settings
  *   processed.
  */
 function skinr_submit_handler(&$form, $form_state, $module, $form_settings) {
+  if (!$element = skinr_handler('form_index_handler', 'submit', $form_settings['index_handler'], $form, $form_state)) {
+    // We require a valid element to continue.
+    // @todo This should really be in a validation handler.
+    drupal_set_message(t("Skinr settings weren't saved due to an error."), 'error');
+    return;
+  }
+
   if (isset($form_state['values']['skinr_settings'][$module . '_group'])) {
     foreach ($form_state['values']['skinr_settings'][$module . '_group'] as $theme_name => $theme) {
-      if ((!empty($theme['widgets']) && is_array($theme['widgets'])) || isset($theme['_additional'])) {
-        $skin = new stdClass();
-        $skin->theme = $theme_name;
-        $skin->module = $module;
-        $skin->sid = skinr_handler('form_index_handler', 'submit', $form_settings['index_handler'], $form, $form_state);
-        $skin->skins = array();
-
-        if (!empty($theme['widgets']) && is_array($theme['widgets'])) {
-          foreach ($theme['widgets'] as $skin_name => $skin_value) {
-            $skin->skins['_options'][$skin_name] = $skin_value;
+      // Process widgets.
+      if (!empty($theme) && is_array($theme)) {
+        foreach ($theme as $skin_name => $options) {
+          // Ensure options is an array.
+          if (!is_array($options)) {
+            $options = $skin_name == '_additional' ? explode(' ', $options) : array($options);
+          }
+          // Sanitzie options.
+          $options = _skinr_array_strip_empty($options);
+
+          // Find existing skin.
+          $params = array(
+            'theme' => $theme_name,
+            'module' => $module,
+            'element' => $element,
+            'skin' => $skin_name,
+          );
+          $sids = skinr_skin_get_sids($params);
+
+          unset($skin);
+          if (!empty($sids)) {
+            $sid = reset($sids);
+            $skin = skinr_skin_load($sid);
           }
-        }
 
-        if (isset($theme['_additional'])) {
-          $theme['_additional'] = trim($theme['_additional']);
-          if (!empty($theme['_additional'])) {
-            $skin->skins['_additional'] = $theme['_additional'];
+          if (empty($options)) {
+            if (!empty($skin)) {
+              // Delete this skin configuration.
+              skinr_skin_delete($skin->sid);
+            }
+            continue;
           }
-        }
 
-        if (empty($skin->sid)) {
-          // We didn't receive a valid sid, so raise an error
-          drupal_set_message(t("Skinr settings weren't saved due to an error."), 'error');
-        }
+          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->skin = $skin_name;
+          }
+          $skin->options = $options;
+          $skin->status = 1;
 
-        skinr_skin_save($skin);
+          // 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');
+          }
+        }
       }
     }
   }
diff --git skinr.install skinr.install
index a7af7a0..8c66681 100644
--- skinr.install
+++ skinr.install
@@ -9,50 +9,67 @@
  * Implements hook_schema().
  */
 function skinr_schema() {
-  $schema['skinr'] = array(
+  $schema['skinr_skins'] = array(
     'description' => 'Stores skinr data.',
     'fields' => array(
+      'sid' => array(
+        'description' => 'The primary identifier for a skin configuration.',
+        'type' => 'serial',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
       'theme' => array(
-        'description' => 'The system name of the theme.',
+        'description' => 'The theme this configuration applies to.',
         'type' => 'varchar',
         'length' => 64,
         'not null' => TRUE,
         'default' => '',
       ),
       'module' => array(
-        'description' => 'The module this skinr settings is for.',
+        'description' => 'The module this configuration applies to.',
         'type' => 'varchar',
         'length' => 64,
         'not null' => TRUE,
         'default' => '',
       ),
-      'sid' => array(
-        'description' => 'A unique identifier for this skinr datum.',
+      'element' => array(
+        'description' => 'The element this configutation applies to.',
         'type' => 'varchar',
         'length' => 128,
         'not null' => TRUE,
         'default' => '',
       ),
-      'skins' => array(
-        'description' => 'The skins set for this datum.',
-        'type' => 'text',
-        'size' => 'big',
+      'skin' => array(
+        'description' => 'The skin that has been applied.',
+        'type' => 'varchar',
+        'length' => 128,
         'not null' => TRUE,
-        'serialize' => TRUE,
+        'default' => '',
       ),
-      'settings' => array(
-        'description' => 'Custom settings for this id.',
+      'options' => array(
+        'description' => 'A serialized array containing the skin options that have been applied.',
         'type' => 'text',
         'size' => 'big',
         'not null' => TRUE,
         'serialize' => TRUE,
       ),
+      'status' => array(
+        'description' => 'Boolean indicating whether or not this item is enabled.',
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+        'size' => 'tiny',
+      ),
+    ),
+    'primary key' => array('sid'),
+    'unique keys' => array(
+      'theme_module_element_skin' => array('theme', 'module', 'element', 'skin'),
     ),
-    'primary key' => array('theme', 'module', 'sid'),
     'indexes' => array(
       'theme' => array('theme'),
-      'module' => array('module'),
-      'sid' => array('sid'),
+      'module' => array('theme', 'module'),
+      'element' => array('theme', 'module', 'element'),
+      'skin' => array('skin'),
     ),
   );
 
@@ -101,81 +118,6 @@ function skinr_schema() {
     'primary key' => array('rid'),
   );
 
-  $schema['skinr_skinsets'] = array(
-    'description' => "A list of all non-theme skinsets that are or have been installed in Drupal's file system.",
-    'fields' => array(
-      'filename' => array(
-        'description' => 'The path of the primary file for this item, relative to the Drupal root; e.g. skins/skinset/skinset.info.',
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'name' => array(
-        'description' => 'The name of the item; e.g. skinset.',
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'status' => array(
-        'description' => 'Boolean indicating whether or not this item is enabled.',
-        'type' => 'int',
-        'not null' => TRUE,
-        'default' => 0,
-      ),
-      'info' => array(
-        'description' => "A serialized array containing information from the skinset's .info file; keys can include name, description, package, version, core, and skinr.",
-        'type' => 'text',
-        'not null' => FALSE,
-        'serialize' => TRUE,
-      ),
-    ),
-    'primary key' => array('filename'),
-    'indexes' => array(
-      'name' => array('name'),
-    ),
-  );
-
-  $schema['skinr_skins'] = array(
-    'description' => 'Keeps track of the whether a skin is enabled for a specific skinset and theme.',
-    'fields' => array(
-      'name' => array(
-        'description' => 'The name of the skinset or theme that this skin belongs to.',
-        'type' => 'varchar',
-        'length' => 64,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'type' => array(
-        'description' => 'The type of this item; skinset or theme.',
-        'type' => 'varchar',
-        'length' => 16,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'skin' => array(
-        'description' => 'The name of the skin which you are saving settings for.',
-        'type' => 'varchar',
-        'length' => 128,
-        'not null' => TRUE,
-        'default' => '',
-      ),
-      'status' => array(
-        'description' => 'A serialized array of values for each theme indicating whether or not the skin is enabled.',
-        'type' => 'text',
-        'size' => 'big',
-        'not null' => TRUE,
-        'serialize' => TRUE,
-        ),
-    ),
-    'primary key' => array('name', 'skin'),
-    'indexes' => array(
-      'name' => array('name'),
-      'skin' => array('skin'),
-    ),
-  );
-
   return $schema;
 }
 
@@ -195,95 +137,27 @@ function skinr_uninstall() {
  * Make sure any previous updates aren't skipped.
  */
 function skinr_update_last_removed() {
+  // @todo We probably shouldn't expect people to have ever installed
+  //   Skinr version 6.x-2.x, where updates 6000 through 6003 are from.
   return 6004;
 }
 
 /**
  * Install new skinr tables and convert old variables to the new db system.
+ *
+ * @todo Shoud we remove this?  It was ported from skinr_update_6000(), but
+ *   shouldn't have been.
+ *
+ * Contents removed because the table added here is no longer required.
  */
 function skinr_update_7001() {
-  // Install skinr table.
-  if (!db_table_exists('skinr')) {
-    $schema['skinr'] = array(
-      'description' => 'Stores skinr data.',
-      'fields' => array(
-        'theme' => array(
-          'description' => 'The system name of the theme.',
-          'type' => 'varchar',
-          'length' => 64,
-          'not null' => TRUE,
-          'default' => '',
-        ),
-        'module' => array(
-          'description' => 'The module this skinr settings is for.',
-          'type' => 'varchar',
-          'length' => 64,
-          'not null' => TRUE,
-          'default' => '',
-        ),
-        'sid' => array(
-          'description' => 'A unique identifier for this skinr datum.',
-          'type' => 'varchar',
-          'length' => 128,
-          'not null' => TRUE,
-          'default' => '',
-        ),
-        'skins' => array(
-          'description' => 'The skins set for this datum.',
-          'type' => 'text',
-          'size' => 'big',
-          'not null' => TRUE,
-          'serialize' => TRUE,
-        ),
-        'settings' => array(
-          'description' => 'Custom settings for this id.',
-          'type' => 'text',
-          'size' => 'big',
-          'not null' => TRUE,
-          'serialize' => TRUE,
-        ),
-      ),
-      'primary key' => array('theme', 'module', 'sid'),
-      'indexes' => array(
-        'theme' => array('theme'),
-        'module' => array('module'),
-        'sid' => array('sid'),
-      ),
-    );
-    db_create_table('skinr', $schema['skinr']);
-  }
-
-  // Exclude variables that aren't theme settings (from skinr_ui).
-  $exclude = array('skinr_overlay_width', 'skinr_overlay_height', 'skinr_overlay_autofit', 'skinr_overlay_draggable');
-
-  $result = db_query("SELECT name FROM {variable} WHERE name LIKE 'skinr_%'");
-  foreach ($result as $variable) {
-    if (!in_array($variable->name, $exclude)) {
-      // Convert from variable to db.
-      $theme = substr($variable->name, 6);
-      $skinr = variable_get($variable->name, array());
-      foreach ($skinr as $module => $sids) {
-        foreach ($sids as $sid => $skins) {
-          db_insert('skinr')
-            ->fields(array(
-              'theme' => $theme,
-              'module' => $module,
-              'sid' => $sid,
-              'skins' => serialize($skins),
-              'settings' => serialize(array()),
-            ))
-            ->execute();
-        }
-      }
-
-      // Delete the old variable.
-      variable_del($variable->name);
-    }
-  }
 }
 
 /**
  * Install a new field in {skinr_rules} table.
+ *
+ * @todo Should we remove this? It was ported from skinr_update_6001(), but
+ *   shouldn't have been.
  */
 function skinr_update_7002() {
   // @todo skinr_update_6001() contains additional field manipulations.
@@ -308,86 +182,11 @@ function skinr_update_7002() {
 
 /**
  * Install the new {skinr_skinsets} and {skinr_skins} tables.
+ *
+ * @todo Should we remove this? It was ported from skinr_update_6002() and
+ *   skinr_update_6003(), but should not have been.
+ *
+ * Contents removed because the tables added here are no longer required.
  */
 function skinr_update_7003() {
-  if (!db_table_exists('skinr_skinsets')) {
-    $schema['skinr_skinsets'] = array(
-      'description' => "A list of all non-theme skinsets that are or have been installed in Drupal's file system.",
-      'fields' => array(
-        'filename' => array(
-          'description' => 'The path of the primary file for this item, relative to the Drupal root; e.g. skins/skinset/skinset.info.',
-          'type' => 'varchar',
-          'length' => 255,
-          'not null' => TRUE,
-          'default' => '',
-        ),
-        'name' => array(
-          'description' => 'The name of the item; e.g. skinset.',
-          'type' => 'varchar',
-          'length' => 255,
-          'not null' => TRUE,
-          'default' => '',
-        ),
-        'status' => array(
-          'description' => 'Boolean indicating whether or not this item is enabled.',
-          'type' => 'int',
-          'not null' => TRUE,
-          'default' => 0,
-        ),
-        'info' => array(
-          'description' => "A serialized array containing information from the skinset's .info file; keys can include name, description, package, version, core, and skinr.",
-          'type' => 'text',
-          'not null' => FALSE,
-          'serialize' => TRUE,
-        ),
-      ),
-      'primary key' => array('filename'),
-      'indexes' => array(
-        'name' => array('name'),
-      ),
-    );
-    db_create_table('skinr_skinsets', $schema['skinr_skinsets']);
-  }
-
-  if (!db_table_exists('skinr_skins')) {
-    $schema['skinr_skins'] = array(
-      'description' => 'Keeps track of the whether a skin is enabled for a specific skinset and theme.',
-      'fields' => array(
-        'name' => array(
-          'description' => 'The name of the skinset or theme that this skin belongs to.',
-          'type' => 'varchar',
-          'length' => 64,
-          'not null' => TRUE,
-          'default' => '',
-        ),
-        'type' => array(
-          'description' => 'The type of this item; skinset or theme.',
-          'type' => 'varchar',
-          'length' => 16,
-          'not null' => TRUE,
-          'default' => '',
-        ),
-        'skin' => array(
-          'description' => 'The name of the skin which you are saving settings for.',
-          'type' => 'varchar',
-          'length' => 128,
-          'not null' => TRUE,
-          'default' => '',
-        ),
-        'status' => array(
-          'description' => 'A serialized array of values for each theme indicating whether or not the skin is enabled.',
-          'type' => 'text',
-          'size' => 'big',
-          'not null' => TRUE,
-          'serialize' => TRUE,
-          ),
-      ),
-      'primary key' => array('name', 'skin'),
-      'indexes' => array(
-        'name' => array('name'),
-        'skin' => array('skin'),
-      ),
-    );
-    db_create_table('skinr_skins', $schema['skinr_skins']);
-  }
 }
diff --git skinr.module skinr.module
index dfb9748..8a7b73c 100644
--- skinr.module
+++ skinr.module
@@ -71,6 +71,8 @@ function skinr_init() {
 /**
  * Implements hook_preprocess().
  *
+ * @todo Optimize this function by removing dependencies on
+ *   skinr_get_skin_info() and similar resource heavy functions.
  * @todo Account for Drupal's caching being enabled and make it work.
  */
 function skinr_preprocess(&$variables, $hook) {
@@ -89,16 +91,29 @@ function skinr_preprocess(&$variables, $hook) {
   foreach ($config as $module => $module_settings) {
     if (!empty($module_settings['preprocess'][$original_hook])) {
       $preprocess_settings = $module_settings['preprocess'][$original_hook];
-      $sids = skinr_handler('preprocess_index_handler', 'preprocess', $preprocess_settings['index_handler'], $variables);
-      if (!is_array($sids)) {
-        $sids = array($sids);
+      $elements = skinr_handler('preprocess_index_handler', 'preprocess', $preprocess_settings['index_handler'], $variables);
+      if (empty($elements)) {
+        // We can receive empty arrays; if that happens, there's no point in continuing.
+        continue;
+      }
+
+      // Get a list of skin configuration IDs to pass to
+      // skinr_skin_load_multiple().
+      $params = array(
+        'theme' => $current_theme,
+        'module' => $module,
+        'element' => $elements,
+        'status' => 1,
+      );
+      $sids = skinr_skin_get_sids($params);
+      if (empty($sids)) {
+        // Noting to apply.
+        continue;
       }
 
       $applied_skins = array();
-      foreach ($sids as $sid) {
-        if ($skin = skinr_skin_load($current_theme, $module, $sid)) {
-          $applied_skins = $skin->skins + $applied_skins;
-        }
+      foreach (skinr_skin_load_multiple($sids) as $skin) {
+        $applied_skins = array($skin->skin => $skin->options) + $applied_skins;
       }
 
       // Invoke hook_skinr_preprocess_alter() in all modules.
@@ -109,30 +124,35 @@ function skinr_preprocess(&$variables, $hook) {
         'variables' => &$variables,
         'theme' => $current_theme,
         'module' => $module,
-        'sids' => $sids,
+        'elements' => $elements,
         'options' => $applied_skins,
       );
       drupal_alter('skinr_preprocess', $context);
 
       // Use drupal_process_attached() to add attachements such as JS and CSS.
       if (!empty($applied_skins)) {
-        if (!empty($applied_skins['_options'])) {
-          foreach ($applied_skins['_options'] as $skin_name => $skin_options) {
-            // Make sure this skin is enabled for the current theme.
-            if (!empty($skin_info[$skin_name]['status'][$current_theme])) {
-              if (isset($skin_info[$skin_name]['attached'])) {
-                $elements['#attached'] = $skin_info[$skin_name]['attached'];
-                drupal_process_attached($elements);
-              }
+        foreach ($applied_skins as $skin_name => $skin_options) {
 
-              if (!is_array($skin_options)) {
-                $skin_options = array($skin_options);
-              }
-              foreach ($skin_options as $skin_option) {
-                if (isset($skin_info[$skin_name]['options'][$skin_option]['attached'])) {
-                  $elements['#attached'] = $skin_info[$skin_name]['options'][$skin_option]['attached'];
-                  drupal_process_attached($elements);
-                }
+          // Special case for _additional.
+          if ($skin_name == '_additional') {
+            continue;
+          }
+
+          // Make sure this skin is enabled for the current theme.
+          // @todo Checking for status should probably happen somewhere upstream.
+          if (!empty($skin_info[$skin_name]['status'][$current_theme])) {
+            if (isset($skin_info[$skin_name]['attached'])) {
+              $elements['#attached'] = $skin_info[$skin_name]['attached'];
+              drupal_process_attached($elements);
+            }
+
+            if (!is_array($skin_options)) {
+              $skin_options = array($skin_options);
+            }
+            foreach ($skin_options as $skin_option) {
+              if (isset($skin_info[$skin_name]['options'][$skin_option]['attached'])) {
+                $elements['#attached'] = $skin_info[$skin_name]['options'][$skin_option]['attached'];
+                drupal_process_attached($elements);
               }
             }
           }
@@ -148,31 +168,29 @@ function skinr_preprocess(&$variables, $hook) {
  * Returns an array of classes.
  *
  * @param $skin_options
- *   An array containing the following keys:
- *   - _options: An array of skin options keyed by their skin name.
- *   - _additional: A string containing additional classes to apply.
+ *   An array of skin options keyed by their skin name. The key '_additional'
+ *   is reserved for additional classes entered by the user.
  *
+ * @todo Optimize this function by removing dependencies on the resource heavy
+ *   skinr_get_skin_info() function.
  * @todo Rename function to reflect new functionality.
  */
 function skinr_flatten_skins_array($skin_options) {
-  $skin_infos = skinr_get_skin_info();
+  $skin_info = skinr_get_skin_info();
 
   $classes = array();
-  if (!empty($skin_options['_options'])) {
-    foreach ($skin_options['_options'] as $skin_name => $options) {
-      if (!is_array($options)) {
-        $options = array($options);
-      }
+  foreach ($skin_options as $skin_name => $options) {
+    if ($skin_name == '_additional') {
+      $classes = array_merge($classes, $options);
+    }
+    else {
       foreach ($options as $option) {
-        if (!empty($skin_infos[$skin_name]['options'][$option]['class'])) {
-          $classes = array_merge($classes, $skin_infos[$skin_name]['options'][$option]['class']);
+        if (!empty($skin_info[$skin_name]['options'][$option]['class'])) {
+          $classes = array_merge($classes, $skin_info[$skin_name]['options'][$option]['class']);
         }
       }
     }
   }
-  if (!empty($skin_options['_additional'])) {
-    $classes[] = $skin_options['_additional'];
-  }
   return array_unique($classes);
 }
 
@@ -251,7 +269,7 @@ function skinr_rule_delete($rid) {
       ->execute();
     db_delete('skinr')
       ->condition('module', 'page')
-      ->condition('sid', $rule->rid)
+      ->condition('element', $rule->rid)
       ->execute();
   }
 }
@@ -489,18 +507,18 @@ function skinr_include_once($file) {
  *   TRUE on success, FALSE on failure.
  */
 function skinr_skin_validate(&$skin) {
-  if (!isset($skin->theme) || !isset($skin->module) || !isset($skin->sid) || !isset($skin->skins)) {
+  if (empty($skin->theme) || empty($skin->module) || empty($skin->element) || empty($skin->skin) || empty($skin->options)) {
     return FALSE;
   }
-  if (!isset($skin->settings)) {
-    $skin->settings = array();
-  }
-  if (!is_array($skin->skins) || !is_array($skin->settings)) {
+  if (!is_array($skin->options)) {
     return FALSE;
   }
 
   // Strip empty skins.
-  $skin->skins = _skinr_array_strip_empty($skin->skins);
+  $skin->options = _skinr_array_strip_empty($skin->options);
+  if (empty($skin->options)) {
+    return FALSE;
+  }
 
   return TRUE;
 }
@@ -514,149 +532,230 @@ function skinr_skin_validate(&$skin) {
  * @return
  *   TRUE on success, FALSE on failure.
  */
-function skinr_skin_save($skin) {
+function skinr_skin_save(&$skin) {
   // Make sure we're getting valid data.
   if (!skinr_skin_validate($skin)) {
     return FALSE;
   }
 
-  if (empty($skin->skins) && empty($skin->settings)) {
-    // Delete the db entry if it exists.
-    db_delete('skinr')
-      ->condition('theme', $skin->theme)
-      ->condition('module', $skin->module)
-      ->condition('sid', $skin->sid)
-      ->execute();
+  // Load the stored skin configuration object, if any.
+  if (!empty($skin->sid)) {
+    if (!isset($skin->original)) {
+      // Load an uncached version of the skin configuration object.
+      $skin->original = skinr_skin_load_unchanged($skin->sid);
+    }
+  }
+
+  // Let modules modify the node before it is saved to the database.
+  module_invoke_all('skinr_skin_presave', $skin);
+
+  if (!empty($skin->sid)) {
+    // Record exists, so let's update.
+    $status = drupal_write_record('skinr_skins', $skin, 'sid');
+    module_invoke_all('skinr_skin_update', $skin);
   }
   else {
-    // Let's save the data.
-    if (skinr_skin_load($skin->theme, $skin->module, $skin->sid) !== FALSE) {
-      // Record exists, so let's update.
-      drupal_write_record('skinr', $skin, array('theme', 'module', 'sid'));
-    }
-    else {
-      // Insert a new record.
-      drupal_write_record('skinr', $skin);
-    }
+    // Insert a new record.
+    $status = drupal_write_record('skinr_skins', $skin);
+    module_invoke_all('skinr_skin_insert', $skin);
   }
 
-  return TRUE;
+  // Clear internal properties.
+  unset($skin->original);
+  // Clear the static loading cache.
+  // @todo If we have a more granular reset for skinr_skin_load_multiple(), we
+  //   need to use it here.
+  drupal_static_reset('skinr_skin_load_multiple');
+
+  return $status;
 }
 
 /**
  * Delete a skin object.
  *
- * @param $theme
- *   The theme this skin applies to. If no theme name is provided, the
- *   current theme will be used.
- * @param $module
- *   The module.
  * @param $sid
- *   The element ID.
+ *   The skin configuration ID.
  */
-function skinr_skin_delete($theme = NULL, $module = NULL, $sid = NULL) {
-  node_delete_multiple(array(array($theme, $module, $sid)));
+function skinr_skin_delete($sid) {
+  skinr_skin_delete_multiple(array($sid));
 }
 
 /**
- * Delete multiple skin objects.
- *
- * @param $arguments
- *   An array of arrays containing the following arguments:
- *   - $theme
- *   - $module
- *   - $sid
+ * Delete multiple skin configuration objects.
  *
- * @see skinr_skin_delete().
- *
- * @todo Make this function functional.
+ * @param $sids
+ *   An array of skin configuration IDs.
  */
-function skinr_skin_delete_multiple($arguments) {
+function skinr_skin_delete_multiple($sids) {
+  $transaction = db_transaction();
+  if (!empty($sids)) {
+    $skins = skinr_skin_load_multiple($sids);
+
+    try {
+      foreach ($skins as $sid => $skin) {
+        module_invoke_all('skinr_skin_delete', $skin);
+      }
+
+      // Delete after calling hooks so that they can query node tables as needed.
+      db_delete('skinr_skins')
+        ->condition('sid', $sids, 'IN')
+        ->execute();
+    }
+    catch (Exception $e) {
+      $transaction->rollback();
+      watchdog_exception('skinr', $e);
+      throw $e;
+    }
+
+    // Clear the skinr_skin_load_multiple cache.
+    drupal_static_reset('skinr_skin_load_multiple');
+  }
 }
 
 /**
- * Retrieves a stored skin from the database.
+ * Load a skin configuration object from the database.
  *
- * @param $theme
- *   The theme of the skin. Defaults to the current theme.
- * @param $module
- *   The module of the skin.
  * @param $sid
- *   The element ID of the skin.
+ *   The skin configuration ID.
  *
  * @return
- *   A skin object if both $module and $sid are specified. An array of skins
- *   if only $module is specified. An array of all skins for a theme if neither
- *   $module nor $sid is specified. FALSE on failure.
+ *   A fully-populated skin configuration object.
+ */
+function skinr_skin_load($sid = NULL) {
+  $sids = (isset($sid) ? array($sid) : array());
+  $skin = skinr_skin_load_multiple($sids);
+  return $skin ? reset($skin) : FALSE;
+}
+
+/**
+ * Load skin configuration objects from the database.
+ *
+ * This function should be used whenever you need to load more than one skin
+ * configuration from the database. Skin configurations are loaded into memory
+ * and will not require database access if loaded again during the same page
+ * request.
  *
- * @todo Rename $skin->skins to $skin->options throughout the module.
+ * @see skinr_skin_get_sids()
+ *
+ * @param $sids
+ *   An array of skin configuration IDs.
+ *
+ * @return
+ *   An array of skin configuration objects indexed by sid.
  */
-function skinr_skin_load($theme = NULL, $module = NULL, $sid = NULL) {
+function skinr_skin_load_multiple($sids = array()) {
+  // @todo Do we want to write a more granular cache reset?
   $skins = &drupal_static(__FUNCTION__, array());
 
-  if (!isset($theme)) {
-    $theme = skinr_current_theme();
+  // Create a new variable which is either a prepared version of the $sids
+  // array for later comparison with cached skin configuration objects, or FALSE
+  // if no $sids were passed. The $sids 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 configuration objects are
+  // loaded from cache.
+  $passed_sids = !empty($sids) ? array_flip($sids) : FALSE;
+  if ($passed_sids) {
+    $sids = array_keys(array_diff_key($passed_sids, $skins));
   }
 
-  // @todo This condition is always FALSE when no $sid is passed.
-  if (!isset($skins[$theme][$module][$sid])) {
-    $skins += array($theme => array());
-    if (isset($module)) {
-      $skins[$theme] += array($module => array());
-    }
-
-    $query = db_select('skinr', 's')
-      ->fields('s', array('theme', 'module', 'sid', 'settings', 'skins'));
-    if (isset($theme)) {
-      $query->condition('theme', $theme);
-    }
-    if (isset($module)) {
-      $query->condition('module', $module);
-    }
-    if (isset($sid)) {
-      $query->condition('sid', $sid);
-    }
-    foreach ($query->execute() as $skin) {
-      $skin->settings = unserialize($skin->settings);
-      $skin->skins = unserialize($skin->skins);
-      $skins[$skin->theme][$skin->module][$skin->sid] = $skin;
+  // Load any remaining skin configurations from the database. This is the
+  // case if $sids is set to FALSE (so we load all skins), or if there are any
+  // sids left to load.
+  if ($sids === FALSE || $sids) {
+    // Build the query.
+    $queried_skins = db_select('skinr_skins', 's')
+      ->fields('s')
+      ->condition('sid', $sids)
+      ->execute()
+      ->fetchAllAssoc('sid');
+
+    foreach ($queried_skins as $sid => $skin) {
+      // Unserialize options array.
+      $queried_skins[$sid]->options = unserialize($skin->options);
+
+      // Let modules modify the skin configurations.
+      module_invoke_all('skinr_skin_load', $queried_skins[$sid]);
     }
+    $skins += $queried_skins;
   }
 
-  // Return all skins for the passed theme.
-  if (!isset($module) && !isset($sid)) {
-    if (isset($skins[$theme])) {
-      return $skins[$theme];
-    }
-  }
-  // Return all skins for the passed module.
-  elseif (!isset($sid)) {
-    if (isset($skins[$theme][$module])) {
-      return $skins[$theme][$module];
+  // Ensure that the returned array is ordered the same as the original
+  // $sids array if this was passed in and remove any invalid sids.
+  if ($passed_sids) {
+    // Remove any invalid sids from the array.
+    $passed_sids = array_intersect_key($passed_sids, $skins);
+    $return = array();
+    foreach ($passed_sids as $sid => $ignore) {
+      $return[$sid] = $skins[$sid];
     }
   }
-  // Return the requested skin.
-  elseif (isset($skins[$theme][$module][$sid])) {
-    return $skins[$theme][$module][$sid];
+  else {
+    $return = $skins;
   }
-  return FALSE;
+
+  return $return;
 }
 
 /**
- * Load multiple skin objects.
+ * Load an uncached version of a skin configuration object.
+ *
+ * @param $sid
+ *   The skin configuration ID.
  *
- * @param $arguments
- *   An array of arrays containing the following arguments:
- *   - $theme
- *   - $module
- *   - $sid
+ * @return
+ *   A fully-populated skin configuration object.
+ */
+function skinr_skin_load_unchanged($sid) {
+  // Load an uncached version of the skin configuration object.
+  $skin = db_query("SELECT * FROM {skinr_skins} WHERE sid = :sid", array(
+    ':sid' => $sid,
+  ))
+  ->fetchObject();
+
+  // Unserialize options array.
+  $skin->options = unserialize($skin->options);
+
+  // Let modules modify the skin configuration.
+  module_invoke_all('skinr_skin_load', $skin);
+
+  return $skin;
+}
+
+/**
+ * Get skin configuration IDs.
  *
- * @see skinr_skin_load().
+ * @param $filter_by
+ *   An associative array whose keys are:
+ *   - theme: (optional) The theme.
+ *   - module: (optional) The module.
+ *   - element: (optional) The element ID.
+ *   - skin: (optional) The skin name.
+ *   - status: (optional) Boolean indicating whether or not this skin
+ *     configuration is enabled.
  *
- * @todo Make this function functional.
- * @todo Look at using hook_entity_info() and entity_load().
+ * @return
+ *   An array of skin configuration IDs.
  */
-function skinr_skin_load_multiple($arguments) {
+function skinr_skin_get_sids($filter_by = array()) {
+  $query = db_select('skinr_skins', 's')
+      ->fields('s', array('sid'));
+  if (isset($filter_by['theme'])) {
+    $query->condition('theme', $filter_by['theme']);
+  }
+  if (isset($filter_by['module'])) {
+    $query->condition('module', $filter_by['module']);
+  }
+  if (isset($filter_by['element'])) {
+    $query->condition('element', $filter_by['element']);
+  }
+  if (isset($filter_by['skin'])) {
+    $query->condition('skin', $filter_by['skin']);
+  }
+  if (isset($filter_by['status'])) {
+    $query->condition('status', $filter_by['status']);
+  }
+  return $query->execute()
+    ->fetchCol();
 }
 
 /**
@@ -788,7 +887,7 @@ function _skinr_add_path_to_files(&$files, $path) {
  * script paths to be relative to Drupal's root.
  *
  * @param $skin_infos
- *   A skins array as returned from a skins plugin.
+ *   An array of skins as returned from skin plugins.
  * @param $source
  *   An associative array containing information about the source of the skin.
  *   See skinr_implements() for details.
@@ -1128,4 +1227,3 @@ function skinr_themes_enabled() {
 function skinr_themes_disabled() {
   skinr_cache_reset();
 }
-
diff --git skinr.skinr.inc skinr.skinr.inc
index fc260e8..a5a5c37 100644
--- skinr.skinr.inc
+++ skinr.skinr.inc
@@ -114,7 +114,7 @@ function rules_skinr_preprocess_hook_callback(&$form, $form_state) {
     $hooks = explode('__', $form['rule']['rule_type']['#value']);
   }
   else {
-    $rule = skinr_rule_load($form['skinr']['sid']['#value']);
+    $rule = skinr_rule_load($form['skinr']['element']['#value']);
     $hooks = explode('__', $rule->rule_type);
   }
   while (count($hooks)) {
diff --git skinr_ui.admin.inc skinr_ui.admin.inc
index d464f1f..6e117df 100644
--- skinr_ui.admin.inc
+++ skinr_ui.admin.inc
@@ -6,12 +6,22 @@
  */
 
 /**
- * Implements hook_skinr_operations().
+ * Implements hook_skinr_ui_operations().
  */
-function skinr_ui_skinr_operations() {
+function skinr_ui_skinr_ui_operations() {
   $operations = array(
+    'enable' => array(
+      'label' => t('Enable selected skin configuration'),
+      'callback' => 'skinr_ui_mass_update',
+      'callback arguments' => array('updates' => array('status' => 1)),
+    ),
+    'disable' => array(
+      'label' => t('Disable selected skin configuration'),
+      'callback' => 'skinr_ui_mass_update',
+      'callback arguments' => array('updates' => array('status' => 0)),
+    ),
     'delete' => array(
-      'label' => t('Delete selected Skinr settings'),
+      'label' => t('Delete selected skin configuration'),
       'callback' => NULL,
     ),
   );
@@ -50,20 +60,56 @@ function skinr_ui_filters() {
     $options[$type] = $type;
   }
 
-  $filters['type'] = array(
+  $filters['module'] = array(
     'title' => t('type'),
     'options' => $options,
   );
 
+  // Skin filter.
+  $skin_info = skinr_get_skin_info();
+
+  $options = array('[any]' => t('any'), '_additional' => t('Additional classes'));
+  foreach ($skin_info as $skin => $info) {
+    $options[$skin] = $info['title'];
+  }
+
+  $filters['skin'] = array(
+    'title' => t('skin'),
+    'options' => $options,
+  );
+
+  // Status filter.
+  $filters['status'] = array(
+    'title' => t('status'),
+    'options' => array(
+      '[any]' => t('any'),
+      '1' => t('enabled'),
+      '0' => t('disabled'),
+    ),
+  );
+
   return $filters;
 }
 
 /**
+ * Apply filters for skin configuration administration filters based on session.
+ *
+ * @param $query
+ *   A SelectQuery to which the filters should be applied.
+ */
+function skinr_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;
+    $query->condition('s.' . $key, $value);
+  }
+}
+
+/**
  * Form builder for the Skinr administration filters form.
  *
  * @ingroup forms
- *
- * @todo This function is missing the $form and $form_state parameters.
  */
 function skinr_ui_filter_form() {
   $session = &$_SESSION['skinr_ui_overview_filter'];
@@ -87,10 +133,8 @@ function skinr_ui_filter_form() {
     else {
       $form['filters']['current'][] = array('#markup' => t('where %property is %value', $t_args));
     }
-    if (in_array($type, array('theme', 'type'))) {
-      // Remove the option if it is already being filtered on.
-      unset($filters[$type]);
-    }
+    // Remove the option if it is already being filtered on.
+    unset($filters[$type]);
   }
 
   $form['filters']['status'] = array(
@@ -135,6 +179,111 @@ function skinr_ui_filter_form() {
 }
 
 /**
+ * Mass update skin configurations, updating all skin configurations in the
+ * $skins array with the field values in $updates.
+ *
+ * IMPORTANT NOTE: This function is intended to work when called
+ * from a form submit handler. Calling it outside of the form submission
+ * process may not work correctly.
+ *
+ * @param array $skins
+ *   Array of skin configuration sids to update.
+ * @param array $updates
+ *   Array of key/value pairs with skin configuration field names and the
+ *   value to update that field to.
+ */
+function skinr_ui_mass_update($skins, $updates) {
+  // We use batch processing to prevent timeout when updating a large number
+  // of skins.
+  if (count($skins) > 10) {
+    $batch = array(
+      'operations' => array(
+        array('_skinr_ui_mass_update_batch_process', array($skins, $updates))
+      ),
+      'finished' => '_skinr_ui_mass_update_batch_finished',
+      'title' => t('Processing'),
+      // We use a single multi-pass operation, so the default
+      // 'Remaining x of y operations' message will be confusing here.
+      'progress_message' => '',
+      'error_message' => t('The update has encountered an error.'),
+      // The operations do not live in the .module file, so we need to
+      // tell the batch engine which file to load before calling them.
+      'file' => drupal_get_path('module', 'skinr_ui') . '/skinr_ui.admin.inc',
+    );
+    batch_set($batch);
+  }
+  else {
+    foreach ($skins as $sid) {
+      _skinr_ui_mass_update_helper($sid, $updates);
+    }
+    drupal_set_message(t('The update has been performed.'));
+  }
+}
+
+/**
+ * Helper function for skin configuration mass updates.
+ */
+function _skinr_ui_mass_update_helper($sid, $updates) {
+  drupal_static_reset('skinr_skin_load_multiple');
+  $skin = skinr_skin_load($sid);
+  // For efficiency manually store the original skin configuration before
+  // applying any changes.
+  $skin->original = clone $skin;
+  foreach ($updates as $name => $value) {
+    $skin->$name = $value;
+  }
+  skinr_skin_save($skin);
+  return $skin;
+}
+
+/**
+ * Batch operation for skin configuration mass updates.
+ */
+function _skinr_ui_mass_update_batch_process($skins, $updates, &$context) {
+  if (!isset($context['sandbox']['progress'])) {
+    $context['sandbox']['progress'] = 0;
+    $context['sandbox']['max'] = count($skins);
+    $context['sandbox']['skins'] = $skins;
+  }
+
+  // Process skins in groups of 5.
+  $count = min(5, count($context['sandbox']['skins']));
+  for ($i = 1; $i <= $count; $i++) {
+    // For each sid, load the skin configuration, reset the values, and save it.
+    $sid = array_shift($context['sandbox']['skins']);
+    $skin = _skinr_ui_mass_update_helper($sid, $updates);
+
+    // Store result for post-processing in the finished callback.
+    // @todo
+    $context['results'][] = l($skin->title, 'node/' . $skin->sid);
+
+    // Update our progress information.
+    $context['sandbox']['progress']++;
+  }
+
+  // Inform the batch engine that we are not finished,
+  // and provide an estimation of the completion level we reached.
+  if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
+    $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
+  }
+}
+
+/**
+ * Batch 'finished' callback for skin configuration mass updates.
+ */
+function _skinr_ui_mass_update_batch_finished($success, $results, $operations) {
+  if ($success) {
+    drupal_set_message(t('The update has been performed.'));
+  }
+  else {
+    drupal_set_message(t('An error occurred and processing did not complete.'), 'error');
+    $message = format_plural(count($results), '1 item successfully processed:', '@count items successfully processed:');
+    $message .= theme('item_list', array('items' => $results));
+    drupal_set_message($message);
+  }
+}
+
+/**
  * Form submission handler for skinr_ui_filter_form().
  */
 function skinr_ui_filter_form_submit($form, &$form_state) {
@@ -164,7 +313,7 @@ function skinr_ui_filter_form_submit($form, &$form_state) {
 }
 
 /**
- * Form builder for the Skinr settings overview form.
+ * Menu callback: content administration.
  *
  * @ingroup forms
  */
@@ -180,32 +329,27 @@ function skinr_ui_list($form, &$form_state) {
 }
 
 /**
- * Subform builder for the Skinr settings overview form.
+ * Form builder: Builds the skin configuration administration overview.
  *
  * @ingroup forms
  */
 function skinr_ui_admin_skins() {
-  $session = !empty($_SESSION['skinr_ui_overview_filter']) && is_array($_SESSION['skinr_ui_overview_filter']) ? $_SESSION['skinr_ui_overview_filter'] : array();
-  $filters = array();
-  foreach ($session as $filter) {
-    list($key, $value) = $filter;
-    $filters[$key] = $value;
-  }
-
-  // Build an 'Update options' form.
+  // Build the 'Update options' form.
   $form['options'] = array(
     '#type' => 'fieldset',
     '#title' => t('Update options'),
     '#attributes' => array('class' => array('container-inline')),
   );
-
   $options = array();
-  $options['delete'] = t('Delete the selected Skinr settings');
-
+  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' => 'publish',
+    '#default_value' => 'enable',
   );
   $form['options']['submit'] = array(
     '#type' => 'submit',
@@ -214,97 +358,67 @@ function skinr_ui_admin_skins() {
     '#submit' => array('skinr_ui_admin_skins_submit'),
   );
 
-  $sorts = array();
-
-  $headers = array(
-    'theme' => array('data' => t('Theme'), 'field' => 'theme'),
-    'type' => array('data' => t('Type'), 'field' => 'type'),
-    'sid' => array('data' => t('Skinr ID'), 'field' => 'sid'),
+  $header = array(
+    'theme' => array('data' => t('Theme'), 'field' => 's.theme'),
+    'type' => array('data' => t('Type'), 'field' => 's.module'),
+    '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')),
   );
 
-  $ts = tablesort_init($headers);
-  $sort = SORT_DESC;
-  if ($ts['sort'] == 'asc') {
-    $sort = SORT_ASC;
-  }
+  $query = db_select('skinr_skins', 's')->extend('PagerDefault')->extend('TableSort');
+  skinr_ui_build_filter_query($query);
 
-  switch ($ts['sql']) {
-    case 'type':
-    case 'sid':
-      $sortby = $ts['sql'];
-      break;
-
-    case 'theme':
-    default:
-      $sortby = 'theme';
-      break;
-  }
+  $sids = $query
+    ->fields('s', array('sid'))
+    ->limit(50)
+    ->orderByHeader($header)
+    ->execute()
+    ->fetchCol();
+  $skins = skinr_skin_load_multiple($sids);
 
   $themes = list_themes();
-  ksort($themes);
-
-  $options = array();
+  $skin_info = skinr_get_skin_info();
   $destination = drupal_get_destination();
-  $type = !empty($filters['type']) ? $filters['type'] : NULL;
-
-  foreach ($themes as $theme) {
-    if (!$theme->status || !empty($theme->info['hidden']) || (!empty($filters['theme']) && $filters['theme'] != $theme->name)) {
-      continue;
-    }
-    if (empty($type)) {
-      $skins = skinr_skin_load($theme->name);
-    }
-    else {
-      $skins = array($type => skinr_skin_load($theme->name, $type));
-    }
-
-    // skinr_skin_load() could return NULL for this theme.
-    if (!empty($skins)) {
-      foreach ($skins as $module => $elements) {
-        foreach ($elements as $sid => $skin) {
-          $operations = array(
-            'edit' => array(
-              'title' => t('edit'),
-              'href' => 'admin/appearance/skinr/edit/nojs/' . $module . '/' . $sid,
-              'query' => $destination,
-            ),
-            'delete' => array(
-              'title' => t('delete'),
-              'href' => 'admin/appearance/skinr/delete/'. $theme->name .'/'. $module .'/'. $sid,
-              'query' => $destination,
-            ),
-          );
-          $options[$theme->name . '__' . $module . '__' . $sid] = array(
-            'theme' => $theme->info['name'],
-            'type' => $module,
-            'sid' => $sid,
-            'operations' => array(
-              'data' => array(
-                '#theme' => 'links__skinr_operations',
-                '#links' => $operations,
-                '#attributes' => array('class' => array('links', 'inline')),
-              ),
-            ),
-          );
-          $sorts[] = strip_tags($options[$theme->name . '__' . $module . '__' . $sid][$sortby]);
-        }
-      }
-    }
+  $options = array();
+  foreach ($skins as $skin) {
+    $operations = array(
+      'edit' => array(
+        'title' => t('edit'),
+        'href' => 'admin/appearance/skinr/edit/nojs/' . $skin->module . '/' . $skin->element,
+        'query' => $destination,
+      ),
+      'delete' => array(
+        'title' => t('delete'),
+        'href' => 'admin/appearance/skinr/delete/'. $skin->sid,
+        'query' => $destination,
+      ),
+    );
+    $options[$skin->sid] = array(
+      'theme' => isset($themes[$skin->theme]) ? $themes[$skin->theme]->info['name'] : '<em>' . $skin->theme . '</em>',
+      'type' => $skin->module,
+      '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')),
+        ),
+      ),
+    );
   }
 
-  // Sort table.
-  array_multisort($sorts, $sort, $options);
-
-  // Output table.
   $form['skins'] = array(
     '#type' => 'tableselect',
-    '#header' => $headers,
+    '#header' => $header,
     '#options' => $options,
     '#empty' => t('No content available.'),
   );
-  $form['pager'] = array('#markup' => theme('pager', array('tags' => NULL)));
 
+  $form['pager'] = array('#markup' => theme('pager'));
   return $form;
 }
 
@@ -327,7 +441,7 @@ function skinr_ui_admin_skins_validate($form, &$form_state) {
  * Execute the chosen 'Update option' on the selected skinr settings.
  */
 function skinr_ui_admin_skins_submit($form, &$form_state) {
-  $operations = module_invoke_all('skinr_operations');
+  $operations = module_invoke_all('skinr_ui_operations');
   $operation = $operations[$form_state['values']['operation']];
   // Filter out unchecked nodes
   $nodes = array_filter($form_state['values']['skins']);
@@ -363,13 +477,13 @@ function skinr_ui_multiple_delete_confirm($form, &$form_state, $skins) {
 
   $form['skins'] = array('#prefix' => '<ul>', '#suffix' => '</ul>', '#tree' => TRUE);
   // array_filter returns only elements with TRUE values
-  foreach ($skins as $skin => $value) {
-    $parts = explode('__', $skin, 3);
-    $form['skins'][$skin] = array(
+  $original_skins = skinr_skin_load_multiple(array_keys($skins));
+  foreach ($skins as $sid => $value) {
+    $form['skins'][$sid] = array(
       '#type' => 'hidden',
-      '#value' => $skin,
+      '#value' => $sid,
       '#prefix' => '<li>',
-      '#suffix' => t('Skinr ID %sid of type %type for theme %theme', array('%sid' => $parts[2], '%type' => $parts[1], '%theme' => $themes[$parts[0]]->info['name'])) ."</li>\n",
+      '#suffix' => t('Skin %skin for element %element of type %type for the %theme theme', array('%skin' => $original_skins[$sid]->skin, '%element' => $original_skins[$sid]->element, '%type' => $original_skins[$sid]->module, '%theme' => $themes[$original_skins[$sid]->theme]->info['name'])) ."</li>\n",
     );
   }
   $form['operation'] = array('#type' => 'hidden', '#value' => 'delete');
@@ -388,26 +502,15 @@ function skinr_ui_multiple_delete_confirm($form, &$form_state, $skins) {
  */
 function skinr_ui_multiple_delete_confirm_submit($form, &$form_state) {
   if ($form_state['values']['confirm']) {
-    foreach ($form_state['values']['skins'] as $skin => $value) {
-      $parts = explode('__', $skin, 3);
-
-      $skin = new StdClass();
-      $skin->theme = $parts[0];
-      $skin->module = $parts[1];
-      $skin->sid = $parts[2];
-      $skin->skins = array();
-
-      skinr_skin_save($skin);
-    }
-
+    skinr_skin_delete_multiple(array_keys($form_state['values']['skins']));
     $count = count($form_state['values']['skins']);
     if ($count == 1) {
-      watchdog('content', 'Deleted 1 skinr setting.');
+      watchdog('content', 'Deleted 1 skin configuration.');
     }
     else {
-      watchdog('content', 'Deleted @count skinr settings.', array('@count' => $count));
+      watchdog('content', 'Deleted @count skin configurations.', array('@count' => $count));
     }
-    drupal_set_message(format_plural($count, 'Deleted 1 skinr setting.', 'Deleted @count skinr settings.'));
+    drupal_set_message(format_plural($count, 'Deleted 1 skin configuration.', 'Deleted @count skin configurations.'));
   }
   $form_state['redirect'] = 'admin/appearance/skinr';
 }
@@ -417,6 +520,8 @@ function skinr_ui_multiple_delete_confirm_submit($form, &$form_state) {
  *
  * @ingroup forms
  * @see skinr_ui_admin_skin_infos_submit()
+ *
+ * @todo This should not be a form, just a plain page callback.
  */
 function skinr_ui_admin_skin_infos($form, $form_state) {
   $skins = skinr_get_skin_info();
@@ -558,7 +663,8 @@ function skinr_ui_sort_by_title($a, $b) {
 /**
  * Form submission handler for skinr_ui_admin_skin_infos().
  *
- * @todo Update status storage code.
+ * @todo Nix this; status update only happen through hitting the 'configure'
+ *   link for a skin.
  */
 function skinr_ui_admin_skin_infos_submit($form, &$form_state) {
   // Store list of previously enabled themes and disable all themes.
@@ -864,16 +970,19 @@ function skinr_ui_export_form($form, &$form_state, $theme = NULL) {
   if ($theme) {
     // Export an individual theme.
     $theme = str_replace('-', '_', $theme);
-    $skins = skinr_skin_load($theme);
+    $params = array(
+      'theme' => $theme,
+    );
+    $skins = skinr_skin_load_multiple(skinr_skin_get_sids($params));
 
     // Convert classes to arrays.
-    foreach ($skins as $module => $data) {
-      foreach ($data as $sid => $skin) {
-        $skins[$module][$sid] = (array) $skins[$module][$sid];
-      }
+    $code = '';
+    foreach ($skins as $skin) {
+      unset($skin->sid);
+      unset($skin->rdf_mapping);
+      $code .= '$skins[] = '. var_export((array) $skin, TRUE) .";\n";
     }
 
-    $code = '$skins = '. var_export($skins, TRUE) .';';
     $lines = substr_count($code, "\n") + 1;
 
     $form['theme'] = array(
@@ -954,41 +1063,10 @@ function skinr_ui_export_form_submit(&$form, &$form_state) {
  * @ingroup forms
  */
 function skinr_ui_import_form($form, &$form_state) {
-  $form = array();
-
-  $options = array();
-  $themes = list_themes();
-  ksort($themes);
-  $current_theme = skinr_current_theme(TRUE);
-
-  // Put default theme at the top.
-  $options[$current_theme] = $themes[$current_theme]->info['name']. ' [' . t('default') . ']';
-
-  foreach ($themes as $theme) {
-    if (!empty($theme->info['hidden'])) {
-      continue;
-    }
-    if ($theme->name == $current_theme) {
-      // Do nothing.
-    }
-    elseif ($theme->status) {
-      $options[$theme->name] = $theme->info['name'] . ' [' . t('enabled') . ']';
-    }
-    else {
-      $options[$theme->name] = $theme->info['name'];
-    }
-  }
-
-  $form['theme'] = array(
-    '#type' => 'select',
-    '#title' => t('Theme'),
-    '#options' => $options,
-    '#required' => TRUE,
-  );
-  $form['skinr_settings'] = array(
+  $form['skin_configurations'] = array(
     '#type' => 'textarea',
-    '#title' => t('Skinr settings'),
-    '#description' => t('Paste skinr settings here.'),
+    '#title' => t('Skin configurations'),
+    '#description' => t('Paste skin coonfigurations here.'),
     '#rows' => 16,
   );
   $form['submit'] = array(
@@ -1003,57 +1081,55 @@ function skinr_ui_import_form($form, &$form_state) {
  * Form validation handler for skinr_ui_import_form().
  */
 function skinr_ui_import_form_validate(&$form, &$form_state) {
-  if (empty($form_state['values']['skinr_settings'])) {
+  if (empty($form_state['values']['skin_configurations'])) {
     // Error.
-    form_error($form['skinr_settings'], t('These are not valid Skinr settings.'));
+    form_error($form['skin_configurations'], t('These are not valid skin configurations.'));
     return;
   }
 
   $skins = '';
   ob_start();
-  eval($form_state['values']['skinr_settings']);
+  eval($form_state['values']['skin_configurations']);
   ob_end_clean();
 
-  foreach ($skins as $module => $ignored) {
-    if (!is_array($skins[$module])) {
-      // Error.
-      form_error($form['skinr_settings'], t('These are not valid Skinr settings.'));
+  foreach ($skins as $key => $skin) {
+    if (!is_array($skin)) {
+      form_error($form['skin_configurations'], t('These are not valid skin configurations.'));
+      break;
     }
-    foreach ($skins[$module] as $sid => $ignored) {
-      if (!is_array($skins[$module][$sid])) {
-        // Error.
-        form_error($form['skinr_settings'], t('These are not valid Skinr settings.'));
-      }
-
-      // Cast skinr array to object so we can actually use it.
-      $skins[$module][$sid] = (object) $skins[$module][$sid];
-      if (!skinr_validate($skins[$module][$sid])) {
-        // Error.
-        form_error($form['skinr_settings'], t('These are not valid Skinr settings.'));
-      }
+    $skins[$key] = (object) $skin;
+    if (!skinr_skin_validate($skins[$key])) {
+      form_error($form['skin_configurations'], t('These are not valid skin configurations.'));
     }
   }
 
-  if (!empty($form_state['values']['theme']) && preg_match('/[^a-zA-Z0-9_]/', $form_state['values']['theme'])) {
-    form_error($form['theme'], t('The theme name must be alphanumeric and can contain underscores only.'));
-  }
-
-  $form_state['skinrs'] = &$skins;
+  $form_state['skins'] = &$skins;
 }
 
 /**
  * Form submission handler for skinr_ui_import_form().
  */
 function skinr_ui_import_form_submit(&$form, &$form_state) {
-  foreach ($form_state['skinrs'] as $module => $skins) {
-    foreach ($skins as $sid => $skin) {
-      if (!skinr_skin_save($skin)) {
-        drupal_set_message(t('Skinr settings for the theme %theme could not be saved!', array('%theme' => $form_state['values']['theme'])), 'error');
-      }
+  foreach ($form_state['skins'] as $skin) {
+    // Find existing skin configuration and grab its sid.
+    $params = array(
+      'theme' => $skin->theme,
+      'module' => $skin->module,
+      'element' => $skin->element,
+      'skin' => $skin->skin,
+    );
+    $sids = skinr_skin_get_sids($params);
+    if (!empty($sids)) {
+      $skin->sid = reset($sids);
+    }
+
+    // Save skin configuration.
+    if (!skinr_skin_save($skin)) {
+      drupal_set_message(t('Not all skin configurations could be saved!'), 'error', FALSE);
     }
   }
 
-  drupal_set_message(t('Skinr settings for the theme %theme have been saved.', array('%theme' => $form_state['values']['theme'])));
+  drupal_set_message(t('The skin configurations have been saved.'));
   drupal_goto('admin/appearance/skinr');
 }
 
@@ -1064,31 +1140,24 @@ function skinr_ui_import_form_submit(&$form, &$form_state) {
  *   The name of the theme to delete a setting for.
  * @param $module
  *   The module to delete a setting for.
- * @param $sid
+ * @param $element
  *   The ID of the setting to delete.
  *
  * @ingroup forms
  */
-function skinr_ui_delete_confirm($form, &$form_state, $theme, $module, $sid) {
-  $form['theme'] = array(
-    '#type' => 'value',
-    '#value' => isset($form_state['theme']) ? $form_state['theme'] : $theme,
-  );
-  $form['module'] = array(
-    '#type' => 'value',
-    '#value' => isset($form_state['module']) ? $form_state['module'] : $module,
-  );
+function skinr_ui_delete_confirm($form, &$form_state, $skin) {
+  $form['#skin'] = $skin;
+  // Always provide entity id in the same form key as in the entity edit form.
   $form['sid'] = array(
     '#type' => 'value',
-    '#value' => isset($form_state['sid']) ? $form_state['sid'] : $sid,
+    '#value' => $skin->sid,
   );
 
   $themes = list_themes();
-
   return confirm_form($form,
-    t('Are you sure you want to delete these Skinr settings?'),
+    t('Are you sure you want to delete this skin configuration?'),
     isset($_GET['destination']) ? $_GET['destination'] : 'admin/appearance/skinr',
-    t('This action cannot be undone.<br /> Theme: !theme<br />Module: !module<br />Skinr ID: !sid', array('!theme' => $themes[$theme]->info['name'], '!module' => $module, '!sid' => $sid)),
+    t('This action cannot be undone.<br />Theme: %theme<br />Module: %module<br />Element: %element<br />Skin: %skin', array('%theme' => $themes[$skin->theme]->info['name'], '%module' => $skin->module, '%element' => $skin->element, '%skin' => $skin->skin)),
     t('Delete'),
     t('Cancel')
   );
@@ -1099,14 +1168,9 @@ function skinr_ui_delete_confirm($form, &$form_state, $theme, $module, $sid) {
  */
 function skinr_ui_delete_confirm_submit($form, &$form_state) {
   if ($form_state['values']['confirm']) {
-    $skin = new stdClass();
-    $skin->theme = $form_state['values']['theme'];
-    $skin->module = $form_state['values']['module'];
-    $skin->sid = $form_state['values']['sid'];
-    $skin->skins = array();
-    $skin->settings = array();
-
-    skinr_skin_save($skin);
+    skinr_skin_delete($form_state['values']['sid']);
+    watchdog('content', 'Deleted a skin configuration.');
+    drupal_set_message(t('A skin configuration has been deleted.'));
   }
 
   $form_state['redirect'] = 'admin/appearance/skinr';
diff --git skinr_ui.module skinr_ui.module
index f41d604..ba60df7 100644
--- skinr_ui.module
+++ skinr_ui.module
@@ -29,7 +29,7 @@ function skinr_ui_permission() {
 function skinr_ui_menu() {
   $items['admin/appearance/skinr'] = array(
     'title' => 'Skinr',
-    'description' => 'Manage your skinr settings and rules, import and export skinr settings for each theme, and configure skinr\'s overlay settings.',
+    'description' => 'Manage your skin configurations and rules, import and export skin configurations.',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('skinr_ui_list'),
     'access arguments' => array('administer skinr'),
@@ -38,7 +38,7 @@ function skinr_ui_menu() {
   );
   $items['admin/appearance/skinr/list'] = array(
     'title' => 'List',
-    'description' => t('Manage Skinr settings.'),
+    'description' => t('Manage skinr configurations.'),
     'type' => MENU_DEFAULT_LOCAL_TASK,
     'weight' => -10,
   );
@@ -46,7 +46,7 @@ function skinr_ui_menu() {
   // Themes.
   $items['admin/appearance/skinr/skins'] = array(
     'title' => 'Skins',
-    'description' => 'Manage which skins are available when changing Skinr settings.',
+    'description' => 'Manage which skins are available when applying a skin configuration.',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('skinr_ui_admin_skin_infos'),
     'access arguments' => array('administer skinr'),
@@ -63,7 +63,7 @@ function skinr_ui_menu() {
     'title' => 'Skin settings',
     'title callback' => 'skinr_ui_skin_info_title',
     'title arguments' => array(5),
-    'description' => 'Manage which options are available for each Skin when changing Skinr settings.',
+    'description' => 'Manage which options are available for each skin when applying a skin configuration.',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('skinr_ui_admin_skin_infos_settings', 5),
     'access arguments' => array('administer skinr'),
@@ -114,7 +114,7 @@ function skinr_ui_menu() {
     'type' => MENU_LOCAL_TASK,
     'access arguments' => array('administer skinr'),
     'weight' => 2,
-    'description' => t('Import Skinr settings.'),
+    'description' => t('Import skin configurations.'),
     'file' => 'skinr_ui.admin.inc',
   );
   $items['admin/appearance/skinr/export'] = array(
@@ -124,17 +124,17 @@ function skinr_ui_menu() {
     'type' => MENU_LOCAL_TASK,
     'access arguments' => array('administer skinr'),
     'weight' => 3,
-    'description' => t('Export Skinr settings.'),
+    'description' => t('Export skin configurations.'),
     'file' => 'skinr_ui.admin.inc',
   );
 
-  // Edit Skinr settings.
+  // Configure skin settings for an element.
   $items['admin/appearance/skinr/edit/%skinr_js/%/%'] = array(
     'title' => 'Edit skin',
     'title callback' => 'skinr_ui_edit_title',
     'title arguments' => array(5, 6),
     'page callback' => 'skinr_ui_edit',
-    'page arguments' => array(4, 5, 6), // js|nojs, module, sid
+    'page arguments' => array(4, 5, 6), // js|nojs, module, element
     'type' => MENU_CALLBACK,
     'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
     'access arguments' => array('edit skin settings'),
@@ -147,11 +147,11 @@ function skinr_ui_menu() {
     'context' => MENU_CONTEXT_INLINE,
   );
 
-  // Delete Skinr settings.
-  $items['admin/appearance/skinr/delete/%/%/%'] = array(
+  // Delete a skin configuration.
+  $items['admin/appearance/skinr/delete/%skinr_skin'] = array(
     'title' => 'Delete skin',
     'page callback' => 'drupal_get_form',
-    'page arguments' => array('skinr_ui_delete_confirm', 4, 5, 6), // theme, module, sid
+    'page arguments' => array('skinr_ui_delete_confirm', 4),
     'type' => MENU_CALLBACK,
     'access arguments' => array('administer skinr'),
     'file' => 'skinr_ui.admin.inc',
@@ -237,45 +237,45 @@ function skinr_ui_help($path, $arg) {
   }
   switch ($path) {
     case 'admin/appearance/skinr':
-      return  '<p>' . t('Below is a list of all Skinr settings in use on this site.') . '</p>' . $advanced_help;
+      return  '<p>' . t('Below is a list of all skin configurations in use on this site.') . '</p>' . $advanced_help;
     case 'admin/appearance/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/appearance/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/appearance/skinr/import':
-      return  '<p>' . t('To import Skinr settings, ensure the correct theme is selected, paste exported code and click the "Import" button.') . '</p>';
+      return  '<p>' . t('To import skin configurations, paste exported code and click the "Import" button.') . '</p>';
     case 'admin/appearance/skinr/export':
-      return  '<p>' . t('To export Skinr settings, ensure the correct theme is selected and click the "Export" button.') . '</p>';
+      return  '<p>' . t('To export skin configurations, ensure the correct theme is selected and click the "Export" button.') . '</p>';
       break;
   }
 }
 
 /**
- * Menu title callback; sets the title for a Skinr settings form page.
+ * Menu title callback; sets the title for a skins configuration form page.
  *
  * @param $module
  *   The module that we're editing settings of.
- * @param $sid
- *   The sid of the object we're editing settings of.
+ * @param $element
+ *   The element we're editing settings of.
  */
-function skinr_ui_edit_title($module, $sid) {
-  return t('Skinr settings for !module type !sid', array('!module' => $module, '!sid' => $sid));
+function skinr_ui_edit_title($module, $element) {
+  return t('Skin settings for !module type !element', array('!module' => $module, '!element' => $element));
 }
 
 /**
- * Menu title callback; sets the title for a Skinr settings form page.
+ * Menu title callback; sets the title for a skins configuration form page.
  *
  * @param $module
- *   The module that we're editing settings of.
- * @param $sid
- *   The sid of the object we're editing settings of.
+ *   The module that we're editing settings for.
+ * @param $element
+ *   The element we're editing settings for.
  */
-function skinr_ui_edit_contextual_title($module, $sid) {
+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] == $sid) {
+      if ($link[1][0] == $module && $link[1][1] == $element) {
         if (count($links) > 1) {
           return t('Edit skin !number', array('!number' => $counter));
         }
@@ -294,13 +294,13 @@ function skinr_ui_edit_contextual_title($module, $sid) {
  *   TRUE if called from javascript, FALSE otherwise.
  * @param $module
  *   The module that we're editing settings of.
- * @param $sid
- *   The sid of the object we're editing settings of.
- * @param $sids
- *   An array of $sid when more than one is returned from the preprocess
+ * @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, $sid, $sids = NULL) {
+function skinr_ui_edit($js = FALSE, $module, $element, $elements = NULL) {
   if ($js) {
     // Do additional ajax related stuff.
   }
@@ -308,15 +308,15 @@ function skinr_ui_edit($js = FALSE, $module, $sid, $sids = NULL) {
   $arguments = array(
     'skinr' => array(
       'module' => $module,
-      'sid' => $sid,
-      'sids' => $sids,
+      'element' => $element,
+      'elements' => $elements,
     ),
   );
   return drupal_get_form('skinr_ui_form', $arguments);
 }
 
 /**
- * Form builder for the skinr settings configuration form.
+ * Form builder for the skins configuration form.
  *
  * @param $arguments
  *   An array of arguments as passed in by skinr_ui_edit().
@@ -332,14 +332,14 @@ function skinr_ui_form($form, &$form_state, $arguments) {
     '#type' => 'hidden',
     '#value' => !empty($form_state['skinr']['module']) ? $form_state['skinr']['module'] : $arguments['skinr']['module'],
   );
-  $form['skinr']['sid'] = array(
+  $form['skinr']['element'] = array(
     '#type' => 'hidden',
-    '#value' => !empty($form_state['skinr']['sid']) ? $form_state['skinr']['sid'] : $arguments['skinr']['sid'],
+    '#value' => !empty($form_state['skinr']['element']) ? $form_state['skinr']['element'] : $arguments['skinr']['element'],
   );
-  if (!empty($form_state['skinr']['sids']) || !empty($arguments['skinr']['sids'])) {
-    $form['skinr']['sids'] = array(
+  if (!empty($form_state['skinr']['elements']) || !empty($arguments['skinr']['elements'])) {
+    $form['skinr']['elements'] = array(
       '#type' => 'hidden',
-      '#value' => !empty($form_state['skinr']['sids']) ? $form_state['skinr']['sids'] : $arguments['skinr']['sids'],
+      '#value' => !empty($form_state['skinr']['elements']) ? $form_state['skinr']['elements'] : $arguments['skinr']['elements'],
     );
   }
 
@@ -417,19 +417,20 @@ function skinr_ui_form_alter(&$form, $form_state, $form_id) {
         }
 
         if (!$form_state['submitted']) {
-          if ($skin = skinr_handler('data_handler', 'form', $form_settings['data_handler'], $form, $form_state, $theme->name, $module, $form_settings)) {
-            $defaults  = $skin->skins['_options'];
-            $additional_default = isset($skin->skins['_additional']) ? $skin->skins['_additional'] : '';
+          if ($skins = skinr_handler('data_handler', 'form', $form_settings['data_handler'], $form, $form_state, $theme->name, $module, $form_settings)) {
+            $defaults = array();
+            foreach ($skins as $skin) {
+              $defaults[$skin->skin] = $skin->options;
+            }
           }
           else {
-            $defaults  = array();
-            $additional_default = '';
+            $defaults = array();
           }
         }
         else {
           // Handle preview before submit.
-          $defaults  = $form_state['values']['widgets'];
-          $additional_default = $form_state['values']['_additional'];
+          // @todo Is this still needed? If so, it needs to be fixed.
+          $defaults = $form_state['values'];
         }
 
         if (!isset($form['skinr_settings'][$module . '_group'])) {
@@ -510,30 +511,31 @@ function skinr_ui_form_alter(&$form, $form_state, $form_id) {
             }
           }
           if (empty($skin_info['group']) || empty($groups[$skin_info['group']])) {
-            $form['skinr_settings'][$module . '_group'][$theme->name]['widgets'][$skin_name] = $field;
+            $form['skinr_settings'][$module . '_group'][$theme->name][$skin_name] = $field;
           }
           else {
-            if (!isset($form['skinr_settings'][$module . '_group'][$theme->name]['widgets'][$skin_info['group']])) {
+            if (!isset($form['skinr_settings'][$module . '_group'][$theme->name][$skin_info['group']])) {
               $group = $groups[$skin_info['group']];
-              $form['skinr_settings'][$module . '_group'][$theme->name]['widgets'][$skin_info['group']] = array(
+              $form['skinr_settings'][$module . '_group'][$theme->name][$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 . '_group'][$theme->name]['widgets'][$skin_info['group']][$skin_name] = $field;
+            $form['skinr_settings'][$module . '_group'][$theme->name][$skin_info['group']][$skin_name] = $field;
           }
         }
 
         // Check for access.
         if (skinr_handler('access_handler', 'edit advanced skin settings', $form_settings['access_handler'], $form, $form_state)) {
+          $skin_name = '_additional';
           $form['skinr_settings'][$module . '_group'][$theme->name]['_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' => $additional_default,
+            '#default_value' => isset($defaults[$skin_name]) ? $defaults[$skin_name] : '',
           );
 
           // Only add validation handler once.
@@ -599,10 +601,10 @@ function skinr_ui_form_validate($form, &$form_state) {
       if (isset($module_settings['form'][$form_id]) && isset($form_state['values']['skinr_settings'][$module . '_group'])) {
         foreach ($form_state['values']['skinr_settings'][$module . '_group'] as $theme_name => $theme) {
           foreach ($groups as $group_name => $group) {
-            if (!empty($theme['widgets'][$group_name]) && is_array($theme['widgets'][$group_name])) {
-              $group_values = $theme['widgets'][$group_name];
-              unset($form_state['values']['skinr_settings'][$module . '_group'][$theme_name]['widgets'][$group_name]);
-              $form_state['values']['skinr_settings'][$module . '_group'][$theme_name]['widgets'] = array_merge($form_state['values']['skinr_settings'][$module . '_group'][$theme_name]['widgets'], $group_values);
+            if (!empty($theme[$group_name]) && is_array($theme[$group_name])) {
+              $group_values = $theme[$group_name];
+              unset($form_state['values']['skinr_settings'][$module . '_group'][$theme_name][$group_name]);
+              $form_state['values']['skinr_settings'][$module . '_group'][$theme_name] = array_merge($form_state['values']['skinr_settings'][$module . '_group'][$theme_name], $group_values);
             }
           }
         }
diff --git tests/skinr.test tests/skinr.test
index defde6c..553be16 100644
--- tests/skinr.test
+++ tests/skinr.test
@@ -83,6 +83,8 @@ class SkinrInstallationTestCase extends DrupalWebTestCase {
 
 /**
  * Tests API functionality.
+ *
+ * @link http://drupal.org/node/953336#comment-3738456 Make sure this patch is applied to drupal core @endlink
  */
 class SkinrApiTestCase extends DrupalWebTestCase {
   protected $profile = 'testing';
@@ -95,16 +97,37 @@ class SkinrApiTestCase extends DrupalWebTestCase {
     );
   }
 
-  function setUp() {
+  public function setUp() {
     parent::setUp(array('skinr', 'skinr_test', 'skinr_test_incompatible'));
     // Enable skinr_test_subtheme, but NOT the basetheme.
     theme_enable(array('skinr_test_subtheme'));
   }
 
   /**
+   * 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().
    */
-  function testSkinrImplements() {
+  public function testSkinrImplements() {
     // Verify that skinr_implements() only returns extensions that are
     // compatible with this version of Skinr.
     $extensions = skinr_implements();
@@ -168,7 +191,7 @@ class SkinrApiTestCase extends DrupalWebTestCase {
   /**
    * Tests hook_skinr_skin_info().
    */
-  function testSkinrSkinInfo() {
+  public function testSkinrSkinInfo() {
     // Verify that skinr_get_skin_info() finds and returns all registered skins
     // in $module.skinr.inc files as well as Skinr plugin files, but does not
     // return skins that are incompatible with the current Skinr API version.
@@ -223,7 +246,7 @@ class SkinrApiTestCase extends DrupalWebTestCase {
   /**
    * Tests hook_skinr_group_info().
    */
-  function testSkinrGroupInfo() {
+  public function testSkinrGroupInfo() {
     $group_info = skinr_get_group_info();
 
     // Verify that default skin groups are found.
@@ -264,7 +287,7 @@ class SkinrApiTestCase extends DrupalWebTestCase {
   /**
    * Tests hook_skinr_config_info().
    */
-  function testSkinrConfigInfo() {
+  public function testSkinrConfigInfo() {
     // Verify that skinr_get_config_info() finds all existing and compatible
     // hook_skinr_config_info() implementations.
     $config = skinr_get_config_info();
@@ -283,4 +306,233 @@ class SkinrApiTestCase extends DrupalWebTestCase {
     // After asserting all expected, the list of skins should be empty.
     $this->assertTrue(empty($config), 'No unexpected skins found.');
   }
+
+  /**
+   * Test hook invocations for CRUD operations on skin configurations.
+   */
+  public function testSkinrSkinHooks() {
+    $skin = (object) array(
+      'theme' => 'skinr_test_subtheme',
+      'module' => 'block',
+      'element' => 'system-user-menu',
+      'skin' => 'skinr_test_subtheme',
+      'options' => array('option1', 'option2'),
+      'status' => 1,
+    );
+    $_SESSION['skinr_test'] = array();
+    skinr_skin_save($skin);
+
+    $this->assertHookMessage('skinr_test_skinr_skin_presave called');
+    $this->assertHookMessage('skinr_test_skinr_skin_insert called');
+
+    $_SESSION['skinr_test'] = array();
+    $skin = skinr_skin_load($skin->sid);
+
+    $this->assertHookMessage('skinr_test_skinr_skin_load called');
+
+    $_SESSION['skinr_test'] = array();
+    $skin = skinr_skin_load_unchanged($skin->sid);
+
+    $this->assertHookMessage('skinr_test_skinr_skin_load called');
+
+    $_SESSION['skinr_test'] = array();
+    $skin->options = array('option3');
+    skinr_skin_save($skin);
+
+    $this->assertHookMessage('skinr_test_skinr_skin_presave called');
+    $this->assertHookMessage('skinr_test_skinr_skin_update called');
+
+    $_SESSION['skinr_test'] = array();
+    skinr_skin_delete($skin->sid);
+
+    $this->assertHookMessage('skinr_test_skinr_skin_delete called');
+  }
+
+  /**
+   * Test skinr_skin_save() against invalid entries.
+   */
+  public function testSkinrSkinLoadSave() {
+    // Only save valid skins.
+    $skin = (object) array(
+      'theme' => '',
+      'module' => 'block',
+      'element' => 'system-user-menu',
+      'skin' => 'skinr_test_subtheme',
+      'options' => array('option1', 'option2'),
+      'status' => 1,
+    );
+    $this->assertFalse(skinr_skin_save($skin), 'Skin configuration object was not saved when $skin->theme was empty.');
+
+    $skin->theme = 'skinr_test_subtheme';
+    $skin->module = '';
+    $this->assertFalse(skinr_skin_save($skin), 'Skin configuration object was not saved when $skin->module was empty.');
+
+    $skin->module = 'block';
+    $skin->element = '';
+    $this->assertFalse(skinr_skin_save($skin), 'Skin configuration object was not saved when $skin->element was empty.');
+
+    $skin->element = 'system-user-menu';
+    $skin->skin = '';
+    $this->assertFalse(skinr_skin_save($skin), 'Skin configuration object was not saved when $skin->skin was empty.');
+
+    $skin->skin = 'skinr_test_subtheme';
+    $skin->options = '';
+    $this->assertFalse(skinr_skin_save($skin), 'Skin configuration object was not saved when $skin->options was not an array.');
+
+    $skin->options = array();
+    $this->assertFalse(skinr_skin_save($skin), 'Skin configuration object was not saved when $skin->options was an empty array.');
+
+    $skin->options = array('option1' => 0, 'option2' => 0);
+    $this->assertFalse(skinr_skin_save($skin), 'Skin configuration object was not saved when $skin->options was a complex empty array.');
+
+    $skin->options = array('option1', 'option2');
+    $this->assertTrue(skinr_skin_save($skin), 'Skin configuration object was saved.');
+    $this->assertTrue(isset($skin->sid), 'The sid was added to the skin configuration object.');
+
+    // 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($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.');
+
+    // Save a second skin.
+    $second_skin = (object) array(
+      'theme' => 'skinr_test_subtheme',
+      'module' => 'block',
+      'element' => 'system-main',
+      'skin' => 'skinr_test_subtheme',
+      'options' => array('option3'),
+      'status' => 1,
+    );
+    skinr_skin_save($second_skin);
+
+    // Test loading multiple skin configurations.
+    $skins = skinr_skin_load_multiple(array($skin->sid, $second_skin->sid));
+    $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();
+    $this->assertTrue(count($skins) == 2 && isset($skins[$skin->sid]->sid) && isset($skins[$second_skin->sid]->sid), 'Successfully loaded all skins.');
+  }
+}
+
+
+/**
+ * Tests API functionality.
+ *
+ * @link http://drupal.org/node/953336#comment-3738456 Make sure this patch is applied to drupal core @endlink
+ */
+class SkinrDisplayTestCase extends DrupalWebTestCase {
+  protected $profile = 'testing';
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Display',
+      'description' => 'Tests if applied skins appear on the front-end.',
+      'group' => 'Skinr',
+    );
+  }
+
+  public function setUp() {
+    parent::setUp(array('block', 'skinr', 'skinr_test', 'devel'));
+
+    $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'));
+  }
+
+  /**
+   * Asserts that a class is set for the given element id.
+   *
+   * @param $id
+   *   Id of the HTML element to check.
+   * @param $class
+   *   The class name to check for.
+   * @param $message
+   *   Message to display.
+   * @return
+   *   TRUE on pass, FALSE on fail.
+   */
+  function assertSkinrClass($id, $class, $message = '') {
+    $elements = $this->xpath('//div[@id=:id]', array(':id' => $id));
+    $class_attr = (string) $elements[0]['class'];
+    $this->assertTrue(strpos($class_attr, ' ' . $class . ' '), $message);
+  }
+
+  /**
+   * Asserts that a class is not set for the given element id.
+   *
+   * @param $id
+   *   Id of the HTML element to check.
+   * @param $class
+   *   The class name to check for.
+   * @param $message
+   *   Message to display.
+   * @return
+   *   TRUE on pass, FALSE on fail.
+   */
+  function assertNoSkinrClass($id, $class, $message = '') {
+    $elements = $this->xpath('//div[@id=:id]', array(':id' => $id));
+    $class_attr = (string) $elements[0]['class'];
+    $this->assertFalse(strpos($class_attr, ' ' . $class . ' '), $message);
+  }
+
+  public function testSkinrDisplayed() {
+    // Save a skin configuration object.
+    $skin = (object) array(
+      'theme' => 'bartik',
+      'module' => 'block',
+      'element' => 'system-user-menu',
+      'skin' => 'skinr_test_font',
+      'options' => array('font_1'),
+      'status' => 1,
+    );
+    $this->assertTrue(skinr_skin_save($skin), 'Skin configuration object was saved.');
+    $this->verbose(print_r($skin, TRUE));
+
+    // Go to the front page.
+    $this->drupalGet('');
+    $this->assertSkinrClass('block-system-user-menu', 'font-1', 'CSS class of configured skin option found.');
+
+    $content = $this->drupalGetContent();
+
+    $css = drupal_get_path('module', 'skinr_test') . '/skinr_test.css';
+    $this->assertRaw($css, t('Stylesheet was included on page.'));
+
+    $js = drupal_get_path('module', 'skinr_test') . '/skinr_test.js';
+    $this->assertRaw($js, t('Javascript was included on page.'));
+  }
 }
diff --git tests/skinr_test.js tests/skinr_test.js
new file mode 100644
index 0000000..361fce8
--- /dev/null
+++ tests/skinr_test.js
@@ -0,0 +1,3 @@
+/**
+ * Non-functional JS file to test for inclusion on page.
+ */
diff --git tests/skinr_test.module tests/skinr_test.module
index ba7a400..72d43c5 100644
--- tests/skinr_test.module
+++ tests/skinr_test.module
@@ -22,3 +22,58 @@ function skinr_test_system_theme_info() {
   }
   return $themes;
 }
+
+//
+// Presave hooks
+//
+
+/**
+ * Implements hook_skinr_skin_presave().
+ */
+function skinr_test_skinr_skin_presave() {
+  $_SESSION['skinr_test'][] = (__FUNCTION__ . ' called');
+}
+
+//
+// Insert hooks
+//
+
+/**
+ * Implements hook_skinr_skin_insert().
+ */
+function skinr_test_skinr_skin_insert() {
+  $_SESSION['skinr_test'][] = (__FUNCTION__ . ' called');
+}
+
+//
+// Load hooks
+//
+
+/**
+ * Implements hook_skinr_skin_load().
+ */
+function skinr_test_skinr_skin_load() {
+  $_SESSION['skinr_test'][] = (__FUNCTION__ . ' called');
+}
+
+//
+// Update hooks
+//
+
+/**
+ * Implements hook_skinr_skin_update().
+ */
+function skinr_test_skinr_skin_update() {
+  $_SESSION['skinr_test'][] = (__FUNCTION__ . ' called');
+}
+
+//
+// Delete hooks
+//
+
+/**
+ * Implements hook_skinr_skin_delete().
+ */
+function skinr_test_skinr_skin_delete() {
+  $_SESSION['skinr_test'][] = (__FUNCTION__ . ' called');
+}
diff --git tests/skinr_test.skinr.inc tests/skinr_test.skinr.inc
index 3c56c1a..e16ecc9 100644
--- tests/skinr_test.skinr.inc
+++ tests/skinr_test.skinr.inc
@@ -21,6 +21,7 @@ function skinr_test_skinr_skin_info() {
     'default status' => 1,
     'attached' => array(
       'css' => array('skinr_test.css'),
+      'js' => array('skinr_test.js'),
     ),
     'options' => array(
       'font_1' => array(
diff --git tests/skinr_ui.test tests/skinr_ui.test
index b82a8e9..d050d93 100644
--- tests/skinr_ui.test
+++ tests/skinr_ui.test
@@ -103,7 +103,7 @@ class SkinrUIBasicTestCase extends SkinrUITestCase {
     // available.
     // Verify that we can apply the skinr_test_font skin to the block.
     $edit = array(
-      'skinr_settings[block_group][bartik][widgets][typography][skinr_test_font]' => 'font_1',
+      'skinr_settings[block_group][bartik][typography][skinr_test_font]' => 'font_1',
     );
     // 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
@@ -189,4 +189,25 @@ class SkinrUIAdminTestCase extends SkinrUITestCase {
     // registers a skin in that group.
     $this->assertText(t('Typography'));
   }
+
+  /**
+   * Tests skin configuration listing functionality.
+   */
+  function testSkinListing() {
+    $skin = (object) array(
+      'theme' => 'skinr_test_subtheme',
+      'module' => 'block',
+      'element' => 'system-user-menu',
+      '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/appearance/skinr');
+    $this->assertLinkByHref('admin/appearance/skinr/delete/' . $skin->sid . '?destination=admin/appearance/skinr', 0, 'Skin configuration was found on overview page.');
+
+    // @todo Should we check the filtering and update options functionality?
+  }
 }

