diff -urp signup_old/modules/signup_webform/signup_webform.module signup/modules/signup_webform/signup_webform.module
@@ -65,7 +65,7 @@
  */
 function signup_webform_signup_pane_info($node = NULL) {
   // Get the webform nodes.
-  $result = db_query('SELECT n.title, n.nid FROM {node} n WHERE n.type = "webform" AND n.status = 1');
+  $result = db_query(db_rewrite_sql('SELECT n.title, n.nid FROM {node} n WHERE n.type = "webform" AND n.status = 1'));
   while ($webform = db_fetch_object($result)) {
     $panes['webform_' . $webform->nid] = array(
       'label' => 'Webform: ' . $webform->title,
@@ -73,19 +73,20 @@ function signup_webform_signup_pane_info
       'callback' => 'signup_webform_form',
       'operations' => array(
         array(
-          'href'  => 'node/' . $webform->nid . '/edit',
-          'title' => 'Edit webform',
-          'destination' => TRUE,
+          'href'  => 'node/' . $webform->nid . '/webform',
+          'title' => 'Edit webform components',
         ),
         array(
-          'href'  => 'node/' . $webform->nid . '/edit/components',
-          'title' => 'Edit components',
-          'destination' => TRUE,
+          'href'  => 'node/' . $webform->nid . '/webform/configure',
+          'title' => 'Edit webform settings',
+        ),
+        array(
+          'href'  => 'node/' . $webform->nid . '/webform/emails',
+          'title' => 'Edit webform emails',
         ),
       ),
     );
   }
-  
   return $panes;
 }
 
@@ -100,7 +101,7 @@ function signup_webform_signup_pane_info
  * @param $node
  *   The fully loaded node object.
  * @param $signup
- *   If this is an existing signup, the fully loaded signup object. If this is a 
+ *   If this is an existing signup, the fully loaded signup object. If this is a
  *   new signup, this is just NULL.
  * @param $pane_id
  *   The pane ID being invoked. This allows a module to implement multiple panes
@@ -111,41 +112,172 @@ function signup_webform_signup_pane_info
  *    'anon' -- anonymous user signup form (includes required email field).
  *    'admin' -- admin form to signup another user (includes user selector).
  * @return
