diff --git a/sites/all/modules/autosave/README.txt b/sites/all/modules/autosave/README.txt
index dd273bb..4ab5b3d 100644
--- a/sites/all/modules/autosave/README.txt
+++ b/sites/all/modules/autosave/README.txt
@@ -14,12 +14,15 @@ Includes the jQuery Form Plugin which was downloaded from here: http://dev.jquer
 
 NOTE: the plugin has been modified to work with Drupal field names
 
+Requires the jQuery UI Drupal module: http://drupal.org/project/jquery_ui
+
 INSTALLATION
 ============
 1. Place the "autosave" folder in your "modules" directory (i.e. modules/autosave).
 2. Enable the Autosave module under Administer >> Site building >> Modules.
 3. Under config for a node type select it to use Autosave.
-5. Under Admin -> Site Config -> Autosave enter the period of time before each autosave (in milliseconds).
+4. Under Admin -> Site Config -> Autosave enter the period of time before each autosave (in milliseconds).
+5. Grant "autosave forms" permission to some roles.
 
 AUTHOR
 ======
@@ -31,4 +34,4 @@ CHANGE LOG
 - 6.x-2.0 version is a complete re-write to remove dependencies on TinyMCE.
 - this version is now tied to the WYSIWYG module and currently is known to work with FCK, CK and TinyMCE 3.0 editors but requires
 the 6.x-2.x-dev version of WYSIWYG with this patch: http://drupal.org/node/614146#comment-2193764; this patch should be commited soon and will
-eventually be expanded to include other editors.
\ No newline at end of file
+eventually be expanded to include other editors.
diff --git a/sites/all/modules/autosave/autosave.info b/sites/all/modules/autosave/autosave.info
index f1cfce6..8788526 100644
--- a/sites/all/modules/autosave/autosave.info
+++ b/sites/all/modules/autosave/autosave.info
@@ -5,6 +5,8 @@ description = Saves node edits in the background in case browser dies while edit
 package = Other
 project = autosave
 
+dependencies[] = "jquery_ui"
+
 core = 6.x
 ; Information added by drupal.org packaging script on 2009-11-02
 version = "6.x-2.2"
diff --git a/sites/all/modules/autosave/autosave.js b/sites/all/modules/autosave/autosave.js
index 216a743..f1e51d6 100644
--- a/sites/all/modules/autosave/autosave.js
+++ b/sites/all/modules/autosave/autosave.js
@@ -1,94 +1,147 @@
 var autosaved_form;
 
