diff --git a/components/file.inc b/components/file.inc
index e1be9c1..9aa693a 100644
--- a/components/file.inc
+++ b/components/file.inc
@@ -346,13 +346,23 @@ function _webform_render_file($component, $value = NULL, $filter = TRUE, $submis
     $max_filesize = parse_size($set_filesize);
   }
 
+  if (isset($value[0])) {
+    $default_value = $value[0];
+  }
+  elseif (isset($value['fid'])) {
+    $default_value = $value['fid'];
+  }
+  else {
+    $default_value = NULL;
+  }
+
   $element = array(
     '#type' => 'managed_file',
     '#theme' => 'webform_managed_file',
     '#title' => $filter ? webform_filter_xss($component['name']) : $component['name'],
     '#title_display' => $component['extra']['title_display'] ? $component['extra']['title_display'] : 'before',
     '#required' => $component['required'],
-    '#default_value' => isset($value[0]) ? $value[0] : NULL,
+    '#default_value' => $default_value,
     '#attributes' => $component['extra']['attributes'],
     '#upload_validators' => array(
       'file_validate_size' => array($max_filesize),
diff --git a/webform.info b/webform.info
index f58d24f..0529079 100644
--- a/webform.info
+++ b/webform.info
@@ -39,4 +39,5 @@ files[] = tests/components.test
 files[] = tests/conditionals.test
 files[] = tests/permissions.test
 files[] = tests/submission.test
+files[] = tests/submission.file.test
 files[] = tests/webform.test
diff --git a/webform.module b/webform.module
index 56f4b17..977a552 100644
--- a/webform.module
+++ b/webform.module
@@ -2584,7 +2584,31 @@ function webform_client_form($form, &$form_state, $node, $submission = FALSE, $r
         $prev_page_labels[$component['page_num']] = !empty($component['extra']['prev_page_label']) ? t($component['extra']['prev_page_label']) : t('< Previous Page');
       }
       if (!$filter || $sorter->componentVisibility($cid, $page_num)) {
-        $component_value = isset($input_values[$cid]) ? $input_values[$cid] : NULL;
+        if (isset($input_values[$cid])) {
+          $component_value = $input_values[$cid];
+        }
+        elseif (isset($input_values[$component['form_key']])) {
+          $component_value = $input_values[$component['form_key']];
+          // Hack to support multiple files on the same form. Do this for file
+          // components as well as any component that has children (since the
+          // children might contain file components of their own).
+          if ($component['type'] == 'file' || !empty($component['children'])) {
+            if (!isset($form_state['webform_file_storage'])) {
+              $form_state['webform_file_storage'] = array();
+            }
+            // Merge the current submitted file into $form_state storage so it
+            // can be used to populate the file widget on subsequent Ajax
+            // requests.
+            $form_state['webform_file_storage'] = drupal_array_merge_deep($form_state['webform_file_storage'], $input_values);
+          }
+        }
+        elseif (isset($form_state['webform_file_storage'][$component['form_key']])) {
+          // Use the file storage from above, if available.
+          $component_value = $form_state['webform_file_storage'][$component['form_key']];
+        }
+        else {
+          $component_value = NULL;
+        }
         _webform_client_form_add_component($node, $component, $component_value, $form['submitted'], $form, $input_values, 'form', $page_num, $filter);
       }
     }
@@ -2841,7 +2865,15 @@ function _webform_client_form_add_component($node, $component, $component_value,
   if (isset($component['children']) && is_array($component['children'])) {
     $sorter = webform_get_conditional_sorter($node);
     foreach ($component['children'] as $scid => $subcomponent) {
-      $subcomponent_value = isset($input_values[$scid]) ? $input_values[$scid] : NULL;
+      if (isset($input_values[$scid])) {
+        $subcomponent_value = $input_values[$scid];
+      }
+      elseif (isset($component_value[$subcomponent['form_key']])) {
+        $subcomponent_value = $component_value[$subcomponent['form_key']];
+      }
+      else {
+        $subcomponent_value = NULL;
+      }
       // Include if always shown, or for forms, also if currently hidden but might be shown due to conditionals.
       $visibility = $sorter->componentVisibility($scid, $subcomponent['page_num']);
       if ($visibility == WebformConditionals::componentShown || ($format == 'form' && $visibility) || !$filter) {
diff --git a/tests/submission.file.test b/tests/submission.file.test
new file mode 100644
index 0000000..fc03022
--- /dev/null
+++ b/tests/submission.file.test
@@ -0,0 +1,254 @@
+<?php
+
+/**
+ * @file
+ * Webform module submission tests that focus on file components.
+ */
+
+class WebformFileSubmissionTestCase extends WebformTestHelper {
+  /**
+   * Implements getInfo().
+   */
+  public static function getInfo() {
+    return array(
+      'name' => t('Webform file submission'),
+      'description' => t('Submits a sample webform and checks the database integrity for file components.'),
+      'group' => t('Webform'),
+    );
+  }
+
+  /**
+   * Test that a form can have a file component added and have it show for
+   * authenticated visitors.
+   */
+  function testAuthBasicSubmission() {
+    // Create the node with a file component.
+    $node = $this->createTestWebform();
+
+    // Run the basic submission tests against this webform.
+    $this->basicSubmissionTest($node->nid);
+
+    // Logout.
+    $this->drupalLogout();
+  }
+
+  /**
+   * Test that a form can have a file component added and have it show for
+   * anonymous visitors.
+   */
+  function testAnonBasicSubmission() {
+    // Create the node with a file component.
+    $node = $this->createTestWebform();
+
+    // Logout.
+    $this->drupalLogout();
+
+    // Run the basic submission tests against this webform.
+    $this->basicSubmissionTest($node->nid);
+  }
+
+  /**
+   * Confirm a file can be submitted by an authenticated user.
+   */
+  function testAuthFileSubmission() {
+    // Create the node with a file component.
+    $node = $this->createTestWebform();
+
+    // Submit the webform with a file.
+    $args = array();
+    $this->drupalPost('node/' . $node->nid, $args, 'Submit', array(), array(), 'webform-client-form-' . $node->nid);
+    $this->assertResponse(200);
+    $this->assertText(t('Thanks!'));
+
+    // Logout.
+    $this->drupalLogout();
+  }
+
+  /**
+   * Confirm a file can be submitted by an anonymous user.
+   */
+  function testAnonFileSubmission() {
+    // Create the node with a file component.
+    $node = $this->createTestWebform();
+
+    // Logout.
+    $this->drupalLogout();
+
+    // Submit the webform with a file.
+    $args = array();
+    $this->drupalPost('node/' . $node->nid, $args, 'Submit', array(), array(), 'webform-client-form-' . $node->nid);
+    $this->assertResponse(200);
+    $this->assertText(t('Thanks!'));
+  }
+
+  /**
+   * Confirm that a file can be submitted when another component is required.
+   */
+  function testAuthFileRequiredSubmission() {
+    // Create the node with a file component.
+    $node = $this->createTestWebform();
+
+    // Submit the webform with a file but also a missing required text field, to
+    // confirm that the file can still be submitted.
+    $args = array();
+    $this->drupalPost('node/' . $node->nid, $args, 'Submit', array(), array(), 'webform-client-form-' . $node->nid);
+    foreach ($node->webform['components'] as $component) {
+      if ($component['type'] == 'textcomponent') {
+        $this->assertText(t('!name component is required.', array('!name' => $component['name'])));
+      }
+    }
+    $this->assertResponse(200);
+    $this->assertText(t('Thanks!'));
+
+    // Logout.
+    $this->drupalLogout();
+  }
+
+  /**
+   * Confirm that a file can be submitted by anonymous visitors when another component is required.
+   */
+  function testAnonFileRequiredSubmission() {
+    // Create the node with a file component.
+    $node = $this->createTestWebform();
+
+    // Logout.
+    $this->drupalLogout();
+
+    // Submit the webform with a file but also a missing required text field, to
+    // confirm that the file can still be submitted.
+    $args = array();
+    $this->drupalPost('node/' . $node->nid, $args, 'Submit', array(), array(), 'webform-client-form-' . $node->nid);
+    foreach ($node->webform['components'] as $component) {
+      if ($component['type'] == 'textcomponent') {
+        $this->assertText(t('!name component is required.', array('!name' => $component['name'])));
+      }
+    }
+    $this->assertResponse(200);
+    $this->assertText(t('Thanks!'));
+  }
+
+  /**
+   * Confirm multiple files can be submitted by authenticated visitors.
+   */
+  function testAuthMultipleFileSubmission() {
+    // Create the node with a file component.
+    $node = $this->createTestWebform();
+
+    // Submit the webform with multiple files.
+    $args = array();
+    $this->drupalPost('node/' . $node->nid, $args, 'Submit', array(), array(), 'webform-client-form-' . $node->nid);
+
+    // Logout.
+    $this->drupalLogout();
+  }
+
+  /**
+   * Confirm multiple files can be submitted by anonymous visitors.
+   */
+  function testAnonMultipleFileSubmission() {
+    // Create the node with a file component.
+    $node = $this->createTestWebform();
+
+    // Logout.
+    $this->drupalLogout();
+
+    // Submit the webform with multiple files.
+    $args = array();
+    $this->drupalPost('node/' . $node->nid, $args, 'Submit', array(), array(), 'webform-client-form-' . $node->nid);
+  }
+
+  /**
+   * Creates a webform with a text component and a file component.
+   *
+   * @return object
+   *   A node StdClass object.
+   */
+  function createTestWebform() {
+    $this->drupalLogin($this->webform_users['admin']);
+    $this->webformReset();
+
+    // Create the Webform test node, and only keep the plain text component.
+    $node = $this->getTestWebformNode();
+    $node = node_load($node->nid);
+
+    // Delete components that aren't text components, to keep the form simpler.
+    foreach ($node->webform['components'] as $key => $component) {
+      if ($component['form_key'] != 'textcomponent') {
+        unset($node->webform['components'][$key]);
+      }
+    }
+
+    // Add a file component.
+    $node->webform['components'][] = array(
+      'name' => 'File',
+      'form_key' => 'file',
+      'type' => 'file',
+      'value' => '',
+      'pid' => '0',
+      'required' => '0',
+      'weight' => '-12',
+      'extra' => array(
+        'title_display' => 'before',
+        'private' => 0,
+        'progress_indicator' => 'throbber',
+        'filtering' => array(
+          'size' => '5 MB',
+          'types' => array(
+            'gif',
+            'jpg',
+            'png',
+            'bmp',
+            'tif',
+            'pict',
+            'psd',
+            'txt',
+            'rtf',
+            'html',
+            'odf',
+            'pdf',
+            'doc',
+            'docx',
+            'ppt',
+            'pptx',
+            'xls',
+            'xlsx',
+            'xml',
+            'avi',
+            'mov',
+            'mp3',
+            'ogg',
+            'wav',
+            'zip',
+          ),
+          'addextensions' => '',
+        ),
+      ),
+    );
+    node_save($node);
+
+    return $node;
+  }
+
+  /**
+   * Run basic tests for a given node.
+   *
+   * @param int $nid
+   *   The node ID to test against.
+   */
+  function basicSubmissionTest($nid) {
+    // Load the form and confirm the components exist.
+    $this->drupalGet('node/' . $nid);
+    $this->assertResponse(200);
+
+    // Confirm that the two components are present.
+    $this->assertFieldByName('submitted[textcomponent]', '', 'Found the text component.');
+    $this->assertFieldByName('files[submitted_file]', '', 'Found the file component.');
+    $this->assertFieldByName('submitted_file_upload_button', '', 'Found the file component upload button.');
+
+    // Submit the form, confirm that the submission went ok.
+    $this->drupalPost('node/' . $nid, array(), 'Submit', array(), array(), 'webform-client-form-' . $nid);
+    $this->assertResponse(200);
+    $this->assertText(t('Thanks!'));
+  }
+
+}