- *   A form API array for insertion into the signup form. 
+ *   A form API array for insertion into the signup form.
  */
 function signup_webform_form(&$signup_form, &$form_state, $node, $signup, $pane_id, $signup_type = 'auth') {
   $form = array();
-
   // Get the real nid from the prefixed pane ID and thence the node.
-  $webform_nid = substr($pane_id, 8);
+  $webform_nid = drupal_substr($pane_id, 8);
   $webform_node = node_load($webform_nid);
-  
-  module_load_include('inc', 'webform', 'webform_components');
-  webform_load_components();
-  
+
+  module_load_include('inc', 'webform', 'includes/webform.components');
+  global $user;
+  $filter = TRUE;
+  $is_draft = FALSE;
+
   // Load the webform submission for existing signups, so the webform API
   // takes care of putting in existing data.
   if (isset($signup) && $signup_type != 'anon') {
     $submission = signup_webform_get_signup_submission($signup, $webform_nid);
-  }  
-  
-  $component_tree = array();
-  $page_count = 1;
-  $page_num = 1;
-  _webform_components_tree_build($webform_node->webform['components'], $component_tree, 0, $page_count);
-  
-  //dsm($component_tree);
-
-  // Recursively add components to the form. Microweights keep things in webform order.
-  // No idea what most of these do; _webform_client_form_add_component() is an undocumented black box!
-  $microweight = 0.001;
-  $enabled = TRUE;
-  foreach ($component_tree['children'] as $cid => $component) {
-    // we have no existing values here ever.
-    $component_value = NULL;
-    _webform_client_form_add_component($cid, $component, $component_value, $form, $form, $submission, $page_num, $enabled);
   }
-    
+
+  /**
+  * The following was extracted from webform_client_form().
+  */
+  // Bind arguments to $form to make them available in theming and form_alter.
+  $form['#node'] = $webform_node;
+  $form['#submission'] = isset($submission) ? $submission : '';
+  $form['#is_draft'] = $is_draft;
+  $form['#filter'] = $filter;
+
+  // Add a theme function for this form.
+  $form['#theme'] = array('webform_form_' . $webform_node->nid, 'webform_form');
+
+  // Add a css class for all client forms.
+  $form['#attributes'] = array('class' => 'webform-client-form');
+
+  // Set the encoding type (necessary for file uploads).
+  $form['#attributes']['enctype'] = 'multipart/form-data';
+
+  // Set the form action to the node ID in case this is being displayed on the
+  // teaser, subsequent pages should be on the node page directly.
+  if (!isset($webform_node->webform_block) && empty($submission)) {
+    $form['#action'] = url('node/' . $webform_node->nid);
+  }
+
+  $form['#submit'] = array('webform_client_form_pages', 'webform_client_form_submit');
+  $form['#validate'] = array('webform_client_form_validate');
+
+  if (is_array($webform_node->webform['components']) && !empty($webform_node->webform['components'])) {
+    // Prepare a new form array.
+    $form['submitted'] = array(
+      '#tree' => TRUE
+    );
+    $form['details'] = array(
+      '#tree' => TRUE,
+    );
+
+    // Put the components into a tree structure.
+    if (!isset($form_state['storage']['component_tree'])) {
+      $form_state['webform']['component_tree'] = array();
+      $form_state['webform']['page_count'] = 1;
+      $form_state['webform']['page_num'] = 1;
+      _webform_components_tree_build($webform_node->webform['components'], $form_state['webform']['component_tree'], 0, $form_state['webform']['page_count']);
+    }
+    else {
+      $form_state['webform']['component_tree'] = $form_state['storage']['component_tree'];
+      $form_state['webform']['page_count'] = $form_state['storage']['page_count'];
+      $form_state['webform']['page_num'] = $form_state['storage']['page_num'];
+    }
+
+    // Shorten up our variable names.
+    $component_tree = $form_state['webform']['component_tree'];
+    $page_count = $form_state['webform']['page_count'];
+    $page_num = $form_state['webform']['page_num'];
+
+    // Recursively add components to the form.
+    foreach ($component_tree['children'] as $cid => $component) {
+      $component_value = isset($form_state['post']['signup_form_data'][$pane_id]['submitted'][$component['form_key']]) ? $form_state['post']['signup_form_data'][$pane_id]['submitted'][$component['form_key']] : NULL;
+      if (_webform_client_form_rule_check($webform_node, $component, $page_num, $form_state)) {
+        _webform_client_form_add_component($webform_node, $component, $component_value, $form['submitted'], $form, $form_state, isset($submission) ? $submission : '', 'form', $page_num, $filter);
+      }
+    }
+
+    // These form details help managing data upon submission.
+    $form['details']['nid'] = array(
+      '#type' => 'value',
+      '#value' => $webform_node->nid,
+    );
+    $form['details']['sid'] = array(
+      '#type' => 'hidden',
+      '#value' => isset($submission->sid) ? $submission->sid : '',
+    );
+    $form['details']['uid'] = array(
+      '#type' => 'value',
+      '#value' => isset($submission->uid) && !is_null($submission->uid) ? $submission->uid : $user->uid,
+    );
+    $form['details']['page_num'] = array(
+      '#type' => 'hidden',
+      '#value' => $page_num,
+    );
+    $form['details']['page_count'] = array(
+      '#type' => 'hidden',
+      '#value' => $page_count,
+    );
+    $form['details']['finished'] = array(
+      '#type' => 'hidden',
+      '#value' => isset($submission->is_draft) ? (!$submission->is_draft) : 0,
+    );
+    // Add the signup sid to the form
+    $form['details']['pane_id'] = array(
+      '#type' => 'hidden',
+      '#value' => $pane_id,
+    );
+    // Add buttons for pages, drafts, and submissions.
+    $form['actions'] = array(
+      '#tree' => FALSE,
+      '#weight' => 1000,
+      '#prefix' => '<div id="edit-actions" class="form-actions form-wrapper">',
+      '#suffix' => '</div>',
+    );
+
+    if ($page_count > 1) {
+      $next_page = t('Next Page >');
+      $prev_page = t('< Previous Page');
+
+      // Add the submit button(s).
+      if ($webform_node->webform['allow_draft'] && (empty($submission) || $submission->is_draft) && $user->uid != 0) {
+        $form['actions']['draft'] = array(
+          '#type' => 'submit',
+          '#value' => t('Save Draft'),
+          '#weight' => -2,
+          '#validate' => array(),
+        );
+      }
+
+      if ($page_num > 1) {
+        $form['actions']['previous'] = array(
+          '#type' => 'submit',
+          '#value' => $prev_page,
+          '#weight' => 5,
+          '#validate' => array(),
+        );
+      }
+
+      if ($page_num == $page_count) {
+        //$form['actions']['submit'] = array(
+        //  '#type' => 'submit',
+        //  '#value' => empty($webform_node->webform['submit_text']) ? t('Submit') : t($webform_node->webform['submit_text']),
+        //  '#weight' => 10,
+        //);
+      }
+      elseif ($page_num < $page_count) {
+        $form['actions']['next'] = array(
+          '#type' => 'submit',
+          '#value' => $next_page,
+          '#weight' => 10,
+        );
+      }
+    }
+    else {
+      // Add the submit button.
+      //$form['actions']['submit'] = array(
+      //  '#type' => 'submit',
+      //  '#value' => empty($webform_node->webform['submit_text']) ? t('Submit') : t($webform_node->webform['submit_text']),
+      //  '#weight' => 10,
+      //);
+    }
+  }
   return $form;
 }
 
