diff --git a/components/select.inc b/components/select.inc
index 326dde2..7871407 100644
--- a/components/select.inc
+++ b/components/select.inc
@@ -325,11 +325,12 @@ function _webform_render_select($component, $value = NULL, $filter = TRUE) {
   }
 
   if ($component['extra']['other_option'] && module_exists('select_or_other')) {
-    // Set display as a select list:
+    // Set display as a select_or_other element:
     $element['#type'] = 'select_or_other';
     $element['#other'] = !empty($component['extra']['other_text']) ? check_plain($component['extra']['other_text']) : t('Other...');
     $element['#other_unknown_defaults'] = 'other';
     $element['#other_delimiter'] = ', ';
+    $element['#process'] = array('select_or_other_process', 'webform_expand_select_or_other');
     if ($component['extra']['multiple']) {
       $element['#multiple'] = TRUE;
       $element['#select_type'] = 'checkboxes';
@@ -368,6 +369,29 @@ function _webform_render_select($component, $value = NULL, $filter = TRUE) {
 }
 
 /**
+ * Process function to ensure select_or_other elements validate properly.
+ */
+function webform_expand_select_or_other($element) {
+  // Disable validation for back-button and save draft.
+  $element['select']['#validated'] = TRUE;
+  $element['select']['#webform_validated'] = FALSE;
+
+  $element['other']['#validated'] = TRUE;
+  $element['other']['#webform_validated'] = FALSE;
+
+  // If the default value contains "select_or_other" (the key of the select
+  // element for the "other..." choice), discard it and set the "other" value.
+  if (is_array($element['#default_value']) && in_array('select_or_other', $element['#default_value'])) {
+    $key = array_search('select_or_other', $element['#default_value']);
+    unset($element['#default_value'][$key]);
+    $element['#default_value'] = array_values($element['#default_value']);
+    $element['other']['#default_value'] = implode(', ', $element['#default_value']);
+  }
+
+  return $element;
+}
+
+/**
  * Drupal 6 hack that properly *renders* checkboxes in multistep forms. This is
  * different than the value hack needed in Drupal 5, which is no longer needed.
  */
@@ -491,8 +515,9 @@ function _webform_submit_select($component, $value) {
           $return[] = $option_value;
         }
       }
-      // Handle options that are added through the "other" field.
-      elseif ($component['extra']['other_option'] && module_exists('select_or_other')) {
+      // Handle options that are added through the "other" field. Specifically
+      // exclude the "select_or_other" value, which is added by the select list.
+      elseif ($component['extra']['other_option'] && module_exists('select_or_other') && $option_value != 'select_or_other') {
         $return[] = $option_value;
       }
     }
diff --git a/webform.module b/webform.module
index aeb10b2..f829942 100644
--- a/webform.module
+++ b/webform.module
@@ -2165,7 +2165,12 @@ function webform_client_form_submit($form, &$form_state) {
     // To maintain time and user information, load the existing submission.
     $submission = webform_get_submission($node->nid, $sid);
     $submission->is_draft = $is_draft;
-    $submission->data = webform_submission_data($node, $form_state['values']['submitted']);
+
+    // Merge with new submission data. The + operator maintains numeric keys.
+    // This maintains existing data with just-submitted data when a user resumes
+    // a submission previously saved as a draft.
+    $new_data = webform_submission_data($node, $form_state['values']['submitted']);
+    $submission->data = $new_data + $submission->data;
   }
 
   // Save the submission to the database.