-if (Drupal.jsEnabled) {
-  $(document).ready(function() {
-    $('body').append('<div id="autosave-status"><span id="status"></span><span id="operations"> \
-    <span id="view"><a href="#">View</a></span> \
-    <span id="ignore"><a href="#" title="Ignore/Delete Saved Form">Ignore</a></span> \
-    <span id="keep"><a href="#" title="Keep Saved Form - Revert to Saved">Keep</a></span></span></div>');
-    autosaved = Drupal.settings.autosave;   
-    autosaved_form_id = 'node-form';
+/**
+ * Autosave init.
+ * If there's no previously saved form, then start saving.
+ * If there is a previously saved form, ask the user what to do with it.
+ */
+Drupal.behaviors.autosave = function (context) {
+  $(context).find('body:not(.autosave-processed)').append('<div id="autosave-status" style="display: none;"><span id="autosave-status-message"></span></div>');
+  $(context).find('#autosave-status').css('display', 'none');
+
+  autosaved = Drupal.settings.autosave;   
+  autosaved_form_id = 'node-form';
+
+  if (autosaved.serialized) {
+    Drupal.autosave_view_ignore_dialog(context);
+  }
+  // There are no autosaved forms, continue with autosave.
+  else {
+    Drupal.attachAutosave(context);
+  }
+
+  $(context).find('body').addClass('autosave-processed');
+}
+
+/**
+ * Ask the user if they want to review the saved contents of the form, or
+ * simply ignore them.
+ */
+Drupal.autosave_view_ignore_dialog = function (context) {
+  var autosaved = Drupal.settings.autosave;   
+  var autosaved_form_id = 'node-form';
+
+  $(context).find('body:not(.autosave-processed)').append('<div id="autosave-operations"> \
+  <span id="autosave-operations-status-message">'+Drupal.t('This form was autosaved on !date', {'!date': autosaved.saved_date})+'</span> \
+  </div>');
+
+  var view_ignore_buttons = {};
+  view_ignore_buttons[Drupal.t('View')] = function () {
+    $(context).find('#' + autosaved_form_id).formHash(autosaved.serialized);
+    if (Drupal.settings.autosave.wysiwyg && Drupal.wysiwyg) {
+      // need to loop through any WYSIWYG editor fields and update the visible iframe fields with hidden field content
+      for (var instance in Drupal.wysiwyg.instances) {
+        Drupal.wysiwyg.instances[instance].setContent($(context).find('#' + instance).val());
+      }
+    }
     
-    if (autosaved.serialized) {
-      $('#autosave-status #keep').css('display', 'none').css('visibility', 'hidden');
-      $('#autosave-status #view a').click(function() {
-        if ($(this).html() == 'View') {
-          $('#' + autosaved_form_id).formHash(autosaved.serialized);
-          if (Drupal.settings.autosave.wysiwyg && Drupal.wysiwyg) {
-            // need to loop through any WYSIWYG editor fields and update the visible iframe fields with hidden field content
-            for (var instance in Drupal.wysiwyg.instances) {
-              Drupal.wysiwyg.instances[instance].setContent($('#' + instance).val());
-            }
-          }
-          
-          //CKEditor support
-          if (typeof(CKEDITOR) != 'undefined' ) {
-            for (var instance in CKEDITOR.instances) {
-              CKEDITOR.instances[instance].setData($('#' + instance).val());
-            }
-          }
-          
-          $('#' + autosaved_form_id).focus();
-          $(this).html('Reset');
-          $('#autosave-status #keep').css('display', 'inline').css('visibility', 'visible');
-          $('#autosave-status #keep a').html('Keep'); 
-        }
-        else if ($(this).html() == 'Reset') {
-          form = document.getElementById(autosaved_form_id);
-          form.reset();
-
-          //CKEditor support
-          if (typeof(CKEDITOR) != 'undefined' ) {
-            for (var instance in CKEDITOR.instances) {
-              CKEDITOR.instances[instance].setData($('#' + instance).val());
-            }
-          }
-          
-          $('#autosave-status #keep').css('display', 'none').css('visibility', 'hidden');
-          $(this).html('View');
-        }    
-        return false;
-      });
-      $('#autosave-status #ignore a').click(function() {
-        $('#autosave-status').fadeOut('slow');
-        form = document.getElementById(autosaved_form_id);
-        form.reset();
-
-        //CKEditor support
-        if (typeof(CKEDITOR) != 'undefined' ) {
-          for (var instance in CKEDITOR.instances) {
-            CKEDITOR.instances[instance].setData($('#' + instance).val());
-          }
-        }
-        
-        $('#autosave-status #operations').css('display', 'none').css('visibility', 'hidden');
-        Drupal.attachAutosave();
-        return false;
-      });
-      $('#autosave-status #keep a').click(function() {
-        $('#autosave-status').fadeOut('slow');
-        form = document.getElementById(autosaved_form_id);
-        $('#autosave-status #operations').css('display', 'none').css('visibility', 'hidden');
-        Drupal.attachAutosave();
-        return false;
-      });
-      $('#autosave-status #status').html('This form was autosaved on ' + autosaved.saved_date);
-      $('#autosave-status').slideDown();
+    //CKEditor support
+    if (typeof(CKEDITOR) != 'undefined' ) {
+      for (var instance in CKEDITOR.instances) {
+        CKEDITOR.instances[instance].setData($(context).find('#' + instance).val());
+      }
+    }
+
+    $(this).dialog('destroy');
+    $(this).remove();
+
+    Drupal.autosave_keep_reset_dialog(context);
+    
+    $(context).find('#' + autosaved_form_id).focus();
+  };
+      
+  view_ignore_buttons[Drupal.t('Ignore')] = function () {
+    $(context).find('#autosave-operations').fadeOut('slow');
+    form = document.getElementById(autosaved_form_id);
+    form.reset();
+
+    //CKEditor support
+    if (typeof(CKEDITOR) != 'undefined' ) {
+      for (var instance in CKEDITOR.instances) {
+        CKEDITOR.instances[instance].setData($(context).find('#' + instance).val());
+      }
     }
-    // There are no autosaved forms, continue with autosave.
-    else {
-      Drupal.attachAutosave();
+    
+    $(this).dialog('destroy');
+    $(this).remove();
+
+    // Start autosaving.
+    Drupal.attachAutosave(context);
+  };
+
+  $(context).find('#autosave-operations').dialog({
+    modal: true,
+    buttons: view_ignore_buttons,
+    show: 'fold',
+    hide: 'fold'
+  });
+}
+
+/**
+ * Ask the user if they want to keep the saved contents of the form or start over.
+ */
+Drupal.autosave_keep_reset_dialog = function (context) {
+  var autosaved = Drupal.settings.autosave;   
+  var autosaved_form_id = 'node-form';
+
+  $(context).find('body').append('<div id="autosave-operations"> \
+  <span id="autosave-operations-status-message">'+Drupal.t('Please examine these values, autosaved on !date.  If you would like to continue from where you left off, click "Keep".  If you would like to start over with this form, click "Reset".', {'!date': autosaved.saved_date})+'</span> \
+  </div>');
+
+  $(context).find('#' + autosaved_form_id).focus();
+
+  var keep_reset_buttons = {};
+  keep_reset_buttons[Drupal.t('Keep')] = function () {
+    $(context).find('#autosave-operations').fadeOut('slow');
+    form = document.getElementById(autosaved_form_id);
+
+    $(this).dialog('disable');
+    $(this).remove();
+
+    Drupal.attachAutosave(context);
+  };
+
+  keep_reset_buttons[Drupal.t('Reset')] = function () {
+    form = document.getElementById(autosaved_form_id);
+    form.reset();
+
+    //CKEditor support
+    if (typeof(CKEDITOR) != 'undefined' ) {
+      for (var instance in CKEDITOR.instances) {
+        CKEDITOR.instances[instance].setData($(context).find('#' + instance).val());
+      }
     }
+    
+    $(this).dialog('destroy');
+    $(this).remove();
+
+    Drupal.attachAutosave(context);
+  };
+
+  $(context).find('#autosave-operations').dialog({
+    buttons: keep_reset_buttons,
+    show: 'fold',
+    hide: 'fold'
   });
-} 
+}
 
-Drupal.saveForm = function() {
+Drupal.saveForm = function(context) {
   if (Drupal.settings.autosave.wysiwyg && Drupal.wysiwyg) {
     // need to loop through any WYSIWYG editor fields and update the real (hidden) text fields before saving
     for (var instance in Drupal.wysiwyg.instances) {
       if (Drupal.wysiwyg.instances[instance].editor != 'none') {
         var content = Drupal.wysiwyg.instances[instance].getContent();
-        $('#' + instance).val(content);
+        $(context).find('#' + instance).val(content);
       }
     }
   }
@@ -100,28 +153,28 @@ Drupal.saveForm = function() {
     }
   }
   
-  var serialized = $('#node-form').formHash();
-  serialized['q'] =  Drupal.settings.autosave.q;
+  var serialized = $(context).find('#node-form').formHash();
+  serialized['autosave_path'] =  Drupal.settings.autosave.autosave_path;
   $.ajax({
     url: Drupal.settings.basePath + "autosave/handler",
     type: "POST",
     dataType: "xml/html/script/json",
     data: serialized,
     complete: function(XMLHttpRequest, textStatus) {
-      if (!Drupal.settings.autosave.hidden) Drupal.displaySaved();
-      Drupal.attachAutosave();
+      if (!Drupal.settings.autosave.hidden) Drupal.displaySaved(context);
+      Drupal.attachAutosave(context);
     }
   });
 }   
 
-Drupal.attachAutosave = function() {
-  setTimeout('Drupal.saveForm()', Drupal.settings.autosave.period * 1000);
+Drupal.attachAutosave = function(context) {
+  setTimeout(function () { Drupal.saveForm(context); }, Drupal.settings.autosave.period * 1000);
 }
 
-Drupal.displaySaved = function() {
-  $('#autosave-status #status').html('Form autosaved.');
-  $('#autosave-status #operations').css('display', 'none').css('visibility', 'hidden');
-  $('#autosave-status').slideDown();
-  setTimeout("$('#autosave-status').fadeOut('slow')", 3000);  
+Drupal.displaySaved = function(context) {
+  $(context).find('#autosave-status #autosave-status-message').html(Drupal.t('Form autosaved.'));
+  $(context).find('#autosave-status #autosave-operations').css('display', 'none').css('visibility', 'hidden');
+  $(context).find('#autosave-status').slideDown();
+  setTimeout(function () { $(context).find('#autosave-status').fadeOut('slow'); }, 3000);
 }
 
diff --git a/sites/all/modules/autosave/autosave.module b/sites/all/modules/autosave/autosave.module
index 4c22a3f..73b1a53 100644
--- a/sites/all/modules/autosave/autosave.module
+++ b/sites/all/modules/autosave/autosave.module
@@ -22,13 +22,20 @@ function autosave_help($path, $arg) {
 }
 
 /**
+ * Implementation of hook_perm.
+ */
+function autosave_perm() {
+  return array('autosave forms');
+}
+
+/**
  * Implementation of hook_menu().
  */
 function autosave_menu() {
   $items['autosave/handler'] = array(
     'title'           => 'Autosave save',
     'page callback'   => 'autosave_save',
-    'access callback' => TRUE,
+    'access arguments' => array('autosave forms'),
     'type'            => MENU_CALLBACK,
   );
 
@@ -87,6 +94,10 @@ function autosave_form_node_type_form_alter(&$form, $form_state) {
 function autosave_form_alter(&$form, &$form_state, $form_id) {
   global $user;
   $path = $_GET['q'];
+
+  jquery_ui_add(array('ui.draggable', 'ui.resizable'));
+  drupal_add_css(jquery_ui_get_path()."/themes/base/jquery-ui.css");
+  drupal_add_css(jquery_ui_get_path()."/themes/base/ui.all.css");
   
   if (stristr($form_id, '_node_form') && arg(0) != 'admin') {
 
@@ -96,20 +107,23 @@ function autosave_form_alter(&$form, &$form_state, $form_id) {
       drupal_add_js(AUTOSAVE_PATH .'/jquery.field.js');
       drupal_add_css(AUTOSAVE_PATH .'/autosave.css');
 
+      $form['#submit'][] = 'autosave_submit';
+
       // if WYSIWYG module is enabled; lets let JS know this
       if (module_exists('wysiwyg')) $settings['autosave']['wysiwyg'] = 1;
       else $settings['autosave']['wysiwyg'] = 0;
       
       $settings['autosave']['url'] = url('autosave/handler');
       $settings['autosave']['period'] = variable_get('autosave_period', 10);
-      $settings['autosave']['q'] = $path;
+      $settings['autosave']['autosave_path'] = $path;
       $settings['autosave']['hidden'] = variable_get('autosave_hidden', 0);
       
       // If an autosaved version of the form exists, make it available via javascript.
       if ($autosaved_form = autosave_get_autosaved_form($form_id, $path, $user->uid)) {
-        //$autosaved_form_id = $form['type']['#value'] ? $form['type']['#value'] .'_node_form' : 'node_form';
+        $form_contents = unserialize($autosaved_form['serialized']);
+        autosave_tweak_autosaved_form($form, $form_state);
         $settings['autosave'] = array_merge($settings['autosave'], array(
-          'serialized' => unserialize($autosaved_form['serialized']),
+          'serialized' => $form_contents,
           'saved_date' => format_date($autosaved_form['timestamp'], 'medium'),
         ));
       }
@@ -118,18 +132,104 @@ function autosave_form_alter(&$form, &$form_state, $form_id) {
   }
 }
 
+/**
+ * Tweak the form, given the autosaved values.
+ * If the user was editing a multiply-occuring field, they may have added
+ * values to it, ahose values will have been saved.  However, when the field is
+ * rebuilt, it will have only the original number of fields, so we will not be
+ * able to fill them in with the new values.
+ * This function searches the form for situations like this and adds enough
+ * fields to match the number of values stored.
+ */
+function autosave_tweak_autosaved_form(&$form, &$form_state, $form_id=null, $path=null, $orig_form=null) {
+  global $user;
+  if ($form_id == null) {
+    $form_id = $form['form_id']['#value'];
+    $path = $_GET['q'];
+    $orig_form = $form;
+  }
+
+  $autosaved_form = autosave_get_autosaved_form($form_id, $path, $user->uid);
+  $form_contents = unserialize($autosaved_form['serialized']);
+
+  $field_info = $orig_form['#field_info'];
+
+  foreach (element_children($form) as $child) {
+    if (!is_array($form[$child])) {
+      continue; 
+    }
+
+    // Find the maximum numeric child of this form element.
+    $max_in_form = -1;
+    foreach (element_children($form[$child]) as $number) {
+      if (is_numeric($number) && $number > $max_in_form) {
+        $max_in_form = $number;
+      }
+    }
+
+    // Find the maximum equivalent number in the saved values.
+    $max_in_values = -1;
+    foreach (element_children($form_contents[$child]) as $number) {
+      if (is_numeric($number) && $number > $max_in_values) {
+        $max_in_values = $number;
+      }
+    }
+
+    $field = $field_info[$child];
+
+    if ($field && $max_in_values > $max_in_form) {
+      // Call the ahah "add more", to make space for the new values.
+      for ($delta = $max_in_form+1; $delta <= $max_in_values; $delta++) {
+        $add_more = content_field_form($orig_form, $form_state, $field, $delta);
+
+        $data = &$add_more;
+        $empty_form_state = array();
+        $data['__drupal_alter_by_ref'] = array(&$empty_form_state);
+        drupal_alter('form', $data, 'content_add_more_js');
+
+        $add_more = $add_more[$child][0];
+        $form[$child][$delta] = $add_more;
+      }
+      continue;
+    }
+
+    if (is_array($form[$child])) {
+      autosave_tweak_autosaved_form($form[$child], $form_state, $form_id, $path, $orig_form);
+    }
+  }
+
+  return $form;
+}
+
+/**
+ * Submit handler.
+ * When the form successfully submits, we can blow away the autosaved version
+ * of the form.
+ */
+function autosave_submit($form, &$form_state) {
+  global $user;
+
+  if (!user_access('autosave forms')) {
+    return;
+  }
+
+  $path = $_GET['q'];
+  $form_id = $form['form_id']['#value'];
+  db_query("DELETE FROM {autosaved_forms} WHERE form_id = '%s' AND path = '%s' AND uid = %d", $form_id, $path, $user->uid);
+}
+
 
 /**
  * Menu callback; autosaves the node.
  */
 function autosave_save() {
   global $user;
-  
-  $path = $_POST['q'];
+
+  $path = $_POST['autosave_path'];
   $form_id = $_POST['form_id'];
   // Not all variables need to be serialized.
-  //    - for Drupal 6 version need to remove op and form_build_id
-  unset($_POST['q'], $_POST['op'], $_POST['form_build_id']);
+  //    - for Drupal 6 version need to remove op
+  unset($_POST['autosave_path'], $_POST['op']);
   $serialized = serialize($_POST);
 
   // check if node has just been saved - if it has then it's because AS ajax fired off as user was submitting
@@ -168,12 +268,21 @@ function autosave_save() {
  *   An array containing the serialized values of the autosaved form and the timestamp of when the form was autosaved.
  */
 function autosave_get_autosaved_form($form_id, $path, $uid) {
+  static $autosaved_forms = array();
+
+  if (isset($autosaved_forms[$form_id][$path][$uid])) {
+    return $autosaved_forms[$form_id][$path][$uid];
+  }
+
   $result = db_query("SELECT form_id, serialized, timestamp FROM {autosaved_forms} WHERE form_id = '%s' AND path = '%s' AND uid = %d", $form_id, $path, $uid);
 
   while ($data = db_fetch_object($result)) {
     $form['serialized'] = $data->serialized;
     $form['timestamp'] = $data->timestamp;
   }
+
+  $autosaved_forms[$form_id][$path][$uid] = $form;
+
   return $form;
 }
 