@@ -155,69 +287,227 @@ function signup_webform_form(&$signup_fo
 function signup_webform_signup_data_alter(&$signup, $form_values) {
   // Act on each pane that is a webform pane.
   foreach (_signup_webform_pane_ids($signup->form_data) as $pane_id) {
-    // Load the webform API. 
+    // Load the webform API.
     // Do this inside the loop so signups that don't use webform don't load this.
-    module_load_include('inc', 'webform', 'webform_submissions');
-    
+    module_load_include('inc', 'webform', 'includes/webform.submissions');
+
     // Get the real nid from the prefixed pane ID and thence the node.
-    $webform_nid = substr($pane_id, 8);
+    $webform_nid = drupal_substr($pane_id, 8);
     $webform_node = node_load($webform_nid);
-          
-    /*
-    So... some missing documentation!
-    webform_submission_insert($node, $submitted)
-    expects this for $submitted, where keys are cids:
-    *   Array
-    *  (
-    *      [1] => Array // Single checkbox TRUE/FALSE
-    *          (
-    *              [1] => 1 
-    *          )
-    *  
-    *      [2] => Abbey Road // Textfield
-    *      [3] => Array // Multiple select: checkboxes
-    *          (
-    *              [John] => John
-    *              [Paul] => Paul
-    *          )
-    *  
-    *  )
-    *
-    */
+
     $component_lookup = _signup_webform_translate_cid_form_keys($webform_node);
-    
-    $submitted = array();
+
     $webform_data = $signup->form_data[$pane_id];
-    foreach ($webform_data as $form_key => $component_data) {
-      $cid = $component_lookup[$form_key];
-      // Remove 0 values for unselected checkbox items
-      if (is_array($component_data)) {
-        $component_data = array_filter($component_data);
-      }
-      
-      $submitted[$cid] = $component_data;
-    }
-    
-    if (isset($signup->sid)) {
-      // existing signup: update the webform submission with the new data.
-      $submission_sid = db_result(db_query('SELECT submission_sid FROM {signup_webform_submission} WHERE signup_sid = %d AND webform_nid = %d', $signup->sid, $webform_nid));
-      webform_submission_update($webform_node, $submission_sid, $submitted);
-      // We store the sid so hook_signup_form_data_display() has something to work on.
-      $signup->form_data[$pane_id] = array(
-        'sid' => $submission_sid,
-      );
+    global $user;
+
+    $submitted_data = array();
+    $flipped_lookup = array_flip($component_lookup);
+    foreach ($webform_node->webform['components'] as $comp_key => $comp_data) {
+      //$sub_data = $signup->form_data[$comp_key]['submitted']['value'];
+      switch ($webform_node->webform['components'][$comp_key]['type']) {
+        case 'fieldset':
+          break;
+        case 'pagebreak':
+          break;
+        case 'markup':
+          break;
+        case 'file':
+          $submitted_data[$comp_key] = _signup_webform_search_key($comp_data['form_key'],$webform_data['submitted']);
+          $submitted_data[$comp_key] = _webform_submit_file($webform_node->webform['components'][$comp_key], $submitted_data[$comp_key]);
+          break;
+        case 'select':
+          $submitted_data[$comp_key] = _signup_webform_search_key($comp_data['form_key'],$webform_data['submitted']);
+          $submitted_data[$comp_key] = _webform_submit_select($webform_node->webform['components'][$comp_key], $submitted_data[$comp_key]);
+          break;
+        case 'time':
+          $submitted_data[$comp_key] = _signup_webform_search_key($comp_data['form_key'],$webform_data['submitted']);
+          $submitted_data[$comp_key] = _webform_submit_time($webform_node->webform['components'][$comp_key], $submitted_data[$comp_key]);
+          break;
+        case 'date':
+          $submitted_data[$comp_key] = _signup_webform_search_key($comp_data['form_key'],$webform_data['submitted']);
+          $submitted_data[$comp_key] = _webform_submit_date($webform_node->webform['components'][$comp_key], $submitted_data[$comp_key]);
+          break;
+        default:
+          $submitted_data[$comp_key] = _signup_webform_search_key($comp_data['form_key'],$webform_data['submitted']);
+      }
+    }
+
+    $is_draft = FALSE;
+    // Create the submission object.
+    $submitted = (object) array(
+      'nid' => $webform_nid,
+      'uid' => $user->uid,
+      'submitted' => time(),
+      'remote_addr' => ip_address(),
+      'is_draft' => $is_draft,
+      'data' => webform_submission_data($webform_node, $submitted_data),
+    );
+
+    // Save the submission to the database.
+    if (empty($webform_data['details']['sid'])) {
+      // No sid was found thus insert it in the dataabase.
+      $webform_data['details']['sid'] = webform_submission_insert($webform_node, $submitted);
+      $submitted->sid = $webform_data['details']['sid'];
+      $webform_data['details']['is_new'] = TRUE;
+      // Set a cookie including the server's submission time.
+      // The cookie expires in the length of the interval plus a day to compensate for different timezones.
+      if (variable_get('webform_use_cookies', 0)) {
+        $cookie_name = 'webform-' . $webform_nid;
+        $time = time();
+        setcookie($cookie_name . '[' . $time . ']', $time, $time + $webform_node->webform['submit_interval'] + 86400);
+      }
+
+      // Save session information about this submission for anonymous users,
+      // allowing them to access or edit their submissions.
+      if (!$user->uid && user_access('access own webform submissions')) {
+        $_SESSION['webform_submission'][$webform_data['details']['sid']] = $webform_nid;
+      }
     }
     else {
-      // new signup: insert webform submission.
-      $sid = webform_submission_insert($webform_node, $submitted);
-      
-      // Replace our data with just the submission ID; this is retrieved
-      // by signup_webform_signup_insert() once the signup is saved and has 
-      // an ID.
-      $signup->form_data[$pane_id] = array(
-        'sid' => $sid,
-      );
+      // Sid was found thus update the existing sid in the database.
+      $submitted->sid = $webform_data['details']['sid'];
+      webform_submission_update($webform_node, $submitted);
+      $webform_data['details']['is_new'] = FALSE;
     }
+
+    $sid = $webform_data['details']['sid'];
+
+    // Check if this form is sending an email.
+    if (!$is_draft && !$webform_data['details']['finished']) {
+      $submitted = webform_get_submission($webform_nid, $sid, TRUE);
+
+      // Create a themed message for mailing.
+      foreach ($webform_node->webform['emails'] as $eid => $email) {
+        // Pass through the theme layer if using the default template.
+        if ($email['template'] == 'default') {
+          $email['message'] = theme(array('webform_mail_' . $webform_nid, 'webform_mail', 'webform_mail_message'), $webform_node, $submitted, $email);
+        }
+        else {
+          $email['message'] = $email['template'];
+        }
+
+        // Replace tokens in the message.
+        $email['message'] = _webform_filter_values($email['message'], $webform_node, $submitted, $email, FALSE, TRUE);
+
+        // Build the e-mail headers.
+        $email['headers'] = theme(array('webform_mail_headers_' . $webform_nid, 'webform_mail_headers'), $webform_node, $submitted, $email);
+
+        // Assemble the FROM string.
+        if (isset($email['headers']['From'])) {
+          // If a header From is already set, don't override it.
+          $email['from'] = $email['headers']['From'];
+          unset($email['headers']['From']);
+        }
+        else {
+          $email['from'] = webform_format_email_address($email['from_address'], $email['from_name'], $webform_node, $submitted);
+        }
+
+        // Update the subject if set in the themed headers.
+        if (isset($email['headers']['Subject'])) {
+          $email['headers']['subject'] = $email['headers']['Subject'];
+          unset($email['headers']['Subject']);
+        }
+        else {
+          $email['subject'] = webform_format_email_subject($email['subject'], $webform_node, $submitted);
+        }
+
+        // Update the to e-mail if set in the themed headers.
+        if (isset($headers['To'])) {
+          $email['email'] = $headers['To'];
+          unset($headers['To']);
+        }
+
+        // Generate the list of addresses that this e-mail will be sent to.
+        $addresses = array_filter(explode(',', $email['email']));
+        $addresses_final = array();
+        foreach ($addresses as $address) {
+          $address = trim($address);
+
+          // After filtering e-mail addresses with component values, a single value
+          // might contain multiple addresses (such as from checkboxes or selects).
+          $address = webform_format_email_address($address, NULL, $webform_node, $submitted, TRUE, FALSE, 'short');
+
+          if (is_array($address)) {
+            foreach ($address as $new_address) {
+              $new_address = trim($new_address);
+              if (valid_email_address($new_address)) {
+                $addresses_final[] = $new_address;
+              }
+            }
+          }
+          elseif (valid_email_address($address)) {
+            $addresses_final[] = $address;
+          }
+        }
+
+        // Mail the webform results.
+        foreach ($addresses_final as $address) {
+          // Verify that this submission is not attempting to send any spam hacks.
+          if (_webform_submission_spam_check($address, $email['subject'], $email['from'], $email['headers'])) {
+            watchdog('webform', 'Possible spam attempt from @remote_addr' . "<br />\n" . nl2br(htmlentities($email['message'])), array('@remote_add' => ip_address()));
+            drupal_set_message(t('Illegal information. Data not submitted.'), 'error');
+            return FALSE;
+          }
+
+          $language = $user->uid ? user_preferred_language($user) : language_default();
+          $mail_params = array(
+            'message' => $email['message'],
+            'subject' => $email['subject'],
+            'headers' => $email['headers'],
+            'node' => $webform_node,
+            'submission' => $submitted,
+          );
+          drupal_mail('webform', 'submission', $address, $language, $mail_params, $email['from']);
+        }
+
+      }
+    }
+
+    // Strip out empty tags added by WYSIWYG editors if needed.
+    $confirmation = drupal_strlen(trim(strip_tags($webform_node->webform['confirmation']))) ? $webform_node->webform['confirmation'] : '';
+    $redirect_url = trim($webform_node->webform['redirect_url']);
+
+    // Remove the domain name from the redirect.
+    $redirect_url = preg_replace('/^' . preg_quote($GLOBALS['base_url'], '/') . '\//', '', $redirect_url);
+
+    // Check confirmation and redirect_url fields.
+    $message = NULL;
+    $external_url = FALSE;
+    if ($is_draft) {
+      $redirect = NULL;
+      $message = t('Draft saved');
+    }
+    elseif (!empty($webform_data['details']['finished'])) {
+      $redirect = NULL;
+      $message = t('Submission updated.');
+    }
+    elseif (valid_url($redirect_url, TRUE)) {
+      $redirect = $redirect_url;
+      $external_url = TRUE;
+    }
+    elseif ($redirect_url && strpos($redirect_url, 'http') !== 0) {
+      $parts = parse_url($redirect_url);
+      $query = isset($parts['query']) ? ($parts['query'] . isset($sid) ? '&sid=' . $sid : '') : (isset($sid) ? 'sid=' . $sid : '');
+      $redirect = array($parts['path'], $query, isset($parts['fragment']) ? $parts['fragment'] : '');
+    }
+    else {
+      $redirect = array('node/' . $webform_nid . '/done', 'sid=' . $sid);
+    }
+
+    // Show a message if manually set.
+    if (isset($message)) {
+      drupal_set_message($message);
+    }
+    // If redirecting and we have a confirmation message, show it as a message.
+    elseif (!$external_url && !empty($redirect_url) && !empty($confirmation)) {
+      drupal_set_message(check_markup($confirmation, $webform_node->webform['confirmation_format'], FALSE));
+    }
+
+    $form_state['redirect'] = $redirect;
+
+    $signup->form_data[$pane_id] = array(
+      'sid' => $sid,
+    );
   }
 }
 
@@ -233,7 +523,7 @@ function signup_webform_signup_insert($s
   foreach (_signup_webform_pane_ids($signup->form_data) as $pane_id) {
     // Retrieve the Submission id where we put it in the form data.
     $submission_sid = $signup->form_data[$pane_id]['sid'];
-    $webform_nid = substr($pane_id, 8);
+    $webform_nid = drupal_substr($pane_id, 8);
     db_query("INSERT INTO {signup_webform_submission} (signup_sid, webform_nid, submission_sid) VALUES (%d, %d, %d)", $signup->sid, $webform_nid, $submission_sid);
   }
 }
@@ -245,7 +535,7 @@ function signup_webform_signup_insert($s
  * a node's list of signups.
  *
  * We remove the submission ID that is internal data.
- * Since webform does not yet have view support, we add in the webform 
+ * Since webform does not yet have view support, we add in the webform
  * submission data.
  * @todo: Change all this when webform gets views support!
  *
@@ -261,13 +551,12 @@ function signup_webform_signup_insert($s
  *  The type of output being prepared. Possible values are:
  *    - 'list': The hardcoded admin lists of signups, eg at node/X/signups/admin
  *    - 'view': The form data field in Views.
- *    - 'mail': Email output. This is likely the only one that needs special 
+ *    - 'mail': Email output. This is likely the only one that needs special
  *      handling; in this case, modules should be more generous about supplying
  *      data since there's no other place to see it.
  */
 function signup_webform_signup_form_data_display_alter(&$form_data, $nid, $sid, $uid, $type = 'list') {
-  //dsm($form_data);
-  // Cache any webform components we load, as we are probably coming here 
+  // Cache any webform components we load, as we are probably coming here
   // multiple times to show a set of signups that all involve the same webform.
   static $components = array();
   static $webform_loaded;
@@ -275,14 +564,14 @@ function signup_webform_signup_form_data
   foreach (_signup_webform_pane_ids($form_data) as $pane_id) {
     // Load the webform API.
     if (!isset($webform_loaded)) {
-      module_load_include('inc', 'webform', 'webform_submissions');
-      module_load_include('inc', 'webform', 'webform_components');
-      webform_load_components();
+      module_load_include('inc', 'webform', 'includes/webform.submissions');
+      module_load_include('inc', 'webform', 'includes/webform.components');
+      webform_components();
       $webform_loaded = TRUE;
     }
-    
+
     // Get the real nid from the prefixed pane ID.
-    $webform_nid = substr($pane_id, 8);
+    $webform_nid = drupal_substr($pane_id, 8);
 
     // Get the submission ID from the signup data and thence the submission.
     // We could get this from {signup_webform_submission}, but might as well
@@ -292,36 +581,6 @@ function signup_webform_signup_form_data
     // as an additional field for the ['signup_log']['form_data'] field.
     $submission_sid = $form_data[$pane_id]['sid'];
     $submission = webform_get_submission($webform_nid, $submission_sid);
-    
-    // Check there is an actual submission: if no webform fields are compulsory,
-    // a user can sign up and not create a corresponding webform submission.
-    if (isset($submission)) {
-      if (!isset($components[$webform_nid])) {
-        $webform_node = node_load($webform_nid);
-        // Cache the components for this webform node.
-        $components[$webform_nid] = $webform_node->webform['components'];
-      }
-
-      foreach ($submission->data as $cid => $component_data) {
-        $component = $components[$webform_nid][$cid];
-        $label     = $components[$webform_nid][$cid]['name'];
-        // Hijack webform's email output theming: this, as far as I can tell,
-        // is the only way there is of getting a component's data flattened to 
-        // a human-readable string.
-        // @todo: textfields do not render properly here; I am assuming that
-        // all single-values fields need their arrays exploding. Figure out
-        // what is going on with webform and do this the correct way!
-        if  (count($component_data['value']) == 1) {
-          $component_data['value'] = array_shift($component_data['value']); 
-        }
-        $themed_output = theme('webform_mail_' . $component['type'], $component_data['value'], $component);
-        // Use a numeric key rather than $label so the key is not output by 
-        // theme functions -- webform's output already includes the label.
-        $form_data[$pane_id][] = $themed_output;
-      }
-    }
-    // Remove the sid from display: it is internal data.
-    unset($form_data[$pane_id]['sid']);
   }
 }
 
@@ -332,66 +591,27 @@ function signup_webform_signup_form_data
  */
 function signup_webform_signup_cancel($signup, $node) {
   $form_data = unserialize($signup->form_data);
-  
+
   foreach (_signup_webform_pane_ids($form_data) as $pane_id) {
     // Load the webform API.
-    module_load_include('inc', 'webform', 'webform_submissions');
-    
+    module_load_include('inc', 'webform', 'includes/webform.submissions');
+
     // Get the real nid from the prefixed pane ID and thence the node.
-    $webform_nid = substr($pane_id, 8);
+    $webform_nid = drupal_substr($pane_id, 8);
     $webform_node = node_load($webform_nid);
-    
+
     // Get the submission ID from the signup data and thence the submission.
     $sid = $form_data[$pane_id]['sid'];
     $submission = webform_get_submission($webform_nid, $sid);
-    
+
     // Delete the webform submission.
     webform_submission_delete($webform_node, $submission);
     // Delete the signup-webform submission relationship.
-    db_query("DELETE FROM {signup_webform_submission} WHERE signup_sid = %d", $signup->sid);          
+    db_query("DELETE FROM {signup_webform_submission} WHERE signup_sid = %d", $signup->sid);
   }
 }
 
 /**
- * Implementation of hook_nodeapi().
- *
- * When a whole signup node is deleted, delete data related to it.
- */
-/* 
-// needs work.
-function signup_webform_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
-  if ($op == 'delete' && isset($node->signup_form_panes)) {
-    $signup_nid = $node->nid;
-    // Act on records pertaining to each webform that this signup is linked to.
-    foreach (_signup_webform_pane_ids($node->signup_form_panes) as $pane_id) {
-      // Load the webform API.
-      module_load_include('inc', 'webform', 'webform_submissions');
-      
-      $webform_nid = substr($pane_id, 8);
-      $webform_node = node_load($webform_nid);
-      
-      // One webform may be used in several signup nodes. So we need to get 
-      // *only* the webform submissions that came from the signup node being deleted.
-      // @todo BUG!!! this doesn't seem to work at all!
-      // do we even have {signup_log} any more at this point?? 
-      // may be module weight issues here -- urgh!
-      $result = db_query('SELECT sws.submission_sid FROM {signup_log} sl INNER JOIN {signup_webform_submission} sws ON sl.sid = sws.signup_sid WHERE sl.nid = %d', $signup_nid);
-      // Act on each submission.
-      while ($submission_data = db_fetch_array($result)) {
-        // Load the submission in order to delete it... 
-        $submission = webform_get_submission($webform_nid, $submission_data['sid']);
-        webform_submission_delete($webform_node, $submission);
-        // Delete the signup-submission link for this submission.
-        // @todo: replace this with a DELETE SELECT query outside this loop, joining
-        // to {signup_log} if possible.
-        db_query('DELETE FROM {signup_webform_submission} WHERE submission_sid = %d', $submission_data['sid']);
-      }
-    }
-  }
-}
-*/
-
-/**
  * Implementation of hook_form_FORM_ID_alter().
  *
  * If a webform node is about to be deleted, and it is being used as a pane
@@ -403,9 +623,9 @@ function signup_webform_form_node_delete
     $webform_nid = $node->nid;
     $pane_id = 'webform_' . $node->nid;
     // Get the signup nodes the pane based on this webform is used in.
-    // A left join gets us the special case where nid is 0 which represents the 
+    // A left join gets us the special case where nid is 0 which represents the
     // signup defaults.
-    $result = db_query("SELECT n.nid, n.title FROM {signup_panes} sp LEFT JOIN {node} n ON sp.nid = n.nid WHERE sp.pane_id = '%s'", $pane_id);
+    $result = db_query(db_rewrite_sql("SELECT n.nid, n.title FROM {signup_panes} sp LEFT JOIN {node} n ON sp.nid = n.nid WHERE sp.pane_id = '%s'"), $pane_id);
     while ($signup_node = db_fetch_object($result)) {
       if ($signup_node->nid == 0 ) {
         $text = t('Signup default settings');
@@ -426,10 +646,53 @@ function signup_webform_form_node_delete
 }
 
 /**
+ * Implementation of hook_form_FORM_ID_alter().
+ *
+ * If a webform submission that is also part of a signup_webform is being deleted
+ * prevent deletion.
+ */
+
+function signup_webform_form_webform_submission_delete_form_alter(&$form, &$form_state) {
+  $submission_sid = $form['details']['sid']['#value'];
+  if (db_result(db_query('SELECT COUNT(*) FROM {signup_webform_submission} WHERE submission_sid = %d', $submission_sid)) > 0) {
+    $result = db_query(db_rewrite_sql("SELECT sl.nid, n.title FROM {signup_log} sl INNER JOIN {signup_webform_submission} sws ON sl.sid = sws.signup_sid INNER JOIN {node} n ON sl.nid = n.nid WHERE sws.submission_sid = '%d'"), $submission_sid);
+    while ($signup_node = db_fetch_object($result)) {
+      $items[] = l($signup_node->title, 'node/' . $signup_node->nid);
+    }
+    $form['description']['#value'] = t('This webform submission can not be deleted because it is currently used in the signup-enabled content listed below:');
+    $form['description']['#suffix'] = theme('item_list', $items);
+    drupal_set_title(t('Unable to delete Submission #' . $submission_sid, array('%title' => $node->title)));
+    unset($form['actions']['submit']);
+  }
+}
+
+/**
+ * Form validation function.
+ */
+function signup_webform_form_validate($element, &$form_state) {
+  foreach ($element as $element_id => $element_data) {
+    $this_webform_name = '';
+    $exploded_name = explode('_', $element_id);
+    if ($exploded_name[0] == 'webform') {
+      $webform_node = $element_data['#node'];
+      if ($webform_node->webform['submit_limit'] != -1) { // -1: Submissions are never throttled.
+        module_load_include('inc', 'webform', 'includes/webform.submissions');
+        if ($limit_exceeded = _webform_submission_limit_check($webform_node)) { // Check if submission limit has been reached.
+          $error = theme('webform_view_messages', $webform_node, 0, 1, 0, $limit_exceeded, array_keys(user_roles()));
+          form_set_error('', check_plain($error));
+          return;
+        }
+      }
+      _webform_client_form_validate($element_data, $form_state); // Validate
+    }
+  }
+}
+
+/**
  * Get the webform submission record for a given signup record.
  *
  * @param $signup
- *  The signup record object, as generally swilled around the place. 
+ *  The signup record object, as generally swilled around the place.
  * @param $webform_nid
  *  The node ID of the webform node in question.
  * @return
@@ -439,16 +702,21 @@ function signup_webform_get_signup_submi
   // Beware: both pieces of data we care about here are called sid!
   $submission_sid = db_result(db_query('SELECT submission_sid FROM {signup_webform_submission} WHERE signup_sid = %d AND webform_nid = %d', $signup->sid, $webform_nid));
   // Load the webform API.
-  module_load_include('inc', 'webform', 'webform_submissions');
-  $submission = webform_get_submission($webform_nid, $submission_sid);
+  module_load_include('inc', 'webform', 'includes/webform.submissions');
+  /**
+  * Errors are suppressed here because webform_get_submission() throws a SQL warning for previously signed up users
+  * of an existing signup if a new webform has just been added that didn't exist when they initially registered.
+  * Once the signup is re-saved thus including the new webform, the warning will no longer appear.
+  */
+  $submission = @webform_get_submission($webform_nid, $submission_sid, TRUE);
   return $submission;
 }
 
 /**
  * Helper function to make a lookup array of form keys => cid.
- * 
+ *
  * @param $webform_node
- *  Just feed this the entire webform $node object. 
+ *  Just feed this the entire webform $node object.
  */
 function _signup_webform_translate_cid_form_keys($webform_node) {
   $components = $webform_node->webform['components'];
@@ -460,7 +728,7 @@ function _signup_webform_translate_cid_f
 
 /**
  * Helper function to get the webform panes from an array on pane IDs.
- * 
+ *
  * Same pattern as element_children().
  *
  * @param $signup_data
@@ -470,10 +738,29 @@ function _signup_webform_translate_cid_f
  */
 function _signup_webform_pane_ids($signup_data) {
   $return = array();
-  foreach($signup_data as $pane_id => $data) {
-    if (substr($pane_id, 0, 7) == 'webform') {
+  foreach ($signup_data as $pane_id => $data) {
+    if (drupal_substr($pane_id, 0, 7) == 'webform') {
       $return[] = $pane_id;
     }
   }
   return $return;
 }
+
+/**
+ * Recursively searches through submission keys to retrieve results
+ * from within fieldsets.
+ *
+*/
+function _signup_webform_search_key($find, $search_array) {
+  foreach ($search_array as $key=>$value) {
+    if ($find===$key) {
+      return $value;
+    }
+    if (is_array($value)) {
+      if(_signup_webform_search_key($find, $value)) {
+        return _signup_webform_search_key($find, $value);
+      }
+    }
+  }
+  return false;
+}
